Skip to content

Commit

Permalink
feat: forkchoice filter change (#6288)
Browse files Browse the repository at this point in the history
* fix: cache justifiedTotalActiveBalanceByIncrement and implement getProposerScore()

* feat: confirmation rule prerequisite for forkchoice

* chore: no need to change unrealizedJustified in ForkChoiceStore

* fix: beacon-node perf test

* fix: spec test v1.4.0-beta.6

* fix: ignore whisk for now
  • Loading branch information
twoeths committed Jan 19, 2024
1 parent ea4cdad commit 2db7120
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,17 @@ describe("getAttestationsForBlock", () => {
);
}

let totalBalance = 0;
for (let i = 0; i < originalState.epochCtx.effectiveBalanceIncrements.length; i++) {
totalBalance += originalState.epochCtx.effectiveBalanceIncrements[i];
}

const fcStore: IForkChoiceStore = {
currentSlot: originalState.slot,
justified: {
checkpoint: {...justifiedCheckpoint, rootHex: toHexString(justifiedCheckpoint.root)},
balances: originalState.epochCtx.effectiveBalanceIncrements,
totalBalance,
},
unrealizedJustified: {
checkpoint: {...justifiedCheckpoint, rootHex: toHexString(justifiedCheckpoint.root)},
Expand Down
9 changes: 7 additions & 2 deletions packages/beacon-node/test/spec/presets/ssz_static.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ type Types = Record<string, Type<any>>;
//

const sszStatic =
(skippedTypes?: string[]) =>
(skippedFork: string, skippedTypes?: string[]) =>
(fork: ForkName, typeName: string, testSuite: string, testSuiteDirpath: string): void => {
if (fork === skippedFork) {
return;
}

// Do not manually skip tests here, do it in packages/beacon-node/test/spec/presets/index.test.ts
if (skippedTypes?.includes(typeName)) {
return;
Expand Down Expand Up @@ -72,6 +76,7 @@ specTestIterator(path.join(ethereumConsensusSpecsTests.outputDir, "tests", ACTIV
// eslint-disable-next-line @typescript-eslint/naming-convention
ssz_static: {
type: RunnerType.custom,
fn: sszStatic(),
// starting from v1.4.0-beta.6, there is "whisk" fork in ssz_static tests but we ignore them
fn: sszStatic("whisk"),
},
});
2 changes: 1 addition & 1 deletion packages/beacon-node/test/spec/specTestVersioning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {DownloadTestsOptions} from "@lodestar/spec-test-util/downloadTests";
const __dirname = path.dirname(fileURLToPath(import.meta.url));

export const ethereumConsensusSpecsTests: DownloadTestsOptions = {
specVersion: "v1.4.0-beta.5",
specVersion: "v1.4.0-beta.6",
// Target directory is the host package root: 'packages/*/spec-tests'
outputDir: path.join(__dirname, "../../spec-tests"),
specTestsRepoUrl: "https://github.com/ethereum/consensus-spec-tests",
Expand Down
32 changes: 5 additions & 27 deletions packages/fork-choice/src/forkChoice/forkChoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export class ForkChoice implements IForkChoice {
if (this.opts?.proposerBoostEnabled && this.proposerBoostRoot) {
const proposerBoostScore =
this.justifiedProposerBoostScore ??
computeProposerBoostScoreFromBalances(this.fcStore.justified.balances, {
getProposerScore(this.fcStore.justified.totalBalance, {
slotsPerEpoch: SLOTS_PER_EPOCH,
proposerScoreBoost: this.config.PROPOSER_SCORE_BOOST,
});
Expand Down Expand Up @@ -1262,32 +1262,10 @@ export function assertValidTerminalPowBlock(
}
}

function computeProposerBoostScore(
{
justifiedTotalActiveBalanceByIncrement,
justifiedActiveValidators,
}: {justifiedTotalActiveBalanceByIncrement: number; justifiedActiveValidators: number},
export function getProposerScore(
justifiedTotalActiveBalanceByIncrement: number,
config: {slotsPerEpoch: number; proposerScoreBoost: number}
): number {
const avgBalanceByIncrement = Math.floor(justifiedTotalActiveBalanceByIncrement / justifiedActiveValidators);
const committeeSize = Math.floor(justifiedActiveValidators / config.slotsPerEpoch);
const committeeWeight = committeeSize * avgBalanceByIncrement;
const proposerScore = Math.floor((committeeWeight * config.proposerScoreBoost) / 100);
return proposerScore;
}

export function computeProposerBoostScoreFromBalances(
justifiedBalances: EffectiveBalanceIncrements,
config: {slotsPerEpoch: number; proposerScoreBoost: number}
): number {
let justifiedTotalActiveBalanceByIncrement = 0,
justifiedActiveValidators = 0;
for (let i = 0; i < justifiedBalances.length; i++) {
if (justifiedBalances[i] > 0) {
justifiedActiveValidators += 1;
// justified balances here are by increment
justifiedTotalActiveBalanceByIncrement += justifiedBalances[i];
}
}
return computeProposerBoostScore({justifiedTotalActiveBalanceByIncrement, justifiedActiveValidators}, config);
const committeeWeight = Math.floor(justifiedTotalActiveBalanceByIncrement / config.slotsPerEpoch);
return Math.floor((committeeWeight * config.proposerScoreBoost) / 100);
}
4 changes: 4 additions & 0 deletions packages/fork-choice/src/forkChoice/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export type CheckpointHexWithBalance = {
balances: EffectiveBalanceIncrements;
};

export type CheckpointHexWithTotalBalance = CheckpointHexWithBalance & {
totalBalance: number;
};

export enum EpochDifference {
current = 0,
previous = 1,
Expand Down
22 changes: 16 additions & 6 deletions packages/fork-choice/src/forkChoice/store.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {toHexString} from "@chainsafe/ssz";
import {EffectiveBalanceIncrements, CachedBeaconStateAllForks} from "@lodestar/state-transition";
import {phase0, Slot, RootHex, ValidatorIndex} from "@lodestar/types";
import {CheckpointHexWithBalance} from "./interface.js";
import {CheckpointHexWithTotalBalance, CheckpointHexWithBalance} from "./interface.js";

/**
* Stores checkpoints in a hybrid format:
Expand Down Expand Up @@ -37,7 +37,8 @@ export type JustifiedBalancesGetter = (
*/
export interface IForkChoiceStore {
currentSlot: Slot;
justified: CheckpointHexWithBalance;
get justified(): CheckpointHexWithTotalBalance;
set justified(justified: CheckpointHexWithBalance);
unrealizedJustified: CheckpointHexWithBalance;
finalizedCheckpoint: CheckpointWithHex;
unrealizedFinalizedCheckpoint: CheckpointWithHex;
Expand All @@ -49,7 +50,7 @@ export interface IForkChoiceStore {
* IForkChoiceStore implementer which emits forkChoice events on updated justified and finalized checkpoints.
*/
export class ForkChoiceStore implements IForkChoiceStore {
private _justified: CheckpointHexWithBalance;
private _justified: CheckpointHexWithTotalBalance;
unrealizedJustified: CheckpointHexWithBalance;
private _finalizedCheckpoint: CheckpointWithHex;
unrealizedFinalizedCheckpoint: CheckpointWithHex;
Expand All @@ -66,21 +67,22 @@ export class ForkChoiceStore implements IForkChoiceStore {
onFinalized: (cp: CheckpointWithHex) => void;
}
) {
const justified: CheckpointHexWithBalance = {
const justified = {
checkpoint: toCheckpointWithHex(justifiedCheckpoint),
balances: justifiedBalances,
totalBalance: computeTotalBalance(justifiedBalances),
};
this._justified = justified;
this.unrealizedJustified = justified;
this._finalizedCheckpoint = toCheckpointWithHex(finalizedCheckpoint);
this.unrealizedFinalizedCheckpoint = this._finalizedCheckpoint;
}

get justified(): CheckpointHexWithBalance {
get justified(): CheckpointHexWithTotalBalance {
return this._justified;
}
set justified(justified: CheckpointHexWithBalance) {
this._justified = justified;
this._justified = {...justified, totalBalance: computeTotalBalance(justified.balances)};
this.events?.onJustified(justified.checkpoint);
}

Expand Down Expand Up @@ -108,3 +110,11 @@ export function toCheckpointWithHex(checkpoint: phase0.Checkpoint): CheckpointWi
export function equalCheckpointWithHex(a: CheckpointWithHex, b: CheckpointWithHex): boolean {
return a.epoch === b.epoch && a.rootHex === b.rootHex;
}

export function computeTotalBalance(balances: EffectiveBalanceIncrements): number {
let totalBalance = 0;
for (let i = 0; i < balances.length; i++) {
totalBalance += balances[i];
}
return totalBalance;
}
16 changes: 6 additions & 10 deletions packages/fork-choice/src/protoArray/protoArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -723,22 +723,18 @@ export class ProtoArray {
return false;
}
const currentEpoch = computeEpochAtSlot(currentSlot);
const previousEpoch = currentEpoch - 1;

// If block is from a previous epoch, filter using unrealized justification & finalization information
// If block is from the current epoch, filter using the head state's justification & finalization information
const isFromPrevEpoch = computeEpochAtSlot(node.slot) < currentEpoch;
const votingSourceEpoch = isFromPrevEpoch ? node.unrealizedJustifiedEpoch : node.justifiedEpoch;

// The voting source should be at the same height as the store's justified checkpoint
let correctJustified = votingSourceEpoch === this.justifiedEpoch || this.justifiedEpoch === 0;

// If this is a pulled-up block from the current epoch, also check that
// the unrealized justification is higher than the store's justified checkpoint, and
// the voting source is not more than two epochs ago.
if (!correctJustified && currentEpoch > GENESIS_EPOCH && this.justifiedEpoch === previousEpoch) {
correctJustified = node.unrealizedJustifiedEpoch >= previousEpoch && votingSourceEpoch + 2 >= currentEpoch;
}
// The voting source should be at the same height as the store's justified checkpoint or
// not more than two epochs ago
const correctJustified =
this.justifiedEpoch === GENESIS_EPOCH ||
votingSourceEpoch === this.justifiedEpoch ||
votingSourceEpoch + 2 >= currentEpoch;

const correctFinalized = this.finalizedEpoch === 0 || this.isFinalizedRootOrDescendant(node);
return correctJustified && correctFinalized;
Expand Down
2 changes: 2 additions & 0 deletions packages/fork-choice/test/perf/forkChoice/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {fromHexString} from "@chainsafe/ssz";
import {config} from "@lodestar/config/default";
import {ExecutionStatus, ForkChoice, IForkChoiceStore, ProtoBlock, ProtoArray} from "../../../src/index.js";
import {computeTotalBalance} from "../../../src/forkChoice/store.js";

const genesisSlot = 0;
const genesisEpoch = 0;
Expand Down Expand Up @@ -39,6 +40,7 @@ export function initializeForkChoice(opts: Opts): ForkChoice {
justified: {
checkpoint: {epoch: genesisEpoch, root: fromHexString(genesisRoot), rootHex: genesisRoot},
balances,
totalBalance: computeTotalBalance(balances),
},
unrealizedJustified: {
checkpoint: {epoch: genesisEpoch, root: fromHexString(genesisRoot), rootHex: genesisRoot},
Expand Down
10 changes: 0 additions & 10 deletions packages/fork-choice/test/perf/protoArray/computeDeltas.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {itBench, setBenchOpts} from "@dapplion/benchmark";
import {EffectiveBalanceIncrements, getEffectiveBalanceIncrementsZeroed} from "@lodestar/state-transition";
import {VoteTracker} from "../../../src/protoArray/interface.js";
import {computeDeltas} from "../../../src/protoArray/computeDeltas.js";
import {computeProposerBoostScoreFromBalances} from "../../../src/forkChoice/forkChoice.js";

describe("computeDeltas", () => {
let oldBalances: EffectiveBalanceIncrements;
Expand Down Expand Up @@ -51,13 +50,4 @@ describe("computeDeltas", () => {
});
}
}

for (const numValidator of numValidators) {
itBench({
id: `computeProposerBoostScoreFromBalances ${numValidator} validators`,
fn: () => {
computeProposerBoostScoreFromBalances(newBalances, {slotsPerEpoch: 32, proposerScoreBoost: 70});
},
});
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ describe("Forkchoice", function () {
justified: {
checkpoint: {epoch: genesisEpoch, root: fromHexString(finalizedRoot), rootHex: finalizedRoot},
balances: new Uint8Array([32]),
totalBalance: 32,
},
unrealizedJustified: {
checkpoint: {epoch: genesisEpoch, root: fromHexString(finalizedRoot), rootHex: finalizedRoot},
Expand Down

1 comment on commit 2db7120

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for some benchmarks.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold.

Benchmark suite Current: 2db7120 Previous: ea4cdad Ratio
phase0 processBlock - 250000 vs - 7PWei normalcase 6.7883 ms/op 1.9404 ms/op 3.50
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:15 15.588 us/op 3.7150 us/op 4.20
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:42 33.924 us/op 9.3820 us/op 3.62
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:18 14.123 us/op 4.4090 us/op 3.20
BeaconState.hashTreeRoot - No change 787.00 ns/op 220.00 ns/op 3.58
Full benchmark results
Benchmark suite Current: 2db7120 Previous: ea4cdad Ratio
getPubkeys - index2pubkey - req 1000 vs - 250000 vc 736.57 us/op 845.57 us/op 0.87
getPubkeys - validatorsArr - req 1000 vs - 250000 vc 106.78 us/op 87.344 us/op 1.22
BLS verify - blst-native 1.2986 ms/op 1.0954 ms/op 1.19
BLS verifyMultipleSignatures 3 - blst-native 2.7347 ms/op 2.3661 ms/op 1.16
BLS verifyMultipleSignatures 8 - blst-native 5.9769 ms/op 5.3253 ms/op 1.12
BLS verifyMultipleSignatures 32 - blst-native 21.953 ms/op 19.553 ms/op 1.12
BLS verifyMultipleSignatures 64 - blst-native 43.329 ms/op 38.858 ms/op 1.12
BLS verifyMultipleSignatures 128 - blst-native 86.089 ms/op 77.730 ms/op 1.11
BLS deserializing 10000 signatures 925.41 ms/op 823.35 ms/op 1.12
BLS deserializing 100000 signatures 9.5280 s/op 8.2558 s/op 1.15
BLS verifyMultipleSignatures - same message - 3 - blst-native 1.3469 ms/op 1.1401 ms/op 1.18
BLS verifyMultipleSignatures - same message - 8 - blst-native 1.5299 ms/op 1.2852 ms/op 1.19
BLS verifyMultipleSignatures - same message - 32 - blst-native 2.8199 ms/op 2.4333 ms/op 1.16
BLS verifyMultipleSignatures - same message - 64 - blst-native 4.8022 ms/op 3.4817 ms/op 1.38
BLS verifyMultipleSignatures - same message - 128 - blst-native 5.7440 ms/op 4.9668 ms/op 1.16
BLS aggregatePubkeys 32 - blst-native 26.473 us/op 22.542 us/op 1.17
BLS aggregatePubkeys 128 - blst-native 102.29 us/op 88.558 us/op 1.16
getAttestationsForBlock 54.596 ms/op 41.188 ms/op 1.33
getSlashingsAndExits - default max 171.34 us/op 115.65 us/op 1.48
getSlashingsAndExits - 2k 415.87 us/op 306.12 us/op 1.36
proposeBlockBody type=full, size=empty 5.3139 ms/op 4.0500 ms/op 1.31
isKnown best case - 1 super set check 512.00 ns/op 565.00 ns/op 0.91
isKnown normal case - 2 super set checks 359.00 ns/op 555.00 ns/op 0.65
isKnown worse case - 16 super set checks 315.00 ns/op 567.00 ns/op 0.56
CheckpointStateCache - add get delete 4.8920 us/op 5.0350 us/op 0.97
validate api signedAggregateAndProof - struct 2.7740 ms/op 2.4247 ms/op 1.14
validate gossip signedAggregateAndProof - struct 2.7897 ms/op 2.4078 ms/op 1.16
validate gossip attestation - vc 640000 1.3663 ms/op 1.1828 ms/op 1.16
batch validate gossip attestation - vc 640000 - chunk 32 172.20 us/op 146.58 us/op 1.17
batch validate gossip attestation - vc 640000 - chunk 64 151.73 us/op 130.63 us/op 1.16
batch validate gossip attestation - vc 640000 - chunk 128 148.69 us/op 123.12 us/op 1.21
batch validate gossip attestation - vc 640000 - chunk 256 132.70 us/op 128.08 us/op 1.04
pickEth1Vote - no votes 1.3804 ms/op 1.0244 ms/op 1.35
pickEth1Vote - max votes 10.811 ms/op 10.187 ms/op 1.06
pickEth1Vote - Eth1Data hashTreeRoot value x2048 20.293 ms/op 15.745 ms/op 1.29
pickEth1Vote - Eth1Data hashTreeRoot tree x2048 27.367 ms/op 28.655 ms/op 0.96
pickEth1Vote - Eth1Data fastSerialize value x2048 701.15 us/op 414.26 us/op 1.69
pickEth1Vote - Eth1Data fastSerialize tree x2048 7.5143 ms/op 8.6475 ms/op 0.87
bytes32 toHexString 578.00 ns/op 354.00 ns/op 1.63
bytes32 Buffer.toString(hex) 302.00 ns/op 205.00 ns/op 1.47
bytes32 Buffer.toString(hex) from Uint8Array 488.00 ns/op 309.00 ns/op 1.58
bytes32 Buffer.toString(hex) + 0x 304.00 ns/op 194.00 ns/op 1.57
Object access 1 prop 0.20000 ns/op 0.11100 ns/op 1.80
Map access 1 prop 0.15400 ns/op 0.10100 ns/op 1.52
Object get x1000 7.9470 ns/op 5.2210 ns/op 1.52
Map get x1000 0.76000 ns/op 0.79200 ns/op 0.96
Object set x1000 51.020 ns/op 27.319 ns/op 1.87
Map set x1000 41.317 ns/op 17.558 ns/op 2.35
Return object 10000 times 0.24210 ns/op 0.23070 ns/op 1.05
Throw Error 10000 times 3.8166 us/op 2.8890 us/op 1.32
fastMsgIdFn sha256 / 200 bytes 3.2970 us/op 2.0080 us/op 1.64
fastMsgIdFn h32 xxhash / 200 bytes 294.00 ns/op 254.00 ns/op 1.16
fastMsgIdFn h64 xxhash / 200 bytes 364.00 ns/op 293.00 ns/op 1.24
fastMsgIdFn sha256 / 1000 bytes 11.566 us/op 6.3210 us/op 1.83
fastMsgIdFn h32 xxhash / 1000 bytes 440.00 ns/op 393.00 ns/op 1.12
fastMsgIdFn h64 xxhash / 1000 bytes 441.00 ns/op 369.00 ns/op 1.20
fastMsgIdFn sha256 / 10000 bytes 103.20 us/op 53.754 us/op 1.92
fastMsgIdFn h32 xxhash / 10000 bytes 1.9620 us/op 1.9000 us/op 1.03
fastMsgIdFn h64 xxhash / 10000 bytes 1.3480 us/op 1.1830 us/op 1.14
send data - 1000 256B messages 19.680 ms/op 14.367 ms/op 1.37
send data - 1000 512B messages 24.243 ms/op 21.262 ms/op 1.14
send data - 1000 1024B messages 43.434 ms/op 32.568 ms/op 1.33
send data - 1000 1200B messages 38.443 ms/op 37.930 ms/op 1.01
send data - 1000 2048B messages 47.237 ms/op 47.571 ms/op 0.99
send data - 1000 4096B messages 40.468 ms/op 41.817 ms/op 0.97
send data - 1000 16384B messages 116.25 ms/op 113.31 ms/op 1.03
send data - 1000 65536B messages 508.89 ms/op 455.28 ms/op 1.12
enrSubnets - fastDeserialize 64 bits 1.2290 us/op 1.0220 us/op 1.20
enrSubnets - ssz BitVector 64 bits 427.00 ns/op 421.00 ns/op 1.01
enrSubnets - fastDeserialize 4 bits 164.00 ns/op 139.00 ns/op 1.18
enrSubnets - ssz BitVector 4 bits 409.00 ns/op 401.00 ns/op 1.02
prioritizePeers score -10:0 att 32-0.1 sync 2-0 100.67 us/op 84.064 us/op 1.20
prioritizePeers score 0:0 att 32-0.25 sync 2-0.25 129.04 us/op 111.74 us/op 1.15
prioritizePeers score 0:0 att 32-0.5 sync 2-0.5 176.49 us/op 166.17 us/op 1.06
prioritizePeers score 0:0 att 64-0.75 sync 4-0.75 302.90 us/op 275.67 us/op 1.10
prioritizePeers score 0:0 att 64-1 sync 4-1 349.63 us/op 315.43 us/op 1.11
array of 16000 items push then shift 1.6142 us/op 1.3896 us/op 1.16
LinkedList of 16000 items push then shift 8.7790 ns/op 6.5940 ns/op 1.33
array of 16000 items push then pop 92.025 ns/op 114.88 ns/op 0.80
LinkedList of 16000 items push then pop 8.7410 ns/op 6.6000 ns/op 1.32
array of 24000 items push then shift 2.4574 us/op 2.0031 us/op 1.23
LinkedList of 24000 items push then shift 8.7650 ns/op 10.272 ns/op 0.85
array of 24000 items push then pop 116.77 ns/op 173.35 ns/op 0.67
LinkedList of 24000 items push then pop 8.4730 ns/op 5.8660 ns/op 1.44
intersect bitArray bitLen 8 6.1730 ns/op 5.4150 ns/op 1.14
intersect array and set length 8 60.485 ns/op 49.712 ns/op 1.22
intersect bitArray bitLen 128 33.317 ns/op 28.448 ns/op 1.17
intersect array and set length 128 902.86 ns/op 736.36 ns/op 1.23
bitArray.getTrueBitIndexes() bitLen 128 1.4880 us/op 1.5870 us/op 0.94
bitArray.getTrueBitIndexes() bitLen 248 2.3410 us/op 2.9940 us/op 0.78
bitArray.getTrueBitIndexes() bitLen 512 4.6700 us/op 6.2920 us/op 0.74
Buffer.concat 32 items 1.0120 us/op 890.00 ns/op 1.14
Uint8Array.set 32 items 1.9720 us/op 1.6780 us/op 1.18
Set add up to 64 items then delete first 4.4104 us/op 2.5204 us/op 1.75
OrderedSet add up to 64 items then delete first 5.6100 us/op 3.9496 us/op 1.42
Set add up to 64 items then delete last 4.7044 us/op 2.7205 us/op 1.73
OrderedSet add up to 64 items then delete last 5.9024 us/op 4.3201 us/op 1.37
Set add up to 64 items then delete middle 4.6269 us/op 2.7549 us/op 1.68
OrderedSet add up to 64 items then delete middle 7.1678 us/op 5.5489 us/op 1.29
Set add up to 128 items then delete first 9.3366 us/op 5.2815 us/op 1.77
OrderedSet add up to 128 items then delete first 12.512 us/op 8.2628 us/op 1.51
Set add up to 128 items then delete last 9.1703 us/op 4.9656 us/op 1.85
OrderedSet add up to 128 items then delete last 11.619 us/op 7.7623 us/op 1.50
Set add up to 128 items then delete middle 9.0540 us/op 5.3568 us/op 1.69
OrderedSet add up to 128 items then delete middle 16.933 us/op 13.365 us/op 1.27
Set add up to 256 items then delete first 19.528 us/op 10.707 us/op 1.82
OrderedSet add up to 256 items then delete first 28.219 us/op 17.081 us/op 1.65
Set add up to 256 items then delete last 19.767 us/op 10.522 us/op 1.88
OrderedSet add up to 256 items then delete last 23.292 us/op 14.705 us/op 1.58
Set add up to 256 items then delete middle 18.278 us/op 10.037 us/op 1.82
OrderedSet add up to 256 items then delete middle 45.075 us/op 35.919 us/op 1.25
transfer serialized Status (84 B) 1.6650 us/op 1.5110 us/op 1.10
copy serialized Status (84 B) 1.2520 us/op 1.1660 us/op 1.07
transfer serialized SignedVoluntaryExit (112 B) 1.8550 us/op 1.5590 us/op 1.19
copy serialized SignedVoluntaryExit (112 B) 1.3740 us/op 1.2090 us/op 1.14
transfer serialized ProposerSlashing (416 B) 2.4920 us/op 1.8990 us/op 1.31
copy serialized ProposerSlashing (416 B) 2.6590 us/op 1.8410 us/op 1.44
transfer serialized Attestation (485 B) 3.2050 us/op 1.9940 us/op 1.61
copy serialized Attestation (485 B) 2.8960 us/op 1.9010 us/op 1.52
transfer serialized AttesterSlashing (33232 B) 3.0290 us/op 1.5240 us/op 1.99
copy serialized AttesterSlashing (33232 B) 6.3360 us/op 7.9340 us/op 0.80
transfer serialized Small SignedBeaconBlock (128000 B) 2.9850 us/op 1.8260 us/op 1.63
copy serialized Small SignedBeaconBlock (128000 B) 14.834 us/op 25.747 us/op 0.58
transfer serialized Avg SignedBeaconBlock (200000 B) 2.8250 us/op 1.9480 us/op 1.45
copy serialized Avg SignedBeaconBlock (200000 B) 30.191 us/op 42.152 us/op 0.72
transfer serialized BlobsSidecar (524380 B) 3.2670 us/op 2.3390 us/op 1.40
copy serialized BlobsSidecar (524380 B) 96.383 us/op 183.13 us/op 0.53
transfer serialized Big SignedBeaconBlock (1000000 B) 3.2910 us/op 3.0720 us/op 1.07
copy serialized Big SignedBeaconBlock (1000000 B) 366.20 us/op 278.15 us/op 1.32
pass gossip attestations to forkchoice per slot 4.3233 ms/op 2.8200 ms/op 1.53
forkChoice updateHead vc 100000 bc 64 eq 0 761.49 us/op 465.73 us/op 1.64
forkChoice updateHead vc 600000 bc 64 eq 0 4.2206 ms/op 3.0348 ms/op 1.39
forkChoice updateHead vc 1000000 bc 64 eq 0 6.8921 ms/op 4.5694 ms/op 1.51
forkChoice updateHead vc 600000 bc 320 eq 0 4.2519 ms/op 2.6901 ms/op 1.58
forkChoice updateHead vc 600000 bc 1200 eq 0 4.4226 ms/op 2.7404 ms/op 1.61
forkChoice updateHead vc 600000 bc 7200 eq 0 5.2757 ms/op 3.7514 ms/op 1.41
forkChoice updateHead vc 600000 bc 64 eq 1000 11.429 ms/op 10.050 ms/op 1.14
forkChoice updateHead vc 600000 bc 64 eq 10000 12.393 ms/op 9.8486 ms/op 1.26
forkChoice updateHead vc 600000 bc 64 eq 300000 15.885 ms/op 12.354 ms/op 1.29
computeDeltas 500000 validators 300 proto nodes 6.6687 ms/op 3.1688 ms/op 2.10
computeDeltas 500000 validators 1200 proto nodes 6.8137 ms/op 2.9780 ms/op 2.29
computeDeltas 500000 validators 7200 proto nodes 6.7639 ms/op 2.8549 ms/op 2.37
computeDeltas 750000 validators 300 proto nodes 9.7864 ms/op 4.3259 ms/op 2.26
computeDeltas 750000 validators 1200 proto nodes 9.9852 ms/op 4.4229 ms/op 2.26
computeDeltas 750000 validators 7200 proto nodes 10.164 ms/op 4.3462 ms/op 2.34
computeDeltas 1400000 validators 300 proto nodes 19.800 ms/op 8.4912 ms/op 2.33
computeDeltas 1400000 validators 1200 proto nodes 18.898 ms/op 8.4567 ms/op 2.23
computeDeltas 1400000 validators 7200 proto nodes 18.812 ms/op 9.0931 ms/op 2.07
computeDeltas 2100000 validators 300 proto nodes 27.961 ms/op 13.887 ms/op 2.01
computeDeltas 2100000 validators 1200 proto nodes 28.909 ms/op 13.452 ms/op 2.15
computeDeltas 2100000 validators 7200 proto nodes 28.200 ms/op 13.350 ms/op 2.11
altair processAttestation - 250000 vs - 7PWei normalcase 2.1891 ms/op 1.9969 ms/op 1.10
altair processAttestation - 250000 vs - 7PWei worstcase 3.4223 ms/op 2.6677 ms/op 1.28
altair processAttestation - setStatus - 1/6 committees join 143.46 us/op 90.138 us/op 1.59
altair processAttestation - setStatus - 1/3 committees join 275.28 us/op 174.83 us/op 1.57
altair processAttestation - setStatus - 1/2 committees join 382.97 us/op 232.70 us/op 1.65
altair processAttestation - setStatus - 2/3 committees join 478.88 us/op 296.00 us/op 1.62
altair processAttestation - setStatus - 4/5 committees join 667.86 us/op 410.02 us/op 1.63
altair processAttestation - setStatus - 100% committees join 775.32 us/op 542.69 us/op 1.43
altair processBlock - 250000 vs - 7PWei normalcase 10.944 ms/op 8.8227 ms/op 1.24
altair processBlock - 250000 vs - 7PWei normalcase hashState 34.056 ms/op 33.288 ms/op 1.02
altair processBlock - 250000 vs - 7PWei worstcase 38.901 ms/op 33.431 ms/op 1.16
altair processBlock - 250000 vs - 7PWei worstcase hashState 99.558 ms/op 80.519 ms/op 1.24
phase0 processBlock - 250000 vs - 7PWei normalcase 6.7883 ms/op 1.9404 ms/op 3.50
phase0 processBlock - 250000 vs - 7PWei worstcase 31.682 ms/op 28.928 ms/op 1.10
altair processEth1Data - 250000 vs - 7PWei normalcase 654.38 us/op 320.19 us/op 2.04
getExpectedWithdrawals 250000 eb:1,eth1:1,we:0,wn:0,smpl:15 15.588 us/op 3.7150 us/op 4.20
getExpectedWithdrawals 250000 eb:0.95,eth1:0.1,we:0.05,wn:0,smpl:219 46.251 us/op 38.203 us/op 1.21
getExpectedWithdrawals 250000 eb:0.95,eth1:0.3,we:0.05,wn:0,smpl:42 33.924 us/op 9.3820 us/op 3.62
getExpectedWithdrawals 250000 eb:0.95,eth1:0.7,we:0.05,wn:0,smpl:18 14.123 us/op 4.4090 us/op 3.20
getExpectedWithdrawals 250000 eb:0.1,eth1:0.1,we:0,wn:0,smpl:1020 218.80 us/op 125.49 us/op 1.74
getExpectedWithdrawals 250000 eb:0.03,eth1:0.03,we:0,wn:0,smpl:11777 1.5955 ms/op 824.92 us/op 1.93
getExpectedWithdrawals 250000 eb:0.01,eth1:0.01,we:0,wn:0,smpl:16384 1.8834 ms/op 1.0902 ms/op 1.73
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,smpl:16384 1.8350 ms/op 1.0008 ms/op 1.83
getExpectedWithdrawals 250000 eb:0,eth1:0,we:0,wn:0,nocache,smpl:16384 3.8793 ms/op 2.3989 ms/op 1.62
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,smpl:16384 2.8651 ms/op 1.5767 ms/op 1.82
getExpectedWithdrawals 250000 eb:0,eth1:1,we:0,wn:0,nocache,smpl:16384 5.6020 ms/op 3.9101 ms/op 1.43
Tree 40 250000 create 419.16 ms/op 262.52 ms/op 1.60
Tree 40 250000 get(125000) 222.13 ns/op 112.38 ns/op 1.98
Tree 40 250000 set(125000) 1.1403 us/op 760.98 ns/op 1.50
Tree 40 250000 toArray() 22.889 ms/op 13.265 ms/op 1.73
Tree 40 250000 iterate all - toArray() + loop 23.495 ms/op 10.554 ms/op 2.23
Tree 40 250000 iterate all - get(i) 77.076 ms/op 45.454 ms/op 1.70
MutableVector 250000 create 12.072 ms/op 10.605 ms/op 1.14
MutableVector 250000 get(125000) 6.8340 ns/op 5.5060 ns/op 1.24
MutableVector 250000 set(125000) 348.28 ns/op 199.10 ns/op 1.75
MutableVector 250000 toArray() 4.3115 ms/op 3.7689 ms/op 1.14
MutableVector 250000 iterate all - toArray() + loop 4.1133 ms/op 2.6108 ms/op 1.58
MutableVector 250000 iterate all - get(i) 1.6028 ms/op 1.3339 ms/op 1.20
Array 250000 create 3.8431 ms/op 2.4185 ms/op 1.59
Array 250000 clone - spread 1.6532 ms/op 1.0808 ms/op 1.53
Array 250000 get(125000) 1.3900 ns/op 0.94100 ns/op 1.48
Array 250000 set(125000) 5.7160 ns/op 1.1210 ns/op 5.10
Array 250000 iterate all - loop 180.98 us/op 154.90 us/op 1.17
effectiveBalanceIncrements clone Uint8Array 300000 62.834 us/op 12.639 us/op 4.97
effectiveBalanceIncrements clone MutableVector 300000 477.00 ns/op 298.00 ns/op 1.60
effectiveBalanceIncrements rw all Uint8Array 300000 216.70 us/op 184.96 us/op 1.17
effectiveBalanceIncrements rw all MutableVector 300000 120.21 ms/op 63.614 ms/op 1.89
phase0 afterProcessEpoch - 250000 vs - 7PWei 121.00 ms/op 78.924 ms/op 1.53
phase0 beforeProcessEpoch - 250000 vs - 7PWei 43.861 ms/op 51.014 ms/op 0.86
altair processEpoch - mainnet_e81889 575.46 ms/op 456.32 ms/op 1.26
mainnet_e81889 - altair beforeProcessEpoch 96.783 ms/op 81.870 ms/op 1.18
mainnet_e81889 - altair processJustificationAndFinalization 25.612 us/op 8.5720 us/op 2.99
mainnet_e81889 - altair processInactivityUpdates 6.7508 ms/op 6.6446 ms/op 1.02
mainnet_e81889 - altair processRewardsAndPenalties 69.496 ms/op 58.042 ms/op 1.20
mainnet_e81889 - altair processRegistryUpdates 3.9930 us/op 1.2070 us/op 3.31
mainnet_e81889 - altair processSlashings 491.00 ns/op 409.00 ns/op 1.20
mainnet_e81889 - altair processEth1DataReset 767.00 ns/op 498.00 ns/op 1.54
mainnet_e81889 - altair processEffectiveBalanceUpdates 1.6003 ms/op 1.1097 ms/op 1.44
mainnet_e81889 - altair processSlashingsReset 6.2420 us/op 4.1820 us/op 1.49
mainnet_e81889 - altair processRandaoMixesReset 7.9520 us/op 5.0080 us/op 1.59
mainnet_e81889 - altair processHistoricalRootsUpdate 896.00 ns/op 606.00 ns/op 1.48
mainnet_e81889 - altair processParticipationFlagUpdates 4.7290 us/op 3.0110 us/op 1.57
mainnet_e81889 - altair processSyncCommitteeUpdates 1.3370 us/op 774.00 ns/op 1.73
mainnet_e81889 - altair afterProcessEpoch 132.10 ms/op 89.000 ms/op 1.48
capella processEpoch - mainnet_e217614 2.6790 s/op 2.2757 s/op 1.18
mainnet_e217614 - capella beforeProcessEpoch 579.95 ms/op 498.56 ms/op 1.16
mainnet_e217614 - capella processJustificationAndFinalization 15.166 us/op 8.2870 us/op 1.83
mainnet_e217614 - capella processInactivityUpdates 18.625 ms/op 15.497 ms/op 1.20
mainnet_e217614 - capella processRewardsAndPenalties 414.22 ms/op 398.71 ms/op 1.04
mainnet_e217614 - capella processRegistryUpdates 19.483 us/op 22.399 us/op 0.87
mainnet_e217614 - capella processSlashings 471.00 ns/op 616.00 ns/op 0.76
mainnet_e217614 - capella processEth1DataReset 413.00 ns/op 219.00 ns/op 1.89
mainnet_e217614 - capella processEffectiveBalanceUpdates 6.9391 ms/op 5.0092 ms/op 1.39
mainnet_e217614 - capella processSlashingsReset 2.9950 us/op 3.5790 us/op 0.84
mainnet_e217614 - capella processRandaoMixesReset 4.3780 us/op 4.9620 us/op 0.88
mainnet_e217614 - capella processHistoricalRootsUpdate 416.00 ns/op 346.00 ns/op 1.20
mainnet_e217614 - capella processParticipationFlagUpdates 1.4060 us/op 1.2510 us/op 1.12
mainnet_e217614 - capella afterProcessEpoch 301.56 ms/op 212.97 ms/op 1.42
phase0 processEpoch - mainnet_e58758 414.53 ms/op 438.54 ms/op 0.95
mainnet_e58758 - phase0 beforeProcessEpoch 126.04 ms/op 120.20 ms/op 1.05
mainnet_e58758 - phase0 processJustificationAndFinalization 16.199 us/op 8.5110 us/op 1.90
mainnet_e58758 - phase0 processRewardsAndPenalties 51.007 ms/op 44.184 ms/op 1.15
mainnet_e58758 - phase0 processRegistryUpdates 13.473 us/op 4.0940 us/op 3.29
mainnet_e58758 - phase0 processSlashings 558.00 ns/op 217.00 ns/op 2.57
mainnet_e58758 - phase0 processEth1DataReset 389.00 ns/op 314.00 ns/op 1.24
mainnet_e58758 - phase0 processEffectiveBalanceUpdates 1.1561 ms/op 835.37 us/op 1.38
mainnet_e58758 - phase0 processSlashingsReset 4.0220 us/op 3.7170 us/op 1.08
mainnet_e58758 - phase0 processRandaoMixesReset 6.0730 us/op 4.0530 us/op 1.50
mainnet_e58758 - phase0 processHistoricalRootsUpdate 609.00 ns/op 306.00 ns/op 1.99
mainnet_e58758 - phase0 processParticipationRecordUpdates 4.8200 us/op 1.8530 us/op 2.60
mainnet_e58758 - phase0 afterProcessEpoch 96.211 ms/op 65.874 ms/op 1.46
phase0 processEffectiveBalanceUpdates - 250000 normalcase 1.4121 ms/op 1.0389 ms/op 1.36
phase0 processEffectiveBalanceUpdates - 250000 worstcase 0.5 1.5751 ms/op 1.1162 ms/op 1.41
altair processInactivityUpdates - 250000 normalcase 29.510 ms/op 22.819 ms/op 1.29
altair processInactivityUpdates - 250000 worstcase 21.778 ms/op 22.811 ms/op 0.95
phase0 processRegistryUpdates - 250000 normalcase 13.362 us/op 3.5790 us/op 3.73
phase0 processRegistryUpdates - 250000 badcase_full_deposits 474.87 us/op 261.22 us/op 1.82
phase0 processRegistryUpdates - 250000 worstcase 0.5 126.16 ms/op 114.67 ms/op 1.10
altair processRewardsAndPenalties - 250000 normalcase 58.318 ms/op 47.050 ms/op 1.24
altair processRewardsAndPenalties - 250000 worstcase 56.507 ms/op 54.059 ms/op 1.05
phase0 getAttestationDeltas - 250000 normalcase 12.337 ms/op 9.1407 ms/op 1.35
phase0 getAttestationDeltas - 250000 worstcase 12.708 ms/op 7.0746 ms/op 1.80
phase0 processSlashings - 250000 worstcase 122.30 us/op 59.090 us/op 2.07
altair processSyncCommitteeUpdates - 250000 169.22 ms/op 127.56 ms/op 1.33
BeaconState.hashTreeRoot - No change 787.00 ns/op 220.00 ns/op 3.58
BeaconState.hashTreeRoot - 1 full validator 140.52 us/op 161.53 us/op 0.87
BeaconState.hashTreeRoot - 32 full validator 1.4482 ms/op 1.2748 ms/op 1.14
BeaconState.hashTreeRoot - 512 full validator 18.432 ms/op 15.571 ms/op 1.18
BeaconState.hashTreeRoot - 1 validator.effectiveBalance 167.89 us/op 153.69 us/op 1.09
BeaconState.hashTreeRoot - 32 validator.effectiveBalance 2.2951 ms/op 1.9203 ms/op 1.20
BeaconState.hashTreeRoot - 512 validator.effectiveBalance 42.441 ms/op 30.297 ms/op 1.40
BeaconState.hashTreeRoot - 1 balances 164.32 us/op 131.87 us/op 1.25
BeaconState.hashTreeRoot - 32 balances 1.3654 ms/op 1.5311 ms/op 0.89
BeaconState.hashTreeRoot - 512 balances 13.547 ms/op 10.073 ms/op 1.34
BeaconState.hashTreeRoot - 250000 balances 218.35 ms/op 164.35 ms/op 1.33
aggregationBits - 2048 els - zipIndexesInBitList 19.673 us/op 12.437 us/op 1.58
byteArrayEquals 32 77.188 ns/op 70.042 ns/op 1.10
Buffer.compare 32 56.063 ns/op 41.676 ns/op 1.35
byteArrayEquals 1024 2.0788 us/op 1.8660 us/op 1.11
Buffer.compare 1024 74.864 ns/op 46.757 ns/op 1.60
byteArrayEquals 16384 33.107 us/op 28.960 us/op 1.14
Buffer.compare 16384 276.20 ns/op 231.83 ns/op 1.19
byteArrayEquals 123687377 260.27 ms/op 217.69 ms/op 1.20
Buffer.compare 123687377 8.4484 ms/op 6.4326 ms/op 1.31
byteArrayEquals 32 - diff last byte 77.465 ns/op 60.504 ns/op 1.28
Buffer.compare 32 - diff last byte 59.642 ns/op 37.730 ns/op 1.58
byteArrayEquals 1024 - diff last byte 2.1742 us/op 1.6941 us/op 1.28
Buffer.compare 1024 - diff last byte 74.093 ns/op 48.071 ns/op 1.54
byteArrayEquals 16384 - diff last byte 33.112 us/op 27.135 us/op 1.22
Buffer.compare 16384 - diff last byte 271.73 ns/op 196.99 ns/op 1.38
byteArrayEquals 123687377 - diff last byte 251.25 ms/op 205.46 ms/op 1.22
Buffer.compare 123687377 - diff last byte 8.0408 ms/op 6.5881 ms/op 1.22
byteArrayEquals 32 - random bytes 5.7840 ns/op 5.4220 ns/op 1.07
Buffer.compare 32 - random bytes 63.802 ns/op 39.225 ns/op 1.63
byteArrayEquals 1024 - random bytes 5.4600 ns/op 5.5730 ns/op 0.98
Buffer.compare 1024 - random bytes 62.038 ns/op 37.470 ns/op 1.66
byteArrayEquals 16384 - random bytes 5.9320 ns/op 5.0810 ns/op 1.17
Buffer.compare 16384 - random bytes 60.077 ns/op 36.988 ns/op 1.62
byteArrayEquals 123687377 - random bytes 8.3300 ns/op 7.3500 ns/op 1.13
Buffer.compare 123687377 - random bytes 61.980 ns/op 46.090 ns/op 1.34
regular array get 100000 times 44.679 us/op 42.562 us/op 1.05
wrappedArray get 100000 times 44.683 us/op 42.129 us/op 1.06
arrayWithProxy get 100000 times 14.515 ms/op 9.8656 ms/op 1.47
ssz.Root.equals 55.326 ns/op 56.228 ns/op 0.98
byteArrayEquals 54.536 ns/op 57.189 ns/op 0.95
Buffer.compare 11.508 ns/op 9.5750 ns/op 1.20
shuffle list - 16384 els 7.1020 ms/op 4.7380 ms/op 1.50
shuffle list - 250000 els 104.16 ms/op 70.468 ms/op 1.48
processSlot - 1 slots 16.974 us/op 16.876 us/op 1.01
processSlot - 32 slots 3.6258 ms/op 2.6759 ms/op 1.35
getEffectiveBalanceIncrementsZeroInactive - 250000 vs - 7PWei 55.085 ms/op 51.872 ms/op 1.06
getCommitteeAssignments - req 1 vs - 250000 vc 2.4832 ms/op 2.2554 ms/op 1.10
getCommitteeAssignments - req 100 vs - 250000 vc 3.5669 ms/op 3.4010 ms/op 1.05
getCommitteeAssignments - req 1000 vs - 250000 vc 3.8554 ms/op 3.7177 ms/op 1.04
findModifiedValidators - 10000 modified validators 521.43 ms/op 450.27 ms/op 1.16
findModifiedValidators - 1000 modified validators 427.43 ms/op 352.50 ms/op 1.21
findModifiedValidators - 100 modified validators 401.96 ms/op 326.35 ms/op 1.23
findModifiedValidators - 10 modified validators 446.17 ms/op 335.22 ms/op 1.33
findModifiedValidators - 1 modified validators 392.93 ms/op 339.26 ms/op 1.16
findModifiedValidators - no difference 422.97 ms/op 317.31 ms/op 1.33
compare ViewDUs 4.3951 s/op 3.6755 s/op 1.20
compare each validator Uint8Array 1.4423 s/op 926.57 ms/op 1.56
compare ViewDU to Uint8Array 1.3331 s/op 908.79 ms/op 1.47
migrate state 1000000 validators, 24 modified, 0 new 828.85 ms/op 656.50 ms/op 1.26
migrate state 1000000 validators, 1700 modified, 1000 new 1.1720 s/op 1.0806 s/op 1.08
migrate state 1000000 validators, 3400 modified, 2000 new 1.4498 s/op 1.3965 s/op 1.04
migrate state 1500000 validators, 24 modified, 0 new 993.22 ms/op 710.62 ms/op 1.40
migrate state 1500000 validators, 1700 modified, 1000 new 1.1004 s/op 951.86 ms/op 1.16
migrate state 1500000 validators, 3400 modified, 2000 new 1.3011 s/op 1.1503 s/op 1.13
RootCache.getBlockRootAtSlot - 250000 vs - 7PWei 4.2300 ns/op 3.4500 ns/op 1.23
state getBlockRootAtSlot - 250000 vs - 7PWei 760.47 ns/op 627.71 ns/op 1.21
computeProposers - vc 250000 9.3263 ms/op 5.9566 ms/op 1.57
computeEpochShuffling - vc 250000 103.32 ms/op 66.530 ms/op 1.55
getNextSyncCommittee - vc 250000 149.73 ms/op 100.73 ms/op 1.49
computeSigningRoot for AttestationData 25.908 us/op 25.667 us/op 1.01
hash AttestationData serialized data then Buffer.toString(base64) 2.2573 us/op 1.1808 us/op 1.91
toHexString serialized data 1.0464 us/op 738.78 ns/op 1.42
Buffer.toString(base64) 195.42 ns/op 152.80 ns/op 1.28

Please sign in to comment.