Skip to content

Commit 51f21a5

Browse files
committed
refactor code
1 parent ab740cb commit 51f21a5

File tree

8 files changed

+282
-53
lines changed

8 files changed

+282
-53
lines changed

core/state_transition.go

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
145145
type 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.
176193
func 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
}

core/types/transaction.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ func (tx *Transaction) SetCodeAuthorities() []common.Address {
525525
auths = make([]common.Address, 0, len(setcodetx.AuthList))
526526
)
527527
for _, auth := range setcodetx.AuthList {
528-
if addr, err := auth.Authority(true); err == nil {
528+
if addr, err := auth.Authority(); err == nil {
529529
if marks[addr] {
530530
continue
531531
}

core/types/tx_setcode.go

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@ type SetCodeTx struct {
6868

6969
//go:generate go run github.com/fjl/gencodec -type SetCodeAuthorization -field-override authorizationMarshaling -out gen_authorization.go
7070

71+
// SetCodeAuth is an interface for getting authorization details.
72+
// It abstracts over signed and unsigned authorizations, enabling
73+
// gas estimation without valid signatures.
74+
type SetCodeAuth interface {
75+
GetChainID() uint256.Int
76+
GetAddress() common.Address
77+
GetNonce() uint64
78+
GetAuthority() (common.Address, error)
79+
80+
// AsSetCodeAuthorization returns the underlying SetCodeAuthorization for encoding.
81+
AsSetCodeAuthorization() SetCodeAuthorization
82+
}
83+
7184
// SetCodeAuthorization is an authorization from an account to deploy code at its address.
7285
type SetCodeAuthorization struct {
7386
ChainID uint256.Int `json:"chainId" gencodec:"required"`
@@ -115,9 +128,9 @@ func (a *SetCodeAuthorization) SigHash() common.Hash {
115128
}
116129

117130
// Authority recovers the the authorizing account of an authorization.
118-
func (a *SetCodeAuthorization) Authority(validateSig bool) (common.Address, error) {
131+
func (a *SetCodeAuthorization) Authority() (common.Address, error) {
119132
sighash := a.SigHash()
120-
if validateSig && !crypto.ValidateSignatureValues(a.V, a.R.ToBig(), a.S.ToBig(), true) {
133+
if !crypto.ValidateSignatureValues(a.V, a.R.ToBig(), a.S.ToBig(), true) {
121134
return common.Address{}, ErrInvalidSig
122135
}
123136
// encode the signature in uncompressed format
@@ -241,3 +254,80 @@ func (tx *SetCodeTx) sigHash(chainID *big.Int) common.Hash {
241254
tx.AuthList,
242255
})
243256
}
257+
258+
// SignedAuthorization wraps a SetCodeAuthorization and recovers authority from signature.
259+
type SignedAuthorization struct {
260+
auth SetCodeAuthorization
261+
}
262+
263+
// NewSignedAuthorization creates a new SignedAuthorization.
264+
func NewSignedAuthorization(auth SetCodeAuthorization) *SignedAuthorization {
265+
return &SignedAuthorization{auth: auth}
266+
}
267+
268+
func (s *SignedAuthorization) GetChainID() uint256.Int {
269+
return s.auth.ChainID
270+
}
271+
272+
func (s *SignedAuthorization) GetAddress() common.Address {
273+
return s.auth.Address
274+
}
275+
276+
func (s *SignedAuthorization) GetNonce() uint64 {
277+
return s.auth.Nonce
278+
}
279+
280+
func (s *SignedAuthorization) GetAuthority() (common.Address, error) {
281+
return s.auth.Authority()
282+
}
283+
284+
func (s *SignedAuthorization) AsSetCodeAuthorization() SetCodeAuthorization {
285+
return s.auth
286+
}
287+
288+
// UnsignedAuthorization represents an authorization with an authority address,
289+
// used for gas estimation when a valid signature is not available.
290+
type UnsignedAuthorization struct {
291+
chainID uint256.Int
292+
address common.Address
293+
nonce uint64
294+
authority common.Address
295+
}
296+
297+
// NewUnsignedAuthorization creates a new UnsignedAuthorization.
298+
func NewUnsignedAuthorization(chainID uint256.Int, address common.Address, nonce uint64, authority common.Address) *UnsignedAuthorization {
299+
return &UnsignedAuthorization{
300+
chainID: chainID,
301+
address: address,
302+
nonce: nonce,
303+
authority: authority,
304+
}
305+
}
306+
307+
func (u *UnsignedAuthorization) GetChainID() uint256.Int {
308+
return u.chainID
309+
}
310+
311+
func (u *UnsignedAuthorization) GetAddress() common.Address {
312+
return u.address
313+
}
314+
315+
func (u *UnsignedAuthorization) GetNonce() uint64 {
316+
return u.nonce
317+
}
318+
319+
func (u *UnsignedAuthorization) GetAuthority() (common.Address, error) {
320+
return u.authority, nil
321+
}
322+
323+
func (u *UnsignedAuthorization) AsSetCodeAuthorization() SetCodeAuthorization {
324+
// Return a zero-valued authorization with basic fields filled in
325+
return SetCodeAuthorization{
326+
ChainID: u.chainID,
327+
Address: u.address,
328+
Nonce: u.nonce,
329+
V: 0,
330+
R: uint256.Int{},
331+
S: uint256.Int{},
332+
}
333+
}

eth/tracers/native/prestate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ func (t *prestateTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction
186186

187187
// Add accounts with authorizations to the prestate before they get applied.
188188
for _, auth := range tx.SetCodeAuthorizations() {
189-
addr, err := auth.Authority(true)
189+
addr, err := auth.Authority()
190190
if err != nil {
191191
continue
192192
}

internal/ethapi/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,7 +1295,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
12951295
continue
12961296
}
12971297

1298-
if authority, err := auth.Authority(true); err == nil {
1298+
if authority, err := auth.Authority(); err == nil {
12991299
addressesToExclude[authority] = struct{}{}
13001300
}
13011301
}

0 commit comments

Comments
 (0)