mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
Merge 81d5d79109 into b135da2eac
This commit is contained in:
commit
c14eeec71b
29 changed files with 235 additions and 144 deletions
|
|
@ -213,7 +213,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
if beaconRoot := pre.Env.ParentBeaconBlockRoot; beaconRoot != nil {
|
if beaconRoot := pre.Env.ParentBeaconBlockRoot; beaconRoot != nil {
|
||||||
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||||
}
|
}
|
||||||
if pre.Env.BlockHashes != nil && chainConfig.IsPrague(new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp) {
|
rules := evm.Rules()
|
||||||
|
if pre.Env.BlockHashes != nil && rules.IsPrague {
|
||||||
var (
|
var (
|
||||||
prevNumber = pre.Env.Number - 1
|
prevNumber = pre.Env.Number - 1
|
||||||
prevHash = pre.Env.BlockHashes[math.HexOrDecimal64(prevNumber)]
|
prevHash = pre.Env.BlockHashes[math.HexOrDecimal64(prevNumber)]
|
||||||
|
|
@ -233,7 +234,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
rejectedTxs = append(rejectedTxs, &rejectedTx{i, errMsg})
|
rejectedTxs = append(rejectedTxs, &rejectedTx{i, errMsg})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee)
|
msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err)
|
log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err)
|
||||||
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
|
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
|
||||||
|
|
|
||||||
|
|
@ -132,9 +132,9 @@ func Transaction(ctx *cli.Context) error {
|
||||||
} else {
|
} else {
|
||||||
r.Address = sender
|
r.Address = sender
|
||||||
}
|
}
|
||||||
// Check intrinsic gas
|
|
||||||
rules := chainConfig.Rules(common.Big0, true, 0)
|
rules := chainConfig.Rules(common.Big0, true, 0)
|
||||||
gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai)
|
// Check intrinsic gas
|
||||||
|
gas, err := tx.IntrinsicGas(&rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Error = err
|
r.Error = err
|
||||||
results = append(results, r)
|
results = append(results, r)
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ func applyMergeChecks(env *stEnv, chainConfig *params.ChainConfig) error {
|
||||||
switch {
|
switch {
|
||||||
case env.Random == nil:
|
case env.Random == nil:
|
||||||
return NewError(ErrorConfig, errors.New("post-merge requires currentRandom to be defined in env"))
|
return NewError(ErrorConfig, errors.New("post-merge requires currentRandom to be defined in env"))
|
||||||
case env.Difficulty != nil && env.Difficulty.BitLen() != 0:
|
case env.Difficulty != nil && env.Difficulty.Sign() != 0:
|
||||||
return NewError(ErrorConfig, errors.New("post-merge difficulty must be zero (or omitted) in env"))
|
return NewError(ErrorConfig, errors.New("post-merge difficulty must be zero (or omitted) in env"))
|
||||||
}
|
}
|
||||||
env.Difficulty = nil
|
env.Difficulty = nil
|
||||||
|
|
|
||||||
|
|
@ -90,20 +90,21 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
|
||||||
data := make([]byte, nbytes)
|
data := make([]byte, nbytes)
|
||||||
return func(i int, gen *BlockGen) {
|
return func(i int, gen *BlockGen) {
|
||||||
toaddr := common.Address{}
|
toaddr := common.Address{}
|
||||||
gas, _ := IntrinsicGas(data, nil, nil, false, false, false, false)
|
|
||||||
signer := gen.Signer()
|
signer := gen.Signer()
|
||||||
gasPrice := big.NewInt(0)
|
gasPrice := big.NewInt(0)
|
||||||
if gen.header.BaseFee != nil {
|
if gen.header.BaseFee != nil {
|
||||||
gasPrice = gen.header.BaseFee
|
gasPrice = gen.header.BaseFee
|
||||||
}
|
}
|
||||||
tx, _ := types.SignNewTx(benchRootKey, signer, &types.LegacyTx{
|
rules := params.TestChainConfig.Rules(common.Big0, true, 0)
|
||||||
|
txdata := &types.LegacyTx{
|
||||||
Nonce: gen.TxNonce(benchRootAddr),
|
Nonce: gen.TxNonce(benchRootAddr),
|
||||||
To: &toaddr,
|
To: &toaddr,
|
||||||
Value: big.NewInt(1),
|
Value: big.NewInt(1),
|
||||||
Gas: gas,
|
|
||||||
Data: data,
|
Data: data,
|
||||||
GasPrice: gasPrice,
|
GasPrice: gasPrice,
|
||||||
})
|
}
|
||||||
|
txdata.Gas = types.IntrinsicGas(txdata, &rules)
|
||||||
|
tx, _ := types.SignNewTx(benchRootKey, signer, txdata)
|
||||||
gen.AddTx(tx)
|
gen.AddTx(tx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
||||||
blockContext = NewEVMBlockContext(header, p.chain, nil)
|
blockContext = NewEVMBlockContext(header, p.chain, nil)
|
||||||
evm = vm.NewEVM(blockContext, statedb, p.config, cfg)
|
evm = vm.NewEVM(blockContext, statedb, p.config, cfg)
|
||||||
signer = types.MakeSigner(p.config, header.Number, header.Time)
|
signer = types.MakeSigner(p.config, header.Number, header.Time)
|
||||||
|
rules = evm.Rules()
|
||||||
)
|
)
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
byzantium := p.config.IsByzantium(block.Number())
|
byzantium := p.config.IsByzantium(block.Number())
|
||||||
|
|
@ -60,7 +61,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Convert the transaction into an executable message and pre-cache its sender
|
// Convert the transaction into an executable message and pre-cache its sender
|
||||||
msg, err := TransactionToMessage(tx, signer, header.BaseFee)
|
msg, err := TransactionToMessage(tx, signer, header.BaseFee, rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return // Also invalid block, bail out
|
return // Also invalid block, bail out
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,29 +69,29 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||||
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
var (
|
|
||||||
context vm.BlockContext
|
|
||||||
signer = types.MakeSigner(p.config, header.Number, header.Time)
|
|
||||||
)
|
|
||||||
|
|
||||||
// Apply pre-execution system calls.
|
// Apply pre-execution system calls.
|
||||||
var tracingStateDB = vm.StateDB(statedb)
|
var tracingStateDB = vm.StateDB(statedb)
|
||||||
if hooks := cfg.Tracer; hooks != nil {
|
if hooks := cfg.Tracer; hooks != nil {
|
||||||
tracingStateDB = state.NewHookedState(statedb, hooks)
|
tracingStateDB = state.NewHookedState(statedb, hooks)
|
||||||
}
|
}
|
||||||
context = NewEVMBlockContext(header, p.chain, nil)
|
|
||||||
evm := vm.NewEVM(context, tracingStateDB, p.config, cfg)
|
|
||||||
|
|
||||||
|
var (
|
||||||
|
context = NewEVMBlockContext(header, p.chain, nil)
|
||||||
|
evm = vm.NewEVM(context, tracingStateDB, p.config, cfg)
|
||||||
|
rules = evm.Rules()
|
||||||
|
signer = types.MakeSigner(p.config, header.Number, header.Time)
|
||||||
|
)
|
||||||
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
ProcessBeaconBlockRoot(*beaconRoot, evm)
|
ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||||
}
|
}
|
||||||
if p.config.IsPrague(block.Number(), block.Time()) || p.config.IsVerkle(block.Number(), block.Time()) {
|
if rules.IsPrague || rules.IsVerkle {
|
||||||
ProcessParentBlockHash(block.ParentHash(), evm)
|
ProcessParentBlockHash(block.ParentHash(), evm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
msg, err := TransactionToMessage(tx, signer, header.BaseFee)
|
msg, err := TransactionToMessage(tx, signer, header.BaseFee, rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
return nil, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +205,7 @@ func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, b
|
||||||
// for the transaction, gas used and an error if the transaction failed,
|
// for the transaction, gas used and an error if the transaction failed,
|
||||||
// indicating the block was invalid.
|
// indicating the block was invalid.
|
||||||
func ApplyTransaction(evm *vm.EVM, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64) (*types.Receipt, error) {
|
func ApplyTransaction(evm *vm.EVM, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64) (*types.Receipt, error) {
|
||||||
msg, err := TransactionToMessage(tx, types.MakeSigner(evm.ChainConfig(), header.Number, header.Time), header.BaseFee)
|
msg, err := TransactionToMessage(tx, types.MakeSigner(evm.ChainConfig(), header.Number, header.Time), header.BaseFee, evm.Rules())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,55 +67,6 @@ func (result *ExecutionResult) Revert() []byte {
|
||||||
return common.CopyBytes(result.ReturnData)
|
return common.CopyBytes(result.ReturnData)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
|
|
||||||
func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.SetCodeAuthorization, isContractCreation, isHomestead, isEIP2028, isEIP3860 bool) (uint64, error) {
|
|
||||||
// Set the starting gas for the raw transaction
|
|
||||||
var gas uint64
|
|
||||||
if isContractCreation && isHomestead {
|
|
||||||
gas = params.TxGasContractCreation
|
|
||||||
} else {
|
|
||||||
gas = params.TxGas
|
|
||||||
}
|
|
||||||
dataLen := uint64(len(data))
|
|
||||||
// Bump the required gas by the amount of transactional data
|
|
||||||
if dataLen > 0 {
|
|
||||||
// Zero and non-zero bytes are priced differently
|
|
||||||
z := uint64(bytes.Count(data, []byte{0}))
|
|
||||||
nz := dataLen - z
|
|
||||||
|
|
||||||
// Make sure we don't exceed uint64 for all data combinations
|
|
||||||
nonZeroGas := params.TxDataNonZeroGasFrontier
|
|
||||||
if isEIP2028 {
|
|
||||||
nonZeroGas = params.TxDataNonZeroGasEIP2028
|
|
||||||
}
|
|
||||||
if (math.MaxUint64-gas)/nonZeroGas < nz {
|
|
||||||
return 0, ErrGasUintOverflow
|
|
||||||
}
|
|
||||||
gas += nz * nonZeroGas
|
|
||||||
|
|
||||||
if (math.MaxUint64-gas)/params.TxDataZeroGas < z {
|
|
||||||
return 0, ErrGasUintOverflow
|
|
||||||
}
|
|
||||||
gas += z * params.TxDataZeroGas
|
|
||||||
|
|
||||||
if isContractCreation && isEIP3860 {
|
|
||||||
lenWords := toWordSize(dataLen)
|
|
||||||
if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords {
|
|
||||||
return 0, ErrGasUintOverflow
|
|
||||||
}
|
|
||||||
gas += lenWords * params.InitCodeWordGas
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if accessList != nil {
|
|
||||||
gas += uint64(len(accessList)) * params.TxAccessListAddressGas
|
|
||||||
gas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas
|
|
||||||
}
|
|
||||||
if authList != nil {
|
|
||||||
gas += uint64(len(authList)) * params.CallNewAccountGas
|
|
||||||
}
|
|
||||||
return gas, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FloorDataGas computes the minimum gas required for a transaction based on its data tokens (EIP-7623).
|
// FloorDataGas computes the minimum gas required for a transaction based on its data tokens (EIP-7623).
|
||||||
func FloorDataGas(data []byte) (uint64, error) {
|
func FloorDataGas(data []byte) (uint64, error) {
|
||||||
var (
|
var (
|
||||||
|
|
@ -131,15 +82,6 @@ func FloorDataGas(data []byte) (uint64, error) {
|
||||||
return params.TxGas + tokens*params.TxCostFloorPerToken, nil
|
return params.TxGas + tokens*params.TxCostFloorPerToken, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// toWordSize returns the ceiled word size required for init code payment calculation.
|
|
||||||
func toWordSize(size uint64) uint64 {
|
|
||||||
if size > math.MaxUint64-31 {
|
|
||||||
return math.MaxUint64/32 + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return (size + 31) / 32
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Message contains the data derived from a single transaction that is relevant to state
|
// A Message contains the data derived from a single transaction that is relevant to state
|
||||||
// processing.
|
// processing.
|
||||||
type Message struct {
|
type Message struct {
|
||||||
|
|
@ -151,6 +93,7 @@ type Message struct {
|
||||||
GasPrice *big.Int
|
GasPrice *big.Int
|
||||||
GasFeeCap *big.Int
|
GasFeeCap *big.Int
|
||||||
GasTipCap *big.Int
|
GasTipCap *big.Int
|
||||||
|
IntrinsicGas uint64
|
||||||
Data []byte
|
Data []byte
|
||||||
AccessList types.AccessList
|
AccessList types.AccessList
|
||||||
BlobGasFeeCap *big.Int
|
BlobGasFeeCap *big.Int
|
||||||
|
|
@ -167,7 +110,7 @@ type Message struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TransactionToMessage converts a transaction into a Message.
|
// TransactionToMessage converts a transaction into a Message.
|
||||||
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) {
|
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int, rules *params.Rules) (*Message, error) {
|
||||||
msg := &Message{
|
msg := &Message{
|
||||||
Nonce: tx.Nonce(),
|
Nonce: tx.Nonce(),
|
||||||
GasLimit: tx.Gas(),
|
GasLimit: tx.Gas(),
|
||||||
|
|
@ -191,7 +134,14 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
|
||||||
msg.GasPrice = msg.GasFeeCap
|
msg.GasPrice = msg.GasFeeCap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var err error
|
// Fill in intrinsic gas.
|
||||||
|
intrinsicGas, err := tx.IntrinsicGas(rules)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
msg.IntrinsicGas = intrinsicGas
|
||||||
|
|
||||||
|
// Recover sender.
|
||||||
msg.From, err = types.Sender(s, tx)
|
msg.From, err = types.Sender(s, tx)
|
||||||
return msg, err
|
return msg, err
|
||||||
}
|
}
|
||||||
|
|
@ -426,15 +376,12 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Random != nil, st.evm.Context.Time)
|
rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Random != nil, st.evm.Context.Time)
|
||||||
contractCreation = msg.To == nil
|
contractCreation = msg.To == nil
|
||||||
floorDataGas uint64
|
floorDataGas uint64
|
||||||
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
// Check clauses 4-5, subtract intrinsic gas if everything is correct
|
// Check clauses 4-5, subtract intrinsic gas if everything is correct
|
||||||
gas, err := IntrinsicGas(msg.Data, msg.AccessList, msg.SetCodeAuthorizations, contractCreation, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai)
|
if st.gasRemaining < msg.IntrinsicGas {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, msg.IntrinsicGas)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if st.gasRemaining < gas {
|
|
||||||
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gasRemaining, gas)
|
|
||||||
}
|
}
|
||||||
// Gas limit suffices for the floor data cost (EIP-7623)
|
// Gas limit suffices for the floor data cost (EIP-7623)
|
||||||
if rules.IsPrague {
|
if rules.IsPrague {
|
||||||
|
|
@ -447,9 +394,9 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil {
|
if t := st.evm.Config.Tracer; t != nil && t.OnGasChange != nil {
|
||||||
t.OnGasChange(st.gasRemaining, st.gasRemaining-gas, tracing.GasChangeTxIntrinsicGas)
|
t.OnGasChange(st.gasRemaining, st.gasRemaining-msg.IntrinsicGas, tracing.GasChangeTxIntrinsicGas)
|
||||||
}
|
}
|
||||||
st.gasRemaining -= gas
|
st.gasRemaining -= msg.IntrinsicGas
|
||||||
|
|
||||||
if rules.IsEIP4762 {
|
if rules.IsEIP4762 {
|
||||||
st.evm.AccessEvents.AddTxOrigin(msg.From)
|
st.evm.AccessEvents.AddTxOrigin(msg.From)
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
||||||
}
|
}
|
||||||
// Ensure the transaction has more gas than the bare minimum needed to cover
|
// Ensure the transaction has more gas than the bare minimum needed to cover
|
||||||
// the transaction metadata
|
// the transaction metadata
|
||||||
intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, true, rules.IsIstanbul, rules.IsShanghai)
|
intrGas, err := tx.IntrinsicGas(&rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,14 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -40,6 +42,7 @@ var (
|
||||||
errInvalidYParity = errors.New("'yParity' field must be 0 or 1")
|
errInvalidYParity = errors.New("'yParity' field must be 0 or 1")
|
||||||
errVYParityMismatch = errors.New("'v' and 'yParity' fields do not match")
|
errVYParityMismatch = errors.New("'v' and 'yParity' fields do not match")
|
||||||
errVYParityMissing = errors.New("missing 'yParity' or 'v' field in transaction")
|
errVYParityMissing = errors.New("missing 'yParity' or 'v' field in transaction")
|
||||||
|
ErrGasUintOverflow = errors.New("gas uint64 overflow")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Transaction types.
|
// Transaction types.
|
||||||
|
|
@ -86,6 +89,7 @@ type TxData interface {
|
||||||
value() *big.Int
|
value() *big.Int
|
||||||
nonce() uint64
|
nonce() uint64
|
||||||
to() *common.Address
|
to() *common.Address
|
||||||
|
setCodeAuthorizations() []SetCodeAuthorization
|
||||||
|
|
||||||
rawSignatureValues() (v, r, s *big.Int)
|
rawSignatureValues() (v, r, s *big.Int)
|
||||||
setSignatureValues(chainID, v, r, s *big.Int)
|
setSignatureValues(chainID, v, r, s *big.Int)
|
||||||
|
|
@ -479,11 +483,7 @@ func (tx *Transaction) WithBlobTxSidecar(sideCar *BlobTxSidecar) *Transaction {
|
||||||
|
|
||||||
// SetCodeAuthorizations returns the authorizations list of the transaction.
|
// SetCodeAuthorizations returns the authorizations list of the transaction.
|
||||||
func (tx *Transaction) SetCodeAuthorizations() []SetCodeAuthorization {
|
func (tx *Transaction) SetCodeAuthorizations() []SetCodeAuthorization {
|
||||||
setcodetx, ok := tx.inner.(*SetCodeTx)
|
return tx.inner.setCodeAuthorizations()
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return setcodetx.AuthList
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCodeAuthorities returns a list of unique authorities from the
|
// SetCodeAuthorities returns a list of unique authorities from the
|
||||||
|
|
@ -581,6 +581,78 @@ func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, e
|
||||||
return &Transaction{inner: cpy, time: tx.time}, nil
|
return &Transaction{inner: cpy, time: tx.time}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IntrinsicGas returns the calculated intrinsic gas for the given transaction.
|
||||||
|
func (tx *Transaction) IntrinsicGas(rules *params.Rules) (uint64, error) {
|
||||||
|
return calcIntrinsicGas(tx.inner, rules)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntrinsicGas returns the calculated intrinsic gas for the given transaction.
|
||||||
|
func IntrinsicGas(txdata TxData, rules *params.Rules) uint64 {
|
||||||
|
gas, err := calcIntrinsicGas(txdata, rules)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return gas
|
||||||
|
}
|
||||||
|
|
||||||
|
// calcIntrinsicGas is an internal function that drives exported versions of the function.
|
||||||
|
func calcIntrinsicGas(txdata TxData, rules *params.Rules) (uint64, error) {
|
||||||
|
// Set the starting gas for the raw transaction
|
||||||
|
var gas uint64
|
||||||
|
if txdata.to() == nil && rules.IsHomestead {
|
||||||
|
gas = params.TxGasContractCreation
|
||||||
|
} else {
|
||||||
|
gas = params.TxGas
|
||||||
|
}
|
||||||
|
dataLen := uint64(len(txdata.data()))
|
||||||
|
// Bump the required gas by the amount of transactional data
|
||||||
|
if dataLen > 0 {
|
||||||
|
// Zero and non-zero bytes are priced differently
|
||||||
|
z := uint64(bytes.Count(txdata.data(), []byte{0}))
|
||||||
|
nz := dataLen - z
|
||||||
|
|
||||||
|
// Make sure we don't exceed uint64 for all data combinations
|
||||||
|
nonZeroGas := params.TxDataNonZeroGasFrontier
|
||||||
|
if rules.IsIstanbul {
|
||||||
|
nonZeroGas = params.TxDataNonZeroGasEIP2028
|
||||||
|
}
|
||||||
|
if (math.MaxUint64-gas)/nonZeroGas < nz {
|
||||||
|
return 0, ErrGasUintOverflow
|
||||||
|
}
|
||||||
|
gas += nz * nonZeroGas
|
||||||
|
|
||||||
|
if (math.MaxUint64-gas)/params.TxDataZeroGas < z {
|
||||||
|
return 0, ErrGasUintOverflow
|
||||||
|
}
|
||||||
|
gas += z * params.TxDataZeroGas
|
||||||
|
|
||||||
|
if txdata.to() == nil && rules.IsShanghai {
|
||||||
|
lenWords := toWordSize(dataLen)
|
||||||
|
if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords {
|
||||||
|
return 0, ErrGasUintOverflow
|
||||||
|
}
|
||||||
|
gas += lenWords * params.InitCodeWordGas
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if txdata.accessList() != nil {
|
||||||
|
gas += uint64(len(txdata.accessList())) * params.TxAccessListAddressGas
|
||||||
|
gas += uint64(txdata.accessList().StorageKeys()) * params.TxAccessListStorageKeyGas
|
||||||
|
}
|
||||||
|
if txdata.setCodeAuthorizations() != nil {
|
||||||
|
gas += uint64(len(txdata.setCodeAuthorizations())) * params.CallNewAccountGas
|
||||||
|
}
|
||||||
|
return gas, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// toWordSize returns the ceiled word size required for init code payment calculation.
|
||||||
|
func toWordSize(size uint64) uint64 {
|
||||||
|
if size > math.MaxUint64-31 {
|
||||||
|
return math.MaxUint64/32 + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return (size + 31) / 32
|
||||||
|
}
|
||||||
|
|
||||||
// Transactions implements DerivableList for transactions.
|
// Transactions implements DerivableList for transactions.
|
||||||
type Transactions []*Transaction
|
type Transactions []*Transaction
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,9 @@ func (tx *AccessListTx) gasFeeCap() *big.Int { return tx.GasPrice }
|
||||||
func (tx *AccessListTx) value() *big.Int { return tx.Value }
|
func (tx *AccessListTx) value() *big.Int { return tx.Value }
|
||||||
func (tx *AccessListTx) nonce() uint64 { return tx.Nonce }
|
func (tx *AccessListTx) nonce() uint64 { return tx.Nonce }
|
||||||
func (tx *AccessListTx) to() *common.Address { return tx.To }
|
func (tx *AccessListTx) to() *common.Address { return tx.To }
|
||||||
|
func (tx *AccessListTx) setCodeAuthorizations() []SetCodeAuthorization {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *AccessListTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
func (tx *AccessListTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
return dst.Set(tx.GasPrice)
|
return dst.Set(tx.GasPrice)
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,9 @@ func (tx *BlobTx) value() *big.Int { return tx.Value.ToBig() }
|
||||||
func (tx *BlobTx) nonce() uint64 { return tx.Nonce }
|
func (tx *BlobTx) nonce() uint64 { return tx.Nonce }
|
||||||
func (tx *BlobTx) to() *common.Address { tmp := tx.To; return &tmp }
|
func (tx *BlobTx) to() *common.Address { tmp := tx.To; return &tmp }
|
||||||
func (tx *BlobTx) blobGas() uint64 { return params.BlobTxBlobGasPerBlob * uint64(len(tx.BlobHashes)) }
|
func (tx *BlobTx) blobGas() uint64 { return params.BlobTxBlobGasPerBlob * uint64(len(tx.BlobHashes)) }
|
||||||
|
func (tx *BlobTx) setCodeAuthorizations() []SetCodeAuthorization {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *BlobTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
func (tx *BlobTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,9 @@ func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap }
|
||||||
func (tx *DynamicFeeTx) value() *big.Int { return tx.Value }
|
func (tx *DynamicFeeTx) value() *big.Int { return tx.Value }
|
||||||
func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce }
|
func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce }
|
||||||
func (tx *DynamicFeeTx) to() *common.Address { return tx.To }
|
func (tx *DynamicFeeTx) to() *common.Address { return tx.To }
|
||||||
|
func (tx *DynamicFeeTx) setCodeAuthorizations() []SetCodeAuthorization {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *DynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
func (tx *DynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,9 @@ func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice }
|
||||||
func (tx *LegacyTx) value() *big.Int { return tx.Value }
|
func (tx *LegacyTx) value() *big.Int { return tx.Value }
|
||||||
func (tx *LegacyTx) nonce() uint64 { return tx.Nonce }
|
func (tx *LegacyTx) nonce() uint64 { return tx.Nonce }
|
||||||
func (tx *LegacyTx) to() *common.Address { return tx.To }
|
func (tx *LegacyTx) to() *common.Address { return tx.To }
|
||||||
|
func (tx *LegacyTx) setCodeAuthorizations() []SetCodeAuthorization {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *LegacyTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
func (tx *LegacyTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
return dst.Set(tx.GasPrice)
|
return dst.Set(tx.GasPrice)
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,9 @@ func (tx *SetCodeTx) gasPrice() *big.Int { return tx.GasFeeCap.ToBig() }
|
||||||
func (tx *SetCodeTx) value() *big.Int { return tx.Value.ToBig() }
|
func (tx *SetCodeTx) value() *big.Int { return tx.Value.ToBig() }
|
||||||
func (tx *SetCodeTx) nonce() uint64 { return tx.Nonce }
|
func (tx *SetCodeTx) nonce() uint64 { return tx.Nonce }
|
||||||
func (tx *SetCodeTx) to() *common.Address { tmp := tx.To; return &tmp }
|
func (tx *SetCodeTx) to() *common.Address { tmp := tx.To; return &tmp }
|
||||||
|
func (tx *SetCodeTx) setCodeAuthorizations() []SetCodeAuthorization {
|
||||||
|
return tx.AuthList
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *SetCodeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
func (tx *SetCodeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int {
|
||||||
if baseFee == nil {
|
if baseFee == nil {
|
||||||
|
|
|
||||||
|
|
@ -92,12 +92,13 @@ var (
|
||||||
func TestProcessVerkle(t *testing.T) {
|
func TestProcessVerkle(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`)
|
code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`)
|
||||||
intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, nil, true, true, true, true)
|
rules = testVerkleChainConfig.Rules(common.Big0, true, 0)
|
||||||
|
intrinsicContractCreationGas, _ = types.NewContractCreation(0, big.NewInt(999), params.TxGas, big.NewInt(875000000), code).IntrinsicGas(&rules)
|
||||||
// A contract creation that calls EXTCODECOPY in the constructor. Used to ensure that the witness
|
// A contract creation that calls EXTCODECOPY in the constructor. Used to ensure that the witness
|
||||||
// will not contain that copied data.
|
// will not contain that copied data.
|
||||||
// Source: https://gist.github.com/gballet/a23db1e1cb4ed105616b5920feb75985
|
// Source: https://gist.github.com/gballet/a23db1e1cb4ed105616b5920feb75985
|
||||||
codeWithExtCodeCopy = common.FromHex(`0x60806040526040516100109061017b565b604051809103906000f08015801561002c573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561007857600080fd5b5060008067ffffffffffffffff8111156100955761009461024a565b5b6040519080825280601f01601f1916602001820160405280156100c75781602001600182028036833780820191505090505b50905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506020600083833c81610101906101e3565b60405161010d90610187565b61011791906101a3565b604051809103906000f080158015610133573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061029b565b60d58061046783390190565b6102068061053c83390190565b61019d816101d9565b82525050565b60006020820190506101b86000830184610194565b92915050565b6000819050602082019050919050565b600081519050919050565b6000819050919050565b60006101ee826101ce565b826101f8846101be565b905061020381610279565b925060208210156102435761023e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261028e565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600061028582516101d9565b80915050919050565b600082821b905092915050565b6101bd806102aa6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f566852414610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381ca91d36040518163ffffffff1660e01b815260040160206040518083038186803b1580156100b857600080fd5b505afa1580156100cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f0919061010a565b905090565b60008151905061010481610170565b92915050565b6000602082840312156101205761011f61016b565b5b600061012e848285016100f5565b91505092915050565b61014081610161565b82525050565b600060208201905061015b6000830184610137565b92915050565b6000819050919050565b600080fd5b61017981610161565b811461018457600080fd5b5056fea2646970667358221220a6a0e11af79f176f9c421b7b12f441356b25f6489b83d38cc828a701720b41f164736f6c63430008070033608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ab5ed15014602d575b600080fd5b60336047565b604051603e9190605d565b60405180910390f35b60006001905090565b6057816076565b82525050565b6000602082019050607060008301846050565b92915050565b600081905091905056fea26469706673582212203a14eb0d5cd07c277d3e24912f110ddda3e553245a99afc4eeefb2fbae5327aa64736f6c63430008070033608060405234801561001057600080fd5b5060405161020638038061020683398181016040528101906100329190610063565b60018160001c6100429190610090565b60008190555050610145565b60008151905061005d8161012e565b92915050565b60006020828403121561007957610078610129565b5b60006100878482850161004e565b91505092915050565b600061009b826100f0565b91506100a6836100f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156100db576100da6100fa565b5b828201905092915050565b6000819050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610137816100e6565b811461014257600080fd5b50565b60b3806101536000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806381ca91d314602d575b600080fd5b60336047565b604051603e9190605a565b60405180910390f35b60005481565b6054816073565b82525050565b6000602082019050606d6000830184604d565b92915050565b600081905091905056fea26469706673582212209bff7098a2f526de1ad499866f27d6d0d6f17b74a413036d6063ca6a0998ca4264736f6c63430008070033`)
|
codeWithExtCodeCopy = common.FromHex(`0x60806040526040516100109061017b565b604051809103906000f08015801561002c573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561007857600080fd5b5060008067ffffffffffffffff8111156100955761009461024a565b5b6040519080825280601f01601f1916602001820160405280156100c75781602001600182028036833780820191505090505b50905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506020600083833c81610101906101e3565b60405161010d90610187565b61011791906101a3565b604051809103906000f080158015610133573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061029b565b60d58061046783390190565b6102068061053c83390190565b61019d816101d9565b82525050565b60006020820190506101b86000830184610194565b92915050565b6000819050602082019050919050565b600081519050919050565b6000819050919050565b60006101ee826101ce565b826101f8846101be565b905061020381610279565b925060208210156102435761023e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261028e565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600061028582516101d9565b80915050919050565b600082821b905092915050565b6101bd806102aa6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f566852414610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381ca91d36040518163ffffffff1660e01b815260040160206040518083038186803b1580156100b857600080fd5b505afa1580156100cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f0919061010a565b905090565b60008151905061010481610170565b92915050565b6000602082840312156101205761011f61016b565b5b600061012e848285016100f5565b91505092915050565b61014081610161565b82525050565b600060208201905061015b6000830184610137565b92915050565b6000819050919050565b600080fd5b61017981610161565b811461018457600080fd5b5056fea2646970667358221220a6a0e11af79f176f9c421b7b12f441356b25f6489b83d38cc828a701720b41f164736f6c63430008070033608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ab5ed15014602d575b600080fd5b60336047565b604051603e9190605d565b60405180910390f35b60006001905090565b6057816076565b82525050565b6000602082019050607060008301846050565b92915050565b600081905091905056fea26469706673582212203a14eb0d5cd07c277d3e24912f110ddda3e553245a99afc4eeefb2fbae5327aa64736f6c63430008070033608060405234801561001057600080fd5b5060405161020638038061020683398181016040528101906100329190610063565b60018160001c6100429190610090565b60008190555050610145565b60008151905061005d8161012e565b92915050565b60006020828403121561007957610078610129565b5b60006100878482850161004e565b91505092915050565b600061009b826100f0565b91506100a6836100f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156100db576100da6100fa565b5b828201905092915050565b6000819050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610137816100e6565b811461014257600080fd5b50565b60b3806101536000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806381ca91d314602d575b600080fd5b60336047565b604051603e9190605a565b60405180910390f35b60005481565b6054816073565b82525050565b6000602082019050606d6000830184604d565b92915050565b600081905091905056fea26469706673582212209bff7098a2f526de1ad499866f27d6d0d6f17b74a413036d6063ca6a0998ca4264736f6c63430008070033`)
|
||||||
intrinsicCodeWithExtCodeCopyGas, _ = IntrinsicGas(codeWithExtCodeCopy, nil, nil, true, true, true, true)
|
intrinsicCodeWithExtCodeCopyGas, _ = types.NewContractCreation(0, big.NewInt(999), params.TxGas, big.NewInt(875000000), codeWithExtCodeCopy).IntrinsicGas(&rules)
|
||||||
signer = types.LatestSigner(testVerkleChainConfig)
|
signer = types.LatestSigner(testVerkleChainConfig)
|
||||||
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain
|
bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain
|
||||||
|
|
|
||||||
|
|
@ -591,6 +591,13 @@ func (evm *EVM) resolveCodeHash(addr common.Address) common.Hash {
|
||||||
// ChainConfig returns the environment's chain configuration
|
// ChainConfig returns the environment's chain configuration
|
||||||
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
|
func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig }
|
||||||
|
|
||||||
|
// Rules returns the rules for the EVM given the current block's context.
|
||||||
|
func (evm *EVM) Rules() *params.Rules {
|
||||||
|
bctx := evm.Context
|
||||||
|
rules := evm.ChainConfig().Rules(bctx.BlockNumber, bctx.Random != nil, bctx.Time)
|
||||||
|
return &rules
|
||||||
|
}
|
||||||
|
|
||||||
func (evm *EVM) captureBegin(depth int, typ OpCode, from common.Address, to common.Address, input []byte, startGas uint64, value *big.Int) {
|
func (evm *EVM) captureBegin(depth int, typ OpCode, from common.Address, to common.Address, input []byte, startGas uint64, value *big.Int) {
|
||||||
tracer := evm.Config.Tracer
|
tracer := evm.Config.Tracer
|
||||||
if tracer.OnEnter != nil {
|
if tracer.OnEnter != nil {
|
||||||
|
|
|
||||||
|
|
@ -235,13 +235,16 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
||||||
return nil, vm.BlockContext{}, nil, nil, err
|
return nil, vm.BlockContext{}, nil, nil, err
|
||||||
}
|
}
|
||||||
// Insert parent beacon block root in the state as per EIP-4788.
|
// Insert parent beacon block root in the state as per EIP-4788.
|
||||||
context := core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
|
var (
|
||||||
evm := vm.NewEVM(context, statedb, eth.blockchain.Config(), vm.Config{})
|
context = core.NewEVMBlockContext(block.Header(), eth.blockchain, nil)
|
||||||
|
evm = vm.NewEVM(context, statedb, eth.blockchain.Config(), vm.Config{})
|
||||||
|
rules = evm.Rules()
|
||||||
|
)
|
||||||
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||||
}
|
}
|
||||||
// If prague hardfork, insert parent block hash in the state as per EIP-2935.
|
// If prague hardfork, insert parent block hash in the state as per EIP-2935.
|
||||||
if eth.blockchain.Config().IsPrague(block.Number(), block.Time()) {
|
if rules.IsPrague {
|
||||||
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
||||||
}
|
}
|
||||||
if txIndex == 0 && len(block.Transactions()) == 0 {
|
if txIndex == 0 && len(block.Transactions()) == 0 {
|
||||||
|
|
@ -254,7 +257,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
|
||||||
return tx, context, statedb, release, nil
|
return tx, context, statedb, release, nil
|
||||||
}
|
}
|
||||||
// Assemble the transaction call message and return if the requested offset
|
// Assemble the transaction call message and return if the requested offset
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), rules)
|
||||||
|
|
||||||
// Not yet the searched for transaction, execute on top of the current state
|
// Not yet the searched for transaction, execute on top of the current state
|
||||||
statedb.SetTxContext(tx.Hash(), idx)
|
statedb.SetTxContext(tx.Hash(), idx)
|
||||||
|
|
|
||||||
|
|
@ -270,10 +270,11 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
|
||||||
var (
|
var (
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time())
|
signer = types.MakeSigner(api.backend.ChainConfig(), task.block.Number(), task.block.Time())
|
||||||
blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil)
|
blockCtx = core.NewEVMBlockContext(task.block.Header(), api.chainContext(ctx), nil)
|
||||||
|
rules = api.backend.ChainConfig().Rules(task.block.Number(), blockCtx.Random != nil, task.block.Time())
|
||||||
)
|
)
|
||||||
// Trace all the transactions contained within
|
// Trace all the transactions contained within
|
||||||
for i, tx := range task.block.Transactions() {
|
for i, tx := range task.block.Transactions() {
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, task.block.BaseFee(), &rules)
|
||||||
txctx := &Context{
|
txctx := &Context{
|
||||||
BlockHash: task.block.Hash(),
|
BlockHash: task.block.Hash(),
|
||||||
BlockNumber: task.block.Number(),
|
BlockNumber: task.block.Number(),
|
||||||
|
|
@ -536,19 +537,20 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
|
||||||
chainConfig = api.backend.ChainConfig()
|
chainConfig = api.backend.ChainConfig()
|
||||||
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
vmctx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
|
||||||
|
evm = vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{})
|
||||||
|
rules = evm.Rules()
|
||||||
)
|
)
|
||||||
evm := vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{})
|
|
||||||
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||||
}
|
}
|
||||||
if chainConfig.IsPrague(block.Number(), block.Time()) {
|
if rules.IsPrague {
|
||||||
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
||||||
}
|
}
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), rules)
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
|
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
|
||||||
log.Warn("Tracing intermediate roots did not complete", "txindex", i, "txhash", tx.Hash(), "err", err)
|
log.Warn("Tracing intermediate roots did not complete", "txindex", i, "txhash", tx.Hash(), "err", err)
|
||||||
|
|
@ -600,12 +602,15 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
}
|
}
|
||||||
defer release()
|
defer release()
|
||||||
|
|
||||||
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
var (
|
||||||
evm := vm.NewEVM(blockCtx, statedb, api.backend.ChainConfig(), vm.Config{})
|
blockCtx = core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
|
||||||
|
evm = vm.NewEVM(blockCtx, statedb, api.backend.ChainConfig(), vm.Config{})
|
||||||
|
rules = evm.Rules()
|
||||||
|
)
|
||||||
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||||
}
|
}
|
||||||
if api.backend.ChainConfig().IsPrague(block.Number(), block.Time()) {
|
if rules.IsPrague {
|
||||||
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -626,7 +631,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
|
||||||
)
|
)
|
||||||
for i, tx := range txs {
|
for i, tx := range txs {
|
||||||
// Generate the next state snapshot fast without tracing
|
// Generate the next state snapshot fast without tracing
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), rules)
|
||||||
txctx := &Context{
|
txctx := &Context{
|
||||||
BlockHash: blockHash,
|
BlockHash: blockHash,
|
||||||
BlockNumber: block.Number(),
|
BlockNumber: block.Number(),
|
||||||
|
|
@ -653,6 +658,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
||||||
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time())
|
||||||
results = make([]*txTraceResult, len(txs))
|
results = make([]*txTraceResult, len(txs))
|
||||||
pend sync.WaitGroup
|
pend sync.WaitGroup
|
||||||
|
rules = api.backend.ChainConfig().Rules(block.Number(), block.Difficulty().Sign() == 0, block.Time())
|
||||||
)
|
)
|
||||||
threads := runtime.NumCPU()
|
threads := runtime.NumCPU()
|
||||||
if threads > len(txs) {
|
if threads > len(txs) {
|
||||||
|
|
@ -665,7 +671,7 @@ func (api *API) traceBlockParallel(ctx context.Context, block *types.Block, stat
|
||||||
defer pend.Done()
|
defer pend.Done()
|
||||||
// Fetch and execute the next transaction trace tasks
|
// Fetch and execute the next transaction trace tasks
|
||||||
for task := range jobs {
|
for task := range jobs {
|
||||||
msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(txs[task.index], signer, block.BaseFee(), &rules)
|
||||||
txctx := &Context{
|
txctx := &Context{
|
||||||
BlockHash: blockHash,
|
BlockHash: blockHash,
|
||||||
BlockNumber: block.Number(),
|
BlockNumber: block.Number(),
|
||||||
|
|
@ -704,7 +710,7 @@ txloop:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the next state snapshot fast without tracing
|
// Generate the next state snapshot fast without tracing
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), &rules)
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
|
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)); err != nil {
|
||||||
failed = err
|
failed = err
|
||||||
|
|
@ -778,17 +784,20 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
|
||||||
// Note: This copies the config, to not screw up the main config
|
// Note: This copies the config, to not screw up the main config
|
||||||
chainConfig, canon = overrideConfig(chainConfig, config.Overrides)
|
chainConfig, canon = overrideConfig(chainConfig, config.Overrides)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{})
|
var (
|
||||||
|
evm = vm.NewEVM(vmctx, statedb, chainConfig, vm.Config{})
|
||||||
|
rules = evm.Rules()
|
||||||
|
)
|
||||||
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
core.ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||||
}
|
}
|
||||||
if chainConfig.IsPrague(block.Number(), block.Time()) {
|
if rules.IsPrague {
|
||||||
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
core.ProcessParentBlockHash(block.ParentHash(), evm)
|
||||||
}
|
}
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
// Prepare the transaction for un-traced execution
|
// Prepare the transaction for un-traced execution
|
||||||
var (
|
var (
|
||||||
msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ = core.TransactionToMessage(tx, signer, block.BaseFee(), rules)
|
||||||
vmConf vm.Config
|
vmConf vm.Config
|
||||||
dump *os.File
|
dump *os.File
|
||||||
writer *bufio.Writer
|
writer *bufio.Writer
|
||||||
|
|
@ -885,7 +894,8 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config *
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer release()
|
defer release()
|
||||||
msg, err := core.TransactionToMessage(tx, types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()), block.BaseFee())
|
rules := api.backend.ChainConfig().Rules(block.Number(), vmctx.Random != nil, block.Time())
|
||||||
|
msg, err := core.TransactionToMessage(tx, types.MakeSigner(api.backend.ChainConfig(), block.Number(), block.Time()), block.BaseFee(), &rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -967,7 +977,8 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
msg = args.ToMessage(vmctx.BaseFee, true, true)
|
rules = api.backend.ChainConfig().Rules(block.Number(), vmctx.Random != nil, block.Time())
|
||||||
|
msg = args.ToMessage(&rules, vmctx.BaseFee, true, true)
|
||||||
tx = args.ToTransaction(types.LegacyTxType)
|
tx = args.ToTransaction(types.LegacyTxType)
|
||||||
traceConfig *TraceConfig
|
traceConfig *TraceConfig
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -178,11 +178,12 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block
|
||||||
signer := types.MakeSigner(b.chainConfig, block.Number(), block.Time())
|
signer := types.MakeSigner(b.chainConfig, block.Number(), block.Time())
|
||||||
context := core.NewEVMBlockContext(block.Header(), b.chain, nil)
|
context := core.NewEVMBlockContext(block.Header(), b.chain, nil)
|
||||||
evm := vm.NewEVM(context, statedb, b.chainConfig, vm.Config{})
|
evm := vm.NewEVM(context, statedb, b.chainConfig, vm.Config{})
|
||||||
|
rules := evm.Rules()
|
||||||
for idx, tx := range block.Transactions() {
|
for idx, tx := range block.Transactions() {
|
||||||
if idx == txIndex {
|
if idx == txIndex {
|
||||||
return tx, context, statedb, release, nil
|
return tx, context, statedb, release, nil
|
||||||
}
|
}
|
||||||
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee())
|
msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee(), rules)
|
||||||
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
if _, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil {
|
||||||
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,11 +125,11 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
|
||||||
if tracer.Hooks != nil {
|
if tracer.Hooks != nil {
|
||||||
logState = state.NewHookedState(st.StateDB, tracer.Hooks)
|
logState = state.NewHookedState(st.StateDB, tracer.Hooks)
|
||||||
}
|
}
|
||||||
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
|
evm := vm.NewEVM(context, logState, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
||||||
|
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee, evm.Rules())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, logState, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
|
||||||
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||||
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -201,20 +201,20 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) {
|
||||||
if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil {
|
if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil {
|
||||||
b.Fatalf("failed to parse testcase input: %v", err)
|
b.Fatalf("failed to parse testcase input: %v", err)
|
||||||
}
|
}
|
||||||
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
|
|
||||||
context := test.Context.toBlockContext(test.Genesis)
|
|
||||||
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
|
||||||
}
|
|
||||||
state := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
|
state := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme)
|
||||||
defer state.Close()
|
defer state.Close()
|
||||||
|
|
||||||
|
signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time))
|
||||||
|
context := test.Context.toBlockContext(test.Genesis)
|
||||||
|
evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{})
|
||||||
|
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee, evm.Rules())
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{})
|
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
snap := state.StateDB.Snapshot()
|
snap := state.StateDB.Snapshot()
|
||||||
tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil, test.Genesis.Config)
|
tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil, test.Genesis.Config)
|
||||||
|
|
@ -370,7 +370,7 @@ func TestInternals(t *testing.T) {
|
||||||
t.Fatalf("test %v: failed to sign transaction: %v", tc.name, err)
|
t.Fatalf("test %v: failed to sign transaction: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, logState, config, vm.Config{Tracer: tc.tracer.Hooks})
|
evm := vm.NewEVM(context, logState, config, vm.Config{Tracer: tc.tracer.Hooks})
|
||||||
msg, err := core.TransactionToMessage(tx, signer, big.NewInt(0))
|
msg, err := core.TransactionToMessage(tx, signer, big.NewInt(0), evm.Rules())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("test %v: failed to create message: %v", tc.name, err)
|
t.Fatalf("test %v: failed to create message: %v", tc.name, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,11 +107,11 @@ func flatCallTracerTestRunner(tracerName string, filename string, dirPath string
|
||||||
return fmt.Errorf("failed to create call tracer: %v", err)
|
return fmt.Errorf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
|
evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
||||||
|
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee, evm.Rules())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
|
return fmt.Errorf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
|
||||||
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||||
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,11 @@ func testPrestateTracer(tracerName string, dirPath string, t *testing.T) {
|
||||||
t.Fatalf("failed to create call tracer: %v", err)
|
t.Fatalf("failed to create call tracer: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
|
evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
||||||
|
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee, evm.Rules())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
|
||||||
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||||
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ func BenchmarkTransactionTraceV2(b *testing.B) {
|
||||||
|
|
||||||
evm := vm.NewEVM(context, state.StateDB, params.AllEthashProtocolChanges, vm.Config{})
|
evm := vm.NewEVM(context, state.StateDB, params.AllEthashProtocolChanges, vm.Config{})
|
||||||
|
|
||||||
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
|
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee, evm.Rules())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
b.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -695,7 +695,8 @@ func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *s
|
||||||
if err := args.CallDefaults(gp.Gas(), blockContext.BaseFee, b.ChainConfig().ChainID); err != nil {
|
if err := args.CallDefaults(gp.Gas(), blockContext.BaseFee, b.ChainConfig().ChainID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
msg := args.ToMessage(header.BaseFee, skipChecks, skipChecks)
|
rules := b.ChainConfig().Rules(header.Number, blockContext.Random != nil, header.Time)
|
||||||
|
msg := args.ToMessage(&rules, header.BaseFee, skipChecks, skipChecks)
|
||||||
// Lower the basefee to 0 to avoid breaking EVM
|
// Lower the basefee to 0 to avoid breaking EVM
|
||||||
// invariants (basefee < feecap).
|
// invariants (basefee < feecap).
|
||||||
if msg.GasPrice.Sign() == 0 {
|
if msg.GasPrice.Sign() == 0 {
|
||||||
|
|
@ -838,7 +839,8 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
|
||||||
if err := args.CallDefaults(gasCap, header.BaseFee, b.ChainConfig().ChainID); err != nil {
|
if err := args.CallDefaults(gasCap, header.BaseFee, b.ChainConfig().ChainID); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
call := args.ToMessage(header.BaseFee, true, true)
|
rules := b.ChainConfig().Rules(header.Number, header.Difficulty.Sign() == 0, header.Time)
|
||||||
|
call := args.ToMessage(&rules, header.BaseFee, true, true)
|
||||||
|
|
||||||
// Run the gas estimation and wrap any revertals into a custom return
|
// Run the gas estimation and wrap any revertals into a custom return
|
||||||
estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap)
|
estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap)
|
||||||
|
|
@ -1214,15 +1216,15 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH
|
||||||
|
|
||||||
// Copy the original db so we don't modify it
|
// Copy the original db so we don't modify it
|
||||||
statedb := db.Copy()
|
statedb := db.Copy()
|
||||||
// Set the accesslist to the last al
|
|
||||||
args.AccessList = &accessList
|
|
||||||
msg := args.ToMessage(header.BaseFee, true, true)
|
|
||||||
|
|
||||||
// Apply the transaction with the access list tracer
|
// Apply the transaction with the access list tracer
|
||||||
tracer := logger.NewAccessListTracer(accessList, addressesToExclude)
|
tracer := logger.NewAccessListTracer(accessList, addressesToExclude)
|
||||||
config := vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true}
|
config := vm.Config{Tracer: tracer.Hooks(), NoBaseFee: true}
|
||||||
evm := b.GetEVM(ctx, statedb, header, &config, nil)
|
evm := b.GetEVM(ctx, statedb, header, &config, nil)
|
||||||
|
|
||||||
|
// Set the accesslist to the last al
|
||||||
|
args.AccessList = &accessList
|
||||||
|
msg := args.ToMessage(evm.Rules(), header.BaseFee, true, true)
|
||||||
|
|
||||||
// Lower the basefee to 0 to avoid breaking EVM
|
// Lower the basefee to 0 to avoid breaking EVM
|
||||||
// invariants (basefee < feecap).
|
// invariants (basefee < feecap).
|
||||||
if msg.GasPrice.Sign() == 0 {
|
if msg.GasPrice.Sign() == 0 {
|
||||||
|
|
|
||||||
|
|
@ -259,12 +259,13 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
tracingStateDB = state.NewHookedState(sim.state, hooks)
|
tracingStateDB = state.NewHookedState(sim.state, hooks)
|
||||||
}
|
}
|
||||||
evm := vm.NewEVM(blockContext, tracingStateDB, sim.chainConfig, *vmConfig)
|
evm := vm.NewEVM(blockContext, tracingStateDB, sim.chainConfig, *vmConfig)
|
||||||
|
rules := evm.Rules()
|
||||||
// It is possible to override precompiles with EVM bytecode, or
|
// It is possible to override precompiles with EVM bytecode, or
|
||||||
// move them to another address.
|
// move them to another address.
|
||||||
if precompiles != nil {
|
if precompiles != nil {
|
||||||
evm.SetPrecompiles(precompiles)
|
evm.SetPrecompiles(precompiles)
|
||||||
}
|
}
|
||||||
if sim.chainConfig.IsPrague(header.Number, header.Time) || sim.chainConfig.IsVerkle(header.Number, header.Time) {
|
if rules.IsPrague || rules.IsVerkle {
|
||||||
core.ProcessParentBlockHash(header.ParentHash, evm)
|
core.ProcessParentBlockHash(header.ParentHash, evm)
|
||||||
}
|
}
|
||||||
if header.ParentBeaconRoot != nil {
|
if header.ParentBeaconRoot != nil {
|
||||||
|
|
@ -287,7 +288,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
||||||
tracer.reset(txHash, uint(i))
|
tracer.reset(txHash, uint(i))
|
||||||
sim.state.SetTxContext(txHash, i)
|
sim.state.SetTxContext(txHash, i)
|
||||||
// EoA check is always skipped, even in validation mode.
|
// EoA check is always skipped, even in validation mode.
|
||||||
msg := call.ToMessage(header.BaseFee, !sim.validate, true)
|
msg := call.ToMessage(rules, header.BaseFee, !sim.validate, true)
|
||||||
result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp)
|
result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
txErr := txValidationError(err)
|
txErr := txValidationError(err)
|
||||||
|
|
|
||||||
|
|
@ -414,7 +414,7 @@ func (args *TransactionArgs) CallDefaults(globalGasCap uint64, baseFee *big.Int,
|
||||||
// core evm. This method is used in calls and traces that do not require a real
|
// core evm. This method is used in calls and traces that do not require a real
|
||||||
// live transaction.
|
// live transaction.
|
||||||
// Assumes that fields are not nil, i.e. setDefaults or CallDefaults has been called.
|
// Assumes that fields are not nil, i.e. setDefaults or CallDefaults has been called.
|
||||||
func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck, skipEoACheck bool) *core.Message {
|
func (args *TransactionArgs) ToMessage(rules *params.Rules, baseFee *big.Int, skipNonceCheck, skipEoACheck bool) *core.Message {
|
||||||
var (
|
var (
|
||||||
gasPrice *big.Int
|
gasPrice *big.Int
|
||||||
gasFeeCap *big.Int
|
gasFeeCap *big.Int
|
||||||
|
|
@ -447,11 +447,25 @@ func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck, skipEoA
|
||||||
if args.AccessList != nil {
|
if args.AccessList != nil {
|
||||||
accessList = *args.AccessList
|
accessList = *args.AccessList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the intrinsic gas for stTransaction. Since the test file doesn't
|
||||||
|
// specify the transaction type we need to infer. This is hacky but we can use
|
||||||
|
// dynamic fee tx to represent all txs (with respect to instrinsic gas calc at
|
||||||
|
// least) types except the set code tx type.
|
||||||
|
var txdata types.TxData
|
||||||
|
if args.To == nil {
|
||||||
|
txdata = &types.DynamicFeeTx{To: args.To, Data: args.data(), AccessList: accessList}
|
||||||
|
} else {
|
||||||
|
txdata = &types.SetCodeTx{To: *args.To, Data: args.data(), AccessList: accessList, AuthList: args.AuthorizationList}
|
||||||
|
}
|
||||||
|
intrinsicGas := types.IntrinsicGas(txdata, rules)
|
||||||
|
|
||||||
return &core.Message{
|
return &core.Message{
|
||||||
From: args.from(),
|
From: args.from(),
|
||||||
To: args.To,
|
To: args.To,
|
||||||
Value: (*big.Int)(args.Value),
|
Value: (*big.Int)(args.Value),
|
||||||
Nonce: uint64(*args.Nonce),
|
Nonce: uint64(*args.Nonce),
|
||||||
|
IntrinsicGas: intrinsicGas,
|
||||||
GasLimit: uint64(*args.Gas),
|
GasLimit: uint64(*args.Gas),
|
||||||
GasPrice: gasPrice,
|
GasPrice: gasPrice,
|
||||||
GasFeeCap: gasFeeCap,
|
GasFeeCap: gasFeeCap,
|
||||||
|
|
|
||||||
|
|
@ -271,7 +271,7 @@ func runBenchmark(b *testing.B, t *StateTest) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
post := t.json.Post[subtest.Fork][subtest.Index]
|
post := t.json.Post[subtest.Fork][subtest.Index]
|
||||||
msg, err := t.json.Tx.toMessage(post, baseFee)
|
msg, err := t.json.Tx.toMessage(post, baseFee, &rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Error(err)
|
b.Error(err)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
||||||
return st, common.Hash{}, 0, UnsupportedForkError{subtest.Fork}
|
return st, common.Hash{}, 0, UnsupportedForkError{subtest.Fork}
|
||||||
}
|
}
|
||||||
vmconfig.ExtraEips = eips
|
vmconfig.ExtraEips = eips
|
||||||
|
rules := config.Rules(new(big.Int).SetUint64(t.json.Env.Number), t.json.Env.Random != nil, t.json.Env.Timestamp)
|
||||||
|
|
||||||
block := t.genesis(config).ToBlock()
|
block := t.genesis(config).ToBlock()
|
||||||
st = MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter, scheme)
|
st = MakePreState(rawdb.NewMemoryDatabase(), t.json.Pre, snapshotter, scheme)
|
||||||
|
|
@ -271,7 +272,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
post := t.json.Post[subtest.Fork][subtest.Index]
|
post := t.json.Post[subtest.Fork][subtest.Index]
|
||||||
msg, err := t.json.Tx.toMessage(post, baseFee)
|
msg, err := t.json.Tx.toMessage(post, baseFee, &rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return st, common.Hash{}, 0, err
|
return st, common.Hash{}, 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -376,7 +377,7 @@ func (t *StateTest) genesis(config *params.ChainConfig) *core.Genesis {
|
||||||
return genesis
|
return genesis
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Message, error) {
|
func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int, rules *params.Rules) (*core.Message, error) {
|
||||||
var from common.Address
|
var from common.Address
|
||||||
// If 'sender' field is present, use that
|
// If 'sender' field is present, use that
|
||||||
if tx.Sender != nil {
|
if tx.Sender != nil {
|
||||||
|
|
@ -463,11 +464,24 @@ func (tx *stTransaction) toMessage(ps stPostState, baseFee *big.Int) (*core.Mess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute the intrinsic gas for stTransaction. Since the test file doesn't
|
||||||
|
// specify the transaction type we need to infer. This is hacky but we can use
|
||||||
|
// dynamic fee tx to represent all txs (with respect to instrinsic gas calc at
|
||||||
|
// least) types except the set code tx type.
|
||||||
|
var txdata types.TxData
|
||||||
|
if to == nil {
|
||||||
|
txdata = &types.DynamicFeeTx{To: to, Data: data, AccessList: accessList}
|
||||||
|
} else {
|
||||||
|
txdata = &types.SetCodeTx{To: *to, Data: data, AccessList: accessList, AuthList: authList}
|
||||||
|
}
|
||||||
|
gas := types.IntrinsicGas(txdata, rules)
|
||||||
|
|
||||||
msg := &core.Message{
|
msg := &core.Message{
|
||||||
From: from,
|
From: from,
|
||||||
To: to,
|
To: to,
|
||||||
Nonce: tx.Nonce,
|
Nonce: tx.Nonce,
|
||||||
Value: value,
|
Value: value,
|
||||||
|
IntrinsicGas: gas,
|
||||||
GasLimit: gasLimit,
|
GasLimit: gasLimit,
|
||||||
GasPrice: gasPrice,
|
GasPrice: gasPrice,
|
||||||
GasFeeCap: tx.MaxFeePerGas,
|
GasFeeCap: tx.MaxFeePerGas,
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ func (tt *TransactionTest) Run() error {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Intrinsic gas
|
// Intrinsic gas
|
||||||
requiredGas, err = core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, rules.IsHomestead, rules.IsIstanbul, rules.IsShanghai)
|
requiredGas, err = tx.IntrinsicGas(rules)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue