From fa0a851aa681e9bdf50b508b2ca625ad3e015227 Mon Sep 17 00:00:00 2001 From: Tuyen Nguyen Date: Tue, 29 Oct 2024 14:51:35 +0700 Subject: [PATCH 1/2] feat: do not always extract root from gossip messages --- .../network/processor/extractSlotRootFns.ts | 37 ++++++++++++++----- .../src/network/processor/index.ts | 8 +++- .../src/network/processor/types.ts | 2 +- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/packages/beacon-node/src/network/processor/extractSlotRootFns.ts b/packages/beacon-node/src/network/processor/extractSlotRootFns.ts index d31cb3e2d7f9..7d957d48e017 100644 --- a/packages/beacon-node/src/network/processor/extractSlotRootFns.ts +++ b/packages/beacon-node/src/network/processor/extractSlotRootFns.ts @@ -16,23 +16,40 @@ import {ExtractSlotRootFns} from "./types.js"; */ export function createExtractBlockSlotRootFns(): ExtractSlotRootFns { return { - [GossipType.beacon_attestation]: (data: Uint8Array): SlotRootHex | null => { + [GossipType.beacon_attestation]: (data: Uint8Array, extractRoot: boolean): SlotOptionalRoot | null => { const slot = getSlotFromAttestationSerialized(data); - const root = getBlockRootFromAttestationSerialized(data); - - if (slot === null || root === null) { + if (slot === null) { return null; } - return {slot, root}; + + if (extractRoot) { + const root = getBlockRootFromAttestationSerialized(data); + if (root === null) { + return null; + } + + return {slot, root}; + } + + return {slot}; }, - [GossipType.beacon_aggregate_and_proof]: (data: Uint8Array): SlotRootHex | null => { + [GossipType.beacon_aggregate_and_proof]: (data: Uint8Array, extractRoot: boolean): SlotOptionalRoot | null => { const slot = getSlotFromSignedAggregateAndProofSerialized(data); - const root = getBlockRootFromSignedAggregateAndProofSerialized(data); - - if (slot === null || root === null) { + if (slot === null) { return null; } - return {slot, root}; + + if (extractRoot) { + const root = getBlockRootFromSignedAggregateAndProofSerialized(data); + + if (root === null) { + return null; + } + + return {slot, root}; + } + + return {slot}; }, [GossipType.beacon_block]: (data: Uint8Array): SlotOptionalRoot | null => { const slot = getSlotFromSignedBeaconBlockSerialized(data); diff --git a/packages/beacon-node/src/network/processor/index.ts b/packages/beacon-node/src/network/processor/index.ts index ec0edf54644f..d1fdfc69dc2b 100644 --- a/packages/beacon-node/src/network/processor/index.ts +++ b/packages/beacon-node/src/network/processor/index.ts @@ -160,6 +160,7 @@ export class NetworkProcessor { private readonly awaitingGossipsubMessagesByRootBySlot: MapDef>>; private unknownBlockGossipsubMessagesCount = 0; private isProcessingCurrentSlotBlock = false; + private receivedGossipBlock = false; private unknownRootsBySlot = new MapDef>(() => new Set()); constructor( @@ -247,7 +248,8 @@ export class NetworkProcessor { const extractBlockSlotRootFn = this.extractBlockSlotRootFns[topicType]; // check block root of Attestation and SignedAggregateAndProof messages if (extractBlockSlotRootFn) { - const slotRoot = extractBlockSlotRootFn(message.msg.data); + const extractRoot = !this.receivedGossipBlock; + const slotRoot = extractBlockSlotRootFn(message.msg.data, extractRoot); // if slotRoot is null, it means the msg.data is invalid // in that case message will be rejected when deserializing data in later phase (gossipValidatorFn) if (slotRoot) { @@ -319,6 +321,9 @@ export class NetworkProcessor { executionOptimistic: boolean; }): Promise { this.isProcessingCurrentSlotBlock = false; + if (slot === this.chain.clock.currentSlot) { + this.receivedGossipBlock = true; + } const byRootGossipsubMessages = this.awaitingGossipsubMessagesByRootBySlot.getOrDefault(slot); const waitingGossipsubMessages = byRootGossipsubMessages.getOrDefault(rootHex); if (waitingGossipsubMessages.size === 0) { @@ -346,6 +351,7 @@ export class NetworkProcessor { private onClockSlot(clockSlot: Slot): void { this.isProcessingCurrentSlotBlock = false; + this.receivedGossipBlock = false; const nowSec = Date.now() / 1000; for (const [slot, gossipMessagesByRoot] of this.awaitingGossipsubMessagesByRootBySlot.entries()) { if (slot < clockSlot) { diff --git a/packages/beacon-node/src/network/processor/types.ts b/packages/beacon-node/src/network/processor/types.ts index 386b9e8afc37..72f025891938 100644 --- a/packages/beacon-node/src/network/processor/types.ts +++ b/packages/beacon-node/src/network/processor/types.ts @@ -22,5 +22,5 @@ export type PendingGossipsubMessage = { }; export type ExtractSlotRootFns = { - [K in GossipType]?: (data: Uint8Array) => SlotOptionalRoot | null; + [K in GossipType]?: (data: Uint8Array, extractRoot: boolean) => SlotOptionalRoot | null; }; From 9c9f063133e884767a218db0266bc4c351f2ed47 Mon Sep 17 00:00:00 2001 From: Tuyen Nguyen Date: Wed, 30 Oct 2024 08:34:07 +0700 Subject: [PATCH 2/2] chore: more comments --- packages/beacon-node/src/network/processor/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/beacon-node/src/network/processor/index.ts b/packages/beacon-node/src/network/processor/index.ts index d1fdfc69dc2b..293dd6412e1d 100644 --- a/packages/beacon-node/src/network/processor/index.ts +++ b/packages/beacon-node/src/network/processor/index.ts @@ -248,6 +248,8 @@ export class NetworkProcessor { const extractBlockSlotRootFn = this.extractBlockSlotRootFns[topicType]; // check block root of Attestation and SignedAggregateAndProof messages if (extractBlockSlotRootFn) { + // only extract roots for early gossip messages + // see https://github.com/ChainSafe/lodestar/issues/7205 const extractRoot = !this.receivedGossipBlock; const slotRoot = extractBlockSlotRootFn(message.msg.data, extractRoot); // if slotRoot is null, it means the msg.data is invalid