mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
Backported commits from extended-tracer
-6c44a594f4-188cd4182e-f3c0a89b57-95b50299a5-2cc09548bb
This commit is contained in:
parent
7f8926e716
commit
9f71824d8c
5 changed files with 107 additions and 157 deletions
|
|
@ -190,9 +190,10 @@ func DefaultCacheConfigWithScheme(scheme string) *CacheConfig {
|
|||
type BlockchainLogger interface {
|
||||
vm.EVMLogger
|
||||
state.StateLogger
|
||||
OnBlockchainInit(chainConfig *params.ChainConfig)
|
||||
// OnBlockStart is called before executing `block`.
|
||||
// `td` is the total difficulty prior to `block`.
|
||||
OnBlockStart(block *types.Block, td *big.Int, finalized *types.Header, safe *types.Header, chainConfig *params.ChainConfig)
|
||||
OnBlockStart(block *types.Block, td *big.Int, finalized *types.Header, safe *types.Header)
|
||||
OnBlockEnd(err error)
|
||||
OnGenesisBlock(genesis *types.Block, alloc GenesisAlloc)
|
||||
OnBeaconBlockRootStart(root common.Hash)
|
||||
|
|
@ -501,6 +502,9 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
|||
}
|
||||
rawdb.WriteChainConfig(db, genesisHash, chainConfig)
|
||||
}
|
||||
if bc.logger != nil {
|
||||
bc.logger.OnBlockchainInit(chainConfig)
|
||||
}
|
||||
// Start tx indexer/unindexer if required.
|
||||
if txLookupLimit != nil {
|
||||
bc.txLookupLimit = *txLookupLimit
|
||||
|
|
@ -1804,7 +1808,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
|||
}
|
||||
stats.processed++
|
||||
if bc.logger != nil {
|
||||
bc.logger.OnBlockStart(block, bc.GetTd(block.ParentHash(), block.NumberU64()-1), bc.CurrentFinalBlock(), bc.CurrentSafeBlock(), bc.chainConfig)
|
||||
bc.logger.OnBlockStart(block, bc.GetTd(block.ParentHash(), block.NumberU64()-1), bc.CurrentFinalBlock(), bc.CurrentSafeBlock())
|
||||
bc.logger.OnBlockEnd(nil)
|
||||
}
|
||||
|
||||
|
|
@ -1933,7 +1937,7 @@ type blockProcessingResult struct {
|
|||
func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, start time.Time, setHead bool) (_ *blockProcessingResult, blockEndErr error) {
|
||||
if bc.logger != nil {
|
||||
td := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
|
||||
bc.logger.OnBlockStart(block, td, bc.CurrentFinalBlock(), bc.CurrentSafeBlock(), bc.chainConfig)
|
||||
bc.logger.OnBlockStart(block, td, bc.CurrentFinalBlock(), bc.CurrentSafeBlock())
|
||||
defer func() {
|
||||
bc.logger.OnBlockEnd(blockEndErr)
|
||||
}()
|
||||
|
|
|
|||
|
|
@ -124,9 +124,6 @@ type StateDB struct {
|
|||
// Preimages occurred seen by VM in the scope of block.
|
||||
preimages map[common.Hash][]byte
|
||||
|
||||
// Enabled precompile contracts
|
||||
precompiles map[common.Address]struct{}
|
||||
|
||||
// Per-transaction access list
|
||||
accessList *accessList
|
||||
|
||||
|
|
@ -183,7 +180,6 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
|
|||
stateObjectsDestruct: make(map[common.Address]*types.StateAccount),
|
||||
logs: make(map[common.Hash][]*types.Log),
|
||||
preimages: make(map[common.Hash][]byte),
|
||||
precompiles: make(map[common.Address]struct{}),
|
||||
journal: newJournal(),
|
||||
accessList: newAccessList(),
|
||||
transientStorage: newTransientStorage(),
|
||||
|
|
@ -667,11 +663,7 @@ func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject)
|
|||
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
|
||||
newobj = newObject(s, addr, nil)
|
||||
if s.logger != nil {
|
||||
// Precompiled contracts are touched during a call.
|
||||
// Make sure we avoid emitting a new account event for them.
|
||||
if _, ok := s.precompiles[addr]; !ok {
|
||||
s.logger.OnNewAccount(addr, prev != nil)
|
||||
}
|
||||
s.logger.OnNewAccount(addr, prev != nil)
|
||||
}
|
||||
if prev == nil {
|
||||
s.journal.append(createObjectChange{account: &addr})
|
||||
|
|
@ -883,7 +875,7 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) {
|
|||
obj.deleted = true
|
||||
|
||||
// If ether was sent to account post-selfdestruct it is burnt.
|
||||
if bal := obj.Balance(); bal.Sign() != 0 && s.logger != nil {
|
||||
if bal := obj.Balance(); s.logger != nil && obj.selfDestructed && bal.Sign() != 0 {
|
||||
s.logger.OnBalanceChange(obj.address, bal, new(big.Int), BalanceDecreaseSelfdestructBurn)
|
||||
}
|
||||
// We need to maintain account deletions explicitly (will remain
|
||||
|
|
@ -1391,14 +1383,6 @@ func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, d
|
|||
s.transientStorage = newTransientStorage()
|
||||
}
|
||||
|
||||
// PrepareBlock prepares the statedb for execution of a block. It tracks
|
||||
// the addresses of enabled precompiles for debugging purposes.
|
||||
func (s *StateDB) PrepareBlock(precompiles []common.Address) {
|
||||
for _, addr := range precompiles {
|
||||
s.precompiles[addr] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// AddAddressToAccessList adds the given address to the access list
|
||||
func (s *StateDB) AddAddressToAccessList(addr common.Address) {
|
||||
if s.accessList.AddAddress(addr) {
|
||||
|
|
|
|||
|
|
@ -75,13 +75,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
|||
var (
|
||||
context = NewEVMBlockContext(header, p.bc, nil)
|
||||
vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg)
|
||||
rules = vmenv.ChainConfig().Rules(context.BlockNumber, context.Random != nil, context.Time)
|
||||
signer = types.MakeSigner(p.config, header.Number, header.Time)
|
||||
)
|
||||
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||
ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb, p.bc.logger)
|
||||
}
|
||||
statedb.PrepareBlock(vm.ActivePrecompiles(rules))
|
||||
// Iterate over and process the individual transactions
|
||||
for i, tx := range block.Transactions() {
|
||||
msg, err := TransactionToMessage(tx, signer, header.BaseFee)
|
||||
|
|
|
|||
98
eth/tracers/live/noop.go
Normal file
98
eth/tracers/live/noop.go
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
package live
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"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/eth/tracers/directory"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
func init() {
|
||||
directory.LiveDirectory.Register("noop", newNoopTracer)
|
||||
}
|
||||
|
||||
// noop is a no-op live tracer. It's there to
|
||||
// catch changes in the tracing interface, as well as
|
||||
// for testing live tracing performance. Can be removed
|
||||
// as soon as we have a real live tracer.
|
||||
type noop struct{}
|
||||
|
||||
func newNoopTracer() (core.BlockchainLogger, error) {
|
||||
return &noop{}, nil
|
||||
}
|
||||
|
||||
// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
|
||||
func (t *noop) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
|
||||
}
|
||||
|
||||
// CaptureEnd is called after the call finishes to finalize the tracing.
|
||||
func (t *noop) CaptureEnd(output []byte, gasUsed uint64, err error, reverted bool) {
|
||||
}
|
||||
|
||||
// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
|
||||
func (t *noop) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
|
||||
}
|
||||
|
||||
// CaptureFault implements the EVMLogger interface to trace an execution fault.
|
||||
func (t *noop) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) {
|
||||
}
|
||||
|
||||
// CaptureKeccakPreimage is called during the KECCAK256 opcode.
|
||||
func (t *noop) CaptureKeccakPreimage(hash common.Hash, data []byte) {}
|
||||
|
||||
// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
|
||||
func (t *noop) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
|
||||
}
|
||||
|
||||
// CaptureExit is called when EVM exits a scope, even if the scope didn't
|
||||
// execute any code.
|
||||
func (t *noop) CaptureExit(output []byte, gasUsed uint64, err error, reverted bool) {
|
||||
}
|
||||
|
||||
func (t *noop) OnBeaconBlockRootStart(root common.Hash) {}
|
||||
func (t *noop) OnBeaconBlockRootEnd() {}
|
||||
|
||||
func (t *noop) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) {
|
||||
}
|
||||
|
||||
func (t *noop) CaptureTxEnd(receipt *types.Receipt, err error) {
|
||||
}
|
||||
|
||||
func (t *noop) OnBlockStart(b *types.Block, td *big.Int, finalized, safe *types.Header) {
|
||||
}
|
||||
|
||||
func (t *noop) OnBlockEnd(err error) {
|
||||
}
|
||||
|
||||
func (t *noop) OnBlockchainInit(chainConfig *params.ChainConfig) {
|
||||
}
|
||||
|
||||
func (t *noop) OnGenesisBlock(b *types.Block, alloc core.GenesisAlloc) {
|
||||
}
|
||||
|
||||
func (t *noop) OnBalanceChange(a common.Address, prev, new *big.Int, reason state.BalanceChangeReason) {
|
||||
}
|
||||
|
||||
func (t *noop) OnNonceChange(a common.Address, prev, new uint64) {
|
||||
}
|
||||
|
||||
func (t *noop) OnCodeChange(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte) {
|
||||
}
|
||||
|
||||
func (t *noop) OnStorageChange(a common.Address, k, prev, new common.Hash) {
|
||||
}
|
||||
|
||||
func (t *noop) OnLog(l *types.Log) {
|
||||
|
||||
}
|
||||
|
||||
func (t *noop) OnNewAccount(a common.Address, reset bool) {
|
||||
}
|
||||
|
||||
func (t *noop) OnGasChange(old, new uint64, reason vm.GasChangeReason) {
|
||||
}
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
package live
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"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/eth/tracers/directory"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
)
|
||||
|
||||
func init() {
|
||||
directory.LiveDirectory.Register("printer", newPrinter)
|
||||
}
|
||||
|
||||
type Printer struct{}
|
||||
|
||||
func newPrinter() (core.BlockchainLogger, error) {
|
||||
return &Printer{}, nil
|
||||
}
|
||||
|
||||
// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
|
||||
func (p *Printer) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
|
||||
fmt.Printf("CaptureStart: from=%v, to=%v, create=%v, input=%s, gas=%v, value=%v\n", from, to, create, hexutil.Bytes(input), gas, value)
|
||||
}
|
||||
|
||||
// CaptureEnd is called after the call finishes to finalize the tracing.
|
||||
func (p *Printer) CaptureEnd(output []byte, gasUsed uint64, err error, reverted bool) {
|
||||
fmt.Printf("CaptureEnd: output=%s, gasUsed=%v, err=%v\n", hexutil.Bytes(output), gasUsed, err)
|
||||
}
|
||||
|
||||
// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
|
||||
func (p *Printer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
|
||||
//fmt.Printf("CaptureState: pc=%v, op=%v, gas=%v, cost=%v, scope=%v, rData=%v, depth=%v, err=%v\n", pc, op, gas, cost, scope, rData, depth, err)
|
||||
}
|
||||
|
||||
// CaptureFault implements the EVMLogger interface to trace an execution fault.
|
||||
func (p *Printer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) {
|
||||
fmt.Printf("CaptureFault: pc=%v, op=%v, gas=%v, cost=%v, depth=%v, err=%v\n", pc, op, gas, cost, depth, err)
|
||||
}
|
||||
|
||||
// CaptureKeccakPreimage is called during the KECCAK256 opcode.
|
||||
func (p *Printer) CaptureKeccakPreimage(hash common.Hash, data []byte) {}
|
||||
|
||||
// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
|
||||
func (p *Printer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
|
||||
fmt.Printf("CaptureEnter: typ=%v, from=%v, to=%v, input=%s, gas=%v, value=%v\n", typ, from, to, hexutil.Bytes(input), gas, value)
|
||||
}
|
||||
|
||||
// CaptureExit is called when EVM exits a scope, even if the scope didn't
|
||||
// execute any code.
|
||||
func (p *Printer) CaptureExit(output []byte, gasUsed uint64, err error, reverted bool) {
|
||||
fmt.Printf("CaptureExit: output=%s, gasUsed=%v, err=%v\n", hexutil.Bytes(output), gasUsed, err)
|
||||
}
|
||||
|
||||
func (p *Printer) OnBeaconBlockRootStart(root common.Hash) {}
|
||||
func (p *Printer) OnBeaconBlockRootEnd() {}
|
||||
|
||||
func (p *Printer) CaptureTxStart(env *vm.EVM, tx *types.Transaction, from common.Address) {
|
||||
buf, err := json.Marshal(tx)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("CaptureTxStart: tx=%s\n", buf)
|
||||
}
|
||||
|
||||
func (p *Printer) CaptureTxEnd(receipt *types.Receipt, err error) {
|
||||
if err != nil {
|
||||
fmt.Printf("CaptureTxEnd err: %v\n", err)
|
||||
return
|
||||
}
|
||||
buf, err := json.Marshal(receipt)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("CaptureTxEnd: receipt=%s\n", buf)
|
||||
}
|
||||
|
||||
func (p *Printer) OnBlockStart(b *types.Block, td *big.Int, finalized, safe *types.Header, _ *params.ChainConfig) {
|
||||
if finalized != nil && safe != nil {
|
||||
fmt.Printf("OnBlockStart: b=%v, td=%v, finalized=%v, safe=%v\n", b.NumberU64(), td, finalized.Number.Uint64(), safe.Number.Uint64())
|
||||
} else {
|
||||
fmt.Printf("OnBlockStart: b=%v, td=%v\n", b.NumberU64(), td)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Printer) OnBlockEnd(err error) {
|
||||
fmt.Printf("OnBlockEnd: err=%v\n", err)
|
||||
}
|
||||
|
||||
func (p *Printer) OnGenesisBlock(b *types.Block, alloc core.GenesisAlloc) {
|
||||
fmt.Printf("OnGenesisBlock: b=%v, allocLength=%d\n", b.NumberU64(), len(alloc))
|
||||
}
|
||||
|
||||
func (p *Printer) OnBalanceChange(a common.Address, prev, new *big.Int, reason state.BalanceChangeReason) {
|
||||
fmt.Printf("OnBalanceChange: a=%v, prev=%v, new=%v\n", a, prev, new)
|
||||
}
|
||||
|
||||
func (p *Printer) OnNonceChange(a common.Address, prev, new uint64) {
|
||||
fmt.Printf("OnNonceChange: a=%v, prev=%v, new=%v\n", a, prev, new)
|
||||
}
|
||||
|
||||
func (p *Printer) OnCodeChange(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte) {
|
||||
fmt.Printf("OnCodeChange: a=%v, prevCodeHash=%v, prev=%s, codeHash=%v, code=%s\n", a, prevCodeHash, hexutil.Bytes(prev), codeHash, hexutil.Bytes(code))
|
||||
}
|
||||
|
||||
func (p *Printer) OnStorageChange(a common.Address, k, prev, new common.Hash) {
|
||||
fmt.Printf("OnStorageChange: a=%v, k=%v, prev=%v, new=%v\n", a, k, prev, new)
|
||||
}
|
||||
|
||||
func (p *Printer) OnLog(l *types.Log) {
|
||||
buf, err := json.Marshal(l)
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("OnLog: l=%s\n", buf)
|
||||
}
|
||||
|
||||
func (p *Printer) OnNewAccount(a common.Address, reset bool) {
|
||||
fmt.Printf("OnNewAccount: a=%v\n", a)
|
||||
}
|
||||
|
||||
func (p *Printer) OnGasChange(old, new uint64, reason vm.GasChangeReason) {
|
||||
fmt.Printf("OnGasChange: old=%v, new=%v, diff=%v\n", old, new, new-old)
|
||||
}
|
||||
Loading…
Reference in a new issue