From ad5982176179d23a26d8bf3d8e05b1309ea7e84b Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 21 Oct 2023 22:47:26 +0200 Subject: [PATCH] cmd/evm: make t8ntool rlp-tranaction handle errors individually --- cmd/evm/internal/t8ntool/tx_iterator.go | 58 +++++++++++-------- cmd/evm/t8n_test.go | 8 +++ cmd/evm/testdata/30/README.txt | 77 +++++++++++++++++++++++++ cmd/evm/testdata/30/alloc.json | 7 +++ cmd/evm/testdata/30/command.sh | 1 - cmd/evm/testdata/30/env.json | 1 + cmd/evm/testdata/30/error.json | 1 - cmd/evm/testdata/30/exp.json | 62 ++++++++++++++++++++ cmd/evm/testdata/30/txs_more.rlp | 1 + 9 files changed, 190 insertions(+), 26 deletions(-) create mode 100644 cmd/evm/testdata/30/README.txt delete mode 100644 cmd/evm/testdata/30/command.sh delete mode 100644 cmd/evm/testdata/30/error.json create mode 100644 cmd/evm/testdata/30/exp.json create mode 100644 cmd/evm/testdata/30/txs_more.rlp diff --git a/cmd/evm/internal/t8ntool/tx_iterator.go b/cmd/evm/internal/t8ntool/tx_iterator.go index 1588da8f84..c1f3302280 100644 --- a/cmd/evm/internal/t8ntool/tx_iterator.go +++ b/cmd/evm/internal/t8ntool/tx_iterator.go @@ -17,9 +17,11 @@ package t8ntool import ( + "bytes" "crypto/ecdsa" "encoding/json" "fmt" + "io" "os" "strings" @@ -29,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" - "io" ) // txWithKey is a helper-struct, to allow us to use the types.Transaction along with @@ -113,7 +114,6 @@ func signUnsignedTransactions(txs []*txWithKey, signer types.Signer) (types.Tran func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *params.ChainConfig) (txIterator, error) { var txsWithKeys []*txWithKey - var signed types.Transactions if txStr != stdinSelector { data, err := os.ReadFile(txStr) if err != nil { @@ -124,11 +124,7 @@ func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *pa if err := json.Unmarshal(data, &body); err != nil { return nil, err } - // Already signed transactions - if err := rlp.DecodeBytes(body, &signed); err != nil { - return nil, err - } - return newArrayIterator(signed), err + return newRlpTxIterator(body), nil } if err := json.Unmarshal(data, &txsWithKeys); err != nil { return nil, NewError(ErrorJson, fmt.Errorf("failed unmarshaling txs-file: %v", err)) @@ -136,12 +132,7 @@ func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *pa } else { if len(inputData.TxRlp) > 0 { // Decode the body of already signed transactions - body := common.FromHex(inputData.TxRlp) - // Already signed transactions - if err := rlp.DecodeBytes(body, &signed); err != nil { - return nil, err - } - return newArrayIterator(signed), nil + return newRlpTxIterator(common.FromHex(inputData.TxRlp)), nil } // JSON encoded transactions txsWithKeys = inputData.Txs @@ -149,7 +140,7 @@ func loadTransactions(txStr string, inputData *input, env stEnv, chainConfig *pa // We may have to sign the transactions. signer := types.LatestSignerForChainID(chainConfig.ChainID) txs, err := signUnsignedTransactions(txsWithKeys, signer) - return newArrayIterator(txs), err + return newSliceTxIterator(txs), err } type txIterator interface { @@ -159,26 +150,45 @@ type txIterator interface { Tx() (*types.Transaction, error) } -type arrayIterator struct { +type sliceTxIterator struct { idx int - txs types.Transactions + txs []*types.Transaction } -func newArrayIterator(transactions types.Transactions) *arrayIterator { - return &arrayIterator{0, transactions} +func newSliceTxIterator(transactions types.Transactions) txIterator { + return &sliceTxIterator{0, transactions} } -func (ait *arrayIterator) Next() bool { - if ait.idx < len(ait.txs) { - return true - } - return false +func (ait *sliceTxIterator) Next() bool { + return ait.idx < len(ait.txs) } -func (ait *arrayIterator) Tx() (*types.Transaction, error) { +func (ait *sliceTxIterator) Tx() (*types.Transaction, error) { if ait.idx < len(ait.txs) { ait.idx++ return ait.txs[ait.idx-1], nil } return nil, io.EOF } + +type rlpTxIterator struct { + in *rlp.Stream +} + +func newRlpTxIterator(rlpData []byte) txIterator { + in := rlp.NewStream(bytes.NewBuffer(rlpData), 1024*1024) + in.List() + return &rlpTxIterator{in} +} + +func (it *rlpTxIterator) Next() bool { + return it.in.MoreDataInList() +} + +func (it *rlpTxIterator) Tx() (*types.Transaction, error) { + var a types.Transaction + if err := it.in.Decode(&a); err != nil { + return nil, err + } + return &a, nil +} diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index ad09a6b4d6..efacbe95ae 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -275,6 +275,14 @@ func TestT8n(t *testing.T) { output: t8nOutput{alloc: true, result: true}, expOut: "exp.json", }, + { // More cancun test, plus example of rlp-transaction that cannot be decoded properly + base: "./testdata/30", + input: t8nInput{ + "alloc.json", "txs_more.rlp", "env.json", "Cancun", "", + }, + output: t8nOutput{alloc: true, result: true}, + expOut: "exp.json", + }, } { args := []string{"t8n"} args = append(args, tc.output.get()...) diff --git a/cmd/evm/testdata/30/README.txt b/cmd/evm/testdata/30/README.txt new file mode 100644 index 0000000000..84c92de853 --- /dev/null +++ b/cmd/evm/testdata/30/README.txt @@ -0,0 +1,77 @@ +This example comes from https://github.com/ethereum/go-ethereum/issues/27730. +The input transactions contain three transactions, number `0` and `2` are taken from +`testdata/13`, whereas number `1` is taken from #27730. + +The problematic second transaction cannot be RLP-decoded, and the expectation is +that that particular transaction should be rejected, but number `0` and `1` should +still be accepted. + +``` +$ go run . t8n --input.alloc=./testdata/30/alloc.json --input.txs=./testdata/30/txs_more.rlp --input.env=./testdata/30/env.json --output.result=stdout --output.alloc=stdout --state.fork=Cancun +WARN [10-22|15:38:03.283] rejected tx index=1 error="rlp: input string too short for common.Address, decoding into (types.Transaction)(types.BlobTx).To" +INFO [10-22|15:38:03.284] Trie dumping started root=348312..915c93 +INFO [10-22|15:38:03.284] Trie dumping complete accounts=3 elapsed="160.831µs" +{ + "alloc": { + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "code": "0x60004960005500", + "balance": "0xde0b6b3a7640000" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0xde0b6b3a7640000" + }, + "0xd02d72e067e77158444ef2020ff2d325f929b363": { + "balance": "0xfffffffb8390", + "nonce": "0x3" + } + }, + "result": { + "stateRoot": "0x3483124b6710486c9fb3e07975669c66924697c88cccdcc166af5e1218915c93", + "txRoot": "0x013509c8563d41c0ae4bf38f2d6d19fc6512a1d0d6be045079c8c9f68bf45f9d", + "receiptsRoot": "0x75308898d571eafb5cd8cde8278bf5b3d13c5f6ec074926de3bb895b519264e1", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "receipts": [ + { + "type": "0x2", + "root": "0x", + "status": "0x1", + "cumulativeGasUsed": "0x5208", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logs": null, + "transactionHash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476", + "contractAddress": "0x0000000000000000000000000000000000000000", + "gasUsed": "0x5208", + "effectiveGasPrice": null, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x0" + }, + { + "type": "0x2", + "root": "0x", + "status": "0x1", + "cumulativeGasUsed": "0xa410", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logs": null, + "transactionHash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a", + "contractAddress": "0x0000000000000000000000000000000000000000", + "gasUsed": "0x5208", + "effectiveGasPrice": null, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x1" + } + ], + "rejected": [ + { + "index": 1, + "error": "rlp: input string too short for common.Address, decoding into (types.Transaction)(types.BlobTx).To" + } + ], + "currentDifficulty": null, + "gasUsed": "0xa410", + "currentBaseFee": "0x7", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + } +} + +``` \ No newline at end of file diff --git a/cmd/evm/testdata/30/alloc.json b/cmd/evm/testdata/30/alloc.json index 561b2fbd03..6bc93d2552 100644 --- a/cmd/evm/testdata/30/alloc.json +++ b/cmd/evm/testdata/30/alloc.json @@ -6,6 +6,13 @@ "storage" : { } }, + "0xd02d72e067e77158444ef2020ff2d325f929b363" : { + "balance": "0x01000000000000", + "code": "0x", + "nonce": "0x01", + "storage": { + } + }, "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "0x0de0b6b3a7640000", "code" : "0x", diff --git a/cmd/evm/testdata/30/command.sh b/cmd/evm/testdata/30/command.sh deleted file mode 100644 index 98257529ca..0000000000 --- a/cmd/evm/testdata/30/command.sh +++ /dev/null @@ -1 +0,0 @@ -/home/wins/.retesteth/default/start.sh --state.fork Cancun --state.reward 0 --state.chainid 1 --input.alloc /home/wins/Ethereum/rettmp/default_Cancun_block1_0xe4e2a3/alloc.json --input.txs /home/wins/Ethereum/rettmp/default_Cancun_block1_0xe4e2a3/txs.rlp --input.env /home/wins/Ethereum/rettmp/default_Cancun_block1_0xe4e2a3/env.json --output.basedir /home/wins/Ethereum/rettmp/default_Cancun_block1_0xe4e2a3 --output.result out.json --output.alloc outAlloc.json --output.errorlog /home/wins/Ethereum/rettmp/default_Cancun_block1_0xe4e2a3/error.json \ No newline at end of file diff --git a/cmd/evm/testdata/30/env.json b/cmd/evm/testdata/30/env.json index 40ce9f2b9d..af448d7b09 100644 --- a/cmd/evm/testdata/30/env.json +++ b/cmd/evm/testdata/30/env.json @@ -8,6 +8,7 @@ "parentTimestamp" : "0x00", "parentDifficulty" : "0x00", "parentUncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "parentBeaconBlockRoot" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "currentRandom" : "0x0000000000000000000000000000000000000000000000000000000000020000", "withdrawals" : [ ], diff --git a/cmd/evm/testdata/30/error.json b/cmd/evm/testdata/30/error.json deleted file mode 100644 index 45dfdae18a..0000000000 --- a/cmd/evm/testdata/30/error.json +++ /dev/null @@ -1 +0,0 @@ -rlp: input string too short for common.Address, decoding into (types.Transactions)[0](types.BlobTx).To diff --git a/cmd/evm/testdata/30/exp.json b/cmd/evm/testdata/30/exp.json new file mode 100644 index 0000000000..28c53c1b87 --- /dev/null +++ b/cmd/evm/testdata/30/exp.json @@ -0,0 +1,62 @@ +{ + "alloc": { + "0x095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "code": "0x60004960005500", + "balance": "0xde0b6b3a7640000" + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0xde0b6b3a7640000" + }, + "0xd02d72e067e77158444ef2020ff2d325f929b363": { + "balance": "0xfffffffb8390", + "nonce": "0x3" + } + }, + "result": { + "stateRoot": "0x3483124b6710486c9fb3e07975669c66924697c88cccdcc166af5e1218915c93", + "txRoot": "0x013509c8563d41c0ae4bf38f2d6d19fc6512a1d0d6be045079c8c9f68bf45f9d", + "receiptsRoot": "0x75308898d571eafb5cd8cde8278bf5b3d13c5f6ec074926de3bb895b519264e1", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "receipts": [ + { + "type": "0x2", + "root": "0x", + "status": "0x1", + "cumulativeGasUsed": "0x5208", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logs": null, + "transactionHash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476", + "contractAddress": "0x0000000000000000000000000000000000000000", + "gasUsed": "0x5208", + "effectiveGasPrice": null, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x0" + }, + { + "type": "0x2", + "root": "0x", + "status": "0x1", + "cumulativeGasUsed": "0xa410", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "logs": null, + "transactionHash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a", + "contractAddress": "0x0000000000000000000000000000000000000000", + "gasUsed": "0x5208", + "effectiveGasPrice": null, + "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "transactionIndex": "0x1" + } + ], + "rejected": [ + { + "index": 1, + "error": "rlp: input string too short for common.Address, decoding into (types.Transaction)(types.BlobTx).To" + } + ], + "currentDifficulty": null, + "gasUsed": "0xa410", + "currentBaseFee": "0x7", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + } +} diff --git a/cmd/evm/testdata/30/txs_more.rlp b/cmd/evm/testdata/30/txs_more.rlp new file mode 100644 index 0000000000..35af8d1f23 --- /dev/null +++ b/cmd/evm/testdata/30/txs_more.rlp @@ -0,0 +1 @@ +"0xf901adb86702f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904b8d903f8d601800285012a05f200833d090080830186a000f85bf85994095e7baea6a6c7c4c2dfeb977efac326af552d87f842a00000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010ae1a001a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d880a0fc12b67159a3567f8bdbc49e0be369a2e20e09d57a51c41310543a4128409464a02de0cfe5495c4f58ff60645ceda0afd67a4c90a70bc89fe207269435b35e5b67b86702f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9" \ No newline at end of file