From 6139430ed71fde0b00992063972d376632cfa7cc Mon Sep 17 00:00:00 2001 From: colinlyguo Date: Tue, 18 Feb 2025 02:05:44 +0800 Subject: [PATCH 1/2] client: add AuthList field in toCallArg --- core/state_processor_test.go | 3 +- core/txpool/legacypool/legacypool_test.go | 2 +- core/vm/errors.go | 5 +++ ethclient/ethclient.go | 3 ++ ethclient/gethclient/gethclient.go | 3 ++ interfaces.go | 3 ++ internal/ethapi/api_test.go | 49 +++++++++++++++++++++++ 7 files changed, 66 insertions(+), 2 deletions(-) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index a6ca2781f811..ffdf06381223 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -255,7 +255,8 @@ func TestStateProcessorErrors(t *testing.T) { }, want: "could not apply tx 0 [0xc18d10f4c809dbdfa1a074c3300de9bc4b7f16a20f0ec667f6f67312b71b956a]: EIP-7702 transaction with empty auth list (sender 0x71562b71999873DB5b286dF957af199Ec94617F7)", }, - // ErrSetCodeTxCreate cannot be tested: it is impossible to create a SetCode-tx with nil `to`. + // ErrSetCodeTxCreate cannot be tested here: it is impossible to create a SetCode-tx with nil `to`. + // The EstimateGas API tests test this case. } { block := GenerateBadBlock(gspec.ToBlock(), beacon.New(ethash.NewFaker()), tt.txs, gspec.Config, false) _, err := blockchain.InsertChain(types.Blocks{block}) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index da28e8a75bdc..470501c9ded1 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -2280,7 +2280,7 @@ func TestSetCodeTransactions(t *testing.T) { t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err) } if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyC)); err != nil { - t.Fatalf("%s: failed to add with pending delegatio: %v", name, err) + t.Fatalf("%s: failed to add with pending delegation: %v", name, err) } // Also check gapped transaction is rejected. if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, txpool.ErrAccountLimitExceeded) { diff --git a/core/vm/errors.go b/core/vm/errors.go index e33c9fcb853c..b4ffd15e452e 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -81,6 +81,11 @@ type ErrInvalidOpCode struct { func (e *ErrInvalidOpCode) Error() string { return fmt.Sprintf("invalid opcode: %s", e.opcode) } +// NewErrInvalidOpCode is only used in tests to generate an exact ErrInvalidOpCode error. +func NewErrInvalidOpCode(opcode OpCode) *ErrInvalidOpCode { + return &ErrInvalidOpCode{opcode: opcode} +} + // rpcError is the same interface as the one defined in rpc/errors.go // but we do not want to depend on rpc package here so we redefine it. // diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index f10626c01fb7..5362dbd4800c 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -694,6 +694,9 @@ func toCallArg(msg ethereum.CallMsg) interface{} { if msg.BlobHashes != nil { arg["blobVersionedHashes"] = msg.BlobHashes } + if msg.AuthList != nil { + arg["authorizationList"] = msg.AuthList + } return arg } diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go index 02b2598b37d2..e74f335a171e 100644 --- a/ethclient/gethclient/gethclient.go +++ b/ethclient/gethclient/gethclient.go @@ -251,6 +251,9 @@ func toCallArg(msg ethereum.CallMsg) interface{} { if msg.BlobHashes != nil { arg["blobVersionedHashes"] = msg.BlobHashes } + if msg.AuthList != nil { + arg["authorizationList"] = msg.AuthList + } return arg } diff --git a/interfaces.go b/interfaces.go index 53e2e3ae169d..e7ccb93c1538 100644 --- a/interfaces.go +++ b/interfaces.go @@ -156,6 +156,9 @@ type CallMsg struct { // For BlobTxType BlobGasFeeCap *big.Int BlobHashes []common.Hash + + // For SetCodeTxType + AuthList []types.SetCodeAuthorization } // A ContractCaller provides contract calls, essentially transactions that are executed by diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index f00022e3de4f..702b2b150f04 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -656,6 +656,11 @@ func TestEstimateGas(t *testing.T) { b.SetPoS() })) + setCodeAuthorization, _ := types.SignSetCode(accounts[0].key, types.SetCodeAuthorization{ + Address: accounts[0].addr, + Nonce: uint64(genBlocks + 1), + }) + var testSuite = []struct { blockNumber rpc.BlockNumber call TransactionArgs @@ -834,6 +839,50 @@ func TestEstimateGas(t *testing.T) { }, want: 21000, }, + // Should be able to estimate SetCodeTx. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: &accounts[1].addr, + Value: (*hexutil.Big)(big.NewInt(0)), + AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization}, + }, + want: 46000, + }, + // Should retrieve the code of 0xef0001 || accounts[0].addr and return an invalid opcode error. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: &accounts[0].addr, + Value: (*hexutil.Big)(big.NewInt(0)), + AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization}, + }, + expectErr: vm.NewErrInvalidOpCode(0xef), + }, + // SetCodeTx with empty authorization list should fail. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: &common.Address{}, + Value: (*hexutil.Big)(big.NewInt(0)), + AuthorizationList: []types.SetCodeAuthorization{}, + }, + expectErr: core.ErrEmptyAuthList, + }, + // SetCodeTx with nil `to` should fail. + { + blockNumber: rpc.LatestBlockNumber, + call: TransactionArgs{ + From: &accounts[0].addr, + To: nil, + Value: (*hexutil.Big)(big.NewInt(0)), + AuthorizationList: []types.SetCodeAuthorization{setCodeAuthorization}, + }, + expectErr: core.ErrSetCodeTxCreate, + }, } for i, tc := range testSuite { result, err := api.EstimateGas(context.Background(), tc.call, &rpc.BlockNumberOrHash{BlockNumber: &tc.blockNumber}, &tc.overrides, &tc.blockOverrides) From 1d5cae80d03894779847aefedb9e2834f3af2b69 Mon Sep 17 00:00:00 2001 From: colinlyguo Date: Thu, 20 Feb 2025 20:45:00 +0800 Subject: [PATCH 2/2] tweak --- core/blockchain_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 04dfa87b8b88..d72f49795457 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -4212,7 +4212,7 @@ func TestEIP7702(t *testing.T) { // The way the auths are combined, it becomes // 1. tx -> addr1 which is delegated to 0xaaaa // 2. addr1:0xaaaa calls into addr2:0xbbbb - // 3. addr2:0xbbbb writes to storage + // 3. addr2:0xbbbb writes to storage auth1, _ := types.SignSetCode(key1, types.SetCodeAuthorization{ ChainID: *uint256.MustFromBig(gspec.Config.ChainID), Address: aa,