From e2da8daab4bbd1ab7430c16544aec4f729efb88a Mon Sep 17 00:00:00 2001 From: Daniel Liu <139250065@qq.com> Date: Sat, 20 Dec 2025 13:43:04 +0800 Subject: [PATCH] core/types: updates for EIP-7702 API functions #30933 (#1827) --- core/state_processor_test.go | 2 +- core/state_transition.go | 8 ++--- core/types/gen_authorization.go | 48 +++++++++++++-------------- core/types/transaction.go | 2 +- core/types/transaction_marshalling.go | 30 ++++++++--------- core/types/tx_setcode.go | 36 +++++++++----------- internal/ethapi/api.go | 42 +++++++++++------------ internal/ethapi/transaction_args.go | 4 +-- tests/state_test_util.go | 6 ++-- 9 files changed, 86 insertions(+), 92 deletions(-) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 77cfa53d35..a12f0ce2b7 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -91,7 +91,7 @@ func TestStateProcessorErrors(t *testing.T) { }), signer, key1) return tx } - var mkSetCodeTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap *big.Int, authlist []types.Authorization) *types.Transaction { + var mkSetCodeTx = func(nonce uint64, to common.Address, gasLimit uint64, gasTipCap, gasFeeCap *big.Int, authlist []types.SetCodeAuthorization) *types.Transaction { tx, err := types.SignTx(types.NewTx(&types.SetCodeTx{ Nonce: nonce, GasTipCap: uint256.MustFromBig(gasTipCap), diff --git a/core/state_transition.go b/core/state_transition.go index 9236bc739e..af08bba096 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -59,7 +59,7 @@ func (result *ExecutionResult) Revert() []byte { } // IntrinsicGas computes the 'intrinsic gas' for a message with the given data. -func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.Authorization, isContractCreation, isHomestead bool, isEIP3860 bool) (uint64, error) { +func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.SetCodeAuthorization, isContractCreation, isHomestead bool, isEIP3860 bool) (uint64, error) { // Set the starting gas for the raw transaction var gas uint64 if isContractCreation && isHomestead { @@ -130,7 +130,7 @@ type Message struct { BalanceTokenFee *big.Int Data []byte AccessList types.AccessList - AuthList []types.Authorization + AuthList []types.SetCodeAuthorization // When SkipNonceChecks is true, the message nonce is not checked against the // account nonce in state. @@ -483,7 +483,7 @@ func (st *StateTransition) TransitionDb(owner common.Address) (*ExecutionResult, } // validateAuthorization validates an EIP-7702 authorization against the state. -func (st *StateTransition) validateAuthorization(auth *types.Authorization) (authority common.Address, err error) { +func (st *StateTransition) validateAuthorization(auth *types.SetCodeAuthorization) (authority common.Address, err error) { // Verify chain ID is 0 or equal to current chain ID. if auth.ChainID != 0 && st.evm.ChainConfig().ChainID.Uint64() != auth.ChainID { return authority, ErrAuthorizationWrongChainID @@ -514,7 +514,7 @@ func (st *StateTransition) validateAuthorization(auth *types.Authorization) (aut } // applyAuthorization applies an EIP-7702 code delegation to the state. -func (st *StateTransition) applyAuthorization(msg *Message, auth *types.Authorization) error { +func (st *StateTransition) applyAuthorization(msg *Message, auth *types.SetCodeAuthorization) error { authority, err := st.validateAuthorization(auth) if err != nil { return err diff --git a/core/types/gen_authorization.go b/core/types/gen_authorization.go index 460f9c4eb3..8b639367a2 100644 --- a/core/types/gen_authorization.go +++ b/core/types/gen_authorization.go @@ -14,8 +14,8 @@ import ( var _ = (*authorizationMarshaling)(nil) // MarshalJSON marshals as JSON. -func (a Authorization) MarshalJSON() ([]byte, error) { - type Authorization struct { +func (s SetCodeAuthorization) MarshalJSON() ([]byte, error) { + type SetCodeAuthorization struct { ChainID hexutil.Uint64 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"` @@ -23,19 +23,19 @@ func (a Authorization) MarshalJSON() ([]byte, error) { R hexutil.U256 `json:"r" gencodec:"required"` S hexutil.U256 `json:"s" gencodec:"required"` } - var enc Authorization - enc.ChainID = hexutil.Uint64(a.ChainID) - enc.Address = a.Address - enc.Nonce = hexutil.Uint64(a.Nonce) - enc.V = hexutil.Uint64(a.V) - enc.R = hexutil.U256(a.R) - enc.S = hexutil.U256(a.S) + var enc SetCodeAuthorization + enc.ChainID = hexutil.Uint64(s.ChainID) + enc.Address = s.Address + enc.Nonce = hexutil.Uint64(s.Nonce) + enc.V = hexutil.Uint64(s.V) + enc.R = hexutil.U256(s.R) + enc.S = hexutil.U256(s.S) return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. -func (a *Authorization) UnmarshalJSON(input []byte) error { - type Authorization struct { +func (s *SetCodeAuthorization) UnmarshalJSON(input []byte) error { + type SetCodeAuthorization struct { ChainID *hexutil.Uint64 `json:"chainId" gencodec:"required"` Address *common.Address `json:"address" gencodec:"required"` Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` @@ -43,33 +43,33 @@ func (a *Authorization) UnmarshalJSON(input []byte) error { R *hexutil.U256 `json:"r" gencodec:"required"` S *hexutil.U256 `json:"s" gencodec:"required"` } - var dec Authorization + var dec SetCodeAuthorization if err := json.Unmarshal(input, &dec); err != nil { return err } if dec.ChainID == nil { - return errors.New("missing required field 'chainId' for Authorization") + return errors.New("missing required field 'chainId' for SetCodeAuthorization") } - a.ChainID = uint64(*dec.ChainID) + s.ChainID = uint64(*dec.ChainID) if dec.Address == nil { - return errors.New("missing required field 'address' for Authorization") + return errors.New("missing required field 'address' for SetCodeAuthorization") } - a.Address = *dec.Address + s.Address = *dec.Address if dec.Nonce == nil { - return errors.New("missing required field 'nonce' for Authorization") + return errors.New("missing required field 'nonce' for SetCodeAuthorization") } - a.Nonce = uint64(*dec.Nonce) + s.Nonce = uint64(*dec.Nonce) if dec.V == nil { - return errors.New("missing required field 'v' for Authorization") + return errors.New("missing required field 'v' for SetCodeAuthorization") } - a.V = uint8(*dec.V) + s.V = uint8(*dec.V) if dec.R == nil { - return errors.New("missing required field 'r' for Authorization") + return errors.New("missing required field 'r' for SetCodeAuthorization") } - a.R = uint256.Int(*dec.R) + s.R = uint256.Int(*dec.R) if dec.S == nil { - return errors.New("missing required field 's' for Authorization") + return errors.New("missing required field 's' for SetCodeAuthorization") } - a.S = uint256.Int(*dec.S) + s.S = uint256.Int(*dec.S) return nil } diff --git a/core/types/transaction.go b/core/types/transaction.go index 02ea89aeaf..4a3364a5e0 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -393,7 +393,7 @@ func (tx *Transaction) EffectiveGasTipIntCmp(other *big.Int, baseFee *big.Int) i } // AuthList returns the authorizations list of the transaction. -func (tx *Transaction) AuthList() []Authorization { +func (tx *Transaction) AuthList() []SetCodeAuthorization { setcodetx, ok := tx.inner.(*SetCodeTx) if !ok { return nil diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index dadd6b030d..d978ea17d4 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -30,21 +30,21 @@ import ( type txJSON struct { Type hexutil.Uint64 `json:"type"` - ChainID *hexutil.Big `json:"chainId,omitempty"` - Nonce *hexutil.Uint64 `json:"nonce"` - To *common.Address `json:"to"` - Gas *hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` - MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` - Value *hexutil.Big `json:"value"` - Input *hexutil.Bytes `json:"input"` - AccessList *AccessList `json:"accessList,omitempty"` - AuthorizationList []Authorization `json:"authorizationList,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - YParity *hexutil.Uint64 `json:"yParity,omitempty"` + ChainID *hexutil.Big `json:"chainId,omitempty"` + Nonce *hexutil.Uint64 `json:"nonce"` + To *common.Address `json:"to"` + Gas *hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` + MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` + Value *hexutil.Big `json:"value"` + Input *hexutil.Bytes `json:"input"` + AccessList *AccessList `json:"accessList,omitempty"` + AuthorizationList []SetCodeAuthorization `json:"authorizationList,omitempty"` + V *hexutil.Big `json:"v"` + R *hexutil.Big `json:"r"` + S *hexutil.Big `json:"s"` + YParity *hexutil.Uint64 `json:"yParity,omitempty"` // Only used for encoding: Hash common.Hash `json:"hash"` diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index a9c3ed9620..decd404054 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -58,7 +58,7 @@ type SetCodeTx struct { Value *uint256.Int Data []byte AccessList AccessList - AuthList []Authorization + AuthList []SetCodeAuthorization // Signature values V *uint256.Int `json:"v" gencodec:"required"` @@ -66,10 +66,10 @@ type SetCodeTx struct { S *uint256.Int `json:"s" gencodec:"required"` } -//go:generate go run github.com/fjl/gencodec -type Authorization -field-override authorizationMarshaling -out gen_authorization.go +//go:generate go run github.com/fjl/gencodec -type SetCodeAuthorization -field-override authorizationMarshaling -out gen_authorization.go -// Authorization is an authorization from an account to deploy code at its address. -type Authorization struct { +// SetCodeAuthorization is an authorization from an account to deploy code at its address. +type SetCodeAuthorization struct { ChainID uint64 `json:"chainId" gencodec:"required"` Address common.Address `json:"address" gencodec:"required"` Nonce uint64 `json:"nonce" gencodec:"required"` @@ -87,31 +87,25 @@ type authorizationMarshaling struct { S hexutil.U256 } -// SignAuth signs the provided authorization. -func SignAuth(auth Authorization, prv *ecdsa.PrivateKey) (Authorization, error) { +// SignSetCode creates a signed SetCode authorization. +func SignSetCode(auth SetCodeAuthorization, prv *ecdsa.PrivateKey) (SetCodeAuthorization, error) { sighash := auth.sigHash() sig, err := crypto.Sign(sighash[:], prv) if err != nil { - return Authorization{}, err + return SetCodeAuthorization{}, err } - return auth.withSignature(sig), nil -} - -// withSignature updates the signature of an Authorization to be equal the -// decoded signature provided in sig. -func (a *Authorization) withSignature(sig []byte) Authorization { r, s, _ := decodeSignature(sig) - return Authorization{ - ChainID: a.ChainID, - Address: a.Address, - Nonce: a.Nonce, + return SetCodeAuthorization{ + ChainID: auth.ChainID, + Address: auth.Address, + Nonce: auth.Nonce, V: sig[64], R: *uint256.MustFromBig(r), S: *uint256.MustFromBig(s), - } + }, nil } -func (a *Authorization) sigHash() common.Hash { +func (a *SetCodeAuthorization) sigHash() common.Hash { return prefixedRlpHash(0x05, []any{ a.ChainID, a.Address, @@ -120,7 +114,7 @@ func (a *Authorization) sigHash() common.Hash { } // Authority recovers the authorizing account of an authorization. -func (a *Authorization) Authority() (common.Address, error) { +func (a *SetCodeAuthorization) Authority() (common.Address, error) { sighash := a.sigHash() if !crypto.ValidateSignatureValues(a.V, a.R.ToBig(), a.S.ToBig(), true) { return common.Address{}, ErrInvalidSig @@ -152,7 +146,7 @@ func (tx *SetCodeTx) copy() TxData { Gas: tx.Gas, // These are copied below. AccessList: make(AccessList, len(tx.AccessList)), - AuthList: make([]Authorization, len(tx.AuthList)), + AuthList: make([]SetCodeAuthorization, len(tx.AuthList)), Value: new(uint256.Int), ChainID: tx.ChainID, GasTipCap: new(uint256.Int), diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 0615da8637..62f8b31599 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1654,27 +1654,27 @@ func (api *BlockChainAPI) rpcOutputBlockSigners(b *types.Block, ctx context.Cont // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction type RPCTransaction struct { - BlockHash *common.Hash `json:"blockHash"` - BlockNumber *hexutil.Big `json:"blockNumber"` - From common.Address `json:"from"` - Gas hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` - GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` - Hash common.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` - Nonce hexutil.Uint64 `json:"nonce"` - To *common.Address `json:"to"` - TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` - Value *hexutil.Big `json:"value"` - Type hexutil.Uint64 `json:"type"` - Accesses *types.AccessList `json:"accessList,omitempty"` - ChainID *hexutil.Big `json:"chainId,omitempty"` - AuthorizationList []types.Authorization `json:"authorizationList,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - YParity *hexutil.Uint64 `json:"yParity,omitempty"` + BlockHash *common.Hash `json:"blockHash"` + BlockNumber *hexutil.Big `json:"blockNumber"` + From common.Address `json:"from"` + Gas hexutil.Uint64 `json:"gas"` + GasPrice *hexutil.Big `json:"gasPrice"` + GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` + GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` + Hash common.Hash `json:"hash"` + Input hexutil.Bytes `json:"input"` + Nonce hexutil.Uint64 `json:"nonce"` + To *common.Address `json:"to"` + TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` + Value *hexutil.Big `json:"value"` + Type hexutil.Uint64 `json:"type"` + Accesses *types.AccessList `json:"accessList,omitempty"` + ChainID *hexutil.Big `json:"chainId,omitempty"` + AuthorizationList []types.SetCodeAuthorization `json:"authorizationList,omitempty"` + V *hexutil.Big `json:"v"` + R *hexutil.Big `json:"r"` + S *hexutil.Big `json:"s"` + YParity *hexutil.Uint64 `json:"yParity,omitempty"` } // newRPCTransaction returns a transaction that will serialize to the RPC diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index d41b74a646..096ed539e2 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -57,7 +57,7 @@ type TransactionArgs struct { ChainID *hexutil.Big `json:"chainId,omitempty"` // For SetCodeTxType - AuthorizationList []types.Authorization `json:"authorizationList"` + AuthorizationList []types.SetCodeAuthorization `json:"authorizationList"` } // from retrieves the transaction sender address. @@ -373,7 +373,7 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction { if args.AccessList != nil { al = *args.AccessList } - authList := []types.Authorization{} + authList := []types.SetCodeAuthorization{} if args.AuthorizationList != nil { authList = args.AuthorizationList } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 8b4a835293..99c1ca8469 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -307,11 +307,11 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess if gasPrice == nil { return nil, errors.New("no gas price provided") } - var authList []types.Authorization + var authList []types.SetCodeAuthorization if tx.AuthorizationList != nil { - authList = make([]types.Authorization, len(tx.AuthorizationList)) + authList = make([]types.SetCodeAuthorization, len(tx.AuthorizationList)) for i, auth := range tx.AuthorizationList { - authList[i] = types.Authorization{ + authList[i] = types.SetCodeAuthorization{ ChainID: auth.ChainID, Address: auth.Address, Nonce: auth.Nonce,