-
-
Notifications
You must be signed in to change notification settings - Fork 272
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
228d7ba
commit 2ea45a3
Showing
4 changed files
with
233 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import {CachedBeaconStateAltair} from "@lodestar/state-transition"; | ||
import {capella} from "@lodestar/types"; | ||
|
||
export function generateBlsToExecutionChanges( | ||
state: CachedBeaconStateAltair, | ||
count: number | ||
): capella.SignedBLSToExecutionChange[] { | ||
const result: capella.SignedBLSToExecutionChange[] = []; | ||
|
||
for (const validatorIndex of state.epochCtx.proposers) { | ||
result.push({ | ||
message: { | ||
fromBlsPubkey: state.epochCtx.index2pubkey[validatorIndex].toBytes(), | ||
toExecutionAddress: Buffer.alloc(20), | ||
validatorIndex, | ||
}, | ||
signature: Buffer.alloc(96), | ||
}); | ||
|
||
if (result.length >= count) return result; | ||
} | ||
|
||
return result; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import {SLOTS_PER_EPOCH} from "@lodestar/params"; | ||
import { | ||
CachedBeaconStateAltair, | ||
computeEpochAtSlot, | ||
computeStartSlotAtEpoch, | ||
getBlockRootAtSlot, | ||
} from "@lodestar/state-transition"; | ||
import {phase0} from "@lodestar/types"; | ||
|
||
export function generateIndexedAttestations( | ||
state: CachedBeaconStateAltair, | ||
count: number | ||
): phase0.IndexedAttestation[] { | ||
const result: phase0.IndexedAttestation[] = []; | ||
|
||
for (let epochSlot = 0; epochSlot < SLOTS_PER_EPOCH; epochSlot++) { | ||
const slot = state.slot - 1 - epochSlot; | ||
const epoch = computeEpochAtSlot(slot); | ||
const committeeCount = state.epochCtx.getCommitteeCountPerSlot(epoch); | ||
|
||
for (let committeeIndex = 0; committeeIndex < committeeCount; committeeIndex++) { | ||
result.push({ | ||
attestingIndices: state.epochCtx.getBeaconCommittee(slot, committeeIndex), | ||
data: { | ||
slot: slot, | ||
index: committeeIndex, | ||
beaconBlockRoot: getBlockRootAtSlot(state, slot), | ||
source: { | ||
epoch: state.currentJustifiedCheckpoint.epoch, | ||
root: state.currentJustifiedCheckpoint.root, | ||
}, | ||
target: { | ||
epoch: epoch, | ||
root: getBlockRootAtSlot(state, computeStartSlotAtEpoch(epoch)), | ||
}, | ||
}, | ||
signature: Buffer.alloc(96), | ||
}); | ||
|
||
if (result.length >= count) return result; | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
export function generateBeaconBlockHeader(state: CachedBeaconStateAltair, count: number): phase0.BeaconBlockHeader[] { | ||
const headers: phase0.BeaconBlockHeader[] = []; | ||
|
||
for (let i = 1; i <= count; i++) { | ||
const slot = state.slot - i; | ||
const epoch = computeEpochAtSlot(slot); | ||
const epochStartSlot = computeStartSlotAtEpoch(epoch); | ||
const parentRoot = getBlockRootAtSlot(state, slot - 1); | ||
const stateRoot = getBlockRootAtSlot(state, epochStartSlot); | ||
const bodyRoot = getBlockRootAtSlot(state, epochStartSlot + 1); | ||
const header: phase0.BeaconBlockHeader = { | ||
slot, | ||
proposerIndex: state.epochCtx.proposers[slot % SLOTS_PER_EPOCH], | ||
parentRoot, | ||
stateRoot, | ||
bodyRoot, | ||
}; | ||
|
||
headers.push(header); | ||
} | ||
return headers; | ||
} | ||
|
||
export function generateSignedBeaconBlockHeader( | ||
state: CachedBeaconStateAltair, | ||
count: number | ||
): phase0.SignedBeaconBlockHeader[] { | ||
const headers = generateBeaconBlockHeader(state, count); | ||
|
||
return headers.map((header) => ({ | ||
message: header, | ||
signature: Buffer.alloc(96), | ||
})); | ||
} | ||
|
||
export function generateVoluntaryExits(state: CachedBeaconStateAltair, count: number): phase0.SignedVoluntaryExit[] { | ||
const result: phase0.SignedVoluntaryExit[] = []; | ||
|
||
for (const validatorIndex of state.epochCtx.proposers) { | ||
result.push({ | ||
message: { | ||
epoch: state.currentJustifiedCheckpoint.epoch, | ||
validatorIndex, | ||
}, | ||
signature: Buffer.alloc(96), | ||
}); | ||
|
||
if (result.length >= count) return result; | ||
} | ||
|
||
return result; | ||
} |
109 changes: 109 additions & 0 deletions
109
packages/beacon-node/test/perf/chain/opPools/opPool.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import {itBench} from "@dapplion/benchmark"; | ||
import { | ||
MAX_ATTESTER_SLASHINGS, | ||
MAX_BLS_TO_EXECUTION_CHANGES, | ||
MAX_PROPOSER_SLASHINGS, | ||
MAX_VOLUNTARY_EXITS, | ||
} from "@lodestar/params"; | ||
import {CachedBeaconStateAltair} from "@lodestar/state-transition"; | ||
import {ssz} from "@lodestar/types"; | ||
// eslint-disable-next-line import/no-relative-packages | ||
import {generatePerfTestCachedStateAltair} from "../../../../../state-transition/test/perf/util.js"; | ||
import {OpPool} from "../../../../src/chain/opPools/opPool.js"; | ||
import {generateBlsToExecutionChanges} from "../../../fixtures/capella.js"; | ||
import { | ||
generateIndexedAttestations, | ||
generateSignedBeaconBlockHeader, | ||
generateVoluntaryExits, | ||
} from "../../../fixtures/phase0.js"; | ||
|
||
// Aug 11 2021 | ||
// getAttestationsForBlock | ||
// ✓ getAttestationsForBlock 4.410948 ops/s 226.7086 ms/op - 64 runs 51.8 s | ||
describe("opPool", () => { | ||
let originalState: CachedBeaconStateAltair; | ||
|
||
before(function () { | ||
this.timeout(2 * 60 * 1000); // Generating the states for the first time is very slow | ||
|
||
originalState = generatePerfTestCachedStateAltair({goBackOneSlot: true}); | ||
}); | ||
|
||
itBench({ | ||
id: "getSlashingsAndExits - default max", | ||
beforeEach: () => { | ||
const pool = new OpPool(); | ||
fillAttesterSlashing(pool, originalState, MAX_ATTESTER_SLASHINGS); | ||
fillProposerSlashing(pool, originalState, MAX_PROPOSER_SLASHINGS); | ||
fillVoluntaryExits(pool, originalState, MAX_VOLUNTARY_EXITS); | ||
fillBlsToExecutionChanges(pool, originalState, MAX_BLS_TO_EXECUTION_CHANGES); | ||
|
||
return pool; | ||
}, | ||
fn: (pool) => { | ||
pool.getSlashingsAndExits(originalState); | ||
}, | ||
}); | ||
|
||
itBench({ | ||
id: "getSlashingsAndExits - 2k", | ||
beforeEach: () => { | ||
const pool = new OpPool(); | ||
const maxItemsInPool = 2_000; | ||
|
||
fillAttesterSlashing(pool, originalState, maxItemsInPool); | ||
fillProposerSlashing(pool, originalState, maxItemsInPool); | ||
fillVoluntaryExits(pool, originalState, maxItemsInPool); | ||
fillBlsToExecutionChanges(pool, originalState, maxItemsInPool); | ||
|
||
return pool; | ||
}, | ||
fn: (pool) => { | ||
pool.getSlashingsAndExits(originalState); | ||
}, | ||
}); | ||
}); | ||
|
||
function fillAttesterSlashing(pool: OpPool, state: CachedBeaconStateAltair, count: number): OpPool { | ||
for (const attestation of generateIndexedAttestations(state, count)) { | ||
pool.insertAttesterSlashing({ | ||
attestation1: ssz.phase0.IndexedAttestationBigint.fromJson(ssz.phase0.IndexedAttestation.toJson(attestation)), | ||
attestation2: ssz.phase0.IndexedAttestationBigint.fromJson(ssz.phase0.IndexedAttestation.toJson(attestation)), | ||
}); | ||
} | ||
|
||
return pool; | ||
} | ||
|
||
function fillProposerSlashing(pool: OpPool, state: CachedBeaconStateAltair, count: number): OpPool { | ||
for (const blockHeader of generateSignedBeaconBlockHeader(state, count)) { | ||
pool.insertProposerSlashing({ | ||
signedHeader1: ssz.phase0.SignedBeaconBlockHeaderBigint.fromJson( | ||
ssz.phase0.SignedBeaconBlockHeader.toJson(blockHeader) | ||
), | ||
signedHeader2: ssz.phase0.SignedBeaconBlockHeaderBigint.fromJson( | ||
ssz.phase0.SignedBeaconBlockHeader.toJson(blockHeader) | ||
), | ||
}); | ||
} | ||
|
||
return pool; | ||
} | ||
|
||
function fillVoluntaryExits(pool: OpPool, state: CachedBeaconStateAltair, count: number): OpPool { | ||
for (const exit of generateVoluntaryExits(state, count)) { | ||
pool.insertVoluntaryExit(exit); | ||
} | ||
|
||
return pool; | ||
} | ||
|
||
// This does not set the `withdrawalCredentials` for the validator | ||
// So it will be in the pool but not returned from `getSlashingsAndExits` | ||
function fillBlsToExecutionChanges(pool: OpPool, state: CachedBeaconStateAltair, count: number): OpPool { | ||
for (const blsToExecution of generateBlsToExecutionChanges(state, count)) { | ||
pool.insertBlsToExecutionChange(blsToExecution); | ||
} | ||
|
||
return pool; | ||
} |