core: track system contract executions separately

Extend the unique code execution tracking to distinguish between system
contract calls (EIP-4788 beacon root, EIP-2935 history storage, EIP-7002
withdrawal queue, EIP-7251 consolidation queue) and user contract calls.

The MarkCodeExecuted method now takes an isSystem parameter to track
system contracts separately. This is useful for understanding block
execution statistics, as system contracts are called automatically by
the protocol at the start of each block.

The slow block log now shows "Contracts executed: N (M system)" to
make it clear how many of the executed contracts were system calls.
This commit is contained in:
CPerezz 2026-01-04 00:36:38 +01:00
parent be2d43090c
commit b9a50aeadb
No known key found for this signature in database
GPG key ID: 62045F34B97177DD
6 changed files with 26 additions and 11 deletions

View file

@ -2192,6 +2192,7 @@ func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, s
stats.UniqueAccountsAccessed = statedb.UniqueAccountsAccessed()
stats.UniqueStorageAccessed = statedb.UniqueStorageAccessed()
stats.UniqueCodeExecuted = statedb.UniqueCodeExecuted()
stats.SystemCodeExecuted = statedb.SystemCodeExecuted()
stats.Execution = ptime - (statedb.AccountReads + statedb.StorageReads + statedb.CodeReads) // The time spent on EVM processing
stats.Validation = vtime - (statedb.AccountHashes + statedb.AccountUpdates + statedb.StorageUpdates) // The time spent on block validation

View file

@ -52,6 +52,7 @@ type ExecuteStats struct {
UniqueAccountsAccessed int // Number of unique accounts accessed
UniqueStorageAccessed int // Number of unique storage slots accessed
UniqueCodeExecuted int // Number of unique contracts executed
SystemCodeExecuted int // Number of unique system contracts executed (subset of UniqueCodeExecuted)
Execution time.Duration // Time spent on the EVM execution
Validation time.Duration // Time spent on the block validation
@ -132,7 +133,7 @@ State read: %v
Unique state access:
Accounts: %d
Storage slots: %d
Contracts executed: %d
Contracts executed: %d (%d system)
State hash: %v
Account hash: %v
@ -158,7 +159,7 @@ DB write: %v
// Unique state access
s.UniqueAccountsAccessed,
s.UniqueStorageAccessed,
s.UniqueCodeExecuted,
s.UniqueCodeExecuted, s.SystemCodeExecuted,
// State hash
common.PrettyDuration(s.AccountHashes+s.AccountUpdates+s.StorageUpdates+max(s.AccountCommits, s.StorageCommits)),

View file

@ -163,7 +163,8 @@ type StateDB struct {
CodeBytesRead int64 // Total bytes of contract code read during the state transition
// Unique contracts executed tracking (set of code hashes executed during the state transition)
executedCodes map[common.Hash]struct{}
executedCodes map[common.Hash]struct{}
systemExecutedCodes map[common.Hash]struct{} // Subset of executedCodes that are system calls
}
// New creates a new state from a given trie.
@ -191,6 +192,7 @@ func NewWithReader(root common.Hash, db Database, reader Reader) (*StateDB, erro
accessList: newAccessList(),
transientStorage: newTransientStorage(),
executedCodes: make(map[common.Hash]struct{}),
systemExecutedCodes: make(map[common.Hash]struct{}),
}
if db.TrieDB().IsVerkle() {
sdb.accessEvents = NewAccessEvents(db.PointCache())
@ -386,7 +388,8 @@ func (s *StateDB) GetCodeHash(addr common.Address) common.Hash {
// MarkCodeExecuted records that a contract's code was executed.
// This is used for metrics tracking to count unique contracts executed.
func (s *StateDB) MarkCodeExecuted(codeHash common.Hash) {
// The isSystem parameter indicates if this is a system call (e.g., EIP-4788 beacon root).
func (s *StateDB) MarkCodeExecuted(codeHash common.Hash, isSystem bool) {
if codeHash == types.EmptyCodeHash || codeHash == (common.Hash{}) {
return
}
@ -394,6 +397,9 @@ func (s *StateDB) MarkCodeExecuted(codeHash common.Hash) {
return // Skip tracking for state copies (e.g., prefetcher)
}
s.executedCodes[codeHash] = struct{}{}
if isSystem {
s.systemExecutedCodes[codeHash] = struct{}{}
}
}
// UniqueCodeExecuted returns the number of unique contract codes executed.
@ -401,6 +407,12 @@ func (s *StateDB) UniqueCodeExecuted() int {
return len(s.executedCodes)
}
// SystemCodeExecuted returns the number of unique system contract codes executed
// (e.g., EIP-4788 beacon root, EIP-2935 history storage, etc.).
func (s *StateDB) SystemCodeExecuted() int {
return len(s.systemExecutedCodes)
}
// UniqueAccountsAccessed returns the number of unique accounts accessed during the state transition.
func (s *StateDB) UniqueAccountsAccessed() int {
return len(s.stateObjects)

View file

@ -298,6 +298,6 @@ func (s *hookedStateDB) Inner() *StateDB {
}
// MarkCodeExecuted records that a contract's code was executed.
func (s *hookedStateDB) MarkCodeExecuted(codeHash common.Hash) {
s.inner.MarkCodeExecuted(codeHash)
func (s *hookedStateDB) MarkCodeExecuted(codeHash common.Hash, isSystem bool) {
s.inner.MarkCodeExecuted(codeHash, isSystem)
}

View file

@ -296,7 +296,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
codeHash := evm.resolveCodeHash(addr)
contract.SetCallCode(codeHash, code)
// Track unique contract execution for metrics
evm.StateDB.MarkCodeExecuted(codeHash)
evm.StateDB.MarkCodeExecuted(codeHash, contract.IsSystemCall)
ret, err = evm.Run(contract, input, false)
gas = contract.Gas
}
@ -358,7 +358,7 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
codeHash := evm.resolveCodeHash(addr)
contract.SetCallCode(codeHash, evm.resolveCode(addr))
// Track unique contract execution for metrics
evm.StateDB.MarkCodeExecuted(codeHash)
evm.StateDB.MarkCodeExecuted(codeHash, isSystemCall(caller))
ret, err = evm.Run(contract, input, false)
gas = contract.Gas
}
@ -405,7 +405,7 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
codeHash := evm.resolveCodeHash(addr)
contract.SetCallCode(codeHash, evm.resolveCode(addr))
// Track unique contract execution for metrics
evm.StateDB.MarkCodeExecuted(codeHash)
evm.StateDB.MarkCodeExecuted(codeHash, isSystemCall(originCaller))
ret, err = evm.Run(contract, input, false)
gas = contract.Gas
}
@ -459,7 +459,7 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
codeHash := evm.resolveCodeHash(addr)
contract.SetCallCode(codeHash, evm.resolveCode(addr))
// Track unique contract execution for metrics
evm.StateDB.MarkCodeExecuted(codeHash)
evm.StateDB.MarkCodeExecuted(codeHash, isSystemCall(caller))
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally

View file

@ -104,5 +104,6 @@ type StateDB interface {
// MarkCodeExecuted records that a contract's code was executed.
// Used for metrics tracking to count unique contracts executed.
MarkCodeExecuted(codeHash common.Hash)
// The isSystem parameter indicates if this is a system call (e.g., EIP-4788).
MarkCodeExecuted(codeHash common.Hash, isSystem bool)
}