From fb481d25728da3cf5e0a3eaedc5dad1879aa86f2 Mon Sep 17 00:00:00 2001 From: otherview Date: Tue, 24 Sep 2024 14:08:55 +0100 Subject: [PATCH] changing the builder to a tx.signer --- api/accounts/accounts_test.go | 13 ++--- api/blocks/blocks_test.go | 24 ++++---- api/debug/debug_test.go | 13 ++--- api/subscriptions/block_reader_test.go | 7 +-- api/subscriptions/pending_tx_test.go | 32 +++++------ api/subscriptions/types_test.go | 27 ++++----- api/transactions/transactions_test.go | 35 ++++++------ cmd/thor/node/tx_stash_test.go | 7 ++- cmd/thor/solo/solo.go | 5 +- consensus/consensus_test.go | 7 +-- packer/packer_test.go | 7 ++- runtime/resolved_tx_test.go | 4 +- tx/builder.go | 36 ------------ tx/signer.go | 79 ++++++++++++++++++++++++++ txpool/tx_object_test.go | 19 ++++--- 15 files changed, 184 insertions(+), 131 deletions(-) create mode 100644 tx/signer.go diff --git a/api/accounts/accounts_test.go b/api/accounts/accounts_test.go index 76c6e5240..70590c318 100644 --- a/api/accounts/accounts_test.go +++ b/api/accounts/accounts_test.go @@ -21,7 +21,6 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/gorilla/mux" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ABI "github.com/vechain/thor/v2/abi" "github.com/vechain/thor/v2/api/accounts" "github.com/vechain/thor/v2/block" @@ -262,7 +261,7 @@ func initAccountServer(t *testing.T) { repo, _ := chain.NewRepository(db, b) claTransfer := tx.NewClause(&addr).WithValue(value) claDeploy := tx.NewClause(nil).WithData(bytecode) - transaction := buildTxWithClauses(t, repo.ChainTag(), claTransfer, claDeploy) + transaction := buildTxWithClauses(repo.ChainTag(), claTransfer, claDeploy) contractAddr = thor.CreateContractAddress(transaction.ID(), 1, 0) packTx(repo, stater, transaction, t) @@ -274,7 +273,7 @@ func initAccountServer(t *testing.T) { t.Fatal(err) } claCall := tx.NewClause(&contractAddr).WithData(input) - transactionCall := buildTxWithClauses(t, repo.ChainTag(), claCall) + transactionCall := buildTxWithClauses(repo.ChainTag(), claCall) packTx(repo, stater, transactionCall, t) router := mux.NewRouter() @@ -284,7 +283,7 @@ func initAccountServer(t *testing.T) { ts = httptest.NewServer(router) } -func buildTxWithClauses(t *testing.T, chaiTag byte, clauses ...*tx.Clause) *tx.Transaction { +func buildTxWithClauses(chaiTag byte, clauses ...*tx.Clause) *tx.Transaction { builder := new(tx.Builder). ChainTag(chaiTag). Expiration(10). @@ -293,9 +292,9 @@ func buildTxWithClauses(t *testing.T, chaiTag byte, clauses ...*tx.Clause) *tx.T builder.Clause(c) } - transaction, err := builder.BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) - return transaction + trx := builder.Build() + + return tx.MustSignTx(trx, genesis.DevAccounts()[0].PrivateKey) } func packTx(repo *chain.Repository, stater *state.Stater, transaction *tx.Transaction, t *testing.T) { diff --git a/api/blocks/blocks_test.go b/api/blocks/blocks_test.go index 63dec2d64..dbaf8f0b6 100644 --- a/api/blocks/blocks_test.go +++ b/api/blocks/blocks_test.go @@ -170,16 +170,18 @@ func initBlockServer(t *testing.T) { repo, _ := chain.NewRepository(db, b) addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - tx, err := new(tx.Builder). - ChainTag(repo.ChainTag()). - GasPriceCoef(1). - Expiration(10). - Gas(21000). - Nonce(1). - Clause(cla). - BlockRef(tx.NewBlockRef(0)). - BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) + trx := tx.MustSignTx( + new(tx.Builder). + ChainTag(repo.ChainTag()). + GasPriceCoef(1). + Expiration(10). + Gas(21000). + Nonce(1). + Clause(cla). + BlockRef(tx.NewBlockRef(0)). + Build(), + genesis.DevAccounts()[0].PrivateKey, + ) packer := packer.New(repo, stater, genesis.DevAccounts()[0].Address, &genesis.DevAccounts()[0].Address, thor.NoFork) sum, _ := repo.GetBlockSummary(b.Header().ID()) @@ -187,7 +189,7 @@ func initBlockServer(t *testing.T) { if err != nil { t.Fatal(err) } - err = flow.Adopt(tx) + err = flow.Adopt(trx) if err != nil { t.Fatal(err) } diff --git a/api/debug/debug_test.go b/api/debug/debug_test.go index 40cbd42b5..3b7365d2c 100644 --- a/api/debug/debug_test.go +++ b/api/debug/debug_test.go @@ -22,7 +22,6 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/gorilla/mux" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/vechain/thor/v2/block" "github.com/vechain/thor/v2/builtin" "github.com/vechain/thor/v2/chain" @@ -527,16 +526,16 @@ 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, err := new(tx.Builder). + noClausesTx := new(tx.Builder). ChainTag(repo.ChainTag()). Expiration(10). Gas(21000). - BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) + Build() + noClausesTx = tx.MustSignTx(noClausesTx, genesis.DevAccounts()[0].PrivateKey) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) cla2 := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - transaction, err = new(tx.Builder). + transaction = new(tx.Builder). ChainTag(repo.ChainTag()). GasPriceCoef(1). Expiration(10). @@ -545,8 +544,8 @@ func initDebugServer(t *testing.T) { Clause(cla). Clause(cla2). BlockRef(tx.NewBlockRef(0)). - BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) + Build() + transaction = tx.MustSignTx(transaction, genesis.DevAccounts()[0].PrivateKey) packer := packer.New(repo, stater, genesis.DevAccounts()[0].Address, &genesis.DevAccounts()[0].Address, thor.NoFork) sum, _ := repo.GetBlockSummary(b.Header().ID()) diff --git a/api/subscriptions/block_reader_test.go b/api/subscriptions/block_reader_test.go index 13feb9901..51bde8f97 100644 --- a/api/subscriptions/block_reader_test.go +++ b/api/subscriptions/block_reader_test.go @@ -11,7 +11,6 @@ import ( "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/vechain/thor/v2/block" "github.com/vechain/thor/v2/chain" "github.com/vechain/thor/v2/genesis" @@ -77,7 +76,7 @@ func initChain(t *testing.T) (*chain.Repository, []*block.Block, *txpool.TxPool) addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - tr, err := new(tx.Builder). + tr := new(tx.Builder). ChainTag(repo.ChainTag()). GasPriceCoef(1). Expiration(10). @@ -85,8 +84,8 @@ func initChain(t *testing.T) (*chain.Repository, []*block.Block, *txpool.TxPool) Nonce(1). Clause(cla). BlockRef(tx.NewBlockRef(0)). - BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) + Build() + tr = tx.MustSignTx(tr, genesis.DevAccounts()[0].PrivateKey) packer := packer.New(repo, stater, genesis.DevAccounts()[0].Address, &genesis.DevAccounts()[0].Address, thor.NoFork) sum, _ := repo.GetBlockSummary(b.Header().ID()) diff --git a/api/subscriptions/pending_tx_test.go b/api/subscriptions/pending_tx_test.go index 6eef399fc..aa8314fa7 100644 --- a/api/subscriptions/pending_tx_test.go +++ b/api/subscriptions/pending_tx_test.go @@ -11,7 +11,6 @@ import ( "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/vechain/thor/v2/block" "github.com/vechain/thor/v2/chain" "github.com/vechain/thor/v2/genesis" @@ -77,7 +76,7 @@ func TestPendingTx_DispatchLoop(t *testing.T) { p.Subscribe(txCh) // Add a new tx to the mempool - transaction := createTx(t, repo, 0) + transaction := createTx(repo, 0) txPool.AddLocal(transaction) // Start the dispatch loop @@ -95,7 +94,7 @@ func TestPendingTx_DispatchLoop(t *testing.T) { p.Unsubscribe(txCh) // Add another tx to the mempool - tx2 := createTx(t, repo, 1) + tx2 := createTx(repo, 1) txPool.AddLocal(tx2) // Assert that the channel did not receive the second transaction @@ -129,19 +128,20 @@ func addNewBlock(repo *chain.Repository, stater *state.Stater, b0 *block.Block, } } -func createTx(t *testing.T, repo *chain.Repository, addressNumber uint) *tx.Transaction { +func createTx(repo *chain.Repository, addressNumber uint) *tx.Transaction { addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - tx, err := new(tx.Builder). - ChainTag(repo.ChainTag()). - GasPriceCoef(1). - Expiration(10). - Gas(21000). - Nonce(1). - Clause(cla). - BlockRef(tx.NewBlockRef(0)). - BuildAndSign(genesis.DevAccounts()[addressNumber].PrivateKey) - require.NoError(t, err) - - return tx + + return tx.MustSignTx( + new(tx.Builder). + ChainTag(repo.ChainTag()). + GasPriceCoef(1). + Expiration(10). + Gas(21000). + Nonce(1). + Clause(cla). + BlockRef(tx.NewBlockRef(0)). + Build(), + genesis.DevAccounts()[addressNumber].PrivateKey, + ) } diff --git a/api/subscriptions/types_test.go b/api/subscriptions/types_test.go index 7cb498a28..8aee6b3b2 100644 --- a/api/subscriptions/types_test.go +++ b/api/subscriptions/types_test.go @@ -14,7 +14,6 @@ import ( "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/vechain/thor/v2/block" "github.com/vechain/thor/v2/chain" "github.com/vechain/thor/v2/genesis" @@ -96,15 +95,15 @@ func TestConvertTransfer(t *testing.T) { repo, _ := chain.NewRepository(db, b) // New tx - transaction, err := new(tx.Builder). + transaction := new(tx.Builder). ChainTag(repo.ChainTag()). GasPriceCoef(1). Expiration(10). Gas(21000). Nonce(1). BlockRef(tx.NewBlockRef(0)). - BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) + Build() + transaction = tx.MustSignTx(transaction, genesis.DevAccounts()[0].PrivateKey) // New block blk := new(block.Builder). @@ -183,15 +182,17 @@ func TestConvertEvent(t *testing.T) { repo, _ := chain.NewRepository(db, b) // New tx - transaction, err := new(tx.Builder). - ChainTag(repo.ChainTag()). - GasPriceCoef(1). - Expiration(10). - Gas(21000). - Nonce(1). - BlockRef(tx.NewBlockRef(0)). - BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) + transaction := tx.MustSignTx( + new(tx.Builder). + ChainTag(repo.ChainTag()). + GasPriceCoef(1). + Expiration(10). + Gas(21000). + Nonce(1). + BlockRef(tx.NewBlockRef(0)). + Build(), + genesis.DevAccounts()[0].PrivateKey, + ) // New block blk := new(block.Builder). diff --git a/api/transactions/transactions_test.go b/api/transactions/transactions_test.go index ca001531a..9ec885762 100644 --- a/api/transactions/transactions_test.go +++ b/api/transactions/transactions_test.go @@ -21,7 +21,6 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/gorilla/mux" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/vechain/thor/v2/api/transactions" "github.com/vechain/thor/v2/chain" "github.com/vechain/thor/v2/genesis" @@ -112,15 +111,17 @@ func sendTx(t *testing.T) { var expiration = uint32(10) var gas = uint64(21000) - tx, err := new(tx.Builder). - BlockRef(blockRef). - ChainTag(chainTag). - Expiration(expiration). - Gas(gas). - BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) - - rlpTx, err := rlp.EncodeToBytes(tx) + trx := tx.MustSignTx( + new(tx.Builder). + BlockRef(blockRef). + ChainTag(chainTag). + Expiration(expiration). + Gas(gas). + Build(), + genesis.DevAccounts()[0].PrivateKey, + ) + + rlpTx, err := rlp.EncodeToBytes(trx) if err != nil { t.Fatal(err) } @@ -130,7 +131,7 @@ func sendTx(t *testing.T) { if err = json.Unmarshal(res, &txObj); err != nil { t.Fatal(err) } - assert.Equal(t, tx.ID().String(), txObj["id"], "should be the same transaction id") + assert.Equal(t, trx.ID().String(), txObj["id"], "should be the same transaction id") } func getTxWithBadID(t *testing.T) { @@ -284,7 +285,7 @@ func initTransactionServer(t *testing.T) { repo, _ = chain.NewRepository(db, b) addr := thor.BytesToAddress([]byte("to")) cla := tx.NewClause(&addr).WithValue(big.NewInt(10000)) - transaction, err = new(tx.Builder). + transaction = new(tx.Builder). ChainTag(repo.ChainTag()). GasPriceCoef(1). Expiration(10). @@ -292,16 +293,16 @@ func initTransactionServer(t *testing.T) { Nonce(1). Clause(cla). BlockRef(tx.NewBlockRef(0)). - BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) + Build() + transaction = tx.MustSignTx(transaction, genesis.DevAccounts()[0].PrivateKey) - mempoolTx, err = new(tx.Builder). + mempoolTx = new(tx.Builder). ChainTag(repo.ChainTag()). Expiration(10). Gas(21000). Nonce(1). - BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - require.NoError(t, err) + Build() + mempoolTx = tx.MustSignTx(mempoolTx, genesis.DevAccounts()[0].PrivateKey) packer := packer.New(repo, stater, genesis.DevAccounts()[0].Address, &genesis.DevAccounts()[0].Address, thor.NoFork) sum, _ := repo.GetBlockSummary(b.Header().ID()) diff --git a/cmd/thor/node/tx_stash_test.go b/cmd/thor/node/tx_stash_test.go index 274ef7981..c236a9341 100644 --- a/cmd/thor/node/tx_stash_test.go +++ b/cmd/thor/node/tx_stash_test.go @@ -19,8 +19,11 @@ import ( ) func newTx() *tx.Transaction { - tx, _ := new(tx.Builder).Nonce(rand.Uint64()).BuildAndSign(genesis.DevAccounts()[0].PrivateKey) // nolint:gosec - return tx + return tx.MustSignTx( + new(tx.Builder). + Nonce(rand.Uint64()).Build(), // nolint:gosec, + genesis.DevAccounts()[0].PrivateKey, + ) } func TestTxStash(t *testing.T) { diff --git a/cmd/thor/solo/solo.go b/cmd/thor/solo/solo.go index c6ef10800..0d00cefc5 100644 --- a/cmd/thor/solo/solo.go +++ b/cmd/thor/solo/solo.go @@ -260,10 +260,11 @@ func (s *Solo) newTx(clauses []*tx.Clause, from genesis.DevAccount) (*tx.Transac builder.Clause(c) } - return builder.BlockRef(tx.NewBlockRef(0)). + trx := builder.BlockRef(tx.NewBlockRef(0)). Expiration(math.MaxUint32). Nonce(rand.Uint64()). // #nosec DependsOn(nil). Gas(1_000_000). - BuildAndSign(from.PrivateKey) + Build() + return tx.SignTx(trx, from.PrivateKey) } diff --git a/consensus/consensus_test.go b/consensus/consensus_test.go index 9d726bd74..73cead551 100644 --- a/consensus/consensus_test.go +++ b/consensus/consensus_test.go @@ -14,7 +14,6 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/vechain/thor/v2/block" "github.com/vechain/thor/v2/builtin" "github.com/vechain/thor/v2/chain" @@ -578,11 +577,11 @@ func TestValidateBlockBody(t *testing.T) { { "TxOriginBlocked", func(t *testing.T) { thor.MockBlocklist([]string{genesis.DevAccounts()[9].Address.String()}) - tx, err := txBuilder(tc.tag).BuildAndSign(genesis.DevAccounts()[9].PrivateKey) - require.NoError(t, err) + trx := txBuilder(tc.tag).Build() + trx = tx.MustSignTx(trx, genesis.DevAccounts()[9].PrivateKey) blk, err := tc.sign( - tc.builder(tc.original.Header()).Transaction(tx), + tc.builder(tc.original.Header()).Transaction(trx), ) if err != nil { t.Fatal(err) diff --git a/packer/packer_test.go b/packer/packer_test.go index d0f8ac333..c6829700d 100644 --- a/packer/packer_test.go +++ b/packer/packer_test.go @@ -50,13 +50,14 @@ func (ti *txIterator) Next() *tx.Transaction { data, _ := method.EncodeInput(a1.Address, big.NewInt(1)) - tx, _ := new(tx.Builder). + trx := new(tx.Builder). ChainTag(ti.chainTag). Clause(tx.NewClause(&builtin.Energy.Address).WithData(data)). - Gas(300000).GasPriceCoef(0).Nonce(nonce).Expiration(math.MaxUint32).BuildAndSign(a0.PrivateKey) + Gas(300000).GasPriceCoef(0).Nonce(nonce).Expiration(math.MaxUint32).Build() + trx = tx.MustSignTx(trx, a0.PrivateKey) nonce++ - return tx + return trx } func (ti *txIterator) OnProcessed(_ thor.Bytes32, _ error) { diff --git a/runtime/resolved_tx_test.go b/runtime/resolved_tx_test.go index 97c31d32c..c0c521354 100644 --- a/runtime/resolved_tx_test.go +++ b/runtime/resolved_tx_test.go @@ -185,6 +185,6 @@ func txBuilder(tag byte) *tx.Builder { } func txSign(builder *tx.Builder) *tx.Transaction { - transaction, _ := builder.BuildAndSign(genesis.DevAccounts()[0].PrivateKey) - return transaction + transaction := builder.Build() + return tx.MustSignTx(transaction, genesis.DevAccounts()[0].PrivateKey) } diff --git a/tx/builder.go b/tx/builder.go index b7e25df9c..64f98868f 100644 --- a/tx/builder.go +++ b/tx/builder.go @@ -6,11 +6,8 @@ package tx import ( - "crypto/ecdsa" "encoding/binary" - "fmt" - "github.com/ethereum/go-ethereum/crypto" "github.com/vechain/thor/v2/thor" ) @@ -83,36 +80,3 @@ func (b *Builder) Build() *Transaction { tx := Transaction{body: b.body} return &tx } - -// BuildAndSign builds tx object and signs it using the provided key. -func (b *Builder) BuildAndSign(privateKey *ecdsa.PrivateKey) (*Transaction, error) { - tx := b.Build() - sig, err := crypto.Sign(tx.SigningHash().Bytes(), privateKey) - if err != nil { - return nil, fmt.Errorf("unable to sign transaction: %w", err) - } - - return tx.WithSignature(sig), nil -} - -func (b *Builder) BuildAndSignWithDelegator(privateKey *ecdsa.PrivateKey, delegatorPK *ecdsa.PrivateKey) (*Transaction, error) { - tx := b.Build() - sig, err := crypto.Sign(tx.SigningHash().Bytes(), privateKey) - if err != nil { - return nil, fmt.Errorf("unable to sign transaction: %w", err) - } - - pub, err := crypto.SigToPub(tx.SigningHash().Bytes(), sig[:65]) - if err != nil { - return nil, fmt.Errorf("unable to recover address from signature: %w", err) - } - origin := thor.Address(crypto.PubkeyToAddress(*pub)) - - dSig, err := crypto.Sign(tx.DelegatorSigningHash(origin).Bytes(), delegatorPK) - if err != nil { - return nil, fmt.Errorf("unable to delegator sign transaction: %w", err) - } - sig = append(sig, dSig...) - - return tx.WithSignature(sig), nil -} diff --git a/tx/signer.go b/tx/signer.go new file mode 100644 index 000000000..913c0b21d --- /dev/null +++ b/tx/signer.go @@ -0,0 +1,79 @@ +package tx + +import ( + "crypto/ecdsa" + "fmt" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/vechain/thor/v2/thor" +) + +// SignFunction is a type alias for a function that signs a hash using a private key. +// It returns the signature and an error if any occurs. +type SignFunction func(hash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) + +// MustSignTx signs a transaction with the provided private key using the default signing function. +// It panics if the signing process fails. +func MustSignTx(tx *Transaction, pk *ecdsa.PrivateKey) *Transaction { + return MustCustomSignTx(crypto.Sign, tx, pk) +} + +// MustCustomSignTx signs a transaction using a custom signing function and private key. +// It panics if the signing process fails. +func MustCustomSignTx(sign SignFunction, tx *Transaction, pk *ecdsa.PrivateKey) *Transaction { + trx, err := CustomSignTx(sign, tx, pk) + if err != nil { + panic(err) + } + return trx +} + +// SignTx signs a transaction with the provided private key using the default signing function. +// It returns the signed transaction or an error if the signing fails. +func SignTx(tx *Transaction, pk *ecdsa.PrivateKey) (*Transaction, error) { + return CustomSignTx(crypto.Sign, tx, pk) +} + +// CustomSignTx signs a transaction using a custom signing function and private key. +// It returns the signed transaction or an error if the signing fails. +func CustomSignTx(sign SignFunction, tx *Transaction, pk *ecdsa.PrivateKey) (*Transaction, error) { + // Generate the signature for the transaction's signing hash. + sig, err := sign(tx.SigningHash().Bytes(), pk) + if err != nil { + return nil, fmt.Errorf("unable to sign transaction: %w", err) + } + + // Attach the signature to the transaction. + return tx.WithSignature(sig), nil +} + +// DelegatorSignTx signs a transaction as a delegator with the provided private key using the default signing function. +// It returns the signed transaction or an error if the signing fails. +func DelegatorSignTx(tx *Transaction, pk *ecdsa.PrivateKey) (*Transaction, error) { + return CustomDelegatorSignTx(crypto.Sign, tx, pk) +} + +// CustomDelegatorSignTx signs a transaction as a delegator using a custom signing function and private key. +// It returns the signed transaction or an error if the signing fails. +func CustomDelegatorSignTx(sign SignFunction, tx *Transaction, pk *ecdsa.PrivateKey) (*Transaction, error) { + // Extract the public key from the existing transaction signature. + pub, err := crypto.SigToPub(tx.SigningHash().Bytes(), tx.Signature()) + if err != nil { + return nil, fmt.Errorf("unable to extract public key from signature: %w", err) + } + + // Convert the public key to the corresponding address. + origin := thor.Address(crypto.PubkeyToAddress(*pub)) + + // Generate the delegator's signature using the delegator signing hash. + dSig, err := sign(tx.DelegatorSigningHash(origin).Bytes(), pk) + if err != nil { + return nil, fmt.Errorf("unable to delegator sign transaction: %w", err) + } + + // Append the delegator's signature to the existing transaction signature. + sig := append(tx.Signature(), dSig...) + + // Attach the combined signature to the transaction. + return tx.WithSignature(sig), nil +} diff --git a/txpool/tx_object_test.go b/txpool/tx_object_test.go index 9deca6edb..30fa58de3 100644 --- a/txpool/tx_object_test.go +++ b/txpool/tx_object_test.go @@ -34,15 +34,15 @@ func newTx(chainTag byte, clauses []*tx.Clause, gas uint64, blockRef tx.BlockRef builder.Clause(c) } - tx, _ := builder.BlockRef(blockRef). + return tx.MustSignTx(builder.BlockRef(blockRef). Expiration(expiration). Nonce(rand.Uint64()). // nolint:gosec DependsOn(dependsOn). Features(features). Gas(gas). - BuildAndSign(from.PrivateKey) - - return tx + Build(), + from.PrivateKey, + ) } func newDelegatedTx(chainTag byte, clauses []*tx.Clause, gas uint64, blockRef tx.BlockRef, expiration uint32, dependsOn *thor.Bytes32, from genesis.DevAccount, delegator genesis.DevAccount) *tx.Transaction { @@ -54,15 +54,20 @@ func newDelegatedTx(chainTag byte, clauses []*tx.Clause, gas uint64, blockRef tx var features tx.Features features.SetDelegated(true) - tx, _ := builder.BlockRef(blockRef). + trx := builder.BlockRef(blockRef). Expiration(expiration). Nonce(rand.Uint64()). // nolint:gosec DependsOn(dependsOn). Features(features). Gas(gas). - BuildAndSignWithDelegator(from.PrivateKey, delegator.PrivateKey) + Build() + + trx, _ = tx.DelegatorSignTx( + tx.MustSignTx(trx, from.PrivateKey), + delegator.PrivateKey, + ) - return tx + return trx } func SetupTest() (genesis.DevAccount, *chain.Repository, *block.Block, *state.State) {