Skip to content

feat: add fork choice compliance test for pre-gloas forks#9670

Open
ensi321 wants to merge 21 commits into
unstablefrom
nc/fork-choice-compliance
Open

feat: add fork choice compliance test for pre-gloas forks#9670
ensi321 wants to merge 21 commits into
unstablefrom
nc/fork-choice-compliance

Conversation

@ensi321

@ensi321 ensi321 commented Jul 16, 2026

Copy link
Copy Markdown
Member

Description

The suite is a standalone flow parallel to the standard spec tests, sharing only the fork-choice test runner:

  • pnpm download-comptests — fetches the comptests.tar.gz release asset (same version pin and repo as the standard spec tests, configured in spec-tests-version.json) into its own spec-tests-comptests/ directory, fully order-independent from download-spec-tests.
  • pnpm test:comptest — runs the suite via a dedicated comptest vitest project. The regular spec projects exclude it, so test:spec / test:spec:minimal never pick it up. A zero-test guard fails the run loudly when fixtures are absent (the workspace vitest config sets passWithNoTests: true).
  • The shared runner logic is extracted from presets/fork_choice.test.ts into utils/forkChoiceTestRunner.ts (mechanical move); the preset file and the new comptest entry file only register runners.
  • CI: nightly scheduled workflow (comptests.yml, 03:00 UTC + workflow_dispatch), following the Kurtosis sim-tests pattern — most PRs don't touch fork choice, so per-PR runs are not worth the cost (~10 min per fork, single vitest worker).

Runner/fork-choice changes needed for the new checks:

  • ForkChoice.getViableHeads() (test-only, not on IForkChoice): leaves of the spec's filtered block tree with weights, backing the suite's viable_for_head_roots_and_weights check — head equivalence alone can't catch filtered-tree/weight regressions. Gloas payload-status variants are reported per (root, payload_status, weight)
  • Exact weight comparison via proposer-boost emulation (bigint): lodestar tracks weights in EFFECTIVE_BALANCE_INCREMENT units and double-floors the boost score (up to 1.2 ETH below the spec's Gwei-precision value). Instead of comparing within a tolerance (which would mask small weight bugs), the runner normalizes the expected weight of the boosted entry using the production getCommitteeFraction and compares exactly.
  • Spec-semantics fixes in the runner: nested checks.head.payload_status (current vector shape), on_attestation one-slot-delay precondition, target-checkpoint shuffling for attestation decoding, bls_setting: 2 (placeholder signatures) handling, payload-attestation negative-test completeness (slot mismatch is a spec no-op success; missing PTC membership is a rejection).
  • specTestIterator: central SkipOpts.skippedTests now composes with runner-local shouldSkip (previously silently ignored for runners defining their own, e.g. fork_choice).

Results

vectors pre-gloas result
v1.7.0-alpha.11 (current pin) 8,832/8,832 pass (all 6 forks)
v1.7.0-alpha.12 8,831/8,832 — the single failure is #9666, skip-listed with issue link (that case name only exists in the alpha.12 vector set)

Supersedes #9314 — the runner and fork-choice work from that PR is carried forward as cherry-picked commits with authorship preserved. Coauthored by @GrapeBaBa

GrapeBaBa and others added 20 commits July 15, 2026 23:24
The fork-choice compliance suite (consensus-specs#3831) introduces a
`viable_for_head_roots_and_weights` check that asserts the leaves and
weights of the internal `filter_block_tree(store, justified.root)`.
Head equivalence alone is too weak to catch filtered-tree regressions.

Add `IForkChoice.getViableHeads()` that returns the viable-for-head
leaves of the filtered tree paired with their weights:

- A node is a filter_block_tree leaf iff it is viable AND has no viable
  descendants. `maybeUpdateBestChildAndDescendant` only sets `bestChild`
  to a child that `nodeLeadsToViableHead`, so `bestChild === undefined`
  iff no viable descendant. Combined with `nodeIsViableForHead`, this
  matches the spec exactly. Same approach as Teku's
  `ForkChoiceStrategy.getChainHeads`.
- Weight is converted from internal increment units to Gwei on read
  (compliance fixtures expect Gwei). Note the proposer-boost score
  contribution is also stored in increments and may round down on
  minimal preset (102 vs 102.4 ETH); attestation weight is exact, the
  rounding only surfaces while boost is active. Mainnet boost values
  are integer ETH so this is a non-issue there.
Wire the consensus-specs Fork Choice Compliance suite (#3831) into
the existing `forkChoiceTest` runner. The on-disk layout matches the
standard spec-test layout
(`tests/<preset>/<fork>/fork_choice_compliance/<handler>/<suite>/<case>/`),
so it slots in alongside `fork_choice` and `sync` runners.

Three test-only accommodations the compliance fixtures require:

1. `bls_setting: 2` — every compliance fixture uses placeholder
   signatures. Pass `validSignatures: testcase.meta?.bls_setting !==
   BigInt(1)` to `chain.processBlock` so verification short-circuits.
   Standard `fork_choice` fixtures use `bls_setting: 1` so behavior
   there is unchanged.

2. `BLOCK_ERROR_ALREADY_KNOWN` — compliance fixtures intentionally
   re-import the same block (`dup_shift` mutations in their
   `meta.yaml`). Spec semantics for `on_block(store, known_block)` is
   a no-op success. Production block import correctly rejects with
   ALREADY_KNOWN; this runner treats that case as success only when
   the step is `valid: true`.

3. Cross-epoch attestation shuffling — `on_attestation` decodes
   aggregation_bits using the state at the attestation's target
   checkpoint, not the head state. The runner now resolves the right
   shuffling via ShufflingCache + regen (mirroring the production
   validation path) instead of `headState.epochCtx.getIndexedAttestation`,
   which only worked when the attestation's epoch happened to be in
   the head's epoch cache (±1 epoch) and broke on cross-epoch fork
   attestations surfaced by the compliance suite.

Adds support for two compliance-only check fields:

- `viable_for_head_roots_and_weights` (consensus-specs#3831): compared
  via `getViableHeads()`. Both sides are sorted by root before
  comparison since the spec doesn't fix order.
- `head_payload_status` (gloas): mapped between our internal enum
  ordering (PENDING=0, EMPTY=1, FULL=2) and spec ordering (EMPTY=0,
  FULL=1, PENDING=2).

Pass rate against the latest comptests workflow `small.tar.gz` artifact:

  fulu/fork_choice_compliance: 253/1472 cases pass (17.2%)

Top remaining failures:
- ~80% `Invalid proposer boost root` — consensus-specs#4807 introduced
  a `block.proposer_index == get_beacon_proposer_index(head_state)`
  guard in `update_proposer_boost_root` that we do not yet implement;
  affects all forks (not just gloas equivocation handling). Tracked
  for follow-up alongside #9233.
- ~1% `Invalid viable heads` — proposer-boost rounding on minimal
  preset (see `getViableHeads()` weight note).
…e gloas variants

Three corrections to the compliance-only getViableHeads getter, plus an
API-surface trim:

- Restrict leaves to descendants of the justified checkpoint block: the
  spec's get_filtered_block_tree is rooted at store.justified_checkpoint,
  so iterating all proto-array nodes over-included FFG-viable leaves
  hanging off the finalized checkpoint on branches not under the current
  justified checkpoint (~87 of 100 'Invalid viable heads' compliance
  failures were this, not proposer-boost rounding as previously assumed).
  The descendant walk follows parent links to the justified root — a
  slot-based getAncestor lookup returns the node itself for leaves whose
  own slot equals the justified epoch start slot — and stops early once
  it passes the justified block's slot (parent slots are non-increasing).

- Emit each block root at most once: gloas payload-status variants share
  a blockRoot and more than one can be a leaf (EMPTY and FULL are both
  parented under PENDING), which produced duplicate roots that broke the
  index-paired comparison in the compliance check. Which variant's weight
  the spec expects is part of the open gloas vote-attribution divergence;
  keep the heaviest qualifying variant deterministically.

- Drop getViableHeads from IForkChoice: it is compliance-test-only and
  its single caller accesses the ForkChoice class directly.

Verified against consensus-specs compliance vectors (run 28413328593,
minimal fulu): viable-head root-set failures 100 -> 0; standard minimal
fork_choice+sync spectests unaffected (397 passed).
Changes to the shared fork-choice runner, each anchored to a test-format
or spec contract (not compliance-suite identity), so they apply uniformly
to fork_choice/sync/fork_choice_compliance:

- Register fork_choice_compliance in coveredTestRunners: without it every
  other spec suite iterating the same fixture tree (ssz_static, operations,
  sanity, ...) throws 'No test runner for fork_choice_compliance' once
  compliance fixtures are downloaded.

- Attestation timing precondition: spec validate_on_attestation requires
  get_current_slot(store) >= data.slot + 1. Lodestar enforces this 1-slot
  delay in the gossip/attestation-pool layer, not forkChoice.onAttestation;
  the runner calls onAttestation directly, so replicate the precondition
  (Lighthouse's runner excuses the same case post-hoc: DidntFail tolerated
  when data.slot >= current_slot). Clears all 298 negative-attestation
  compliance failures.

- Attestation step hardening: an unknown beacon block root on a valid:true
  step now fails loudly instead of being silently skipped, and the
  shuffling resolution runs inside the negative-test try/catch so that
  errors on valid:false steps (e.g. attesting to a future block) count as
  the expected rejection instead of crashing the case.

- Skip gloas ePBS signature verification unless bls_setting == 1: the
  test format mandates skipping verification for placeholder signatures
  (bls_setting: 2), which the block-import path already honors via
  validSignatures. Extend the same handling to the execution_payload and
  payload_attestation_message steps (Teku disables BLS at spec level for
  bls_setting IGNORED; Lighthouse compiles compliance under fake_crypto).

- Split viable_for_head_roots_and_weights into exact root-set equality
  plus a 1.2 ETH weight tolerance: the root set is epoch-determined and
  must match exactly (this strictness caught the getViableHeads
  justified-subtree bug; Teku's containsAll would not), while weights are
  stored in EFFECTIVE_BALANCE_INCREMENT units so the proposer-boost score
  quantizes to whole ETH; the divergence is bounded by
  (100 - gcd(P,100) + P)/100 = 1.2 ETH independent of preset.

Compliance (run 28413328593, minimal): fulu 1459/1472 (99.1%), remaining
11 proposer-boost-root divergences + 1-2 timeouts; gloas 200/1472, blocked
by processPayloadAttestation verifying signatures unconditionally (ignores
verifySignatures; not batched in getBlockSignatureSets) and a payload-status
vote-attribution divergence (weight diffs are exact multiples of 32 ETH
between EMPTY/FULL variants of the same root) — both documented follow-ups,
out of scope here. Known accommodation limit: ALREADY_KNOWN treated as
no-op success cannot re-apply proposer boost for a timely duplicate the
way spec on_block re-processing would. Standard minimal fork_choice+sync:
397 passed, unchanged.
Use the single getDefaultNodeIndex + getNodeByIndex idiom already used
elsewhere in protoArray instead of the two-hop getDefaultVariant + getNode
lookup. Semantically identical for all variant cases (pre-gloas FULL,
gloas PENDING, absent root); drops one redundant indices map lookup and
removes an unreachable throw path.
- getViableHeads(): emit one entry per gloas payload-status variant
  (root, payload_status, weight) per consensus-specs #5393; drop the
  dedupe-by-root heuristic; return increment-unit weights
- runner: read nested checks.head.payload_status (alpha.12 shape),
  replacing the dead flat head_payload_status key
- runner: exact viable-head weight comparison via proposer-boost
  emulation (bigint) instead of the 1.2 ETH tolerance; normalizes the
  documented boost-quantization divergence using the vector's expected
  boost root and the production getCommitteeFraction
- runner: payload-attestation steps now reject slot mismatch and
  non-PTC validators, and fail on unexpectedly-successful negative tests
- specTestIterator: compose SkipOpts.skippedTests with runner-local
  shouldSkip (was silently ignored for fork_choice); gate
  fork_choice_compliance behind RUN_FORK_CHOICE_COMPLIANCE=1; defer
  gloas compliance suite

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add `pnpm download-comptests` and `pnpm test:comptest` (root + beacon-node),
fully outside the regular download-spec-tests/test:spec flow.

The comptests.tar.gz release asset exists since consensus-specs #5334;
vectors are fetched pinned to v1.7.0-alpha.12 (valid against the alpha.11
pin: the pre-gloas fork-choice spec delta is rename-only).

The standard downloader deletes its entire output directory on a cache
miss, so it cannot be reused for a second asset sharing spec-tests/.
downloadComptests() is asset-scoped instead: extracts to a temp dir,
replaces only tests/<preset>/<fork>/fork_choice_compliance/ subtrees,
and writes its own comptests-version.json marker only after a successful
merge — a failed download leaves existing fixtures and marker untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Covers: additive install alongside standard fixtures, refresh replacing
comptest paths + removing stale forks, cache hit, failed extraction
leaving fixtures and marker untouched, legacy marker treated as stale.

Also fixes the ordering bug the tests caught: validate the temp
extraction is non-empty BEFORE removing existing comptest paths — tar
can exit 0 on a truncated archive, which would have wiped the existing
vectors against an empty extraction.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Covers justified-subtree leaf selection with increment-unit weights, and
gloas payload-status variants of one root reported as separate entries
(EMPTY-only before the envelope, EMPTY+FULL after onExecutionPayload).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Single source of truth: spec-tests-version.json. The asset exists on
every release since v1.7.0-alpha.11 (consensus-specs #5334), so no
separate pin is needed; the comptests follow the pin bump in #9390
automatically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… gating

Compliance registration moves out of fork_choice.test.ts into its own
test/spec/comptest/ file backed by a dedicated `comptest` vitest
project; the shared runner is extracted to utils/forkChoiceTestRunner.ts.

The regular spec projects exclude test/spec/comptest/** so
test:spec/test:spec:minimal can never pick the suite up, which removes
the need for RUN_FORK_CHOICE_COMPLIANCE: `pnpm test:comptest` simply
runs the comptest project. Zero-test guard (workspace config has
passWithNoTests: true) moves into the comptest entry file, now
unconditional.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
block_tree_test_16_201284350_1 fails identically on every pre-gloas fork:
the dependent-root gate compares against the cached head, which is stale
when the preceding tick crosses an epoch boundary and pulls up the
justified checkpoint. Tracked in #9666.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Spec on_payload_attestation_message returns early when the message slot
does not match the attested block's slot ('PTC votes can only change the
vote for their assigned beacon block, return early otherwise') — it is
not a rejection. Restore conditional processing; the PTC-membership
assert and the negative-test assertion remain.

https://github.com/ethereum/consensus-specs/blob/v1.7.0-alpha.12/specs/gloas/fork-choice.md#on_payload_attestation_message

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
comptests-version.txt, matching the standard downloader's version.txt
convention; a single version string needs no JSON.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Compliance vectors now live in spec-tests-comptests/ with their own
version.txt, downloaded via the plain generic downloader — a flow fully
parallel to the standard spec tests, sharing only the fork-choice test
runner. download-spec-tests and download-comptests are order-independent
(previously, a standard-tests version change wiped the shared directory
including the merged compliance vectors).

Deletes the asset-scoped merge downloader and its tests — no longer
needed without a shared directory.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Scheduled (03:00 UTC) rather than per-PR: most PRs don't touch fork
choice, and the vectors are pinned — nightly on unstable is the right
cadence to catch regressions. Same pattern as Kurtosis sim tests.
Manual runs via workflow_dispatch.

Also documents download-comptests/test:comptest in AGENTS.md/CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Own outputDirBase and testsToDownload like the other entries; version
and repo URL shared with the standard spec tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ensi321
ensi321 requested a review from a team as a code owner July 16, 2026 23:13
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.


const logger = testLogger("spec-test");

export const forkChoiceTestRunner =

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for reviewers: a lot of the code here is migrated from fork_choice.test.ts so both spec test and compliance test can share a single runner.

Would be easier to view the diff by:
git diff unstable:packages/beacon-node/test/spec/presets/fork_choice.test.ts nc/fork-choice-compliance:packages/beacon-node/test/spec/utils/forkChoiceTestRunner.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48f1f5f479

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/beacon-node/test/spec/utils/forkChoiceTestRunner.ts Outdated
tickTime starts at 0, so an attestation step before the first tick
computed slot 0 regardless of the anchor state slot. clock.currentSlot
is initialized from the anchor slot and advanced by tick steps, matching
get_current_slot(store). Also document the ALREADY_KNOWN duplicate-block
accommodation honestly (spec re-processes duplicates; it is not a no-op).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ensi321

ensi321 commented Jul 17, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a standalone fork-choice compliance test suite (pnpm test:comptest) parallel to the standard spec tests, extracting the fork-choice test runner into a reusable utility. It also implements helper methods in ProtoArray and ForkChoice to retrieve viable heads and justified balances for compliance assertions. Feedback from the review highlights opportunities to improve type safety in the test runner by adding type guards before casting blockState to IBeaconStateViewGloas, and to optimize performance in protoArray.ts by returning early when justifiedSlot is undefined to avoid unnecessary tree traversals.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +272 to +282
if (protoBlock.slot === payloadAttestationMessage.data.slot) {
const blockState = await chain.regen.getBlockSlotState(
protoBlock,
payloadAttestationMessage.data.slot,
{dontTransferCache: true},
RegenCaller.processBlock
);

const ptcIndices = (blockState as IBeaconStateViewGloas).getIndicesInPayloadTimelinessCommittee(
payloadAttestationMessage.validatorIndex,
payloadAttestationMessage.data.slot

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The blockState variable is cast to IBeaconStateViewGloas without checking if it is null/undefined or if it is actually a Gloas state. Adding a type guard check ensures type safety and prevents potential runtime TypeErrors.

Suggested change
if (protoBlock.slot === payloadAttestationMessage.data.slot) {
const blockState = await chain.regen.getBlockSlotState(
protoBlock,
payloadAttestationMessage.data.slot,
{dontTransferCache: true},
RegenCaller.processBlock
);
const ptcIndices = (blockState as IBeaconStateViewGloas).getIndicesInPayloadTimelinessCommittee(
payloadAttestationMessage.validatorIndex,
payloadAttestationMessage.data.slot
const blockState = await chain.regen.getBlockSlotState(
protoBlock,
payloadAttestationMessage.data.slot,
{dontTransferCache: true},
RegenCaller.processBlock
);
if (!blockState || !isGloasStateType(blockState)) {
throw Error("State is not a Gloas state");
}
const ptcIndices = blockState.getIndicesInPayloadTimelinessCommittee(
payloadAttestationMessage.validatorIndex,
payloadAttestationMessage.data.slot
);

Comment on lines +550 to +556

// Verify envelope against the state
const protoBlock = chain.forkChoice.getBlockHexDefaultStatus(beaconBlockRoot);
if (!protoBlock) throw Error(`Block not found for root ${beaconBlockRoot}`);
const blockState = await chain.regen.getBlockSlotState(
protoBlock,
protoBlock.slot,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The blockState variable is cast to IBeaconStateViewGloas without verifying that it is not null/undefined and is indeed a Gloas state. Adding a type guard check prevents potential runtime TypeErrors when accessing its properties or passing it to verifyExecutionPayloadEnvelope.

Suggested change
// Verify envelope against the state
const protoBlock = chain.forkChoice.getBlockHexDefaultStatus(beaconBlockRoot);
if (!protoBlock) throw Error(`Block not found for root ${beaconBlockRoot}`);
const blockState = await chain.regen.getBlockSlotState(
protoBlock,
protoBlock.slot,
const blockState = await chain.regen.getBlockSlotState(
protoBlock,
protoBlock.slot,
{dontTransferCache: true},
RegenCaller.processBlock
);
if (!blockState || !isGloasStateType(blockState)) {
throw Error("State is not a Gloas state");
}
verifyExecutionPayloadEnvelope(beaconConfig, blockState, envelope.message);

Comment on lines +1572 to +1580
private descendsFromJustified(node: ProtoNode, justifiedSlot: Slot | undefined): boolean {
let current: ProtoNode | undefined = node;
while (current !== undefined && (justifiedSlot === undefined || current.slot >= justifiedSlot)) {
if (current.blockRoot === this.justifiedRoot) {
return true;
}
current = current.parent !== undefined ? this.getNodeByIndex(current.parent) : undefined;
}
return false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If justifiedSlot is undefined, the loop condition justifiedSlot === undefined || current.slot >= justifiedSlot is always true. This causes the loop to walk all the way to the root of the tree for every node in this.nodes, resulting in $O(N^2)$ worst-case performance. Returning false immediately when justifiedSlot is undefined avoids this unnecessary traversal.

  private descendsFromJustified(node: ProtoNode, justifiedSlot: Slot | undefined): boolean {
    if (justifiedSlot === undefined) {
      return false;
    }
    let current: ProtoNode | undefined = node;
    while (current !== undefined && current.slot >= justifiedSlot) {
      if (current.blockRoot === this.justifiedRoot) {
        return true;
      }
      current = current.parent !== undefined ? this.getNodeByIndex(current.parent) : undefined;
    }
    return false;
  }

@github-actions

Copy link
Copy Markdown
Contributor

Performance Report

✔️ no performance regression detected

Full benchmark results
Benchmark suite Current: cf55ee3 Previous: 77f7452 Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 929.62 us/op 1.0518 ms/op 0.88
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 42.756 us/op 40.506 us/op 1.06
BLS verify - blst 724.00 us/op 775.57 us/op 0.93
BLS verifyMultipleSignatures 3 - blst 1.3876 ms/op 1.4124 ms/op 0.98
BLS verifyMultipleSignatures 8 - blst 2.2110 ms/op 2.2349 ms/op 0.99
BLS verifyMultipleSignatures 32 - blst 6.9406 ms/op 7.1021 ms/op 0.98
BLS verifyMultipleSignatures 64 - blst 13.543 ms/op 14.224 ms/op 0.95
BLS verifyMultipleSignatures 128 - blst 26.480 ms/op 26.740 ms/op 0.99
BLS deserializing 10000 signatures 631.34 ms/op 662.17 ms/op 0.95
BLS deserializing 100000 signatures 6.3491 s/op 6.6393 s/op 0.96
BLS verifyMultipleSignatures - same message - 3 - blst 792.46 us/op 803.61 us/op 0.99
BLS verifyMultipleSignatures - same message - 8 - blst 872.27 us/op 937.41 us/op 0.93
BLS verifyMultipleSignatures - same message - 32 - blst 1.6064 ms/op 1.5064 ms/op 1.07
BLS verifyMultipleSignatures - same message - 64 - blst 2.5486 ms/op 2.5143 ms/op 1.01
BLS verifyMultipleSignatures - same message - 128 - blst 4.2131 ms/op 4.1791 ms/op 1.01
BLS aggregatePubkeys 32 - blst 18.230 us/op 18.209 us/op 1.00
BLS aggregatePubkeys 128 - blst 65.009 us/op 64.407 us/op 1.01
getSlashingsAndExits - default max 52.159 us/op 51.574 us/op 1.01
getSlashingsAndExits - 2k 335.54 us/op 394.66 us/op 0.85
proposeBlockBody type=full, size=empty 625.09 us/op 647.76 us/op 0.97
isKnown best case - 1 super set check 182.00 ns/op 180.00 ns/op 1.01
isKnown normal case - 2 super set checks 162.00 ns/op 184.00 ns/op 0.88
isKnown worse case - 16 super set checks 160.00 ns/op 184.00 ns/op 0.87
validate api signedAggregateAndProof - struct 1.5517 ms/op 1.5573 ms/op 1.00
validate gossip signedAggregateAndProof - struct 1.5371 ms/op 1.5554 ms/op 0.99
batch validate gossip attestation - vc 640000 - chunk 32 105.41 us/op 110.22 us/op 0.96
batch validate gossip attestation - vc 640000 - chunk 64 92.640 us/op 95.949 us/op 0.97
batch validate gossip attestation - vc 640000 - chunk 128 94.202 us/op 89.427 us/op 1.05
batch validate gossip attestation - vc 640000 - chunk 256 109.01 us/op 85.388 us/op 1.28
bytes32 toHexString 337.00 ns/op 296.00 ns/op 1.14
bytes32 Buffer.toString(hex) 168.00 ns/op 172.00 ns/op 0.98
bytes32 Buffer.toString(hex) from Uint8Array 243.00 ns/op 242.00 ns/op 1.00
bytes32 Buffer.toString(hex) + 0x 180.00 ns/op 168.00 ns/op 1.07
Return object 10000 times 0.22060 ns/op 0.21940 ns/op 1.01
Throw Error 10000 times 3.6467 us/op 3.4297 us/op 1.06
toHex 96.158 ns/op 100.94 ns/op 0.95
Buffer.from 86.618 ns/op 92.757 ns/op 0.93
shared Buffer 58.017 ns/op 61.682 ns/op 0.94
fastMsgIdFn sha256 / 200 bytes 1.4680 us/op 1.5150 us/op 0.97
fastMsgIdFn h32 xxhash / 200 bytes 152.00 ns/op 155.00 ns/op 0.98
fastMsgIdFn h64 xxhash / 200 bytes 201.00 ns/op 208.00 ns/op 0.97
fastMsgIdFn sha256 / 1000 bytes 4.7180 us/op 4.8770 us/op 0.97
fastMsgIdFn h32 xxhash / 1000 bytes 239.00 ns/op 249.00 ns/op 0.96
fastMsgIdFn h64 xxhash / 1000 bytes 249.00 ns/op 255.00 ns/op 0.98
fastMsgIdFn sha256 / 10000 bytes 41.311 us/op 43.136 us/op 0.96
fastMsgIdFn h32 xxhash / 10000 bytes 1.2570 us/op 1.3300 us/op 0.95
fastMsgIdFn h64 xxhash / 10000 bytes 819.00 ns/op 867.00 ns/op 0.94
send data - 1000 256B messages 4.4159 ms/op 4.1941 ms/op 1.05
send data - 1000 512B messages 5.8315 ms/op 5.1326 ms/op 1.14
send data - 1000 1024B messages 5.4689 ms/op 5.6186 ms/op 0.97
send data - 1000 1200B messages 6.1056 ms/op 6.4862 ms/op 0.94
send data - 1000 2048B messages 8.8420 ms/op 11.019 ms/op 0.80
send data - 1000 4096B messages 76.613 ms/op 26.656 ms/op 2.87
send data - 1000 16384B messages 321.94 ms/op 244.36 ms/op 1.32
send data - 1000 65536B messages 1.6496 s/op 745.03 ms/op 2.21
enrSubnets - fastDeserialize 64 bits 928.00 ns/op 733.00 ns/op 1.27
enrSubnets - ssz BitVector 64 bits 281.00 ns/op 279.00 ns/op 1.01
enrSubnets - fastDeserialize 4 bits 107.00 ns/op 104.00 ns/op 1.03
enrSubnets - ssz BitVector 4 bits 279.00 ns/op 270.00 ns/op 1.03
prioritizePeers score -10:0 att 32-0.1 sync 2-0 224.85 us/op 206.27 us/op 1.09
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 260.96 us/op 234.72 us/op 1.11
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 370.24 us/op 344.14 us/op 1.08
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 664.23 us/op 619.59 us/op 1.07
prioritizePeers score 0:0 att 64-1 sync 4-1 769.25 us/op 749.31 us/op 1.03
array of 16000 items push then shift 1.3610 us/op 1.3187 us/op 1.03
LinkedList of 16000 items push then shift 8.4240 ns/op 7.2520 ns/op 1.16
array of 16000 items push then pop 83.037 ns/op 70.003 ns/op 1.19
LinkedList of 16000 items push then pop 6.4200 ns/op 6.1970 ns/op 1.04
array of 24000 items push then shift 1.9885 us/op 1.9597 us/op 1.01
LinkedList of 24000 items push then shift 7.2390 ns/op 7.1990 ns/op 1.01
array of 24000 items push then pop 123.72 ns/op 99.772 ns/op 1.24
LinkedList of 24000 items push then pop 6.4850 ns/op 6.2290 ns/op 1.04
intersect bitArray bitLen 8 4.9880 ns/op 4.9730 ns/op 1.00
intersect array and set length 8 30.857 ns/op 30.333 ns/op 1.02
intersect bitArray bitLen 128 25.293 ns/op 24.951 ns/op 1.01
intersect array and set length 128 524.26 ns/op 514.67 ns/op 1.02
bitArray.getTrueBitIndexes() bitLen 128 1.1340 us/op 1.0060 us/op 1.13
bitArray.getTrueBitIndexes() bitLen 248 1.8680 us/op 1.7870 us/op 1.05
bitArray.getTrueBitIndexes() bitLen 512 3.7530 us/op 3.7040 us/op 1.01
Full columns - reconstruct all 6 blobs 116.67 us/op 113.56 us/op 1.03
Full columns - reconstruct half of the blobs out of 6 74.188 us/op 113.99 us/op 0.65
Full columns - reconstruct single blob out of 6 36.736 us/op 52.124 us/op 0.70
Half columns - reconstruct all 6 blobs 419.80 ms/op 401.43 ms/op 1.05
Half columns - reconstruct half of the blobs out of 6 208.16 ms/op 199.39 ms/op 1.04
Half columns - reconstruct single blob out of 6 74.962 ms/op 72.733 ms/op 1.03
Set add up to 64 items then delete first 2.5218 us/op 1.7045 us/op 1.48
OrderedSet add up to 64 items then delete first 3.5757 us/op 2.6196 us/op 1.36
Set add up to 64 items then delete last 3.1898 us/op 1.9523 us/op 1.63
OrderedSet add up to 64 items then delete last 5.5203 us/op 2.8948 us/op 1.91
Set add up to 64 items then delete middle 3.3560 us/op 1.9426 us/op 1.73
OrderedSet add up to 64 items then delete middle 7.1533 us/op 4.4313 us/op 1.61
Set add up to 128 items then delete first 6.7378 us/op 3.8568 us/op 1.75
OrderedSet add up to 128 items then delete first 9.9858 us/op 6.0538 us/op 1.65
Set add up to 128 items then delete last 6.0780 us/op 3.7053 us/op 1.64
OrderedSet add up to 128 items then delete last 9.9939 us/op 5.5440 us/op 1.80
Set add up to 128 items then delete middle 5.3994 us/op 3.7114 us/op 1.45
OrderedSet add up to 128 items then delete middle 14.944 us/op 11.790 us/op 1.27
Set add up to 256 items then delete first 10.835 us/op 7.6572 us/op 1.42
OrderedSet add up to 256 items then delete first 17.093 us/op 12.160 us/op 1.41
Set add up to 256 items then delete last 10.660 us/op 7.5662 us/op 1.41
OrderedSet add up to 256 items then delete last 16.469 us/op 11.749 us/op 1.40
Set add up to 256 items then delete middle 10.904 us/op 7.3544 us/op 1.48
OrderedSet add up to 256 items then delete middle 42.005 us/op 36.241 us/op 1.16
runFastConfirmationRules vc:100000 bc:96 eq:0 9.0799 ms/op 4.9043 ms/op 1.85
runFastConfirmationRules vc:600000 bc:96 eq:0 46.482 ms/op 36.768 ms/op 1.26
runFastConfirmationRules vc:1000000 bc:96 eq:0 64.164 ms/op 61.358 ms/op 1.05
runFastConfirmationRules vc:600000 bc:320 eq:0 35.896 ms/op 36.310 ms/op 0.99
runFastConfirmationRules vc:100000 bc:96 eq:1000 1.2923 s/op 1.1403 s/op 1.13
pass gossip attestations to forkchoice per slot 2.6194 ms/op 2.7258 ms/op 0.96
forkChoice updateHead vc 100000 bc 64 eq 0 419.59 us/op 426.40 us/op 0.98
forkChoice updateHead vc 600000 bc 64 eq 0 2.4901 ms/op 2.5385 ms/op 0.98
forkChoice updateHead vc 1000000 bc 64 eq 0 3.8988 ms/op 4.2755 ms/op 0.91
forkChoice updateHead vc 600000 bc 320 eq 0 2.3566 ms/op 2.5683 ms/op 0.92
forkChoice updateHead vc 600000 bc 1200 eq 0 2.3841 ms/op 2.6031 ms/op 0.92
forkChoice updateHead vc 600000 bc 7200 eq 0 3.4235 ms/op 2.9197 ms/op 1.17
forkChoice updateHead vc 600000 bc 64 eq 1000 2.3684 ms/op 2.5520 ms/op 0.93
forkChoice updateHead vc 600000 bc 64 eq 10000 2.4372 ms/op 2.6593 ms/op 0.92
forkChoice updateHead vc 600000 bc 64 eq 300000 6.6905 ms/op 6.7760 ms/op 0.99
computeDeltas 1400000 validators 0% inactive 11.617 ms/op 12.705 ms/op 0.91
computeDeltas 1400000 validators 10% inactive 11.037 ms/op 11.911 ms/op 0.93
computeDeltas 1400000 validators 20% inactive 10.345 ms/op 11.272 ms/op 0.92
computeDeltas 1400000 validators 50% inactive 8.4578 ms/op 9.2743 ms/op 0.91
computeDeltas 2100000 validators 0% inactive 17.396 ms/op 19.039 ms/op 0.91
computeDeltas 2100000 validators 10% inactive 16.741 ms/op 18.001 ms/op 0.93
computeDeltas 2100000 validators 20% inactive 15.508 ms/op 17.051 ms/op 0.91
computeDeltas 2100000 validators 50% inactive 10.383 ms/op 11.340 ms/op 0.92
altair processAttestation - 250000 vs - 7PWei normalcase 1.7025 ms/op 2.4598 ms/op 0.69
altair processAttestation - 250000 vs - 7PWei worstcase 2.4316 ms/op 3.1286 ms/op 0.78
altair processAttestation - setStatus - 1/6 committees join 97.717 us/op 113.95 us/op 0.86
altair processAttestation - setStatus - 1/3 committees join 201.09 us/op 211.34 us/op 0.95
altair processAttestation - setStatus - 1/2 committees join 281.64 us/op 297.23 us/op 0.95
altair processAttestation - setStatus - 2/3 committees join 378.09 us/op 387.67 us/op 0.98
altair processAttestation - setStatus - 4/5 committees join 525.61 us/op 555.03 us/op 0.95
altair processAttestation - setStatus - 100% committees join 619.09 us/op 657.10 us/op 0.94
altair processBlock - 250000 vs - 7PWei normalcase 3.2781 ms/op 3.3439 ms/op 0.98
altair processBlock - 250000 vs - 7PWei normalcase hashState 12.271 ms/op 15.650 ms/op 0.78
altair processBlock - 250000 vs - 7PWei worstcase 19.940 ms/op 21.340 ms/op 0.93
altair processBlock - 250000 vs - 7PWei worstcase hashState 42.067 ms/op 46.342 ms/op 0.91
phase0 processBlock - 250000 vs - 7PWei normalcase 1.4248 ms/op 1.3461 ms/op 1.06
phase0 processBlock - 250000 vs - 7PWei worstcase 16.945 ms/op 17.885 ms/op 0.95
altair processEth1Data - 250000 vs - 7PWei normalcase 286.38 us/op 295.21 us/op 0.97
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:16 3.2260 us/op 3.5260 us/op 0.91
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:220 21.088 us/op 22.656 us/op 0.93
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:43 5.7960 us/op 6.4240 us/op 0.90
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:19 3.6880 us/op 3.7380 us/op 0.99
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1021 85.548 us/op 92.129 us/op 0.93
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11778 1.4050 ms/op 1.4524 ms/op 0.97
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.7718 ms/op 1.9319 ms/op 0.92
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.7484 ms/op 1.9134 ms/op 0.91
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.4548 ms/op 3.8558 ms/op 0.90
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 1.9814 ms/op 2.1739 ms/op 0.91
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 3.7720 ms/op 4.2596 ms/op 0.89
Tree 40 250000 create 354.22 ms/op 315.49 ms/op 1.12
Tree 40 250000 get(125000) 93.067 ns/op 95.338 ns/op 0.98
Tree 40 250000 set(125000) 955.68 ns/op 1.0481 us/op 0.91
Tree 40 250000 toArray() 14.301 ms/op 9.7642 ms/op 1.46
Tree 40 250000 iterate all - toArray() + loop 13.748 ms/op 9.9748 ms/op 1.38
Tree 40 250000 iterate all - get(i) 41.289 ms/op 38.314 ms/op 1.08
Array 250000 create 2.5074 ms/op 2.4536 ms/op 1.02
Array 250000 clone - spread 769.02 us/op 742.40 us/op 1.04
Array 250000 get(125000) 0.28900 ns/op 0.31000 ns/op 0.93
Array 250000 set(125000) 0.28900 ns/op 0.31100 ns/op 0.93
Array 250000 iterate all - loop 55.433 us/op 58.988 us/op 0.94
phase0 afterProcessEpoch - 250000 vs - 7PWei 39.188 ms/op 40.150 ms/op 0.98
Array.fill - length 1000000 2.1062 ms/op 2.2310 ms/op 0.94
Array push - length 1000000 7.9150 ms/op 7.9406 ms/op 1.00
Array.get 0.20243 ns/op 0.21699 ns/op 0.93
Uint8Array.get 0.23655 ns/op 0.26300 ns/op 0.90
phase0 beforeProcessEpoch - 250000 vs - 7PWei 16.345 ms/op 11.914 ms/op 1.37
altair processEpoch - mainnet_e81889 332.06 ms/op 243.02 ms/op 1.37
mainnet_e81889 - altair beforeProcessEpoch 36.103 ms/op 14.050 ms/op 2.57
mainnet_e81889 - altair processJustificationAndFinalization 7.2870 us/op 4.9820 us/op 1.46
mainnet_e81889 - altair processInactivityUpdates 3.7333 ms/op 3.5891 ms/op 1.04
mainnet_e81889 - altair processRewardsAndPenalties 16.657 ms/op 17.433 ms/op 0.96
mainnet_e81889 - altair processRegistryUpdates 536.00 ns/op 543.00 ns/op 0.99
mainnet_e81889 - altair processSlashings 132.00 ns/op 134.00 ns/op 0.99
mainnet_e81889 - altair processEth1DataReset 127.00 ns/op 128.00 ns/op 0.99
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.4434 ms/op 1.3203 ms/op 1.09
mainnet_e81889 - altair processSlashingsReset 743.00 ns/op 689.00 ns/op 1.08
mainnet_e81889 - altair processRandaoMixesReset 1.3170 us/op 1.0220 us/op 1.29
mainnet_e81889 - altair processHistoricalRootsUpdate 123.00 ns/op 134.00 ns/op 0.92
mainnet_e81889 - altair processParticipationFlagUpdates 409.00 ns/op 425.00 ns/op 0.96
mainnet_e81889 - altair processSyncCommitteeUpdates 102.00 ns/op 106.00 ns/op 0.96
mainnet_e81889 - altair afterProcessEpoch 40.107 ms/op 42.450 ms/op 0.94
capella processEpoch - mainnet_e217614 938.05 ms/op 719.70 ms/op 1.30
mainnet_e217614 - capella beforeProcessEpoch 54.612 ms/op 65.054 ms/op 0.84
mainnet_e217614 - capella processJustificationAndFinalization 6.0580 us/op 5.0120 us/op 1.21
mainnet_e217614 - capella processInactivityUpdates 11.532 ms/op 11.143 ms/op 1.03
mainnet_e217614 - capella processRewardsAndPenalties 107.65 ms/op 85.967 ms/op 1.25
mainnet_e217614 - capella processRegistryUpdates 4.5160 us/op 4.5070 us/op 1.00
mainnet_e217614 - capella processSlashings 125.00 ns/op 134.00 ns/op 0.93
mainnet_e217614 - capella processEth1DataReset 123.00 ns/op 127.00 ns/op 0.97
mainnet_e217614 - capella processEffectiveBalanceUpdates 12.782 ms/op 5.4797 ms/op 2.33
mainnet_e217614 - capella processSlashingsReset 664.00 ns/op 682.00 ns/op 0.97
mainnet_e217614 - capella processRandaoMixesReset 1.3140 us/op 1.0370 us/op 1.27
mainnet_e217614 - capella processHistoricalRootsUpdate 124.00 ns/op 129.00 ns/op 0.96
mainnet_e217614 - capella processParticipationFlagUpdates 408.00 ns/op 425.00 ns/op 0.96
mainnet_e217614 - capella afterProcessEpoch 107.09 ms/op 109.43 ms/op 0.98
phase0 processEpoch - mainnet_e58758 330.92 ms/op 257.67 ms/op 1.28
mainnet_e58758 - phase0 beforeProcessEpoch 63.465 ms/op 49.790 ms/op 1.27
mainnet_e58758 - phase0 processJustificationAndFinalization 6.6340 us/op 4.9910 us/op 1.33
mainnet_e58758 - phase0 processRewardsAndPenalties 15.213 ms/op 15.198 ms/op 1.00
mainnet_e58758 - phase0 processRegistryUpdates 2.3270 us/op 2.2800 us/op 1.02
mainnet_e58758 - phase0 processSlashings 132.00 ns/op 133.00 ns/op 0.99
mainnet_e58758 - phase0 processEth1DataReset 133.00 ns/op 340.00 ns/op 0.39
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 806.88 us/op 855.42 us/op 0.94
mainnet_e58758 - phase0 processSlashingsReset 892.00 ns/op 852.00 ns/op 1.05
mainnet_e58758 - phase0 processRandaoMixesReset 1.3850 us/op 1.1440 us/op 1.21
mainnet_e58758 - phase0 processHistoricalRootsUpdate 128.00 ns/op 135.00 ns/op 0.95
mainnet_e58758 - phase0 processParticipationRecordUpdates 1.2400 us/op 992.00 ns/op 1.25
mainnet_e58758 - phase0 afterProcessEpoch 33.954 ms/op 34.325 ms/op 0.99
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.1357 ms/op 1.1195 ms/op 1.01
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.5737 ms/op 1.6821 ms/op 0.94
altair processInactivityUpdates - 250000 normalcase 11.542 ms/op 10.836 ms/op 1.07
altair processInactivityUpdates - 250000 worstcase 12.597 ms/op 10.832 ms/op 1.16
phase0 processRegistryUpdates - 250000 normalcase 2.2060 us/op 2.5670 us/op 0.86
phase0 processRegistryUpdates - 250000 badcase_full_deposits 144.33 us/op 139.70 us/op 1.03
phase0 processRegistryUpdates - 250000 worstcase 0.5 64.045 ms/op 51.953 ms/op 1.23
altair processRewardsAndPenalties - 250000 normalcase 14.922 ms/op 14.058 ms/op 1.06
altair processRewardsAndPenalties - 250000 worstcase 12.768 ms/op 13.493 ms/op 0.95
phase0 getAttestationDeltas - 250000 normalcase 8.0912 ms/op 5.7535 ms/op 1.41
phase0 getAttestationDeltas - 250000 worstcase 5.7991 ms/op 5.6507 ms/op 1.03
phase0 processSlashings - 250000 worstcase 59.191 us/op 60.427 us/op 0.98
altair processSyncCommitteeUpdates - 250000 10.359 ms/op 10.343 ms/op 1.00
BeaconState.hashTreeRoot - No change 176.00 ns/op 174.00 ns/op 1.01
BeaconState.hashTreeRoot - 1 full validator 72.100 us/op 56.879 us/op 1.27
BeaconState.hashTreeRoot - 32 full validator 1.0358 ms/op 654.63 us/op 1.58
BeaconState.hashTreeRoot - 512 full validator 6.9346 ms/op 5.9669 ms/op 1.16
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 109.77 us/op 70.583 us/op 1.56
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 2.5511 ms/op 1.0100 ms/op 2.53
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 19.241 ms/op 12.914 ms/op 1.49
BeaconState.hashTreeRoot - 1 balances 87.105 us/op 56.661 us/op 1.54
BeaconState.hashTreeRoot - 32 balances 854.23 us/op 570.73 us/op 1.50
BeaconState.hashTreeRoot - 512 balances 5.4483 ms/op 4.6263 ms/op 1.18
BeaconState.hashTreeRoot - 250000 balances 173.05 ms/op 90.410 ms/op 1.91
aggregationBits - 2048 els - zipIndexesInBitList 19.561 us/op 19.687 us/op 0.99
regular array get 100000 times 23.313 us/op 23.280 us/op 1.00
wrappedArray get 100000 times 23.267 us/op 23.262 us/op 1.00
arrayWithProxy get 100000 times 15.163 ms/op 10.241 ms/op 1.48
ssz.Root.equals 21.933 ns/op 21.941 ns/op 1.00
byteArrayEquals 21.733 ns/op 21.747 ns/op 1.00
Buffer.compare 9.0600 ns/op 9.0370 ns/op 1.00
processSlot - 1 slots 12.564 us/op 8.0330 us/op 1.56
processSlot - 32 slots 2.0133 ms/op 1.5590 ms/op 1.29
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 4.1461 ms/op 3.1104 ms/op 1.33
getCommitteeAssignments - req 1 vs - 250000 vc 1.6926 ms/op 1.7205 ms/op 0.98
getCommitteeAssignments - req 100 vs - 250000 vc 3.4668 ms/op 3.5109 ms/op 0.99
getCommitteeAssignments - req 1000 vs - 250000 vc 3.7222 ms/op 3.7914 ms/op 0.98
findModifiedValidators - 10000 modified validators 796.74 ms/op 811.65 ms/op 0.98
findModifiedValidators - 1000 modified validators 563.83 ms/op 443.34 ms/op 1.27
findModifiedValidators - 100 modified validators 255.88 ms/op 349.03 ms/op 0.73
findModifiedValidators - 10 modified validators 227.70 ms/op 281.63 ms/op 0.81
findModifiedValidators - 1 modified validators 190.93 ms/op 189.88 ms/op 1.01
findModifiedValidators - no difference 147.42 ms/op 165.01 ms/op 0.89
migrate state 1500000 validators, 3400 modified, 2000 new 3.4373 s/op 3.1227 s/op 1.10
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 3.7800 ns/op 3.8400 ns/op 0.98
state getBlockRootAtSlot - 250000 vs - 7PWei 465.61 ns/op 295.49 ns/op 1.58
computeProposerIndex 100000 validators 1.3244 ms/op 1.3767 ms/op 0.96
getNextSyncCommitteeIndices 1000 validators 2.9165 ms/op 2.9728 ms/op 0.98
getNextSyncCommitteeIndices 10000 validators 25.543 ms/op 25.921 ms/op 0.99
getNextSyncCommitteeIndices 100000 validators 86.275 ms/op 91.799 ms/op 0.94
computeProposers - vc 250000 554.39 us/op 571.81 us/op 0.97
computeEpochShuffling - vc 250000 39.291 ms/op 40.760 ms/op 0.96
getNextSyncCommittee - vc 250000 9.5718 ms/op 9.7351 ms/op 0.98
nodejs block root to RootHex using toHex 100.50 ns/op 102.37 ns/op 0.98
nodejs block root to RootHex using toRootHex 64.869 ns/op 64.247 ns/op 1.01
nodejs fromHex(blob) 843.06 us/op 813.79 us/op 1.04
nodejs fromHexInto(blob) 646.96 us/op 653.02 us/op 0.99
nodejs block root to RootHex using the deprecated toHexString 490.90 ns/op 553.51 ns/op 0.89
nodejs byteArrayEquals 32 bytes (block root) 26.389 ns/op 27.074 ns/op 0.97
nodejs byteArrayEquals 48 bytes (pubkey) 38.038 ns/op 39.084 ns/op 0.97
nodejs byteArrayEquals 96 bytes (signature) 38.227 ns/op 35.740 ns/op 1.07
nodejs byteArrayEquals 1024 bytes 44.956 ns/op 43.319 ns/op 1.04
nodejs byteArrayEquals 131072 bytes (blob) 1.7794 us/op 1.8516 us/op 0.96
browser block root to RootHex using toHex 146.89 ns/op 149.98 ns/op 0.98
browser block root to RootHex using toRootHex 133.07 ns/op 135.76 ns/op 0.98
browser fromHex(blob) 1.6742 ms/op 1.7015 ms/op 0.98
browser fromHexInto(blob) 645.22 us/op 654.91 us/op 0.99
browser block root to RootHex using the deprecated toHexString 339.94 ns/op 365.67 ns/op 0.93
browser byteArrayEquals 32 bytes (block root) 28.689 ns/op 28.972 ns/op 0.99
browser byteArrayEquals 48 bytes (pubkey) 40.208 ns/op 40.894 ns/op 0.98
browser byteArrayEquals 96 bytes (signature) 74.934 ns/op 76.487 ns/op 0.98
browser byteArrayEquals 1024 bytes 766.04 ns/op 779.02 ns/op 0.98
browser byteArrayEquals 131072 bytes (blob) 96.450 us/op 98.236 us/op 0.98

by benchmarkbot/action

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants