From 0282fff31353a2bca4903faf481bebec0f6f891c Mon Sep 17 00:00:00 2001 From: Julien Eluard Date: Mon, 5 Feb 2024 11:32:45 +0100 Subject: [PATCH] feat: emit slashing events --- packages/api/src/beacon/routes/events.ts | 10 +++ .../api/test/unit/beacon/testData/events.ts | 62 +++++++++++++++++++ .../src/chain/blocks/importBlock.ts | 10 +++ .../src/network/processor/gossipHandlers.ts | 4 ++ 4 files changed, 86 insertions(+) diff --git a/packages/api/src/beacon/routes/events.ts b/packages/api/src/beacon/routes/events.ts index 41a8e2e9cad9..1db61bafafbd 100644 --- a/packages/api/src/beacon/routes/events.ts +++ b/packages/api/src/beacon/routes/events.ts @@ -35,6 +35,10 @@ export enum EventType { attestation = "attestation", /** The node has received a valid voluntary exit (from P2P or API) */ voluntaryExit = "voluntary_exit", + /** The node has received a ProposerSlashing (from P2P or API) that passes validation rules of the `proposer_slashing` topic */ + proposerSlashing = "proposer_slashing", + /** The node has received an AttesterSlashing (from P2P or API) that passes validation rules of the `attester_slashing` topic */ + attesterSlashing = "attester_slashing", /** The node has received a valid blsToExecutionChange (from P2P or API) */ blsToExecutionChange = "bls_to_execution_change", /** Finalized checkpoint has been updated */ @@ -58,6 +62,8 @@ export const eventTypes: {[K in EventType]: K} = { [EventType.block]: EventType.block, [EventType.attestation]: EventType.attestation, [EventType.voluntaryExit]: EventType.voluntaryExit, + [EventType.proposerSlashing]: EventType.proposerSlashing, + [EventType.attesterSlashing]: EventType.attesterSlashing, [EventType.blsToExecutionChange]: EventType.blsToExecutionChange, [EventType.finalizedCheckpoint]: EventType.finalizedCheckpoint, [EventType.chainReorg]: EventType.chainReorg, @@ -85,6 +91,8 @@ export type EventData = { }; [EventType.attestation]: phase0.Attestation; [EventType.voluntaryExit]: phase0.SignedVoluntaryExit; + [EventType.proposerSlashing]: phase0.ProposerSlashing; + [EventType.attesterSlashing]: phase0.AttesterSlashing; [EventType.blsToExecutionChange]: capella.SignedBLSToExecutionChange; [EventType.finalizedCheckpoint]: { block: RootHex; @@ -174,6 +182,8 @@ export function getTypeByEvent(): {[K in EventType]: TypeJson} { [EventType.attestation]: ssz.phase0.Attestation, [EventType.voluntaryExit]: ssz.phase0.SignedVoluntaryExit, + [EventType.proposerSlashing]: ssz.phase0.ProposerSlashing, + [EventType.attesterSlashing]: ssz.phase0.AttesterSlashing, [EventType.blsToExecutionChange]: ssz.capella.SignedBLSToExecutionChange, [EventType.finalizedCheckpoint]: new ContainerType( diff --git a/packages/api/test/unit/beacon/testData/events.ts b/packages/api/test/unit/beacon/testData/events.ts index 7bfac9a59a88..08dd27e09d76 100644 --- a/packages/api/test/unit/beacon/testData/events.ts +++ b/packages/api/test/unit/beacon/testData/events.ts @@ -48,6 +48,68 @@ export const eventTestData: EventData = { signature: "0x1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505cc411d61252fb6cb3fa0017b679f8bb2305b26a285fa2737f175668d0dff91cc1b66ac1fb663c9bc59509846d6ec05345bd908eda73e670af888da41af171505", }), + [EventType.proposerSlashing]: ssz.phase0.ProposerSlashing.fromJson({ + signed_header_1: { + message: { + slot: "0", + proposer_index: "0", + parent_root: "0x0000000000000000000000000000000000000000000000000000000000000000", + state_root: "0x0000000000000000000000000000000000000000000000000000000000000000", + body_root: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, + signature: + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }, + signed_header_2: { + message: { + slot: "0", + proposer_index: "0", + parent_root: "0x0000000000000000000000000000000000000000000000000000000000000000", + state_root: "0x0000000000000000000000000000000000000000000000000000000000000000", + body_root: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, + signature: + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }, + }), + [EventType.attesterSlashing]: ssz.phase0.AttesterSlashing.fromJson({ + attestation_1: { + attesting_indices: ["0", "1"], + data: { + slot: "0", + index: "0", + beacon_block_root: "0x0000000000000000000000000000000000000000000000000000000000000000", + source: { + epoch: "0", + root: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, + target: { + epoch: "0", + root: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, + }, + signature: + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }, + attestation_2: { + attesting_indices: ["0", "1"], + data: { + slot: "0", + index: "0", + beacon_block_root: "0x0000000000000000000000000000000000000000000000000000000000000000", + source: { + epoch: "0", + root: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, + target: { + epoch: "0", + root: "0x0000000000000000000000000000000000000000000000000000000000000000", + }, + }, + signature: + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + }, + }), [EventType.blsToExecutionChange]: ssz.capella.SignedBLSToExecutionChange.fromJson({ message: { validator_index: "1", diff --git a/packages/beacon-node/src/chain/blocks/importBlock.ts b/packages/beacon-node/src/chain/blocks/importBlock.ts index 89ed52b66750..c8fc62eaa622 100644 --- a/packages/beacon-node/src/chain/blocks/importBlock.ts +++ b/packages/beacon-node/src/chain/blocks/importBlock.ts @@ -414,6 +414,16 @@ export async function importBlock( this.emitter.emit(routes.events.EventType.attestation, attestation); } } + if (this.emitter.listenerCount(routes.events.EventType.attesterSlashing)) { + for (const attesterSlashing of block.message.body.attesterSlashings) { + this.emitter.emit(routes.events.EventType.attesterSlashing, attesterSlashing); + } + } + if (this.emitter.listenerCount(routes.events.EventType.proposerSlashing)) { + for (const proposerSlashing of block.message.body.proposerSlashings) { + this.emitter.emit(routes.events.EventType.proposerSlashing, proposerSlashing); + } + } } // Register stat metrics about the block after importing it diff --git a/packages/beacon-node/src/network/processor/gossipHandlers.ts b/packages/beacon-node/src/network/processor/gossipHandlers.ts index 9073a204b785..bdd5f1917dc5 100644 --- a/packages/beacon-node/src/network/processor/gossipHandlers.ts +++ b/packages/beacon-node/src/network/processor/gossipHandlers.ts @@ -453,6 +453,8 @@ function getDefaultHandlers(modules: ValidatorFnsModules, options: GossipHandler } catch (e) { logger.error("Error adding attesterSlashing to pool", {}, e as Error); } + + chain.emitter.emit(routes.events.EventType.attesterSlashing, attesterSlashing); }, [GossipType.proposer_slashing]: async ({ @@ -470,6 +472,8 @@ function getDefaultHandlers(modules: ValidatorFnsModules, options: GossipHandler } catch (e) { logger.error("Error adding attesterSlashing to pool", {}, e as Error); } + + chain.emitter.emit(routes.events.EventType.proposerSlashing, proposerSlashing); }, [GossipType.voluntary_exit]: async ({gossipData, topic}: GossipHandlerParamGeneric) => {