diff --git a/core/state_transition.go b/core/state_transition.go index bf5ac07636..6821efd49d 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -575,16 +575,18 @@ func (st *stateTransition) execute() (*ExecutionResult, error) { // validateAuthorization validates an EIP-7702 authorization against the state. func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorization) (authority common.Address, err error) { + skipValidation := st.msg.SkipTransactionChecks + // Verify chain ID is null or equal to current chain ID. - if !auth.ChainID.IsZero() && auth.ChainID.CmpBig(st.evm.ChainConfig().ChainID) != 0 { + if !skipValidation && !auth.ChainID.IsZero() && auth.ChainID.CmpBig(st.evm.ChainConfig().ChainID) != 0 { return authority, ErrAuthorizationWrongChainID } // Limit nonce to 2^64-1 per EIP-2681. - if auth.Nonce+1 < auth.Nonce { + if !skipValidation && auth.Nonce+1 < auth.Nonce { return authority, ErrAuthorizationNonceOverflow } // Validate signature values and recover authority. - authority, err = auth.Authority() + authority, err = auth.Authority(!skipValidation) if err != nil { return authority, fmt.Errorf("%w: %v", ErrAuthorizationInvalidSignature, err) } @@ -594,12 +596,15 @@ func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorizatio // // Note it is added to the access list even if the authorization is invalid. st.state.AddAddressToAccessList(authority) - code := st.state.GetCode(authority) - if _, ok := types.ParseDelegation(code); len(code) != 0 && !ok { - return authority, ErrAuthorizationDestinationHasCode - } - if have := st.state.GetNonce(authority); have != auth.Nonce { - return authority, ErrAuthorizationNonceMismatch + // Skip state checks during gas estimation + if !skipValidation { + code := st.state.GetCode(authority) + if _, ok := types.ParseDelegation(code); len(code) != 0 && !ok { + return authority, ErrAuthorizationDestinationHasCode + } + if have := st.state.GetNonce(authority); have != auth.Nonce { + return authority, ErrAuthorizationNonceMismatch + } } return authority, nil } diff --git a/core/types/transaction.go b/core/types/transaction.go index be8e90364e..c9665f7084 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -525,7 +525,7 @@ func (tx *Transaction) SetCodeAuthorities() []common.Address { auths = make([]common.Address, 0, len(setcodetx.AuthList)) ) for _, auth := range setcodetx.AuthList { - if addr, err := auth.Authority(); err == nil { + if addr, err := auth.Authority(true); err == nil { if marks[addr] { continue } diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index f2281d4ae7..930c774484 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -115,9 +115,9 @@ func (a *SetCodeAuthorization) SigHash() common.Hash { } // Authority recovers the the authorizing account of an authorization. -func (a *SetCodeAuthorization) Authority() (common.Address, error) { +func (a *SetCodeAuthorization) Authority(validateSig bool) (common.Address, error) { sighash := a.SigHash() - if !crypto.ValidateSignatureValues(a.V, a.R.ToBig(), a.S.ToBig(), true) { + if validateSig && !crypto.ValidateSignatureValues(a.V, a.R.ToBig(), a.S.ToBig(), true) { return common.Address{}, ErrInvalidSig } // encode the signature in uncompressed format diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 49679d312f..4d4a1dd9e5 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -186,7 +186,7 @@ func (t *prestateTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction // Add accounts with authorizations to the prestate before they get applied. for _, auth := range tx.SetCodeAuthorizations() { - addr, err := auth.Authority() + addr, err := auth.Authority(true) if err != nil { continue } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index eb7a34474c..676b84011e 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1296,7 +1296,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH continue } - if authority, err := auth.Authority(); err == nil { + if authority, err := auth.Authority(true); err == nil { addressesToExclude[authority] = struct{}{} } }