core/state, core/tracing: add state read hooks

This commit is contained in:
Gary Rong 2025-10-09 15:09:08 +08:00 committed by Jared Wasinger
parent af34c01b90
commit 7410413eec
3 changed files with 51 additions and 6 deletions

View file

@ -53,22 +53,37 @@ func (s *hookedStateDB) CreateContract(addr common.Address) {
}
func (s *hookedStateDB) GetBalance(addr common.Address) *uint256.Int {
if s.hooks.OnAccountRead != nil {
s.hooks.OnAccountRead(addr)
}
return s.inner.GetBalance(addr)
}
func (s *hookedStateDB) GetNonce(addr common.Address) uint64 {
if s.hooks.OnAccountRead != nil {
s.hooks.OnAccountRead(addr)
}
return s.inner.GetNonce(addr)
}
func (s *hookedStateDB) GetCodeHash(addr common.Address) common.Hash {
if s.hooks.OnAccountRead != nil {
s.hooks.OnAccountRead(addr)
}
return s.inner.GetCodeHash(addr)
}
func (s *hookedStateDB) GetCode(addr common.Address) []byte {
if s.hooks.OnAccountRead != nil {
s.hooks.OnAccountRead(addr)
}
return s.inner.GetCode(addr)
}
func (s *hookedStateDB) GetCodeSize(addr common.Address) int {
if s.hooks.OnAccountRead != nil {
s.hooks.OnAccountRead(addr)
}
return s.inner.GetCodeSize(addr)
}
@ -85,14 +100,23 @@ func (s *hookedStateDB) GetRefund() uint64 {
}
func (s *hookedStateDB) GetStateAndCommittedState(addr common.Address, hash common.Hash) (common.Hash, common.Hash) {
if s.hooks.OnStorageRead != nil {
s.hooks.OnStorageRead(addr, hash)
}
return s.inner.GetStateAndCommittedState(addr, hash)
}
func (s *hookedStateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
if s.hooks.OnStorageRead != nil {
s.hooks.OnStorageRead(addr, hash)
}
return s.inner.GetState(addr, hash)
}
func (s *hookedStateDB) GetStorageRoot(addr common.Address) common.Hash {
if s.hooks.OnAccountRead != nil {
s.hooks.OnAccountRead(addr)
}
return s.inner.GetStorageRoot(addr)
}
@ -105,14 +129,23 @@ func (s *hookedStateDB) SetTransientState(addr common.Address, key, value common
}
func (s *hookedStateDB) HasSelfDestructed(addr common.Address) bool {
if s.hooks.OnAccountRead != nil {
s.hooks.OnAccountRead(addr)
}
return s.inner.HasSelfDestructed(addr)
}
func (s *hookedStateDB) Exist(addr common.Address) bool {
if s.hooks.OnAccountRead != nil {
s.hooks.OnAccountRead(addr)
}
return s.inner.Exist(addr)
}
func (s *hookedStateDB) Empty(addr common.Address) bool {
if s.hooks.OnAccountRead != nil {
s.hooks.OnAccountRead(addr)
}
return s.inner.Empty(addr)
}

View file

@ -194,6 +194,12 @@ type (
// LogHook is called when a log is emitted.
LogHook = func(log *types.Log)
// AccountReadHook is called when the account is accessed.
AccountReadHook = func(addr common.Address)
// StorageReadHook is called when the storage slot is accessed.
StorageReadHook = func(addr common.Address, slot common.Hash)
// BlockHashReadHook is called when EVM reads the blockhash of a block.
BlockHashReadHook = func(blockNumber uint64, hash common.Hash)
)
@ -222,7 +228,7 @@ type Hooks struct {
OnPreTxExecutionDone func() // called after pre-tx system contracts are invoked
OnBlockFinalization func() // called after post-tx system contracts and consensus finalization are invoked
// State events
// State mutation events
OnBalanceChange BalanceChangeHook
OnNonceChange NonceChangeHook
OnNonceChangeV2 NonceChangeHookV2
@ -231,9 +237,10 @@ type Hooks struct {
OnStorageChange StorageChangeHook
OnLog LogHook
OnSelfDestructChange SelfDestructHook
//State read events
OnColdStorageRead ColdStorageReadHook
OnColdAccountRead ColdAccountReadHook
// State access events
OnAccountRead AccountReadHook
OnStorageRead StorageReadHook
// Block hash read
OnBlockHashRead BlockHashReadHook

View file

@ -63,7 +63,7 @@ func (t *testTracer) OnCodeChangeV2(addr common.Address, prevCodeHash common.Has
}
func (t *testTracer) OnStorageChange(addr common.Address, slot common.Hash, prev common.Hash, new common.Hash) {
t.t.Logf("OnStorageCodeChange(%v, %v, %v -> %v)", addr, slot, prev, new)
t.t.Logf("OnStorageChange(%v, %v, %v -> %v)", addr, slot, prev, new)
if t.storage == nil {
t.storage = make(map[common.Hash]common.Hash)
}
@ -76,7 +76,12 @@ func (t *testTracer) OnStorageChange(addr common.Address, slot common.Hash, prev
func TestJournalIntegration(t *testing.T) {
tr := &testTracer{t: t}
wr, err := WrapWithJournal(&Hooks{OnBalanceChange: tr.OnBalanceChange, OnNonceChange: tr.OnNonceChange, OnCodeChange: tr.OnCodeChange, OnStorageChange: tr.OnStorageChange})
wr, err := WrapWithJournal(&Hooks{
OnBalanceChange: tr.OnBalanceChange,
OnNonceChange: tr.OnNonceChange,
OnCodeChange: tr.OnCodeChange,
OnStorageChange: tr.OnStorageChange,
})
if err != nil {
t.Fatalf("failed to wrap test tracer: %v", err)
}