From 9266bd3bedeb90f43e860e6cc9f4437995f4af22 Mon Sep 17 00:00:00 2001 From: harkamal Date: Mon, 8 Nov 2021 20:49:17 +0530 Subject: [PATCH] spec runner merge sanity and operations fixes --- .../src/merge/block/index.ts | 8 +++- .../merge/block/processAttesterSlashing.ts | 17 +++++++ .../src/merge/block/processOperations.ts | 44 +++++++++++++++++++ .../merge/block/processProposerSlashing.ts | 17 +++++++ .../src/merge/epoch/index.ts | 1 + .../src/merge/epoch/processSlashings.ts | 8 ++++ .../src/merge/index.ts | 5 ++- .../test/spec/merge/epoch_processing.test.ts | 4 +- .../test/spec/merge/operations.test.ts | 20 ++++----- 9 files changed, 108 insertions(+), 16 deletions(-) create mode 100644 packages/beacon-state-transition/src/merge/block/processAttesterSlashing.ts create mode 100644 packages/beacon-state-transition/src/merge/block/processOperations.ts create mode 100644 packages/beacon-state-transition/src/merge/block/processProposerSlashing.ts create mode 100644 packages/beacon-state-transition/src/merge/epoch/index.ts create mode 100644 packages/beacon-state-transition/src/merge/epoch/processSlashings.ts diff --git a/packages/beacon-state-transition/src/merge/block/index.ts b/packages/beacon-state-transition/src/merge/block/index.ts index ac8d3a53f915..ec25375e87fd 100644 --- a/packages/beacon-state-transition/src/merge/block/index.ts +++ b/packages/beacon-state-transition/src/merge/block/index.ts @@ -2,11 +2,15 @@ import {allForks, altair, merge} from "@chainsafe/lodestar-types"; import {CachedBeaconState} from "../../allForks/util"; import {processBlockHeader, processEth1Data, processRandao} from "../../allForks/block"; -import {processOperations} from "../../altair/block/processOperations"; +import {processOperations} from "./processOperations"; import {processSyncAggregate} from "../../altair/block/processSyncCommittee"; import {processExecutionPayload} from "./processExecutionPayload"; import {ExecutionEngine} from "../executionEngine"; import {isExecutionEnabled} from "../utils"; +import {processAttesterSlashing} from "./processAttesterSlashing"; +import {processProposerSlashing} from "./processProposerSlashing"; + +export {processOperations, processAttesterSlashing, processProposerSlashing}; export function processBlock( state: CachedBeaconState, @@ -23,6 +27,6 @@ export function processBlock( processRandao(state as CachedBeaconState, block, verifySignatures); processEth1Data(state as CachedBeaconState, block.body); - processOperations((state as unknown) as CachedBeaconState, block.body, verifySignatures); + processOperations(state, block.body, verifySignatures); processSyncAggregate((state as unknown) as CachedBeaconState, block, verifySignatures); } diff --git a/packages/beacon-state-transition/src/merge/block/processAttesterSlashing.ts b/packages/beacon-state-transition/src/merge/block/processAttesterSlashing.ts new file mode 100644 index 000000000000..10135559479c --- /dev/null +++ b/packages/beacon-state-transition/src/merge/block/processAttesterSlashing.ts @@ -0,0 +1,17 @@ +import {allForks, merge, phase0} from "@chainsafe/lodestar-types"; +import {ForkName} from "@chainsafe/lodestar-params"; +import {CachedBeaconState} from "../../allForks/util"; +import {processAttesterSlashing as processAttesterSlashingAllForks} from "../../allForks/block"; + +export function processAttesterSlashing( + state: CachedBeaconState, + attesterSlashing: phase0.AttesterSlashing, + verifySignatures = true +): void { + processAttesterSlashingAllForks( + ForkName.merge, + state as CachedBeaconState, + attesterSlashing, + verifySignatures + ); +} diff --git a/packages/beacon-state-transition/src/merge/block/processOperations.ts b/packages/beacon-state-transition/src/merge/block/processOperations.ts new file mode 100644 index 000000000000..7d625ee19f46 --- /dev/null +++ b/packages/beacon-state-transition/src/merge/block/processOperations.ts @@ -0,0 +1,44 @@ +import {readonlyValues} from "@chainsafe/ssz"; +import {altair, merge} from "@chainsafe/lodestar-types"; + +import {CachedBeaconState} from "../../allForks/util"; +import {processProposerSlashing} from "./processProposerSlashing"; +import {processAttesterSlashing} from "./processAttesterSlashing"; +import {processAttestations} from "../../altair/block/processAttestation"; +import {processDeposit} from "../../altair/block/processDeposit"; +import {processVoluntaryExit} from "../../altair/block/processVoluntaryExit"; +import {MAX_DEPOSITS} from "@chainsafe/lodestar-params"; + +export function processOperations( + state: CachedBeaconState, + body: merge.BeaconBlockBody, + verifySignatures = true +): void { + // verify that outstanding deposits are processed up to the maximum number of deposits + const maxDeposits = Math.min(MAX_DEPOSITS, state.eth1Data.depositCount - state.eth1DepositIndex); + if (body.deposits.length !== maxDeposits) { + throw new Error( + `Block contains incorrect number of deposits: depositCount=${body.deposits.length} expected=${maxDeposits}` + ); + } + + for (const proposerSlashing of readonlyValues(body.proposerSlashings)) { + processProposerSlashing(state, proposerSlashing, verifySignatures); + } + for (const attesterSlashing of readonlyValues(body.attesterSlashings)) { + processAttesterSlashing(state, attesterSlashing, verifySignatures); + } + + processAttestations( + (state as unknown) as CachedBeaconState, + Array.from(readonlyValues(body.attestations)), + verifySignatures + ); + + for (const deposit of readonlyValues(body.deposits)) { + processDeposit((state as unknown) as CachedBeaconState, deposit); + } + for (const voluntaryExit of readonlyValues(body.voluntaryExits)) { + processVoluntaryExit((state as unknown) as CachedBeaconState, voluntaryExit, verifySignatures); + } +} diff --git a/packages/beacon-state-transition/src/merge/block/processProposerSlashing.ts b/packages/beacon-state-transition/src/merge/block/processProposerSlashing.ts new file mode 100644 index 000000000000..4162fc13c3c3 --- /dev/null +++ b/packages/beacon-state-transition/src/merge/block/processProposerSlashing.ts @@ -0,0 +1,17 @@ +import {allForks, merge, phase0} from "@chainsafe/lodestar-types"; +import {ForkName} from "@chainsafe/lodestar-params"; +import {CachedBeaconState} from "../../allForks/util"; +import {processProposerSlashing as processProposerSlashingAllForks} from "../../allForks/block"; + +export function processProposerSlashing( + state: CachedBeaconState, + proposerSlashing: phase0.ProposerSlashing, + verifySignatures = true +): void { + processProposerSlashingAllForks( + ForkName.merge, + state as CachedBeaconState, + proposerSlashing, + verifySignatures + ); +} diff --git a/packages/beacon-state-transition/src/merge/epoch/index.ts b/packages/beacon-state-transition/src/merge/epoch/index.ts new file mode 100644 index 000000000000..5cf1ff67e89d --- /dev/null +++ b/packages/beacon-state-transition/src/merge/epoch/index.ts @@ -0,0 +1 @@ +export {processSlashings} from "./processSlashings"; diff --git a/packages/beacon-state-transition/src/merge/epoch/processSlashings.ts b/packages/beacon-state-transition/src/merge/epoch/processSlashings.ts new file mode 100644 index 000000000000..579915b2691a --- /dev/null +++ b/packages/beacon-state-transition/src/merge/epoch/processSlashings.ts @@ -0,0 +1,8 @@ +import {allForks, merge} from "@chainsafe/lodestar-types"; +import {ForkName} from "@chainsafe/lodestar-params"; +import {CachedBeaconState, IEpochProcess} from "../../allForks/util"; +import {processSlashingsAllForks} from "../../allForks/epoch/processSlashings"; + +export function processSlashings(state: CachedBeaconState, epochProcess: IEpochProcess): void { + processSlashingsAllForks(ForkName.merge, state as CachedBeaconState, epochProcess); +} diff --git a/packages/beacon-state-transition/src/merge/index.ts b/packages/beacon-state-transition/src/merge/index.ts index e94ddb31653a..273834de561d 100644 --- a/packages/beacon-state-transition/src/merge/index.ts +++ b/packages/beacon-state-transition/src/merge/index.ts @@ -1,5 +1,6 @@ -export {processBlock} from "./block"; -export {upgradeState} from "./upgradeState"; +export * from "./block"; +export * from "./epoch"; +export * from "./upgradeState"; export * from "./utils"; // re-export merge lodestar types for ergonomic usage downstream diff --git a/packages/spec-test-runner/test/spec/merge/epoch_processing.test.ts b/packages/spec-test-runner/test/spec/merge/epoch_processing.test.ts index c5ae9039f0d6..52b6c21df8a6 100644 --- a/packages/spec-test-runner/test/spec/merge/epoch_processing.test.ts +++ b/packages/spec-test-runner/test/spec/merge/epoch_processing.test.ts @@ -1,4 +1,4 @@ -import {allForks, altair} from "@chainsafe/lodestar-beacon-state-transition"; +import {allForks, altair, merge} from "@chainsafe/lodestar-beacon-state-transition"; import {processParticipationRecordUpdates} from "@chainsafe/lodestar-beacon-state-transition/src/phase0/epoch/processParticipationRecordUpdates"; import {ForkName} from "@chainsafe/lodestar-params"; import {EpochProcessFn, epochProcessing} from "../allForks/epochProcessing"; @@ -18,7 +18,7 @@ epochProcessing(ForkName.merge, { randao_mixes_reset: allForks.processRandaoMixesReset, registry_updates: allForks.processRegistryUpdates, rewards_and_penalties: altair.processRewardsAndPenalties as EpochProcessFn, - slashings: altair.processSlashings as EpochProcessFn, + slashings: merge.processSlashings as EpochProcessFn, slashings_reset: allForks.processSlashingsReset, sync_committee_updates: altair.processSyncCommitteeUpdates as EpochProcessFn, }); diff --git a/packages/spec-test-runner/test/spec/merge/operations.test.ts b/packages/spec-test-runner/test/spec/merge/operations.test.ts index b05f590b7e7a..2f96a7a070ac 100644 --- a/packages/spec-test-runner/test/spec/merge/operations.test.ts +++ b/packages/spec-test-runner/test/spec/merge/operations.test.ts @@ -1,5 +1,5 @@ -import {CachedBeaconState, allForks, altair} from "@chainsafe/lodestar-beacon-state-transition"; -import {phase0, merge, ssz} from "@chainsafe/lodestar-types"; +import {CachedBeaconState, allForks, altair, merge} from "@chainsafe/lodestar-beacon-state-transition"; +import {phase0, ssz} from "@chainsafe/lodestar-types"; import {ForkName} from "@chainsafe/lodestar-params"; import {IBaseSpecTest} from "../type"; import {operations, BlockProcessFn} from "../allForks/operations"; @@ -9,7 +9,7 @@ import {processExecutionPayload} from "@chainsafe/lodestar-beacon-state-transiti /* eslint-disable @typescript-eslint/naming-convention */ // Define above to re-use in sync_aggregate and sync_aggregate_random -const sync_aggregate: BlockProcessFn = ( +const sync_aggregate: BlockProcessFn = ( state, testCase: IBaseSpecTest & {sync_aggregate: altair.SyncAggregate} ) => { @@ -19,17 +19,17 @@ const sync_aggregate: BlockProcessFn = ( block.slot = state.slot; block.body.syncAggregate = testCase["sync_aggregate"]; - altair.processSyncAggregate(state, block); + altair.processSyncAggregate((state as unknown) as CachedBeaconState, block); }; -operations(ForkName.merge, { +operations(ForkName.merge, { attestation: (state, testCase: IBaseSpecTest & {attestation: phase0.Attestation}) => { - altair.processAttestations(state, [testCase.attestation]); + altair.processAttestations((state as unknown) as CachedBeaconState, [testCase.attestation]); }, attester_slashing: (state, testCase: IBaseSpecTest & {attester_slashing: phase0.AttesterSlashing}) => { const verify = !!testCase.meta && !!testCase.meta.blsSetting && testCase.meta.blsSetting === BigInt(1); - altair.processAttesterSlashing(state, testCase.attester_slashing, verify); + merge.processAttesterSlashing(state, testCase.attester_slashing, verify); }, block_header: (state, testCase: IBaseSpecTest & {block: altair.BeaconBlock}) => { @@ -37,18 +37,18 @@ operations(ForkName.merge, { }, deposit: (state, testCase: IBaseSpecTest & {deposit: phase0.Deposit}) => { - altair.processDeposit(state, testCase.deposit); + altair.processDeposit((state as unknown) as CachedBeaconState, testCase.deposit); }, proposer_slashing: (state, testCase: IBaseSpecTest & {proposer_slashing: phase0.ProposerSlashing}) => { - altair.processProposerSlashing(state, testCase.proposer_slashing); + merge.processProposerSlashing(state, testCase.proposer_slashing); }, sync_aggregate, sync_aggregate_random: sync_aggregate, voluntary_exit: (state, testCase: IBaseSpecTest & {voluntary_exit: phase0.SignedVoluntaryExit}) => { - altair.processVoluntaryExit(state, testCase.voluntary_exit); + altair.processVoluntaryExit((state as unknown) as CachedBeaconState, testCase.voluntary_exit); }, execution_payload: (