@@ -143,19 +143,23 @@ func toWordSize(size uint64) uint64 {
143143// A Message contains the data derived from a single transaction that is relevant to state
144144// processing.
145145type Message struct {
146- To * common.Address
147- From common.Address
148- Nonce uint64
149- Value * big.Int
150- GasLimit uint64
151- GasPrice * big.Int
152- GasFeeCap * big.Int
153- GasTipCap * big.Int
154- Data []byte
155- AccessList types.AccessList
156- BlobGasFeeCap * big.Int
157- BlobHashes []common.Hash
158- SetCodeAuthorizations []types.SetCodeAuthorization
146+ To * common.Address
147+ From common.Address
148+ Nonce uint64
149+ Value * big.Int
150+ GasLimit uint64
151+ GasPrice * big.Int
152+ GasFeeCap * big.Int
153+ GasTipCap * big.Int
154+ Data []byte
155+ AccessList types.AccessList
156+ BlobGasFeeCap * big.Int
157+ BlobHashes []common.Hash
158+
159+ // AuthList provides an abstraction over authorization handling.
160+ // It handles both signed authorizations (with signature recovery) and unsigned
161+ // authorizations (with explicit authority addresses for gas estimation).
162+ AuthList []types.SetCodeAuth
159163
160164 // When SkipNonceChecks is true, the message nonce is not checked against the
161165 // account nonce in state.
@@ -172,8 +176,30 @@ type Message struct {
172176 SkipTransactionChecks bool
173177}
174178
179+ // getAuthorizationList extracts SetCodeAuthorization list from auth interfaces.
180+ // This is used for intrinsic gas calculation and validation.
181+ func (msg * Message ) getAuthorizationList () []types.SetCodeAuthorization {
182+ if msg .AuthList == nil {
183+ return nil
184+ }
185+ authList := make ([]types.SetCodeAuthorization , len (msg .AuthList ))
186+ for i , auth := range msg .AuthList {
187+ authList [i ] = auth .AsSetCodeAuthorization ()
188+ }
189+ return authList
190+ }
191+
175192// TransactionToMessage converts a transaction into a Message.
176193func TransactionToMessage (tx * types.Transaction , s types.Signer , baseFee * big.Int ) (* Message , error ) {
194+ // Create authorization interfaces from transaction authorizations
195+ var authList []types.SetCodeAuth
196+ if auths := tx .SetCodeAuthorizations (); auths != nil {
197+ authList = make ([]types.SetCodeAuth , len (auths ))
198+ for i , auth := range auths {
199+ authList [i ] = types .NewSignedAuthorization (auth )
200+ }
201+ }
202+
177203 msg := & Message {
178204 Nonce : tx .Nonce (),
179205 GasLimit : tx .Gas (),
@@ -184,7 +210,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
184210 Value : tx .Value (),
185211 Data : tx .Data (),
186212 AccessList : tx .AccessList (),
187- SetCodeAuthorizations : tx . SetCodeAuthorizations () ,
213+ AuthList : authList ,
188214 SkipNonceChecks : false ,
189215 SkipTransactionChecks : false ,
190216 BlobHashes : tx .BlobHashes (),
@@ -398,11 +424,11 @@ func (st *stateTransition) preCheck() error {
398424 }
399425 }
400426 // Check that EIP-7702 authorization list signatures are well formed.
401- if msg .SetCodeAuthorizations != nil {
427+ if msg .AuthList != nil {
402428 if msg .To == nil {
403429 return fmt .Errorf ("%w (sender %v)" , ErrSetCodeTxCreate , msg .From )
404430 }
405- if len (msg .SetCodeAuthorizations ) == 0 {
431+ if len (msg .AuthList ) == 0 {
406432 return fmt .Errorf ("%w (sender %v)" , ErrEmptyAuthList , msg .From )
407433 }
408434 }
@@ -443,7 +469,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
443469 )
444470
445471 // Check clauses 4-5, subtract intrinsic gas if everything is correct
446- gas , err := IntrinsicGas (msg .Data , msg .AccessList , msg .SetCodeAuthorizations , contractCreation , rules .IsHomestead , rules .IsIstanbul , rules .IsShanghai )
472+ gas , err := IntrinsicGas (msg .Data , msg .AccessList , msg .getAuthorizationList () , contractCreation , rules .IsHomestead , rules .IsIstanbul , rules .IsShanghai )
447473 if err != nil {
448474 return nil , err
449475 }
@@ -503,10 +529,10 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
503529 st .state .SetNonce (msg .From , st .state .GetNonce (msg .From )+ 1 , tracing .NonceChangeEoACall )
504530
505531 // Apply EIP-7702 authorizations.
506- if msg .SetCodeAuthorizations != nil {
507- for _ , auth := range msg .SetCodeAuthorizations {
532+ if msg .AuthList != nil {
533+ for _ , auth := range msg .AuthList {
508534 // Note errors are ignored, we simply skip invalid authorizations here.
509- st .applyAuthorization (& auth )
535+ st .applyAuthorization (auth )
510536 }
511537 }
512538
@@ -574,19 +600,21 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
574600}
575601
576602// validateAuthorization validates an EIP-7702 authorization against the state.
577- func (st * stateTransition ) validateAuthorization (auth * types.SetCodeAuthorization ) (authority common.Address , err error ) {
603+ func (st * stateTransition ) validateAuthorization (auth types.SetCodeAuth ) (authority common.Address , err error ) {
578604 skipValidation := st .msg .SkipTransactionChecks
579605
580606 // Verify chain ID is null or equal to current chain ID.
581- if ! skipValidation && ! auth .ChainID .IsZero () && auth .ChainID .CmpBig (st .evm .ChainConfig ().ChainID ) != 0 {
607+ chainID := auth .GetChainID ()
608+ if ! skipValidation && ! chainID .IsZero () && chainID .CmpBig (st .evm .ChainConfig ().ChainID ) != 0 {
582609 return authority , ErrAuthorizationWrongChainID
583610 }
584611 // Limit nonce to 2^64-1 per EIP-2681.
585- if ! skipValidation && auth .Nonce + 1 < auth .Nonce {
612+ nonce := auth .GetNonce ()
613+ if ! skipValidation && nonce + 1 < nonce {
586614 return authority , ErrAuthorizationNonceOverflow
587615 }
588- // Validate signature values and recover authority .
589- authority , err = auth .Authority ( ! skipValidation )
616+ // Get authority from auth (may recover from signature or use explicit address) .
617+ authority , err = auth .GetAuthority ( )
590618 if err != nil {
591619 return authority , fmt .Errorf ("%w: %v" , ErrAuthorizationInvalidSignature , err )
592620 }
@@ -602,15 +630,15 @@ func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorizatio
602630 if _ , ok := types .ParseDelegation (code ); len (code ) != 0 && ! ok {
603631 return authority , ErrAuthorizationDestinationHasCode
604632 }
605- if have := st .state .GetNonce (authority ); have != auth . Nonce {
633+ if have := st .state .GetNonce (authority ); have != nonce {
606634 return authority , ErrAuthorizationNonceMismatch
607635 }
608636 }
609637 return authority , nil
610638}
611639
612640// applyAuthorization applies an EIP-7702 code delegation to the state.
613- func (st * stateTransition ) applyAuthorization (auth * types.SetCodeAuthorization ) error {
641+ func (st * stateTransition ) applyAuthorization (auth types.SetCodeAuth ) error {
614642 authority , err := st .validateAuthorization (auth )
615643 if err != nil {
616644 return err
@@ -623,15 +651,17 @@ func (st *stateTransition) applyAuthorization(auth *types.SetCodeAuthorization)
623651 }
624652
625653 // Update nonce and account code.
626- st .state .SetNonce (authority , auth .Nonce + 1 , tracing .NonceChangeAuthorization )
627- if auth .Address == (common.Address {}) {
654+ nonce := auth .GetNonce ()
655+ address := auth .GetAddress ()
656+ st .state .SetNonce (authority , nonce + 1 , tracing .NonceChangeAuthorization )
657+ if address == (common.Address {}) {
628658 // Delegation to zero address means clear.
629659 st .state .SetCode (authority , nil , tracing .CodeChangeAuthorizationClear )
630660 return nil
631661 }
632662
633663 // Otherwise install delegation to auth.Address.
634- st .state .SetCode (authority , types .AddressToDelegation (auth . Address ), tracing .CodeChangeAuthorization )
664+ st .state .SetCode (authority , types .AddressToDelegation (address ), tracing .CodeChangeAuthorization )
635665
636666 return nil
637667}
0 commit comments