Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ethclient: add AuthList field in toCallArg #31198

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down
2 changes: 1 addition & 1 deletion core/txpool/legacypool/legacypool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
5 changes: 5 additions & 0 deletions core/vm/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
Expand Down
3 changes: 3 additions & 0 deletions ethclient/ethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
3 changes: 3 additions & 0 deletions ethclient/gethclient/gethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
3 changes: 3 additions & 0 deletions interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
49 changes: 49 additions & 0 deletions internal/ethapi/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mind-twisting test but I think I get it now :)

Authorization: account0 to itself
Execute: recipient is account0, it will fetch the delegate which is again itself (recursive). So it will return the raw delegation code (prefix+account0) and try to execute it which will fail.

Is that the intention?

Copy link
Contributor Author

@colinlyguo colinlyguo Feb 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I found this test case during local test. This unit test reminds that EIP-7702 only retrieves one layer of account code.

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)
Expand Down