From b797b1067a6396db4e01a09c60d68ff78dc05980 Mon Sep 17 00:00:00 2001 From: paologalligit Date: Thu, 9 Jan 2025 16:15:38 +0100 Subject: [PATCH] refactor: merge tx builder into one builder --- api/accounts/accounts_test.go | 27 +--- api/blocks/blocks_test.go | 47 +++--- api/debug/debug_test.go | 27 ++-- api/subscriptions/block_reader_test.go | 4 +- api/subscriptions/pending_tx_test.go | 47 ++---- api/subscriptions/subscriptions_test.go | 8 +- api/subscriptions/types_test.go | 28 ++-- .../transactions_benchmark_test.go | 6 +- .../transactions_coverter_test.go | 4 +- api/transactions/transactions_test.go | 40 ++--- api/transactions/types_test.go | 12 +- block/block_test.go | 4 +- chain/chain_test.go | 19 +-- chain/repository_test.go | 4 +- cmd/thor/node/node_benchmark_test.go | 6 +- cmd/thor/node/tx_stash_test.go | 16 +- cmd/thor/solo/solo.go | 7 +- consensus/consensus_test.go | 32 ++-- logdb/logdb_test.go | 10 +- packer/flow_test.go | 43 ++--- packer/packer_test.go | 4 +- runtime/resolved_tx_test.go | 115 ++++++++------ runtime/runtime_test.go | 8 +- thorclient/api_test.go | 10 +- tx/builder.go | 150 ++++++++++++++++++ tx/builder_dynamic_fee.go | 89 ----------- tx/builder_dynamic_fee_test.go | 92 ----------- tx/builder_legacy.go | 82 ---------- tx/builder_legacy_test.go | 89 ----------- tx/builder_test.go | 141 ++++++++++++++++ tx/signer_test.go | 24 ++- tx/transaction.go | 4 +- tx/transaction_test.go | 68 ++++---- tx/transactions_test.go | 2 +- txpool/tx_object_test.go | 38 +---- 35 files changed, 569 insertions(+), 738 deletions(-) create mode 100644 tx/builder.go delete mode 100644 tx/builder_dynamic_fee.go delete mode 100644 tx/builder_dynamic_fee_test.go delete mode 100644 tx/builder_legacy.go delete mode 100644 tx/builder_legacy_test.go create mode 100644 tx/builder_test.go diff --git a/api/accounts/accounts_test.go b/api/accounts/accounts_test.go index 0d3f83bfe..c07e23fbf 100644 --- a/api/accounts/accounts_test.go +++ b/api/accounts/accounts_test.go @@ -313,27 +313,12 @@ func initAccountServer(t *testing.T, enabledDeprecated bool) { } func buildTxWithClauses(txType int, chainTag byte, clauses ...*tx.Clause) *tx.Transaction { - var trx *tx.Transaction - switch txType { - case tx.LegacyTxType: - builder := new(tx.LegacyBuilder). - ChainTag(chainTag). - Expiration(10). - Gas(1000000) - for _, c := range clauses { - builder.Clause(c) - } - trx = builder.Build() - case tx.DynamicFeeTxType: - builder := new(tx.DynFeeBuilder). - ChainTag(chainTag). - Expiration(10). - Gas(1000000) - for _, c := range clauses { - builder.Clause(c) - } - trx = builder.Build() - } + trx, _ := tx.NewTxBuilder(txType). + ChainTag(chainTag). + Expiration(10). + Gas(1000000). + Clauses(clauses). + Build() return tx.MustSign(trx, genesis.DevAccounts()[0].PrivateKey) } diff --git a/api/blocks/blocks_test.go b/api/blocks/blocks_test.go index c89a0ff85..ac520d343 100644 --- a/api/blocks/blocks_test.go +++ b/api/blocks/blocks_test.go @@ -230,31 +230,28 @@ func initBlockServer(t *testing.T) { addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - legacyTx := tx.MustSign( - new(tx.LegacyBuilder). - ChainTag(thorChain.Repo().ChainTag()). - GasPriceCoef(1). - Expiration(10). - Gas(21000). - Nonce(1). - Clause(cla). - BlockRef(tx.NewBlockRef(0)). - Build(), - genesis.DevAccounts()[0].PrivateKey, - ) - dynFeeTx := tx.MustSign( - new(tx.DynFeeBuilder). - ChainTag(thorChain.Repo().ChainTag()). - MaxFeePerGas(big.NewInt(1000)). - MaxPriorityFeePerGas(big.NewInt(100000)). - Expiration(10). - Gas(21000). - Nonce(2). - Clause(cla). - BlockRef(tx.NewBlockRef(0)). - Build(), - genesis.DevAccounts()[0].PrivateKey, - ) + legacyTx, _ := tx.NewTxBuilder(tx.LegacyTxType). + ChainTag(thorChain.Repo().ChainTag()). + GasPriceCoef(1). + Expiration(10). + Gas(21000). + Nonce(1). + Clause(cla). + BlockRef(tx.NewBlockRef(0)). + Build() + legacyTx = tx.MustSign(legacyTx, genesis.DevAccounts()[0].PrivateKey) + + dynFeeTx, _ := tx.NewTxBuilder(tx.DynamicFeeTxType). + ChainTag(thorChain.Repo().ChainTag()). + MaxFeePerGas(big.NewInt(100000)). + MaxPriorityFeePerGas(big.NewInt(100)). + Expiration(10). + Gas(21000). + Nonce(2). + Clause(cla). + BlockRef(tx.NewBlockRef(0)). + Build() + dynFeeTx = tx.MustSign(dynFeeTx, genesis.DevAccounts()[0].PrivateKey) require.NoError(t, thorChain.MintTransactions(genesis.DevAccounts()[0], legacyTx, dynFeeTx)) diff --git a/api/debug/debug_test.go b/api/debug/debug_test.go index cdd7c81a5..7bc2c7c92 100644 --- a/api/debug/debug_test.go +++ b/api/debug/debug_test.go @@ -541,7 +541,7 @@ func initDebugServer(t *testing.T) { // Adding an empty clause transaction to the block to cover the case of // scanning multiple txs before getting the right one - noClausesTx := new(tx.LegacyBuilder). + noClausesTx, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). Expiration(10). Gas(21000). @@ -550,7 +550,7 @@ func initDebugServer(t *testing.T) { cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) cla2 := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - transaction = new(tx.LegacyBuilder). + transaction, _ = tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(10). @@ -562,17 +562,18 @@ func initDebugServer(t *testing.T) { Build() transaction = tx.MustSign(transaction, genesis.DevAccounts()[0].PrivateKey) - dynFeeTx := tx.MustSign( - new(tx.DynFeeBuilder). - ChainTag(thorChain.Repo().ChainTag()). - Expiration(10). - Gas(21000). - MaxFeePerGas(big.NewInt(1000)). - MaxPriorityFeePerGas(big.NewInt(100000)). - Nonce(1). - Clause(cla). - BlockRef(tx.NewBlockRef(0)). - Build(), + dynFeeTx, _ := tx.NewTxBuilder(tx.DynamicFeeTxType). + ChainTag(thorChain.Repo().ChainTag()). + Expiration(10). + Gas(21000). + MaxFeePerGas(big.NewInt(1000)). + MaxPriorityFeePerGas(big.NewInt(100000)). + Nonce(1). + Clause(cla). + BlockRef(tx.NewBlockRef(0)). + Build() + dynFeeTx = tx.MustSign( + dynFeeTx, genesis.DevAccounts()[0].PrivateKey, ) diff --git a/api/subscriptions/block_reader_test.go b/api/subscriptions/block_reader_test.go index e60bfb770..550a89319 100644 --- a/api/subscriptions/block_reader_test.go +++ b/api/subscriptions/block_reader_test.go @@ -64,7 +64,7 @@ func initChain(t *testing.T) *testchain.Chain { addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - tr := new(tx.LegacyBuilder). + tr, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(10). @@ -75,7 +75,7 @@ func initChain(t *testing.T) *testchain.Chain { Build() tr = tx.MustSign(tr, genesis.DevAccounts()[0].PrivateKey) - txDeploy := new(tx.DynFeeBuilder). + txDeploy, _ := tx.NewTxBuilder(tx.DynamicFeeTxType). ChainTag(thorChain.Repo().ChainTag()). MaxFeePerGas(big.NewInt(1)). Expiration(100). diff --git a/api/subscriptions/pending_tx_test.go b/api/subscriptions/pending_tx_test.go index c1bf98509..d60127c4d 100644 --- a/api/subscriptions/pending_tx_test.go +++ b/api/subscriptions/pending_tx_test.go @@ -95,7 +95,7 @@ func TestPendingTx_DispatchLoop(t *testing.T) { p.Subscribe(txCh) // Add a new tx to the mempool - transaction := createLegacyTx(repo, 0) + transaction := createTx(repo, 0, tx.LegacyTxType) txPool.AddLocal(transaction) // Start the dispatch loop @@ -113,7 +113,7 @@ func TestPendingTx_DispatchLoop(t *testing.T) { p.Unsubscribe(txCh) // Add another tx to the mempool - tx2 := createDynFeeTx(repo, 1) + tx2 := createTx(repo, 1, tx.DynamicFeeTxType) txPool.AddLocal(tx2) // Assert that the channel did not receive the second transaction @@ -165,7 +165,7 @@ func TestPendingTx_NoWriteAfterUnsubscribe(t *testing.T) { done := make(chan struct{}) // Attempt to write a new transaction - trx := createLegacyTx(thorChain.Repo(), 0) + trx := createTx(thorChain.Repo(), 0, tx.LegacyTxType) assert.NotPanics(t, func() { p.dispatch(trx, done) // dispatch should not panic after unsubscribe }, "Dispatching after unsubscribe should not panic") @@ -203,7 +203,7 @@ func TestPendingTx_UnsubscribeOnWebSocketClose(t *testing.T) { defer ws.Close() // Add a transaction - trx := createLegacyTx(thorChain.Repo(), 0) + trx := createTx(thorChain.Repo(), 0, tx.LegacyTxType) txPool.AddLocal(trx) // Wait to receive transaction @@ -225,38 +225,21 @@ func TestPendingTx_UnsubscribeOnWebSocketClose(t *testing.T) { sub.pendingTx.mu.Unlock() } -func createLegacyTx(repo *chain.Repository, addressNumber uint) *tx.Transaction { +func createTx(repo *chain.Repository, addressNumber uint, txType int) *tx.Transaction { addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) + trx, _ := tx.NewTxBuilder(txType). + ChainTag(repo.ChainTag()). + GasPriceCoef(1). + Expiration(1000). + Gas(21000). + Nonce(uint64(datagen.RandInt())). + Clause(cla). + BlockRef(tx.NewBlockRef(0)). + Build() return tx.MustSign( - new(tx.LegacyBuilder). - ChainTag(repo.ChainTag()). - GasPriceCoef(1). - Expiration(1000). - Gas(21000). - Nonce(uint64(datagen.RandInt())). - Clause(cla). - BlockRef(tx.NewBlockRef(0)). - Build(), - genesis.DevAccounts()[addressNumber].PrivateKey, - ) -} - -func createDynFeeTx(repo *chain.Repository, addressNumber uint) *tx.Transaction { - addr := thor.BytesToAddress([]byte("to")) - cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - - return tx.MustSign( - new(tx.DynFeeBuilder). - ChainTag(repo.ChainTag()). - MaxFeePerGas(big.NewInt(1)). - Expiration(10). - Gas(21000). - Nonce(1). - Clause(cla). - BlockRef(tx.NewBlockRef(0)). - Build(), + trx, genesis.DevAccounts()[addressNumber].PrivateKey, ) } diff --git a/api/subscriptions/subscriptions_test.go b/api/subscriptions/subscriptions_test.go index ec6af802c..ba972fcbd 100644 --- a/api/subscriptions/subscriptions_test.go +++ b/api/subscriptions/subscriptions_test.go @@ -239,7 +239,7 @@ func initSubscriptionsServer(t *testing.T, enabledDeprecated bool) { addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - tr := new(tx.DynFeeBuilder). + tr, _ := tx.NewTxBuilder(tx.DynamicFeeTxType). ChainTag(thorChain.Repo().ChainTag()). MaxFeePerGas(big.NewInt(1)). Expiration(10). @@ -255,7 +255,7 @@ func initSubscriptionsServer(t *testing.T, enabledDeprecated bool) { } tr = tr.WithSignature(sig) - txDeploy := new(tx.LegacyBuilder). + txDeploy, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(100). @@ -291,7 +291,7 @@ func TestSubscriptionsBacktrace(t *testing.T) { addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - tr := new(tx.LegacyBuilder). + tr, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(10). @@ -307,7 +307,7 @@ func TestSubscriptionsBacktrace(t *testing.T) { } tr = tr.WithSignature(sig) - txDeploy := new(tx.LegacyBuilder). + txDeploy, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(100). diff --git a/api/subscriptions/types_test.go b/api/subscriptions/types_test.go index 5720ad2b2..299512310 100644 --- a/api/subscriptions/types_test.go +++ b/api/subscriptions/types_test.go @@ -95,7 +95,7 @@ func TestConvertTransfer(t *testing.T) { repo, _ := chain.NewRepository(db, b) // New tx - legacyTx := new(tx.LegacyBuilder). + legacyTx, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(repo.ChainTag()). GasPriceCoef(1). Expiration(10). @@ -105,7 +105,7 @@ func TestConvertTransfer(t *testing.T) { Build() legacyTx = tx.MustSign(legacyTx, genesis.DevAccounts()[0].PrivateKey) - dynFeeTx := new(tx.DynFeeBuilder). + dynFeeTx, _ := tx.NewTxBuilder(tx.DynamicFeeTxType). ChainTag(repo.ChainTag()). MaxFeePerGas(big.NewInt(1)). Expiration(10). @@ -175,14 +175,15 @@ func TestConvertEventWithBadSignature(t *testing.T) { badSig := bytes.Repeat([]byte{0xf}, 65) // New tx - transaction := new(tx.LegacyBuilder). + transaction, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(1). GasPriceCoef(1). Expiration(10). Gas(21000). Nonce(1). BlockRef(tx.NewBlockRef(0)). - Build(). + Build() + transaction = transaction. WithSignature(badSig[:]) // New block @@ -214,15 +215,16 @@ func TestConvertEvent(t *testing.T) { repo, _ := chain.NewRepository(db, b) // New tx - transaction := tx.MustSign( - new(tx.LegacyBuilder). - ChainTag(repo.ChainTag()). - GasPriceCoef(1). - Expiration(10). - Gas(21000). - Nonce(1). - BlockRef(tx.NewBlockRef(0)). - Build(), + transaction, _ := tx.NewTxBuilder(tx.LegacyTxType). + ChainTag(repo.ChainTag()). + GasPriceCoef(1). + Expiration(10). + Gas(21000). + Nonce(1). + BlockRef(tx.NewBlockRef(0)). + Build() + transaction = tx.MustSign( + transaction, genesis.DevAccounts()[0].PrivateKey, ) diff --git a/api/transactions/transactions_benchmark_test.go b/api/transactions/transactions_benchmark_test.go index 667574f1b..c6eb55820 100644 --- a/api/transactions/transactions_benchmark_test.go +++ b/api/transactions/transactions_benchmark_test.go @@ -233,7 +233,7 @@ func createOneClausePerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Chain for gasUsed < 9_500_000 { toAddr := datagen.RandAddress() cla := tx.NewClause(&toAddr).WithValue(big.NewInt(10000)) - transaction := new(tx.LegacyBuilder). + transaction, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(math.MaxUint32 - 1). @@ -260,7 +260,7 @@ func createManyClausesPerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Cha gasUsed := uint64(0) txGas := uint64(42_000) - transactionBuilder := new(tx.LegacyBuilder). + transactionBuilder := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(math.MaxUint32 - 1). @@ -272,7 +272,7 @@ func createManyClausesPerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Cha transactionBuilder.Clause(tx.NewClause(&toAddr).WithValue(big.NewInt(10000))) } - transaction := transactionBuilder.Gas(gasUsed).Build() + transaction, _ := transactionBuilder.Gas(gasUsed).Build() sig, err := crypto.Sign(transaction.SigningHash().Bytes(), signerPK) if err != nil { diff --git a/api/transactions/transactions_coverter_test.go b/api/transactions/transactions_coverter_test.go index 58f3cef7c..ea042f969 100644 --- a/api/transactions/transactions_coverter_test.go +++ b/api/transactions/transactions_coverter_test.go @@ -22,7 +22,7 @@ func TestConvertLegacyTransaction_Success(t *testing.T) { cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) cla2 := tx.NewClause(&addr).WithValue(big.NewInt(10000)) br := tx.NewBlockRef(0) - transaction := new(tx.LegacyBuilder). + transaction, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(123). GasPriceCoef(1). Expiration(10). @@ -61,7 +61,7 @@ func TestConvertDynTransaction_Success(t *testing.T) { br := tx.NewBlockRef(0) maxFeePerGas := big.NewInt(25000) maxPriorityFeePerGas := big.NewInt(100) - transaction := new(tx.DynFeeBuilder). + transaction, _ := tx.NewTxBuilder(tx.DynamicFeeTxType). ChainTag(123). MaxFeePerGas(maxFeePerGas). MaxPriorityFeePerGas(maxPriorityFeePerGas). diff --git a/api/transactions/transactions_test.go b/api/transactions/transactions_test.go index 40ec4f7f5..21586b73a 100644 --- a/api/transactions/transactions_test.go +++ b/api/transactions/transactions_test.go @@ -141,13 +141,14 @@ func sendLegacyTx(t *testing.T) { var expiration = uint32(10) var gas = uint64(21000) - trx := tx.MustSign( - new(tx.LegacyBuilder). - BlockRef(blockRef). - ChainTag(chainTag). - Expiration(expiration). - Gas(gas). - Build(), + trx, _ := tx.NewTxBuilder(tx.LegacyTxType). + BlockRef(blockRef). + ChainTag(chainTag). + Expiration(expiration). + Gas(gas). + Build() + trx = tx.MustSign( + trx, genesis.DevAccounts()[0].PrivateKey, ) @@ -170,14 +171,15 @@ func sendDynamicFeeTx(t *testing.T) { var gas = uint64(21000) var maxFeePerGas = big.NewInt(128) - trx := tx.MustSign( - new(tx.DynFeeBuilder). - BlockRef(blockRef). - ChainTag(chainTag). - Expiration(expiration). - Gas(gas). - MaxFeePerGas(maxFeePerGas). - Build(), + trx, _ := tx.NewTxBuilder(tx.DynamicFeeTxType). + BlockRef(blockRef). + ChainTag(chainTag). + Expiration(expiration). + Gas(gas). + MaxFeePerGas(maxFeePerGas). + Build() + trx = tx.MustSign( + trx, genesis.DevAccounts()[0].PrivateKey, ) @@ -286,7 +288,7 @@ func sendTxWithBadFormat(t *testing.T) { } func sendTxThatCannotBeAcceptedInLocalMempool(t *testing.T) { - tx := new(tx.LegacyBuilder).Build() + tx, _ := tx.NewTxBuilder(tx.LegacyTxType).Build() rlpTx, err := rlp.EncodeToBytes(tx) if err != nil { t.Fatal(err) @@ -336,7 +338,7 @@ func initTransactionServer(t *testing.T) { addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - legacyTx = new(tx.LegacyBuilder). + legacyTx, _ = tx.NewTxBuilder(tx.LegacyTxType). ChainTag(chainTag). GasPriceCoef(1). Expiration(10). @@ -347,7 +349,7 @@ func initTransactionServer(t *testing.T) { Build() legacyTx = tx.MustSign(legacyTx, genesis.DevAccounts()[0].PrivateKey) - dynFeeTx = new(tx.DynFeeBuilder). + dynFeeTx, _ = tx.NewTxBuilder(tx.DynamicFeeTxType). ChainTag(chainTag). MaxFeePerGas(new(big.Int).SetInt64(1)). MaxPriorityFeePerGas(new(big.Int).SetInt64(10)). @@ -363,7 +365,7 @@ func initTransactionServer(t *testing.T) { mempool := txpool.New(thorChain.Repo(), thorChain.Stater(), txpool.Options{Limit: 10000, LimitPerAccount: 16, MaxLifetime: 10 * time.Minute}) - mempoolTx = new(tx.LegacyBuilder). + mempoolTx, _ = tx.NewTxBuilder(tx.LegacyTxType). ChainTag(chainTag). Expiration(10). Gas(21000). diff --git a/api/transactions/types_test.go b/api/transactions/types_test.go index e11d346df..5cfec0c87 100644 --- a/api/transactions/types_test.go +++ b/api/transactions/types_test.go @@ -21,12 +21,10 @@ import ( ) func TestErrorWhileRetrievingTxOriginInConvertReceipt(t *testing.T) { - txs := []*tx.Transaction{ - new(tx.LegacyBuilder).Build(), - new(tx.DynFeeBuilder).Build(), - } + txTypes := []int{tx.LegacyTxType, tx.DynamicFeeTxType} - for _, tr := range txs { + for _, txType := range txTypes { + tr, _ := tx.NewTxBuilder(txType).Build() header := &block.Header{} receipt := &tx.Receipt{ Reward: big.NewInt(100), @@ -117,7 +115,7 @@ func newReceipt() *tx.Receipt { } func newLegacyTx(clause *tx.Clause) *tx.Transaction { - tx := new(tx.LegacyBuilder). + tx, _ := tx.NewTxBuilder(tx.LegacyTxType). Clause(clause). Build() pk, _ := crypto.GenerateKey() @@ -126,7 +124,7 @@ func newLegacyTx(clause *tx.Clause) *tx.Transaction { } func newDynFeeTx(clause *tx.Clause) *tx.Transaction { - tx := new(tx.DynFeeBuilder). + tx, _ := tx.NewTxBuilder(tx.DynamicFeeTxType). Clause(clause). Build() pk, _ := crypto.GenerateKey() diff --git a/block/block_test.go b/block/block_test.go index 3f635e2a2..ba83d876b 100644 --- a/block/block_test.go +++ b/block/block_test.go @@ -18,8 +18,8 @@ import ( ) func TestBlock(t *testing.T) { - tx1 := new(tx.LegacyBuilder).Clause(tx.NewClause(&thor.Address{})).Clause(tx.NewClause(&thor.Address{})).Build() - tx2 := new(tx.DynFeeBuilder).Clause(tx.NewClause(nil)).Build() + tx1, _ := tx.NewTxBuilder(tx.LegacyTxType).Clause(tx.NewClause(&thor.Address{})).Clause(tx.NewClause(&thor.Address{})).Build() + tx2, _ := tx.NewTxBuilder(tx.DynamicFeeTxType).Clause(tx.NewClause(nil)).Build() privKey := string("dce1443bd2ef0c2631adc1c67e5c93f13dc23a41c18b536effbbdcbcdb96fb65") diff --git a/chain/chain_test.go b/chain/chain_test.go index 781d4ca86..2645cbe1c 100644 --- a/chain/chain_test.go +++ b/chain/chain_test.go @@ -16,15 +16,8 @@ import ( "github.com/vechain/thor/v2/tx" ) -func newLegacyTx() *tx.Transaction { - tx := new(tx.LegacyBuilder).Build() - pk, _ := crypto.GenerateKey() - sig, _ := crypto.Sign(tx.SigningHash().Bytes(), pk) - return tx.WithSignature(sig) -} - -func newDynFeeTx() *tx.Transaction { - tx := new(tx.LegacyBuilder).Build() +func newTx(txType int) *tx.Transaction { + tx, _ := tx.NewTxBuilder(txType).Build() pk, _ := crypto.GenerateKey() sig, _ := crypto.Sign(tx.SigningHash().Bytes(), pk) return tx.WithSignature(sig) @@ -32,12 +25,10 @@ func newDynFeeTx() *tx.Transaction { func TestChain(t *testing.T) { _, repo := newTestRepo() - txs := []*tx.Transaction{ - newLegacyTx(), - newDynFeeTx(), - } + txTypes := []int{tx.LegacyTxType, tx.DynamicFeeTxType} - for _, tr := range txs { + for _, txType := range txTypes { + tr := newTx(txType) b1 := newBlock(repo.GenesisBlock(), 10, tr) tx1Meta := &chain.TxMeta{BlockID: b1.Header().ID(), Index: 0, Reverted: false} tx1Receipt := &tx.Receipt{} diff --git a/chain/repository_test.go b/chain/repository_test.go index 48e7f31aa..3e7688371 100644 --- a/chain/repository_test.go +++ b/chain/repository_test.go @@ -71,7 +71,7 @@ func TestRepository(t *testing.T) { assert.Equal(t, b0summary, repo1.BestBlockSummary()) assert.Equal(t, repo1.GenesisBlock().Header().ID()[31], repo1.ChainTag()) - tx1 := new(tx.LegacyBuilder).Build() + tx1, _ := tx.NewTxBuilder(tx.LegacyTxType).Build() receipt1 := &tx.Receipt{} b1 := newBlock(repo1.GenesisBlock(), 10, tx1) @@ -98,7 +98,7 @@ func TestRepository(t *testing.T) { assert.Equal(t, tx.Receipts{receipt1}.RootHash(), gotReceipts.RootHash()) } - tx2 := new(tx.DynFeeBuilder).Build() + tx2, _ := tx.NewTxBuilder(tx.DynamicFeeTxType).Build() receipt2 := &tx.Receipt{} b2 := newBlock(b1, 20, tx2) diff --git a/cmd/thor/node/node_benchmark_test.go b/cmd/thor/node/node_benchmark_test.go index 01f9843c9..f4012a253 100644 --- a/cmd/thor/node/node_benchmark_test.go +++ b/cmd/thor/node/node_benchmark_test.go @@ -262,7 +262,7 @@ func createOneClausePerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Chain for gasUsed < 9_500_000 { toAddr := datagen.RandAddress() cla := tx.NewClause(&toAddr).WithValue(big.NewInt(10000)) - transaction := new(tx.LegacyBuilder). + transaction, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(math.MaxUint32 - 1). @@ -289,7 +289,7 @@ func createManyClausesPerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Cha gasUsed := uint64(0) txGas := uint64(42_000) - transactionBuilder := new(tx.LegacyBuilder). + transactionBuilder := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(math.MaxUint32 - 1). @@ -301,7 +301,7 @@ func createManyClausesPerTx(signerPK *ecdsa.PrivateKey, thorChain *testchain.Cha transactionBuilder.Clause(tx.NewClause(&toAddr).WithValue(big.NewInt(10000))) } - transaction := transactionBuilder.Gas(gasUsed).Build() + transaction, _ := transactionBuilder.Gas(gasUsed).Build() sig, err := crypto.Sign(transaction.SigningHash().Bytes(), signerPK) if err != nil { diff --git a/cmd/thor/node/tx_stash_test.go b/cmd/thor/node/tx_stash_test.go index 9b604534c..58357b377 100644 --- a/cmd/thor/node/tx_stash_test.go +++ b/cmd/thor/node/tx_stash_test.go @@ -18,16 +18,10 @@ import ( "github.com/vechain/thor/v2/tx" ) -func newLegacyTx() *tx.Transaction { +func newTx(txType int) *tx.Transaction { + trx, _ := tx.NewTxBuilder(txType).Nonce(rand.Uint64()).Build() //#nosec return tx.MustSign( - new(tx.LegacyBuilder).Nonce(rand.Uint64()).Build(), //#nosec - genesis.DevAccounts()[0].PrivateKey, - ) -} - -func newDynFeeTx() *tx.Transaction { - return tx.MustSign( - new(tx.DynFeeBuilder).Nonce(rand.Uint64()).Build(), //#nosec + trx, genesis.DevAccounts()[0].PrivateKey, ) } @@ -40,13 +34,13 @@ func TestTxStash(t *testing.T) { var saved tx.Transactions for i := 0; i < 11; i++ { - tx := newLegacyTx() + tx := newTx(tx.LegacyTxType) assert.Nil(t, stash.Save(tx)) saved = append(saved, tx) } for i := 0; i < 11; i++ { - tx := newDynFeeTx() + tx := newTx(tx.DynamicFeeTxType) assert.Nil(t, stash.Save(tx)) saved = append(saved, tx) } diff --git a/cmd/thor/solo/solo.go b/cmd/thor/solo/solo.go index d3125c39e..d071cc51f 100644 --- a/cmd/thor/solo/solo.go +++ b/cmd/thor/solo/solo.go @@ -255,16 +255,19 @@ func (s *Solo) init(ctx context.Context) error { // newTx builds and signs a new transaction from the given clauses func (s *Solo) newTx(clauses []*tx.Clause, from genesis.DevAccount) (*tx.Transaction, error) { - builder := new(tx.LegacyBuilder).ChainTag(s.repo.ChainTag()) + builder := tx.NewTxBuilder(tx.LegacyTxType).ChainTag(s.repo.ChainTag()) for _, c := range clauses { builder.Clause(c) } - trx := builder.BlockRef(tx.NewBlockRef(0)). + trx, err := builder.BlockRef(tx.NewBlockRef(0)). Expiration(math.MaxUint32). Nonce(rand.Uint64()). //#nosec G404 DependsOn(nil). Gas(1_000_000). Build() + if err != nil { + return nil, err + } return tx.Sign(trx, from.PrivateKey) } diff --git a/consensus/consensus_test.go b/consensus/consensus_test.go index 816c7c463..a0d8b69cd 100644 --- a/consensus/consensus_test.go +++ b/consensus/consensus_test.go @@ -27,9 +27,9 @@ import ( "github.com/vechain/thor/v2/vrf" ) -func txBuilder(tag byte) *tx.LegacyBuilder { +func txBuilder(tag byte, txType int) *tx.Builder { address := thor.BytesToAddress([]byte("addr")) - return new(tx.LegacyBuilder). + return tx.NewTxBuilder(txType). GasPriceCoef(1). Gas(1000000). Expiration(100). @@ -38,8 +38,8 @@ func txBuilder(tag byte) *tx.LegacyBuilder { ChainTag(tag) } -func txSign(builder *tx.LegacyBuilder) *tx.Transaction { - transaction := builder.Build() +func txSign(builder *tx.Builder) *tx.Transaction { + transaction, _ := builder.Build() sig, _ := crypto.Sign(transaction.SigningHash().Bytes(), genesis.DevAccounts()[0].PrivateKey) return transaction.WithSignature(sig) } @@ -99,7 +99,7 @@ func newTestConsensus() (*testConsensus, error) { addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - txBuilder := txBuilder(repo.ChainTag()).Clause(cla) + txBuilder := txBuilder(repo.ChainTag(), tx.LegacyTxType).Clause(cla) transaction := txSign(txBuilder) err = flow.Adopt(transaction) @@ -466,8 +466,8 @@ func TestVerifyBlock(t *testing.T) { }{ { "TxDepBroken", func(t *testing.T) { - txID := txSign(txBuilder(tc.tag)).ID() - tx := txSign(txBuilder(tc.tag).DependsOn(&txID)) + txID := txSign(txBuilder(tc.tag, tx.LegacyTxType)).ID() + tx := txSign(txBuilder(tc.tag, tx.LegacyTxType).DependsOn(&txID)) blk, err := tc.sign(tc.builder(tc.original.Header()).Transaction(tx)) if err != nil { @@ -481,7 +481,7 @@ func TestVerifyBlock(t *testing.T) { }, { "TxAlreadyExists", func(t *testing.T) { - tx := txSign(txBuilder(tc.tag)) + tx := txSign(txBuilder(tc.tag, tx.LegacyTxType)) blk, err := tc.sign(tc.builder(tc.original.Header()).Transaction(tx).Transaction(tx)) if err != nil { t.Fatal(err) @@ -578,7 +578,7 @@ func TestValidateBlockBody(t *testing.T) { }{ { "ErrTxsRootMismatch", func(t *testing.T) { - transaction := txSign(txBuilder(tc.tag)) + transaction := txSign(txBuilder(tc.tag, tx.LegacyTxType)) transactions := tx.Transactions{transaction} blk := block.Compose(tc.original.Header(), transactions) expected := consensusError( @@ -594,7 +594,7 @@ func TestValidateBlockBody(t *testing.T) { }, { "ErrChainTagMismatch", func(t *testing.T) { - blk, err := tc.sign(tc.builder(tc.original.Header()).Transaction(txSign(txBuilder(tc.tag + 1)))) + blk, err := tc.sign(tc.builder(tc.original.Header()).Transaction(txSign(txBuilder(tc.tag+1, tx.LegacyTxType)))) if err != nil { t.Fatal(err) } @@ -613,7 +613,7 @@ func TestValidateBlockBody(t *testing.T) { "ErrRefFutureBlock", func(t *testing.T) { blk, err := tc.sign( tc.builder(tc.original.Header()).Transaction( - txSign(txBuilder(tc.tag).BlockRef(tx.NewBlockRef(100))), + txSign(txBuilder(tc.tag, tx.LegacyTxType).BlockRef(tx.NewBlockRef(100))), )) if err != nil { t.Fatal(err) @@ -626,7 +626,7 @@ func TestValidateBlockBody(t *testing.T) { { "TxOriginBlocked", func(t *testing.T) { thor.MockBlocklist([]string{genesis.DevAccounts()[9].Address.String()}) - trx := txBuilder(tc.tag).Build() + trx, _ := txBuilder(tc.tag, tx.LegacyTxType).Build() trx = tx.MustSign(trx, genesis.DevAccounts()[9].PrivateKey) blk, err := tc.sign( @@ -644,7 +644,7 @@ func TestValidateBlockBody(t *testing.T) { }, { "TxSignerUnavailable", func(t *testing.T) { - tx := txBuilder(tc.tag).Build() + tx, _ := txBuilder(tc.tag, tx.LegacyTxType).Build() var sig [65]byte tx = tx.WithSignature(sig[:]) @@ -663,7 +663,7 @@ func TestValidateBlockBody(t *testing.T) { }, { "UnsupportedFeatures", func(t *testing.T) { - tx := txBuilder(tc.tag).Features(tx.Features(2)).Build() + tx, _ := txBuilder(tc.tag, tx.LegacyTxType).Features(tx.Features(2)).Build() sig, _ := crypto.Sign(tx.SigningHash().Bytes(), genesis.DevAccounts()[2].PrivateKey) tx = tx.WithSignature(sig) @@ -680,7 +680,7 @@ func TestValidateBlockBody(t *testing.T) { }, { "TxExpired", func(t *testing.T) { - tx := txSign(txBuilder(tc.tag).BlockRef(tx.NewBlockRef(0)).Expiration(0)) + tx := txSign(txBuilder(tc.tag, tx.LegacyTxType).BlockRef(tx.NewBlockRef(0)).Expiration(0)) blk, err := tc.sign(tc.builder(tc.original.Header()).Transaction(tx).Transaction(tx)) if err != nil { t.Fatal(err) @@ -700,7 +700,7 @@ func TestValidateBlockBody(t *testing.T) { }, { "ZeroGasTx", func(t *testing.T) { - txBuilder := new(tx.LegacyBuilder). + txBuilder := tx.NewTxBuilder(tx.LegacyTxType). GasPriceCoef(0). Gas(0). Expiration(100). diff --git a/logdb/logdb_test.go b/logdb/logdb_test.go index af766be6b..d67b46bbd 100644 --- a/logdb/logdb_test.go +++ b/logdb/logdb_test.go @@ -20,15 +20,7 @@ import ( ) func newTx(txType int) *tx.Transaction { - var trx *tx.Transaction - switch txType { - case tx.LegacyTxType: - trx = new(tx.LegacyBuilder).Build() - case tx.DynamicFeeTxType: - trx = new(tx.DynFeeBuilder).Build() - default: - panic(tx.ErrTxTypeNotSupported) - } + trx, _ := tx.NewTxBuilder(txType).Build() pk, _ := crypto.GenerateKey() diff --git a/packer/flow_test.go b/packer/flow_test.go index 0fcb61be2..1023cd0c0 100644 --- a/packer/flow_test.go +++ b/packer/flow_test.go @@ -21,8 +21,8 @@ import ( "github.com/vechain/thor/v2/tx" ) -func createLegacyTx(chainTag byte, gasPriceCoef uint8, expiration uint32, gas uint64, nonce uint64, dependsOn *thor.Bytes32, clause *tx.Clause, br tx.BlockRef) *tx.Transaction { - builder := new(tx.LegacyBuilder). +func createTx(txType int, chainTag byte, gasPriceCoef uint8, expiration uint32, gas uint64, nonce uint64, dependsOn *thor.Bytes32, clause *tx.Clause, br tx.BlockRef) *tx.Transaction { + builder := tx.NewTxBuilder(txType). ChainTag(chainTag). GasPriceCoef(gasPriceCoef). Expiration(expiration). @@ -32,26 +32,7 @@ func createLegacyTx(chainTag byte, gasPriceCoef uint8, expiration uint32, gas ui Clause(clause). BlockRef(br) - transaction := builder.Build() - - signature, _ := crypto.Sign(transaction.SigningHash().Bytes(), genesis.DevAccounts()[0].PrivateKey) - - return transaction.WithSignature(signature) -} - -func createDynFeeTx(chainTag byte, expiration uint32, gas uint64, maxFeePerGas, maxPriorityFeePerGas *big.Int, nonce uint64, dependsOn *thor.Bytes32, clause *tx.Clause, br tx.BlockRef) *tx.Transaction { - builder := new(tx.DynFeeBuilder). - ChainTag(chainTag). - Expiration(expiration). - Gas(gas). - MaxFeePerGas(maxFeePerGas). - MaxPriorityFeePerGas(maxPriorityFeePerGas). - Nonce(nonce). - DependsOn(dependsOn). - Clause(clause). - BlockRef(br) - - transaction := builder.Build() + transaction, _ := builder.Build() signature, _ := crypto.Sign(transaction.SigningHash().Bytes(), genesis.DevAccounts()[0].PrivateKey) @@ -85,12 +66,12 @@ func TestAdopt(t *testing.T) { t.Fatal("Error scheduling:", err) } - tx1 := createLegacyTx(chainTag, 1, 10, 21000, 1, nil, clause, tx.NewBlockRef(0)) + tx1 := createTx(tx.LegacyTxType, chainTag, 1, 10, 21000, 1, nil, clause, tx.NewBlockRef(0)) if err := flow.Adopt(tx1); err != nil { t.Fatal("Error adopting tx1:", err) } - tx2 := createLegacyTx(chainTag, 1, 10, 21000, 2, (*thor.Bytes32)(tx1.ID().Bytes()), clause, tx.NewBlockRef(0)) + tx2 := createTx(tx.LegacyTxType, chainTag, 1, 10, 21000, 2, (*thor.Bytes32)(tx1.ID().Bytes()), clause, tx.NewBlockRef(0)) if err := flow.Adopt(tx2); err != nil { t.Fatal("Error adopting tx2:", err) } @@ -102,7 +83,7 @@ func TestAdopt(t *testing.T) { } // Test dependency that does not exist - tx3 := createLegacyTx(chainTag, 1, 10, 21000, 2, (*thor.Bytes32)((thor.Bytes32{0x1}).Bytes()), clause, tx.NewBlockRef(0)) + tx3 := createTx(tx.LegacyTxType, chainTag, 1, 10, 21000, 2, (*thor.Bytes32)((thor.Bytes32{0x1}).Bytes()), clause, tx.NewBlockRef(0)) expectedErrorMessage = "tx not adoptable now" if err := flow.Adopt(tx3); err.Error() != expectedErrorMessage { t.Fatalf("Expected error message: '%s', but got: '%s'", expectedErrorMessage, err.Error()) @@ -141,12 +122,12 @@ func TestAdoptTypedTxs(t *testing.T) { t.Fatal("Error scheduling:", err) } - tx1 := createLegacyTx(chainTag, 1, 10, 21000, 1, nil, clause, tx.NewBlockRef(0)) + tx1 := createTx(tx.LegacyTxType, chainTag, 1, 10, 21000, 1, nil, clause, tx.NewBlockRef(0)) if err := flow.Adopt(tx1); err != nil { t.Fatal("Error adopting tx1:", err) } - tx2 := createDynFeeTx(chainTag, 10, 21000, big.NewInt(2500), big.NewInt(1000), 2, (*thor.Bytes32)(tx1.ID().Bytes()), clause, tx.NewBlockRef(0)) + tx2 := createTx(tx.DynamicFeeTxType, chainTag, 1, 10, 21000, 2, (*thor.Bytes32)(tx1.ID().Bytes()), clause, tx.NewBlockRef(0)) if err := flow.Adopt(tx2); err != nil { t.Fatal("Error adopting tx2:", err) } @@ -158,7 +139,7 @@ func TestAdoptTypedTxs(t *testing.T) { } // Test dependency that does not exist - tx3 := createDynFeeTx(chainTag, 10, 21000, big.NewInt(2500), big.NewInt(1000), 2, (*thor.Bytes32)((thor.Bytes32{0x1}).Bytes()), clause, tx.NewBlockRef(0)) + tx3 := createTx(tx.DynamicFeeTxType, chainTag, 1, 10, 21000, 2, (*thor.Bytes32)((thor.Bytes32{0x1}).Bytes()), clause, tx.NewBlockRef(0)) expectedErrorMessage = "tx not adoptable now" if err := flow.Adopt(tx3); err.Error() != expectedErrorMessage { t.Fatalf("Expected error message: '%s', but got: '%s'", expectedErrorMessage, err.Error()) @@ -230,21 +211,21 @@ func TestAdoptErr(t *testing.T) { flow, _ := pkr.Schedule(sum, uint64(time.Now().Unix())) // Test chain tag mismatch - tx1 := createLegacyTx(byte(0xFF), 1, 10, 21000, 1, nil, clause, tx.NewBlockRef(0)) + tx1 := createTx(tx.LegacyTxType, byte(0xFF), 1, 10, 21000, 1, nil, clause, tx.NewBlockRef(0)) expectedErrorMessage := "bad tx: chain tag mismatch" if err := flow.Adopt(tx1); err.Error() != expectedErrorMessage { t.Fatalf("Expected error message: '%s', but got: '%s'", expectedErrorMessage, err.Error()) } // Test wrong block reference - tx2 := createLegacyTx(repo.ChainTag(), 1, 10, 1, 21000, nil, clause, tx.NewBlockRef(1000)) + tx2 := createTx(tx.LegacyTxType, repo.ChainTag(), 1, 10, 21000, 1, nil, clause, tx.NewBlockRef(1000)) expectedErrorMessage = "tx not adoptable now" if err := flow.Adopt(tx2); err.Error() != expectedErrorMessage { t.Fatalf("Expected error message: '%s', but got: '%s'", expectedErrorMessage, err.Error()) } // Test exceeded gas limit - tx3 := createLegacyTx(repo.ChainTag(), 1, 0, 1, 1, nil, clause, tx.NewBlockRef(1)) + tx3 := createTx(tx.LegacyTxType, repo.ChainTag(), 1, 0, 1, 1, nil, clause, tx.NewBlockRef(1)) expectedErrorMessage = "gas limit reached" if err := flow.Adopt(tx3); err.Error() != expectedErrorMessage { t.Fatalf("Expected error message: '%s', but got: '%s'", expectedErrorMessage, err.Error()) diff --git a/packer/packer_test.go b/packer/packer_test.go index 7c1f5fd50..5ad1a688d 100644 --- a/packer/packer_test.go +++ b/packer/packer_test.go @@ -50,7 +50,7 @@ func (ti *txIterator) Next() *tx.Transaction { data, _ := method.EncodeInput(a1.Address, big.NewInt(1)) - trx := new(tx.LegacyBuilder). + trx, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(ti.chainTag). Clause(tx.NewClause(&builtin.Energy.Address).WithData(data)). Gas(300000).GasPriceCoef(0).Nonce(nonce).Expiration(math.MaxUint32).Build() @@ -207,7 +207,7 @@ func TestBlocklist(t *testing.T) { t.Fatal(err) } - tx0 := new(tx.LegacyBuilder). + tx0, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(repo.ChainTag()). Clause(tx.NewClause(&a1.Address)). Gas(300000).GasPriceCoef(0).Nonce(0).Expiration(math.MaxUint32).Build() diff --git a/runtime/resolved_tx_test.go b/runtime/resolved_tx_test.go index 31880d4d5..89343029b 100644 --- a/runtime/resolved_tx_test.go +++ b/runtime/resolved_tx_test.go @@ -76,52 +76,60 @@ func (tr *testResolvedTransaction) currentState() *state.State { } func (tr *testResolvedTransaction) TestResolveTransaction() { - legacyTxBuild := func() *tx.LegacyBuilder { - return legacyTxBuilder(tr.repo.ChainTag()) + legacyTxBuild := func() *tx.Builder { + return txBuilder(tr.repo.ChainTag(), tx.LegacyTxType) } - dynFeeTxBuild := func() *tx.DynFeeBuilder { - return dynFeeTxBuilder(tr.repo.ChainTag()) + dynFeeTxBuild := func() *tx.Builder { + return txBuilder(tr.repo.ChainTag(), tx.DynamicFeeTxType) } - _, err := runtime.ResolveTransaction(legacyTxBuild().Build()) + trx, _ := legacyTxBuild().Build() + _, err := runtime.ResolveTransaction(trx) tr.assert.Equal(secp256k1.ErrInvalidSignatureLen.Error(), err.Error()) - _, err = runtime.ResolveTransaction(dynFeeTxBuild().Build()) + trx, _ = dynFeeTxBuild().Build() + _, err = runtime.ResolveTransaction(trx) tr.assert.Equal(secp256k1.ErrInvalidSignatureLen.Error(), err.Error()) - _, err = runtime.ResolveTransaction(txSign(legacyTxBuild().Gas(21000 - 1).Build())) + trx, _ = legacyTxBuild().Gas(21000 - 1).Build() + _, err = runtime.ResolveTransaction(txSign(trx)) tr.assert.NotNil(err) - _, err = runtime.ResolveTransaction(txSign(dynFeeTxBuild().Gas(21000 - 1).Build())) + trx, _ = dynFeeTxBuild().Gas(21000 - 1).Build() + _, err = runtime.ResolveTransaction(txSign(trx)) tr.assert.NotNil(err) address := thor.BytesToAddress([]byte("addr")) - _, err = runtime.ResolveTransaction(txSign(legacyTxBuild().Clause(tx.NewClause(&address).WithValue(big.NewInt(-10)).WithData(nil)).Build())) + trx, _ = legacyTxBuild().Clause(tx.NewClause(&address).WithValue(big.NewInt(-10)).WithData(nil)).Build() + _, err = runtime.ResolveTransaction(txSign(trx)) tr.assert.NotNil(err) - _, err = runtime.ResolveTransaction(txSign(dynFeeTxBuild().Clause(tx.NewClause(&address).WithValue(big.NewInt(-10)).WithData(nil)).Build())) + trx, _ = dynFeeTxBuild().Clause(tx.NewClause(&address).WithValue(big.NewInt(-10)).WithData(nil)).Build() + _, err = runtime.ResolveTransaction(txSign(trx)) tr.assert.NotNil(err) - _, err = runtime.ResolveTransaction(txSign(legacyTxBuild(). + trx, _ = legacyTxBuild(). Clause(tx.NewClause(&address).WithValue(math.MaxBig256).WithData(nil)). - Clause(tx.NewClause(&address).WithValue(math.MaxBig256).WithData(nil)).Build(), - )) + Clause(tx.NewClause(&address).WithValue(math.MaxBig256).WithData(nil)).Build() + _, err = runtime.ResolveTransaction(txSign(trx)) tr.assert.NotNil(err) - _, err = runtime.ResolveTransaction(txSign(dynFeeTxBuild(). + trx, _ = dynFeeTxBuild(). Clause(tx.NewClause(&address).WithValue(math.MaxBig256).WithData(nil)). - Clause(tx.NewClause(&address).WithValue(math.MaxBig256).WithData(nil)).Build(), - )) + Clause(tx.NewClause(&address).WithValue(math.MaxBig256).WithData(nil)).Build() + _, err = runtime.ResolveTransaction(txSign(trx)) tr.assert.NotNil(err) - _, err = runtime.ResolveTransaction(txSign(legacyTxBuild().Build())) + trx, _ = legacyTxBuild().Build() + _, err = runtime.ResolveTransaction(txSign(trx)) tr.assert.Nil(err) - _, err = runtime.ResolveTransaction(txSign(dynFeeTxBuild().Build())) + trx, _ = dynFeeTxBuild().Build() + _, err = runtime.ResolveTransaction(txSign(trx)) tr.assert.Nil(err) } func (tr *testResolvedTransaction) TestCommonTo() { - legacyTxBuild := func() *tx.LegacyBuilder { - return legacyTxBuilder(tr.repo.ChainTag()) + legacyTxBuild := func() *tx.Builder { + return txBuilder(tr.repo.ChainTag(), tx.LegacyTxType) } - dynFeeTxBuild := func() *tx.DynFeeBuilder { - return dynFeeTxBuilder(tr.repo.ChainTag()) + dynFeeTxBuild := func() *tx.Builder { + return txBuilder(tr.repo.ChainTag(), tx.DynamicFeeTxType) } commonTo := func(tx *tx.Transaction, assert func(interface{}, ...interface{}) bool) { @@ -133,34 +141,43 @@ func (tr *testResolvedTransaction) TestCommonTo() { assert(to) } - commonTo(txSign(legacyTxBuild().Build()), tr.assert.Nil) - commonTo(txSign(dynFeeTxBuild().Build()), tr.assert.Nil) + legacyTx, _ := legacyTxBuild().Build() + dynFeeTx, _ := dynFeeTxBuild().Build() + commonTo(txSign(legacyTx), tr.assert.Nil) + commonTo(txSign(dynFeeTx), tr.assert.Nil) - commonTo(txSign(legacyTxBuild().Clause(tx.NewClause(nil)).Build()), tr.assert.Nil) - commonTo(txSign(dynFeeTxBuild().Clause(tx.NewClause(nil)).Build()), tr.assert.Nil) + legacyTx, _ = legacyTxBuild().Clause(tx.NewClause(nil)).Build() + dynFeeTx, _ = dynFeeTxBuild().Clause(tx.NewClause(nil)).Build() + commonTo(txSign(legacyTx), tr.assert.Nil) + commonTo(txSign(dynFeeTx), tr.assert.Nil) - commonTo(txSign(legacyTxBuild().Clause(clause()).Clause(tx.NewClause(nil)).Build()), tr.assert.Nil) - commonTo(txSign(dynFeeTxBuild().Clause(clause()).Clause(tx.NewClause(nil)).Build()), tr.assert.Nil) + legacyTx, _ = legacyTxBuild().Clause(clause()).Clause(tx.NewClause(nil)).Build() + dynFeeTx, _ = dynFeeTxBuild().Clause(clause()).Clause(tx.NewClause(nil)).Build() + commonTo(txSign(legacyTx), tr.assert.Nil) + commonTo(txSign(dynFeeTx), tr.assert.Nil) address := thor.BytesToAddress([]byte("addr1")) - commonTo(txSign(legacyTxBuild(). + legacyTx, _ = legacyTxBuild(). Clause(clause()). - Clause(tx.NewClause(&address)).Build(), - ), tr.assert.Nil) - commonTo(txSign(dynFeeTxBuild(). + Clause(tx.NewClause(&address)).Build() + commonTo(txSign(legacyTx), tr.assert.Nil) + + dynFeeTx, _ = dynFeeTxBuild(). Clause(clause()). - Clause(tx.NewClause(&address)).Build(), - ), tr.assert.Nil) + Clause(tx.NewClause(&address)).Build() + commonTo(txSign(dynFeeTx), tr.assert.Nil) - commonTo(txSign(legacyTxBuild().Clause(clause()).Build()), tr.assert.NotNil) - commonTo(txSign(dynFeeTxBuild().Clause(clause()).Build()), tr.assert.NotNil) + legacyTx, _ = legacyTxBuild().Clause(clause()).Build() + dynFeeTx, _ = dynFeeTxBuild().Clause(clause()).Build() + commonTo(txSign(legacyTx), tr.assert.NotNil) + commonTo(txSign(dynFeeTx), tr.assert.NotNil) } func (tr *testResolvedTransaction) TestBuyGas() { state := tr.currentState() - txBuild := func() *tx.LegacyBuilder { - return legacyTxBuilder(tr.repo.ChainTag()) + txBuild := func() *tx.Builder { + return txBuilder(tr.repo.ChainTag(), tx.LegacyTxType) } targetTime := tr.repo.BestBlockSummary().Header.Timestamp() + thor.BlockInterval @@ -176,24 +193,27 @@ func (tr *testResolvedTransaction) TestBuyGas() { return payer } + trx, _ := txBuild().Clause(clause().WithValue(big.NewInt(100))).Build() tr.assert.Equal( genesis.DevAccounts()[0].Address, - buyGas(txSign(txBuild().Clause(clause().WithValue(big.NewInt(100))).Build())), + buyGas(txSign(trx)), ) bind := builtin.Prototype.Native(state).Bind(genesis.DevAccounts()[1].Address) bind.SetCreditPlan(math.MaxBig256, big.NewInt(1000)) bind.AddUser(genesis.DevAccounts()[0].Address, targetTime) + trx, _ = txBuild().Clause(clause().WithValue(big.NewInt(100))).Build() tr.assert.Equal( genesis.DevAccounts()[1].Address, - buyGas(txSign(txBuild().Clause(clause().WithValue(big.NewInt(100))).Build())), + buyGas(txSign(trx)), ) bind.Sponsor(genesis.DevAccounts()[2].Address, true) bind.SelectSponsor(genesis.DevAccounts()[2].Address) + trx, _ = txBuild().Clause(clause().WithValue(big.NewInt(100))).Build() tr.assert.Equal( genesis.DevAccounts()[2].Address, - buyGas(txSign(txBuild().Clause(clause().WithValue(big.NewInt(100))).Build())), + buyGas(txSign(trx)), ) } @@ -202,8 +222,8 @@ func clause() *tx.Clause { return tx.NewClause(&address).WithData(nil) } -func legacyTxBuilder(tag byte) *tx.LegacyBuilder { - return new(tx.LegacyBuilder). +func txBuilder(tag byte, txType int) *tx.Builder { + return tx.NewTxBuilder(txType). GasPriceCoef(1). Gas(1000000). Expiration(100). @@ -211,15 +231,6 @@ func legacyTxBuilder(tag byte) *tx.LegacyBuilder { ChainTag(tag) } -func dynFeeTxBuilder(tag byte) *tx.DynFeeBuilder { - return new(tx.DynFeeBuilder). - MaxFeePerGas(big.NewInt(1)). - Gas(1000000). - Expiration(100). - Nonce(1). - ChainTag(tag) -} - func txSign(trx *tx.Transaction) *tx.Transaction { return tx.MustSign(trx, genesis.DevAccounts()[0].PrivateKey) } diff --git a/runtime/runtime_test.go b/runtime/runtime_test.go index 70b38eff0..3543c3ef1 100644 --- a/runtime/runtime_test.go +++ b/runtime/runtime_test.go @@ -663,7 +663,7 @@ func getMockTx(repo *chain.Repository, txType int, t *testing.T) *tx.Transaction var gas = uint64(210000) to, _ := thor.ParseAddress("0x7567d83b7b8d80addcb281a71d54fc7b3364ffed") - tx := new(tx.LegacyBuilder). + tx, _ := tx.NewTxBuilder(txType). BlockRef(blockRef). ChainTag(chainTag). Clause(tx.NewClause(&to).WithValue(big.NewInt(10000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})). @@ -680,9 +680,9 @@ func getMockTx(repo *chain.Repository, txType int, t *testing.T) *tx.Transaction return tx } -func GetMockFailedTx() tx.Transaction { +func GetMockFailedTx(txType int) tx.Transaction { to, _ := thor.ParseAddress("0x7567d83b7b8d80addcb281a71d54fc7b3364ffed") - trx := new(tx.LegacyBuilder).ChainTag(1). + trx, _ := tx.NewTxBuilder(txType).ChainTag(1). BlockRef(tx.BlockRef{0, 0, 0, 0, 0xaa, 0xbb, 0xcc, 0xdd}). Expiration(32). Clause(tx.NewClause(&to).WithValue(big.NewInt(10000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})). @@ -766,7 +766,7 @@ func TestExecuteTransactionFailure(t *testing.T) { originEnergy.SetString("9000000000000000000000000000000000000", 10) state.SetEnergy(origin.Address, originEnergy, 0) - tx := GetMockFailedTx() + tx := GetMockFailedTx(tx.LegacyTxType) rt := runtime.New(repo.NewChain(b0.Header().ID()), state, &xenv.BlockContext{}, thor.NoFork) diff --git a/thorclient/api_test.go b/thorclient/api_test.go index 36116bee5..fdb0252c7 100644 --- a/thorclient/api_test.go +++ b/thorclient/api_test.go @@ -87,7 +87,7 @@ func initAPIServer(t *testing.T) (*testchain.Chain, *httptest.Server) { func mintTransactions(t *testing.T, thorChain *testchain.Chain) { toAddr := datagen.RandAddress() - noClausesTx := new(tx.LegacyBuilder). + noClausesTx, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). Expiration(10). Gas(21000). @@ -100,7 +100,7 @@ func mintTransactions(t *testing.T, thorChain *testchain.Chain) { cla := tx.NewClause(&toAddr).WithValue(big.NewInt(10000)) cla2 := tx.NewClause(&toAddr).WithValue(big.NewInt(10000)) - transaction := new(tx.LegacyBuilder). + transaction, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). GasPriceCoef(1). Expiration(10). @@ -218,7 +218,7 @@ func testTransactionsEndpoint(t *testing.T, thorChain *testchain.Chain, ts *http t.Run("SendTransaction", func(t *testing.T) { toAddr := thor.MustParseAddress("0x0123456789abcdef0123456789abcdef01234567") clause := tx.NewClause(&toAddr).WithValue(big.NewInt(10000)) - trx := new(tx.LegacyBuilder). + trx, _ := tx.NewTxBuilder(tx.LegacyTxType). ChainTag(thorChain.Repo().ChainTag()). Expiration(10). Gas(21000). @@ -231,7 +231,7 @@ func testTransactionsEndpoint(t *testing.T, thorChain *testchain.Chain, ts *http require.NotNil(t, sendResult) require.Equal(t, trx.ID().String(), sendResult.ID.String()) // Ensure transaction was successful - trx = new(tx.DynFeeBuilder). + trx, _ = tx.NewTxBuilder(tx.DynamicFeeTxType). ChainTag(thorChain.Repo().ChainTag()). Expiration(10). Gas(21000). @@ -380,7 +380,7 @@ func testEventsEndpoint(t *testing.T, _ *testchain.Chain, ts *httptest.Server) { // Define the payload for filtering events payload := &events.EventFilter{ CriteriaSet: []*events.EventCriteria{ - &events.EventCriteria{ + { Address: &address, TopicSet: events.TopicSet{ Topic0: &topic, diff --git a/tx/builder.go b/tx/builder.go new file mode 100644 index 000000000..a441a56f6 --- /dev/null +++ b/tx/builder.go @@ -0,0 +1,150 @@ +// Copyright (c) 2024 The VeChainThor developers + +// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying +// file LICENSE or + +package tx + +import ( + "encoding/binary" + "math/big" + + "github.com/vechain/thor/v2/thor" +) + +// Builder to make it easy to build transaction. +type Builder struct { + txType int + chainTag byte + clauses []*Clause + gasPriceCoef uint8 + maxFeePerGas *big.Int + maxPriorityFeePerGas *big.Int + gas uint64 + blockRef uint64 + expiration uint32 + nonce uint64 + dependsOn *thor.Bytes32 + reserved reserved +} + +func NewTxBuilder(txType int) *Builder { + return &Builder{txType: txType} +} + +// ChainTag set chain tag. +func (b *Builder) ChainTag(tag byte) *Builder { + b.chainTag = tag + return b +} + +// Clause add a clause. +func (b *Builder) Clause(c *Clause) *Builder { + b.clauses = append(b.clauses, c) + return b +} + +func (b *Builder) Clauses(clauses []*Clause) *Builder { + for _, c := range clauses { + b.Clause(c) + } + return b +} + +// GasPriceCoef set gas price coef. +func (b *Builder) GasPriceCoef(coef uint8) *Builder { + b.gasPriceCoef = coef + return b +} + +// MaxFeePerGas set max fee per gas. +func (b *Builder) MaxFeePerGas(maxFeePerGas *big.Int) *Builder { + b.maxFeePerGas = maxFeePerGas + return b +} + +// MaxPriorityFeePerGas set max priority fee per gas. +func (b *Builder) MaxPriorityFeePerGas(maxPriorityFeePerGas *big.Int) *Builder { + b.maxPriorityFeePerGas = maxPriorityFeePerGas + return b +} + +// Gas set gas provision for tx. +func (b *Builder) Gas(gas uint64) *Builder { + b.gas = gas + return b +} + +// BlockRef set block reference. +func (b *Builder) BlockRef(br BlockRef) *Builder { + b.blockRef = binary.BigEndian.Uint64(br[:]) + return b +} + +// Expiration set expiration. +func (b *Builder) Expiration(exp uint32) *Builder { + b.expiration = exp + return b +} + +// Nonce set nonce. +func (b *Builder) Nonce(nonce uint64) *Builder { + b.nonce = nonce + return b +} + +// DependsOn set depended tx. +func (b *Builder) DependsOn(txID *thor.Bytes32) *Builder { + if txID == nil { + b.dependsOn = nil + } else { + cpy := *txID + b.dependsOn = &cpy + } + return b +} + +// Features set features. +func (b *Builder) Features(feat Features) *Builder { + b.reserved.Features = feat + return b +} + +// BuildLegacy builds legacy tx object. +func (b *Builder) Build() (*Transaction, error) { + var tx *Transaction + switch b.txType { + case LegacyTxType: + tx = &Transaction{ + body: &LegacyTransaction{ + ChainTag: b.chainTag, + Clauses: b.clauses, + GasPriceCoef: b.gasPriceCoef, + Gas: b.gas, + BlockRef: b.blockRef, + Expiration: b.expiration, + Nonce: b.nonce, + DependsOn: b.dependsOn, + Reserved: b.reserved, + }, + } + case DynamicFeeTxType: + tx = &Transaction{ + body: &DynamicFeeTransaction{ + ChainTag: b.chainTag, + Clauses: b.clauses, + MaxFeePerGas: b.maxFeePerGas, + MaxPriorityFeePerGas: b.maxPriorityFeePerGas, + Gas: b.gas, + BlockRef: b.blockRef, + Expiration: b.expiration, + Nonce: b.nonce, + DependsOn: b.dependsOn, + Reserved: b.reserved, + }, + } + default: + return nil, ErrTxTypeNotSupported + } + return tx, nil +} diff --git a/tx/builder_dynamic_fee.go b/tx/builder_dynamic_fee.go deleted file mode 100644 index 703a89328..000000000 --- a/tx/builder_dynamic_fee.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2024 The VeChainThor developers - -// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying -// file LICENSE or - -package tx - -import ( - "encoding/binary" - "math/big" - - "github.com/vechain/thor/v2/thor" -) - -// DynFeeBuilder to make it easy to build transaction. -type DynFeeBuilder struct { - dynamicFeeTx DynamicFeeTransaction -} - -// ChainTag set chain tag. -func (b *DynFeeBuilder) ChainTag(tag byte) *DynFeeBuilder { - b.dynamicFeeTx.ChainTag = tag - return b -} - -// Clause add a clause. -func (b *DynFeeBuilder) Clause(c *Clause) *DynFeeBuilder { - b.dynamicFeeTx.Clauses = append(b.dynamicFeeTx.Clauses, c) - return b -} - -// Gas set gas provision for tx. -func (b *DynFeeBuilder) Gas(gas uint64) *DynFeeBuilder { - b.dynamicFeeTx.Gas = gas - return b -} - -// MaxFeePerGas set max fee per gas. -func (b *DynFeeBuilder) MaxFeePerGas(maxFeePerGas *big.Int) *DynFeeBuilder { - b.dynamicFeeTx.MaxFeePerGas = maxFeePerGas - return b -} - -// MaxPriorityFeePerGas set max priority fee per gas. -func (b *DynFeeBuilder) MaxPriorityFeePerGas(maxPriorityFeePerGas *big.Int) *DynFeeBuilder { - b.dynamicFeeTx.MaxPriorityFeePerGas = maxPriorityFeePerGas - return b -} - -// BlockRef set block reference. -func (b *DynFeeBuilder) BlockRef(br BlockRef) *DynFeeBuilder { - b.dynamicFeeTx.BlockRef = binary.BigEndian.Uint64(br[:]) - return b -} - -// Expiration set expiration. -func (b *DynFeeBuilder) Expiration(exp uint32) *DynFeeBuilder { - b.dynamicFeeTx.Expiration = exp - return b -} - -// Nonce set nonce. -func (b *DynFeeBuilder) Nonce(nonce uint64) *DynFeeBuilder { - b.dynamicFeeTx.Nonce = nonce - return b -} - -// DependsOn set depended tx. -func (b *DynFeeBuilder) DependsOn(txID *thor.Bytes32) *DynFeeBuilder { - if txID == nil { - b.dynamicFeeTx.DependsOn = nil - } else { - cpy := *txID - b.dynamicFeeTx.DependsOn = &cpy - } - return b -} - -// Features set features. -func (b *DynFeeBuilder) Features(feat Features) *DynFeeBuilder { - b.dynamicFeeTx.Reserved.Features = feat - return b -} - -// BuildDynamicFee builds dynamic fee tx object. -func (b *DynFeeBuilder) Build() *Transaction { - tx := Transaction{body: &b.dynamicFeeTx} - return &tx -} diff --git a/tx/builder_dynamic_fee_test.go b/tx/builder_dynamic_fee_test.go deleted file mode 100644 index cdec978b0..000000000 --- a/tx/builder_dynamic_fee_test.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2024 The VeChainThor developers - -// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying -// file LICENSE or - -package tx - -import ( - "encoding/binary" - "math/big" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/vechain/thor/v2/thor" -) - -func TestDynFeeBuilder_ChainTag(t *testing.T) { - builder := &DynFeeBuilder{} - builder.ChainTag(0x4a) - assert.Equal(t, byte(0x4a), builder.dynamicFeeTx.ChainTag) -} - -func TestDynFeeBuilder_Clause(t *testing.T) { - builder := &DynFeeBuilder{} - addr := thor.BytesToAddress([]byte("to")) - clause := NewClause(&addr) - builder.Clause(clause) - assert.Equal(t, 1, len(builder.dynamicFeeTx.Clauses)) - assert.Equal(t, clause, builder.dynamicFeeTx.Clauses[0]) -} - -func TestDynFeeBuilder_Gas(t *testing.T) { - builder := &DynFeeBuilder{} - builder.Gas(21000) - assert.Equal(t, uint64(21000), builder.dynamicFeeTx.Gas) -} - -func TestDynFeeBuilder_MaxFeePerGas(t *testing.T) { - builder := &DynFeeBuilder{} - maxFee := big.NewInt(1000000000) - builder.MaxFeePerGas(maxFee) - assert.Equal(t, maxFee, builder.dynamicFeeTx.MaxFeePerGas) -} - -func TestDynFeeBuilder_MaxPriorityFeePerGas(t *testing.T) { - builder := &DynFeeBuilder{} - maxPriorityFee := big.NewInt(2000000000) - builder.MaxPriorityFeePerGas(maxPriorityFee) - assert.Equal(t, maxPriorityFee, builder.dynamicFeeTx.MaxPriorityFeePerGas) -} - -func TestDynFeeBuilder_BlockRef(t *testing.T) { - builder := &DynFeeBuilder{} - blockRef := BlockRef{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08} - builder.BlockRef(blockRef) - assert.Equal(t, binary.BigEndian.Uint64(blockRef[:]), builder.dynamicFeeTx.BlockRef) -} - -func TestDynFeeBuilder_Expiration(t *testing.T) { - builder := &DynFeeBuilder{} - builder.Expiration(720) - assert.Equal(t, uint32(720), builder.dynamicFeeTx.Expiration) -} - -func TestDynFeeBuilder_Nonce(t *testing.T) { - builder := &DynFeeBuilder{} - builder.Nonce(12345) - assert.Equal(t, uint64(12345), builder.dynamicFeeTx.Nonce) -} - -func TestDynFeeBuilder_DependsOn(t *testing.T) { - builder := &DynFeeBuilder{} - txID := thor.Bytes32{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20} - builder.DependsOn(&txID) - assert.Equal(t, &txID, builder.dynamicFeeTx.DependsOn) - builder.DependsOn(nil) - assert.Nil(t, builder.dynamicFeeTx.DependsOn) -} - -func TestDynFeeBuilder_Features(t *testing.T) { - builder := &DynFeeBuilder{} - features := Features(0x01) - builder.Features(features) - assert.Equal(t, features, builder.dynamicFeeTx.Reserved.Features) -} - -func TestDynFeeBuilder_Build(t *testing.T) { - builder := &DynFeeBuilder{} - tx := builder.Build() - assert.NotNil(t, tx) - assert.Equal(t, &builder.dynamicFeeTx, tx.body) -} diff --git a/tx/builder_legacy.go b/tx/builder_legacy.go deleted file mode 100644 index ebcdde955..000000000 --- a/tx/builder_legacy.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2024 The VeChainThor developers - -// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying -// file LICENSE or - -package tx - -import ( - "encoding/binary" - - "github.com/vechain/thor/v2/thor" -) - -// LegacyBuilder to make it easy to build transaction. -type LegacyBuilder struct { - legacyTx LegacyTransaction -} - -// ChainTag set chain tag. -func (b *LegacyBuilder) ChainTag(tag byte) *LegacyBuilder { - b.legacyTx.ChainTag = tag - return b -} - -// Clause add a clause. -func (b *LegacyBuilder) Clause(c *Clause) *LegacyBuilder { - b.legacyTx.Clauses = append(b.legacyTx.Clauses, c) - return b -} - -// GasPriceCoef set gas price coef. -func (b *LegacyBuilder) GasPriceCoef(coef uint8) *LegacyBuilder { - b.legacyTx.GasPriceCoef = coef - return b -} - -// Gas set gas provision for tx. -func (b *LegacyBuilder) Gas(gas uint64) *LegacyBuilder { - b.legacyTx.Gas = gas - return b -} - -// BlockRef set block reference. -func (b *LegacyBuilder) BlockRef(br BlockRef) *LegacyBuilder { - b.legacyTx.BlockRef = binary.BigEndian.Uint64(br[:]) - return b -} - -// Expiration set expiration. -func (b *LegacyBuilder) Expiration(exp uint32) *LegacyBuilder { - b.legacyTx.Expiration = exp - return b -} - -// Nonce set nonce. -func (b *LegacyBuilder) Nonce(nonce uint64) *LegacyBuilder { - b.legacyTx.Nonce = nonce - return b -} - -// DependsOn set depended tx. -func (b *LegacyBuilder) DependsOn(txID *thor.Bytes32) *LegacyBuilder { - if txID == nil { - b.legacyTx.DependsOn = nil - } else { - cpy := *txID - b.legacyTx.DependsOn = &cpy - } - return b -} - -// Features set features. -func (b *LegacyBuilder) Features(feat Features) *LegacyBuilder { - b.legacyTx.Reserved.Features = feat - return b -} - -// BuildLegacy builds legacy tx object. -func (b *LegacyBuilder) Build() *Transaction { - tx := Transaction{body: &b.legacyTx} - return &tx -} diff --git a/tx/builder_legacy_test.go b/tx/builder_legacy_test.go deleted file mode 100644 index 2ba47624c..000000000 --- a/tx/builder_legacy_test.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2024 The VeChainThor developers - -// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying -// file LICENSE or - -package tx - -import ( - "encoding/binary" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/vechain/thor/v2/thor" -) - -func TestLegacyBuilder_ChainTag(t *testing.T) { - builder := &LegacyBuilder{} - tag := byte(0x4a) - builder.ChainTag(tag) - - assert.Equal(t, tag, builder.Build().ChainTag()) -} - -func TestLegacyBuilder_Clause(t *testing.T) { - builder := &LegacyBuilder{} - addr := thor.BytesToAddress([]byte("to")) - clause := NewClause(&addr) - builder.Clause(clause) - - assert.Equal(t, 1, len(builder.legacyTx.Clauses)) - assert.Equal(t, clause, builder.legacyTx.Clauses[0]) -} - -func TestLegacyBuilder_GasPriceCoef(t *testing.T) { - builder := &LegacyBuilder{} - coef := uint8(10) - builder.GasPriceCoef(coef) - - assert.Equal(t, coef, builder.Build().GasPriceCoef()) -} - -func TestLegacyBuilder_Gas(t *testing.T) { - builder := &LegacyBuilder{} - gas := uint64(21000) - builder.Gas(gas) - - assert.Equal(t, gas, builder.Build().Gas()) -} - -func TestLegacyBuilder_BlockRef(t *testing.T) { - builder := &LegacyBuilder{} - blockRef := BlockRef{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08} - builder.BlockRef(blockRef) - - expected := binary.BigEndian.Uint32(blockRef[:]) - assert.Equal(t, expected, builder.Build().BlockRef().Number()) -} - -func TestLegacyBuilder_Expiration(t *testing.T) { - builder := &LegacyBuilder{} - expiration := uint32(100) - builder.Expiration(expiration) - - assert.Equal(t, expiration, builder.Build().Expiration()) -} - -func TestLegacyBuilder_Nonce(t *testing.T) { - builder := &LegacyBuilder{} - nonce := uint64(12345) - builder.Nonce(nonce) - - assert.Equal(t, nonce, builder.Build().Nonce()) -} - -func TestLegacyBuilder_DependsOn(t *testing.T) { - builder := &LegacyBuilder{} - txID := thor.Bytes32{0x01, 0x02, 0x03, 0x04} - builder.DependsOn(&txID) - - assert.Equal(t, txID, *builder.Build().DependsOn()) -} - -func TestLegacyBuilder_Features(t *testing.T) { - builder := &LegacyBuilder{} - features := Features(0x01) - builder.Features(features) - - assert.Equal(t, features, builder.Build().Features()) -} diff --git a/tx/builder_test.go b/tx/builder_test.go new file mode 100644 index 000000000..fdd669e3c --- /dev/null +++ b/tx/builder_test.go @@ -0,0 +1,141 @@ +// Copyright (c) 2024 The VeChainThor developers + +// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying +// file LICENSE or + +package tx + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/vechain/thor/v2/thor" +) + +func TestNewTxBuilder(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + assert.NotNil(t, builder) + assert.Equal(t, LegacyTxType, builder.txType) +} + +func TestBuilder_ChainTag(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + builder.ChainTag(0x4a) + assert.Equal(t, byte(0x4a), builder.chainTag) +} + +func TestBuilder_Clause(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + addr := thor.BytesToAddress([]byte("to")) + clause := NewClause(&addr) + builder.Clause(clause) + assert.Equal(t, 1, len(builder.clauses)) + assert.Equal(t, clause, builder.clauses[0]) +} + +func TestBuilder_GasPriceCoef(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + builder.GasPriceCoef(10) + assert.Equal(t, uint8(10), builder.gasPriceCoef) +} + +func TestBuilder_MaxFeePerGas(t *testing.T) { + builder := NewTxBuilder(DynamicFeeTxType) + maxFee := big.NewInt(1000000000) + builder.MaxFeePerGas(maxFee) + assert.Equal(t, maxFee, builder.maxFeePerGas) +} + +func TestBuilder_MaxPriorityFeePerGas(t *testing.T) { + builder := NewTxBuilder(DynamicFeeTxType) + maxPriorityFee := big.NewInt(2000000000) + builder.MaxPriorityFeePerGas(maxPriorityFee) + assert.Equal(t, maxPriorityFee, builder.maxPriorityFeePerGas) +} + +func TestBuilder_Gas(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + builder.Gas(21000) + assert.Equal(t, uint64(21000), builder.gas) +} + +func TestBuilder_BlockRef(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + blockRef := BlockRef{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08} + builder.BlockRef(blockRef) + assert.Equal(t, uint64(0x0102030405060708), builder.blockRef) +} + +func TestBuilder_Expiration(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + builder.Expiration(100) + assert.Equal(t, uint32(100), builder.expiration) +} + +func TestBuilder_Nonce(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + builder.Nonce(12345) + assert.Equal(t, uint64(12345), builder.nonce) +} + +func TestBuilder_DependsOn(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + txID := thor.Bytes32{0x01, 0x02, 0x03, 0x04} + builder.DependsOn(&txID) + assert.Equal(t, &txID, builder.dependsOn) + builder.DependsOn(nil) + assert.Nil(t, builder.dependsOn) +} + +func TestBuilder_Features(t *testing.T) { + builder := NewTxBuilder(LegacyTxType) + features := Features(0x01) + builder.Features(features) + assert.Equal(t, features, builder.reserved.Features) +} + +func TestBuilder_Build_Legacy(t *testing.T) { + builder := NewTxBuilder(LegacyTxType). + ChainTag(0x4a). + Clause(&Clause{}). + GasPriceCoef(10). + Gas(21000). + BlockRef(BlockRef{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}). + Expiration(100). + Nonce(12345). + DependsOn(&thor.Bytes32{0x01, 0x02, 0x03, 0x04}). + Features(0x01) + + tx, err := builder.Build() + assert.NoError(t, err) + assert.NotNil(t, tx) + assert.IsType(t, &LegacyTransaction{}, tx.body) +} + +func TestBuilder_Build_DynamicFee(t *testing.T) { + builder := NewTxBuilder(DynamicFeeTxType). + ChainTag(0x4a). + Clause(&Clause{}). + MaxFeePerGas(big.NewInt(1000000000)). + MaxPriorityFeePerGas(big.NewInt(2000000000)). + Gas(21000). + BlockRef(BlockRef{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}). + Expiration(100). + Nonce(12345). + DependsOn(&thor.Bytes32{0x01, 0x02, 0x03, 0x04}). + Features(0x01) + + tx, err := builder.Build() + assert.NoError(t, err) + assert.NotNil(t, tx) + assert.IsType(t, &DynamicFeeTransaction{}, tx.body) +} + +func TestBuilder_Build_InvalidType(t *testing.T) { + builder := NewTxBuilder(0xff) + tx, err := builder.Build() + assert.Error(t, err) + assert.Nil(t, tx) + assert.Equal(t, ErrTxTypeNotSupported, err) +} diff --git a/tx/signer_test.go b/tx/signer_test.go index 452f6039a..6b3492ea8 100644 --- a/tx/signer_test.go +++ b/tx/signer_test.go @@ -19,14 +19,12 @@ func TestSign(t *testing.T) { pk, err := crypto.GenerateKey() assert.NoError(t, err) - txs := []*Transaction{ - new(LegacyBuilder).Build(), - new(DynFeeBuilder).Build(), - } + txTypes := []int{LegacyTxType, DynamicFeeTxType} - for _, tx := range txs { + for _, txType := range txTypes { + trx, _ := NewTxBuilder(txType).Build() // Sign the transaction - signedTx, err := Sign(tx, pk) + signedTx, err := Sign(trx, pk) assert.NoError(t, err) // Verify the transaction was signed @@ -52,24 +50,22 @@ func TestSignDelegated(t *testing.T) { originPK, err := crypto.GenerateKey() assert.NoError(t, err) - txs := []*Transaction{ - new(LegacyBuilder).Build(), - new(DynFeeBuilder).Build(), - } + txTypes := []int{LegacyTxType, DynamicFeeTxType} - for _, tx := range txs { + for _, txType := range txTypes { // Feature not enabled - signedTx, err := SignDelegated(tx, originPK, delegatorPK) + trx, _ := NewTxBuilder(txType).Build() + signedTx, err := SignDelegated(trx, originPK, delegatorPK) assert.ErrorContains(t, err, "transaction delegated feature is not enabled") assert.Nil(t, signedTx) // enable the feature var features Features features.SetDelegated(true) - tx = new(LegacyBuilder).Features(features).Build() + trx, _ = NewTxBuilder(txType).Features(features).Build() // Sign the transaction as a delegator - signedTx, err = SignDelegated(tx, originPK, delegatorPK) + signedTx, err = SignDelegated(trx, originPK, delegatorPK) assert.NoError(t, err) assert.NotNil(t, signedTx) diff --git a/tx/transaction.go b/tx/transaction.go index c2b0a8773..d684bde3b 100644 --- a/tx/transaction.go +++ b/tx/transaction.go @@ -30,8 +30,8 @@ var ( // Starting from the max value allowed to avoid ambiguity with Ethereum tx type codes. const ( - LegacyTxType = 0x7f - DynamicFeeTxType = 0x7e + LegacyTxType = 0x00 + DynamicFeeTxType = 0x51 ) // Transaction is an immutable tx type. diff --git a/tx/transaction_test.go b/tx/transaction_test.go index b40422750..36b8e94b1 100644 --- a/tx/transaction_test.go +++ b/tx/transaction_test.go @@ -17,31 +17,17 @@ import ( "github.com/vechain/thor/v2/tx" ) -func GetMockLegacyTx() tx.Transaction { +func GetMockTx(txType int) tx.Transaction { to, _ := thor.ParseAddress("0x7567d83b7b8d80addcb281a71d54fc7b3364ffed") - trx := new(tx.LegacyBuilder).ChainTag(1). + trx, _ := tx.NewTxBuilder(txType).ChainTag(1). BlockRef(tx.BlockRef{0, 0, 0, 0, 0xaa, 0xbb, 0xcc, 0xdd}). Expiration(32). Clause(tx.NewClause(&to).WithValue(big.NewInt(10000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})). Clause(tx.NewClause(&to).WithValue(big.NewInt(20000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})). GasPriceCoef(128). - Gas(21000). - DependsOn(nil). - Nonce(12345678).Build() - - return *trx -} - -func getMockDynFeeTx() tx.Transaction { - to, _ := thor.ParseAddress("0x7567d83b7b8d80addcb281a71d54fc7b3364ffed") - trx := new(tx.DynFeeBuilder).ChainTag(1). - BlockRef(tx.BlockRef{0, 0, 0, 0, 0xaa, 0xbb, 0xcc, 0xdd}). - Expiration(32). - Clause(tx.NewClause(&to).WithValue(big.NewInt(10000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})). - Clause(tx.NewClause(&to).WithValue(big.NewInt(20000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})). - Gas(21000). MaxFeePerGas(big.NewInt(10000000)). MaxPriorityFeePerGas(big.NewInt(20000)). + Gas(21000). DependsOn(nil). Nonce(12345678).Build() @@ -49,60 +35,60 @@ func getMockDynFeeTx() tx.Transaction { } func TestIsExpired(t *testing.T) { - tx := GetMockLegacyTx() + tx := GetMockTx(tx.LegacyTxType) res := tx.IsExpired(10) assert.Equal(t, res, false) } func TestDependsOn(t *testing.T) { - tx := GetMockLegacyTx() + tx := GetMockTx(tx.LegacyTxType) res := tx.DependsOn() var expected *thor.Bytes32 assert.Equal(t, expected, res) } func TestTestFeatures(t *testing.T) { - txx := GetMockLegacyTx() - supportedFeatures := tx.Features(1) - res := txx.TestFeatures(supportedFeatures) + tx := GetMockTx(tx.LegacyTxType) + supportedFeatures := tx.Features() + res := tx.TestFeatures(supportedFeatures) assert.Equal(t, res, nil) } func TestToString(t *testing.T) { // Legacy transaction - tx := GetMockLegacyTx() // Ensure this mock transaction has all the necessary fields populated + trx := GetMockTx(tx.LegacyTxType) // Ensure this mock transaction has all the necessary fields populated // Construct the expected string representation of the transaction // This should match the format used in the String() method of the Transaction struct // and should reflect the actual state of the mock transaction expectedString := "\n\tTx(0x0000000000000000000000000000000000000000000000000000000000000000, 87 B)\n\tOrigin: N/A\n\tClauses: [\n\t\t(To:\t0x7567d83b7b8d80addcb281a71d54fc7b3364ffed\n\t\t Value:\t10000\n\t\t Data:\t0x000000606060) \n\t\t(To:\t0x7567d83b7b8d80addcb281a71d54fc7b3364ffed\n\t\t Value:\t20000\n\t\t Data:\t0x000000606060)]\n\tGas: 21000\n\tChainTag: 1\n\tBlockRef: 0-aabbccdd\n\tExpiration: 32\n\tDependsOn: nil\n\tNonce: 12345678\n\tUnprovedWork: 0\n\tDelegator: N/A\n\tSignature: 0x\n\n\t\tGasPriceCoef: 128\n\t\t" - res := tx.String() + res := trx.String() // Use assert.Equal to compare the actual result with the expected string assert.Equal(t, expectedString, res) // Dynamic fee transaction - tx = getMockDynFeeTx() + trx = GetMockTx(tx.DynamicFeeTxType) expectedString = "\n\tTx(0x0000000000000000000000000000000000000000000000000000000000000000, 95 B)\n\tOrigin: N/A\n\tClauses: [\n\t\t(To:\t0x7567d83b7b8d80addcb281a71d54fc7b3364ffed\n\t\t Value:\t10000\n\t\t Data:\t0x000000606060) \n\t\t(To:\t0x7567d83b7b8d80addcb281a71d54fc7b3364ffed\n\t\t Value:\t20000\n\t\t Data:\t0x000000606060)]\n\tGas: 21000\n\tChainTag: 1\n\tBlockRef: 0-aabbccdd\n\tExpiration: 32\n\tDependsOn: nil\n\tNonce: 12345678\n\tUnprovedWork: 0\n\tDelegator: N/A\n\tSignature: 0x\n\n\t\tMaxFeePerGas: 10000000\n\t\tMaxPriorityFeePerGas: 20000\n\t\t" - res = tx.String() + res = trx.String() assert.Equal(t, expectedString, res) } func TestTxSize(t *testing.T) { - tx := GetMockLegacyTx() + trx := GetMockTx(tx.LegacyTxType) - size := tx.Size() + size := trx.Size() assert.Equal(t, size, thor.StorageSize(87)) - tx = getMockDynFeeTx() - size = tx.Size() + trx = GetMockTx(tx.DynamicFeeTxType) + size = trx.Size() assert.Equal(t, size, thor.StorageSize(95)) } func TestProvedWork(t *testing.T) { // Mock the transaction - tx := GetMockLegacyTx() + trx := GetMockTx(tx.LegacyTxType) // Define a head block number headBlockNum := uint32(20) @@ -113,7 +99,7 @@ func TestProvedWork(t *testing.T) { } // Call ProvedWork - provedWork, err := tx.ProvedWork(headBlockNum, getBlockID) + provedWork, err := trx.ProvedWork(headBlockNum, getBlockID) // Check for errors assert.NoError(t, err) @@ -123,20 +109,20 @@ func TestProvedWork(t *testing.T) { } func TestChainTag(t *testing.T) { - tx := GetMockLegacyTx() + tx := GetMockTx(tx.LegacyTxType) res := tx.ChainTag() assert.Equal(t, res, uint8(0x1)) } func TestNonce(t *testing.T) { - tx := GetMockLegacyTx() + tx := GetMockTx(tx.LegacyTxType) res := tx.Nonce() assert.Equal(t, res, uint64(0xbc614e)) } func TestOverallGasPrice(t *testing.T) { // Mock or create a Transaction with necessary fields initialized - tx := GetMockLegacyTx() + tx := GetMockTx(tx.LegacyTxType) // Define test cases testCases := []struct { @@ -175,7 +161,7 @@ func TestOverallGasPrice(t *testing.T) { func TestEvaluateWork(t *testing.T) { origin := thor.BytesToAddress([]byte("origin")) - tx := GetMockLegacyTx() + tx := GetMockTx(tx.LegacyTxType) // Returns a function evaluate := tx.EvaluateWork(origin) @@ -192,7 +178,7 @@ func TestEvaluateWork(t *testing.T) { func TestLegacyTx(t *testing.T) { to, _ := thor.ParseAddress("0x7567d83b7b8d80addcb281a71d54fc7b3364ffed") - trx := new(tx.LegacyBuilder).ChainTag(1). + trx, _ := tx.NewTxBuilder(tx.LegacyTxType).ChainTag(1). BlockRef(tx.BlockRef{0, 0, 0, 0, 0xaa, 0xbb, 0xcc, 0xdd}). Expiration(32). Clause(tx.NewClause(&to).WithValue(big.NewInt(10000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})). @@ -205,7 +191,7 @@ func TestLegacyTx(t *testing.T) { assert.Equal(t, "0x2a1c25ce0d66f45276a5f308b99bf410e2fc7d5b6ea37a49f2ab9f1da9446478", trx.SigningHash().String()) assert.Equal(t, thor.Bytes32{}, trx.ID()) - assert.Equal(t, uint64(21000), func() uint64 { g, _ := new(tx.LegacyBuilder).Build().IntrinsicGas(); return g }()) + assert.Equal(t, uint64(21000), func() uint64 { t, _ := tx.NewTxBuilder(tx.LegacyTxType).Build(); g, _ := t.IntrinsicGas(); return g }()) assert.Equal(t, uint64(37432), func() uint64 { g, _ := trx.IntrinsicGas(); return g }()) assert.Equal(t, big.NewInt(150), trx.GasPrice(big.NewInt(100))) @@ -237,7 +223,7 @@ func TestDelegatedTx(t *testing.T) { var feat tx.Features feat.SetDelegated(true) - trx := new(tx.LegacyBuilder).ChainTag(0xa4). + trx, _ := tx.NewTxBuilder(tx.LegacyTxType).ChainTag(0xa4). BlockRef(tx.BlockRef{0, 0, 0, 0, 0xaa, 0xbb, 0xcc, 0xdd}). Expiration(32). Clause(tx.NewClause(&to).WithValue(big.NewInt(10000)).WithData([]byte{0, 0, 0, 0x60, 0x60, 0x60})). @@ -302,10 +288,10 @@ func TestIntrinsicGas(t *testing.T) { } func BenchmarkTxMining(b *testing.B) { - tx := new(tx.LegacyBuilder).Build() + trx, _ := tx.NewTxBuilder(tx.LegacyTxType).Build() signer := thor.BytesToAddress([]byte("acc1")) maxWork := &big.Int{} - eval := tx.EvaluateWork(signer) + eval := trx.EvaluateWork(signer) for i := 0; i < b.N; i++ { work := eval(uint64(i)) if work.Cmp(maxWork) > 0 { diff --git a/tx/transactions_test.go b/tx/transactions_test.go index ec6005e05..728a4bdf0 100644 --- a/tx/transactions_test.go +++ b/tx/transactions_test.go @@ -16,7 +16,7 @@ import ( func MockTransactions(n int) tx.Transactions { txs := make(tx.Transactions, n) for i := range txs { - mockTx := GetMockLegacyTx() + mockTx := GetMockTx(tx.LegacyTxType) txs[i] = &mockTx } return txs diff --git a/txpool/tx_object_test.go b/txpool/tx_object_test.go index 512d6fb64..08c0de2a7 100644 --- a/txpool/tx_object_test.go +++ b/txpool/tx_object_test.go @@ -29,15 +29,7 @@ func newChainRepo(db *muxdb.MuxDB) *chain.Repository { } func newTx(txType int, chainTag byte, clauses []*tx.Clause, gas uint64, blockRef tx.BlockRef, expiration uint32, dependsOn *thor.Bytes32, features tx.Features, from genesis.DevAccount) *tx.Transaction { - var trx *tx.Transaction - switch txType { - case tx.LegacyTxType: - trx = legacyTxBuilder(chainTag, clauses, gas, blockRef, expiration, dependsOn, features).Build() - case tx.DynamicFeeTxType: - trx = dynFeeTxBuilder(chainTag, clauses, gas, blockRef, expiration, dependsOn, features).Build() - default: - panic(tx.ErrTxTypeNotSupported) - } + trx, _ := txBuilder(txType, chainTag, clauses, gas, blockRef, expiration, dependsOn, features).Build() return tx.MustSign(trx, from.PrivateKey) } @@ -45,15 +37,7 @@ func newDelegatedTx(txType int, chainTag byte, clauses []*tx.Clause, gas uint64, var features tx.Features features.SetDelegated(true) - var trx *tx.Transaction - switch txType { - case tx.LegacyTxType: - trx = legacyTxBuilder(chainTag, clauses, gas, blockRef, expiration, dependsOn, features).Build() - case tx.DynamicFeeTxType: - trx = dynFeeTxBuilder(chainTag, clauses, gas, blockRef, expiration, dependsOn, features).Build() - default: - panic(tx.ErrTxTypeNotSupported) - } + trx, _ := txBuilder(txType, chainTag, clauses, gas, blockRef, expiration, dependsOn, features).Build() trx = tx.MustSignDelegated( trx, @@ -64,22 +48,8 @@ func newDelegatedTx(txType int, chainTag byte, clauses []*tx.Clause, gas uint64, return trx } -func legacyTxBuilder(chainTag byte, clauses []*tx.Clause, gas uint64, blockRef tx.BlockRef, expiration uint32, dependsOn *thor.Bytes32, features tx.Features) *tx.LegacyBuilder { - builder := new(tx.LegacyBuilder).ChainTag(chainTag) - for _, c := range clauses { - builder.Clause(c) - } - - return builder.BlockRef(blockRef). - Expiration(expiration). - Nonce(rand.Uint64()). //#nosec G404 - DependsOn(dependsOn). - Features(features). - Gas(gas) -} - -func dynFeeTxBuilder(chainTag byte, clauses []*tx.Clause, gas uint64, blockRef tx.BlockRef, expiration uint32, dependsOn *thor.Bytes32, features tx.Features) *tx.DynFeeBuilder { - builder := new(tx.DynFeeBuilder).ChainTag(chainTag) +func txBuilder(txType int, chainTag byte, clauses []*tx.Clause, gas uint64, blockRef tx.BlockRef, expiration uint32, dependsOn *thor.Bytes32, features tx.Features) *tx.Builder { + builder := tx.NewTxBuilder(txType).ChainTag(chainTag) for _, c := range clauses { builder.Clause(c) }