mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
core/state, core/vm, eth/tracers: move state log mechanisms to separate layer
core/state: wip move state log mechanism in to a separate layer core/state: fix tests core/state: fix miscalc in OnBalanceChange eth/tracers: fix tests core/state: re-enable verkle witness generation internal/ethapi: fix simulation + new logging schema
This commit is contained in:
parent
3ff73d46b3
commit
ccaab0ae10
21 changed files with 266 additions and 108 deletions
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
|
|
@ -349,7 +350,7 @@ func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.H
|
|||
}
|
||||
|
||||
// Finalize implements consensus.Engine and processes withdrawals on top.
|
||||
func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body) {
|
||||
func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, body *types.Body) {
|
||||
if !beacon.IsPoSHeader(header) {
|
||||
beacon.ethone.Finalize(chain, header, state, body)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
|
@ -580,7 +581,7 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header
|
|||
|
||||
// Finalize implements consensus.Engine. There is no post-transaction
|
||||
// consensus rules in clique, do nothing here.
|
||||
func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body) {
|
||||
func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, body *types.Body) {
|
||||
// No block rewards in PoA, so the state remains as is
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
|
@ -88,7 +89,7 @@ type Engine interface {
|
|||
//
|
||||
// Note: The state database might be updated to reflect any consensus rules
|
||||
// that happen at finalization (e.g. block rewards).
|
||||
Finalize(chain ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body)
|
||||
Finalize(chain ChainHeaderReader, header *types.Header, state vm.StateDB, body *types.Body)
|
||||
|
||||
// FinalizeAndAssemble runs any post-transaction state modifications (e.g. block
|
||||
// rewards or process withdrawals) and assembles the final block.
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
|
|
@ -502,7 +503,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H
|
|||
}
|
||||
|
||||
// Finalize implements consensus.Engine, accumulating the block and uncle rewards.
|
||||
func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, body *types.Body) {
|
||||
func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state vm.StateDB, body *types.Body) {
|
||||
// Accumulate any block and uncle rewards
|
||||
accumulateRewards(chain.Config(), state, header, body.Uncles)
|
||||
}
|
||||
|
|
@ -565,7 +566,7 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
|
|||
// accumulateRewards credits the coinbase of the given block with the mining
|
||||
// reward. The total reward consists of the static block reward and rewards for
|
||||
// included uncles. The coinbase of each uncle block is also rewarded.
|
||||
func accumulateRewards(config *params.ChainConfig, stateDB *state.StateDB, header *types.Header, uncles []*types.Header) {
|
||||
func accumulateRewards(config *params.ChainConfig, stateDB vm.StateDB, header *types.Header, uncles []*types.Header) {
|
||||
// Select the correct block reward based on chain progression
|
||||
blockReward := FrontierBlockReward
|
||||
if config.IsByzantium(header.Number) {
|
||||
|
|
|
|||
|
|
@ -21,11 +21,10 @@ import (
|
|||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -74,7 +73,7 @@ func VerifyDAOHeaderExtraData(config *params.ChainConfig, header *types.Header)
|
|||
// ApplyDAOHardFork modifies the state database according to the DAO hard-fork
|
||||
// rules, transferring all balances of a set of DAO accounts to a single refund
|
||||
// contract.
|
||||
func ApplyDAOHardFork(statedb *state.StateDB) {
|
||||
func ApplyDAOHardFork(statedb vm.StateDB) {
|
||||
// Retrieve the contract to refund balances into
|
||||
if !statedb.Exist(params.DAORefundContract) {
|
||||
statedb.CreateAccount(params.DAORefundContract)
|
||||
|
|
@ -82,7 +81,8 @@ func ApplyDAOHardFork(statedb *state.StateDB) {
|
|||
|
||||
// Move every DAO account and extra-balance account funds into the refund contract
|
||||
for _, addr := range params.DAODrainList() {
|
||||
statedb.AddBalance(params.DAORefundContract, statedb.GetBalance(addr), tracing.BalanceIncreaseDaoContract)
|
||||
statedb.SetBalance(addr, new(uint256.Int), tracing.BalanceDecreaseDaoAccount)
|
||||
balance := statedb.GetBalance(addr)
|
||||
statedb.AddBalance(params.DAORefundContract, balance, tracing.BalanceIncreaseDaoContract)
|
||||
statedb.SubBalance(addr, balance, tracing.BalanceDecreaseDaoAccount)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1893,10 +1893,13 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s
|
|||
bc.logger.OnBlockEnd(blockEndErr)
|
||||
}()
|
||||
}
|
||||
|
||||
var wStateDb = vm.StateDB(statedb)
|
||||
if w := statedb.Wrapped(); w != nil {
|
||||
wStateDb = w
|
||||
}
|
||||
// Process block using the parent state as reference point
|
||||
pstart := time.Now()
|
||||
res, err := bc.processor.Process(block, statedb, bc.vmConfig)
|
||||
res, err := bc.processor.Process(block, wStateDb, bc.vmConfig)
|
||||
if err != nil {
|
||||
bc.reportBlock(block, res, err)
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
|
@ -208,19 +207,18 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
|
|||
}
|
||||
|
||||
// SetState updates a value in account storage.
|
||||
func (s *stateObject) SetState(key, value common.Hash) {
|
||||
// It returns the previous value
|
||||
func (s *stateObject) SetState(key, value common.Hash) common.Hash {
|
||||
// If the new value is the same as old, don't set. Otherwise, track only the
|
||||
// dirty changes, supporting reverting all of it back to no change.
|
||||
prev, origin := s.getState(key)
|
||||
if prev == value {
|
||||
return
|
||||
return prev
|
||||
}
|
||||
// New value is different, update and journal the change
|
||||
s.db.journal.storageChange(s.address, key, prev, origin)
|
||||
s.setState(key, value, origin)
|
||||
if s.db.logger != nil && s.db.logger.OnStorageChange != nil {
|
||||
s.db.logger.OnStorageChange(s.address, key, prev, value)
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
// setState updates a value in account dirty storage. The dirtiness will be
|
||||
|
|
@ -448,33 +446,25 @@ func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) {
|
|||
|
||||
// AddBalance adds amount to s's balance.
|
||||
// It is used to add funds to the destination account of a transfer.
|
||||
func (s *stateObject) AddBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) {
|
||||
// returns the previous balance
|
||||
func (s *stateObject) AddBalance(amount *uint256.Int) uint256.Int {
|
||||
// EIP161: We must check emptiness for the objects such that the account
|
||||
// clearing (0,0,0 objects) can take effect.
|
||||
if amount.IsZero() {
|
||||
if s.empty() {
|
||||
s.touch()
|
||||
}
|
||||
return
|
||||
return *(s.Balance())
|
||||
}
|
||||
s.SetBalance(new(uint256.Int).Add(s.Balance(), amount), reason)
|
||||
return s.SetBalance(new(uint256.Int).Add(s.Balance(), amount))
|
||||
}
|
||||
|
||||
// SubBalance removes amount from s's balance.
|
||||
// It is used to remove funds from the origin account of a transfer.
|
||||
func (s *stateObject) SubBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) {
|
||||
if amount.IsZero() {
|
||||
return
|
||||
}
|
||||
s.SetBalance(new(uint256.Int).Sub(s.Balance(), amount), reason)
|
||||
}
|
||||
|
||||
func (s *stateObject) SetBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) {
|
||||
// SetBalance sets the balance for the object, and returns the prevous balance
|
||||
func (s *stateObject) SetBalance(amount *uint256.Int) uint256.Int {
|
||||
prev := *s.data.Balance
|
||||
s.db.journal.balanceChange(s.address, s.data.Balance)
|
||||
if s.db.logger != nil && s.db.logger.OnBalanceChange != nil {
|
||||
s.db.logger.OnBalanceChange(s.address, s.Balance().ToBig(), amount.ToBig(), reason)
|
||||
}
|
||||
s.setBalance(amount)
|
||||
return prev
|
||||
}
|
||||
|
||||
func (s *stateObject) setBalance(amount *uint256.Int) {
|
||||
|
|
@ -547,10 +537,6 @@ func (s *stateObject) CodeSize() int {
|
|||
|
||||
func (s *stateObject) SetCode(codeHash common.Hash, code []byte) {
|
||||
s.db.journal.setCode(s.address)
|
||||
if s.db.logger != nil && s.db.logger.OnCodeChange != nil {
|
||||
// TODO remove prevcode from this callback
|
||||
s.db.logger.OnCodeChange(s.address, common.BytesToHash(s.CodeHash()), nil, codeHash, code)
|
||||
}
|
||||
s.setCode(codeHash, code)
|
||||
}
|
||||
|
||||
|
|
@ -562,9 +548,6 @@ func (s *stateObject) setCode(codeHash common.Hash, code []byte) {
|
|||
|
||||
func (s *stateObject) SetNonce(nonce uint64) {
|
||||
s.db.journal.nonceChange(s.address, s.data.Nonce)
|
||||
if s.db.logger != nil && s.db.logger.OnNonceChange != nil {
|
||||
s.db.logger.OnNonceChange(s.address, s.data.Nonce, nonce)
|
||||
}
|
||||
s.setNonce(nonce)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/triedb"
|
||||
|
|
@ -48,11 +47,11 @@ func TestDump(t *testing.T) {
|
|||
|
||||
// generate a few entries
|
||||
obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01}))
|
||||
obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified)
|
||||
obj1.AddBalance(uint256.NewInt(22))
|
||||
obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02}))
|
||||
obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3})
|
||||
obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02}))
|
||||
obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified)
|
||||
obj3.SetBalance(uint256.NewInt(44))
|
||||
|
||||
// write some of them to the trie
|
||||
s.state.updateStateObject(obj1)
|
||||
|
|
@ -106,13 +105,13 @@ func TestIterativeDump(t *testing.T) {
|
|||
|
||||
// generate a few entries
|
||||
obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01}))
|
||||
obj1.AddBalance(uint256.NewInt(22), tracing.BalanceChangeUnspecified)
|
||||
obj1.AddBalance(uint256.NewInt(22))
|
||||
obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02}))
|
||||
obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3})
|
||||
obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02}))
|
||||
obj3.SetBalance(uint256.NewInt(44), tracing.BalanceChangeUnspecified)
|
||||
obj3.SetBalance(uint256.NewInt(44))
|
||||
obj4 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x00}))
|
||||
obj4.AddBalance(uint256.NewInt(1337), tracing.BalanceChangeUnspecified)
|
||||
obj4.AddBalance(uint256.NewInt(1337))
|
||||
|
||||
// write some of them to the trie
|
||||
s.state.updateStateObject(obj1)
|
||||
|
|
@ -200,7 +199,7 @@ func TestCreateObjectRevert(t *testing.T) {
|
|||
|
||||
state.CreateAccount(addr)
|
||||
so0 := state.getStateObject(addr)
|
||||
so0.SetBalance(uint256.NewInt(42), tracing.BalanceChangeUnspecified)
|
||||
so0.SetBalance(uint256.NewInt(42))
|
||||
so0.SetNonce(43)
|
||||
so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'})
|
||||
state.setStateObject(so0)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"math/big"
|
||||
"slices"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
|
@ -82,8 +81,11 @@ type StateDB struct {
|
|||
db Database
|
||||
prefetcher *triePrefetcher
|
||||
trie Trie
|
||||
logger *tracing.Hooks
|
||||
reader Reader
|
||||
|
||||
onSelfDestructBurn func(common.Address, *uint256.Int)
|
||||
shim *stateDBLogger
|
||||
|
||||
reader Reader
|
||||
|
||||
// originalRoot is the pre-state root, before any changes were made.
|
||||
// It will be updated when the Commit is called.
|
||||
|
|
@ -190,9 +192,17 @@ func New(root common.Hash, db Database) (*StateDB, error) {
|
|||
return sdb, nil
|
||||
}
|
||||
|
||||
func (s *StateDB) SetBurnCallback(fn func(common.Address, *uint256.Int)) {
|
||||
s.onSelfDestructBurn = fn
|
||||
}
|
||||
|
||||
// SetLogger sets the logger for account update hooks.
|
||||
func (s *StateDB) SetLogger(l *tracing.Hooks) {
|
||||
s.logger = l
|
||||
s.shim = newStateDBLogger(s, l)
|
||||
}
|
||||
|
||||
func (s *StateDB) Wrapped() *stateDBLogger {
|
||||
return s.shim
|
||||
}
|
||||
|
||||
// StartPrefetcher initializes a new trie prefetcher to pull in nodes from the
|
||||
|
|
@ -248,9 +258,6 @@ func (s *StateDB) AddLog(log *types.Log) {
|
|||
log.TxHash = s.thash
|
||||
log.TxIndex = uint(s.txIndex)
|
||||
log.Index = s.logSize
|
||||
if s.logger != nil && s.logger.OnLog != nil {
|
||||
s.logger.OnLog(log)
|
||||
}
|
||||
s.logs[s.thash] = append(s.logs[s.thash], log)
|
||||
s.logSize++
|
||||
}
|
||||
|
|
@ -410,25 +417,32 @@ func (s *StateDB) HasSelfDestructed(addr common.Address) bool {
|
|||
*/
|
||||
|
||||
// AddBalance adds amount to the account associated with addr.
|
||||
func (s *StateDB) AddBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) {
|
||||
func (s *StateDB) AddBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) uint256.Int {
|
||||
stateObject := s.getOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.AddBalance(amount, reason)
|
||||
return stateObject.AddBalance(amount)
|
||||
}
|
||||
return uint256.Int{}
|
||||
}
|
||||
|
||||
// SubBalance subtracts amount from the account associated with addr.
|
||||
func (s *StateDB) SubBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) {
|
||||
func (s *StateDB) SubBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) uint256.Int {
|
||||
stateObject := s.getOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SubBalance(amount, reason)
|
||||
var prev uint256.Int
|
||||
if amount.IsZero() {
|
||||
return prev
|
||||
}
|
||||
if stateObject != nil {
|
||||
prev = *(stateObject.Balance())
|
||||
stateObject.SetBalance(new(uint256.Int).Sub(stateObject.Balance(), amount))
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
func (s *StateDB) SetBalance(addr common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) {
|
||||
stateObject := s.getOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetBalance(amount, reason)
|
||||
stateObject.SetBalance(amount)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -446,11 +460,11 @@ func (s *StateDB) SetCode(addr common.Address, code []byte) {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *StateDB) SetState(addr common.Address, key, value common.Hash) {
|
||||
stateObject := s.getOrNewStateObject(addr)
|
||||
if stateObject != nil {
|
||||
stateObject.SetState(key, value)
|
||||
func (s *StateDB) SetState(addr common.Address, key, value common.Hash) common.Hash {
|
||||
if stateObject := s.getOrNewStateObject(addr); stateObject != nil {
|
||||
return stateObject.SetState(key, value)
|
||||
}
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
// SetStorage replaces the entire storage for the specified account with given
|
||||
|
|
@ -478,7 +492,7 @@ func (s *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common
|
|||
if obj != nil {
|
||||
newObj.SetCode(common.BytesToHash(obj.CodeHash()), obj.code)
|
||||
newObj.SetNonce(obj.Nonce())
|
||||
newObj.SetBalance(obj.Balance(), tracing.BalanceChangeUnspecified)
|
||||
newObj.SetBalance(obj.Balance())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -487,15 +501,17 @@ func (s *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common
|
|||
//
|
||||
// The account's state object is still available until the state is committed,
|
||||
// getStateObject will return a non-nil account after SelfDestruct.
|
||||
func (s *StateDB) SelfDestruct(addr common.Address) {
|
||||
func (s *StateDB) SelfDestruct(addr common.Address) uint256.Int {
|
||||
stateObject := s.getStateObject(addr)
|
||||
var prevBalance uint256.Int
|
||||
if stateObject == nil {
|
||||
return
|
||||
return prevBalance
|
||||
}
|
||||
prevBalance = *(stateObject.Balance())
|
||||
// Regardless of whether it is already destructed or not, we do have to
|
||||
// journal the balance-change, if we set it to zero here.
|
||||
if !stateObject.Balance().IsZero() {
|
||||
stateObject.SetBalance(new(uint256.Int), tracing.BalanceDecreaseSelfdestruct)
|
||||
stateObject.SetBalance(new(uint256.Int))
|
||||
}
|
||||
// If it is already marked as self-destructed, we do not need to add it
|
||||
// for journalling a second time.
|
||||
|
|
@ -503,16 +519,18 @@ func (s *StateDB) SelfDestruct(addr common.Address) {
|
|||
s.journal.destruct(addr)
|
||||
stateObject.markSelfdestructed()
|
||||
}
|
||||
return prevBalance
|
||||
}
|
||||
|
||||
func (s *StateDB) Selfdestruct6780(addr common.Address) {
|
||||
func (s *StateDB) Selfdestruct6780(addr common.Address) uint256.Int {
|
||||
stateObject := s.getStateObject(addr)
|
||||
if stateObject == nil {
|
||||
return
|
||||
return uint256.Int{}
|
||||
}
|
||||
if stateObject.newContract {
|
||||
s.SelfDestruct(addr)
|
||||
return s.SelfDestruct(addr)
|
||||
}
|
||||
return *(stateObject.Balance())
|
||||
}
|
||||
|
||||
// SetTransientState sets transient storage for a given account. It
|
||||
|
|
@ -738,8 +756,8 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) {
|
|||
s.markDelete(addr)
|
||||
|
||||
// If ether was sent to account post-selfdestruct it is burnt.
|
||||
if bal := obj.Balance(); s.logger != nil && s.logger.OnBalanceChange != nil && obj.selfDestructed && bal.Sign() != 0 {
|
||||
s.logger.OnBalanceChange(obj.address, bal.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestructBurn)
|
||||
if bal := obj.Balance(); bal.Sign() != 0 && obj.selfDestructed && s.onSelfDestructBurn != nil {
|
||||
s.onSelfDestructBurn(obj.address, bal)
|
||||
}
|
||||
// We need to maintain account deletions explicitly (will remain
|
||||
// set indefinitely). Note only the first occurred self-destruct
|
||||
|
|
|
|||
104
core/state/statedb_logger.go
Normal file
104
core/state/statedb_logger.go
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2024 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package state
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
type stateDBLogger struct {
|
||||
*StateDB
|
||||
hooks *tracing.Hooks
|
||||
}
|
||||
|
||||
func newStateDBLogger(db *StateDB, hooks *tracing.Hooks) *stateDBLogger {
|
||||
s := &stateDBLogger{db, hooks}
|
||||
if s.hooks == nil {
|
||||
s.hooks = new(tracing.Hooks)
|
||||
}
|
||||
db.SetBurnCallback(func(address common.Address, amount *uint256.Int) {
|
||||
if s.hooks.OnBalanceChange != nil {
|
||||
s.hooks.OnBalanceChange(address, amount.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestructBurn)
|
||||
}
|
||||
})
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *stateDBLogger) AddBalance(address common.Address, amount *uint256.Int, reason tracing.BalanceChangeReason) uint256.Int {
|
||||
prev := s.StateDB.AddBalance(address, amount, reason)
|
||||
if s.hooks.OnBalanceChange != nil {
|
||||
newBalance := new(uint256.Int).Add(&prev, amount)
|
||||
s.hooks.OnBalanceChange(address, prev.ToBig(), newBalance.ToBig(), reason)
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
func (s *stateDBLogger) SetNonce(address common.Address, nonce uint64) {
|
||||
s.StateDB.SetNonce(address, nonce)
|
||||
if s.hooks.OnNonceChange != nil {
|
||||
s.hooks.OnNonceChange(address, nonce-1, nonce)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *stateDBLogger) SetCode(address common.Address, code []byte) {
|
||||
s.StateDB.SetCode(address, code)
|
||||
if s.hooks.OnCodeChange != nil {
|
||||
s.hooks.OnCodeChange(address, types.EmptyCodeHash, nil, crypto.Keccak256Hash(code), code)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *stateDBLogger) SetState(address common.Address, key common.Hash, value common.Hash) common.Hash {
|
||||
prev := s.StateDB.SetState(address, key, value)
|
||||
if s.hooks.OnStorageChange != nil && prev != value {
|
||||
s.hooks.OnStorageChange(address, key, prev, value)
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
func (s *stateDBLogger) SelfDestruct(address common.Address) uint256.Int {
|
||||
prev := s.StateDB.SelfDestruct(address)
|
||||
if !prev.IsZero() {
|
||||
if s.hooks.OnBalanceChange != nil {
|
||||
s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
|
||||
}
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
func (s *stateDBLogger) Selfdestruct6780(address common.Address) uint256.Int {
|
||||
prev := s.StateDB.Selfdestruct6780(address)
|
||||
if !prev.IsZero() {
|
||||
if s.hooks.OnBalanceChange != nil {
|
||||
s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
|
||||
}
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
func (s *stateDBLogger) AddLog(log *types.Log) {
|
||||
// The inner will modify the log (add fields), so invoke that first
|
||||
s.StateDB.AddLog(log)
|
||||
if s.hooks.OnLog != nil {
|
||||
s.hooks.OnLog(log)
|
||||
}
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ func TestCopy(t *testing.T) {
|
|||
|
||||
for i := byte(0); i < 255; i++ {
|
||||
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||
obj.AddBalance(uint256.NewInt(uint64(i)), tracing.BalanceChangeUnspecified)
|
||||
obj.AddBalance(uint256.NewInt(uint64(i)))
|
||||
orig.updateStateObject(obj)
|
||||
}
|
||||
orig.Finalise(false)
|
||||
|
|
@ -187,9 +187,9 @@ func TestCopy(t *testing.T) {
|
|||
copyObj := copy.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||
ccopyObj := ccopy.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||
|
||||
origObj.AddBalance(uint256.NewInt(2*uint64(i)), tracing.BalanceChangeUnspecified)
|
||||
copyObj.AddBalance(uint256.NewInt(3*uint64(i)), tracing.BalanceChangeUnspecified)
|
||||
ccopyObj.AddBalance(uint256.NewInt(4*uint64(i)), tracing.BalanceChangeUnspecified)
|
||||
origObj.AddBalance(uint256.NewInt(2 * uint64(i)))
|
||||
copyObj.AddBalance(uint256.NewInt(3 * uint64(i)))
|
||||
ccopyObj.AddBalance(uint256.NewInt(4 * uint64(i)))
|
||||
|
||||
orig.updateStateObject(origObj)
|
||||
copy.updateStateObject(copyObj)
|
||||
|
|
@ -236,7 +236,7 @@ func TestCopyWithDirtyJournal(t *testing.T) {
|
|||
// Fill up the initial states
|
||||
for i := byte(0); i < 255; i++ {
|
||||
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||
obj.AddBalance(uint256.NewInt(uint64(i)), tracing.BalanceChangeUnspecified)
|
||||
obj.AddBalance(uint256.NewInt(uint64(i)))
|
||||
obj.data.Root = common.HexToHash("0xdeadbeef")
|
||||
orig.updateStateObject(obj)
|
||||
}
|
||||
|
|
@ -246,7 +246,9 @@ func TestCopyWithDirtyJournal(t *testing.T) {
|
|||
// modify all in memory without finalizing
|
||||
for i := byte(0); i < 255; i++ {
|
||||
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||
obj.SubBalance(uint256.NewInt(uint64(i)), tracing.BalanceChangeUnspecified)
|
||||
amount := uint256.NewInt(uint64(i))
|
||||
obj.SetBalance(new(uint256.Int).Sub(obj.Balance(), amount))
|
||||
|
||||
orig.updateStateObject(obj)
|
||||
}
|
||||
cpy := orig.Copy()
|
||||
|
|
@ -280,7 +282,7 @@ func TestCopyObjectState(t *testing.T) {
|
|||
// Fill up the initial states
|
||||
for i := byte(0); i < 5; i++ {
|
||||
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||
obj.AddBalance(uint256.NewInt(uint64(i)), tracing.BalanceChangeUnspecified)
|
||||
obj.AddBalance(uint256.NewInt(uint64(i)))
|
||||
obj.data.Root = common.HexToHash("0xdeadbeef")
|
||||
orig.updateStateObject(obj)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
|
|
@ -62,7 +61,7 @@ func makeTestState(scheme string) (ethdb.Database, Database, *triedb.Database, c
|
|||
obj := state.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||
acc := &testAccount{address: common.BytesToAddress([]byte{i})}
|
||||
|
||||
obj.AddBalance(uint256.NewInt(uint64(11*i)), tracing.BalanceChangeUnspecified)
|
||||
obj.AddBalance(uint256.NewInt(uint64(11 * i)))
|
||||
acc.balance = uint256.NewInt(uint64(11 * i))
|
||||
|
||||
obj.SetNonce(uint64(42 * i))
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/misc"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
|
|
@ -53,7 +52,7 @@ func NewStateProcessor(config *params.ChainConfig, chain *HeaderChain) *StatePro
|
|||
// Process returns the receipts and logs accumulated during the process and
|
||||
// returns the amount of gas that was used in the process. If any of the
|
||||
// transactions failed to execute due to insufficient gas it will return an error.
|
||||
func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResult, error) {
|
||||
func (p *StateProcessor) Process(block *types.Block, statedb vm.StateDB, cfg vm.Config) (*ProcessResult, error) {
|
||||
var (
|
||||
receipts types.Receipts
|
||||
usedGas = new(uint64)
|
||||
|
|
@ -75,6 +74,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
|
||||
// Apply pre-execution system calls.
|
||||
context = NewEVMBlockContext(header, p.chain, nil)
|
||||
|
||||
vmenv := vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg)
|
||||
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||
ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb)
|
||||
|
|
@ -130,7 +130,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
// ApplyTransactionWithEVM attempts to apply a transaction to the given state database
|
||||
// and uses the input parameters for its environment similar to ApplyTransaction. However,
|
||||
// this method takes an already created EVM instance as input.
|
||||
func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPool, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (receipt *types.Receipt, err error) {
|
||||
func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPool, statedb vm.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas *uint64, evm *vm.EVM) (receipt *types.Receipt, err error) {
|
||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxStart != nil {
|
||||
evm.Config.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||
if evm.Config.Tracer.OnTxEnd != nil {
|
||||
|
|
@ -139,6 +139,7 @@ func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPo
|
|||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new context to be used in the EVM environment.
|
||||
txContext := NewEVMTxContext(msg)
|
||||
evm.Reset(txContext, statedb)
|
||||
|
|
@ -162,7 +163,7 @@ func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPo
|
|||
}
|
||||
|
||||
// MakeReceipt generates the receipt object for a transaction given its execution result.
|
||||
func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas uint64, root []byte) *types.Receipt {
|
||||
func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb vm.StateDB, blockNumber *big.Int, blockHash common.Hash, tx *types.Transaction, usedGas uint64, root []byte) *types.Receipt {
|
||||
// Create a new receipt for the transaction, storing the intermediate root and gas used
|
||||
// by the tx.
|
||||
receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: usedGas}
|
||||
|
|
@ -203,7 +204,7 @@ func MakeReceipt(evm *vm.EVM, result *ExecutionResult, statedb *state.StateDB, b
|
|||
// and uses the input parameters for its environment. It returns the receipt
|
||||
// for the transaction, gas used and an error if the transaction failed,
|
||||
// indicating the block was invalid.
|
||||
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
|
||||
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb vm.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
|
||||
msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -217,7 +218,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
|||
|
||||
// ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root
|
||||
// contract. This method is exported to be used in tests.
|
||||
func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *state.StateDB) {
|
||||
func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb vm.StateDB) {
|
||||
if tracer := vmenv.Config.Tracer; tracer != nil {
|
||||
if tracer.OnSystemCallStart != nil {
|
||||
tracer.OnSystemCallStart()
|
||||
|
|
@ -243,7 +244,7 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *stat
|
|||
|
||||
// ProcessParentBlockHash stores the parent block hash in the history storage contract
|
||||
// as per EIP-2935.
|
||||
func ProcessParentBlockHash(prevHash common.Hash, vmenv *vm.EVM, statedb *state.StateDB) {
|
||||
func ProcessParentBlockHash(prevHash common.Hash, vmenv *vm.EVM, statedb vm.StateDB) {
|
||||
if tracer := vmenv.Config.Tracer; tracer != nil {
|
||||
if tracer.OnSystemCallStart != nil {
|
||||
tracer.OnSystemCallStart()
|
||||
|
|
@ -269,17 +270,17 @@ func ProcessParentBlockHash(prevHash common.Hash, vmenv *vm.EVM, statedb *state.
|
|||
|
||||
// ProcessWithdrawalQueue calls the EIP-7002 withdrawal queue contract.
|
||||
// It returns the opaque request data returned by the contract.
|
||||
func ProcessWithdrawalQueue(vmenv *vm.EVM, statedb *state.StateDB) []byte {
|
||||
func ProcessWithdrawalQueue(vmenv *vm.EVM, statedb vm.StateDB) []byte {
|
||||
return processRequestsSystemCall(vmenv, statedb, 0x01, params.WithdrawalQueueAddress)
|
||||
}
|
||||
|
||||
// ProcessConsolidationQueue calls the EIP-7251 consolidation queue contract.
|
||||
// It returns the opaque request data returned by the contract.
|
||||
func ProcessConsolidationQueue(vmenv *vm.EVM, statedb *state.StateDB) []byte {
|
||||
func ProcessConsolidationQueue(vmenv *vm.EVM, statedb vm.StateDB) []byte {
|
||||
return processRequestsSystemCall(vmenv, statedb, 0x02, params.ConsolidationQueueAddress)
|
||||
}
|
||||
|
||||
func processRequestsSystemCall(vmenv *vm.EVM, statedb *state.StateDB, requestType byte, addr common.Address) []byte {
|
||||
func processRequestsSystemCall(vmenv *vm.EVM, statedb vm.StateDB, requestType byte, addr common.Address) []byte {
|
||||
if tracer := vmenv.Config.Tracer; tracer != nil {
|
||||
if tracer.OnSystemCallStart != nil {
|
||||
tracer.OnSystemCallStart()
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ type Processor interface {
|
|||
// Process processes the state changes according to the Ethereum rules by running
|
||||
// the transaction messages using the statedb and applying any rewards to both
|
||||
// the processor (coinbase) and any included uncles.
|
||||
Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResult, error)
|
||||
Process(block *types.Block, statedb vm.StateDB, cfg vm.Config) (*ProcessResult, error)
|
||||
}
|
||||
|
||||
// ProcessResult contains the values computed by Process.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/stateless"
|
||||
"github.com/ethereum/go-ethereum/core/tracing"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
|
@ -33,8 +34,8 @@ type StateDB interface {
|
|||
CreateAccount(common.Address)
|
||||
CreateContract(common.Address)
|
||||
|
||||
SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason)
|
||||
AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason)
|
||||
SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) uint256.Int
|
||||
AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) uint256.Int
|
||||
GetBalance(common.Address) *uint256.Int
|
||||
|
||||
GetNonce(common.Address) uint64
|
||||
|
|
@ -51,16 +52,16 @@ type StateDB interface {
|
|||
|
||||
GetCommittedState(common.Address, common.Hash) common.Hash
|
||||
GetState(common.Address, common.Hash) common.Hash
|
||||
SetState(common.Address, common.Hash, common.Hash)
|
||||
SetState(common.Address, common.Hash, common.Hash) common.Hash
|
||||
GetStorageRoot(addr common.Address) common.Hash
|
||||
|
||||
GetTransientState(addr common.Address, key common.Hash) common.Hash
|
||||
SetTransientState(addr common.Address, key, value common.Hash)
|
||||
|
||||
SelfDestruct(common.Address)
|
||||
SelfDestruct(common.Address) uint256.Int
|
||||
HasSelfDestructed(common.Address) bool
|
||||
|
||||
Selfdestruct6780(common.Address)
|
||||
Selfdestruct6780(common.Address) uint256.Int
|
||||
|
||||
// Exist reports whether the given account exists in state.
|
||||
// Notably this should also return true for self-destructed accounts.
|
||||
|
|
@ -90,6 +91,32 @@ type StateDB interface {
|
|||
AddPreimage(common.Hash, []byte)
|
||||
|
||||
Witness() *stateless.Witness
|
||||
Finalise(bool)
|
||||
// IntermediateRoot computes the current root hash of the state trie.
|
||||
// It is called in
|
||||
// - between transactions (pre-byzantium)
|
||||
// - nowadays only after all transactions,
|
||||
// in order to obtain the state root hash .
|
||||
IntermediateRoot(deleteEmptyObjects bool) common.Hash
|
||||
|
||||
// GetLogs returns the logs matching the specified transaction hash, and annotates
|
||||
// them with the given blockNumber and blockHash.
|
||||
GetLogs(txHash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log
|
||||
// TxIndex returns the current transaction index set by SetTxContext.
|
||||
TxIndex() int
|
||||
|
||||
// SetTxContext sets the current transaction hash and index which are
|
||||
// used when the EVM emits new state logs. It should be invoked before
|
||||
// transaction execution.
|
||||
SetTxContext(txHash common.Hash, txIndex int)
|
||||
|
||||
// GetTrie returns the account trie. Verkle-related
|
||||
GetTrie() state.Trie
|
||||
// AccessEvents returns the access-events collected for verkle-witness processing.
|
||||
AccessEvents() *state.AccessEvents
|
||||
|
||||
// Error returns any memorized database failure occurred previously.
|
||||
Error() error
|
||||
}
|
||||
|
||||
// CallContext provides a basic interface for the EVM calling conventions. The EVM
|
||||
|
|
|
|||
|
|
@ -126,11 +126,15 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) {
|
|||
}
|
||||
|
||||
state.StateDB.SetLogger(tracer.Hooks)
|
||||
logState := vm.StateDB(state.StateDB.Wrapped())
|
||||
if logState == nil {
|
||||
logState = state.StateDB
|
||||
}
|
||||
msg, err := core.TransactionToMessage(tx, signer, context.BaseFee)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to prepare transaction for tracing: %v", err)
|
||||
}
|
||||
evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
||||
evm := vm.NewEVM(context, core.NewEVMTxContext(msg), logState, test.Genesis.Config, vm.Config{Tracer: tracer.Hooks})
|
||||
tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
|
||||
vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas()))
|
||||
if err != nil {
|
||||
|
|
@ -360,6 +364,12 @@ func TestInternals(t *testing.T) {
|
|||
}, false, rawdb.HashScheme)
|
||||
defer state.Close()
|
||||
state.StateDB.SetLogger(tc.tracer.Hooks)
|
||||
|
||||
logState := vm.StateDB(state.StateDB.Wrapped())
|
||||
if logState == nil {
|
||||
logState = state.StateDB
|
||||
}
|
||||
|
||||
tx, err := types.SignNewTx(key, signer, &types.LegacyTx{
|
||||
To: &to,
|
||||
Value: big.NewInt(0),
|
||||
|
|
@ -373,7 +383,7 @@ func TestInternals(t *testing.T) {
|
|||
Origin: origin,
|
||||
GasPrice: tx.GasPrice(),
|
||||
}
|
||||
evm := vm.NewEVM(context, txContext, state.StateDB, config, vm.Config{Tracer: tc.tracer.Hooks})
|
||||
evm := vm.NewEVM(context, txContext, logState, config, vm.Config{Tracer: tc.tracer.Hooks})
|
||||
msg, err := core.TransactionToMessage(tx, signer, big.NewInt(0))
|
||||
if err != nil {
|
||||
t.Fatalf("test %v: failed to create message: %v", tc.name, err)
|
||||
|
|
|
|||
|
|
@ -597,6 +597,7 @@ func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockG
|
|||
}
|
||||
|
||||
func compareAsJSON(t *testing.T, expected interface{}, actual interface{}) {
|
||||
t.Helper()
|
||||
want, err := json.Marshal(expected)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal expected value to JSON: %v", err)
|
||||
|
|
@ -608,6 +609,6 @@ func compareAsJSON(t *testing.T, expected interface{}, actual interface{}) {
|
|||
}
|
||||
|
||||
if !bytes.Equal(want, have) {
|
||||
t.Fatalf("incorrect supply info: expected %s, got %s", string(want), string(have))
|
||||
t.Fatalf("incorrect supply info:\nwant %s\nhave %s", string(want), string(have))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,9 +49,11 @@ type dummyStatedb struct {
|
|||
state.StateDB
|
||||
}
|
||||
|
||||
func (*dummyStatedb) GetRefund() uint64 { return 1337 }
|
||||
func (*dummyStatedb) GetState(_ common.Address, _ common.Hash) common.Hash { return common.Hash{} }
|
||||
func (*dummyStatedb) SetState(_ common.Address, _ common.Hash, _ common.Hash) {}
|
||||
func (*dummyStatedb) GetRefund() uint64 { return 1337 }
|
||||
func (*dummyStatedb) GetState(_ common.Address, _ common.Hash) common.Hash { return common.Hash{} }
|
||||
func (*dummyStatedb) SetState(_ common.Address, _ common.Hash, _ common.Hash) common.Hash {
|
||||
return common.Hash{}
|
||||
}
|
||||
|
||||
func TestStoreCapture(t *testing.T) {
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -1212,7 +1212,7 @@ func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *s
|
|||
return applyMessageWithEVM(ctx, evm, msg, state, timeout, gp)
|
||||
}
|
||||
|
||||
func applyMessageWithEVM(ctx context.Context, evm *vm.EVM, msg *core.Message, state *state.StateDB, timeout time.Duration, gp *core.GasPool) (*core.ExecutionResult, error) {
|
||||
func applyMessageWithEVM(ctx context.Context, evm *vm.EVM, msg *core.Message, state vm.StateDB, timeout time.Duration, gp *core.GasPool) (*core.ExecutionResult, error) {
|
||||
// Wait for the context to be done and cancel the evm. Even if the
|
||||
// EVM has finished, cancelling may be done (repeatedly)
|
||||
go func() {
|
||||
|
|
|
|||
|
|
@ -2192,6 +2192,7 @@ func TestSimulateV1(t *testing.T) {
|
|||
t.Fatalf("failed to unmarshal result: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(have, tc.want) {
|
||||
t.Log(string(resBytes))
|
||||
t.Errorf("test %s, result mismatch, have\n%v\n, want\n%v\n", tc.name, have, tc.want)
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -188,6 +188,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
|||
evm = vm.NewEVM(blockContext, vm.TxContext{GasPrice: new(big.Int)}, sim.state, sim.chainConfig, *vmConfig)
|
||||
)
|
||||
sim.state.SetLogger(tracer.Hooks())
|
||||
logState := vm.StateDB(sim.state.Wrapped())
|
||||
if logState == nil {
|
||||
logState = vm.StateDB(sim.state)
|
||||
}
|
||||
// It is possible to override precompiles with EVM bytecode, or
|
||||
// move them to another address.
|
||||
if precompiles != nil {
|
||||
|
|
@ -205,8 +209,8 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
|
|||
tracer.reset(tx.Hash(), uint(i))
|
||||
// EoA check is always skipped, even in validation mode.
|
||||
msg := call.ToMessage(header.BaseFee, !sim.validate, true)
|
||||
evm.Reset(core.NewEVMTxContext(msg), sim.state)
|
||||
result, err := applyMessageWithEVM(ctx, evm, msg, sim.state, timeout, sim.gp)
|
||||
evm.Reset(core.NewEVMTxContext(msg), logState)
|
||||
result, err := applyMessageWithEVM(ctx, evm, msg, logState, timeout, sim.gp)
|
||||
if err != nil {
|
||||
txErr := txValidationError(err)
|
||||
return nil, nil, txErr
|
||||
|
|
|
|||
Loading…
Reference in a new issue