Skip to content

Commit

Permalink
fix: improve compute new state root when producing block (#6195)
Browse files Browse the repository at this point in the history
* feat: track and call state.hashTreeRoot() in prepareNextSlot

* fix: correct stateHashTreeRootTime bucket

* docs: add more comment for the fix
  • Loading branch information
twoeths authored Dec 15, 2023
1 parent 4658348 commit c044d4c
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export async function verifyBlocksStateTransitionOnly(
metrics
);

const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer();
const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({source: "block_transition"});
const stateRoot = postState.hashTreeRoot();
hashTreeRootTimer?.();

Expand Down
6 changes: 6 additions & 0 deletions packages/beacon-node/src/chain/prepareNextSlot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ export class PrepareNextSlotScheduler {
RegenCaller.precomputeEpoch
);

// cache HashObjects for faster hashTreeRoot() later, especially for computeNewStateRoot() if we need to produce a block at slot 0 of epoch
// see https://github.com/ChainSafe/lodestar/issues/6194
const hashTreeRootTimer = this.metrics?.stateHashTreeRootTime.startTimer({source: "prepare_next_slot"});
prepareState.hashTreeRoot();
hashTreeRootTimer?.();

// assuming there is no reorg, it caches the checkpoint state & helps avoid doing a full state transition in the next slot
// + when gossip block comes, we need to validate and run state transition
// + if next slot is a skipped slot, it'd help getting target checkpoint state faster to validate attestations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,9 @@ export function computeNewStateRoot(
const {attestations, syncAggregate, slashing} = postState.proposerRewards;
const proposerReward = BigInt(attestations + syncAggregate + slashing);

return {newStateRoot: postState.hashTreeRoot(), proposerReward};
const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({source: "compute_new_state_root"});
const newStateRoot = postState.hashTreeRoot();
hashTreeRootTimer?.();

return {newStateRoot, proposerReward};
}
5 changes: 3 additions & 2 deletions packages/beacon-node/src/metrics/metrics/lodestar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,10 +304,11 @@ export function createLodestarMetrics(
help: "Time to call commit after process a single block in seconds",
buckets: [0.005, 0.01, 0.02, 0.05, 0.1, 1],
}),
stateHashTreeRootTime: register.histogram({
stateHashTreeRootTime: register.histogram<"source">({
name: "lodestar_stfn_hash_tree_root_seconds",
help: "Time to compute the hash tree root of a post state in seconds",
buckets: [0.005, 0.01, 0.02, 0.05, 0.1, 1],
buckets: [0.05, 0.1, 0.2, 0.5, 1, 1.5],
labelNames: ["source"],
}),
preStateBalancesNodesPopulatedMiss: register.gauge<"source">({
name: "lodestar_stfn_balances_nodes_populated_miss_total",
Expand Down

0 comments on commit c044d4c

Please sign in to comment.