From b6ef123d0b8a62f0c573b30122842ba7a42c4594 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Fri, 2 Feb 2024 07:51:59 +0100 Subject: [PATCH 01/18] Mixed transaction to different types of transactions --- blockchain/blockchain.go | 4 +- blockchain/blockchain_test.go | 69 +-- blockchain/storage/leveldb/leveldb_test.go | 6 +- blockchain/storage/testing.go | 6 +- consensus/polybft/block_builder_test.go | 2 +- consensus/polybft/fsm.go | 5 +- consensus/polybft/fsm_test.go | 3 +- consensus/polybft/polybft.go | 2 +- consensus/polybft/state_sync_commitment.go | 2 +- crypto/txsigner.go | 6 +- crypto/txsigner_eip155_test.go | 4 +- crypto/txsigner_frontier_test.go | 2 +- crypto/txsigner_london_berlin.go | 4 +- crypto/txsigner_london_berlin_test.go | 37 +- e2e/framework/testserver.go | 2 +- e2e/txpool_test.go | 36 +- gasprice/feehistory_test.go | 4 +- gasprice/gasprice_test.go | 6 +- helper/tests/testing.go | 2 +- jsonrpc/debug_endpoint_test.go | 3 +- jsonrpc/eth_blockchain_test.go | 2 +- jsonrpc/eth_endpoint.go | 2 +- jsonrpc/eth_endpoint_test.go | 67 ++- jsonrpc/eth_txpool_test.go | 4 +- jsonrpc/filter_manager_fuzz_test.go | 6 +- jsonrpc/filter_manager_test.go | 6 +- jsonrpc/helper.go | 51 +- jsonrpc/helper_test.go | 19 +- jsonrpc/txpool_endpoint_test.go | 9 +- jsonrpc/types_test.go | 9 +- state/executor.go | 10 +- state/executor_test.go | 12 +- state/transition_test.go | 2 +- tests/state_test_util.go | 9 +- txpool/queue_priced_test.go | 101 ++-- txpool/txpool.go | 8 +- txpool/txpool_test.go | 520 +++++++++++---------- types/access_list_tx.go | 275 ++++++++++- types/dynamic_fee_tx.go | 372 +++++++++++++++ types/legacy_tx.go | 263 +++++++++++ types/mixed_tx.go | 2 +- types/receipt.go | 2 +- types/rlp_encoding_test.go | 76 +-- types/rlp_marshal.go | 117 +---- types/rlp_marshal_storage.go | 4 +- types/rlp_unmarshal.go | 354 +------------- types/rlp_unmarshal_storage.go | 31 +- types/state_tx.go | 277 +++++++++++ types/transaction.go | 137 ++---- types/types_test.go | 3 +- 50 files changed, 1822 insertions(+), 1133 deletions(-) create mode 100644 types/dynamic_fee_tx.go create mode 100644 types/legacy_tx.go create mode 100644 types/state_tx.go diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index e9749db955..75f6e91d17 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -1020,7 +1020,7 @@ func (b *Blockchain) ReadTxLookup(hash types.Hash) (types.Hash, bool) { // return error if the invalid signature found func (b *Blockchain) recoverFromFieldsInBlock(block *types.Block) error { for _, tx := range block.Transactions { - if tx.From() != types.ZeroAddress || tx.Type() == types.StateTx { + if tx.From() != types.ZeroAddress || tx.Type() == types.StateTxType { continue } @@ -1041,7 +1041,7 @@ func (b *Blockchain) recoverFromFieldsInTransactions(transactions []*types.Trans updated := false for _, tx := range transactions { - if tx.From() != types.ZeroAddress || tx.Type() == types.StateTx { + if tx.From() != types.ZeroAddress || tx.Type() == types.StateTxType { continue } diff --git a/blockchain/blockchain_test.go b/blockchain/blockchain_test.go index 567e605944..4c67d0effe 100644 --- a/blockchain/blockchain_test.go +++ b/blockchain/blockchain_test.go @@ -590,7 +590,7 @@ func TestBlockchainWriteBody(t *testing.T) { t.Run("should succeed if tx has from field", func(t *testing.T) { t.Parallel() - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.StateTx{ Value: big.NewInt(10), V: big.NewInt(1), From: addr, @@ -622,7 +622,7 @@ func TestBlockchainWriteBody(t *testing.T) { t.Run("should return error if tx doesn't have from and recovering address fails", func(t *testing.T) { t.Parallel() - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.LegacyTx{ Value: big.NewInt(10), V: big.NewInt(1), }) @@ -654,7 +654,7 @@ func TestBlockchainWriteBody(t *testing.T) { t.Run("should recover from address and store to storage", func(t *testing.T) { t.Parallel() - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.StateTx{ Value: big.NewInt(10), V: big.NewInt(1), }) @@ -715,8 +715,8 @@ func Test_recoverFromFieldsInBlock(t *testing.T) { }, } - tx1 := types.NewTx(&types.MixedTxn{Nonce: 0, From: addr1}) - tx2 := types.NewTx(&types.MixedTxn{Nonce: 1, From: types.ZeroAddress}) + tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: addr1}) + tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: types.ZeroAddress}) computeTxHashes(tx1, tx2) @@ -745,9 +745,9 @@ func Test_recoverFromFieldsInBlock(t *testing.T) { }, } - tx1 := types.NewTx(&types.MixedTxn{Nonce: 0, From: types.ZeroAddress}) - tx2 := types.NewTx(&types.MixedTxn{Nonce: 1, From: types.ZeroAddress}) - tx3 := types.NewTx(&types.MixedTxn{Nonce: 2, From: types.ZeroAddress}) + tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: types.ZeroAddress}) + tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: types.ZeroAddress}) + tx3 := types.NewTx(&types.StateTx{Nonce: 2, From: types.ZeroAddress}) computeTxHashes(tx1, tx2, tx3) @@ -801,8 +801,8 @@ func Test_recoverFromFieldsInTransactions(t *testing.T) { }, } - tx1 := types.NewTx(&types.MixedTxn{Nonce: 0, From: addr1}) - tx2 := types.NewTx(&types.MixedTxn{Nonce: 1, From: types.ZeroAddress}) + tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: addr1}) + tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: types.ZeroAddress}) computeTxHashes(tx1, tx2) @@ -830,9 +830,9 @@ func Test_recoverFromFieldsInTransactions(t *testing.T) { }, } - tx1 := types.NewTx(&types.MixedTxn{Nonce: 0, From: types.ZeroAddress}) - tx2 := types.NewTx(&types.MixedTxn{Nonce: 1, From: types.ZeroAddress}) - tx3 := types.NewTx(&types.MixedTxn{Nonce: 2, From: types.ZeroAddress}) + tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: types.ZeroAddress}) + tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: types.ZeroAddress}) + tx3 := types.NewTx(&types.StateTx{Nonce: 2, From: types.ZeroAddress}) computeTxHashes(tx1, tx2, tx3) @@ -864,8 +864,8 @@ func Test_recoverFromFieldsInTransactions(t *testing.T) { }, } - tx1 := types.NewTx(&types.MixedTxn{Nonce: 0, From: addr1}) - tx2 := types.NewTx(&types.MixedTxn{Nonce: 1, From: addr2}) + tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: addr1}) + tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: addr2}) computeTxHashes(tx1, tx2) @@ -900,7 +900,7 @@ func TestBlockchainReadBody(t *testing.T) { batchWriter := storage.NewBatchWriter(b.db) - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.StateTx{ Value: big.NewInt(10), V: big.NewInt(1), }) @@ -1602,7 +1602,7 @@ func TestBlockchain_WriteFullBlock(t *testing.T) { {GasUsed: 100}, {GasUsed: 200}, } - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.StateTx{ Value: big.NewInt(1), }) @@ -1868,7 +1868,31 @@ func customJSONBlockUnmarshall(tb testing.TB, jsonData []byte) (*types.FullBlock for _, transactionJSON := range transactionsJSON { tr := transactionJSON.(map[string]interface{}) - transaction := types.NewTx(&types.MixedTxn{}) + + var txData types.TxData + txType := tr["type"].(string) + + txTypeNumber, err := common.ParseUint64orHex(&txType) + if err != nil { + return nil, err + } + + switch types.TxType(txTypeNumber) { + case types.AccessListTxType: + txData = &types.AccessListTxn{} + case types.StateTxType: + txData = &types.DynamicFeeTx{} + case types.LegacyTxType: + txData = &types.LegacyTx{} + default: + txData = &types.DynamicFeeTx{} + } + + if txData == nil { + continue + } + + transaction := types.NewTx(&types.StateTx{}) transaction.SetHash(types.StringToHash(tr["hash"].(string))) nonce := tr["nonce"].(string) @@ -1935,15 +1959,6 @@ func customJSONBlockUnmarshall(tb testing.TB, jsonData []byte) (*types.FullBlock transaction.SetChainID(chainIDNumber) - txType := tr["type"].(string) - - txTypeNumber, err := common.ParseUint64orHex(&txType) - if err != nil { - return nil, err - } - - transaction.SetTransactionType(types.TxType(txTypeNumber)) - gasFeeCapGeneric, ok := tr["maxFeePerGas"] if ok { gasFeeCap := gasFeeCapGeneric.(string) diff --git a/blockchain/storage/leveldb/leveldb_test.go b/blockchain/storage/leveldb/leveldb_test.go index 21136e69a7..db07be640e 100644 --- a/blockchain/storage/leveldb/leveldb_test.go +++ b/blockchain/storage/leveldb/leveldb_test.go @@ -54,13 +54,11 @@ func generateTxs(t *testing.T, startNonce, count int, from types.Address, to *ty txs := make([]*types.Transaction, count) for i := range txs { - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.DynamicFeeTx{ Gas: types.StateTransactionGasLimit, Nonce: uint64(startNonce + i), - From: from, To: to, Value: big.NewInt(2000), - Type: types.DynamicFeeTx, GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(10), }) @@ -112,7 +110,7 @@ func generateBlock(t *testing.T, num uint64) *types.FullBlock { b.Receipts[i] = &types.Receipt{ TxHash: b.Block.Transactions[i].Hash(), Root: types.StringToHash("mockhashstring"), - TransactionType: types.LegacyTx, + TransactionType: types.LegacyTxType, GasUsed: uint64(100000), Status: &status, Logs: logs, diff --git a/blockchain/storage/testing.go b/blockchain/storage/testing.go index c947251a55..34964a3780 100644 --- a/blockchain/storage/testing.go +++ b/blockchain/storage/testing.go @@ -270,7 +270,7 @@ func testBody(t *testing.T, m PlaceholderStorage) { require.NoError(t, batch.WriteBatch()) addr1 := types.StringToAddress("11") - t0 := types.NewTx(&types.MixedTxn{ + t0 := types.NewTx(&types.LegacyTx{ Nonce: 0, To: &addr1, Value: big.NewInt(1), @@ -282,7 +282,7 @@ func testBody(t *testing.T, m PlaceholderStorage) { t0.ComputeHash() addr2 := types.StringToAddress("22") - t1 := types.NewTx(&types.MixedTxn{ + t1 := types.NewTx(&types.LegacyTx{ Nonce: 0, To: &addr2, Value: big.NewInt(1), @@ -338,7 +338,7 @@ func testReceipts(t *testing.T, m PlaceholderStorage) { body := &types.Body{ Transactions: []*types.Transaction{ - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.StateTx{ Nonce: 1000, Gas: 50, GasPrice: new(big.Int).SetUint64(100), diff --git a/consensus/polybft/block_builder_test.go b/consensus/polybft/block_builder_test.go index bce6cbb733..d2d098ede1 100644 --- a/consensus/polybft/block_builder_test.go +++ b/consensus/polybft/block_builder_test.go @@ -93,7 +93,7 @@ func TestBlockBuilder_BuildBlockTxOneFailedTxAndOneTakesTooMuchGas(t *testing.T) gas = blockGasLimit - 1 } - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.LegacyTx{ Value: big.NewInt(amount), GasPrice: big.NewInt(gasPrice), Gas: gas, diff --git a/consensus/polybft/fsm.go b/consensus/polybft/fsm.go index ca1e81691f..b28e012947 100644 --- a/consensus/polybft/fsm.go +++ b/consensus/polybft/fsm.go @@ -433,7 +433,7 @@ func (f *fsm) VerifyStateTransactions(transactions []*types.Transaction) error { ) for _, tx := range transactions { - if tx.Type() != types.StateTx { + if tx.Type() != types.StateTxType { continue } @@ -716,10 +716,9 @@ func validateHeaderFields(parent *types.Header, header *types.Header, blockTimeD // createStateTransactionWithData creates a state transaction // with provided target address and inputData parameter which is ABI encoded byte array. func createStateTransactionWithData(target types.Address, inputData []byte) *types.Transaction { - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.StateTx{ From: contracts.SystemCaller, To: &target, - Type: types.StateTx, Input: inputData, Gas: types.StateTransactionGasLimit, GasPrice: big.NewInt(0), diff --git a/consensus/polybft/fsm_test.go b/consensus/polybft/fsm_test.go index e65b53f4b5..b126ae74e0 100644 --- a/consensus/polybft/fsm_test.go +++ b/consensus/polybft/fsm_test.go @@ -100,11 +100,10 @@ func TestFSM_verifyCommitEpochTx(t *testing.T) { assert.NoError(t, fsm.verifyCommitEpochTx(commitEpochTx)) // submit tampered commit epoch transaction to the epoch ending block - alteredCommitEpochTx := types.NewTx(&types.MixedTxn{ + alteredCommitEpochTx := types.NewTx(&types.StateTx{ To: &contracts.EpochManagerContract, Input: []byte{}, Gas: 0, - Type: types.StateTx, }) assert.ErrorContains(t, fsm.verifyCommitEpochTx(alteredCommitEpochTx), "invalid commit epoch transaction") diff --git a/consensus/polybft/polybft.go b/consensus/polybft/polybft.go index 9c61613ecb..a9f2d5328d 100644 --- a/consensus/polybft/polybft.go +++ b/consensus/polybft/polybft.go @@ -781,7 +781,7 @@ func (p *Polybft) PreCommitState(block *types.Block, _ *state.Transition) error // validate commitment state transactions for _, tx := range block.Transactions { - if tx.Type() != types.StateTx { + if tx.Type() != types.StateTxType { continue } diff --git a/consensus/polybft/state_sync_commitment.go b/consensus/polybft/state_sync_commitment.go index f352789c0b..dd1ade9d89 100644 --- a/consensus/polybft/state_sync_commitment.go +++ b/consensus/polybft/state_sync_commitment.go @@ -165,7 +165,7 @@ func getCommitmentMessageSignedTx(txs []*types.Transaction) (*CommitmentMessageS var commitFn contractsapi.CommitStateReceiverFn for _, tx := range txs { // skip non state CommitmentMessageSigned transactions - if tx.Type() != types.StateTx || + if tx.Type() != types.StateTxType || len(tx.Input()) < abiMethodIDLength || !bytes.Equal(tx.Input()[:abiMethodIDLength], commitFn.Sig()) { continue diff --git a/crypto/txsigner.go b/crypto/txsigner.go index 530bca94ad..55aed47392 100644 --- a/crypto/txsigner.go +++ b/crypto/txsigner.go @@ -97,7 +97,7 @@ func calcTxHash(tx *types.Transaction, chainID uint64) types.Hash { var hash []byte switch tx.Type() { - case types.AccessListTx: + case types.AccessListTxType: a := signerPool.Get() v := a.NewArray() @@ -141,9 +141,9 @@ func calcTxHash(tx *types.Transaction, chainID uint64) types.Hash { return types.BytesToHash(hash) - case types.DynamicFeeTx, types.LegacyTx, types.StateTx: + case types.DynamicFeeTxType, types.LegacyTxType, types.StateTxType: a := signerPool.Get() - isDynamicFeeTx := tx.Type() == types.DynamicFeeTx + isDynamicFeeTx := tx.Type() == types.DynamicFeeTxType v := a.NewArray() diff --git a/crypto/txsigner_eip155_test.go b/crypto/txsigner_eip155_test.go index 86769d6c7d..ce6c0752a1 100644 --- a/crypto/txsigner_eip155_test.go +++ b/crypto/txsigner_eip155_test.go @@ -70,7 +70,7 @@ func TestEIP155Signer_Sender(t *testing.T) { t.Fatalf("Unable to generate key") } - txn := types.NewTx(&types.MixedTxn{ + txn := types.NewTx(&types.LegacyTx{ To: &toAddress, Value: big.NewInt(1), GasPrice: big.NewInt(0), @@ -106,7 +106,7 @@ func TestEIP155Signer_ChainIDMismatch(t *testing.T) { t.Fatalf("Unable to generate key") } - txn := types.NewTx(&types.MixedTxn{ + txn := types.NewTx(&types.LegacyTx{ To: &toAddress, Value: big.NewInt(1), GasPrice: big.NewInt(0), diff --git a/crypto/txsigner_frontier_test.go b/crypto/txsigner_frontier_test.go index aab7ffe3f6..6a82785734 100644 --- a/crypto/txsigner_frontier_test.go +++ b/crypto/txsigner_frontier_test.go @@ -15,7 +15,7 @@ func TestFrontierSigner(t *testing.T) { key, err := GenerateECDSAKey() assert.NoError(t, err) - txn := types.NewTx(&types.MixedTxn{ + txn := types.NewTx(&types.LegacyTx{ To: &toAddress, Value: big.NewInt(10), GasPrice: big.NewInt(0), diff --git a/crypto/txsigner_london_berlin.go b/crypto/txsigner_london_berlin.go index 29f9d21e70..a8030d334d 100644 --- a/crypto/txsigner_london_berlin.go +++ b/crypto/txsigner_london_berlin.go @@ -34,7 +34,7 @@ func (e *LondonOrBerlinSigner) Hash(tx *types.Transaction) types.Hash { // Sender returns the transaction sender func (e *LondonOrBerlinSigner) Sender(tx *types.Transaction) (types.Address, error) { - if tx.Type() != types.DynamicFeeTx && tx.Type() != types.AccessListTx { + if tx.Type() != types.DynamicFeeTxType && tx.Type() != types.AccessListTxType { return e.fallbackSigner.Sender(tx) } @@ -45,7 +45,7 @@ func (e *LondonOrBerlinSigner) Sender(tx *types.Transaction) (types.Address, err // SignTx signs the transaction using the passed in private key func (e *LondonOrBerlinSigner) SignTx(tx *types.Transaction, pk *ecdsa.PrivateKey) (*types.Transaction, error) { - if tx.Type() != types.DynamicFeeTx && tx.Type() != types.AccessListTx { + if tx.Type() != types.DynamicFeeTxType && tx.Type() != types.AccessListTxType { return e.fallbackSigner.SignTx(tx, pk) } diff --git a/crypto/txsigner_london_berlin_test.go b/crypto/txsigner_london_berlin_test.go index a1c989ce80..617cc351ee 100644 --- a/crypto/txsigner_london_berlin_test.go +++ b/crypto/txsigner_london_berlin_test.go @@ -23,42 +23,42 @@ func TestLondonSignerSender(t *testing.T) { { "mainnet", big.NewInt(1), - types.LegacyTx, + types.LegacyTxType, }, { "expanse mainnet", big.NewInt(2), - types.DynamicFeeTx, + types.DynamicFeeTxType, }, { "ropsten", big.NewInt(3), - types.DynamicFeeTx, + types.DynamicFeeTxType, }, { "rinkeby", big.NewInt(4), - types.AccessListTx, + types.AccessListTxType, }, { "goerli", big.NewInt(5), - types.AccessListTx, + types.AccessListTxType, }, { "kovan", big.NewInt(42), - types.StateTx, + types.StateTxType, }, { "geth private", big.NewInt(1337), - types.StateTx, + types.StateTxType, }, { "mega large", big.NewInt(0).Exp(big.NewInt(2), big.NewInt(20), nil), // 2**20 - types.AccessListTx, + types.AccessListTxType, }, } @@ -73,18 +73,29 @@ func TestLondonSignerSender(t *testing.T) { var txn *types.Transaction switch tc.txType { - case types.AccessListTx: + case types.AccessListTxType: txn = types.NewTx(&types.AccessListTxn{ To: &recipient, Value: big.NewInt(1), GasPrice: big.NewInt(5), }) - case types.DynamicFeeTx, types.LegacyTx, types.StateTx: - txn = types.NewTx(&types.MixedTxn{ + case types.LegacyTxType: + txn = types.NewTx(&types.LegacyTx{ To: &recipient, Value: big.NewInt(1), GasPrice: big.NewInt(5), }) + case types.StateTxType: + txn = types.NewTx(&types.StateTx{ + To: &recipient, + Value: big.NewInt(1), + GasPrice: big.NewInt(5), + }) + case types.DynamicFeeTxType: + txn = types.NewTx(&types.DynamicFeeTx{ + To: &recipient, + Value: big.NewInt(1), + }) } chainID := tc.chainID.Uint64() @@ -120,9 +131,7 @@ func Test_LondonSigner_Sender(t *testing.T) { }{ { name: "sender is 0x85dA99c8a7C2C95964c8EfD687E95E632Fc533D6", - tx: types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, - GasPrice: big.NewInt(1000000402), + tx: types.NewTx(&types.DynamicFeeTx{ GasTipCap: ethgo.Gwei(1), GasFeeCap: ethgo.Gwei(10), Gas: 21000, diff --git a/e2e/framework/testserver.go b/e2e/framework/testserver.go index 3419115ce6..55f5971cbd 100644 --- a/e2e/framework/testserver.go +++ b/e2e/framework/testserver.go @@ -520,7 +520,7 @@ func (t *TestServer) SendRawTx( return nil, err } - signedTx, err := t.SignTx(types.NewTx(&types.MixedTxn{ + signedTx, err := t.SignTx(types.NewTx(&types.StateTx{ From: tx.From, GasPrice: tx.GasPrice, Gas: tx.Gas, diff --git a/e2e/txpool_test.go b/e2e/txpool_test.go index 240e13645f..99dbd9e91c 100644 --- a/e2e/txpool_test.go +++ b/e2e/txpool_test.go @@ -42,20 +42,25 @@ type generateTxReqParams struct { } func generateTx(params generateTxReqParams) *types.Transaction { - unsignedTx := types.NewTx(&types.MixedTxn{ - Nonce: params.nonce, - From: params.referenceAddr, - To: ¶ms.toAddress, - Gas: 1000000, - Value: params.value, - V: big.NewInt(27), // it is necessary to encode in rlp - }) + var unsignedTx *types.Transaction if params.gasPrice != nil { - unsignedTx.SetTransactionType(types.LegacyTx) + unsignedTx = types.NewTx(&types.LegacyTx{ + Nonce: params.nonce, + To: ¶ms.toAddress, + Gas: 1000000, + Value: params.value, + V: big.NewInt(27), // it is necessary to encode in rlp + }) unsignedTx.SetGasPrice(params.gasPrice) } else { - unsignedTx.SetTransactionType(types.DynamicFeeTx) + unsignedTx = types.NewTx(&types.DynamicFeeTx{ + Nonce: params.nonce, + To: ¶ms.toAddress, + Gas: 1000000, + Value: params.value, + V: big.NewInt(27), // it is necessary to encode in rlp + }) unsignedTx.SetGasFeeCap(params.gasFeeCap) unsignedTx.SetGasTipCap(params.gasTipCap) } @@ -236,7 +241,7 @@ func TestTxPool_RecoverableError(t *testing.T) { _, receiverAddress := tests.GenerateKeyAndAddr(t) transactions := []*types.Transaction{ - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.StateTx{ Nonce: 0, GasPrice: big.NewInt(framework.DefaultGasPrice), Gas: 22000, @@ -245,17 +250,15 @@ func TestTxPool_RecoverableError(t *testing.T) { V: big.NewInt(27), From: senderAddress, }), - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.LegacyTx{ Nonce: 1, GasPrice: big.NewInt(framework.DefaultGasPrice), Gas: 22000, To: &receiverAddress, Value: oneEth, V: big.NewInt(27), - From: senderAddress, }), - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + types.NewTx(&types.DynamicFeeTx{ Nonce: 2, GasFeeCap: big.NewInt(framework.DefaultGasPrice), GasTipCap: big.NewInt(1000000000), @@ -263,7 +266,6 @@ func TestTxPool_RecoverableError(t *testing.T) { To: &receiverAddress, Value: oneEth, V: big.NewInt(27), - From: senderAddress, }), } @@ -346,7 +348,7 @@ func TestTxPool_GetPendingTx(t *testing.T) { operator := server.TxnPoolOperator() client := server.JSONRPC() - signedTx, err := signer.SignTx(types.NewTx(&types.MixedTxn{ + signedTx, err := signer.SignTx(types.NewTx(&types.StateTx{ Nonce: 0, GasPrice: big.NewInt(1000000000), Gas: framework.DefaultGasLimit - 1, diff --git a/gasprice/feehistory_test.go b/gasprice/feehistory_test.go index debd24a4e7..dd2b121e13 100644 --- a/gasprice/feehistory_test.go +++ b/gasprice/feehistory_test.go @@ -194,11 +194,9 @@ func TestGasHelper_FeeHistory(t *testing.T) { b.Header.Miner = sender.Bytes() for i := 0; i < 3; i++ { - tx := types.NewTx(&types.MixedTxn{ - From: sender, + tx := types.NewTx(&types.DynamicFeeTx{ Value: ethgo.Ether(1), To: &types.ZeroAddress, - Type: types.DynamicFeeTx, GasTipCap: ethgo.Gwei(uint64(200)), GasFeeCap: ethgo.Gwei(uint64(200 + 200)), }) diff --git a/gasprice/gasprice_test.go b/gasprice/gasprice_test.go index c5df080fd0..a148f2ccad 100644 --- a/gasprice/gasprice_test.go +++ b/gasprice/gasprice_test.go @@ -84,11 +84,10 @@ func TestGasHelper_MaxPriorityFeePerGas(t *testing.T) { b.Header.Miner = sender.Bytes() for i := 0; i < 3; i++ { - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.DynamicFeeTx{ From: sender, Value: ethgo.Ether(1), To: &types.ZeroAddress, - Type: types.DynamicFeeTx, GasTipCap: ethgo.Gwei(uint64(rand.Intn(200))), GasFeeCap: ethgo.Gwei(uint64(rand.Intn(200) + 200)), }) @@ -219,11 +218,10 @@ func createTestTxs(t *testing.T, backend *backendMock, numOfTxsPerBlock, txCap i for i := 0; i < numOfTxsPerBlock; i++ { senderKey, sender := tests.GenerateKeyAndAddr(t) - tx := types.NewTx(&types.MixedTxn{ + tx := types.NewTx(&types.DynamicFeeTx{ From: sender, Value: ethgo.Ether(1), To: &types.ZeroAddress, - Type: types.DynamicFeeTx, GasTipCap: ethgo.Gwei(uint64(rand.Intn(txCap))), GasFeeCap: ethgo.Gwei(uint64(rand.Intn(txCap) + txCap)), }) diff --git a/helper/tests/testing.go b/helper/tests/testing.go index e7ceb0c8a5..96a6ac49be 100644 --- a/helper/tests/testing.go +++ b/helper/tests/testing.go @@ -238,7 +238,7 @@ type GenerateTxReqParams struct { func generateTx(params GenerateTxReqParams) (*types.Transaction, error) { signer := crypto.NewEIP155Signer(100, true) - signedTx, signErr := signer.SignTx(types.NewTx(&types.MixedTxn{ + signedTx, signErr := signer.SignTx(types.NewTx(&types.LegacyTx{ Nonce: params.Nonce, From: params.ReferenceAddr, To: ¶ms.ToAddress, diff --git a/jsonrpc/debug_endpoint_test.go b/jsonrpc/debug_endpoint_test.go index f6e9d1603d..905e92c375 100644 --- a/jsonrpc/debug_endpoint_test.go +++ b/jsonrpc/debug_endpoint_test.go @@ -604,9 +604,8 @@ func TestTraceCall(t *testing.T) { Input: &input, Nonce: &nonce, } - decodedTx = types.NewTx(&types.MixedTxn{ + decodedTx = types.NewTx(&types.DynamicFeeTx{ Nonce: uint64(nonce), - GasPrice: new(big.Int).SetBytes([]byte(gasPrice)), GasTipCap: new(big.Int).SetBytes([]byte(gasTipCap)), GasFeeCap: new(big.Int).SetBytes([]byte(gasFeeCap)), Gas: uint64(gas), diff --git a/jsonrpc/eth_blockchain_test.go b/jsonrpc/eth_blockchain_test.go index 807a0eaf6b..0ddfb86d6b 100644 --- a/jsonrpc/eth_blockchain_test.go +++ b/jsonrpc/eth_blockchain_test.go @@ -89,7 +89,7 @@ func TestEth_Block_GetBlockTransactionCountByNumber(t *testing.T) { for i := 0; i < 10; i++ { block.Transactions = append(block.Transactions, []*types.Transaction{ - types.NewTx(&types.MixedTxn{Nonce: 0, From: addr0})}...) + types.NewTx(&types.LegacyTx{Nonce: 0, From: addr0})}...) } store.add(block) diff --git a/jsonrpc/eth_endpoint.go b/jsonrpc/eth_endpoint.go index 5ca84c79d2..ca90e8455a 100644 --- a/jsonrpc/eth_endpoint.go +++ b/jsonrpc/eth_endpoint.go @@ -408,7 +408,7 @@ func (e *Eth) fillTransactionGasPrice(tx *types.Transaction) error { return err } - if tx.Type() == types.DynamicFeeTx { + if tx.Type() == types.DynamicFeeTxType { tx.SetGasFeeCap(new(big.Int).SetUint64(estimatedGasPrice)) } else { tx.SetGasPrice(new(big.Int).SetUint64(estimatedGasPrice)) diff --git a/jsonrpc/eth_endpoint_test.go b/jsonrpc/eth_endpoint_test.go index 98e3eba23b..757af949b7 100644 --- a/jsonrpc/eth_endpoint_test.go +++ b/jsonrpc/eth_endpoint_test.go @@ -39,18 +39,16 @@ func TestEth_DecodeTxn(t *testing.T) { From: &addr1, To: &addr2, Gas: toArgUint64Ptr(21000), - GasPrice: toArgBytesPtr(big.NewInt(10000).Bytes()), GasTipCap: toArgBytesPtr(big.NewInt(10000).Bytes()), GasFeeCap: toArgBytesPtr(big.NewInt(10000).Bytes()), Value: toArgBytesPtr(oneEther.Bytes()), Data: nil, Nonce: toArgUint64Ptr(0), }, - res: types.NewTx(&types.MixedTxn{ + res: types.NewTx(&types.DynamicFeeTx{ From: addr1, To: &addr2, Gas: 21000, - GasPrice: big.NewInt(10000), GasTipCap: big.NewInt(10000), GasFeeCap: big.NewInt(10000), Value: oneEther, @@ -68,11 +66,10 @@ func TestEth_DecodeTxn(t *testing.T) { Value: toArgBytesPtr(oneEther.Bytes()), Data: nil, }, - res: types.NewTx(&types.MixedTxn{ + res: types.NewTx(&types.DynamicFeeTx{ From: types.ZeroAddress, To: &addr2, Gas: 21000, - GasPrice: big.NewInt(10000), GasTipCap: new(big.Int), GasFeeCap: new(big.Int), Value: oneEther, @@ -96,16 +93,14 @@ func TestEth_DecodeTxn(t *testing.T) { Value: toArgBytesPtr(oneEther.Bytes()), Data: nil, }, - res: types.NewTx(&types.MixedTxn{ - From: addr1, - To: &addr2, - Gas: 21000, - GasPrice: big.NewInt(10000), - GasTipCap: new(big.Int), - GasFeeCap: new(big.Int), - Value: oneEther, - Input: []byte{}, - Nonce: 10, + res: types.NewTx(&types.LegacyTx{ + From: addr1, + To: &addr2, + Gas: 21000, + GasPrice: big.NewInt(10000), + Value: oneEther, + Input: []byte{}, + Nonce: 10, }), err: nil, }, @@ -119,16 +114,14 @@ func TestEth_DecodeTxn(t *testing.T) { Data: nil, Nonce: toArgUint64Ptr(1), }, - res: types.NewTx(&types.MixedTxn{ - From: addr1, - To: &addr2, - Gas: 21000, - GasPrice: big.NewInt(10000), - GasTipCap: new(big.Int), - GasFeeCap: new(big.Int), - Value: new(big.Int).SetBytes([]byte{}), - Input: []byte{}, - Nonce: 1, + res: types.NewTx(&types.LegacyTx{ + From: addr1, + To: &addr2, + Gas: 21000, + GasPrice: big.NewInt(10000), + Value: new(big.Int).SetBytes([]byte{}), + Input: []byte{}, + Nonce: 1, }), err: nil, }, @@ -141,16 +134,14 @@ func TestEth_DecodeTxn(t *testing.T) { Data: nil, Nonce: toArgUint64Ptr(1), }, - res: types.NewTx(&types.MixedTxn{ - From: addr1, - To: &addr2, - Gas: 0, - GasPrice: big.NewInt(10000), - GasTipCap: new(big.Int), - GasFeeCap: new(big.Int), - Value: new(big.Int).SetBytes([]byte{}), - Input: []byte{}, - Nonce: 1, + res: types.NewTx(&types.LegacyTx{ + From: addr1, + To: &addr2, + Gas: 0, + GasPrice: big.NewInt(10000), + Value: new(big.Int).SetBytes([]byte{}), + Input: []byte{}, + Nonce: 1, }), err: nil, }, @@ -275,20 +266,18 @@ func TestEth_TxnType(t *testing.T) { Value: toArgBytesPtr(oneEther.Bytes()), Data: nil, Nonce: toArgUint64Ptr(0), - Type: toArgUint64Ptr(uint64(types.DynamicFeeTx)), + Type: toArgUint64Ptr(uint64(types.DynamicFeeTxType)), } - expectedRes := types.NewTx(&types.MixedTxn{ + expectedRes := types.NewTx(&types.DynamicFeeTx{ From: addr1, To: &addr2, Gas: 21000, - GasPrice: big.NewInt(10000), GasTipCap: big.NewInt(10000), GasFeeCap: big.NewInt(10000), Value: oneEther, Input: []byte{}, Nonce: 0, - Type: types.DynamicFeeTx, }) res, err := DecodeTxn(args, 1, store, false) diff --git a/jsonrpc/eth_txpool_test.go b/jsonrpc/eth_txpool_test.go index eb3cf9e252..4eab2931df 100644 --- a/jsonrpc/eth_txpool_test.go +++ b/jsonrpc/eth_txpool_test.go @@ -11,7 +11,7 @@ import ( func TestEth_TxnPool_SendRawTransaction(t *testing.T) { store := &mockStoreTxn{} eth := newTestEthEndpoint(store) - txn := types.NewTx(&types.MixedTxn{ + txn := types.NewTx(&types.LegacyTx{ From: addr0, V: big.NewInt(1), }) @@ -32,7 +32,7 @@ func TestEth_TxnPool_SendTransaction(t *testing.T) { store := &mockStoreTxn{} store.AddAccount(addr0) eth := newTestEthEndpoint(store) - txToSend := types.NewTx(&types.MixedTxn{ + txToSend := types.NewTx(&types.LegacyTx{ From: addr0, To: argAddrPtr(addr0), Nonce: uint64(0), diff --git a/jsonrpc/filter_manager_fuzz_test.go b/jsonrpc/filter_manager_fuzz_test.go index bb52cd1472..4637a8d874 100644 --- a/jsonrpc/filter_manager_fuzz_test.go +++ b/jsonrpc/filter_manager_fuzz_test.go @@ -34,17 +34,17 @@ func FuzzGetLogsForQuery(f *testing.F) { }, Transactions: []*types.Transaction{ { - Inner: &types.MixedTxn{ + Inner: &types.LegacyTx{ Value: big.NewInt(10), }, }, { - Inner: &types.MixedTxn{ + Inner: &types.LegacyTx{ Value: big.NewInt(11), }, }, { - Inner: &types.MixedTxn{ + Inner: &types.LegacyTx{ Value: big.NewInt(12), }, }, diff --git a/jsonrpc/filter_manager_test.go b/jsonrpc/filter_manager_test.go index 7eefb8b618..c1217dd4f0 100644 --- a/jsonrpc/filter_manager_test.go +++ b/jsonrpc/filter_manager_test.go @@ -114,9 +114,9 @@ func Test_GetLogsForQuery(t *testing.T) { Hash: types.StringToHash(strconv.Itoa(i)), }, Transactions: []*types.Transaction{ - types.NewTx(&types.MixedTxn{Value: big.NewInt(10)}), - types.NewTx(&types.MixedTxn{Value: big.NewInt(11)}), - types.NewTx(&types.MixedTxn{Value: big.NewInt(12)}), + types.NewTx(&types.LegacyTx{Value: big.NewInt(10)}), + types.NewTx(&types.LegacyTx{Value: big.NewInt(11)}), + types.NewTx(&types.LegacyTx{Value: big.NewInt(12)}), }, } } diff --git a/jsonrpc/helper.go b/jsonrpc/helper.go index 5c220d1b58..7883599c90 100644 --- a/jsonrpc/helper.go +++ b/jsonrpc/helper.go @@ -163,6 +163,8 @@ func GetNextNonce(address types.Address, number BlockNumber, store nonceGetter) } func DecodeTxn(arg *txnArgs, blockNumber uint64, store nonceGetter, forceSetNonce bool) (*types.Transaction, error) { + var txn *types.Transaction + if arg == nil { return nil, errors.New("missing value for required argument 0") } @@ -214,22 +216,47 @@ func DecodeTxn(arg *txnArgs, blockNumber uint64, store nonceGetter, forceSetNonc arg.Gas = argUintPtr(0) } - txType := types.LegacyTx + txType := types.LegacyTxType if arg.Type != nil { txType = types.TxType(*arg.Type) } - txn := types.NewTx(&types.MixedTxn{ - From: *arg.From, - Gas: uint64(*arg.Gas), - GasPrice: new(big.Int).SetBytes(*arg.GasPrice), - GasTipCap: new(big.Int).SetBytes(*arg.GasTipCap), - GasFeeCap: new(big.Int).SetBytes(*arg.GasFeeCap), - Value: new(big.Int).SetBytes(*arg.Value), - Input: input, - Nonce: uint64(*arg.Nonce), - Type: txType, - }) + switch txType { + case types.AccessListTxType: + txn = types.NewTx(&types.AccessListTxn{ + From: *arg.From, + Gas: uint64(*arg.Gas), + Value: new(big.Int).SetBytes(*arg.Value), + Input: input, + Nonce: uint64(*arg.Nonce), + }) + case types.LegacyTxType: + txn = types.NewTx(&types.LegacyTx{ + From: *arg.From, + Gas: uint64(*arg.Gas), + Value: new(big.Int).SetBytes(*arg.Value), + Input: input, + Nonce: uint64(*arg.Nonce), + }) + case types.StateTxType: + txn = types.NewTx(&types.StateTx{ + From: *arg.From, + Gas: uint64(*arg.Gas), + Value: new(big.Int).SetBytes(*arg.Value), + Input: input, + Nonce: uint64(*arg.Nonce), + }) + case types.DynamicFeeTxType: + txn = types.NewTx(&types.DynamicFeeTx{ + From: *arg.From, + Gas: uint64(*arg.Gas), + GasTipCap: new(big.Int).SetBytes(*arg.GasTipCap), + GasFeeCap: new(big.Int).SetBytes(*arg.GasFeeCap), + Value: new(big.Int).SetBytes(*arg.Value), + Input: input, + Nonce: uint64(*arg.Nonce), + }) + } if arg.To != nil { txn.SetTo(arg.To) diff --git a/jsonrpc/helper_test.go b/jsonrpc/helper_test.go index c63af1a47a..86ae99880e 100644 --- a/jsonrpc/helper_test.go +++ b/jsonrpc/helper_test.go @@ -14,7 +14,7 @@ import ( func createTestTransaction(hash types.Hash) *types.Transaction { recipient := types.StringToAddress("2") - return types.NewTx(&types.MixedTxn{ + return types.NewTx(&types.LegacyTx{ Hash: hash, From: types.StringToAddress("1"), To: &recipient, @@ -51,7 +51,7 @@ func createTestReceipt(logs []*types.Log, cumulativeGasUsed, gasUsed uint64, txH Logs: logs, GasUsed: gasUsed, TxHash: txHash, - TransactionType: types.DynamicFeeTx, + TransactionType: types.DynamicFeeTxType, } } @@ -707,11 +707,10 @@ func TestDecodeTxn(t *testing.T) { Nonce: &nonce, }, store: &debugEndpointMockStore{}, - expected: types.NewTx(&types.MixedTxn{ + expected: types.NewTx(&types.DynamicFeeTx{ From: from, To: &to, Gas: uint64(gas), - GasPrice: new(big.Int).SetBytes([]byte(gasPrice)), GasTipCap: new(big.Int).SetBytes([]byte(gasTipCap)), GasFeeCap: new(big.Int).SetBytes([]byte(gasFeeCap)), Value: new(big.Int).SetBytes([]byte(value)), @@ -731,11 +730,10 @@ func TestDecodeTxn(t *testing.T) { Nonce: &nonce, }, store: &debugEndpointMockStore{}, - expected: types.NewTx(&types.MixedTxn{ + expected: types.NewTx(&types.DynamicFeeTx{ From: types.ZeroAddress, To: &to, Gas: uint64(gas), - GasPrice: new(big.Int).SetBytes([]byte(gasPrice)), GasTipCap: new(big.Int), GasFeeCap: new(big.Int), Value: new(big.Int).SetBytes([]byte(value)), @@ -766,11 +764,10 @@ func TestDecodeTxn(t *testing.T) { }, nil }, }, - expected: types.NewTx(&types.MixedTxn{ + expected: types.NewTx(&types.DynamicFeeTx{ From: from, To: &to, Gas: uint64(gas), - GasPrice: new(big.Int).SetBytes([]byte(gasPrice)), GasTipCap: new(big.Int), GasFeeCap: new(big.Int), Value: new(big.Int).SetBytes([]byte(value)), @@ -792,11 +789,10 @@ func TestDecodeTxn(t *testing.T) { Nonce: &nonce, }, store: &debugEndpointMockStore{}, - expected: types.NewTx(&types.MixedTxn{ + expected: types.NewTx(&types.DynamicFeeTx{ From: from, To: &to, Gas: uint64(gas), - GasPrice: new(big.Int).SetBytes([]byte(gasPrice)), GasTipCap: new(big.Int), GasFeeCap: new(big.Int), Value: new(big.Int).SetBytes([]byte(value)), @@ -813,11 +809,10 @@ func TestDecodeTxn(t *testing.T) { Nonce: &nonce, }, store: &debugEndpointMockStore{}, - expected: types.NewTx(&types.MixedTxn{ + expected: types.NewTx(&types.DynamicFeeTx{ From: from, To: &to, Gas: uint64(0), - GasPrice: new(big.Int), GasTipCap: new(big.Int), GasFeeCap: new(big.Int), Value: new(big.Int), diff --git a/jsonrpc/txpool_endpoint_test.go b/jsonrpc/txpool_endpoint_test.go index 5d892f4249..6dba9f203e 100644 --- a/jsonrpc/txpool_endpoint_test.go +++ b/jsonrpc/txpool_endpoint_test.go @@ -60,7 +60,7 @@ func TestContentEndpoint(t *testing.T) { txData = response.Pending[address1][testTx2.Nonce()] assert.NotNil(t, txData) - assert.Equal(t, (argUint64)(types.DynamicFeeTx), txData.Type) + assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) assert.Equal(t, (*argBig)(nil), txData.GasPrice) assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) @@ -109,7 +109,7 @@ func TestContentEndpoint(t *testing.T) { txData = response.Queued[address2][testTx2.Nonce()] assert.NotNil(t, txData) - assert.Equal(t, (argUint64)(types.DynamicFeeTx), txData.Type) + assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) assert.Equal(t, (*argBig)(nil), txData.GasPrice) assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) @@ -294,7 +294,7 @@ func (s *mockTxPoolStore) GetBaseFee() uint64 { } func newTestTransaction(nonce uint64, from types.Address) *types.Transaction { - txn := types.NewTx(&types.MixedTxn{ + txn := types.NewTx(&types.LegacyTx{ Nonce: nonce, GasPrice: big.NewInt(1), Gas: nonce * 100, @@ -313,8 +313,7 @@ func newTestTransaction(nonce uint64, from types.Address) *types.Transaction { } func newTestDynamicFeeTransaction(nonce uint64, from types.Address) *types.Transaction { - txn := types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + txn := types.NewTx(&types.DynamicFeeTx{ Nonce: nonce, GasTipCap: big.NewInt(2), GasFeeCap: big.NewInt(4), diff --git a/jsonrpc/types_test.go b/jsonrpc/types_test.go index b3a0f9e738..3ed10d67b2 100644 --- a/jsonrpc/types_test.go +++ b/jsonrpc/types_test.go @@ -103,7 +103,7 @@ func TestToTransaction_Returns_V_R_S_ValuesWithoutLeading0(t *testing.T) { v, _ := hex.DecodeHex(hexWithLeading0) r, _ := hex.DecodeHex(hexWithLeading0) s, _ := hex.DecodeHex(hexWithLeading0) - txn := types.NewTx(&types.MixedTxn{ + txn := types.NewTx(&types.LegacyTx{ Nonce: 0, GasPrice: big.NewInt(0), Gas: 0, @@ -134,9 +134,8 @@ func TestToTransaction_EIP1559(t *testing.T) { v, _ := hex.DecodeHex(hexWithLeading0) r, _ := hex.DecodeHex(hexWithLeading0) s, _ := hex.DecodeHex(hexWithLeading0) - txn := types.NewTx(&types.MixedTxn{ + txn := types.NewTx(&types.DynamicFeeTx{ Nonce: 0, - GasPrice: nil, GasTipCap: big.NewInt(10), GasFeeCap: big.NewInt(10), Gas: 0, @@ -251,7 +250,7 @@ func mockTxn() *transaction { BlockHash: &types.ZeroHash, BlockNumber: argUintPtr(1), TxIndex: argUintPtr(2), - Type: argUint64(types.LegacyTx), + Type: argUint64(types.LegacyTxType), } return tt @@ -288,7 +287,7 @@ func TestTransaction_Encoding(t *testing.T) { tt := mockTxn() tt.GasTipCap = &gasTipCap tt.GasFeeCap = &gasFeeCap - tt.Type = argUint64(types.DynamicFeeTx) + tt.Type = argUint64(types.DynamicFeeTxType) testTransaction("testsuite/transaction-eip1559.json", tt) }) diff --git a/state/executor.go b/state/executor.go index 362b103ad6..6331204d6a 100644 --- a/state/executor.go +++ b/state/executor.go @@ -327,7 +327,7 @@ var emptyFrom = types.Address{} // Write writes another transaction to the executor func (t *Transition) Write(txn *types.Transaction) error { - if txn.From() == emptyFrom && txn.Type() != types.StateTx { + if txn.From() == emptyFrom && txn.Type() != types.StateTxType { // Decrypt the from address signer := crypto.NewSigner(t.config, uint64(t.ctx.ChainID)) @@ -464,7 +464,7 @@ func (t *Transition) subGasLimitPrice(msg *types.Transaction) error { upfrontGasCost := new(big.Int).Mul(new(big.Int).SetUint64(msg.Gas()), msg.GetGasPrice(t.ctx.BaseFee.Uint64())) balanceCheck := new(big.Int).Set(upfrontGasCost) - if msg.Type() == types.DynamicFeeTx { + if msg.Type() == types.DynamicFeeTxType { balanceCheck.Add(balanceCheck, msg.Value()) balanceCheck.SetUint64(msg.Gas()) balanceCheck = balanceCheck.Mul(balanceCheck, msg.GasFeeCap()) @@ -510,7 +510,7 @@ func (t *Transition) checkDynamicFees(msg *types.Transaction) error { return nil } - if msg.Type() == types.DynamicFeeTx { + if msg.Type() == types.DynamicFeeTxType { if msg.GasFeeCap().BitLen() == 0 && msg.GasTipCap().BitLen() == 0 { return nil } @@ -604,7 +604,7 @@ func NewGasLimitReachedTransitionApplicationError(err error) *GasLimitReachedTra func (t *Transition) apply(msg *types.Transaction) (*runtime.ExecutionResult, error) { var err error - if msg.Type() == types.StateTx { + if msg.Type() == types.StateTxType { err = checkAndProcessStateTx(msg) } else { err = checkAndProcessTx(msg, t) @@ -702,7 +702,7 @@ func (t *Transition) apply(msg *types.Transaction) (*runtime.ExecutionResult, er // TODO - burning of base fee should not be done in the EVM // Burn some amount if the london hardfork is applied. // Basically, burn amount is just transferred to the current burn contract. - // if t.config.London && msg.Type() != types.StateTx { + // if t.config.London && msg.Type() != types.StateTxType { // burnAmount := new(big.Int).Mul(new(big.Int).SetUint64(result.GasUsed), t.ctx.BaseFee) // t.state.AddBalance(t.ctx.BurnContract, burnAmount) // } diff --git a/state/executor_test.go b/state/executor_test.go index 31428cbab5..cb04b09b2b 100644 --- a/state/executor_test.go +++ b/state/executor_test.go @@ -80,8 +80,7 @@ func Test_Transition_checkDynamicFees(t *testing.T) { { name: "happy path", baseFee: big.NewInt(100), - tx: types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + tx: types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(100), GasTipCap: big.NewInt(100), }), @@ -94,8 +93,7 @@ func Test_Transition_checkDynamicFees(t *testing.T) { { name: "happy path with empty values", baseFee: big.NewInt(0), - tx: types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + tx: types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(0), GasTipCap: big.NewInt(0), }), @@ -108,8 +106,7 @@ func Test_Transition_checkDynamicFees(t *testing.T) { { name: "gas fee cap less than base fee", baseFee: big.NewInt(20), - tx: types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + tx: types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(10), GasTipCap: big.NewInt(0), }), @@ -124,8 +121,7 @@ func Test_Transition_checkDynamicFees(t *testing.T) { { name: "gas fee cap less than tip cap", baseFee: big.NewInt(5), - tx: types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + tx: types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(10), GasTipCap: big.NewInt(15), }), diff --git a/state/transition_test.go b/state/transition_test.go index 1779d38c72..e75bbb811e 100644 --- a/state/transition_test.go +++ b/state/transition_test.go @@ -70,7 +70,7 @@ func TestSubGasLimitPrice(t *testing.T) { t.Parallel() transition := newTestTransition(tt.preState) - msg := types.NewTx(&types.MixedTxn{ + msg := types.NewTx(&types.StateTx{ From: tt.from, Gas: tt.gas, GasPrice: big.NewInt(tt.gasPrice), diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 41f1d1cc30..f425fab22b 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -348,19 +348,12 @@ func (t *stTransaction) At(i indexes, baseFee *big.Int) (*types.Transaction, err }), nil } - txType := types.LegacyTx - if isDynamiFeeTx { - txType = types.DynamicFeeTx - } - - return types.NewTx(&types.MixedTxn{ - Type: txType, + return types.NewTx(&types.DynamicFeeTx{ From: t.From, To: t.To, Nonce: t.Nonce, Value: value, Gas: t.GasLimit[i.Gas], - GasPrice: gasPrice, GasFeeCap: t.MaxFeePerGas, GasTipCap: t.MaxPriorityFeePerGas, Input: hex.MustDecodeHex(t.Data[i.Data]), diff --git a/txpool/queue_priced_test.go b/txpool/queue_priced_test.go index b619068454..855f7b24e1 100644 --- a/txpool/queue_priced_test.go +++ b/txpool/queue_priced_test.go @@ -23,43 +23,33 @@ func Test_maxPriceQueue(t *testing.T) { baseFee: 1000, unsorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, - GasPrice: big.NewInt(0), + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(500), }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ - Type: types.LegacyTx, + types.NewTx(&types.LegacyTx{ GasPrice: big.NewInt(100), }), // Middle tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, - GasPrice: big.NewInt(0), + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1500), GasTipCap: big.NewInt(200), }), }, sorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, - GasPrice: big.NewInt(0), + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(500), }), // Middle tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, - GasPrice: big.NewInt(0), + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1500), GasTipCap: big.NewInt(200), }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ - Type: types.LegacyTx, + types.NewTx(&types.LegacyTx{ GasPrice: big.NewInt(100), }), }, @@ -69,22 +59,19 @@ func Test_maxPriceQueue(t *testing.T) { baseFee: 1000, unsorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(500), Nonce: 3, }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(500), Nonce: 1, }), // Middle tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(500), Nonce: 2, @@ -92,22 +79,19 @@ func Test_maxPriceQueue(t *testing.T) { }, sorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(500), Nonce: 1, }), // Middle tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(500), Nonce: 2, }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ - Type: types.DynamicFeeTx, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(500), Nonce: 3, @@ -119,34 +103,34 @@ func Test_maxPriceQueue(t *testing.T) { baseFee: 0, unsorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(3000), GasTipCap: big.NewInt(100), }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1000), GasTipCap: big.NewInt(100), }), // Middle tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(100), }), }, sorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.DynamicFeeTx{ GasTipCap: big.NewInt(100), GasFeeCap: big.NewInt(3000), }), // Middle tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(2000), GasTipCap: big.NewInt(100), }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1000), GasTipCap: big.NewInt(100), }), @@ -157,40 +141,34 @@ func Test_maxPriceQueue(t *testing.T) { baseFee: 0, unsorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ - GasPrice: nil, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1000), GasTipCap: big.NewInt(300), }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ - GasPrice: nil, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1000), GasTipCap: big.NewInt(100), }), // Middle tx fee - types.NewTx(&types.MixedTxn{ - GasPrice: nil, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1000), GasTipCap: big.NewInt(200), }), }, sorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ - GasPrice: nil, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1000), GasTipCap: big.NewInt(300), }), // Middle tx fee - types.NewTx(&types.MixedTxn{ - GasPrice: nil, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1000), GasTipCap: big.NewInt(200), }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ - GasPrice: nil, + types.NewTx(&types.DynamicFeeTx{ GasFeeCap: big.NewInt(1000), GasTipCap: big.NewInt(100), }), @@ -201,29 +179,29 @@ func Test_maxPriceQueue(t *testing.T) { baseFee: 0, unsorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.LegacyTx{ GasPrice: big.NewInt(1000), }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.LegacyTx{ GasPrice: big.NewInt(100), }), // Middle tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.LegacyTx{ GasPrice: big.NewInt(500), }), }, sorted: []*types.Transaction{ // Highest tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.LegacyTx{ GasPrice: big.NewInt(1000), }), // Middle tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.LegacyTx{ GasPrice: big.NewInt(500), }), // Lowest tx fee - types.NewTx(&types.MixedTxn{ + types.NewTx(&types.LegacyTx{ GasPrice: big.NewInt(100), }), }, @@ -298,21 +276,24 @@ func generateTx(i int) *types.Transaction { s := rand.NewSource(int64(i)) r := rand.New(s) + var tx *types.Transaction + txTypes := []types.TxType{ - types.LegacyTx, - types.DynamicFeeTx, + types.LegacyTxType, + types.DynamicFeeTxType, } - tx := types.NewTx(&types.MixedTxn{ - Type: txTypes[r.Intn(len(txTypes))], - }) + txType := txTypes[r.Intn(len(txTypes))] - switch tx.Type() { - case types.LegacyTx: + switch txType { + case types.LegacyTxType: minGasPrice := 1000 * i maxGasPrice := 100000 * i + tx = types.NewTx(&types.LegacyTx{}) tx.SetGasPrice(new(big.Int).SetInt64(int64(rand.Intn(maxGasPrice-minGasPrice) + minGasPrice))) - case types.DynamicFeeTx: + case types.DynamicFeeTxType: + tx = types.NewTx(&types.DynamicFeeTx{}) + minGasFeeCap := 1000 * i maxGasFeeCap := 100000 * i tx.SetGasFeeCap(new(big.Int).SetInt64(int64(rand.Intn(maxGasFeeCap-minGasFeeCap) + minGasFeeCap))) diff --git a/txpool/txpool.go b/txpool/txpool.go index 53b041e7d1..8f08436fc5 100644 --- a/txpool/txpool.go +++ b/txpool/txpool.go @@ -544,7 +544,7 @@ func (p *TxPool) processEvent(event *blockchain.Event) { // constraints before entering the pool. func (p *TxPool) validateTx(tx *types.Transaction) error { // Check the transaction type. State transactions are not expected to be added to the pool - if tx.Type() == types.StateTx { + if tx.Type() == types.StateTxType { metrics.IncrCounter([]string{txPoolMetrics, "invalid_tx_type"}, 1) return fmt.Errorf("%w: type %d rejected, state transactions are not expected to be added to the pool", @@ -608,7 +608,7 @@ func (p *TxPool) validateTx(tx *types.Transaction) error { latestBlockGasLimit := currentHeader.GasLimit baseFee := p.GetBaseFee() // base fee is calculated for the next block - if tx.Type() == types.AccessListTx { + if tx.Type() == types.AccessListTxType { // Reject access list tx if berlin hardfork(eip-2930) is not enabled if !forks.Berlin { metrics.IncrCounter([]string{txPoolMetrics, "invalid_tx_type"}, 1) @@ -622,7 +622,7 @@ func (p *TxPool) validateTx(tx *types.Transaction) error { return ErrUnderpriced } - } else if tx.Type() == types.DynamicFeeTx { + } else if tx.Type() == types.DynamicFeeTxType { // Reject dynamic fee tx if london hardfork is not enabled if !forks.London { metrics.IncrCounter([]string{txPoolMetrics, "tx_type"}, 1) @@ -775,7 +775,7 @@ func (p *TxPool) addTx(origin txOrigin, tx *types.Transaction) error { } // add chainID to the tx - only dynamic fee tx - if tx.Type() == types.DynamicFeeTx { + if tx.Type() == types.DynamicFeeTxType { tx.SetChainID(p.chainID) } diff --git a/txpool/txpool_test.go b/txpool/txpool_test.go index 4e1ae0e369..d7184d303f 100644 --- a/txpool/txpool_test.go +++ b/txpool/txpool_test.go @@ -44,7 +44,7 @@ var ( ) // returns a new valid tx of slots size with the given nonce -func newTx(addr types.Address, nonce, slots uint64) *types.Transaction { +func newTx(addr types.Address, nonce, slots uint64, txType types.TxType) *types.Transaction { // base field should take 1 slot at least size := txSlotSize * (slots - 1) if size <= 0 { @@ -56,14 +56,45 @@ func newTx(addr types.Address, nonce, slots uint64) *types.Transaction { return nil } - return types.NewTx(&types.MixedTxn{ - From: addr, - Nonce: nonce, - Value: big.NewInt(1), - GasPrice: big.NewInt(0).SetUint64(defaultPriceLimit), - Gas: validGasLimit, - Input: input, - }) + var tx *types.Transaction + + switch txType { + case types.AccessListTxType: + tx = types.NewTx(&types.AccessListTxn{ + From: addr, + Nonce: nonce, + Value: big.NewInt(1), + GasPrice: big.NewInt(0).SetUint64(defaultPriceLimit), + Gas: validGasLimit, + Input: input, + }) + case types.LegacyTxType: + tx = types.NewTx(&types.LegacyTx{ + Nonce: nonce, + Value: big.NewInt(1), + GasPrice: big.NewInt(0).SetUint64(defaultPriceLimit), + Gas: validGasLimit, + Input: input, + }) + case types.StateTxType: + tx = types.NewTx(&types.StateTx{ + From: addr, + Nonce: nonce, + Value: big.NewInt(1), + GasPrice: big.NewInt(0).SetUint64(defaultPriceLimit), + Gas: validGasLimit, + Input: input, + }) + default: + tx = types.NewTx(&types.DynamicFeeTx{ + Nonce: nonce, + Value: big.NewInt(1), + Gas: validGasLimit, + Input: input, + }) + } + + return tx } // returns a new txpool with default test config @@ -140,8 +171,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1) - tx.SetTransactionType(types.StateTx) + tx := newTx(defaultAddr, 0, 1, types.StateTxType) err := pool.addTx(local, signTx(tx)) @@ -160,8 +190,7 @@ func TestAddTxErrors(t *testing.T) { pool := setupPool() pool.forks.RemoveFork(chain.London) - tx := newTx(defaultAddr, 0, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) err := pool.addTx(local, signTx(tx)) @@ -179,7 +208,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx.SetValue(big.NewInt(-5)) assert.ErrorIs(t, @@ -192,7 +221,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx.SetValue(big.NewInt(1)) tx.SetGas(10000000000001) @@ -208,7 +237,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) assert.ErrorIs(t, pool.addTx(local, tx), @@ -220,7 +249,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(addr1, 0, 1) + tx := newTx(addr1, 0, 1, types.DynamicFeeTxType) // Sign with a private key that corresponds // to a different address @@ -237,7 +266,7 @@ func TestAddTxErrors(t *testing.T) { pool := setupPool() pool.priceLimit = 1000000 - tx := newTx(defaultAddr, 0, 1) // gasPrice == 1 + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) // gasPrice == 1 tx = signTx(tx) assert.ErrorIs(t, @@ -253,7 +282,7 @@ func TestAddTxErrors(t *testing.T) { // nonce is 1000000 so ErrNonceTooLow // doesn't get triggered - tx := newTx(defaultAddr, 1000000, 1) + tx := newTx(defaultAddr, 1000000, 1, types.StateTxType) tx = signTx(tx) assert.ErrorIs(t, @@ -269,7 +298,7 @@ func TestAddTxErrors(t *testing.T) { // fill the pool pool.gauge.increase(defaultMaxSlots) - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) tx = signTx(tx) assert.ErrorIs(t, @@ -286,7 +315,7 @@ func TestAddTxErrors(t *testing.T) { pool.gauge.increase(defaultMaxSlots - 1) // create tx requiring 1 slot - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) tx = signTx(tx) // enqueue tx @@ -298,7 +327,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) tx.SetGas(1) tx = signTx(tx) @@ -312,7 +341,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx = signTx(tx) // send the tx beforehand @@ -329,7 +358,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx.SetGasPrice(big.NewInt(200)) tx = signTx(tx) @@ -337,7 +366,7 @@ func TestAddTxErrors(t *testing.T) { assert.NoError(t, pool.addTx(local, tx)) <-pool.promoteReqCh - tx = newTx(defaultAddr, 0, 1) + tx = newTx(defaultAddr, 0, 1, types.LegacyTxType) tx.SetGasPrice(big.NewInt(100)) tx = signTx(tx) @@ -351,7 +380,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) // set oversized Input field data := make([]byte, 989898) @@ -373,7 +402,7 @@ func TestAddTxErrors(t *testing.T) { // faultyMockStore.GetNonce() == 99999 pool.store = faultyMockStore{} - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx = signTx(tx) assert.ErrorIs(t, @@ -386,7 +415,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx.GasPrice().SetUint64(1000000000000) tx = signTx(tx) @@ -432,7 +461,7 @@ func TestPruneAccountsWithNonceHoles(t *testing.T) { assert.NoError(t, err) pool.SetSigner(&mockSigner{}) - tx := newTx(addr1, 0, 1) + tx := newTx(addr1, 0, 1, types.LegacyTxType) // enqueue tx assert.NoError(t, pool.addTx(local, tx)) @@ -466,7 +495,7 @@ func TestPruneAccountsWithNonceHoles(t *testing.T) { assert.NoError(t, err) pool.SetSigner(&mockSigner{}) - tx := newTx(addr1, 5, 1) + tx := newTx(addr1, 5, 1, types.LegacyTxType) // enqueue tx assert.NoError(t, pool.addTx(local, tx)) @@ -510,7 +539,7 @@ func TestAddTxHighPressure(t *testing.T) { // enqueue tx go func() { assert.NoError(t, - pool.addTx(local, newTx(addr1, 0, 1)), + pool.addTx(local, newTx(addr1, 0, 1, types.LegacyTxType)), ) }() @@ -538,7 +567,7 @@ func TestAddTxHighPressure(t *testing.T) { assert.ErrorIs(t, ErrRejectFutureTx, - pool.addTx(local, newTx(addr1, 8, 1)), + pool.addTx(local, newTx(addr1, 8, 1, types.LegacyTxType)), ) acc := pool.accounts.get(addr1) @@ -564,7 +593,7 @@ func TestAddTxHighPressure(t *testing.T) { println("slots", slots, "max", pool.gauge.max) pool.gauge.increase(slots) - tx := newTx(addr1, 5, 1) + tx := newTx(addr1, 5, 1, types.AccessListTxType) assert.NoError(t, pool.addTx(local, tx)) _, exists := pool.index.get(tx.Hash()) @@ -582,7 +611,7 @@ func TestAddGossipTx(t *testing.T) { key, sender := tests.GenerateKeyAndAddr(t) signer := crypto.NewEIP155Signer(100, true) - tx := newTx(types.ZeroAddress, 1, 1) + tx := newTx(types.ZeroAddress, 1, 1, types.LegacyTxType) t.Run("node is a validator", func(t *testing.T) { t.Parallel() @@ -644,7 +673,7 @@ func TestDropKnownGossipTx(t *testing.T) { assert.NoError(t, err) pool.SetSigner(&mockSigner{}) - tx := newTx(addr1, 1, 1) + tx := newTx(addr1, 1, 1, types.LegacyTxType) // send tx as local assert.NoError(t, pool.addTx(local, tx)) @@ -676,7 +705,7 @@ func TestEnqueueHandler(t *testing.T) { pool.SetSigner(&mockSigner{}) // send higher nonce tx - err = pool.addTx(local, newTx(addr1, 10, 1)) // 10 > 0 + err = pool.addTx(local, newTx(addr1, 10, 1, types.LegacyTxType)) // 10 > 0 assert.NoError(t, err) assert.Equal(t, uint64(1), pool.gauge.read()) @@ -699,7 +728,7 @@ func TestEnqueueHandler(t *testing.T) { // send tx go func() { - err := pool.addTx(local, newTx(addr1, 10, 1)) // 10 < 20 + err := pool.addTx(local, newTx(addr1, 10, 1, types.LegacyTxType)) // 10 < 20 assert.EqualError(t, err, "nonce too low") }() @@ -722,7 +751,7 @@ func TestEnqueueHandler(t *testing.T) { pool.SetSigner(&mockSigner{}) // send tx - err = pool.addTx(local, newTx(addr1, 0, 1)) // 0 == 0 + err = pool.addTx(local, newTx(addr1, 0, 1, types.LegacyTxType)) // 0 == 0 assert.NoError(t, err) // catch pending promotion @@ -747,14 +776,14 @@ func TestEnqueueHandler(t *testing.T) { fillEnqueued := func(pool *TxPool, num uint64) { // first tx will signal promotion, grab the signal // but don't execute the handler - err := pool.addTx(local, newTx(addr1, 0, 1)) + err := pool.addTx(local, newTx(addr1, 0, 1, types.LegacyTxType)) assert.NoError(t, err) // catch pending promotion <-pool.promoteReqCh for i := uint64(1); i < num; i++ { - err := pool.addTx(local, newTx(addr1, i, 1)) + err := pool.addTx(local, newTx(addr1, i, 1, types.LegacyTxType)) assert.NoError(t, err) } } @@ -773,7 +802,7 @@ func TestEnqueueHandler(t *testing.T) { // send next expected tx go func() { - err := pool.addTx(local, newTx(addr1, 1, 1)) + err := pool.addTx(local, newTx(addr1, 1, 1, types.LegacyTxType)) assert.True(t, errors.Is(err, ErrMaxEnqueuedLimitReached)) }() @@ -803,7 +832,7 @@ func TestEnqueueHandler(t *testing.T) { // add 10 transaction in txpool i.e. max enqueued transactions for i := uint64(1); i <= 10; i++ { - err := pool.addTx(local, newTx(addr1, i, 1)) + err := pool.addTx(local, newTx(addr1, i, 1, types.LegacyTxType)) assert.NoError(t, err) } @@ -811,11 +840,11 @@ func TestEnqueueHandler(t *testing.T) { assert.Equal(t, uint64(0), pool.accounts.get(addr1).promoted.length()) assert.Equal(t, uint64(0), pool.accounts.get(addr1).getNonce()) - err = pool.addTx(local, newTx(addr1, 11, 1)) + err = pool.addTx(local, newTx(addr1, 11, 1, types.LegacyTxType)) assert.True(t, errors.Is(err, ErrMaxEnqueuedLimitReached)) // add the transaction with nextNonce i.e. nonce=0 - err = pool.addTx(local, newTx(addr1, uint64(0), 1)) + err = pool.addTx(local, newTx(addr1, uint64(0), 1, types.LegacyTxType)) assert.NoError(t, err) pool.handlePromoteRequest(<-pool.promoteReqCh) @@ -842,7 +871,7 @@ func TestAddTx(t *testing.T) { gasPrice, slots uint64, ) *types.Transaction { - tx := newTx(addr, nonce, slots) + tx := newTx(addr, nonce, slots, types.LegacyTxType) tx.GasPrice().SetUint64(gasPrice) return tx @@ -903,7 +932,7 @@ func TestAddTx(t *testing.T) { gasPrice, slots uint64, ) *types.Transaction { - tx := newTx(addr, nonce, slots) + tx := newTx(addr, nonce, slots, types.LegacyTxType) tx.GasPrice().SetUint64(gasPrice) return tx @@ -959,7 +988,7 @@ func TestAddTx(t *testing.T) { gasPrice, slots uint64, ) *types.Transaction { - tx := newTx(addr, nonce, slots) + tx := newTx(addr, nonce, slots, types.LegacyTxType) tx.GasPrice().SetUint64(gasPrice) return tx @@ -1060,7 +1089,7 @@ func TestAddTx(t *testing.T) { gasPrice, slots uint64, ) *types.Transaction { - tx := newTx(addr, nonce, slots) + tx := newTx(addr, nonce, slots, types.LegacyTxType) tx.GasPrice().SetUint64(gasPrice) return tx @@ -1119,7 +1148,7 @@ func TestAddTx(t *testing.T) { gasPrice, slots uint64, ) *types.Transaction { - tx := newTx(addr, nonce, slots) + tx := newTx(addr, nonce, slots, types.StateTxType) tx.GasPrice().SetUint64(gasPrice) return tx @@ -1218,7 +1247,7 @@ func TestPromoteHandler(t *testing.T) { assert.Equal(t, uint64(0), pool.accounts.get(addr1).promoted.length()) // enqueue higher nonce tx - tx := newTx(addr1, 10, 1) + tx := newTx(addr1, 10, 1, types.LegacyTxType) err = pool.addTx(local, tx) assert.NoError(t, err) @@ -1251,7 +1280,7 @@ func TestPromoteHandler(t *testing.T) { assert.NoError(t, err) pool.SetSigner(&mockSigner{}) - tx := newTx(addr1, 0, 1) + tx := newTx(addr1, 0, 1, types.LegacyTxType) err = pool.addTx(local, tx) assert.NoError(t, err) @@ -1294,7 +1323,7 @@ func TestPromoteHandler(t *testing.T) { txs := make([]*types.Transaction, 10) for i := 0; i < 10; i++ { - txs[i] = newTx(addr1, uint64(i), 1) + txs[i] = newTx(addr1, uint64(i), 1, types.LegacyTxType) } // send the first (expected) tx -> signals promotion @@ -1352,7 +1381,7 @@ func TestPromoteHandler(t *testing.T) { txs := make([]*types.Transaction, 20) for i := 0; i < 20; i++ { - txs[i] = newTx(addr1, uint64(i), 1) + txs[i] = newTx(addr1, uint64(i), 1, types.StateTxType) } for _, tx := range txs { @@ -1393,11 +1422,11 @@ func TestResetAccount(t *testing.T) { { name: "prune all txs with low nonce", txs: []*types.Transaction{ - newTx(addr1, 0, 1), - newTx(addr1, 1, 1), - newTx(addr1, 2, 1), - newTx(addr1, 3, 1), - newTx(addr1, 4, 1), + newTx(addr1, 0, 1, types.LegacyTxType), + newTx(addr1, 1, 1, types.LegacyTxType), + newTx(addr1, 2, 1, types.LegacyTxType), + newTx(addr1, 3, 1, types.LegacyTxType), + newTx(addr1, 4, 1, types.LegacyTxType), }, newNonce: 5, expected: result{ @@ -1412,9 +1441,9 @@ func TestResetAccount(t *testing.T) { { name: "no low nonce txs to prune", txs: []*types.Transaction{ - newTx(addr1, 2, 1), - newTx(addr1, 3, 1), - newTx(addr1, 4, 1), + newTx(addr1, 2, 1, types.LegacyTxType), + newTx(addr1, 3, 1, types.LegacyTxType), + newTx(addr1, 4, 1, types.LegacyTxType), }, newNonce: 1, expected: result{ @@ -1429,9 +1458,9 @@ func TestResetAccount(t *testing.T) { { name: "prune some txs with low nonce", txs: []*types.Transaction{ - newTx(addr1, 7, 1), - newTx(addr1, 8, 1), - newTx(addr1, 9, 1), + newTx(addr1, 7, 1, types.LegacyTxType), + newTx(addr1, 8, 1, types.LegacyTxType), + newTx(addr1, 9, 1, types.LegacyTxType), }, newNonce: 8, expected: result{ @@ -1512,10 +1541,10 @@ func TestResetAccount(t *testing.T) { { name: "prune all txs with low nonce", txs: []*types.Transaction{ - newTx(addr1, 5, 1), - newTx(addr1, 6, 1), - newTx(addr1, 7, 1), - newTx(addr1, 8, 1), + newTx(addr1, 5, 1, types.LegacyTxType), + newTx(addr1, 6, 1, types.LegacyTxType), + newTx(addr1, 7, 1, types.LegacyTxType), + newTx(addr1, 8, 1, types.LegacyTxType), }, newNonce: 10, expected: result{ @@ -1530,9 +1559,9 @@ func TestResetAccount(t *testing.T) { { name: "no low nonce txs to prune", txs: []*types.Transaction{ - newTx(addr1, 2, 1), - newTx(addr1, 3, 1), - newTx(addr1, 4, 1), + newTx(addr1, 2, 1, types.LegacyTxType), + newTx(addr1, 3, 1, types.LegacyTxType), + newTx(addr1, 4, 1, types.LegacyTxType), }, newNonce: 1, expected: result{ @@ -1547,10 +1576,10 @@ func TestResetAccount(t *testing.T) { { name: "prune some txs with low nonce", txs: []*types.Transaction{ - newTx(addr1, 4, 1), - newTx(addr1, 5, 1), - newTx(addr1, 8, 1), - newTx(addr1, 9, 1), + newTx(addr1, 4, 1, types.LegacyTxType), + newTx(addr1, 5, 1, types.LegacyTxType), + newTx(addr1, 8, 1, types.LegacyTxType), + newTx(addr1, 9, 1, types.LegacyTxType), }, newNonce: 6, expected: result{ @@ -1566,9 +1595,9 @@ func TestResetAccount(t *testing.T) { name: "pruning low nonce signals promotion", signal: true, txs: []*types.Transaction{ - newTx(addr1, 8, 1), - newTx(addr1, 9, 1), - newTx(addr1, 10, 1), + newTx(addr1, 8, 1, types.LegacyTxType), + newTx(addr1, 9, 1, types.LegacyTxType), + newTx(addr1, 10, 1, types.LegacyTxType), }, newNonce: 9, expected: result{ @@ -1649,14 +1678,14 @@ func TestResetAccount(t *testing.T) { name: "prune all txs with low nonce", txs: []*types.Transaction{ // promoted - newTx(addr1, 0, 1), - newTx(addr1, 1, 1), - newTx(addr1, 2, 1), - newTx(addr1, 3, 1), + newTx(addr1, 0, 1, types.LegacyTxType), + newTx(addr1, 1, 1, types.LegacyTxType), + newTx(addr1, 2, 1, types.LegacyTxType), + newTx(addr1, 3, 1, types.LegacyTxType), // enqueued - newTx(addr1, 5, 1), - newTx(addr1, 6, 1), - newTx(addr1, 8, 1), + newTx(addr1, 5, 1, types.LegacyTxType), + newTx(addr1, 6, 1, types.LegacyTxType), + newTx(addr1, 8, 1, types.LegacyTxType), }, newNonce: 10, expected: result{ @@ -1673,11 +1702,11 @@ func TestResetAccount(t *testing.T) { name: "no low nonce txs to prune", txs: []*types.Transaction{ // promoted - newTx(addr1, 5, 1), - newTx(addr1, 6, 1), + newTx(addr1, 5, 1, types.LegacyTxType), + newTx(addr1, 6, 1, types.LegacyTxType), // enqueued - newTx(addr1, 9, 1), - newTx(addr1, 10, 1), + newTx(addr1, 9, 1, types.LegacyTxType), + newTx(addr1, 10, 1, types.LegacyTxType), }, newNonce: 3, expected: result{ @@ -1694,13 +1723,13 @@ func TestResetAccount(t *testing.T) { name: "prune all promoted and 1 enqueued", txs: []*types.Transaction{ // promoted - newTx(addr1, 1, 1), - newTx(addr1, 2, 1), - newTx(addr1, 3, 1), + newTx(addr1, 1, 1, types.LegacyTxType), + newTx(addr1, 2, 1, types.LegacyTxType), + newTx(addr1, 3, 1, types.LegacyTxType), // enqueued - newTx(addr1, 5, 1), - newTx(addr1, 8, 1), - newTx(addr1, 9, 1), + newTx(addr1, 5, 1, types.LegacyTxType), + newTx(addr1, 8, 1, types.LegacyTxType), + newTx(addr1, 9, 1, types.LegacyTxType), }, newNonce: 6, expected: result{ @@ -1718,14 +1747,14 @@ func TestResetAccount(t *testing.T) { signal: true, txs: []*types.Transaction{ // promoted - newTx(addr1, 2, 1), - newTx(addr1, 3, 1), - newTx(addr1, 4, 1), - newTx(addr1, 5, 1), + newTx(addr1, 2, 1, types.LegacyTxType), + newTx(addr1, 3, 1, types.LegacyTxType), + newTx(addr1, 4, 1, types.LegacyTxType), + newTx(addr1, 5, 1, types.LegacyTxType), // enqueued - newTx(addr1, 8, 1), - newTx(addr1, 9, 1), - newTx(addr1, 10, 1), + newTx(addr1, 8, 1, types.LegacyTxType), + newTx(addr1, 9, 1, types.LegacyTxType), + newTx(addr1, 10, 1, types.LegacyTxType), }, newNonce: 8, expected: result{ @@ -1811,7 +1840,7 @@ func TestPop(t *testing.T) { pool.SetSigner(&mockSigner{}) // send 1 tx and promote it - tx1 := newTx(addr1, 0, 1) + tx1 := newTx(addr1, 0, 1, types.LegacyTxType) err = pool.addTx(local, tx1) assert.NoError(t, err) @@ -1847,7 +1876,7 @@ func TestDrop(t *testing.T) { pool.SetSigner(&mockSigner{}) // send 1 tx and promote it - tx1 := newTx(addr1, 0, 1) + tx1 := newTx(addr1, 0, 1, types.LegacyTxType) err = pool.addTx(local, tx1) assert.NoError(t, err) @@ -1884,7 +1913,7 @@ func TestDemote(t *testing.T) { pool.SetSigner(&mockSigner{}) // send tx - err = pool.addTx(local, newTx(addr1, 0, 1)) + err = pool.addTx(local, newTx(addr1, 0, 1, types.LegacyTxType)) assert.NoError(t, err) pool.handlePromoteRequest(<-pool.promoteReqCh) @@ -1916,7 +1945,7 @@ func TestDemote(t *testing.T) { pool.SetSigner(&mockSigner{}) // send tx - err = pool.addTx(local, newTx(addr1, 0, 1)) + err = pool.addTx(local, newTx(addr1, 0, 1, types.LegacyTxType)) assert.NoError(t, err) pool.handlePromoteRequest(<-pool.promoteReqCh) @@ -1978,7 +2007,7 @@ func Test_updateAccountSkipsCounts(t *testing.T) { pool.SetSigner(&mockSigner{}) - tx := newTx(addr1, 0, 1) + tx := newTx(addr1, 0, 1, types.LegacyTxType) sendTx(t, pool, tx, true) accountMap := pool.accounts.get(addr1) @@ -2013,7 +2042,7 @@ func Test_updateAccountSkipsCounts(t *testing.T) { pool.SetSigner(&mockSigner{}) - tx := newTx(addr1, 1, 1) // set non-zero nonce to prevent the tx from being added + tx := newTx(addr1, 1, 1, types.LegacyTxType) // set non-zero nonce to prevent the tx from being added sendTx(t, pool, tx, false) accountMap := pool.accounts.get(addr1) @@ -2048,7 +2077,7 @@ func Test_updateAccountSkipsCounts(t *testing.T) { pool.SetSigner(&mockSigner{}) - tx := newTx(addr1, 0, 1) + tx := newTx(addr1, 0, 1, types.LegacyTxType) sendTx(t, pool, tx, true) accountMap := pool.accounts.get(addr1) @@ -2093,25 +2122,25 @@ func Test_updateAccountSkipsCounts(t *testing.T) { accountMap := pool.accounts.initOnce(addr1, storeNonce) accountMap.enqueued.push(&types.Transaction{ - Inner: &types.MixedTxn{ + Inner: &types.LegacyTx{ Nonce: storeNonce + 2, Hash: types.StringToHash("0xffa"), }, }) accountMap.enqueued.push(&types.Transaction{ - Inner: &types.MixedTxn{ + Inner: &types.LegacyTx{ Nonce: storeNonce + 4, Hash: types.StringToHash("0xff1"), }, }) accountMap.promoted.push(&types.Transaction{ - Inner: &types.MixedTxn{ + Inner: &types.LegacyTx{ Nonce: storeNonce, Hash: types.StringToHash("0xff2"), }, }) accountMap.promoted.push(&types.Transaction{ - Inner: &types.MixedTxn{ + Inner: &types.LegacyTx{ Nonce: storeNonce + 1, Hash: types.StringToHash("0xff3"), }, @@ -2169,7 +2198,7 @@ func Test_TxPool_validateTx(t *testing.T) { _, err := rand.Read(input) require.NoError(t, err) - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx.SetTo(nil) tx.SetInput(input) @@ -2188,7 +2217,7 @@ func Test_TxPool_validateTx(t *testing.T) { _, err := rand.Read(input) require.NoError(t, err) - tx := newTx(defaultAddr, 0, 1) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx.SetTo(nil) tx.SetInput(input) tx.SetGasPrice(new(big.Int).SetUint64(pool.GetBaseFee())) @@ -2204,8 +2233,7 @@ func Test_TxPool_validateTx(t *testing.T) { pool := setupPool() - tx := newTx(defaultAddr, 0, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) tx.SetGasFeeCap(big.NewInt(1100)) tx.SetGasTipCap(big.NewInt(10)) @@ -2217,8 +2245,7 @@ func Test_TxPool_validateTx(t *testing.T) { pool := setupPool() - tx := newTx(defaultAddr, 0, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) tx.SetGasFeeCap(big.NewInt(100)) tx.SetGasTipCap(big.NewInt(10)) @@ -2233,8 +2260,7 @@ func Test_TxPool_validateTx(t *testing.T) { pool := setupPool() - tx := newTx(defaultAddr, 0, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) tx.SetGasFeeCap(big.NewInt(10000)) tx.SetGasTipCap(big.NewInt(100000)) @@ -2250,8 +2276,7 @@ func Test_TxPool_validateTx(t *testing.T) { pool := setupPool() // undefined gas tip cap - tx := newTx(defaultAddr, 0, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) tx.SetGasFeeCap(big.NewInt(10000)) signedTx := signTx(tx) @@ -2263,8 +2288,7 @@ func Test_TxPool_validateTx(t *testing.T) { ) // undefined gas fee cap - tx = newTx(defaultAddr, 1, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx = newTx(defaultAddr, 1, 1, types.DynamicFeeTxType) tx.SetGasTipCap(big.NewInt(1000)) signedTx = signTx(tx) @@ -2284,8 +2308,7 @@ func Test_TxPool_validateTx(t *testing.T) { pool := setupPool() // very high gas fee cap - tx := newTx(defaultAddr, 0, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) tx.SetGasFeeCap(new(big.Int).SetBit(new(big.Int), bitLength, 1)) tx.SetGasTipCap(new(big.Int)) @@ -2295,8 +2318,7 @@ func Test_TxPool_validateTx(t *testing.T) { ) // very high gas tip cap - tx = newTx(defaultAddr, 1, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx = newTx(defaultAddr, 1, 1, types.DynamicFeeTxType) tx.SetGasTipCap(new(big.Int).SetBit(new(big.Int), bitLength, 1)) tx.SetGasFeeCap(new(big.Int)) @@ -2312,8 +2334,7 @@ func Test_TxPool_validateTx(t *testing.T) { pool.forks = chain.AllForksEnabled.Copy() pool.forks.RemoveFork(chain.London) - tx := newTx(defaultAddr, 0, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) tx.SetGasFeeCap(big.NewInt(10000)) tx.SetGasTipCap(big.NewInt(100000)) @@ -2397,30 +2418,30 @@ func TestResetAccounts_Promoted(t *testing.T) { allTxs := map[types.Address][]*types.Transaction{ addr1: { - eoa1.signTx(t, newTx(addr1, 0, 1), signerEIP155), // will be pruned - eoa1.signTx(t, newTx(addr1, 1, 1), signerEIP155), // will be pruned - eoa1.signTx(t, newTx(addr1, 2, 1), signerEIP155), // will be pruned - eoa1.signTx(t, newTx(addr1, 3, 1), signerEIP155), // will be pruned + eoa1.signTx(t, newTx(addr1, 0, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa1.signTx(t, newTx(addr1, 1, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa1.signTx(t, newTx(addr1, 2, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa1.signTx(t, newTx(addr1, 3, 1, types.LegacyTxType), signerEIP155), // will be pruned }, addr2: { - eoa2.signTx(t, newTx(addr2, 0, 1), signerEIP155), // will be pruned - eoa2.signTx(t, newTx(addr2, 1, 1), signerEIP155), // will be pruned + eoa2.signTx(t, newTx(addr2, 0, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa2.signTx(t, newTx(addr2, 1, 1, types.LegacyTxType), signerEIP155), // will be pruned }, addr3: { - eoa3.signTx(t, newTx(addr3, 0, 1), signerEIP155), // will be pruned - eoa3.signTx(t, newTx(addr3, 1, 1), signerEIP155), // will be pruned - eoa3.signTx(t, newTx(addr3, 2, 1), signerEIP155), // will be pruned + eoa3.signTx(t, newTx(addr3, 0, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa3.signTx(t, newTx(addr3, 1, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa3.signTx(t, newTx(addr3, 2, 1, types.LegacyTxType), signerEIP155), // will be pruned }, addr4: { // all txs will be pruned - eoa4.signTx(t, newTx(addr4, 0, 1), signerEIP155), // will be pruned - eoa4.signTx(t, newTx(addr4, 1, 1), signerEIP155), // will be pruned - eoa4.signTx(t, newTx(addr4, 2, 1), signerEIP155), // will be pruned - eoa4.signTx(t, newTx(addr4, 3, 1), signerEIP155), // will be pruned - eoa4.signTx(t, newTx(addr4, 4, 1), signerEIP155), // will be pruned + eoa4.signTx(t, newTx(addr4, 0, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa4.signTx(t, newTx(addr4, 1, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa4.signTx(t, newTx(addr4, 2, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa4.signTx(t, newTx(addr4, 3, 1, types.LegacyTxType), signerEIP155), // will be pruned + eoa4.signTx(t, newTx(addr4, 4, 1, types.LegacyTxType), signerEIP155), // will be pruned }, } @@ -2535,22 +2556,22 @@ func TestResetAccounts_Enqueued(t *testing.T) { allTxs := map[types.Address][]*types.Transaction{ addr1: { - eoa1.signTx(t, newTx(addr1, 3, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 4, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 5, 1), signerEIP155), + eoa1.signTx(t, newTx(addr1, 3, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 4, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 5, 1, types.LegacyTxType), signerEIP155), }, addr2: { - eoa2.signTx(t, newTx(addr2, 2, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 3, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 4, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 5, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 6, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 7, 1), signerEIP155), + eoa2.signTx(t, newTx(addr2, 2, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 3, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 4, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 5, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 6, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 7, 1, types.LegacyTxType), signerEIP155), }, addr3: { - eoa3.signTx(t, newTx(addr3, 7, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 8, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 9, 1), signerEIP155), + eoa3.signTx(t, newTx(addr3, 7, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 8, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 9, 1, types.LegacyTxType), signerEIP155), }, } newNonces := map[types.Address]uint64{ @@ -2637,21 +2658,21 @@ func TestResetAccounts_Enqueued(t *testing.T) { allTxs := map[types.Address][]*types.Transaction{ addr1: { - newTx(addr1, 1, 1), - newTx(addr1, 2, 1), - newTx(addr1, 3, 1), - newTx(addr1, 4, 1), + newTx(addr1, 1, 1, types.LegacyTxType), + newTx(addr1, 2, 1, types.LegacyTxType), + newTx(addr1, 3, 1, types.LegacyTxType), + newTx(addr1, 4, 1, types.LegacyTxType), }, addr2: { - newTx(addr2, 3, 3), - newTx(addr2, 4, 3), - newTx(addr2, 5, 3), - newTx(addr2, 6, 3), + newTx(addr2, 3, 3, types.LegacyTxType), + newTx(addr2, 4, 3, types.LegacyTxType), + newTx(addr2, 5, 3, types.LegacyTxType), + newTx(addr2, 6, 3, types.LegacyTxType), }, addr3: { - newTx(addr3, 7, 1), - newTx(addr3, 8, 1), - newTx(addr3, 9, 1), + newTx(addr3, 7, 1, types.LegacyTxType), + newTx(addr3, 8, 1, types.LegacyTxType), + newTx(addr3, 9, 1, types.LegacyTxType), }, } newNonces := map[types.Address]uint64{ @@ -2728,16 +2749,16 @@ func TestExecutablesOrder(t *testing.T) { newPricedTx := func( addr types.Address, nonce, gasPrice uint64, gasFeeCap uint64, value uint64) *types.Transaction { - tx := newTx(addr, nonce, 1) + var tx *types.Transaction tx.SetValue(new(big.Int).SetUint64(value)) if gasPrice == 0 { - tx.SetTransactionType(types.DynamicFeeTx) + tx = newTx(addr, nonce, 1, types.DynamicFeeTxType) tx.SetGasFeeCap(new(big.Int).SetUint64(gasFeeCap)) tx.SetGasTipCap(new(big.Int).SetUint64(2)) tx.SetGasPrice(big.NewInt(0)) } else { - tx.SetTransactionType(types.LegacyTx) + tx = newTx(addr, nonce, 1, types.LegacyTxType) tx.SetGasPrice(new(big.Int).SetUint64(gasPrice)) } @@ -2972,23 +2993,23 @@ func TestRecovery(t *testing.T) { name: "unrecoverable drops account", allTxs: map[types.Address][]statusTx{ addr1: { - {newTx(addr1, 0, 1), ok}, - {newTx(addr1, 1, 1), unrecoverable}, - {newTx(addr1, 2, 1), recoverable}, - {newTx(addr1, 3, 1), recoverable}, - {newTx(addr1, 4, 1), recoverable}, + {newTx(addr1, 0, 1, types.LegacyTxType), ok}, + {newTx(addr1, 1, 1, types.LegacyTxType), unrecoverable}, + {newTx(addr1, 2, 1, types.LegacyTxType), recoverable}, + {newTx(addr1, 3, 1, types.LegacyTxType), recoverable}, + {newTx(addr1, 4, 1, types.LegacyTxType), recoverable}, }, addr2: { - {newTx(addr2, 9, 1), unrecoverable}, - {newTx(addr2, 10, 1), recoverable}, + {newTx(addr2, 9, 1, types.LegacyTxType), unrecoverable}, + {newTx(addr2, 10, 1, types.LegacyTxType), recoverable}, }, addr3: { - {newTx(addr3, 5, 1), ok}, - {newTx(addr3, 6, 1), recoverable}, - {newTx(addr3, 7, 1), recoverable}, - {newTx(addr3, 8, 1), recoverable}, + {newTx(addr3, 5, 1, types.LegacyTxType), ok}, + {newTx(addr3, 6, 1, types.LegacyTxType), recoverable}, + {newTx(addr3, 7, 1, types.LegacyTxType), recoverable}, + {newTx(addr3, 8, 1, types.LegacyTxType), recoverable}, }, }, expected: result{ @@ -3018,15 +3039,15 @@ func TestRecovery(t *testing.T) { name: "recoverable remains in account", allTxs: map[types.Address][]statusTx{ addr1: { - {newTx(addr1, 0, 1), ok}, - {newTx(addr1, 1, 1), ok}, - {newTx(addr1, 2, 1), ok}, - {newTx(addr1, 3, 1), recoverable}, - {newTx(addr1, 4, 1), recoverable}, + {newTx(addr1, 0, 1, types.LegacyTxType), ok}, + {newTx(addr1, 1, 1, types.LegacyTxType), ok}, + {newTx(addr1, 2, 1, types.LegacyTxType), ok}, + {newTx(addr1, 3, 1, types.LegacyTxType), recoverable}, + {newTx(addr1, 4, 1, types.LegacyTxType), recoverable}, }, addr2: { - {newTx(addr2, 9, 1), recoverable}, - {newTx(addr2, 10, 1), recoverable}, + {newTx(addr2, 9, 1, types.LegacyTxType), recoverable}, + {newTx(addr2, 10, 1, types.LegacyTxType), recoverable}, }, }, expected: result{ @@ -3147,40 +3168,40 @@ func TestGetTxs(t *testing.T) { name: "get promoted txs", allTxs: map[types.Address][]*types.Transaction{ addr1: { - eoa1.signTx(t, newTx(addr1, 0, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 1, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 2, 1), signerEIP155), + eoa1.signTx(t, newTx(addr1, 0, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 1, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 2, 1, types.LegacyTxType), signerEIP155), }, addr2: { - eoa2.signTx(t, newTx(addr2, 0, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 1, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 2, 1), signerEIP155), + eoa2.signTx(t, newTx(addr2, 0, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 1, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 2, 1, types.LegacyTxType), signerEIP155), }, addr3: { - eoa3.signTx(t, newTx(addr3, 0, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 1, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 2, 1), signerEIP155), + eoa3.signTx(t, newTx(addr3, 0, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 1, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 2, 1, types.LegacyTxType), signerEIP155), }, }, expectedPromoted: map[types.Address][]*types.Transaction{ addr1: { - eoa1.signTx(t, newTx(addr1, 0, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 1, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 2, 1), signerEIP155), + eoa1.signTx(t, newTx(addr1, 0, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 1, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 2, 1, types.LegacyTxType), signerEIP155), }, addr2: { - eoa2.signTx(t, newTx(addr2, 0, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 1, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 2, 1), signerEIP155), + eoa2.signTx(t, newTx(addr2, 0, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 1, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 2, 1, types.LegacyTxType), signerEIP155), }, addr3: { - eoa3.signTx(t, newTx(addr3, 0, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 1, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 2, 1), signerEIP155), + eoa3.signTx(t, newTx(addr3, 0, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 1, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 2, 1, types.LegacyTxType), signerEIP155), }, }, }, @@ -3188,73 +3209,73 @@ func TestGetTxs(t *testing.T) { name: "get all txs", allTxs: map[types.Address][]*types.Transaction{ addr1: { - eoa1.signTx(t, newTx(addr1, 0, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 1, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 2, 1), signerEIP155), + eoa1.signTx(t, newTx(addr1, 0, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 1, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 2, 1, types.LegacyTxType), signerEIP155), // enqueued - eoa1.signTx(t, newTx(addr1, 10, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 11, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 12, 1), signerEIP155), + eoa1.signTx(t, newTx(addr1, 10, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 11, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 12, 1, types.LegacyTxType), signerEIP155), }, addr2: { - eoa2.signTx(t, newTx(addr2, 0, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 1, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 2, 1), signerEIP155), + eoa2.signTx(t, newTx(addr2, 0, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 1, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 2, 1, types.LegacyTxType), signerEIP155), // enqueued - eoa2.signTx(t, newTx(addr2, 10, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 11, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 12, 1), signerEIP155), + eoa2.signTx(t, newTx(addr2, 10, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 11, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 12, 1, types.LegacyTxType), signerEIP155), }, addr3: { - eoa3.signTx(t, newTx(addr3, 0, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 1, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 2, 1), signerEIP155), + eoa3.signTx(t, newTx(addr3, 0, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 1, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 2, 1, types.LegacyTxType), signerEIP155), // enqueued - eoa3.signTx(t, newTx(addr3, 10, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 11, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 12, 1), signerEIP155), + eoa3.signTx(t, newTx(addr3, 10, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 11, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 12, 1, types.LegacyTxType), signerEIP155), }, }, expectedPromoted: map[types.Address][]*types.Transaction{ addr1: { - eoa1.signTx(t, newTx(addr1, 0, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 1, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 2, 1), signerEIP155), + eoa1.signTx(t, newTx(addr1, 0, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 1, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 2, 1, types.LegacyTxType), signerEIP155), }, addr2: { - eoa2.signTx(t, newTx(addr2, 0, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 1, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 2, 1), signerEIP155), + eoa2.signTx(t, newTx(addr2, 0, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 1, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 2, 1, types.LegacyTxType), signerEIP155), }, addr3: { - eoa3.signTx(t, newTx(addr3, 0, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 1, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 2, 1), signerEIP155), + eoa3.signTx(t, newTx(addr3, 0, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 1, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 2, 1, types.LegacyTxType), signerEIP155), }, }, expectedEnqueued: map[types.Address][]*types.Transaction{ addr1: { - eoa1.signTx(t, newTx(addr1, 10, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 11, 1), signerEIP155), - eoa1.signTx(t, newTx(addr1, 12, 1), signerEIP155), + eoa1.signTx(t, newTx(addr1, 10, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 11, 1, types.LegacyTxType), signerEIP155), + eoa1.signTx(t, newTx(addr1, 12, 1, types.LegacyTxType), signerEIP155), }, addr2: { - eoa2.signTx(t, newTx(addr2, 10, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 11, 1), signerEIP155), - eoa2.signTx(t, newTx(addr2, 12, 1), signerEIP155), + eoa2.signTx(t, newTx(addr2, 10, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 11, 1, types.LegacyTxType), signerEIP155), + eoa2.signTx(t, newTx(addr2, 12, 1, types.LegacyTxType), signerEIP155), }, addr3: { - eoa3.signTx(t, newTx(addr3, 10, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 11, 1), signerEIP155), - eoa3.signTx(t, newTx(addr3, 12, 1), signerEIP155), + eoa3.signTx(t, newTx(addr3, 10, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 11, 1, types.LegacyTxType), signerEIP155), + eoa3.signTx(t, newTx(addr3, 12, 1, types.LegacyTxType), signerEIP155), }, }, }, @@ -3438,7 +3459,7 @@ func TestBatchTx_SingleAccount(t *testing.T) { // run max number of addTx concurrently for i := 0; i < int(defaultMaxAccountEnqueued); i++ { go func(i uint64) { - tx := newTx(addr, i, 1) + tx := newTx(addr, i, 1, types.LegacyTxType) tx.ComputeHash() @@ -3524,7 +3545,7 @@ func TestAddTxsInOrder(t *testing.T) { } for j := uint64(0); j < defaultMaxAccountEnqueued; j++ { - addrsTxs[i].txs[j] = newTx(addrsTxs[i].addr, j, uint64(1)) + addrsTxs[i].txs[j] = newTx(addrsTxs[i].addr, j, uint64(1), types.LegacyTxType) } } @@ -3643,8 +3664,7 @@ func TestAddTx_TxReplacement(t *testing.T) { key *ecdsa.PrivateKey, addr types.Address) *types.Transaction { t.Helper() - tx := newTx(addr, nonce, 1) - tx.SetTransactionType(types.DynamicFeeTx) + tx := newTx(addr, nonce, 1, types.DynamicFeeTxType) tx.SetInput(nil) tx.SetGasPrice(nil) tx.SetGasTipCap(new(big.Int).SetUint64(gasTipCap)) @@ -3663,7 +3683,7 @@ func TestAddTx_TxReplacement(t *testing.T) { key *ecdsa.PrivateKey, addr types.Address) *types.Transaction { t.Helper() - tx := newTx(addr, nonce, 1) + tx := newTx(addr, nonce, 1, types.LegacyTxType) tx.SetInput(nil) tx.SetGasPrice(new(big.Int).SetUint64(gasPrice)) @@ -3755,7 +3775,7 @@ func BenchmarkAddTxTime(b *testing.B) { b.Fatal(err) } - signedTx, err := signer.SignTx(newTx(crypto.PubKeyToAddress(&key.PublicKey), 0, 1), key) + signedTx, err := signer.SignTx(newTx(crypto.PubKeyToAddress(&key.PublicKey), 0, 1, types.LegacyTxType), key) if err != nil { b.Fatal(err) } @@ -3787,7 +3807,7 @@ func BenchmarkAddTxTime(b *testing.B) { txs := make([]*types.Transaction, defaultMaxAccountEnqueued) for i := range txs { - txs[i], err = signer.SignTx(newTx(addr, uint64(i), uint64(1)), key) + txs[i], err = signer.SignTx(newTx(addr, uint64(i), uint64(1), types.LegacyTxType), key) if err != nil { b.Fatal(err) } diff --git a/types/access_list_tx.go b/types/access_list_tx.go index f4c8687074..5c5e1da2a5 100644 --- a/types/access_list_tx.go +++ b/types/access_list_tx.go @@ -1,6 +1,11 @@ package types -import "math/big" +import ( + "fmt" + "math/big" + + "github.com/umbracle/fastrlp" +) type TxAccessList []AccessTuple @@ -55,7 +60,7 @@ type AccessListTxn struct { AccessList TxAccessList } -func (tx *AccessListTxn) transactionType() TxType { return AccessListTx } +func (tx *AccessListTxn) transactionType() TxType { return AccessListTxType } func (tx *AccessListTxn) chainID() *big.Int { return tx.ChainID } func (tx *AccessListTxn) input() []byte { return tx.Input } func (tx *AccessListTxn) gas() uint64 { return tx.Gas } @@ -133,3 +138,269 @@ func (tx *AccessListTxn) setAccessList(accessList TxAccessList) { func (tx *AccessListTxn) setHash(h Hash) { tx.Hash = h } + +// unmarshalRLPFrom unmarshals a Transaction in RLP format +// Be careful! This function does not de-serialize tx type, it assumes that t.Type is already set +// Hash calculation should also be done from the outside! +// Use UnmarshalRLP in most cases +func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { + numOfElems := 11 + elems, err := v.GetElems() + if err != nil { + return err + } + + getElem := func() *fastrlp.Value { + val := elems[0] + elems = elems[1:] + + return val + } + + if numElems := len(elems); numElems != numOfElems { + return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", numOfElems, numElems) + } + txChainID := new(big.Int) + if err = getElem().GetBigInt(txChainID); err != nil { + return err + } + + tx.setChainID(txChainID) + + // nonce + txNonce, err := getElem().GetUint64() + if err != nil { + return err + } + + tx.setNonce(txNonce) + + // gasPrice + txGasPrice := new(big.Int) + if err = getElem().GetBigInt(txGasPrice); err != nil { + return err + } + + tx.setGasPrice(txGasPrice) + + // gas + txGas, err := getElem().GetUint64() + if err != nil { + return err + } + + tx.setGas(txGas) + + // to + if vv, _ := getElem().Bytes(); len(vv) == 20 { + // address + addr := BytesToAddress(vv) + tx.setTo(&addr) + } else { + // reset To + tx.setTo(nil) + } + + // value + txValue := new(big.Int) + if err = getElem().GetBigInt(txValue); err != nil { + return err + } + + tx.setValue(txValue) + + // input + var txInput []byte + + txInput, err = getElem().GetBytes(txInput) + if err != nil { + return err + } + + tx.setInput(txInput) + + //accessList + accessListVV, err := getElem().GetElems() + if err != nil { + return err + } + + var txAccessList TxAccessList + if len(accessListVV) != 0 { + txAccessList = make(TxAccessList, len(accessListVV)) + } + + for i, accessTupleVV := range accessListVV { + accessTupleElems, err := accessTupleVV.GetElems() + if err != nil { + return err + } + + // Read the address + addressVV := accessTupleElems[0] + + addressBytes, err := addressVV.Bytes() + if err != nil { + return err + } + + txAccessList[i].Address = BytesToAddress(addressBytes) + + // Read the storage keys + storageKeysArrayVV := accessTupleElems[1] + + storageKeysElems, err := storageKeysArrayVV.GetElems() + if err != nil { + return err + } + + txAccessList[i].StorageKeys = make([]Hash, len(storageKeysElems)) + + for j, storageKeyVV := range storageKeysElems { + storageKeyBytes, err := storageKeyVV.Bytes() + if err != nil { + return err + } + + txAccessList[i].StorageKeys[j] = BytesToHash(storageKeyBytes) + } + } + + tx.setAccessList(txAccessList) + + // V + txV := new(big.Int) + if err = getElem().GetBigInt(txV); err != nil { + return err + } + + // R + txR := new(big.Int) + if err = getElem().GetBigInt(txR); err != nil { + return err + } + + // S + txS := new(big.Int) + if err = getElem().GetBigInt(txS); err != nil { + return err + } + + tx.setSignatureValues(txV, txR, txS) + + return nil +} + +// MarshalRLPWith marshals the transaction to RLP with a specific fastrlp.Arena +// Be careful! This function does not serialize tx type as a first byte. +// Use MarshalRLP/MarshalRLPTo in most cases +func (tx *AccessListTxn) marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value { + vv := arena.NewArray() + + vv.Set(arena.NewBigInt(tx.chainID())) + vv.Set(arena.NewUint(tx.nonce())) + vv.Set(arena.NewBigInt(tx.gasPrice())) + vv.Set(arena.NewUint(tx.gas())) + + // Address may be empty + if tx.to() != nil { + vv.Set(arena.NewCopyBytes(tx.to().Bytes())) + } else { + vv.Set(arena.NewNull()) + } + + vv.Set(arena.NewBigInt(tx.value())) + vv.Set(arena.NewCopyBytes(tx.input())) + + // add accessList + accessListVV := arena.NewArray() + + for _, accessTuple := range tx.accessList() { + accessTupleVV := arena.NewArray() + accessTupleVV.Set(arena.NewCopyBytes(accessTuple.Address.Bytes())) + + storageKeysVV := arena.NewArray() + for _, storageKey := range accessTuple.StorageKeys { + storageKeysVV.Set(arena.NewCopyBytes(storageKey.Bytes())) + } + + accessTupleVV.Set(storageKeysVV) + accessListVV.Set(accessTupleVV) + } + + vv.Set(accessListVV) + + v, r, s := tx.rawSignatureValues() + vv.Set(arena.NewBigInt(v)) + vv.Set(arena.NewBigInt(r)) + vv.Set(arena.NewBigInt(s)) + + return vv +} + +func (tx *AccessListTxn) copy() TxData { + cpy := &AccessListTxn{} + + if tx.chainID() != nil { + chainID := new(big.Int) + chainID.Set(tx.chainID()) + + cpy.setChainID(chainID) + } + + cpy.setNonce(tx.nonce()) + + if tx.gasPrice() != nil { + gasPrice := new(big.Int) + gasPrice.Set(tx.gasPrice()) + + cpy.setGasPrice(gasPrice) + } + + cpy.setGas(tx.gas()) + + cpy.setTo(tx.to()) + + if tx.value() != nil { + value := new(big.Int) + value.Set(tx.value()) + + cpy.setValue(value) + } + + inputCopy := make([]byte, len(tx.input())) + copy(inputCopy, tx.input()[:]) + + cpy.setInput(inputCopy) + + cpy.setInput(inputCopy) + + v, r, s := tx.rawSignatureValues() + + var vCopy, rCopy, sCopy *big.Int + + if v != nil { + vCopy = new(big.Int) + vCopy.Set(v) + } + + if r != nil { + rCopy = new(big.Int) + rCopy.Set(r) + } + + if s != nil { + sCopy = new(big.Int) + sCopy.Set(s) + } + + cpy.setHash(tx.hash()) + + cpy.setFrom(tx.from()) + + cpy.setSignatureValues(vCopy, rCopy, sCopy) + + cpy.setAccessList(tx.accessList().Copy()) + + return cpy +} diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go new file mode 100644 index 0000000000..3256bc068c --- /dev/null +++ b/types/dynamic_fee_tx.go @@ -0,0 +1,372 @@ +package types + +import ( + "fmt" + "math/big" + + "github.com/umbracle/fastrlp" +) + +type DynamicFeeTx struct { + Nonce uint64 + GasTipCap *big.Int + GasFeeCap *big.Int + Gas uint64 + To *Address + Value *big.Int + Input []byte + V, R, S *big.Int + Hash Hash + From Address + + ChainID *big.Int + AccessList TxAccessList +} + +func (tx *DynamicFeeTx) transactionType() TxType { return DynamicFeeTxType } +func (tx *DynamicFeeTx) chainID() *big.Int { return tx.ChainID } +func (tx *DynamicFeeTx) input() []byte { return tx.Input } +func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas } +func (tx *DynamicFeeTx) gasPrice() *big.Int { return nil } +func (tx *DynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap } +func (tx *DynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap } +func (tx *DynamicFeeTx) value() *big.Int { return tx.Value } +func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce } +func (tx *DynamicFeeTx) to() *Address { return tx.To } +func (tx *DynamicFeeTx) from() Address { return tx.From } + +func (tx *DynamicFeeTx) hash() Hash { return ZeroHash } + +func (tx *DynamicFeeTx) rawSignatureValues() (v, r, s *big.Int) { + return tx.V, tx.R, tx.S +} + +func (tx *DynamicFeeTx) accessList() TxAccessList { return tx.AccessList } + +func (tx *DynamicFeeTx) setSignatureValues(v, r, s *big.Int) { + tx.V, tx.R, tx.S = v, r, s +} + +func (tx *DynamicFeeTx) setFrom(addr Address) { tx.From = addr } + +func (tx *DynamicFeeTx) setGas(gas uint64) { + tx.Gas = gas +} + +func (tx *DynamicFeeTx) setChainID(id *big.Int) { + tx.ChainID = id +} + +func (tx *DynamicFeeTx) setGasPrice(gas *big.Int) {} + +func (tx *DynamicFeeTx) setGasFeeCap(gas *big.Int) { + tx.GasFeeCap = gas +} + +func (tx *DynamicFeeTx) setGasTipCap(gas *big.Int) { + tx.GasTipCap = gas +} + +func (tx *DynamicFeeTx) setValue(value *big.Int) { + tx.Value = value +} + +func (tx *DynamicFeeTx) setInput(input []byte) { + tx.Input = input +} + +func (tx *DynamicFeeTx) setTo(address *Address) { + tx.To = address +} + +func (tx *DynamicFeeTx) setNonce(nonce uint64) { + tx.Nonce = nonce +} + +func (tx *DynamicFeeTx) setAccessList(accessList TxAccessList) { + tx.AccessList = accessList +} + +func (tx *DynamicFeeTx) setHash(h Hash) { tx.Hash = h } + +// unmarshalRLPFrom unmarshals a Transaction in RLP format +// Be careful! This function does not de-serialize tx type, it assumes that t.Type is already set +// Hash calculation should also be done from the outside! +// Use UnmarshalRLP in most cases +func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { + numOfElems := 12 + elems, err := v.GetElems() + if err != nil { + return err + } + + getElem := func() *fastrlp.Value { + val := elems[0] + elems = elems[1:] + + return val + } + + if numElems := len(elems); numElems != numOfElems { + return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", numOfElems, numElems) + } + + // Load Chain ID + txChainID := new(big.Int) + if err = getElem().GetBigInt(txChainID); err != nil { + return err + } + + tx.setChainID(txChainID) + + // nonce + txNonce, err := getElem().GetUint64() + if err != nil { + return err + } + + tx.setNonce(txNonce) + + // gasTipCap + txGasTipCap := new(big.Int) + if err = getElem().GetBigInt(txGasTipCap); err != nil { + return err + } + + tx.setGasTipCap(txGasTipCap) + + // gasFeeCap + txGasFeeCap := new(big.Int) + if err = getElem().GetBigInt(txGasFeeCap); err != nil { + return err + } + + tx.setGasFeeCap(txGasFeeCap) + + // gas + txGas, err := getElem().GetUint64() + if err != nil { + return err + } + + tx.setGas(txGas) + + // to + if vv, _ := getElem().Bytes(); len(vv) == 20 { + // address + addr := BytesToAddress(vv) + tx.setTo(&addr) + } else { + // reset To + tx.setTo(nil) + } + + // value + txValue := new(big.Int) + if err = getElem().GetBigInt(txValue); err != nil { + return err + } + + tx.setValue(txValue) + + // input + var txInput []byte + + txInput, err = getElem().GetBytes(txInput) + if err != nil { + return err + } + + tx.setInput(txInput) + + accessListVV, err := getElem().GetElems() + if err != nil { + return err + } + + var txAccessList TxAccessList + if len(accessListVV) != 0 { + txAccessList = make(TxAccessList, len(accessListVV)) + } + + for i, accessTupleVV := range accessListVV { + accessTupleElems, err := accessTupleVV.GetElems() + if err != nil { + return err + } + + // Read the address + addressVV := accessTupleElems[0] + + addressBytes, err := addressVV.Bytes() + if err != nil { + return err + } + + txAccessList[i].Address = BytesToAddress(addressBytes) + + // Read the storage keys + storageKeysArrayVV := accessTupleElems[1] + + storageKeysElems, err := storageKeysArrayVV.GetElems() + if err != nil { + return err + } + + txAccessList[i].StorageKeys = make([]Hash, len(storageKeysElems)) + + for j, storageKeyVV := range storageKeysElems { + storageKeyBytes, err := storageKeyVV.Bytes() + if err != nil { + return err + } + + txAccessList[i].StorageKeys[j] = BytesToHash(storageKeyBytes) + } + } + + tx.setAccessList(txAccessList) + + // V + txV := new(big.Int) + if err = getElem().GetBigInt(txV); err != nil { + return err + } + + // R + txR := new(big.Int) + if err = getElem().GetBigInt(txR); err != nil { + return err + } + + // S + txS := new(big.Int) + if err = getElem().GetBigInt(txS); err != nil { + return err + } + + tx.setSignatureValues(txV, txR, txS) + + return nil +} + +// MarshalRLPWith marshals the transaction to RLP with a specific fastrlp.Arena +// Be careful! This function does not serialize tx type as a first byte. +// Use MarshalRLP/MarshalRLPTo in most cases +func (tx *DynamicFeeTx) marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value { + vv := arena.NewArray() + + vv.Set(arena.NewBigInt(tx.chainID())) + vv.Set(arena.NewUint(tx.nonce())) + // Add EIP-1559 related fields. + // For non-dynamic-fee-tx gas price is used. + vv.Set(arena.NewBigInt(tx.gasTipCap())) + vv.Set(arena.NewBigInt(tx.gasFeeCap())) + vv.Set(arena.NewUint(tx.gas())) + + // Address may be empty + if tx.to() != nil { + vv.Set(arena.NewCopyBytes(tx.to().Bytes())) + } else { + vv.Set(arena.NewNull()) + } + + vv.Set(arena.NewBigInt(tx.value())) + vv.Set(arena.NewCopyBytes(tx.input())) + + // Convert TxAccessList to RLP format and add it to the vv array. + accessListVV := arena.NewArray() + + for _, accessTuple := range tx.accessList() { + accessTupleVV := arena.NewArray() + accessTupleVV.Set(arena.NewCopyBytes(accessTuple.Address.Bytes())) + + storageKeysVV := arena.NewArray() + for _, storageKey := range accessTuple.StorageKeys { + storageKeysVV.Set(arena.NewCopyBytes(storageKey.Bytes())) + } + + accessTupleVV.Set(storageKeysVV) + accessListVV.Set(accessTupleVV) + } + + vv.Set(accessListVV) + + // signature values + v, r, s := tx.rawSignatureValues() + vv.Set(arena.NewBigInt(v)) + vv.Set(arena.NewBigInt(r)) + vv.Set(arena.NewBigInt(s)) + + return vv +} + +func (tx *DynamicFeeTx) copy() TxData { + cpy := &DynamicFeeTx{} + + if tx.chainID() != nil { + chainID := new(big.Int) + chainID.Set(tx.chainID()) + + cpy.setChainID(chainID) + } + + cpy.setNonce(tx.nonce()) + + if tx.gasTipCap() != nil { + gasTipCap := new(big.Int) + gasTipCap.Set(tx.gasTipCap()) + + cpy.setGasTipCap(gasTipCap) + } + + if tx.gasFeeCap() != nil { + gasFeeCap := new(big.Int) + gasFeeCap.Set(tx.gasFeeCap()) + + cpy.setGasFeeCap(gasFeeCap) + } + + cpy.setGas(tx.gas()) + + cpy.setTo(tx.to()) + + if tx.value() != nil { + value := new(big.Int) + value.Set(tx.value()) + + cpy.setValue(value) + } + + inputCopy := make([]byte, len(tx.input())) + copy(inputCopy, tx.input()[:]) + + cpy.setInput(inputCopy) + + v, r, s := tx.rawSignatureValues() + + var vCopy, rCopy, sCopy *big.Int + + if v != nil { + vCopy = new(big.Int) + vCopy.Set(v) + } + + if r != nil { + rCopy = new(big.Int) + rCopy.Set(r) + } + + if s != nil { + sCopy = new(big.Int) + sCopy.Set(s) + } + + cpy.setSignatureValues(vCopy, rCopy, sCopy) + + cpy.setAccessList(tx.accessList().Copy()) + + cpy.setHash(tx.hash()) + + return cpy +} diff --git a/types/legacy_tx.go b/types/legacy_tx.go new file mode 100644 index 0000000000..a31519a38a --- /dev/null +++ b/types/legacy_tx.go @@ -0,0 +1,263 @@ +package types + +import ( + "fmt" + "math/big" + + "github.com/umbracle/fastrlp" +) + +type LegacyTx struct { + Nonce uint64 + GasPrice *big.Int + Gas uint64 + To *Address + Value *big.Int + Input []byte + V, R, S *big.Int + Hash Hash + From Address +} + +func (tx *LegacyTx) transactionType() TxType { return LegacyTxType } +func (tx *LegacyTx) chainID() *big.Int { return nil } +func (tx *LegacyTx) input() []byte { return tx.Input } +func (tx *LegacyTx) gas() uint64 { return tx.Gas } +func (tx *LegacyTx) gasPrice() *big.Int { return tx.GasPrice } +func (tx *LegacyTx) gasTipCap() *big.Int { return nil } +func (tx *LegacyTx) gasFeeCap() *big.Int { return nil } +func (tx *LegacyTx) value() *big.Int { return tx.Value } +func (tx *LegacyTx) nonce() uint64 { return 0 } +func (tx *LegacyTx) to() *Address { return tx.To } +func (tx *LegacyTx) from() Address { return tx.From } + +func (tx *LegacyTx) hash() Hash { return tx.Hash } + +func (tx *LegacyTx) rawSignatureValues() (v, r, s *big.Int) { + return tx.V, tx.R, tx.S +} + +func (tx *LegacyTx) accessList() TxAccessList { return nil } + +// set methods for transaction fields +func (tx *LegacyTx) setSignatureValues(v, r, s *big.Int) { + tx.V, tx.R, tx.S = v, r, s +} + +func (tx *LegacyTx) setFrom(addr Address) { tx.From = addr } + +func (tx *LegacyTx) setGas(gas uint64) { + tx.Gas = gas +} + +func (tx *LegacyTx) setChainID(id *big.Int) {} + +func (tx *LegacyTx) setGasPrice(gas *big.Int) { + tx.GasPrice = gas +} + +func (tx *LegacyTx) setGasFeeCap(gas *big.Int) {} + +func (tx *LegacyTx) setGasTipCap(gas *big.Int) {} + +func (tx *LegacyTx) setTransactionType(t TxType) {} + +func (tx *LegacyTx) setValue(value *big.Int) { + tx.Value = value +} + +func (tx *LegacyTx) setInput(input []byte) { + tx.Input = input +} + +func (tx *LegacyTx) setTo(addeess *Address) { + tx.To = addeess +} + +func (tx *LegacyTx) setNonce(nonce uint64) { + tx.Nonce = nonce +} + +func (tx *LegacyTx) setAccessList(accessList TxAccessList) {} + +func (tx *LegacyTx) setHash(h Hash) { tx.Hash = h } + +// unmarshalRLPFrom unmarshals a Transaction in RLP format +// Be careful! This function does not de-serialize tx type, it assumes that t.Type is already set +// Hash calculation should also be done from the outside! +// Use UnmarshalRLP in most cases +func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { + numOfElems := 9 + elems, err := v.GetElems() + if err != nil { + return err + } + + getElem := func() *fastrlp.Value { + val := elems[0] + elems = elems[1:] + + return val + } + + if numElems := len(elems); numElems != numOfElems { + return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", numOfElems, numElems) + } + + // nonce + txNonce, err := getElem().GetUint64() + if err != nil { + return err + } + + tx.setNonce(txNonce) + + // gasPrice + txGasPrice := new(big.Int) + if err = getElem().GetBigInt(txGasPrice); err != nil { + return err + } + + tx.setGasPrice(txGasPrice) + + // gas + txGas, err := getElem().GetUint64() + if err != nil { + return err + } + + tx.setGas(txGas) + + // to + if vv, _ := getElem().Bytes(); len(vv) == 20 { + // address + addr := BytesToAddress(vv) + tx.setTo(&addr) + } else { + // reset To + tx.setTo(nil) + } + + // value + txValue := new(big.Int) + if err = getElem().GetBigInt(txValue); err != nil { + return err + } + + tx.setValue(txValue) + + // input + var txInput []byte + + txInput, err = getElem().GetBytes(txInput) + if err != nil { + return err + } + + tx.setInput(txInput) + + // V + txV := new(big.Int) + if err = getElem().GetBigInt(txV); err != nil { + return err + } + + // R + txR := new(big.Int) + if err = getElem().GetBigInt(txR); err != nil { + return err + } + + // S + txS := new(big.Int) + if err = getElem().GetBigInt(txS); err != nil { + return err + } + + tx.setSignatureValues(txV, txR, txS) + + return nil +} + +// MarshalRLPWith marshals the transaction to RLP with a specific fastrlp.Arena +// Be careful! This function does not serialize tx type as a first byte. +// Use MarshalRLP/MarshalRLPTo in most cases +func (tx *LegacyTx) marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value { + vv := arena.NewArray() + + vv.Set(arena.NewUint(tx.nonce())) + vv.Set(arena.NewBigInt(tx.gasPrice())) + vv.Set(arena.NewUint(tx.gas())) + + // Address may be empty + if tx.to() != nil { + vv.Set(arena.NewCopyBytes(tx.to().Bytes())) + } else { + vv.Set(arena.NewNull()) + } + + vv.Set(arena.NewBigInt(tx.value())) + vv.Set(arena.NewCopyBytes(tx.input())) + + // signature values + v, r, s := tx.rawSignatureValues() + vv.Set(arena.NewBigInt(v)) + vv.Set(arena.NewBigInt(r)) + vv.Set(arena.NewBigInt(s)) + + return vv +} + +func (tx *LegacyTx) copy() TxData { + cpy := &LegacyTx{} + + cpy.setNonce(tx.nonce()) + + if tx.gasPrice() != nil { + gasPrice := new(big.Int) + gasPrice.Set(tx.gasPrice()) + + cpy.setGasPrice(gasPrice) + } + + cpy.setGas(tx.gas()) + + cpy.setTo(tx.to()) + + if tx.value() != nil { + value := new(big.Int) + value.Set(tx.value()) + + cpy.setValue(value) + } + + inputCopy := make([]byte, len(tx.input())) + copy(inputCopy, tx.input()[:]) + + cpy.setInput(inputCopy) + + v, r, s := tx.rawSignatureValues() + + var vCopy, rCopy, sCopy *big.Int + + if v != nil { + vCopy = new(big.Int) + vCopy.Set(v) + } + + if r != nil { + rCopy = new(big.Int) + rCopy.Set(r) + } + + if s != nil { + sCopy = new(big.Int) + sCopy.Set(s) + } + + cpy.setSignatureValues(vCopy, rCopy, sCopy) + + cpy.setHash(tx.hash()) + + return cpy +} diff --git a/types/mixed_tx.go b/types/mixed_tx.go index da4094d159..51d595454e 100644 --- a/types/mixed_tx.go +++ b/types/mixed_tx.go @@ -40,7 +40,7 @@ func (tx *MixedTxn) rawSignatureValues() (v, r, s *big.Int) { } func (tx *MixedTxn) accessList() TxAccessList { - if tx.transactionType() == DynamicFeeTx { + if tx.transactionType() == DynamicFeeTxType { return tx.AccessList } diff --git a/types/receipt.go b/types/receipt.go index 93830506a7..a482d9f2bb 100644 --- a/types/receipt.go +++ b/types/receipt.go @@ -34,7 +34,7 @@ type Receipt struct { } func (r *Receipt) IsLegacyTx() bool { - return r.TransactionType == LegacyTx + return r.TransactionType == LegacyTxType } func (r *Receipt) SetStatus(s ReceiptStatus) { diff --git a/types/rlp_encoding_test.go b/types/rlp_encoding_test.go index 1f5c1ae3f5..37fe5756c7 100644 --- a/types/rlp_encoding_test.go +++ b/types/rlp_encoding_test.go @@ -41,9 +41,9 @@ func TestRLPEncoding(t *testing.T) { } } -func TestRLPMarshall_And_Unmarshall_Transaction(t *testing.T) { +func TestRLPMarshall_And_Unmarshall_Legacy_Transaction(t *testing.T) { addrTo := StringToAddress("11") - txn := NewTx(&MixedTxn{ + txn := NewTx(&LegacyTx{ Nonce: 0, GasPrice: big.NewInt(11), Gas: 11, @@ -57,7 +57,7 @@ func TestRLPMarshall_And_Unmarshall_Transaction(t *testing.T) { txn.ComputeHash() - unmarshalledTxn := NewTx(&MixedTxn{}) + unmarshalledTxn := NewTx(&LegacyTx{}) marshaledRlp := txn.MarshalRLP() if err := unmarshalledTxn.UnmarshalRLP(marshaledRlp); err != nil { @@ -149,7 +149,7 @@ func TestRLPUnmarshal_Header_ComputeHash(t *testing.T) { assert.Equal(t, h.Hash, h2.Hash) } -func TestRLPMarshall_And_Unmarshall_TypedTransaction(t *testing.T) { +/* func TestRLPMarshall_And_Unmarshall_TypedTransaction(t *testing.T) { addrTo := StringToAddress("11") addrFrom := StringToAddress("22") originalTx := NewTx(&MixedTxn{ @@ -168,14 +168,13 @@ func TestRLPMarshall_And_Unmarshall_TypedTransaction(t *testing.T) { }) txTypes := []TxType{ - StateTx, - LegacyTx, - DynamicFeeTx, + StateTxType, + LegacyTxType, + DynamicFeeTxType, } for _, v := range txTypes { t.Run(v.String(), func(t *testing.T) { - originalTx.SetTransactionType(v) originalTx.ComputeHash() txRLP := originalTx.MarshalRLP() @@ -188,15 +187,15 @@ func TestRLPMarshall_And_Unmarshall_TypedTransaction(t *testing.T) { assert.Equal(t, originalTx.Hash(), unmarshalledTx.Hash()) }) } -} +} */ func TestRLPMarshall_Unmarshall_Missing_Data(t *testing.T) { t.Parallel() txTypes := []TxType{ - StateTx, - LegacyTx, - DynamicFeeTx, + StateTxType, + LegacyTxType, + DynamicFeeTxType, } for _, txType := range txTypes { @@ -219,27 +218,27 @@ func TestRLPMarshall_Unmarshall_Missing_Data(t *testing.T) { name: fmt.Sprintf("[%s] Missing From", txType), expectedErr: false, omittedValues: map[string]bool{ - "ChainID": txType != DynamicFeeTx, - "GasTipCap": txType != DynamicFeeTx, - "GasFeeCap": txType != DynamicFeeTx, - "GasPrice": txType == DynamicFeeTx, - "AccessList": txType != DynamicFeeTx, - "From": txType != StateTx, + "ChainID": txType != DynamicFeeTxType, + "GasTipCap": txType != DynamicFeeTxType, + "GasFeeCap": txType != DynamicFeeTxType, + "GasPrice": txType == DynamicFeeTxType, + "AccessList": txType != DynamicFeeTxType, + "From": txType != StateTxType, }, - fromAddrSet: txType == StateTx, + fromAddrSet: txType == StateTxType, }, { name: fmt.Sprintf("[%s] Address set for state tx only", txType), expectedErr: false, omittedValues: map[string]bool{ - "ChainID": txType != DynamicFeeTx, - "GasTipCap": txType != DynamicFeeTx, - "GasFeeCap": txType != DynamicFeeTx, - "GasPrice": txType == DynamicFeeTx, - "AccessList": txType != DynamicFeeTx, - "From": txType != StateTx, + "ChainID": txType != DynamicFeeTxType, + "GasTipCap": txType != DynamicFeeTxType, + "GasFeeCap": txType != DynamicFeeTxType, + "GasPrice": txType == DynamicFeeTxType, + "AccessList": txType != DynamicFeeTxType, + "From": txType != StateTxType, }, - fromAddrSet: txType == StateTx, + fromAddrSet: txType == StateTxType, }, } @@ -255,14 +254,23 @@ func TestRLPMarshall_Unmarshall_Missing_Data(t *testing.T) { v, err := parser.Parse(testData) assert.Nil(t, err) - unmarshalledTx := NewTx(&MixedTxn{ - Type: txType, - }) + var unmarshalledTx *Transaction + + switch txType { + case AccessListTxType: + unmarshalledTx = NewTx(&AccessListTxn{}) + case StateTxType: + unmarshalledTx = NewTx(&StateTx{}) + case LegacyTxType: + unmarshalledTx = NewTx(&LegacyTx{}) + case DynamicFeeTxType: + unmarshalledTx = NewTx(&DynamicFeeTx{}) + } if tt.expectedErr { - assert.Error(t, unmarshalledTx.unmarshalRLPFrom(parser, v), tt.name) + assert.Error(t, unmarshalledTx.Inner.unmarshalRLPFrom(parser, v), tt.name) } else { - assert.NoError(t, unmarshalledTx.unmarshalRLPFrom(parser, v), tt.name) + assert.NoError(t, unmarshalledTx.Inner.unmarshalRLPFrom(parser, v), tt.name) assert.Equal(t, tt.fromAddrSet, len(unmarshalledTx.From()) != 0 && unmarshalledTx.From() != ZeroAddress, unmarshalledTx.Type().String(), unmarshalledTx.From()) } @@ -281,15 +289,15 @@ func TestRLPMarshall_And_Unmarshall_TxType(t *testing.T) { }{ { name: "StateTx", - txType: StateTx, + txType: StateTxType, }, { name: "LegacyTx", - txType: LegacyTx, + txType: LegacyTxType, }, { name: "DynamicFeeTx", - txType: DynamicFeeTx, + txType: DynamicFeeTxType, }, { name: "undefined type", diff --git a/types/rlp_marshal.go b/types/rlp_marshal.go index 7cb8b143b2..e8faf9b585 100644 --- a/types/rlp_marshal.go +++ b/types/rlp_marshal.go @@ -40,11 +40,11 @@ func (b *Block) MarshalRLPWith(ar *fastrlp.Arena) *fastrlp.Value { v0 := ar.NewArray() for _, tx := range b.Transactions { - if tx.Type() != LegacyTx { + if tx.Type() != LegacyTxType { v0.Set(ar.NewCopyBytes([]byte{byte(tx.Type())})) } - v0.Set(tx.MarshalRLPWith(ar)) + v0.Set(tx.Inner.marshalRLPWith(ar)) } vv.Set(v0) @@ -183,118 +183,9 @@ func (t *Transaction) MarshalRLP() []byte { } func (t *Transaction) MarshalRLPTo(dst []byte) []byte { - if t.Type() != LegacyTx { + if t.Type() != LegacyTxType { dst = append(dst, byte(t.Type())) } - return MarshalRLPTo(t.MarshalRLPWith, dst) -} - -// MarshalRLPWith marshals the transaction to RLP with a specific fastrlp.Arena -// Be careful! This function does not serialize tx type as a first byte. -// Use MarshalRLP/MarshalRLPTo in most cases -func (t *Transaction) MarshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value { - vv := arena.NewArray() - - switch t.Inner.(type) { - case *MixedTxn: - // Check Transaction1559Payload there https://eips.ethereum.org/EIPS/eip-1559#specification - if t.Type() == DynamicFeeTx { - vv.Set(arena.NewBigInt(t.ChainID())) - } - - vv.Set(arena.NewUint(t.Nonce())) - - if t.Type() == DynamicFeeTx { - // Add EIP-1559 related fields. - // For non-dynamic-fee-tx gas price is used. - vv.Set(arena.NewBigInt(t.GasTipCap())) - vv.Set(arena.NewBigInt(t.GasFeeCap())) - } else { - vv.Set(arena.NewBigInt(t.GasPrice())) - } - - vv.Set(arena.NewUint(t.Gas())) - - // Address may be empty - if t.To() != nil { - vv.Set(arena.NewCopyBytes(t.To().Bytes())) - } else { - vv.Set(arena.NewNull()) - } - - vv.Set(arena.NewBigInt(t.Value())) - vv.Set(arena.NewCopyBytes(t.Input())) - - // Specify access list as per spec. - if t.Type() == DynamicFeeTx { - // Convert TxAccessList to RLP format and add it to the vv array. - accessListVV := arena.NewArray() - - for _, accessTuple := range t.AccessList() { - accessTupleVV := arena.NewArray() - accessTupleVV.Set(arena.NewCopyBytes(accessTuple.Address.Bytes())) - - storageKeysVV := arena.NewArray() - for _, storageKey := range accessTuple.StorageKeys { - storageKeysVV.Set(arena.NewCopyBytes(storageKey.Bytes())) - } - - accessTupleVV.Set(storageKeysVV) - accessListVV.Set(accessTupleVV) - } - - vv.Set(accessListVV) - } - - // signature values - v, r, s := t.RawSignatureValues() - vv.Set(arena.NewBigInt(v)) - vv.Set(arena.NewBigInt(r)) - vv.Set(arena.NewBigInt(s)) - - if t.Type() == StateTx { - vv.Set(arena.NewCopyBytes(t.From().Bytes())) - } - case *AccessListTxn: - vv.Set(arena.NewBigInt(t.ChainID())) - vv.Set(arena.NewUint(t.Nonce())) - vv.Set(arena.NewBigInt(t.GasPrice())) - vv.Set(arena.NewUint(t.Gas())) - - // Address may be empty - if t.To() != nil { - vv.Set(arena.NewCopyBytes(t.To().Bytes())) - } else { - vv.Set(arena.NewNull()) - } - - vv.Set(arena.NewBigInt(t.Value())) - vv.Set(arena.NewCopyBytes(t.Input())) - - // add accessList - accessListVV := arena.NewArray() - - for _, accessTuple := range t.AccessList() { - accessTupleVV := arena.NewArray() - accessTupleVV.Set(arena.NewCopyBytes(accessTuple.Address.Bytes())) - - storageKeysVV := arena.NewArray() - for _, storageKey := range accessTuple.StorageKeys { - storageKeysVV.Set(arena.NewCopyBytes(storageKey.Bytes())) - } - - accessTupleVV.Set(storageKeysVV) - accessListVV.Set(accessTupleVV) - } - - vv.Set(accessListVV) - - v, r, s := t.RawSignatureValues() - vv.Set(arena.NewBigInt(v)) - vv.Set(arena.NewBigInt(r)) - vv.Set(arena.NewBigInt(s)) - } - - return vv + return MarshalRLPTo(t.Inner.marshalRLPWith, dst) } diff --git a/types/rlp_marshal_storage.go b/types/rlp_marshal_storage.go index 82cfbafe86..a38152fa67 100644 --- a/types/rlp_marshal_storage.go +++ b/types/rlp_marshal_storage.go @@ -44,12 +44,12 @@ func (t *Transaction) MarshalStoreRLPTo(dst []byte) []byte { func (t *Transaction) marshalStoreRLPWith(a *fastrlp.Arena) *fastrlp.Value { vv := a.NewArray() - if t.Type() != LegacyTx { + if t.Type() != LegacyTxType { vv.Set(a.NewBytes([]byte{byte(t.Type())})) } // consensus part - vv.Set(t.MarshalRLPWith(a)) + vv.Set(t.Inner.marshalRLPWith(a)) // context part vv.Set(a.NewBytes(t.From().Bytes())) diff --git a/types/rlp_unmarshal.go b/types/rlp_unmarshal.go index 981d789c7f..76cbe766e3 100644 --- a/types/rlp_unmarshal.go +++ b/types/rlp_unmarshal.go @@ -2,7 +2,6 @@ package types import ( "fmt" - "math/big" "github.com/umbracle/fastrlp" ) @@ -45,7 +44,7 @@ func unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value, cb unmarshalRLPFromFu for i := 0; i < len(elems); i++ { // Non-legacy tx raw contains a tx type prefix in the beginning according to EIP-2718. // Here we check if the first element is a tx type and unmarshal it first. - txType := LegacyTx + txType := LegacyTxType if elems[i].Type() == fastrlp.TypeBytes { if err = txType.unmarshalRLPFrom(p, elems[i]); err != nil { return err @@ -107,15 +106,17 @@ func (b *Block) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { if err = unmarshalRLPFrom(p, elems[1], func(txType TxType, p *fastrlp.Parser, v *fastrlp.Value) error { var bTxn *Transaction switch txType { - case AccessListTx: + case AccessListTxType: bTxn = NewTx(&AccessListTxn{}) - case DynamicFeeTx, LegacyTx, StateTx: - bTxn = NewTx(&MixedTxn{ - Type: txType, - }) + case LegacyTxType: + bTxn = NewTx(&LegacyTx{}) + case StateTxType: + bTxn = NewTx(&StateTx{}) + case DynamicFeeTxType: + bTxn = NewTx(&DynamicFeeTx{}) } - if err = bTxn.unmarshalRLPFrom(p, v); err != nil { + if err = bTxn.Inner.unmarshalRLPFrom(p, v); err != nil { return err } @@ -259,7 +260,7 @@ func (r *Receipts) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { } func (r *Receipt) UnmarshalRLP(input []byte) error { - r.TransactionType = LegacyTx + r.TransactionType = LegacyTxType offset := 0 if len(input) > 0 && input[0] <= RLPSingleByteUpperLimit { @@ -370,7 +371,7 @@ func (l *Log) unmarshalRLPFrom(_ *fastrlp.Parser, v *fastrlp.Value) error { // UnmarshalRLP unmarshals transaction from byte slice // Caution: Hash calculation should be done from the outside! func (t *Transaction) UnmarshalRLP(input []byte) error { - txType := LegacyTx + txType := LegacyTxType offset := 0 if len(input) > 0 && input[0] <= RLPSingleByteUpperLimit { @@ -386,340 +387,9 @@ func (t *Transaction) UnmarshalRLP(input []byte) error { t.InitInnerData(txType) - if err := UnmarshalRlp(t.unmarshalRLPFrom, input[offset:]); err != nil { + if err := UnmarshalRlp(t.Inner.unmarshalRLPFrom, input[offset:]); err != nil { return err } return nil } - -// unmarshalRLPFrom unmarshals a Transaction in RLP format -// Be careful! This function does not de-serialize tx type, it assumes that t.Type is already set -// Hash calculation should also be done from the outside! -// Use UnmarshalRLP in most cases -func (t *Transaction) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { - elems, err := v.GetElems() - if err != nil { - return err - } - - getElem := func() *fastrlp.Value { - val := elems[0] - elems = elems[1:] - - return val - } - - var num int - - switch t.Type() { - case LegacyTx: - num = 9 - case StateTx: - num = 10 - case DynamicFeeTx: - num = 12 - case AccessListTx: - num = 11 - default: - return fmt.Errorf("transaction type %d not found", t.Type()) - } - - if numElems := len(elems); numElems != num { - return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", num, numElems) - } - - switch t.Inner.(type) { - case *MixedTxn: - // Load Chain ID for dynamic transactions - if t.Type() == DynamicFeeTx { - txChainID := new(big.Int) - if err = getElem().GetBigInt(txChainID); err != nil { - return err - } - - t.SetChainID(txChainID) - } - - // nonce - txNonce, err := getElem().GetUint64() - if err != nil { - return err - } - - t.SetNonce(txNonce) - - if t.Type() == DynamicFeeTx { - // gasTipCap - txGasTipCap := new(big.Int) - if err = getElem().GetBigInt(txGasTipCap); err != nil { - return err - } - - t.SetGasTipCap(txGasTipCap) - - // gasFeeCap - txGasFeeCap := new(big.Int) - if err = getElem().GetBigInt(txGasFeeCap); err != nil { - return err - } - - t.SetGasFeeCap(txGasFeeCap) - } else { - // gasPrice - txGasPrice := new(big.Int) - if err = getElem().GetBigInt(txGasPrice); err != nil { - return err - } - - t.SetGasPrice(txGasPrice) - } - - // gas - txGas, err := getElem().GetUint64() - if err != nil { - return err - } - - t.SetGas(txGas) - - // to - if vv, _ := getElem().Bytes(); len(vv) == 20 { - // address - addr := BytesToAddress(vv) - t.SetTo(&addr) - } else { - // reset To - t.SetTo(nil) - } - - // value - txValue := new(big.Int) - if err = getElem().GetBigInt(txValue); err != nil { - return err - } - - t.SetValue(txValue) - - // input - var txInput []byte - - txInput, err = getElem().GetBytes(txInput) - if err != nil { - return err - } - - t.SetInput(txInput) - - if t.Type() == DynamicFeeTx { - accessListVV, err := getElem().GetElems() - if err != nil { - return err - } - - var txAccessList TxAccessList - if len(accessListVV) != 0 { - txAccessList = make(TxAccessList, len(accessListVV)) - } - - for i, accessTupleVV := range accessListVV { - accessTupleElems, err := accessTupleVV.GetElems() - if err != nil { - return err - } - - // Read the address - addressVV := accessTupleElems[0] - - addressBytes, err := addressVV.Bytes() - if err != nil { - return err - } - - txAccessList[i].Address = BytesToAddress(addressBytes) - - // Read the storage keys - storageKeysArrayVV := accessTupleElems[1] - - storageKeysElems, err := storageKeysArrayVV.GetElems() - if err != nil { - return err - } - - txAccessList[i].StorageKeys = make([]Hash, len(storageKeysElems)) - - for j, storageKeyVV := range storageKeysElems { - storageKeyBytes, err := storageKeyVV.Bytes() - if err != nil { - return err - } - - txAccessList[i].StorageKeys[j] = BytesToHash(storageKeyBytes) - } - } - - t.SetAccessList(txAccessList) - } - - // V - txV := new(big.Int) - if err = getElem().GetBigInt(txV); err != nil { - return err - } - - // R - txR := new(big.Int) - if err = getElem().GetBigInt(txR); err != nil { - return err - } - - // S - txS := new(big.Int) - if err = getElem().GetBigInt(txS); err != nil { - return err - } - - t.SetSignatureValues(txV, txR, txS) - - if t.Type() == StateTx { - t.SetFrom(ZeroAddress) - - // We need to set From field for state transaction, - // because we are using unique, predefined address, for sending such transactions - if vv, err := getElem().Bytes(); err == nil && len(vv) == AddressLength { - // address - t.SetFrom(BytesToAddress(vv)) - } - } - case *AccessListTxn: - txChainID := new(big.Int) - if err = getElem().GetBigInt(txChainID); err != nil { - return err - } - - t.SetChainID(txChainID) - - // nonce - txNonce, err := getElem().GetUint64() - if err != nil { - return err - } - - t.SetNonce(txNonce) - - // gasPrice - txGasPrice := new(big.Int) - if err = getElem().GetBigInt(txGasPrice); err != nil { - return err - } - - t.SetGasPrice(txGasPrice) - - // gas - txGas, err := getElem().GetUint64() - if err != nil { - return err - } - - t.SetGas(txGas) - - // to - if vv, _ := getElem().Bytes(); len(vv) == 20 { - // address - addr := BytesToAddress(vv) - t.SetTo(&addr) - } else { - // reset To - t.SetTo(nil) - } - - // value - txValue := new(big.Int) - if err = getElem().GetBigInt(txValue); err != nil { - return err - } - - t.SetValue(txValue) - - // input - var txInput []byte - - txInput, err = getElem().GetBytes(txInput) - if err != nil { - return err - } - - t.SetInput(txInput) - - //accessList - accessListVV, err := getElem().GetElems() - if err != nil { - return err - } - - var txAccessList TxAccessList - if len(accessListVV) != 0 { - txAccessList = make(TxAccessList, len(accessListVV)) - } - - for i, accessTupleVV := range accessListVV { - accessTupleElems, err := accessTupleVV.GetElems() - if err != nil { - return err - } - - // Read the address - addressVV := accessTupleElems[0] - - addressBytes, err := addressVV.Bytes() - if err != nil { - return err - } - - txAccessList[i].Address = BytesToAddress(addressBytes) - - // Read the storage keys - storageKeysArrayVV := accessTupleElems[1] - - storageKeysElems, err := storageKeysArrayVV.GetElems() - if err != nil { - return err - } - - txAccessList[i].StorageKeys = make([]Hash, len(storageKeysElems)) - - for j, storageKeyVV := range storageKeysElems { - storageKeyBytes, err := storageKeyVV.Bytes() - if err != nil { - return err - } - - txAccessList[i].StorageKeys[j] = BytesToHash(storageKeyBytes) - } - } - - t.SetAccessList(txAccessList) - - // V - txV := new(big.Int) - if err = getElem().GetBigInt(txV); err != nil { - return err - } - - // R - txR := new(big.Int) - if err = getElem().GetBigInt(txR); err != nil { - return err - } - - // S - txS := new(big.Int) - if err = getElem().GetBigInt(txS); err != nil { - return err - } - - t.SetSignatureValues(txV, txR, txS) - } - - return nil -} diff --git a/types/rlp_unmarshal_storage.go b/types/rlp_unmarshal_storage.go index f83a160ed9..53afd866f2 100644 --- a/types/rlp_unmarshal_storage.go +++ b/types/rlp_unmarshal_storage.go @@ -31,12 +31,14 @@ func (b *Body) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { if err = unmarshalRLPFrom(p, tuple[0], func(txType TxType, p *fastrlp.Parser, v *fastrlp.Value) error { var bTxn *Transaction switch txType { - case AccessListTx: + case AccessListTxType: bTxn = NewTx(&AccessListTxn{}) - case DynamicFeeTx, StateTx, LegacyTx: - bTxn = NewTx(&MixedTxn{ - Type: txType, - }) + case LegacyTxType: + bTxn = NewTx(&LegacyTx{}) + case StateTxType: + bTxn = NewTx(&StateTx{}) + case DynamicFeeTxType: + bTxn = NewTx(&DynamicFeeTx{}) } if err = bTxn.unmarshalStoreRLPFrom(p, v); err != nil { @@ -70,8 +72,6 @@ func (b *Body) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // UnmarshalStoreRLP unmarshals transaction from byte slice. Hash must be computed manually after! func (t *Transaction) UnmarshalStoreRLP(input []byte) error { - t.SetTransactionType(LegacyTx) - offset := 0 if len(input) > 0 && input[0] <= RLPSingleByteUpperLimit { @@ -80,7 +80,16 @@ func (t *Transaction) UnmarshalStoreRLP(input []byte) error { return err } - t.SetTransactionType(tType) + switch tType { + case LegacyTxType: + t.SetTxData(&LegacyTx{}) + case StateTxType: + t.SetTxData(&StateTx{}) + case AccessListTxType: + t.SetTxData(&AccessListTxn{}) + default: + t.SetTxData(&DynamicFeeTx{}) + } offset = 1 } @@ -105,13 +114,11 @@ func (t *Transaction) unmarshalStoreRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) return err } - t.SetTransactionType(tType) - elems = elems[1:] } // consensus part - if err = t.unmarshalRLPFrom(p, elems[0]); err != nil { + if err = t.Inner.unmarshalRLPFrom(p, elems[0]); err != nil { return err } @@ -144,7 +151,7 @@ func (r *Receipts) unmarshalStoreRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er } func (r *Receipt) UnmarshalStoreRLP(input []byte) error { - r.TransactionType = LegacyTx + r.TransactionType = LegacyTxType offset := 0 if len(input) > 0 && input[0] <= RLPSingleByteUpperLimit { diff --git a/types/state_tx.go b/types/state_tx.go new file mode 100644 index 0000000000..14dd1cc61b --- /dev/null +++ b/types/state_tx.go @@ -0,0 +1,277 @@ +package types + +import ( + "fmt" + "math/big" + + "github.com/umbracle/fastrlp" +) + +type StateTx struct { + Nonce uint64 + GasPrice *big.Int + Gas uint64 + To *Address + Value *big.Int + Input []byte + V, R, S *big.Int + From Address + Hash Hash +} + +func (tx *StateTx) transactionType() TxType { return StateTxType } +func (tx *StateTx) chainID() *big.Int { return nil } +func (tx *StateTx) input() []byte { return tx.Input } +func (tx *StateTx) gas() uint64 { return tx.Gas } +func (tx *StateTx) gasPrice() *big.Int { return tx.GasPrice } +func (tx *StateTx) gasTipCap() *big.Int { return nil } +func (tx *StateTx) gasFeeCap() *big.Int { return nil } +func (tx *StateTx) value() *big.Int { return tx.Value } +func (tx *StateTx) nonce() uint64 { return tx.Nonce } +func (tx *StateTx) to() *Address { return tx.To } +func (tx *StateTx) from() Address { return tx.From } + +func (tx *StateTx) hash() Hash { return tx.Hash } + +func (tx *StateTx) rawSignatureValues() (v, r, s *big.Int) { + return tx.V, tx.R, tx.S +} + +func (tx *StateTx) accessList() TxAccessList { + return nil +} + +// set methods for transaction fields +func (tx *StateTx) setSignatureValues(v, r, s *big.Int) { + tx.V, tx.R, tx.S = v, r, s +} + +func (tx *StateTx) setFrom(addr Address) { + tx.From = addr +} + +func (tx *StateTx) setGas(gas uint64) { + tx.Gas = gas +} + +func (tx *StateTx) setChainID(id *big.Int) {} + +func (tx *StateTx) setGasPrice(gas *big.Int) { + tx.GasPrice = gas +} + +func (tx *StateTx) setGasFeeCap(gas *big.Int) {} + +func (tx *StateTx) setGasTipCap(gas *big.Int) {} + +func (tx *StateTx) setValue(value *big.Int) { + tx.Value = value +} + +func (tx *StateTx) setInput(input []byte) { + tx.Input = input +} + +func (tx *StateTx) setTo(addeess *Address) { + tx.To = addeess +} + +func (tx *StateTx) setNonce(nonce uint64) { + tx.Nonce = nonce +} + +func (tx *StateTx) setAccessList(accessList TxAccessList) {} + +func (tx *StateTx) setHash(h Hash) { tx.Hash = h } + +// unmarshalRLPFrom unmarshals a Transaction in RLP format +// Be careful! This function does not de-serialize tx type, it assumes that t.Type is already set +// Hash calculation should also be done from the outside! +// Use UnmarshalRLP in most cases +func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { + numOfElems := 10 + elems, err := v.GetElems() + if err != nil { + return err + } + + getElem := func() *fastrlp.Value { + val := elems[0] + elems = elems[1:] + + return val + } + + if numElems := len(elems); numElems != numOfElems { + return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", numOfElems, numElems) + } + + // nonce + txNonce, err := getElem().GetUint64() + if err != nil { + return err + } + + tx.setNonce(txNonce) + + // gasPrice + txGasPrice := new(big.Int) + if err = getElem().GetBigInt(txGasPrice); err != nil { + return err + } + + tx.setGasPrice(txGasPrice) + + // gas + txGas, err := getElem().GetUint64() + if err != nil { + return err + } + + tx.setGas(txGas) + + // to + if vv, _ := getElem().Bytes(); len(vv) == 20 { + // address + addr := BytesToAddress(vv) + tx.setTo(&addr) + } else { + // reset To + tx.setTo(nil) + } + + // value + txValue := new(big.Int) + if err = getElem().GetBigInt(txValue); err != nil { + return err + } + + tx.setValue(txValue) + + // input + var txInput []byte + + txInput, err = getElem().GetBytes(txInput) + if err != nil { + return err + } + + tx.setInput(txInput) + + // V + txV := new(big.Int) + if err = getElem().GetBigInt(txV); err != nil { + return err + } + + // R + txR := new(big.Int) + if err = getElem().GetBigInt(txR); err != nil { + return err + } + + // S + txS := new(big.Int) + if err = getElem().GetBigInt(txS); err != nil { + return err + } + + tx.setSignatureValues(txV, txR, txS) + + tx.setFrom(ZeroAddress) + + // We need to set From field for state transaction, + // because we are using unique, predefined address, for sending such transactions + if vv, err := getElem().Bytes(); err == nil && len(vv) == AddressLength { + // address + tx.setFrom(BytesToAddress(vv)) + } + + return nil +} + +// MarshalRLPWith marshals the transaction to RLP with a specific fastrlp.Arena +// Be careful! This function does not serialize tx type as a first byte. +// Use MarshalRLP/MarshalRLPTo in most cases +func (tx *StateTx) marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value { + vv := arena.NewArray() + + vv.Set(arena.NewUint(tx.nonce())) + vv.Set(arena.NewBigInt(tx.gasPrice())) + vv.Set(arena.NewUint(tx.gas())) + // Address may be empty + if tx.to() != nil { + vv.Set(arena.NewCopyBytes(tx.to().Bytes())) + } else { + vv.Set(arena.NewNull()) + } + + vv.Set(arena.NewBigInt(tx.value())) + vv.Set(arena.NewCopyBytes(tx.input())) + + // signature values + v, r, s := tx.rawSignatureValues() + vv.Set(arena.NewBigInt(v)) + vv.Set(arena.NewBigInt(r)) + vv.Set(arena.NewBigInt(s)) + + vv.Set(arena.NewCopyBytes(tx.from().Bytes())) + + return vv +} + +func (tx *StateTx) copy() TxData { + cpy := &StateTx{} + + cpy.setNonce(tx.nonce()) + + if tx.gasPrice() != nil { + gasPrice := new(big.Int) + gasPrice.Set(tx.gasPrice()) + + cpy.setGasPrice(gasPrice) + } + + cpy.setGas(tx.gas()) + + cpy.setTo(tx.to()) + + if tx.value() != nil { + value := new(big.Int) + value.Set(tx.value()) + + cpy.setValue(value) + } + + inputCopy := make([]byte, len(tx.input())) + copy(inputCopy, tx.input()[:]) + + cpy.setInput(inputCopy) + + v, r, s := tx.rawSignatureValues() + + var vCopy, rCopy, sCopy *big.Int + + if v != nil { + vCopy = new(big.Int) + vCopy.Set(v) + } + + if r != nil { + rCopy = new(big.Int) + rCopy.Set(r) + } + + if s != nil { + sCopy = new(big.Int) + sCopy.Set(s) + } + + cpy.setSignatureValues(vCopy, rCopy, sCopy) + + cpy.setFrom(tx.from()) + + cpy.setHash(tx.hash()) + + return cpy +} diff --git a/types/transaction.go b/types/transaction.go index 64c508c323..d6a5240ef0 100644 --- a/types/transaction.go +++ b/types/transaction.go @@ -7,6 +7,7 @@ import ( "github.com/0xPolygon/polygon-edge/helper/common" "github.com/0xPolygon/polygon-edge/helper/keccak" + "github.com/umbracle/fastrlp" ) const ( @@ -19,17 +20,17 @@ type TxType byte // List of supported transaction types const ( - LegacyTx TxType = 0x0 - AccessListTx TxType = 0x01 - DynamicFeeTx TxType = 0x02 - StateTx TxType = 0x7f + LegacyTxType TxType = 0x0 + AccessListTxType TxType = 0x01 + DynamicFeeTxType TxType = 0x02 + StateTxType TxType = 0x7f ) func txTypeFromByte(b byte) (TxType, error) { tt := TxType(b) switch tt { - case LegacyTx, StateTx, DynamicFeeTx, AccessListTx: + case LegacyTxType, StateTxType, DynamicFeeTxType, AccessListTxType: return tt, nil default: return tt, fmt.Errorf("unknown transaction type: %d", b) @@ -39,13 +40,13 @@ func txTypeFromByte(b byte) (TxType, error) { // String returns string representation of the transaction type. func (t TxType) String() (s string) { switch t { - case LegacyTx: + case LegacyTxType: return "LegacyTx" - case StateTx: + case StateTxType: return "StateTx" - case DynamicFeeTx: + case DynamicFeeTxType: return "DynamicFeeTx" - case AccessListTx: + case AccessListTxType: return "AccessListTx" } @@ -72,13 +73,15 @@ func NewTx(inner TxData) *Transaction { // depending on the value of txType. func (t *Transaction) InitInnerData(txType TxType) { switch txType { - case AccessListTx: + case AccessListTxType: t.Inner = &AccessListTxn{} + case StateTxType: + t.Inner = &StateTx{} + case LegacyTxType: + t.Inner = &LegacyTx{} default: - t.Inner = &MixedTxn{} + t.Inner = &DynamicFeeTx{} } - - t.Inner.setTransactionType(txType) } type TxData interface { @@ -105,13 +108,15 @@ type TxData interface { setGasPrice(*big.Int) setGasFeeCap(*big.Int) setGasTipCap(*big.Int) - setTransactionType(TxType) setValue(*big.Int) setInput([]byte) setTo(address *Address) setNonce(uint64) setAccessList(TxAccessList) setHash(Hash) + unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error + marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value + copy() TxData } func (t *Transaction) Type() TxType { @@ -199,10 +204,6 @@ func (t *Transaction) SetGasTipCap(gas *big.Int) { t.Inner.setGasTipCap(gas) } -func (t *Transaction) SetTransactionType(tType TxType) { - t.Inner.setTransactionType(tType) -} - func (t *Transaction) SetValue(value *big.Int) { t.Inner.setValue(value) } @@ -258,102 +259,12 @@ func (t *Transaction) Copy() *Transaction { } newTx := new(Transaction) - innerCopy := CopyTxData(t.Inner) + innerCopy := t.Inner.copy() newTx.Inner = innerCopy return newTx } -// CopyTxData creates a deep copy of the provided TxData -func CopyTxData(data TxData) TxData { - if data == nil { - return nil - } - - var copyData TxData - switch data.(type) { - case *MixedTxn: - copyData = &MixedTxn{} - case *AccessListTxn: - copyData = &AccessListTxn{} - } - - if copyData == nil { - return nil - } - - copyData.setNonce(data.nonce()) - copyData.setFrom(data.from()) - copyData.setTo(data.to()) - copyData.setHash(data.hash()) - copyData.setTransactionType(data.transactionType()) - copyData.setGas(data.gas()) - - if data.chainID() != nil { - chainID := new(big.Int) - chainID.Set(data.chainID()) - - copyData.setChainID(chainID) - } - - if data.gasPrice() != nil { - gasPrice := new(big.Int) - gasPrice.Set(data.gasPrice()) - - copyData.setGasPrice(gasPrice) - } - - if data.gasTipCap() != nil { - gasTipCap := new(big.Int) - gasTipCap.Set(data.gasTipCap()) - - copyData.setGasTipCap(gasTipCap) - } - - if data.gasFeeCap() != nil { - gasFeeCap := new(big.Int) - gasFeeCap.Set(data.gasFeeCap()) - - copyData.setGasFeeCap(gasFeeCap) - } - - if data.value() != nil { - value := new(big.Int) - value.Set(data.value()) - - copyData.setValue(value) - } - - v, r, s := data.rawSignatureValues() - - var vCopy, rCopy, sCopy *big.Int - - if v != nil { - vCopy = new(big.Int) - vCopy.Set(v) - } - - if r != nil { - rCopy = new(big.Int) - rCopy.Set(r) - } - - if s != nil { - sCopy = new(big.Int) - sCopy.Set(s) - } - - copyData.setSignatureValues(vCopy, rCopy, sCopy) - - inputCopy := make([]byte, len(data.input())) - copy(inputCopy, data.input()[:]) - - copyData.setInput(inputCopy) - copyData.setAccessList(data.accessList().Copy()) - - return copyData -} - // Cost returns gas * gasPrice + value func (t *Transaction) Cost() *big.Int { var factor *big.Int @@ -435,7 +346,7 @@ func (t *Transaction) EffectiveGasTip(baseFee *big.Int) *big.Int { // Spec: https://eips.ethereum.org/EIPS/eip-1559#specification func (t *Transaction) GetGasTipCap() *big.Int { switch t.Type() { - case DynamicFeeTx: + case DynamicFeeTxType: return t.GasTipCap() default: return t.GasPrice() @@ -446,13 +357,17 @@ func (t *Transaction) GetGasTipCap() *big.Int { // Spec: https://eips.ethereum.org/EIPS/eip-1559#specification func (t *Transaction) GetGasFeeCap() *big.Int { switch t.Type() { - case DynamicFeeTx: + case DynamicFeeTxType: return t.GasFeeCap() default: return t.GasPrice() } } +func (t *Transaction) SetTxData(data TxData) { + t.Inner = data +} + // FindTxByHash returns transaction and its index from a slice of transactions func FindTxByHash(txs []*Transaction, hash Hash) (*Transaction, int) { for idx, txn := range txs { diff --git a/types/types_test.go b/types/types_test.go index aae6150e70..170c4f30e0 100644 --- a/types/types_test.go +++ b/types/types_test.go @@ -68,11 +68,10 @@ func TestEIP55(t *testing.T) { func TestTransactionCopy(t *testing.T) { addrTo := StringToAddress("11") - txn := NewTx(&MixedTxn{ + txn := NewTx(&DynamicFeeTx{ Nonce: 0, GasTipCap: big.NewInt(11), GasFeeCap: big.NewInt(11), - GasPrice: big.NewInt(11), Gas: 11, To: &addrTo, Value: big.NewInt(1), From 283ceedae6122fc0fae30468ff58b7a6296a6d39 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Tue, 6 Feb 2024 11:25:20 +0100 Subject: [PATCH 02/18] Ut fix --- blockchain/blockchain_test.go | 24 ++++++------ jsonrpc/debug_endpoint_test.go | 1 + jsonrpc/eth_endpoint_test.go | 18 ++++----- jsonrpc/helper.go | 11 +++--- jsonrpc/helper_test.go | 69 ++++++++++++++++------------------ txpool/txpool.go | 8 ++-- txpool/txpool_test.go | 38 +++++++++++-------- types/dynamic_fee_tx.go | 4 +- types/legacy_tx.go | 10 +++-- 9 files changed, 97 insertions(+), 86 deletions(-) diff --git a/blockchain/blockchain_test.go b/blockchain/blockchain_test.go index 4c67d0effe..511a79df3c 100644 --- a/blockchain/blockchain_test.go +++ b/blockchain/blockchain_test.go @@ -654,7 +654,7 @@ func TestBlockchainWriteBody(t *testing.T) { t.Run("should recover from address and store to storage", func(t *testing.T) { t.Parallel() - tx := types.NewTx(&types.StateTx{ + tx := types.NewTx(&types.LegacyTx{ Value: big.NewInt(10), V: big.NewInt(1), }) @@ -715,8 +715,8 @@ func Test_recoverFromFieldsInBlock(t *testing.T) { }, } - tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: addr1}) - tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: types.ZeroAddress}) + tx1 := types.NewTx(&types.LegacyTx{Nonce: 0, From: addr1}) + tx2 := types.NewTx(&types.LegacyTx{Nonce: 1, From: types.ZeroAddress}) computeTxHashes(tx1, tx2) @@ -745,9 +745,9 @@ func Test_recoverFromFieldsInBlock(t *testing.T) { }, } - tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: types.ZeroAddress}) - tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: types.ZeroAddress}) - tx3 := types.NewTx(&types.StateTx{Nonce: 2, From: types.ZeroAddress}) + tx1 := types.NewTx(&types.LegacyTx{Nonce: 0, From: types.ZeroAddress}) + tx2 := types.NewTx(&types.LegacyTx{Nonce: 1, From: types.ZeroAddress}) + tx3 := types.NewTx(&types.LegacyTx{Nonce: 2, From: types.ZeroAddress}) computeTxHashes(tx1, tx2, tx3) @@ -801,8 +801,8 @@ func Test_recoverFromFieldsInTransactions(t *testing.T) { }, } - tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: addr1}) - tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: types.ZeroAddress}) + tx1 := types.NewTx(&types.LegacyTx{Nonce: 0, From: addr1}) + tx2 := types.NewTx(&types.LegacyTx{Nonce: 1, From: types.ZeroAddress}) computeTxHashes(tx1, tx2) @@ -830,9 +830,9 @@ func Test_recoverFromFieldsInTransactions(t *testing.T) { }, } - tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: types.ZeroAddress}) - tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: types.ZeroAddress}) - tx3 := types.NewTx(&types.StateTx{Nonce: 2, From: types.ZeroAddress}) + tx1 := types.NewTx(&types.LegacyTx{Nonce: 0, From: types.ZeroAddress}) + tx2 := types.NewTx(&types.LegacyTx{Nonce: 1, From: types.ZeroAddress}) + tx3 := types.NewTx(&types.LegacyTx{Nonce: 2, From: types.ZeroAddress}) computeTxHashes(tx1, tx2, tx3) @@ -900,7 +900,7 @@ func TestBlockchainReadBody(t *testing.T) { batchWriter := storage.NewBatchWriter(b.db) - tx := types.NewTx(&types.StateTx{ + tx := types.NewTx(&types.LegacyTx{ Value: big.NewInt(10), V: big.NewInt(1), }) diff --git a/jsonrpc/debug_endpoint_test.go b/jsonrpc/debug_endpoint_test.go index 905e92c375..bf1cc5b96f 100644 --- a/jsonrpc/debug_endpoint_test.go +++ b/jsonrpc/debug_endpoint_test.go @@ -603,6 +603,7 @@ func TestTraceCall(t *testing.T) { Data: &data, Input: &input, Nonce: &nonce, + Type: toArgUint64Ptr(uint64(types.DynamicFeeTxType)), } decodedTx = types.NewTx(&types.DynamicFeeTx{ Nonce: uint64(nonce), diff --git a/jsonrpc/eth_endpoint_test.go b/jsonrpc/eth_endpoint_test.go index 757af949b7..d0ffb5d344 100644 --- a/jsonrpc/eth_endpoint_test.go +++ b/jsonrpc/eth_endpoint_test.go @@ -44,6 +44,7 @@ func TestEth_DecodeTxn(t *testing.T) { Value: toArgBytesPtr(oneEther.Bytes()), Data: nil, Nonce: toArgUint64Ptr(0), + Type: toArgUint64Ptr(uint64(types.DynamicFeeTxType)), }, res: types.NewTx(&types.DynamicFeeTx{ From: addr1, @@ -66,15 +67,14 @@ func TestEth_DecodeTxn(t *testing.T) { Value: toArgBytesPtr(oneEther.Bytes()), Data: nil, }, - res: types.NewTx(&types.DynamicFeeTx{ - From: types.ZeroAddress, - To: &addr2, - Gas: 21000, - GasTipCap: new(big.Int), - GasFeeCap: new(big.Int), - Value: oneEther, - Input: []byte{}, - Nonce: 0, + res: types.NewTx(&types.LegacyTx{ + From: types.ZeroAddress, + To: &addr2, + Gas: 21000, + GasPrice: big.NewInt(10000), + Value: oneEther, + Input: []byte{}, + Nonce: 0, }), err: nil, }, diff --git a/jsonrpc/helper.go b/jsonrpc/helper.go index 7883599c90..ca711b6bcf 100644 --- a/jsonrpc/helper.go +++ b/jsonrpc/helper.go @@ -232,11 +232,12 @@ func DecodeTxn(arg *txnArgs, blockNumber uint64, store nonceGetter, forceSetNonc }) case types.LegacyTxType: txn = types.NewTx(&types.LegacyTx{ - From: *arg.From, - Gas: uint64(*arg.Gas), - Value: new(big.Int).SetBytes(*arg.Value), - Input: input, - Nonce: uint64(*arg.Nonce), + From: *arg.From, + Gas: uint64(*arg.Gas), + Value: new(big.Int).SetBytes(*arg.Value), + Input: input, + Nonce: uint64(*arg.Nonce), + GasPrice: new(big.Int).SetBytes(*arg.GasPrice), }) case types.StateTxType: txn = types.NewTx(&types.StateTx{ diff --git a/jsonrpc/helper_test.go b/jsonrpc/helper_test.go index 86ae99880e..a95065d0f9 100644 --- a/jsonrpc/helper_test.go +++ b/jsonrpc/helper_test.go @@ -705,6 +705,7 @@ func TestDecodeTxn(t *testing.T) { Value: &value, Input: &input, Nonce: &nonce, + Type: toArgUint64Ptr(uint64(types.DynamicFeeTxType)), }, store: &debugEndpointMockStore{}, expected: types.NewTx(&types.DynamicFeeTx{ @@ -730,15 +731,14 @@ func TestDecodeTxn(t *testing.T) { Nonce: &nonce, }, store: &debugEndpointMockStore{}, - expected: types.NewTx(&types.DynamicFeeTx{ - From: types.ZeroAddress, - To: &to, - Gas: uint64(gas), - GasTipCap: new(big.Int), - GasFeeCap: new(big.Int), - Value: new(big.Int).SetBytes([]byte(value)), - Input: input, - Nonce: uint64(0), + expected: types.NewTx(&types.LegacyTx{ + From: types.ZeroAddress, + To: &to, + Gas: uint64(gas), + Value: new(big.Int).SetBytes([]byte(value)), + GasPrice: new(big.Int).SetBytes([]byte(gasPrice)), + Input: input, + Nonce: uint64(0), }), err: false, }, @@ -764,15 +764,14 @@ func TestDecodeTxn(t *testing.T) { }, nil }, }, - expected: types.NewTx(&types.DynamicFeeTx{ - From: from, - To: &to, - Gas: uint64(gas), - GasTipCap: new(big.Int), - GasFeeCap: new(big.Int), - Value: new(big.Int).SetBytes([]byte(value)), - Input: input, - Nonce: uint64(stateNonce), + expected: types.NewTx(&types.LegacyTx{ + From: from, + To: &to, + Gas: uint64(gas), + Value: new(big.Int).SetBytes([]byte(value)), + GasPrice: new(big.Int).SetBytes([]byte(gasPrice)), + Input: input, + Nonce: uint64(stateNonce), }), err: false, }, @@ -789,15 +788,14 @@ func TestDecodeTxn(t *testing.T) { Nonce: &nonce, }, store: &debugEndpointMockStore{}, - expected: types.NewTx(&types.DynamicFeeTx{ - From: from, - To: &to, - Gas: uint64(gas), - GasTipCap: new(big.Int), - GasFeeCap: new(big.Int), - Value: new(big.Int).SetBytes([]byte(value)), - Input: data, - Nonce: uint64(nonce), + expected: types.NewTx(&types.LegacyTx{ + From: from, + To: &to, + Gas: uint64(gas), + Value: new(big.Int).SetBytes([]byte(value)), + GasPrice: new(big.Int).SetBytes([]byte(gasPrice)), + Input: data, + Nonce: uint64(nonce), }), err: false, }, @@ -809,15 +807,14 @@ func TestDecodeTxn(t *testing.T) { Nonce: &nonce, }, store: &debugEndpointMockStore{}, - expected: types.NewTx(&types.DynamicFeeTx{ - From: from, - To: &to, - Gas: uint64(0), - GasTipCap: new(big.Int), - GasFeeCap: new(big.Int), - Value: new(big.Int), - Input: []byte{}, - Nonce: uint64(nonce), + expected: types.NewTx(&types.LegacyTx{ + From: from, + To: &to, + Gas: uint64(0), + Value: new(big.Int), + GasPrice: new(big.Int), + Input: []byte{}, + Nonce: uint64(nonce), }), err: false, }, diff --git a/txpool/txpool.go b/txpool/txpool.go index 8f08436fc5..129e700879 100644 --- a/txpool/txpool.go +++ b/txpool/txpool.go @@ -671,10 +671,12 @@ func (p *TxPool) validateTx(tx *types.Transaction) error { } // Check if the given tx is not underpriced - if tx.GetGasPrice(baseFee).Cmp(new(big.Int).SetUint64(p.priceLimit)) < 0 { - metrics.IncrCounter([]string{txPoolMetrics, "underpriced_tx"}, 1) + if tx.Type() != types.DynamicFeeTxType { + if tx.GetGasPrice(baseFee).Cmp(new(big.Int).SetUint64(p.priceLimit)) < 0 { + metrics.IncrCounter([]string{txPoolMetrics, "underpriced_tx"}, 1) - return ErrUnderpriced + return ErrUnderpriced + } } // Check nonce ordering diff --git a/txpool/txpool_test.go b/txpool/txpool_test.go index d7184d303f..37a7e7a11d 100644 --- a/txpool/txpool_test.go +++ b/txpool/txpool_test.go @@ -70,6 +70,7 @@ func newTx(addr types.Address, nonce, slots uint64, txType types.TxType) *types. }) case types.LegacyTxType: tx = types.NewTx(&types.LegacyTx{ + From: addr, Nonce: nonce, Value: big.NewInt(1), GasPrice: big.NewInt(0).SetUint64(defaultPriceLimit), @@ -87,10 +88,13 @@ func newTx(addr types.Address, nonce, slots uint64, txType types.TxType) *types. }) default: tx = types.NewTx(&types.DynamicFeeTx{ - Nonce: nonce, - Value: big.NewInt(1), - Gas: validGasLimit, - Input: input, + From: addr, + Nonce: nonce, + Value: big.NewInt(1), + GasTipCap: big.NewInt(100), + GasFeeCap: big.NewInt(100), + Gas: validGasLimit, + Input: input, }) } @@ -249,7 +253,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(addr1, 0, 1, types.DynamicFeeTxType) + tx := newTx(addr1, 0, 1, types.LegacyTxType) // Sign with a private key that corresponds // to a different address @@ -282,7 +286,7 @@ func TestAddTxErrors(t *testing.T) { // nonce is 1000000 so ErrNonceTooLow // doesn't get triggered - tx := newTx(defaultAddr, 1000000, 1, types.StateTxType) + tx := newTx(defaultAddr, 1000000, 1, types.LegacyTxType) tx = signTx(tx) assert.ErrorIs(t, @@ -298,7 +302,7 @@ func TestAddTxErrors(t *testing.T) { // fill the pool pool.gauge.increase(defaultMaxSlots) - tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx = signTx(tx) assert.ErrorIs(t, @@ -315,7 +319,7 @@ func TestAddTxErrors(t *testing.T) { pool.gauge.increase(defaultMaxSlots - 1) // create tx requiring 1 slot - tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx = signTx(tx) // enqueue tx @@ -327,7 +331,7 @@ func TestAddTxErrors(t *testing.T) { t.Parallel() pool := setupPool() - tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx.SetGas(1) tx = signTx(tx) @@ -593,7 +597,7 @@ func TestAddTxHighPressure(t *testing.T) { println("slots", slots, "max", pool.gauge.max) pool.gauge.increase(slots) - tx := newTx(addr1, 5, 1, types.AccessListTxType) + tx := newTx(addr1, 5, 1, types.LegacyTxType) assert.NoError(t, pool.addTx(local, tx)) _, exists := pool.index.get(tx.Hash()) @@ -2276,7 +2280,7 @@ func Test_TxPool_validateTx(t *testing.T) { pool := setupPool() // undefined gas tip cap - tx := newTx(defaultAddr, 0, 1, types.DynamicFeeTxType) + tx := newTx(defaultAddr, 0, 1, types.LegacyTxType) tx.SetGasFeeCap(big.NewInt(10000)) signedTx := signTx(tx) @@ -2288,7 +2292,7 @@ func Test_TxPool_validateTx(t *testing.T) { ) // undefined gas fee cap - tx = newTx(defaultAddr, 1, 1, types.DynamicFeeTxType) + tx = newTx(defaultAddr, 1, 1, types.LegacyTxType) tx.SetGasTipCap(big.NewInt(1000)) signedTx = signTx(tx) @@ -2750,18 +2754,18 @@ func TestExecutablesOrder(t *testing.T) { newPricedTx := func( addr types.Address, nonce, gasPrice uint64, gasFeeCap uint64, value uint64) *types.Transaction { var tx *types.Transaction - tx.SetValue(new(big.Int).SetUint64(value)) if gasPrice == 0 { tx = newTx(addr, nonce, 1, types.DynamicFeeTxType) tx.SetGasFeeCap(new(big.Int).SetUint64(gasFeeCap)) tx.SetGasTipCap(new(big.Int).SetUint64(2)) - tx.SetGasPrice(big.NewInt(0)) } else { tx = newTx(addr, nonce, 1, types.LegacyTxType) tx.SetGasPrice(new(big.Int).SetUint64(gasPrice)) } + tx.SetValue(new(big.Int).SetUint64(value)) + return tx } @@ -2936,8 +2940,10 @@ func TestExecutablesOrder(t *testing.T) { // verify the highest priced transactions // were processed first for i, tx := range successful { - require.Equal(t, test.expectedPriceOrder[i][0], tx.GasPrice().Uint64()) - require.Equal(t, test.expectedPriceOrder[i][1], tx.Value().Uint64()) + if tx.Type() != types.DynamicFeeTxType { + require.Equal(t, test.expectedPriceOrder[i][0], tx.GasPrice().Uint64()) + require.Equal(t, test.expectedPriceOrder[i][1], tx.Value().Uint64()) + } } }) } diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go index 3256bc068c..9d1a8be8e3 100644 --- a/types/dynamic_fee_tx.go +++ b/types/dynamic_fee_tx.go @@ -35,7 +35,7 @@ func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce } func (tx *DynamicFeeTx) to() *Address { return tx.To } func (tx *DynamicFeeTx) from() Address { return tx.From } -func (tx *DynamicFeeTx) hash() Hash { return ZeroHash } +func (tx *DynamicFeeTx) hash() Hash { return tx.Hash } func (tx *DynamicFeeTx) rawSignatureValues() (v, r, s *big.Int) { return tx.V, tx.R, tx.S @@ -368,5 +368,7 @@ func (tx *DynamicFeeTx) copy() TxData { cpy.setHash(tx.hash()) + cpy.setFrom(tx.from()) + return cpy } diff --git a/types/legacy_tx.go b/types/legacy_tx.go index a31519a38a..82fbf7bbfd 100644 --- a/types/legacy_tx.go +++ b/types/legacy_tx.go @@ -27,7 +27,7 @@ func (tx *LegacyTx) gasPrice() *big.Int { return tx.GasPrice } func (tx *LegacyTx) gasTipCap() *big.Int { return nil } func (tx *LegacyTx) gasFeeCap() *big.Int { return nil } func (tx *LegacyTx) value() *big.Int { return tx.Value } -func (tx *LegacyTx) nonce() uint64 { return 0 } +func (tx *LegacyTx) nonce() uint64 { return tx.Nonce } func (tx *LegacyTx) to() *Address { return tx.To } func (tx *LegacyTx) from() Address { return tx.From } @@ -87,7 +87,7 @@ func (tx *LegacyTx) setHash(h Hash) { tx.Hash = h } // Hash calculation should also be done from the outside! // Use UnmarshalRLP in most cases func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { - numOfElems := 9 + num := 9 elems, err := v.GetElems() if err != nil { return err @@ -100,8 +100,8 @@ func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error return val } - if numElems := len(elems); numElems != numOfElems { - return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", numOfElems, numElems) + if numElems := len(elems); numElems != num { + return fmt.Errorf("legacy incorrect number of transaction elements, expected %d but found %d", num, numElems) } // nonce @@ -259,5 +259,7 @@ func (tx *LegacyTx) copy() TxData { cpy.setHash(tx.hash()) + cpy.setFrom(tx.from()) + return cpy } From 9191b657e39153dbc6d56ad940892426777e5c45 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Tue, 6 Feb 2024 16:17:21 +0100 Subject: [PATCH 03/18] Fix for e2e test and deleted mixed_tx.go --- e2e/framework/testserver.go | 2 +- types/mixed_tx.go | 105 --------------------------------- types/rlp_unmarshal_storage.go | 11 ++++ 3 files changed, 12 insertions(+), 106 deletions(-) delete mode 100644 types/mixed_tx.go diff --git a/e2e/framework/testserver.go b/e2e/framework/testserver.go index 55f5971cbd..d851382ca2 100644 --- a/e2e/framework/testserver.go +++ b/e2e/framework/testserver.go @@ -520,7 +520,7 @@ func (t *TestServer) SendRawTx( return nil, err } - signedTx, err := t.SignTx(types.NewTx(&types.StateTx{ + signedTx, err := t.SignTx(types.NewTx(&types.LegacyTx{ From: tx.From, GasPrice: tx.GasPrice, Gas: tx.Gas, diff --git a/types/mixed_tx.go b/types/mixed_tx.go deleted file mode 100644 index 51d595454e..0000000000 --- a/types/mixed_tx.go +++ /dev/null @@ -1,105 +0,0 @@ -package types - -import "math/big" - -type MixedTxn struct { - Nonce uint64 - GasPrice *big.Int - GasTipCap *big.Int - GasFeeCap *big.Int - Gas uint64 - To *Address - Value *big.Int - Input []byte - V, R, S *big.Int - Hash Hash - From Address - - Type TxType - - ChainID *big.Int - AccessList TxAccessList -} - -func (tx *MixedTxn) transactionType() TxType { return tx.Type } -func (tx *MixedTxn) chainID() *big.Int { return tx.ChainID } -func (tx *MixedTxn) input() []byte { return tx.Input } -func (tx *MixedTxn) gas() uint64 { return tx.Gas } -func (tx *MixedTxn) gasPrice() *big.Int { return tx.GasPrice } -func (tx *MixedTxn) gasTipCap() *big.Int { return tx.GasTipCap } -func (tx *MixedTxn) gasFeeCap() *big.Int { return tx.GasFeeCap } -func (tx *MixedTxn) value() *big.Int { return tx.Value } -func (tx *MixedTxn) nonce() uint64 { return tx.Nonce } -func (tx *MixedTxn) to() *Address { return tx.To } -func (tx *MixedTxn) from() Address { return tx.From } - -func (tx *MixedTxn) hash() Hash { return tx.Hash } - -func (tx *MixedTxn) rawSignatureValues() (v, r, s *big.Int) { - return tx.V, tx.R, tx.S -} - -func (tx *MixedTxn) accessList() TxAccessList { - if tx.transactionType() == DynamicFeeTxType { - return tx.AccessList - } - - return nil -} - -// set methods for transaction fields -func (tx *MixedTxn) setSignatureValues(v, r, s *big.Int) { - tx.V, tx.R, tx.S = v, r, s -} - -func (tx *MixedTxn) setFrom(addr Address) { - tx.From = addr -} - -func (tx *MixedTxn) setGas(gas uint64) { - tx.Gas = gas -} - -func (tx *MixedTxn) setChainID(id *big.Int) { - tx.ChainID = id -} - -func (tx *MixedTxn) setGasPrice(gas *big.Int) { - tx.GasPrice = gas -} - -func (tx *MixedTxn) setGasFeeCap(gas *big.Int) { - tx.GasFeeCap = gas -} - -func (tx *MixedTxn) setGasTipCap(gas *big.Int) { - tx.GasTipCap = gas -} - -func (tx *MixedTxn) setTransactionType(t TxType) { - tx.Type = t -} - -func (tx *MixedTxn) setValue(value *big.Int) { - tx.Value = value -} - -func (tx *MixedTxn) setInput(input []byte) { - tx.Input = input -} - -func (tx *MixedTxn) setTo(addeess *Address) { - tx.To = addeess -} - -func (tx *MixedTxn) setNonce(nonce uint64) { - tx.Nonce = nonce -} - -func (tx *MixedTxn) setAccessList(accessList TxAccessList) { - tx.AccessList = accessList -} - -func (tx *MixedTxn) setHash(h Hash) { - tx.Hash = h -} diff --git a/types/rlp_unmarshal_storage.go b/types/rlp_unmarshal_storage.go index 53afd866f2..6888c712ca 100644 --- a/types/rlp_unmarshal_storage.go +++ b/types/rlp_unmarshal_storage.go @@ -115,6 +115,17 @@ func (t *Transaction) unmarshalStoreRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) } elems = elems[1:] + + switch tType { + case LegacyTxType: + t.SetTxData(&LegacyTx{}) + case StateTxType: + t.SetTxData(&StateTx{}) + case AccessListTxType: + t.SetTxData(&AccessListTxn{}) + default: + t.SetTxData(&DynamicFeeTx{}) + } } // consensus part From 6b1bfc1331b1a519514be8c2c02468c11701a8d2 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Wed, 7 Feb 2024 08:09:05 +0100 Subject: [PATCH 04/18] legacy test fix --- e2e/txpool_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/txpool_test.go b/e2e/txpool_test.go index 99dbd9e91c..cbf48e3d08 100644 --- a/e2e/txpool_test.go +++ b/e2e/txpool_test.go @@ -241,7 +241,7 @@ func TestTxPool_RecoverableError(t *testing.T) { _, receiverAddress := tests.GenerateKeyAndAddr(t) transactions := []*types.Transaction{ - types.NewTx(&types.StateTx{ + types.NewTx(&types.LegacyTx{ Nonce: 0, GasPrice: big.NewInt(framework.DefaultGasPrice), Gas: 22000, @@ -348,7 +348,7 @@ func TestTxPool_GetPendingTx(t *testing.T) { operator := server.TxnPoolOperator() client := server.JSONRPC() - signedTx, err := signer.SignTx(types.NewTx(&types.StateTx{ + signedTx, err := signer.SignTx(types.NewTx(&types.LegacyTx{ Nonce: 0, GasPrice: big.NewInt(1000000000), Gas: framework.DefaultGasLimit - 1, From 7a5b364936bb548fad1f255e2dcf19bb0debf742 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Wed, 7 Feb 2024 11:10:10 +0100 Subject: [PATCH 05/18] better code --- blockchain/blockchain_test.go | 10 ++-- txpool/txpool_test.go | 4 +- types/rlp_encoding_test.go | 83 ++++++++++++++++++++-------------- types/rlp_unmarshal.go | 14 ++---- types/rlp_unmarshal_storage.go | 35 ++------------ 5 files changed, 62 insertions(+), 84 deletions(-) diff --git a/blockchain/blockchain_test.go b/blockchain/blockchain_test.go index 511a79df3c..26cbf5ac1f 100644 --- a/blockchain/blockchain_test.go +++ b/blockchain/blockchain_test.go @@ -590,7 +590,7 @@ func TestBlockchainWriteBody(t *testing.T) { t.Run("should succeed if tx has from field", func(t *testing.T) { t.Parallel() - tx := types.NewTx(&types.StateTx{ + tx := types.NewTx(&types.LegacyTx{ Value: big.NewInt(10), V: big.NewInt(1), From: addr, @@ -864,8 +864,8 @@ func Test_recoverFromFieldsInTransactions(t *testing.T) { }, } - tx1 := types.NewTx(&types.StateTx{Nonce: 0, From: addr1}) - tx2 := types.NewTx(&types.StateTx{Nonce: 1, From: addr2}) + tx1 := types.NewTx(&types.LegacyTx{Nonce: 0, From: addr1}) + tx2 := types.NewTx(&types.LegacyTx{Nonce: 1, From: addr2}) computeTxHashes(tx1, tx2) @@ -1602,7 +1602,7 @@ func TestBlockchain_WriteFullBlock(t *testing.T) { {GasUsed: 100}, {GasUsed: 200}, } - tx := types.NewTx(&types.StateTx{ + tx := types.NewTx(&types.LegacyTx{ Value: big.NewInt(1), }) @@ -1892,7 +1892,7 @@ func customJSONBlockUnmarshall(tb testing.TB, jsonData []byte) (*types.FullBlock continue } - transaction := types.NewTx(&types.StateTx{}) + transaction := types.NewTx(txData) transaction.SetHash(types.StringToHash(tr["hash"].(string))) nonce := tr["nonce"].(string) diff --git a/txpool/txpool_test.go b/txpool/txpool_test.go index 37a7e7a11d..ce53303d92 100644 --- a/txpool/txpool_test.go +++ b/txpool/txpool_test.go @@ -1152,7 +1152,7 @@ func TestAddTx(t *testing.T) { gasPrice, slots uint64, ) *types.Transaction { - tx := newTx(addr, nonce, slots, types.StateTxType) + tx := newTx(addr, nonce, slots, types.LegacyTxType) tx.GasPrice().SetUint64(gasPrice) return tx @@ -1385,7 +1385,7 @@ func TestPromoteHandler(t *testing.T) { txs := make([]*types.Transaction, 20) for i := 0; i < 20; i++ { - txs[i] = newTx(addr1, uint64(i), 1, types.StateTxType) + txs[i] = newTx(addr1, uint64(i), 1, types.LegacyTxType) } for _, tx := range txs { diff --git a/types/rlp_encoding_test.go b/types/rlp_encoding_test.go index 37fe5756c7..3190de7242 100644 --- a/types/rlp_encoding_test.go +++ b/types/rlp_encoding_test.go @@ -149,37 +149,59 @@ func TestRLPUnmarshal_Header_ComputeHash(t *testing.T) { assert.Equal(t, h.Hash, h2.Hash) } -/* func TestRLPMarshall_And_Unmarshall_TypedTransaction(t *testing.T) { +func TestRLPMarshall_And_Unmarshall_TypedTransaction(t *testing.T) { addrTo := StringToAddress("11") addrFrom := StringToAddress("22") - originalTx := NewTx(&MixedTxn{ - Nonce: 0, - GasPrice: big.NewInt(11), - GasFeeCap: big.NewInt(12), - GasTipCap: big.NewInt(13), - Gas: 11, - To: &addrTo, - From: addrFrom, - Value: big.NewInt(1), - Input: []byte{1, 2}, - V: big.NewInt(25), - S: big.NewInt(26), - R: big.NewInt(27), - }) - txTypes := []TxType{ - StateTxType, - LegacyTxType, - DynamicFeeTxType, + originalTxs := []*Transaction{ + NewTx(&StateTx{ + Nonce: 0, + GasPrice: big.NewInt(11), + Gas: 11, + To: &addrTo, + From: addrFrom, + Value: big.NewInt(1), + Input: []byte{1, 2}, + V: big.NewInt(25), + S: big.NewInt(26), + R: big.NewInt(27), + }), + NewTx(&LegacyTx{ + Nonce: 0, + GasPrice: big.NewInt(11), + Gas: 11, + To: &addrTo, + From: addrFrom, + Value: big.NewInt(1), + Input: []byte{1, 2}, + V: big.NewInt(25), + S: big.NewInt(26), + R: big.NewInt(27), + }), + NewTx(&DynamicFeeTx{ + Nonce: 0, + GasFeeCap: big.NewInt(12), + GasTipCap: big.NewInt(13), + Gas: 11, + To: &addrTo, + From: addrFrom, + Value: big.NewInt(1), + Input: []byte{1, 2}, + V: big.NewInt(25), + S: big.NewInt(26), + R: big.NewInt(27), + }), } - for _, v := range txTypes { - t.Run(v.String(), func(t *testing.T) { + for _, originalTx := range originalTxs { + t.Run(originalTx.Type().String(), func(t *testing.T) { originalTx.ComputeHash() + unmarshalledTx := &Transaction{} + unmarshalledTx.InitInnerData(originalTx.Type()) + txRLP := originalTx.MarshalRLP() - unmarshalledTx := NewTx(&MixedTxn{}) assert.NoError(t, unmarshalledTx.UnmarshalRLP(txRLP)) unmarshalledTx.ComputeHash() @@ -187,7 +209,7 @@ func TestRLPUnmarshal_Header_ComputeHash(t *testing.T) { assert.Equal(t, originalTx.Hash(), unmarshalledTx.Hash()) }) } -} */ +} func TestRLPMarshall_Unmarshall_Missing_Data(t *testing.T) { t.Parallel() @@ -254,18 +276,9 @@ func TestRLPMarshall_Unmarshall_Missing_Data(t *testing.T) { v, err := parser.Parse(testData) assert.Nil(t, err) - var unmarshalledTx *Transaction - - switch txType { - case AccessListTxType: - unmarshalledTx = NewTx(&AccessListTxn{}) - case StateTxType: - unmarshalledTx = NewTx(&StateTx{}) - case LegacyTxType: - unmarshalledTx = NewTx(&LegacyTx{}) - case DynamicFeeTxType: - unmarshalledTx = NewTx(&DynamicFeeTx{}) - } + unmarshalledTx := &Transaction{} + + unmarshalledTx.InitInnerData(txType) if tt.expectedErr { assert.Error(t, unmarshalledTx.Inner.unmarshalRLPFrom(parser, v), tt.name) diff --git a/types/rlp_unmarshal.go b/types/rlp_unmarshal.go index 76cbe766e3..107cc63451 100644 --- a/types/rlp_unmarshal.go +++ b/types/rlp_unmarshal.go @@ -104,17 +104,9 @@ func (b *Block) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // transactions if err = unmarshalRLPFrom(p, elems[1], func(txType TxType, p *fastrlp.Parser, v *fastrlp.Value) error { - var bTxn *Transaction - switch txType { - case AccessListTxType: - bTxn = NewTx(&AccessListTxn{}) - case LegacyTxType: - bTxn = NewTx(&LegacyTx{}) - case StateTxType: - bTxn = NewTx(&StateTx{}) - case DynamicFeeTxType: - bTxn = NewTx(&DynamicFeeTx{}) - } + bTxn := &Transaction{} + + bTxn.InitInnerData(txType) if err = bTxn.Inner.unmarshalRLPFrom(p, v); err != nil { return err diff --git a/types/rlp_unmarshal_storage.go b/types/rlp_unmarshal_storage.go index 6888c712ca..d82672289e 100644 --- a/types/rlp_unmarshal_storage.go +++ b/types/rlp_unmarshal_storage.go @@ -29,17 +29,8 @@ func (b *Body) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // transactions if err = unmarshalRLPFrom(p, tuple[0], func(txType TxType, p *fastrlp.Parser, v *fastrlp.Value) error { - var bTxn *Transaction - switch txType { - case AccessListTxType: - bTxn = NewTx(&AccessListTxn{}) - case LegacyTxType: - bTxn = NewTx(&LegacyTx{}) - case StateTxType: - bTxn = NewTx(&StateTx{}) - case DynamicFeeTxType: - bTxn = NewTx(&DynamicFeeTx{}) - } + bTxn := &Transaction{} + bTxn.InitInnerData(txType) if err = bTxn.unmarshalStoreRLPFrom(p, v); err != nil { return err @@ -80,16 +71,7 @@ func (t *Transaction) UnmarshalStoreRLP(input []byte) error { return err } - switch tType { - case LegacyTxType: - t.SetTxData(&LegacyTx{}) - case StateTxType: - t.SetTxData(&StateTx{}) - case AccessListTxType: - t.SetTxData(&AccessListTxn{}) - default: - t.SetTxData(&DynamicFeeTx{}) - } + t.InitInnerData(tType) offset = 1 } @@ -116,16 +98,7 @@ func (t *Transaction) unmarshalStoreRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) elems = elems[1:] - switch tType { - case LegacyTxType: - t.SetTxData(&LegacyTx{}) - case StateTxType: - t.SetTxData(&StateTx{}) - case AccessListTxType: - t.SetTxData(&AccessListTxn{}) - default: - t.SetTxData(&DynamicFeeTx{}) - } + t.InitInnerData(tType) } // consensus part From c8f1644261d35ad8f26daad859d36822e85c588c Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Wed, 7 Feb 2024 11:59:16 +0100 Subject: [PATCH 06/18] lint fix --- blockchain/blockchain_test.go | 1 + txpool/queue_priced_test.go | 4 ++-- types/access_list_tx.go | 3 +++ types/dynamic_fee_tx.go | 1 + types/legacy_tx.go | 2 +- types/state_tx.go | 2 +- 6 files changed, 9 insertions(+), 4 deletions(-) diff --git a/blockchain/blockchain_test.go b/blockchain/blockchain_test.go index 26cbf5ac1f..4f78fb7f16 100644 --- a/blockchain/blockchain_test.go +++ b/blockchain/blockchain_test.go @@ -1870,6 +1870,7 @@ func customJSONBlockUnmarshall(tb testing.TB, jsonData []byte) (*types.FullBlock tr := transactionJSON.(map[string]interface{}) var txData types.TxData + txType := tr["type"].(string) txTypeNumber, err := common.ParseUint64orHex(&txType) diff --git a/txpool/queue_priced_test.go b/txpool/queue_priced_test.go index 855f7b24e1..4e172ff71f 100644 --- a/txpool/queue_priced_test.go +++ b/txpool/queue_priced_test.go @@ -98,7 +98,7 @@ func Test_maxPriceQueue(t *testing.T) { }), }, }, - { + { //nolint:dupl name: "sort txs without base fee by fee cap", baseFee: 0, unsorted: []*types.Transaction{ @@ -136,7 +136,7 @@ func Test_maxPriceQueue(t *testing.T) { }), }, }, - { + { //nolint:dupl name: "sort txs without base fee by tip cap", baseFee: 0, unsorted: []*types.Transaction{ diff --git a/types/access_list_tx.go b/types/access_list_tx.go index 5c5e1da2a5..79193b4994 100644 --- a/types/access_list_tx.go +++ b/types/access_list_tx.go @@ -145,6 +145,7 @@ func (tx *AccessListTxn) setHash(h Hash) { // Use UnmarshalRLP in most cases func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { numOfElems := 11 + elems, err := v.GetElems() if err != nil { return err @@ -160,7 +161,9 @@ func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) e if numElems := len(elems); numElems != numOfElems { return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", numOfElems, numElems) } + txChainID := new(big.Int) + if err = getElem().GetBigInt(txChainID); err != nil { return err } diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go index 9d1a8be8e3..78e5e5e951 100644 --- a/types/dynamic_fee_tx.go +++ b/types/dynamic_fee_tx.go @@ -95,6 +95,7 @@ func (tx *DynamicFeeTx) setHash(h Hash) { tx.Hash = h } // Use UnmarshalRLP in most cases func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { numOfElems := 12 + elems, err := v.GetElems() if err != nil { return err diff --git a/types/legacy_tx.go b/types/legacy_tx.go index 82fbf7bbfd..15146757bd 100644 --- a/types/legacy_tx.go +++ b/types/legacy_tx.go @@ -208,7 +208,7 @@ func (tx *LegacyTx) marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value { return vv } -func (tx *LegacyTx) copy() TxData { +func (tx *LegacyTx) copy() TxData { //nolint:dupl cpy := &LegacyTx{} cpy.setNonce(tx.nonce()) diff --git a/types/state_tx.go b/types/state_tx.go index 14dd1cc61b..cb89565e98 100644 --- a/types/state_tx.go +++ b/types/state_tx.go @@ -220,7 +220,7 @@ func (tx *StateTx) marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value { return vv } -func (tx *StateTx) copy() TxData { +func (tx *StateTx) copy() TxData { //nolint:dupl cpy := &StateTx{} cpy.setNonce(tx.nonce()) From 313a5750ec9eacc94a8017817762f5ba822297f4 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Wed, 7 Feb 2024 12:01:55 +0100 Subject: [PATCH 07/18] lint --- types/legacy_tx.go | 1 + types/state_tx.go | 1 + 2 files changed, 2 insertions(+) diff --git a/types/legacy_tx.go b/types/legacy_tx.go index 15146757bd..e01df22caa 100644 --- a/types/legacy_tx.go +++ b/types/legacy_tx.go @@ -88,6 +88,7 @@ func (tx *LegacyTx) setHash(h Hash) { tx.Hash = h } // Use UnmarshalRLP in most cases func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { num := 9 + elems, err := v.GetElems() if err != nil { return err diff --git a/types/state_tx.go b/types/state_tx.go index cb89565e98..e67ebda8e9 100644 --- a/types/state_tx.go +++ b/types/state_tx.go @@ -90,6 +90,7 @@ func (tx *StateTx) setHash(h Hash) { tx.Hash = h } // Use UnmarshalRLP in most cases func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { numOfElems := 10 + elems, err := v.GetElems() if err != nil { return err From ae4d34186d425ecc8fc53ae44ab506484941bd5f Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Thu, 8 Feb 2024 13:18:37 +0100 Subject: [PATCH 08/18] comment fix --- blockchain/blockchain_test.go | 19 +----- jsonrpc/helper.go | 46 ++++---------- state/transition_test.go | 2 +- txpool/txpool.go | 9 +-- txpool/txpool_test.go | 49 ++++---------- types/access_list_tx.go | 113 ++++++++++++++++++--------------- types/dynamic_fee_tx.go | 59 ++--------------- types/legacy_tx.go | 12 ++-- types/rlp_encoding_test.go | 4 +- types/rlp_marshal.go | 2 +- types/rlp_marshal_storage.go | 2 +- types/rlp_unmarshal.go | 6 +- types/rlp_unmarshal_storage.go | 5 +- types/state_tx.go | 12 ++-- types/transaction.go | 16 +++++ 15 files changed, 134 insertions(+), 222 deletions(-) diff --git a/blockchain/blockchain_test.go b/blockchain/blockchain_test.go index 4f78fb7f16..ae301b0f6e 100644 --- a/blockchain/blockchain_test.go +++ b/blockchain/blockchain_test.go @@ -1869,8 +1869,6 @@ func customJSONBlockUnmarshall(tb testing.TB, jsonData []byte) (*types.FullBlock for _, transactionJSON := range transactionsJSON { tr := transactionJSON.(map[string]interface{}) - var txData types.TxData - txType := tr["type"].(string) txTypeNumber, err := common.ParseUint64orHex(&txType) @@ -1878,22 +1876,7 @@ func customJSONBlockUnmarshall(tb testing.TB, jsonData []byte) (*types.FullBlock return nil, err } - switch types.TxType(txTypeNumber) { - case types.AccessListTxType: - txData = &types.AccessListTxn{} - case types.StateTxType: - txData = &types.DynamicFeeTx{} - case types.LegacyTxType: - txData = &types.LegacyTx{} - default: - txData = &types.DynamicFeeTx{} - } - - if txData == nil { - continue - } - - transaction := types.NewTx(txData) + transaction := types.NewTxWithType(types.TxType(txTypeNumber)) transaction.SetHash(types.StringToHash(tr["hash"].(string))) nonce := tr["nonce"].(string) diff --git a/jsonrpc/helper.go b/jsonrpc/helper.go index ca711b6bcf..618739b548 100644 --- a/jsonrpc/helper.go +++ b/jsonrpc/helper.go @@ -163,8 +163,6 @@ func GetNextNonce(address types.Address, number BlockNumber, store nonceGetter) } func DecodeTxn(arg *txnArgs, blockNumber uint64, store nonceGetter, forceSetNonce bool) (*types.Transaction, error) { - var txn *types.Transaction - if arg == nil { return nil, errors.New("missing value for required argument 0") } @@ -221,44 +219,22 @@ func DecodeTxn(arg *txnArgs, blockNumber uint64, store nonceGetter, forceSetNonc txType = types.TxType(*arg.Type) } + txn := types.NewTxWithType(txType) + switch txType { - case types.AccessListTxType: - txn = types.NewTx(&types.AccessListTxn{ - From: *arg.From, - Gas: uint64(*arg.Gas), - Value: new(big.Int).SetBytes(*arg.Value), - Input: input, - Nonce: uint64(*arg.Nonce), - }) case types.LegacyTxType: - txn = types.NewTx(&types.LegacyTx{ - From: *arg.From, - Gas: uint64(*arg.Gas), - Value: new(big.Int).SetBytes(*arg.Value), - Input: input, - Nonce: uint64(*arg.Nonce), - GasPrice: new(big.Int).SetBytes(*arg.GasPrice), - }) - case types.StateTxType: - txn = types.NewTx(&types.StateTx{ - From: *arg.From, - Gas: uint64(*arg.Gas), - Value: new(big.Int).SetBytes(*arg.Value), - Input: input, - Nonce: uint64(*arg.Nonce), - }) + txn.SetGasPrice(new(big.Int).SetBytes(*arg.GasPrice)) case types.DynamicFeeTxType: - txn = types.NewTx(&types.DynamicFeeTx{ - From: *arg.From, - Gas: uint64(*arg.Gas), - GasTipCap: new(big.Int).SetBytes(*arg.GasTipCap), - GasFeeCap: new(big.Int).SetBytes(*arg.GasFeeCap), - Value: new(big.Int).SetBytes(*arg.Value), - Input: input, - Nonce: uint64(*arg.Nonce), - }) + txn.SetGasTipCap(new(big.Int).SetBytes(*arg.GasTipCap)) + txn.SetGasFeeCap(new(big.Int).SetBytes(*arg.GasFeeCap)) } + txn.SetFrom(*arg.From) + txn.SetGas(uint64(*arg.Gas)) + txn.SetValue(new(big.Int).SetBytes(*arg.Value)) + txn.SetInput(input) + txn.SetNonce(uint64(*arg.Nonce)) + if arg.To != nil { txn.SetTo(arg.To) } diff --git a/state/transition_test.go b/state/transition_test.go index e75bbb811e..a7a64e0274 100644 --- a/state/transition_test.go +++ b/state/transition_test.go @@ -70,7 +70,7 @@ func TestSubGasLimitPrice(t *testing.T) { t.Parallel() transition := newTestTransition(tt.preState) - msg := types.NewTx(&types.StateTx{ + msg := types.NewTx(&types.LegacyTx{ From: tt.from, Gas: tt.gas, GasPrice: big.NewInt(tt.gasPrice), diff --git a/txpool/txpool.go b/txpool/txpool.go index 129e700879..3b6adec4cd 100644 --- a/txpool/txpool.go +++ b/txpool/txpool.go @@ -670,13 +670,10 @@ func (p *TxPool) validateTx(tx *types.Transaction) error { } } - // Check if the given tx is not underpriced - if tx.Type() != types.DynamicFeeTxType { - if tx.GetGasPrice(baseFee).Cmp(new(big.Int).SetUint64(p.priceLimit)) < 0 { - metrics.IncrCounter([]string{txPoolMetrics, "underpriced_tx"}, 1) + if tx.GetGasPrice(baseFee).Cmp(new(big.Int).SetUint64(p.priceLimit)) < 0 { + metrics.IncrCounter([]string{txPoolMetrics, "underpriced_tx"}, 1) - return ErrUnderpriced - } + return ErrUnderpriced } // Check nonce ordering diff --git a/txpool/txpool_test.go b/txpool/txpool_test.go index ce53303d92..72fc1af1f4 100644 --- a/txpool/txpool_test.go +++ b/txpool/txpool_test.go @@ -56,48 +56,23 @@ func newTx(addr types.Address, nonce, slots uint64, txType types.TxType) *types. return nil } - var tx *types.Transaction + tx := types.NewTxWithType(txType) switch txType { - case types.AccessListTxType: - tx = types.NewTx(&types.AccessListTxn{ - From: addr, - Nonce: nonce, - Value: big.NewInt(1), - GasPrice: big.NewInt(0).SetUint64(defaultPriceLimit), - Gas: validGasLimit, - Input: input, - }) - case types.LegacyTxType: - tx = types.NewTx(&types.LegacyTx{ - From: addr, - Nonce: nonce, - Value: big.NewInt(1), - GasPrice: big.NewInt(0).SetUint64(defaultPriceLimit), - Gas: validGasLimit, - Input: input, - }) - case types.StateTxType: - tx = types.NewTx(&types.StateTx{ - From: addr, - Nonce: nonce, - Value: big.NewInt(1), - GasPrice: big.NewInt(0).SetUint64(defaultPriceLimit), - Gas: validGasLimit, - Input: input, - }) + case types.DynamicFeeTxType: + tx.SetGasFeeCap(big.NewInt(100)) + tx.SetGasTipCap(big.NewInt(100)) + default: - tx = types.NewTx(&types.DynamicFeeTx{ - From: addr, - Nonce: nonce, - Value: big.NewInt(1), - GasTipCap: big.NewInt(100), - GasFeeCap: big.NewInt(100), - Gas: validGasLimit, - Input: input, - }) + tx.SetGasPrice(big.NewInt(0).SetUint64(defaultPriceLimit)) } + tx.SetFrom(addr) + tx.SetNonce(nonce) + tx.SetValue(big.NewInt(1)) + tx.SetGas(validGasLimit) + tx.SetInput(input) + return tx } diff --git a/types/access_list_tx.go b/types/access_list_tx.go index 79193b4994..44baf033ce 100644 --- a/types/access_list_tx.go +++ b/types/access_list_tx.go @@ -45,6 +45,64 @@ func (al TxAccessList) Copy() TxAccessList { return newAccessList } +func (al TxAccessList) unmarshallRLPFrom(p *fastrlp.Parser, accessListVV []*fastrlp.Value) error { + for i, accessTupleVV := range accessListVV { + accessTupleElems, err := accessTupleVV.GetElems() + if err != nil { + return err + } + + // Read the address + addressVV := accessTupleElems[0] + + addressBytes, err := addressVV.Bytes() + if err != nil { + return err + } + + al[i].Address = BytesToAddress(addressBytes) + + // Read the storage keys + storageKeysArrayVV := accessTupleElems[1] + + storageKeysElems, err := storageKeysArrayVV.GetElems() + if err != nil { + return err + } + + al[i].StorageKeys = make([]Hash, len(storageKeysElems)) + + for j, storageKeyVV := range storageKeysElems { + storageKeyBytes, err := storageKeyVV.Bytes() + if err != nil { + return err + } + + al[i].StorageKeys[j] = BytesToHash(storageKeyBytes) + } + } + + return nil +} + +func (al TxAccessList) marshallRLPWith(arena *fastrlp.Arena) *fastrlp.Value { + accessListVV := arena.NewArray() + + for _, accessTuple := range al { + accessTupleVV := arena.NewArray() + accessTupleVV.Set(arena.NewCopyBytes(accessTuple.Address.Bytes())) + + storageKeysVV := arena.NewArray() + for _, storageKey := range accessTuple.StorageKeys { + storageKeysVV.Set(arena.NewCopyBytes(storageKey.Bytes())) + } + + accessTupleVV.Set(storageKeysVV) + accessListVV.Set(accessTupleVV) + } + return accessListVV +} + type AccessListTxn struct { Nonce uint64 GasPrice *big.Int @@ -233,41 +291,7 @@ func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) e txAccessList = make(TxAccessList, len(accessListVV)) } - for i, accessTupleVV := range accessListVV { - accessTupleElems, err := accessTupleVV.GetElems() - if err != nil { - return err - } - - // Read the address - addressVV := accessTupleElems[0] - - addressBytes, err := addressVV.Bytes() - if err != nil { - return err - } - - txAccessList[i].Address = BytesToAddress(addressBytes) - - // Read the storage keys - storageKeysArrayVV := accessTupleElems[1] - - storageKeysElems, err := storageKeysArrayVV.GetElems() - if err != nil { - return err - } - - txAccessList[i].StorageKeys = make([]Hash, len(storageKeysElems)) - - for j, storageKeyVV := range storageKeysElems { - storageKeyBytes, err := storageKeyVV.Bytes() - if err != nil { - return err - } - - txAccessList[i].StorageKeys[j] = BytesToHash(storageKeyBytes) - } - } + txAccessList.unmarshallRLPFrom(p, accessListVV) tx.setAccessList(txAccessList) @@ -315,23 +339,8 @@ func (tx *AccessListTxn) marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value { vv.Set(arena.NewBigInt(tx.value())) vv.Set(arena.NewCopyBytes(tx.input())) - // add accessList - accessListVV := arena.NewArray() - - for _, accessTuple := range tx.accessList() { - accessTupleVV := arena.NewArray() - accessTupleVV.Set(arena.NewCopyBytes(accessTuple.Address.Bytes())) - - storageKeysVV := arena.NewArray() - for _, storageKey := range accessTuple.StorageKeys { - storageKeysVV.Set(arena.NewCopyBytes(storageKey.Bytes())) - } - - accessTupleVV.Set(storageKeysVV) - accessListVV.Set(accessTupleVV) - } - - vv.Set(accessListVV) + // Convert TxAccessList to RLP format and add it to the vv array. + vv.Set(tx.accessList().marshallRLPWith(arena)) v, r, s := tx.rawSignatureValues() vv.Set(arena.NewBigInt(v)) diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go index 78e5e5e951..4f360c822f 100644 --- a/types/dynamic_fee_tx.go +++ b/types/dynamic_fee_tx.go @@ -27,7 +27,7 @@ func (tx *DynamicFeeTx) transactionType() TxType { return DynamicFeeTxType } func (tx *DynamicFeeTx) chainID() *big.Int { return tx.ChainID } func (tx *DynamicFeeTx) input() []byte { return tx.Input } func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas } -func (tx *DynamicFeeTx) gasPrice() *big.Int { return nil } +func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap } func (tx *DynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap } func (tx *DynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap } func (tx *DynamicFeeTx) value() *big.Int { return tx.Value } @@ -57,7 +57,9 @@ func (tx *DynamicFeeTx) setChainID(id *big.Int) { tx.ChainID = id } -func (tx *DynamicFeeTx) setGasPrice(gas *big.Int) {} +func (tx *DynamicFeeTx) setGasPrice(gas *big.Int) { + tx.GasTipCap = gas +} func (tx *DynamicFeeTx) setGasFeeCap(gas *big.Int) { tx.GasFeeCap = gas @@ -190,41 +192,7 @@ func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er txAccessList = make(TxAccessList, len(accessListVV)) } - for i, accessTupleVV := range accessListVV { - accessTupleElems, err := accessTupleVV.GetElems() - if err != nil { - return err - } - - // Read the address - addressVV := accessTupleElems[0] - - addressBytes, err := addressVV.Bytes() - if err != nil { - return err - } - - txAccessList[i].Address = BytesToAddress(addressBytes) - - // Read the storage keys - storageKeysArrayVV := accessTupleElems[1] - - storageKeysElems, err := storageKeysArrayVV.GetElems() - if err != nil { - return err - } - - txAccessList[i].StorageKeys = make([]Hash, len(storageKeysElems)) - - for j, storageKeyVV := range storageKeysElems { - storageKeyBytes, err := storageKeyVV.Bytes() - if err != nil { - return err - } - - txAccessList[i].StorageKeys[j] = BytesToHash(storageKeyBytes) - } - } + txAccessList.unmarshallRLPFrom(p, accessListVV) tx.setAccessList(txAccessList) @@ -276,22 +244,7 @@ func (tx *DynamicFeeTx) marshalRLPWith(arena *fastrlp.Arena) *fastrlp.Value { vv.Set(arena.NewCopyBytes(tx.input())) // Convert TxAccessList to RLP format and add it to the vv array. - accessListVV := arena.NewArray() - - for _, accessTuple := range tx.accessList() { - accessTupleVV := arena.NewArray() - accessTupleVV.Set(arena.NewCopyBytes(accessTuple.Address.Bytes())) - - storageKeysVV := arena.NewArray() - for _, storageKey := range accessTuple.StorageKeys { - storageKeysVV.Set(arena.NewCopyBytes(storageKey.Bytes())) - } - - accessTupleVV.Set(storageKeysVV) - accessListVV.Set(accessTupleVV) - } - - vv.Set(accessListVV) + vv.Set(tx.accessList().marshallRLPWith(arena)) // signature values v, r, s := tx.rawSignatureValues() diff --git a/types/legacy_tx.go b/types/legacy_tx.go index e01df22caa..f3fff8a206 100644 --- a/types/legacy_tx.go +++ b/types/legacy_tx.go @@ -24,8 +24,8 @@ func (tx *LegacyTx) chainID() *big.Int { return nil } func (tx *LegacyTx) input() []byte { return tx.Input } func (tx *LegacyTx) gas() uint64 { return tx.Gas } func (tx *LegacyTx) gasPrice() *big.Int { return tx.GasPrice } -func (tx *LegacyTx) gasTipCap() *big.Int { return nil } -func (tx *LegacyTx) gasFeeCap() *big.Int { return nil } +func (tx *LegacyTx) gasTipCap() *big.Int { return tx.GasPrice } +func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice } func (tx *LegacyTx) value() *big.Int { return tx.Value } func (tx *LegacyTx) nonce() uint64 { return tx.Nonce } func (tx *LegacyTx) to() *Address { return tx.To } @@ -56,9 +56,13 @@ func (tx *LegacyTx) setGasPrice(gas *big.Int) { tx.GasPrice = gas } -func (tx *LegacyTx) setGasFeeCap(gas *big.Int) {} +func (tx *LegacyTx) setGasFeeCap(gas *big.Int) { + tx.GasPrice = gas +} -func (tx *LegacyTx) setGasTipCap(gas *big.Int) {} +func (tx *LegacyTx) setGasTipCap(gas *big.Int) { + tx.GasPrice = gas +} func (tx *LegacyTx) setTransactionType(t TxType) {} diff --git a/types/rlp_encoding_test.go b/types/rlp_encoding_test.go index 3190de7242..db334ec809 100644 --- a/types/rlp_encoding_test.go +++ b/types/rlp_encoding_test.go @@ -276,9 +276,7 @@ func TestRLPMarshall_Unmarshall_Missing_Data(t *testing.T) { v, err := parser.Parse(testData) assert.Nil(t, err) - unmarshalledTx := &Transaction{} - - unmarshalledTx.InitInnerData(txType) + unmarshalledTx := NewTxWithType(txType) if tt.expectedErr { assert.Error(t, unmarshalledTx.Inner.unmarshalRLPFrom(parser, v), tt.name) diff --git a/types/rlp_marshal.go b/types/rlp_marshal.go index e8faf9b585..b6f543403d 100644 --- a/types/rlp_marshal.go +++ b/types/rlp_marshal.go @@ -187,5 +187,5 @@ func (t *Transaction) MarshalRLPTo(dst []byte) []byte { dst = append(dst, byte(t.Type())) } - return MarshalRLPTo(t.Inner.marshalRLPWith, dst) + return MarshalRLPTo(t.MarshalRLPWith, dst) } diff --git a/types/rlp_marshal_storage.go b/types/rlp_marshal_storage.go index a38152fa67..6d11d009ab 100644 --- a/types/rlp_marshal_storage.go +++ b/types/rlp_marshal_storage.go @@ -49,7 +49,7 @@ func (t *Transaction) marshalStoreRLPWith(a *fastrlp.Arena) *fastrlp.Value { } // consensus part - vv.Set(t.Inner.marshalRLPWith(a)) + vv.Set(t.MarshalRLPWith(a)) // context part vv.Set(a.NewBytes(t.From().Bytes())) diff --git a/types/rlp_unmarshal.go b/types/rlp_unmarshal.go index 107cc63451..197b47da0f 100644 --- a/types/rlp_unmarshal.go +++ b/types/rlp_unmarshal.go @@ -104,9 +104,7 @@ func (b *Block) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // transactions if err = unmarshalRLPFrom(p, elems[1], func(txType TxType, p *fastrlp.Parser, v *fastrlp.Value) error { - bTxn := &Transaction{} - - bTxn.InitInnerData(txType) + bTxn := NewTxWithType(txType) if err = bTxn.Inner.unmarshalRLPFrom(p, v); err != nil { return err @@ -379,7 +377,7 @@ func (t *Transaction) UnmarshalRLP(input []byte) error { t.InitInnerData(txType) - if err := UnmarshalRlp(t.Inner.unmarshalRLPFrom, input[offset:]); err != nil { + if err := UnmarshalRlp(t.UnmarshalRLPFrom, input[offset:]); err != nil { return err } diff --git a/types/rlp_unmarshal_storage.go b/types/rlp_unmarshal_storage.go index d82672289e..e3711f3776 100644 --- a/types/rlp_unmarshal_storage.go +++ b/types/rlp_unmarshal_storage.go @@ -29,8 +29,7 @@ func (b *Body) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // transactions if err = unmarshalRLPFrom(p, tuple[0], func(txType TxType, p *fastrlp.Parser, v *fastrlp.Value) error { - bTxn := &Transaction{} - bTxn.InitInnerData(txType) + bTxn := NewTxWithType(txType) if err = bTxn.unmarshalStoreRLPFrom(p, v); err != nil { return err @@ -102,7 +101,7 @@ func (t *Transaction) unmarshalStoreRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) } // consensus part - if err = t.Inner.unmarshalRLPFrom(p, elems[0]); err != nil { + if err = t.UnmarshalRLPFrom(p, elems[0]); err != nil { return err } diff --git a/types/state_tx.go b/types/state_tx.go index e67ebda8e9..ffc1cbb883 100644 --- a/types/state_tx.go +++ b/types/state_tx.go @@ -24,8 +24,8 @@ func (tx *StateTx) chainID() *big.Int { return nil } func (tx *StateTx) input() []byte { return tx.Input } func (tx *StateTx) gas() uint64 { return tx.Gas } func (tx *StateTx) gasPrice() *big.Int { return tx.GasPrice } -func (tx *StateTx) gasTipCap() *big.Int { return nil } -func (tx *StateTx) gasFeeCap() *big.Int { return nil } +func (tx *StateTx) gasTipCap() *big.Int { return tx.GasPrice } +func (tx *StateTx) gasFeeCap() *big.Int { return tx.GasPrice } func (tx *StateTx) value() *big.Int { return tx.Value } func (tx *StateTx) nonce() uint64 { return tx.Nonce } func (tx *StateTx) to() *Address { return tx.To } @@ -60,9 +60,13 @@ func (tx *StateTx) setGasPrice(gas *big.Int) { tx.GasPrice = gas } -func (tx *StateTx) setGasFeeCap(gas *big.Int) {} +func (tx *StateTx) setGasFeeCap(gas *big.Int) { + tx.GasPrice = gas +} -func (tx *StateTx) setGasTipCap(gas *big.Int) {} +func (tx *StateTx) setGasTipCap(gas *big.Int) { + tx.GasPrice = gas +} func (tx *StateTx) setValue(value *big.Int) { tx.Value = value diff --git a/types/transaction.go b/types/transaction.go index d6a5240ef0..9a1076480a 100644 --- a/types/transaction.go +++ b/types/transaction.go @@ -228,6 +228,14 @@ func (t *Transaction) SetHash(h Hash) { t.Inner.setHash(h) } +func (t *Transaction) MarshalRLPWith(a *fastrlp.Arena) *fastrlp.Value { + return t.Inner.marshalRLPWith(a) +} + +func (t *Transaction) UnmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { + return t.Inner.unmarshalRLPFrom(p, v) +} + // IsContractCreation checks if tx is contract creation func (t *Transaction) IsContractCreation() bool { return t.To() == nil @@ -378,3 +386,11 @@ func FindTxByHash(txs []*Transaction, hash Hash) (*Transaction, int) { return nil, -1 } + +func NewTxWithType(txType TxType) *Transaction { + tx := &Transaction{} + + tx.InitInnerData(txType) + + return tx +} From d900cf24410a72b79a280c3f407fe492d9513e2c Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Thu, 8 Feb 2024 15:40:02 +0100 Subject: [PATCH 09/18] test fix --- jsonrpc/txpool_endpoint_test.go | 12 ++++++------ jsonrpc/types.go | 6 +++--- jsonrpc/types_test.go | 3 ++- types/legacy_tx.go | 3 +-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/jsonrpc/txpool_endpoint_test.go b/jsonrpc/txpool_endpoint_test.go index 6dba9f203e..df9260adb7 100644 --- a/jsonrpc/txpool_endpoint_test.go +++ b/jsonrpc/txpool_endpoint_test.go @@ -49,8 +49,8 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, testTx1.Gas(), uint64(txData.Gas)) assert.Equal(t, *(testTx1.GasPrice()), big.Int(*txData.GasPrice)) - assert.Equal(t, (*argBig)(nil), txData.GasFeeCap) - assert.Equal(t, (*argBig)(nil), txData.GasTipCap) + assert.Equal(t, *(testTx1.GasFeeCap()), big.Int(*txData.GasFeeCap)) + assert.Equal(t, *(testTx1.GasTipCap()), big.Int(*txData.GasTipCap)) assert.Equal(t, testTx1.To(), txData.To) assert.Equal(t, testTx1.From(), txData.From) assert.Equal(t, *(testTx1.Value()), big.Int(txData.Value)) @@ -62,7 +62,7 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) - assert.Equal(t, (*argBig)(nil), txData.GasPrice) + assert.Equal(t, (*testTx2.GasPrice()), big.Int(*txData.GasPrice)) assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) assert.Equal(t, *(testTx2.GasTipCap()), big.Int(*txData.GasTipCap)) assert.Equal(t, testTx2.To(), txData.To) @@ -98,8 +98,8 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, testTx1.Gas(), uint64(txData.Gas)) assert.Equal(t, *(testTx1.GasPrice()), big.Int(*txData.GasPrice)) - assert.Equal(t, (*argBig)(nil), txData.GasFeeCap) - assert.Equal(t, (*argBig)(nil), txData.GasTipCap) + assert.Equal(t, *(testTx1.GasFeeCap()), big.Int(*txData.GasFeeCap)) + assert.Equal(t, *(testTx1.GasTipCap()), big.Int(*txData.GasTipCap)) assert.Equal(t, testTx1.To(), txData.To) assert.Equal(t, testTx1.From(), txData.From) assert.Equal(t, *(testTx1.Value()), big.Int(txData.Value)) @@ -111,7 +111,7 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) - assert.Equal(t, (*argBig)(nil), txData.GasPrice) + assert.Equal(t, *(testTx2.GasPrice()), big.Int(*txData.GasPrice)) assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) assert.Equal(t, *(testTx2.GasTipCap()), big.Int(*txData.GasTipCap)) assert.Equal(t, testTx2.To(), txData.To) diff --git a/jsonrpc/types.go b/jsonrpc/types.go index b1a842eab9..fdb34b7323 100644 --- a/jsonrpc/types.go +++ b/jsonrpc/types.go @@ -77,17 +77,17 @@ func toTransaction( BlockHash: blockHash, } - if t.GasPrice() != nil { + if t.GasPrice() != nil && t.Type() != types.DynamicFeeTxType { gasPrice := argBig(*(t.GasPrice())) res.GasPrice = &gasPrice } - if t.GasTipCap() != nil { + if t.GasTipCap() != nil && t.Type() == types.DynamicFeeTxType { gasTipCap := argBig(*(t.GasTipCap())) res.GasTipCap = &gasTipCap } - if t.GasFeeCap() != nil { + if t.GasFeeCap() != nil && t.Type() == types.DynamicFeeTxType { gasFeeCap := argBig(*(t.GasFeeCap())) res.GasFeeCap = &gasFeeCap } diff --git a/jsonrpc/types_test.go b/jsonrpc/types_test.go index 3ed10d67b2..d0fa5fa30c 100644 --- a/jsonrpc/types_test.go +++ b/jsonrpc/types_test.go @@ -365,7 +365,8 @@ func Test_toBlock(t *testing.T) { require.NoError(t, err) expectedJSON := loadTestData(t, "testsuite/block-with-txn-full.json") - require.JSONEq(t, expectedJSON, string(res)) + str := string(res) + require.JSONEq(t, expectedJSON, str) } func loadTestData(t *testing.T, name string) string { diff --git a/types/legacy_tx.go b/types/legacy_tx.go index f3fff8a206..533681e903 100644 --- a/types/legacy_tx.go +++ b/types/legacy_tx.go @@ -57,11 +57,10 @@ func (tx *LegacyTx) setGasPrice(gas *big.Int) { } func (tx *LegacyTx) setGasFeeCap(gas *big.Int) { - tx.GasPrice = gas } func (tx *LegacyTx) setGasTipCap(gas *big.Int) { - tx.GasPrice = gas + } func (tx *LegacyTx) setTransactionType(t TxType) {} From 718a5e46131326a14908a29cbca341967793ef01 Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Fri, 9 Feb 2024 08:59:31 +0100 Subject: [PATCH 10/18] test and lint fix --- jsonrpc/txpool_endpoint_test.go | 12 ++++++------ types/access_list_tx.go | 5 ++++- types/dynamic_fee_tx.go | 4 +++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/jsonrpc/txpool_endpoint_test.go b/jsonrpc/txpool_endpoint_test.go index df9260adb7..2941a81e14 100644 --- a/jsonrpc/txpool_endpoint_test.go +++ b/jsonrpc/txpool_endpoint_test.go @@ -49,8 +49,8 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, testTx1.Gas(), uint64(txData.Gas)) assert.Equal(t, *(testTx1.GasPrice()), big.Int(*txData.GasPrice)) - assert.Equal(t, *(testTx1.GasFeeCap()), big.Int(*txData.GasFeeCap)) - assert.Equal(t, *(testTx1.GasTipCap()), big.Int(*txData.GasTipCap)) + assert.Equal(t, *(testTx1.GasFeeCap()), big.Int(*txData.GasPrice)) + assert.Equal(t, *(testTx1.GasTipCap()), big.Int(*txData.GasPrice)) assert.Equal(t, testTx1.To(), txData.To) assert.Equal(t, testTx1.From(), txData.From) assert.Equal(t, *(testTx1.Value()), big.Int(txData.Value)) @@ -62,7 +62,7 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) - assert.Equal(t, (*testTx2.GasPrice()), big.Int(*txData.GasPrice)) + assert.Equal(t, (*testTx2.GasPrice()), big.Int(*txData.GasFeeCap)) assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) assert.Equal(t, *(testTx2.GasTipCap()), big.Int(*txData.GasTipCap)) assert.Equal(t, testTx2.To(), txData.To) @@ -98,8 +98,8 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, testTx1.Gas(), uint64(txData.Gas)) assert.Equal(t, *(testTx1.GasPrice()), big.Int(*txData.GasPrice)) - assert.Equal(t, *(testTx1.GasFeeCap()), big.Int(*txData.GasFeeCap)) - assert.Equal(t, *(testTx1.GasTipCap()), big.Int(*txData.GasTipCap)) + assert.Equal(t, *(testTx1.GasFeeCap()), big.Int(*txData.GasPrice)) + assert.Equal(t, *(testTx1.GasTipCap()), big.Int(*txData.GasPrice)) assert.Equal(t, testTx1.To(), txData.To) assert.Equal(t, testTx1.From(), txData.From) assert.Equal(t, *(testTx1.Value()), big.Int(txData.Value)) @@ -111,7 +111,7 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) - assert.Equal(t, *(testTx2.GasPrice()), big.Int(*txData.GasPrice)) + assert.Equal(t, *(testTx2.GasPrice()), big.Int(*txData.GasFeeCap)) assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) assert.Equal(t, *(testTx2.GasTipCap()), big.Int(*txData.GasTipCap)) assert.Equal(t, testTx2.To(), txData.To) diff --git a/types/access_list_tx.go b/types/access_list_tx.go index 44baf033ce..efdadb4b35 100644 --- a/types/access_list_tx.go +++ b/types/access_list_tx.go @@ -100,6 +100,7 @@ func (al TxAccessList) marshallRLPWith(arena *fastrlp.Arena) *fastrlp.Value { accessTupleVV.Set(storageKeysVV) accessListVV.Set(accessTupleVV) } + return accessListVV } @@ -291,7 +292,9 @@ func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) e txAccessList = make(TxAccessList, len(accessListVV)) } - txAccessList.unmarshallRLPFrom(p, accessListVV) + if err = txAccessList.unmarshallRLPFrom(p, accessListVV); err != nil { + return err + } tx.setAccessList(txAccessList) diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go index 4f360c822f..12dc491025 100644 --- a/types/dynamic_fee_tx.go +++ b/types/dynamic_fee_tx.go @@ -192,7 +192,9 @@ func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er txAccessList = make(TxAccessList, len(accessListVV)) } - txAccessList.unmarshallRLPFrom(p, accessListVV) + if err = txAccessList.unmarshallRLPFrom(p, accessListVV); err != nil { + return err + } tx.setAccessList(txAccessList) From 622a24c7c4d7b6b3c7af7d43b98f02e57d4d8925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Tue, 13 Feb 2024 09:41:50 +0100 Subject: [PATCH 11/18] Simplify 1 ETH constant --- jsonrpc/dispatcher_test.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/jsonrpc/dispatcher_test.go b/jsonrpc/dispatcher_test.go index ae0331b228..63cfc7e90d 100644 --- a/jsonrpc/dispatcher_test.go +++ b/jsonrpc/dispatcher_test.go @@ -3,7 +3,6 @@ package jsonrpc import ( "encoding/json" "fmt" - "math/big" "reflect" "testing" "time" @@ -13,12 +12,11 @@ import ( "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/umbracle/ethgo" ) var ( - oneEther = new(big.Int).Mul( - big.NewInt(1), - new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) + oneEther = ethgo.Ether(1) ) func toArgUint64Ptr(value uint64) *argUint64 { From 058fe77559313f3b2bf7b9d778bfe135f59ae40e Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Tue, 13 Feb 2024 12:37:33 +0100 Subject: [PATCH 12/18] comment fix --- txpool/txpool.go | 1 + types/access_list_tx.go | 34 ++++++++++++++-------------------- types/dynamic_fee_tx.go | 37 +++++++++++++++---------------------- types/legacy_tx.go | 30 ++++++++++++------------------ types/rlp_unmarshal.go | 8 ++++++++ types/state_tx.go | 32 +++++++++++++------------------- types/transaction.go | 4 ---- 7 files changed, 63 insertions(+), 83 deletions(-) diff --git a/txpool/txpool.go b/txpool/txpool.go index 3b6adec4cd..3fcba4a526 100644 --- a/txpool/txpool.go +++ b/txpool/txpool.go @@ -671,6 +671,7 @@ func (p *TxPool) validateTx(tx *types.Transaction) error { } if tx.GetGasPrice(baseFee).Cmp(new(big.Int).SetUint64(p.priceLimit)) < 0 { + // Make sure that the transaction is not underpriced metrics.IncrCounter([]string{txPoolMetrics, "underpriced_tx"}, 1) return ErrUnderpriced diff --git a/types/access_list_tx.go b/types/access_list_tx.go index efdadb4b35..2663b304e7 100644 --- a/types/access_list_tx.go +++ b/types/access_list_tx.go @@ -204,33 +204,27 @@ func (tx *AccessListTxn) setHash(h Hash) { // Use UnmarshalRLP in most cases func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { numOfElems := 11 + var values rlpValues - elems, err := v.GetElems() + values, err := v.GetElems() if err != nil { return err } - getElem := func() *fastrlp.Value { - val := elems[0] - elems = elems[1:] - - return val - } - - if numElems := len(elems); numElems != numOfElems { + if numElems := len(values); numElems != numOfElems { return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", numOfElems, numElems) } txChainID := new(big.Int) - if err = getElem().GetBigInt(txChainID); err != nil { + if err = values.dequeueValue().GetBigInt(txChainID); err != nil { return err } tx.setChainID(txChainID) // nonce - txNonce, err := getElem().GetUint64() + txNonce, err := values.dequeueValue().GetUint64() if err != nil { return err } @@ -239,14 +233,14 @@ func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) e // gasPrice txGasPrice := new(big.Int) - if err = getElem().GetBigInt(txGasPrice); err != nil { + if err = values.dequeueValue().GetBigInt(txGasPrice); err != nil { return err } tx.setGasPrice(txGasPrice) // gas - txGas, err := getElem().GetUint64() + txGas, err := values.dequeueValue().GetUint64() if err != nil { return err } @@ -254,7 +248,7 @@ func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) e tx.setGas(txGas) // to - if vv, _ := getElem().Bytes(); len(vv) == 20 { + if vv, _ := values.dequeueValue().Bytes(); len(vv) == 20 { // address addr := BytesToAddress(vv) tx.setTo(&addr) @@ -265,7 +259,7 @@ func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) e // value txValue := new(big.Int) - if err = getElem().GetBigInt(txValue); err != nil { + if err = values.dequeueValue().GetBigInt(txValue); err != nil { return err } @@ -274,7 +268,7 @@ func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) e // input var txInput []byte - txInput, err = getElem().GetBytes(txInput) + txInput, err = values.dequeueValue().GetBytes(txInput) if err != nil { return err } @@ -282,7 +276,7 @@ func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) e tx.setInput(txInput) //accessList - accessListVV, err := getElem().GetElems() + accessListVV, err := values.dequeueValue().GetElems() if err != nil { return err } @@ -300,19 +294,19 @@ func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) e // V txV := new(big.Int) - if err = getElem().GetBigInt(txV); err != nil { + if err = values.dequeueValue().GetBigInt(txV); err != nil { return err } // R txR := new(big.Int) - if err = getElem().GetBigInt(txR); err != nil { + if err = values.dequeueValue().GetBigInt(txR); err != nil { return err } // S txS := new(big.Int) - if err = getElem().GetBigInt(txS); err != nil { + if err = values.dequeueValue().GetBigInt(txS); err != nil { return err } diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go index 12dc491025..383745adb9 100644 --- a/types/dynamic_fee_tx.go +++ b/types/dynamic_fee_tx.go @@ -97,33 +97,27 @@ func (tx *DynamicFeeTx) setHash(h Hash) { tx.Hash = h } // Use UnmarshalRLP in most cases func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { numOfElems := 12 + var values rlpValues - elems, err := v.GetElems() + values, err := v.GetElems() if err != nil { return err } - getElem := func() *fastrlp.Value { - val := elems[0] - elems = elems[1:] - - return val - } - - if numElems := len(elems); numElems != numOfElems { + if numElems := len(values); numElems != numOfElems { return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", numOfElems, numElems) } // Load Chain ID txChainID := new(big.Int) - if err = getElem().GetBigInt(txChainID); err != nil { + if err = values.dequeueValue().GetBigInt(txChainID); err != nil { return err } tx.setChainID(txChainID) // nonce - txNonce, err := getElem().GetUint64() + txNonce, err := values.dequeueValue().GetUint64() if err != nil { return err } @@ -132,7 +126,7 @@ func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er // gasTipCap txGasTipCap := new(big.Int) - if err = getElem().GetBigInt(txGasTipCap); err != nil { + if err = values.dequeueValue().GetBigInt(txGasTipCap); err != nil { return err } @@ -140,14 +134,14 @@ func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er // gasFeeCap txGasFeeCap := new(big.Int) - if err = getElem().GetBigInt(txGasFeeCap); err != nil { + if err = values.dequeueValue().GetBigInt(txGasFeeCap); err != nil { return err } tx.setGasFeeCap(txGasFeeCap) // gas - txGas, err := getElem().GetUint64() + txGas, err := values.dequeueValue().GetUint64() if err != nil { return err } @@ -155,8 +149,7 @@ func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er tx.setGas(txGas) // to - if vv, _ := getElem().Bytes(); len(vv) == 20 { - // address + if vv, _ := values.dequeueValue().Bytes(); len(vv) == 20 { addr := BytesToAddress(vv) tx.setTo(&addr) } else { @@ -166,7 +159,7 @@ func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er // value txValue := new(big.Int) - if err = getElem().GetBigInt(txValue); err != nil { + if err = values.dequeueValue().GetBigInt(txValue); err != nil { return err } @@ -175,14 +168,14 @@ func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er // input var txInput []byte - txInput, err = getElem().GetBytes(txInput) + txInput, err = values.dequeueValue().GetBytes(txInput) if err != nil { return err } tx.setInput(txInput) - accessListVV, err := getElem().GetElems() + accessListVV, err := values.dequeueValue().GetElems() if err != nil { return err } @@ -200,19 +193,19 @@ func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er // V txV := new(big.Int) - if err = getElem().GetBigInt(txV); err != nil { + if err = values.dequeueValue().GetBigInt(txV); err != nil { return err } // R txR := new(big.Int) - if err = getElem().GetBigInt(txR); err != nil { + if err = values.dequeueValue().GetBigInt(txR); err != nil { return err } // S txS := new(big.Int) - if err = getElem().GetBigInt(txS); err != nil { + if err = values.dequeueValue().GetBigInt(txS); err != nil { return err } diff --git a/types/legacy_tx.go b/types/legacy_tx.go index 533681e903..b6e4a4f6be 100644 --- a/types/legacy_tx.go +++ b/types/legacy_tx.go @@ -91,25 +91,19 @@ func (tx *LegacyTx) setHash(h Hash) { tx.Hash = h } // Use UnmarshalRLP in most cases func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { num := 9 + var values rlpValues - elems, err := v.GetElems() + values, err := v.GetElems() if err != nil { return err } - getElem := func() *fastrlp.Value { - val := elems[0] - elems = elems[1:] - - return val - } - - if numElems := len(elems); numElems != num { + if numElems := len(values); numElems != num { return fmt.Errorf("legacy incorrect number of transaction elements, expected %d but found %d", num, numElems) } // nonce - txNonce, err := getElem().GetUint64() + txNonce, err := values.dequeueValue().GetUint64() if err != nil { return err } @@ -118,14 +112,14 @@ func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error // gasPrice txGasPrice := new(big.Int) - if err = getElem().GetBigInt(txGasPrice); err != nil { + if err = values.dequeueValue().GetBigInt(txGasPrice); err != nil { return err } tx.setGasPrice(txGasPrice) // gas - txGas, err := getElem().GetUint64() + txGas, err := values.dequeueValue().GetUint64() if err != nil { return err } @@ -133,7 +127,7 @@ func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error tx.setGas(txGas) // to - if vv, _ := getElem().Bytes(); len(vv) == 20 { + if vv, _ := values.dequeueValue().Bytes(); len(vv) == 20 { // address addr := BytesToAddress(vv) tx.setTo(&addr) @@ -144,7 +138,7 @@ func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error // value txValue := new(big.Int) - if err = getElem().GetBigInt(txValue); err != nil { + if err = values.dequeueValue().GetBigInt(txValue); err != nil { return err } @@ -153,7 +147,7 @@ func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error // input var txInput []byte - txInput, err = getElem().GetBytes(txInput) + txInput, err = values.dequeueValue().GetBytes(txInput) if err != nil { return err } @@ -162,19 +156,19 @@ func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error // V txV := new(big.Int) - if err = getElem().GetBigInt(txV); err != nil { + if err = values.dequeueValue().GetBigInt(txV); err != nil { return err } // R txR := new(big.Int) - if err = getElem().GetBigInt(txR); err != nil { + if err = values.dequeueValue().GetBigInt(txR); err != nil { return err } // S txS := new(big.Int) - if err = getElem().GetBigInt(txS); err != nil { + if err = values.dequeueValue().GetBigInt(txS); err != nil { return err } diff --git a/types/rlp_unmarshal.go b/types/rlp_unmarshal.go index 197b47da0f..3743a151a6 100644 --- a/types/rlp_unmarshal.go +++ b/types/rlp_unmarshal.go @@ -383,3 +383,11 @@ func (t *Transaction) UnmarshalRLP(input []byte) error { return nil } + +type rlpValues []*fastrlp.Value + +func (r rlpValues) dequeueValue() *fastrlp.Value { + val := r[0] + r = r[1:] + return val +} diff --git a/types/state_tx.go b/types/state_tx.go index ffc1cbb883..e0eaf3c72e 100644 --- a/types/state_tx.go +++ b/types/state_tx.go @@ -94,25 +94,19 @@ func (tx *StateTx) setHash(h Hash) { tx.Hash = h } // Use UnmarshalRLP in most cases func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { numOfElems := 10 + var values rlpValues - elems, err := v.GetElems() + values, err := v.GetElems() if err != nil { return err } - getElem := func() *fastrlp.Value { - val := elems[0] - elems = elems[1:] - - return val - } - - if numElems := len(elems); numElems != numOfElems { + if numElems := len(values); numElems != numOfElems { return fmt.Errorf("incorrect number of transaction elements, expected %d but found %d", numOfElems, numElems) } // nonce - txNonce, err := getElem().GetUint64() + txNonce, err := values.dequeueValue().GetUint64() if err != nil { return err } @@ -121,14 +115,14 @@ func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // gasPrice txGasPrice := new(big.Int) - if err = getElem().GetBigInt(txGasPrice); err != nil { + if err = values.dequeueValue().GetBigInt(txGasPrice); err != nil { return err } tx.setGasPrice(txGasPrice) // gas - txGas, err := getElem().GetUint64() + txGas, err := values.dequeueValue().GetUint64() if err != nil { return err } @@ -136,7 +130,7 @@ func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { tx.setGas(txGas) // to - if vv, _ := getElem().Bytes(); len(vv) == 20 { + if vv, _ := values.dequeueValue().Bytes(); len(vv) == 20 { // address addr := BytesToAddress(vv) tx.setTo(&addr) @@ -147,7 +141,7 @@ func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // value txValue := new(big.Int) - if err = getElem().GetBigInt(txValue); err != nil { + if err = values.dequeueValue().GetBigInt(txValue); err != nil { return err } @@ -156,7 +150,7 @@ func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // input var txInput []byte - txInput, err = getElem().GetBytes(txInput) + txInput, err = values.dequeueValue().GetBytes(txInput) if err != nil { return err } @@ -165,19 +159,19 @@ func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // V txV := new(big.Int) - if err = getElem().GetBigInt(txV); err != nil { + if err = values.dequeueValue().GetBigInt(txV); err != nil { return err } // R txR := new(big.Int) - if err = getElem().GetBigInt(txR); err != nil { + if err = values.dequeueValue().GetBigInt(txR); err != nil { return err } // S txS := new(big.Int) - if err = getElem().GetBigInt(txS); err != nil { + if err = values.dequeueValue().GetBigInt(txS); err != nil { return err } @@ -187,7 +181,7 @@ func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { // We need to set From field for state transaction, // because we are using unique, predefined address, for sending such transactions - if vv, err := getElem().Bytes(); err == nil && len(vv) == AddressLength { + if vv, err := values.dequeueValue().Bytes(); err == nil && len(vv) == AddressLength { // address tx.setFrom(BytesToAddress(vv)) } diff --git a/types/transaction.go b/types/transaction.go index 9a1076480a..8df1a40ddc 100644 --- a/types/transaction.go +++ b/types/transaction.go @@ -372,10 +372,6 @@ func (t *Transaction) GetGasFeeCap() *big.Int { } } -func (t *Transaction) SetTxData(data TxData) { - t.Inner = data -} - // FindTxByHash returns transaction and its index from a slice of transactions func FindTxByHash(txs []*Transaction, hash Hash) (*Transaction, int) { for idx, txn := range txs { From 3bb08bf612ab49b64f37d4fa21d6b3000e7f40f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Tue, 13 Feb 2024 15:11:42 +0100 Subject: [PATCH 13/18] Fix tests --- types/rlp_unmarshal.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/types/rlp_unmarshal.go b/types/rlp_unmarshal.go index 3743a151a6..fef4710627 100644 --- a/types/rlp_unmarshal.go +++ b/types/rlp_unmarshal.go @@ -386,8 +386,12 @@ func (t *Transaction) UnmarshalRLP(input []byte) error { type rlpValues []*fastrlp.Value -func (r rlpValues) dequeueValue() *fastrlp.Value { - val := r[0] - r = r[1:] +func (r *rlpValues) dequeueValue() *fastrlp.Value { + if len(*r) == 0 { + return nil + } + val := (*r)[0] + *r = (*r)[1:] + return val } From 617bcd8629be61fe0f645ddb866098e8479d8b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Tue, 13 Feb 2024 15:18:39 +0100 Subject: [PATCH 14/18] Lint fix --- types/access_list_tx.go | 8 ++++++-- types/dynamic_fee_tx.go | 8 ++++++-- types/legacy_tx.go | 8 ++++++-- types/rlp_unmarshal.go | 1 + types/state_tx.go | 8 ++++++-- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/types/access_list_tx.go b/types/access_list_tx.go index 2663b304e7..2a3b5a01f6 100644 --- a/types/access_list_tx.go +++ b/types/access_list_tx.go @@ -204,9 +204,13 @@ func (tx *AccessListTxn) setHash(h Hash) { // Use UnmarshalRLP in most cases func (tx *AccessListTxn) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { numOfElems := 11 - var values rlpValues - values, err := v.GetElems() + var ( + values rlpValues + err error + ) + + values, err = v.GetElems() if err != nil { return err } diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go index 383745adb9..b5352683d3 100644 --- a/types/dynamic_fee_tx.go +++ b/types/dynamic_fee_tx.go @@ -97,9 +97,13 @@ func (tx *DynamicFeeTx) setHash(h Hash) { tx.Hash = h } // Use UnmarshalRLP in most cases func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { numOfElems := 12 - var values rlpValues - values, err := v.GetElems() + var ( + values rlpValues + err error + ) + + values, err = v.GetElems() if err != nil { return err } diff --git a/types/legacy_tx.go b/types/legacy_tx.go index b6e4a4f6be..23af43bd10 100644 --- a/types/legacy_tx.go +++ b/types/legacy_tx.go @@ -91,9 +91,13 @@ func (tx *LegacyTx) setHash(h Hash) { tx.Hash = h } // Use UnmarshalRLP in most cases func (tx *LegacyTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { num := 9 - var values rlpValues - values, err := v.GetElems() + var ( + values rlpValues + err error + ) + + values, err = v.GetElems() if err != nil { return err } diff --git a/types/rlp_unmarshal.go b/types/rlp_unmarshal.go index fef4710627..480acbe54d 100644 --- a/types/rlp_unmarshal.go +++ b/types/rlp_unmarshal.go @@ -390,6 +390,7 @@ func (r *rlpValues) dequeueValue() *fastrlp.Value { if len(*r) == 0 { return nil } + val := (*r)[0] *r = (*r)[1:] diff --git a/types/state_tx.go b/types/state_tx.go index e0eaf3c72e..52c86e3f3b 100644 --- a/types/state_tx.go +++ b/types/state_tx.go @@ -94,9 +94,13 @@ func (tx *StateTx) setHash(h Hash) { tx.Hash = h } // Use UnmarshalRLP in most cases func (tx *StateTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) error { numOfElems := 10 - var values rlpValues - values, err := v.GetElems() + var ( + values rlpValues + err error + ) + + values, err = v.GetElems() if err != nil { return err } From 13e75f69e012fc0427507eb0a3d5f61521d1fb49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Mon, 19 Feb 2024 13:18:05 +0100 Subject: [PATCH 15/18] Instantiate correct tx data --- tests/state_test_util.go | 48 +++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index f425fab22b..a5b9382c71 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -334,9 +334,11 @@ func (t *stTransaction) At(i indexes, baseFee *big.Int) (*types.Transaction, err value = v } + var txData types.TxData + // if tx is not dynamic and accessList is not nil, create an access list transaction if !isDynamiFeeTx && accessList != nil { - return types.NewTx(&types.AccessListTxn{ + txData = &types.AccessListTxn{ From: t.From, To: t.To, Nonce: t.Nonce, @@ -345,20 +347,36 @@ func (t *stTransaction) At(i indexes, baseFee *big.Int) (*types.Transaction, err GasPrice: gasPrice, Input: hex.MustDecodeHex(t.Data[i.Data]), AccessList: accessList, - }), nil - } - - return types.NewTx(&types.DynamicFeeTx{ - From: t.From, - To: t.To, - Nonce: t.Nonce, - Value: value, - Gas: t.GasLimit[i.Gas], - GasFeeCap: t.MaxFeePerGas, - GasTipCap: t.MaxPriorityFeePerGas, - Input: hex.MustDecodeHex(t.Data[i.Data]), - AccessList: accessList, - }), nil + } + } + + if txData == nil { + if isDynamiFeeTx { + txData = &types.DynamicFeeTx{ + From: t.From, + To: t.To, + Nonce: t.Nonce, + Value: value, + Gas: t.GasLimit[i.Gas], + GasFeeCap: t.MaxFeePerGas, + GasTipCap: t.MaxPriorityFeePerGas, + Input: hex.MustDecodeHex(t.Data[i.Data]), + AccessList: accessList, + } + } else { + txData = &types.LegacyTx{ + From: t.From, + To: t.To, + Nonce: t.Nonce, + Value: value, + Gas: t.GasLimit[i.Gas], + GasPrice: t.GasPrice, + Input: hex.MustDecodeHex(t.Data[i.Data]), + } + } + } + + return types.NewTx(txData), nil } func (t *stTransaction) UnmarshalJSON(input []byte) error { From 2c99ad90d8dcb826cb8da464ee50809a99417783 Mon Sep 17 00:00:00 2001 From: Goran Rojovic Date: Thu, 22 Feb 2024 14:52:23 +0100 Subject: [PATCH 16/18] Rebase fix --- types/buildroot/buildroot_test.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/types/buildroot/buildroot_test.go b/types/buildroot/buildroot_test.go index e787fa31cb..839313e0d2 100644 --- a/types/buildroot/buildroot_test.go +++ b/types/buildroot/buildroot_test.go @@ -27,7 +27,7 @@ func TestCalculateReceiptsRoot(t *testing.T) { CumulativeGasUsed: 100, GasUsed: 70, ContractAddress: &contractAddr1, - TransactionType: types.DynamicFeeTx, + TransactionType: types.DynamicFeeTxType, Logs: []*types.Log{ { Address: contractAddr1, @@ -47,7 +47,7 @@ func TestCalculateReceiptsRoot(t *testing.T) { CumulativeGasUsed: 100, GasUsed: 30, ContractAddress: &contractAddr2, - TransactionType: types.LegacyTx, + TransactionType: types.LegacyTxType, Logs: []*types.Log{ { Address: contractAddr1, @@ -82,7 +82,7 @@ func TestCalculateReceiptsRoot(t *testing.T) { CumulativeGasUsed: 100 + i, GasUsed: 70 + i, ContractAddress: &contractAddr1, - TransactionType: types.DynamicFeeTx, + TransactionType: types.DynamicFeeTxType, Logs: []*types.Log{ { Address: contractAddr1, @@ -128,7 +128,7 @@ func TestCalculateTransactionsRoot(t *testing.T) { transactions := []*types.Transaction{ { - Inner: &types.MixedTxn{ + Inner: &types.DynamicFeeTx{ Hash: types.StringToHash("0x1"), From: types.StringToAddress("0x2"), To: &contractAddr1, @@ -139,11 +139,10 @@ func TestCalculateTransactionsRoot(t *testing.T) { Nonce: 1, Gas: 100000, ChainID: big.NewInt(1), - Type: types.DynamicFeeTx, }, }, { - Inner: &types.MixedTxn{ + Inner: &types.LegacyTx{ Hash: types.StringToHash("0x4"), From: types.StringToAddress("0x5"), To: &contractAddr2, @@ -152,7 +151,6 @@ func TestCalculateTransactionsRoot(t *testing.T) { Gas: 200000, Input: []byte{0x4, 0x5, 0x6}, Nonce: 2, - Type: types.LegacyTx, }, }, } From d403c3dd6c93e5eed570b3096de6f164e29156f1 Mon Sep 17 00:00:00 2001 From: Goran Rojovic Date: Thu, 22 Feb 2024 15:54:44 +0100 Subject: [PATCH 17/18] Fix failing tests --- jsonrpc/txpool_endpoint_test.go | 4 ++-- tests/state_test_util.go | 2 +- types/dynamic_fee_tx.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jsonrpc/txpool_endpoint_test.go b/jsonrpc/txpool_endpoint_test.go index 2941a81e14..5173bb8955 100644 --- a/jsonrpc/txpool_endpoint_test.go +++ b/jsonrpc/txpool_endpoint_test.go @@ -62,7 +62,7 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) - assert.Equal(t, (*testTx2.GasPrice()), big.Int(*txData.GasFeeCap)) + assert.Nil(t, testTx2.GasPrice()) assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) assert.Equal(t, *(testTx2.GasTipCap()), big.Int(*txData.GasTipCap)) assert.Equal(t, testTx2.To(), txData.To) @@ -111,7 +111,7 @@ func TestContentEndpoint(t *testing.T) { assert.NotNil(t, txData) assert.Equal(t, (argUint64)(types.DynamicFeeTxType), txData.Type) assert.Equal(t, testTx2.Gas(), uint64(txData.Gas)) - assert.Equal(t, *(testTx2.GasPrice()), big.Int(*txData.GasFeeCap)) + assert.Nil(t, testTx2.GasPrice()) assert.Equal(t, *(testTx2.GasFeeCap()), big.Int(*txData.GasFeeCap)) assert.Equal(t, *(testTx2.GasTipCap()), big.Int(*txData.GasTipCap)) assert.Equal(t, testTx2.To(), txData.To) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index a5b9382c71..afcf3a3d40 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -370,7 +370,7 @@ func (t *stTransaction) At(i indexes, baseFee *big.Int) (*types.Transaction, err Nonce: t.Nonce, Value: value, Gas: t.GasLimit[i.Gas], - GasPrice: t.GasPrice, + GasPrice: gasPrice, Input: hex.MustDecodeHex(t.Data[i.Data]), } } diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go index b5352683d3..bd7f239b97 100644 --- a/types/dynamic_fee_tx.go +++ b/types/dynamic_fee_tx.go @@ -27,7 +27,7 @@ func (tx *DynamicFeeTx) transactionType() TxType { return DynamicFeeTxType } func (tx *DynamicFeeTx) chainID() *big.Int { return tx.ChainID } func (tx *DynamicFeeTx) input() []byte { return tx.Input } func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas } -func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap } +func (tx *DynamicFeeTx) gasPrice() *big.Int { return nil } func (tx *DynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap } func (tx *DynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap } func (tx *DynamicFeeTx) value() *big.Int { return tx.Value } From e4e6b7ac83292822be40d352c9ae0d5ce5561ddf Mon Sep 17 00:00:00 2001 From: Dusan Nosovic Date: Fri, 23 Feb 2024 10:44:39 +0100 Subject: [PATCH 18/18] Comment fix --- types/dynamic_fee_tx.go | 2 +- types/rlp_unmarshal_storage.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/types/dynamic_fee_tx.go b/types/dynamic_fee_tx.go index bd7f239b97..bb055947f1 100644 --- a/types/dynamic_fee_tx.go +++ b/types/dynamic_fee_tx.go @@ -153,7 +153,7 @@ func (tx *DynamicFeeTx) unmarshalRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) er tx.setGas(txGas) // to - if vv, _ := values.dequeueValue().Bytes(); len(vv) == 20 { + if vv, _ := values.dequeueValue().Bytes(); len(vv) == AddressLength { addr := BytesToAddress(vv) tx.setTo(&addr) } else { diff --git a/types/rlp_unmarshal_storage.go b/types/rlp_unmarshal_storage.go index e3711f3776..352c93b3b2 100644 --- a/types/rlp_unmarshal_storage.go +++ b/types/rlp_unmarshal_storage.go @@ -95,9 +95,9 @@ func (t *Transaction) unmarshalStoreRLPFrom(p *fastrlp.Parser, v *fastrlp.Value) return err } - elems = elems[1:] - t.InitInnerData(tType) + + elems = elems[1:] } // consensus part