Files
lodestar/packages/beacon-node/test/perf/eth1/pickEth1Vote.test.ts

99 lines
3.9 KiB
TypeScript

import {bench, describe, setBenchOpts} from "@chainsafe/benchmark";
import {ContainerType, ListCompositeType} from "@chainsafe/ssz";
import {BeaconStateAllForks, newFilledArray} from "@lodestar/state-transition";
import {phase0, ssz} from "@lodestar/types";
import {fastSerializeEth1Data, pickEth1Vote} from "../../../src/eth1/utils/eth1Vote.js";
describe("eth1 / pickEth1Vote", () => {
const ETH1_FOLLOW_DISTANCE_MAINNET = 2048;
const EPOCHS_PER_ETH1_VOTING_PERIOD_MAINNET = 64;
const SLOTS_PER_EPOCH_MAINNET = 32;
const eth1DataVotesLimit = EPOCHS_PER_ETH1_VOTING_PERIOD_MAINNET * SLOTS_PER_EPOCH_MAINNET;
const stateMainnetType = new ContainerType({
eth1DataVotes: new ListCompositeType(ssz.phase0.Eth1Data, eth1DataVotesLimit),
});
const stateNoVotes = stateMainnetType.defaultViewDU();
const stateMaxVotes = stateMainnetType.defaultViewDU();
// Must convert all instances to create a cache
stateMaxVotes.eth1DataVotes = ssz.phase0.Eth1DataVotes.toViewDU(
newFilledArray(eth1DataVotesLimit, {
depositRoot: Buffer.alloc(32, 0xdd),
// All votes are the same
depositCount: 1e6,
blockHash: Buffer.alloc(32, 0xdd),
})
);
stateMaxVotes.commit();
// votesToConsider range:
// lte: periodStart - SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE,
// gte: periodStart - SECONDS_PER_ETH1_BLOCK * ETH1_FOLLOW_DISTANCE * 2,
const votesToConsider = Array.from({length: ETH1_FOLLOW_DISTANCE_MAINNET}, (_, i) => ({
depositRoot: Buffer.alloc(32, 0xdd),
// Each eth1Data is different
depositCount: 1e6 + i,
blockHash: Buffer.alloc(32, 0xdd),
}));
bench("pickEth1Vote - no votes", () => {
pickEth1Vote(stateNoVotes as unknown as BeaconStateAllForks, votesToConsider);
});
bench("pickEth1Vote - max votes", () => {
pickEth1Vote(stateMaxVotes as unknown as BeaconStateAllForks, votesToConsider);
});
});
// Results in Linux Feb 2022
//
// eth1 / pickEth1Vote serializers
// ✓ pickEth1Vote - Eth1Data hashTreeRoot value x2048 58.45559 ops/s 17.10700 ms/op - 45 runs 1.27 s
// ✓ pickEth1Vote - Eth1Data hashTreeRoot tree x2048 122.1150 ops/s 8.189003 ms/op - 65 runs 1.75 s
// ✓ pickEth1Vote - Eth1Data fastSerialize value x2048 533.9807 ops/s 1.872727 ms/op - 272 runs 1.01 s
// ✓ pickEth1Vote - Eth1Data fastSerialize tree x2048 59.49406 ops/s 16.80840 ms/op - 60 runs 1.51 s
describe("eth1 / pickEth1Vote serializers", () => {
setBenchOpts({noThreshold: true});
const ETH1_FOLLOW_DISTANCE_MAINNET = 2048;
const eth1DataValue: phase0.Eth1Data = {
depositRoot: Buffer.alloc(32, 0xdd),
depositCount: 1e6,
blockHash: Buffer.alloc(32, 0xdd),
};
const eth1DataTree = ssz.phase0.Eth1Data.toViewDU(eth1DataValue);
bench(`pickEth1Vote - Eth1Data hashTreeRoot value x${ETH1_FOLLOW_DISTANCE_MAINNET}`, () => {
for (let i = 0; i < ETH1_FOLLOW_DISTANCE_MAINNET; i++) {
ssz.phase0.Eth1Data.hashTreeRoot(eth1DataValue);
}
});
// Create new copies of eth1DataTree to drop the hashing cache
bench({
id: `pickEth1Vote - Eth1Data hashTreeRoot tree x${ETH1_FOLLOW_DISTANCE_MAINNET}`,
beforeEach: () =>
Array.from({length: ETH1_FOLLOW_DISTANCE_MAINNET}, () => ssz.phase0.Eth1Data.toViewDU(eth1DataValue)),
fn: (eth1DataTrees) => {
for (let i = 0; i < eth1DataTrees.length; i++) {
ssz.phase0.Eth1Data.hashTreeRoot(eth1DataTrees[i]);
}
},
});
bench(`pickEth1Vote - Eth1Data fastSerialize value x${ETH1_FOLLOW_DISTANCE_MAINNET}`, () => {
for (let i = 0; i < ETH1_FOLLOW_DISTANCE_MAINNET; i++) {
fastSerializeEth1Data(eth1DataValue);
}
});
bench(`pickEth1Vote - Eth1Data fastSerialize tree x${ETH1_FOLLOW_DISTANCE_MAINNET}`, () => {
for (let i = 0; i < ETH1_FOLLOW_DISTANCE_MAINNET; i++) {
fastSerializeEth1Data(eth1DataTree);
}
});
});