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)
|
writeTime := time.Since(writeStart)
|
||||||
var stats ExecuteStats
|
var stats ExecuteStats
|
||||||
|
|
||||||
// Counts: aggregated from per-tx workers + pre-tx + post-tx state in the
|
// Counts: write counts come from the BAL state transition; read counts
|
||||||
// parallel processor (read counters), plus BAL state-root computation
|
// for accounts/storage come from the BAL access list itself (deduplicated).
|
||||||
// (account/code/storage write counters via stateTransition.WriteCounts).
|
// 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
|
stats.StateCounts = res.Counts
|
||||||
balWrites := stateTransition.WriteCounts()
|
stats.StateCounts.Add(stateTransition.WriteCounts())
|
||||||
stats.StateCounts.Add(balWrites)
|
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.
|
// Time durations under parallel execution use wall-clock semantics.
|
||||||
// Per-tx duration sums (CPU-time) are intentionally not plumbed: they
|
// Per-tx duration sums (CPU-time) are intentionally not plumbed: they
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,23 @@ import (
|
||||||
// BlockAccessList is the encoding format of AccessListBuilder.
|
// BlockAccessList is the encoding format of AccessListBuilder.
|
||||||
type BlockAccessList []AccountAccess
|
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 {
|
func (e BlockAccessList) EncodeRLP(_w io.Writer) error {
|
||||||
w := rlp.NewEncoderBuffer(_w)
|
w := rlp.NewEncoderBuffer(_w)
|
||||||
l := w.List()
|
l := w.List()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue