github.com/ethereum/go-ethereum@v1.16.1/core/state_transition.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package core 18 19 import ( 20 "bytes" 21 "fmt" 22 "math" 23 "math/big" 24 25 "github.com/ethereum/go-ethereum/common" 26 "github.com/ethereum/go-ethereum/core/tracing" 27 "github.com/ethereum/go-ethereum/core/types" 28 "github.com/ethereum/go-ethereum/core/vm" 29 "github.com/ethereum/go-ethereum/crypto/kzg4844" 30 "github.com/ethereum/go-ethereum/params" 31 "github.com/holiman/uint256" 32 ) 33 34 // ExecutionResult includes all output after executing given evm 35 // message no matter the execution itself is successful or not. 36 type ExecutionResult struct { 37 UsedGas uint64 // Total used gas, not including the refunded gas 38 MaxUsedGas uint64 // Maximum gas consumed during execution, excluding gas refunds. 39 Err error // Any error encountered during the execution(listed in core/vm/errors.go) 40 ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode) 41 } 42 43 // Unwrap returns the internal evm error which allows us for further 44 // analysis outside. 45 func (result *ExecutionResult) Unwrap() error { 46 return result.Err 47 } 48 49 // Failed returns the indicator whether the execution is successful or not 50 func (result *ExecutionResult) Failed() bool { return result.Err != nil } 51 52 // Return is a helper function to help caller distinguish between revert reason 53 // and function return. Return returns the data after execution if no error occurs. 54 func (result *ExecutionResult) Return() []byte { 55 if result.Err != nil { 56 return nil 57 } 58 return common.CopyBytes(result.ReturnData) 59 } 60 61 // Revert returns the concrete revert reason if the execution is aborted by `REVERT` 62 // opcode. Note the reason can be nil if no data supplied with revert opcode. 63 func (result *ExecutionResult) Revert() []byte { 64 if result.Err != vm.ErrExecutionReverted { 65 return nil 66 } 67 return common.CopyBytes(result.ReturnData) 68 } 69 70 // IntrinsicGas computes the 'intrinsic gas' for a message with the given data. 71 func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.SetCodeAuthorization, isContractCreation, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) { 72 // Set the starting gas for the raw transaction 73 var gas uint64 74 if isContractCreation && isHomestead { 75 gas = params.TxGasContractCreation 76 } else { 77 gas = params.TxGas 78 } 79 dataLen := uint64(len(data)) 80 // Bump the required gas by the amount of transactional data 81 if dataLen > 0 { 82 // Zero and non-zero bytes are priced differently 83 z := uint64(bytes.Count(data, []byte{0})) 84 nz := dataLen - z 85 86 // Make sure we don't exceed uint64 for all data combinations 87 nonZeroGas := params.TxDataNonZeroGasFrontier 88 if isEIP2028 { 89 nonZeroGas = params.TxDataNonZeroGasEIP2028 90 } 91 if (math.MaxUint64-gas)/nonZeroGas < nz { 92 return 0, ErrGasUintOverflow 93 } 94 gas += nz * nonZeroGas 95 96 if (math.MaxUint64-gas)/params.TxDataZeroGas < z { 97 return 0, ErrGasUintOverflow 98 } 99 gas += z * params.TxDataZeroGas 100 101 if isContractCreation && isEIP3860 { 102 lenWords := toWordSize(dataLen) 103 if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords { 104 return 0, ErrGasUintOverflow 105 } 106 gas += lenWords * params.InitCodeWordGas 107 } 108 } 109 if accessList != nil { 110 gas += uint64(len(accessList)) * params.TxAccessListAddressGas 111 gas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas 112 } 113 if authList != nil { 114 gas += uint64(len(authList)) * params.CallNewAccountGas 115 } 116 return gas, nil 117 } 118 119 // FloorDataGas computes the minimum gas required for a transaction based on its data tokens (EIP-7623). 120 func FloorDataGas(data []byte) (uint64, error) { 121 var ( 122 z = uint64(bytes.Count(data, []byte{0})) 123 nz = uint64(len(data)) - z 124 tokens = nz*params.TxTokenPerNonZeroByte + z 125 ) 126 // Check for overflow 127 if (math.MaxUint64-params.TxGas)/params.TxCostFloorPerToken < tokens { 128 return 0, ErrGasUintOverflow 129 } 130 // Minimum gas required for a transaction based on its data tokens (EIP-7623). 131 return params.TxGas + tokens*params.TxCostFloorPerToken, nil 132 } 133 134 // toWordSize returns the ceiled word size required for init code payment calculation. 135 func toWordSize(size uint64) uint64 { 136 if size > math.MaxUint64-31 { 137 return math.MaxUint64/32 + 1 138 } 139 140 return (size + 31) / 32 141 } 142 143 // A Message contains the data derived from a single transaction that is relevant to state 144 // processing. 145 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 159 160 // When SkipNonceChecks is true, the message nonce is not checked against the 161 // account nonce in state. 162 // 163 // This field will be set to true for operations like RPC eth_call 164 // or the state prefetching. 165 SkipNonceChecks bool 166 167 // When SkipFromEOACheck is true, the message sender is not checked to be an EOA. 168 SkipFromEOACheck bool 169 } 170 171 // TransactionToMessage converts a transaction into a Message. 172 func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) { 173 msg := &Message{ 174 Nonce: tx.Nonce(), 175 GasLimit: tx.Gas(), 176 GasPrice: new(big.Int).Set(tx.GasPrice()), 177 GasFeeCap: new(big.Int).Set(tx.GasFeeCap()), 178 GasTipCap: new(big.Int).Set(tx.GasTipCap()), 179 To: tx.To(), 180 Value: tx.Value(), 181 Data: tx.Data(), 182 AccessList: tx.AccessList(), 183 SetCodeAuthorizations: tx.SetCodeAuthorizations(), 184 SkipNonceChecks: false, 185 SkipFromEOACheck: false, 186 BlobHashes: tx.BlobHashes(), 187 BlobGasFeeCap: tx.BlobGasFeeCap(), 188 } 189 // If baseFee provided, set gasPrice to effectiveGasPrice. 190 if baseFee != nil { 191 msg.GasPrice = msg.GasPrice.Add(msg.GasTipCap, baseFee) 192 if msg.GasPrice.Cmp(msg.GasFeeCap) > 0 { 193 msg.GasPrice = msg.GasFeeCap 194 } 195 } 196 var err error 197 msg.From, err = types.Sender(s, tx) 198 return msg, err 199 } 200 201 // ApplyMessage computes the new state by applying the given message 202 // against the old state within the environment. 203 // 204 // ApplyMessage returns the bytes returned by any EVM execution (if it took place), 205 // the gas used (which includes gas refunds) and an error if it failed. An error always 206 // indicates a core error meaning that the message would always fail for that particular 207 // state and would never be accepted within a block. 208 func ApplyMessage(evm *vm.EVM, msg *Message, gp *GasPool) (*ExecutionResult, error) { 209 evm.SetTxContext(NewEVMTxContext(msg)) 210 return newStateTransition(evm, msg, gp).execute() 211 } 212 213 // stateTransition represents a state transition. 214 // 215 // == The State Transitioning Model 216 // 217 // A state transition is a change made when a transaction is applied to the current world 218 // state. The state transitioning model does all the necessary work to work out a valid new 219 // state root. 220 // 221 // 1. Nonce handling 222 // 2. Pre pay gas 223 // 3. Create a new state object if the recipient is nil 224 // 4. Value transfer 225 // 226 // == If contract creation == 227 // 228 // 4a. Attempt to run transaction data 229 // 4b. If valid, use result as code for the new state object 230 // 231 // == end == 232 // 233 // 5. Run Script section 234 // 6. Derive new state root 235 type stateTransition struct { 236 gp *GasPool 237 msg *Message 238 gasRemaining uint64 239 initialGas uint64 240 state vm.StateDB 241 evm *vm.EVM 242 } 243 244 // newStateTransition initialises and returns a new state transition object. 245 func newStateTransition(evm *vm.EVM, msg *Message, gp *GasPool) *stateTransition { 246 return &stateTransition{ 247 gp: gp, 248 evm: evm, 249 msg: msg, 250 state: evm.StateDB, 251 } 252 } 253 254 // to returns the recipient of the message. 255 func (st *stateTransition) to() common.Address { 256 if st.msg == nil || st.msg.To == nil /* contract creation */ { 257 return common.Address{} 258 } 259 return *st.msg.To 260 } 261 262 func (st *stateTransition) buyGas() error { 263 mgval := new(big.Int).SetUint64(st.msg.GasLimit) 264 mgval.Mul(mgval, st.msg.GasPrice) 265 balanceCheck := new(big.Int).Set(mgval) 266 if st.msg.GasFeeCap != nil { 267 balanceCheck.SetUint64(st.msg.GasLimit) 268 balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap) 269 } 270 balanceCheck.Add(balanceCheck, st.msg.Value) 271 272 if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) { 273 if blobGas := st.blobGasUsed(); blobGas > 0 { 274 // Check that the user has enough funds to cover blobGasUsed * tx.BlobGasFeeCap 275 blobBalanceCheck := new(big.Int).SetUint64(blobGas) 276 blobBalanceCheck.Mul(blobBalanceCheck, st.msg.BlobGasFeeCap) 277 balanceCheck.Add(balanceCheck, blobBalanceCheck) 278 // Pay for blobGasUsed * actual blob fee 279 blobFee := new(big.Int).SetUint64(blobGas) 280 blobFee.Mul(blobFee, st.evm.Context.BlobBaseFee) 281 mgval.Add(mgval, blobFee) 282 } 283 } 284 balanceCheckU256, overflow := uint256.FromBig(balanceCheck) 285 if overflow { 286 return fmt.Errorf("%w: address %v required balance exceeds 256 bits", ErrInsufficientFunds, st.msg.From.Hex()) 287 } 288 if have, want := st.state.GetBalance(st.msg.From), balanceCheckU256; have.Cmp(want) < 0 { 289 return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want) 290 } 291 if err := st.gp.SubGas(st.msg.GasLimit); err != nil { 292 return err 293 } 294 295 if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil { 296 st.evm.Config.Tracer.OnGasChange(0, st.msg.GasLimit, tracing.GasChangeTxInitialBalance) 297 } 298 st.gasRemaining = st.msg.GasLimit 299 300 st.initialGas = st.msg.GasLimit 301 mgvalU256, _ := uint256.FromBig(mgval) 302 st.state.SubBalance(st.msg.From, mgvalU256, tracing.BalanceDecreaseGasBuy) 303 return nil 304 } 305 306 func (st *stateTransition) preCheck() error { 307 // Only check transactions that are not fake 308 msg := st.msg 309 if !msg.SkipNonceChecks { 310 // Make sure this transaction's nonce is correct. 311 stNonce := st.state.GetNonce(msg.From) 312 if msgNonce := msg.Nonce; stNonce < msgNonce { 313 return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooHigh, 314 msg.From.Hex(), msgNonce, stNonce) 315 } else if stNonce > msgNonce { 316 return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow, 317 msg.From.Hex(), msgNonce, stNonce) 318 } else if stNonce+1 < stNonce { 319 return fmt.Errorf("%w: address %v, nonce: %d", ErrNonceMax, 320 msg.From.Hex(), stNonce) 321 } 322 } 323 if !msg.SkipFromEOACheck { 324 // Make sure the sender is an EOA 325 code := st.state.GetCode(msg.From) 326 _, delegated := types.ParseDelegation(code) 327 if len(code) > 0 && !delegated { 328 return fmt.Errorf("%w: address %v, len(code): %d", ErrSenderNoEOA, msg.From.Hex(), len(code)) 329 } 330 } 331 // Make sure that transaction gasFeeCap is greater than the baseFee (post london) 332 if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) { 333 // Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call) 334 skipCheck := st.evm.Config.NoBaseFee && msg.GasFeeCap.BitLen() == 0 && msg.GasTipCap.BitLen() == 0 335 if !skipCheck { 336 if l := msg.GasFeeCap.BitLen(); l > 256 { 337 return fmt.Errorf("%w: address %v, maxFeePerGas bit length: %d", ErrFeeCapVeryHigh, 338 msg.From.Hex(), l) 339 } 340 if l := msg.GasTipCap.BitLen(); l > 256 { 341 return fmt.Errorf("%w: address %v, maxPriorityFeePerGas bit length: %d", ErrTipVeryHigh, 342 msg.From.Hex(), l) 343 } 344 if msg.GasFeeCap.Cmp(msg.GasTipCap) < 0 { 345 return fmt.Errorf("%w: address %v, maxPriorityFeePerGas: %s, maxFeePerGas: %s", ErrTipAboveFeeCap, 346 msg.From.Hex(), msg.GasTipCap, msg.GasFeeCap) 347 } 348 // This will panic if baseFee is nil, but basefee presence is verified 349 // as part of header validation. 350 if msg.GasFeeCap.Cmp(st.evm.Context.BaseFee) < 0 { 351 return fmt.Errorf("%w: address %v, maxFeePerGas: %s, baseFee: %s", ErrFeeCapTooLow, 352 msg.From.Hex(), msg.GasFeeCap, st.evm.Context.BaseFee) 353 } 354 } 355 } 356 // Check the blob version validity 357 if msg.BlobHashes != nil { 358 // The to field of a blob tx type is mandatory, and a `BlobTx` transaction internally 359 // has it as a non-nillable value, so any msg derived from blob transaction has it non-nil. 360 // However, messages created through RPC (eth_call) don't have this restriction. 361 if msg.To == nil { 362 return ErrBlobTxCreate 363 } 364 if len(msg.BlobHashes) == 0 { 365 return ErrMissingBlobHashes 366 } 367 for i, hash := range msg.BlobHashes { 368 if !kzg4844.IsValidVersionedHash(hash[:]) { 369 return fmt.Errorf("blob %d has invalid hash version", i) 370 } 371 } 372 } 373 // Check that the user is paying at least the current blob fee 374 if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) { 375 if st.blobGasUsed() > 0 { 376 // Skip the checks if gas fields are zero and blobBaseFee was explicitly disabled (eth_call) 377 skipCheck := st.evm.Config.NoBaseFee && msg.BlobGasFeeCap.BitLen() == 0 378 if !skipCheck { 379 // This will panic if blobBaseFee is nil, but blobBaseFee presence 380 // is verified as part of header validation. 381 if msg.BlobGasFeeCap.Cmp(st.evm.Context.BlobBaseFee) < 0 { 382 return fmt.Errorf("%w: address %v blobGasFeeCap: %v, blobBaseFee: %v", ErrBlobFeeCapTooLow, 383 msg.From.Hex(), msg.BlobGasFeeCap, st.evm.Context.BlobBaseFee) 384 } 385 } 386 } 387 } 388 // Check that EIP-7702 authorization list signatures are well formed. 389 if msg.SetCodeAuthorizations != nil { 390 if msg.To == nil { 391 return fmt.Errorf("%w (sender %v)", ErrSetCodeTxCreate, msg.From) 392 } 393 if len(msg.SetCodeAuthorizations) == 0 { 394 return fmt.Errorf("%w (sender %v)", ErrEmptyAuthList, msg.From) 395 } 396 } 397 return st.buyGas() 398 } 399 400 // execute will transition the state by applying the current message and 401 // returning the evm execution result with following fields. 402 // 403 // - used gas: total gas used (including gas being refunded) 404 // - returndata: the returned data from evm 405 // - concrete execution error: various EVM errors which abort the execution, e.g. 406 // ErrOutOfGas, ErrExecutionReverted 407 // 408 // However if any consensus issue encountered, return the error directly with 409 // nil evm execution result. 410 func (st *stateTransition) execute() (*ExecutionResult, error) { 411 // First check this message satisfies all consensus rules before 412 // applying the message. The rules include these clauses 413 // 414 // 1. the nonce of the message caller is correct 415 // 2. caller has enough balance to cover transaction fee(gaslimit * gasprice) 416 // 3. the amount of gas required is available in the block 417 // 4. the purchased gas is enough to cover intrinsic usage 418 // 5. there is no overflow when calculating intrinsic gas 419 // 6. caller has enough balance to cover asset transfer for **topmost** call 420 421 // Check clauses 1-3, buy gas if everything is correct 422 if err := st.preCheck(); err != nil { 423 return nil, err 424 } 425 426 var ( 427 msg = st.msg 428 rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Random != nil, st.evm.Context.Time) 429 contractCreation = msg.To == nil 430 floorDataGas uint64 431 ) 432 433 // Check clauses 4-5, subtract intrinsic gas if everything is correct 434 gas, err := IntrinsicGas(msg.Data, msg.AccessList, msg.SetCodeAuthorizations, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai) 435 if err != nil { 436 return nil, err 437 } 438 if st.gasRemaining < gas { 439 return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas) 440 } 441 // Gas limit suffices for the floor data cost (EIP-7623) 442 if rules.IsPrague { 443 floorDataGas, err = FloorDataGas(msg.Data) 444 if err != nil { 445 return nil, err 446 } 447 if msg.GasLimit < floorDataGas { 448 return nil, fmt.Errorf("%w: have %d, want %d", ErrFloorDataGas, msg.GasLimit, floorDataGas) 449 } 450 } 451 if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil { 452 t.OnGasChange(st.gasRemaining, st.gasRemaining-gas, tracing.GasChangeTxIntrinsicGas) 453 } 454 st.gasRemaining -= gas 455 456 if rules.IsEIP4762 { 457 st.evm.AccessEvents.AddTxOrigin(msg.From) 458 459 if targetAddr := msg.To; targetAddr != nil { 460 st.evm.AccessEvents.AddTxDestination(*targetAddr, msg.Value.Sign() != 0, !st.state.Exist(*targetAddr)) 461 } 462 } 463 464 // Check clause 6 465 value, overflow := uint256.FromBig(msg.Value) 466 if overflow { 467 return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex()) 468 } 469 if !value.IsZero() && !st.evm.Context.CanTransfer(st.state, msg.From, value) { 470 return nil, fmt.Errorf("%w: address %v", ErrInsufficientFundsForTransfer, msg.From.Hex()) 471 } 472 473 // Check whether the init code size has been exceeded. 474 if rules.IsShanghai && contractCreation && len(msg.Data) > params.MaxInitCodeSize { 475 return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(msg.Data), params.MaxInitCodeSize) 476 } 477 478 // Execute the preparatory steps for state transition which includes: 479 // - prepare accessList(post-berlin) 480 // - reset transient storage(eip 1153) 481 st.state.Prepare(rules, msg.From, st.evm.Context.Coinbase, msg.To, vm.ActivePrecompiles(rules), msg.AccessList) 482 483 var ( 484 ret []byte 485 vmerr error // vm errors do not effect consensus and are therefore not assigned to err 486 ) 487 if contractCreation { 488 ret, _, st.gasRemaining, vmerr = st.evm.Create(msg.From, msg.Data, st.gasRemaining, value) 489 } else { 490 // Increment the nonce for the next transaction. 491 st.state.SetNonce(msg.From, st.state.GetNonce(msg.From)+1, tracing.NonceChangeEoACall) 492 493 // Apply EIP-7702 authorizations. 494 if msg.SetCodeAuthorizations != nil { 495 for _, auth := range msg.SetCodeAuthorizations { 496 // Note errors are ignored, we simply skip invalid authorizations here. 497 st.applyAuthorization(&auth) 498 } 499 } 500 501 // Perform convenience warming of sender's delegation target. Although the 502 // sender is already warmed in Prepare(..), it's possible a delegation to 503 // the account was deployed during this transaction. To handle correctly, 504 // simply wait until the final state of delegations is determined before 505 // performing the resolution and warming. 506 if addr, ok := types.ParseDelegation(st.state.GetCode(*msg.To)); ok { 507 st.state.AddAddressToAccessList(addr) 508 } 509 510 // Execute the transaction's call. 511 ret, st.gasRemaining, vmerr = st.evm.Call(msg.From, st.to(), msg.Data, st.gasRemaining, value) 512 } 513 514 // Record the gas used excluding gas refunds. This value represents the actual 515 // gas allowance required to complete execution. 516 peakGasUsed := st.gasUsed() 517 518 // Compute refund counter, capped to a refund quotient. 519 st.gasRemaining += st.calcRefund() 520 if rules.IsPrague { 521 // After EIP-7623: Data-heavy transactions pay the floor gas. 522 if st.gasUsed() < floorDataGas { 523 prev := st.gasRemaining 524 st.gasRemaining = st.initialGas - floorDataGas 525 if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil { 526 t.OnGasChange(prev, st.gasRemaining, tracing.GasChangeTxDataFloor) 527 } 528 } 529 if peakGasUsed < floorDataGas { 530 peakGasUsed = floorDataGas 531 } 532 } 533 st.returnGas() 534 535 effectiveTip := msg.GasPrice 536 if rules.IsLondon { 537 effectiveTip = new(big.Int).Sub(msg.GasPrice, st.evm.Context.BaseFee) 538 } 539 effectiveTipU256, _ := uint256.FromBig(effectiveTip) 540 541 if st.evm.Config.NoBaseFee && msg.GasFeeCap.Sign() == 0 && msg.GasTipCap.Sign() == 0 { 542 // Skip fee payment when NoBaseFee is set and the fee fields 543 // are 0. This avoids a negative effectiveTip being applied to 544 // the coinbase when simulating calls. 545 } else { 546 fee := new(uint256.Int).SetUint64(st.gasUsed()) 547 fee.Mul(fee, effectiveTipU256) 548 st.state.AddBalance(st.evm.Context.Coinbase, fee, tracing.BalanceIncreaseRewardTransactionFee) 549 550 // add the coinbase to the witness iff the fee is greater than 0 551 if rules.IsEIP4762 && fee.Sign() != 0 { 552 st.evm.AccessEvents.AddAccount(st.evm.Context.Coinbase, true, math.MaxUint64) 553 } 554 } 555 556 return &ExecutionResult{ 557 UsedGas: st.gasUsed(), 558 MaxUsedGas: peakGasUsed, 559 Err: vmerr, 560 ReturnData: ret, 561 }, nil 562 } 563 564 // validateAuthorization validates an EIP-7702 authorization against the state. 565 func (st *stateTransition) validateAuthorization(auth *types.SetCodeAuthorization) (authority common.Address, err error) { 566 // Verify chain ID is null or equal to current chain ID. 567 if !auth.ChainID.IsZero() && auth.ChainID.CmpBig(st.evm.ChainConfig().ChainID) != 0 { 568 return authority, ErrAuthorizationWrongChainID 569 } 570 // Limit nonce to 2^64-1 per EIP-2681. 571 if auth.Nonce+1 < auth.Nonce { 572 return authority, ErrAuthorizationNonceOverflow 573 } 574 // Validate signature values and recover authority. 575 authority, err = auth.Authority() 576 if err != nil { 577 return authority, fmt.Errorf("%w: %v", ErrAuthorizationInvalidSignature, err) 578 } 579 // Check the authority account 580 // 1) doesn't have code or has exisiting delegation 581 // 2) matches the auth's nonce 582 // 583 // Note it is added to the access list even if the authorization is invalid. 584 st.state.AddAddressToAccessList(authority) 585 code := st.state.GetCode(authority) 586 if _, ok := types.ParseDelegation(code); len(code) != 0 && !ok { 587 return authority, ErrAuthorizationDestinationHasCode 588 } 589 if have := st.state.GetNonce(authority); have != auth.Nonce { 590 return authority, ErrAuthorizationNonceMismatch 591 } 592 return authority, nil 593 } 594 595 // applyAuthorization applies an EIP-7702 code delegation to the state. 596 func (st *stateTransition) applyAuthorization(auth *types.SetCodeAuthorization) error { 597 authority, err := st.validateAuthorization(auth) 598 if err != nil { 599 return err 600 } 601 602 // If the account already exists in state, refund the new account cost 603 // charged in the intrinsic calculation. 604 if st.state.Exist(authority) { 605 st.state.AddRefund(params.CallNewAccountGas - params.TxAuthTupleGas) 606 } 607 608 // Update nonce and account code. 609 st.state.SetNonce(authority, auth.Nonce+1, tracing.NonceChangeAuthorization) 610 if auth.Address == (common.Address{}) { 611 // Delegation to zero address means clear. 612 st.state.SetCode(authority, nil) 613 return nil 614 } 615 616 // Otherwise install delegation to auth.Address. 617 st.state.SetCode(authority, types.AddressToDelegation(auth.Address)) 618 619 return nil 620 } 621 622 // calcRefund computes refund counter, capped to a refund quotient. 623 func (st *stateTransition) calcRefund() uint64 { 624 var refund uint64 625 if !st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) { 626 // Before EIP-3529: refunds were capped to gasUsed / 2 627 refund = st.gasUsed() / params.RefundQuotient 628 } else { 629 // After EIP-3529: refunds are capped to gasUsed / 5 630 refund = st.gasUsed() / params.RefundQuotientEIP3529 631 } 632 if refund > st.state.GetRefund() { 633 refund = st.state.GetRefund() 634 } 635 if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil && refund > 0 { 636 st.evm.Config.Tracer.OnGasChange(st.gasRemaining, st.gasRemaining+refund, tracing.GasChangeTxRefunds) 637 } 638 return refund 639 } 640 641 // returnGas returns ETH for remaining gas, 642 // exchanged at the original rate. 643 func (st *stateTransition) returnGas() { 644 remaining := uint256.NewInt(st.gasRemaining) 645 remaining.Mul(remaining, uint256.MustFromBig(st.msg.GasPrice)) 646 st.state.AddBalance(st.msg.From, remaining, tracing.BalanceIncreaseGasReturn) 647 648 if st.evm.Config.Tracer != nil && st.evm.Config.Tracer.OnGasChange != nil && st.gasRemaining > 0 { 649 st.evm.Config.Tracer.OnGasChange(st.gasRemaining, 0, tracing.GasChangeTxLeftOverReturned) 650 } 651 652 // Also return remaining gas to the block gas counter so it is 653 // available for the next transaction. 654 st.gp.AddGas(st.gasRemaining) 655 } 656 657 // gasUsed returns the amount of gas used up by the state transition. 658 func (st *stateTransition) gasUsed() uint64 { 659 return st.initialGas - st.gasRemaining 660 } 661 662 // blobGasUsed returns the amount of blob gas used by the message. 663 func (st *stateTransition) blobGasUsed() uint64 { 664 return uint64(len(st.msg.BlobHashes) * params.BlobTxBlobGasPerBlob) 665 }