mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-08 07:58:40 +00:00
core: derive BAL block account/storage read counts from access list
Per-tx + pre-tx + post-tx StateDBs each have independent stateObjects caches, so summing their AccountLoaded/StorageLoaded counts over-counts addresses/slots touched by multiple phase StateDBs (compared to non-BAL single-StateDB semantics where the cache deduplicates). Override the read counts at the BAL stats wiring site using two new helpers on bal.BlockAccessList. The BAL is the canonical block-level deduplicated access record, so this restores cross-client comparable "unique accounts/slots touched" semantics. CodeLoaded/CodeLoadBytes still sum per-tx — the BAL doesn't track code- fetch events distinctly. Slight over-count remains there, documented.
This commit is contained in:
parent
4d9405a201
commit
823b582fc4
2 changed files with 27 additions and 5 deletions
|
|
@ -652,12 +652,17 @@ func (bc *BlockChain) processBlockWithAccessList(parentRoot common.Hash, block *
|
|||
writeTime := time.Since(writeStart)
|
||||
var stats ExecuteStats
|
||||
|
||||
// Counts: aggregated from per-tx workers + pre-tx + post-tx state in the
|
||||
// parallel processor (read counters), plus BAL state-root computation
|
||||
// (account/code/storage write counters via stateTransition.WriteCounts).
|
||||
// Counts: write counts come from the BAL state transition; read counts
|
||||
// for accounts/storage come from the BAL access list itself (deduplicated).
|
||||
// CodeLoaded/CodeLoadBytes still sum per-tx worker contributions because
|
||||
// the BAL doesn't track code-fetch events distinctly — accept slight
|
||||
// over-counting there.
|
||||
stats.StateCounts = res.Counts
|
||||
balWrites := stateTransition.WriteCounts()
|
||||
stats.StateCounts.Add(balWrites)
|
||||
stats.StateCounts.Add(stateTransition.WriteCounts())
|
||||
if al := block.AccessList(); al != nil {
|
||||
stats.StateCounts.AccountLoaded = al.UniqueAccountCount()
|
||||
stats.StateCounts.StorageLoaded = al.UniqueStorageSlotCount()
|
||||
}
|
||||
|
||||
// Time durations under parallel execution use wall-clock semantics.
|
||||
// Per-tx duration sums (CPU-time) are intentionally not plumbed: they
|
||||
|
|
|
|||
|
|
@ -44,6 +44,23 @@ import (
|
|||
// BlockAccessList is the encoding format of AccessListBuilder.
|
||||
type BlockAccessList []AccountAccess
|
||||
|
||||
// UniqueAccountCount returns the number of distinct account addresses in
|
||||
// the block access list.
|
||||
func (e BlockAccessList) UniqueAccountCount() int {
|
||||
return len(e)
|
||||
}
|
||||
|
||||
// UniqueStorageSlotCount returns the total number of distinct (address, slot)
|
||||
// pairs accessed across all accounts. Reads and writes are disjoint per
|
||||
// account by spec validation, so we can sum them directly.
|
||||
func (e BlockAccessList) UniqueStorageSlotCount() int {
|
||||
var n int
|
||||
for i := range e {
|
||||
n += len(e[i].StorageReads) + len(e[i].StorageChanges)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (e BlockAccessList) EncodeRLP(_w io.Writer) error {
|
||||
w := rlp.NewEncoderBuffer(_w)
|
||||
l := w.List()
|
||||
|
|
|
|||
Loading…
Reference in a new issue