@lodestar/beacon-node 1.48.0-dev.acdde443d2 → 1.48.0-dev.af8bc602aa
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +4 -4
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +0 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +0 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/metrics.js +1 -12
- package/lib/chain/archiveStore/historicalState/metrics.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.d.ts +0 -2
- package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js +1 -4
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +34 -31
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +2 -3
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +16 -9
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts +3 -4
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +35 -60
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +7 -19
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +2 -2
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/dataColumnSidecarError.d.ts +2 -15
- package/lib/chain/errors/dataColumnSidecarError.d.ts.map +1 -1
- package/lib/chain/errors/dataColumnSidecarError.js.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +11 -10
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +2 -0
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/interface.d.ts +2 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +13 -13
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +54 -35
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +13 -38
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +29 -10
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/db/beacon.d.ts +5 -14
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +3 -17
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/index.d.ts +0 -1
- package/lib/db/index.d.ts.map +1 -1
- package/lib/db/interface.d.ts +1 -8
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchive.d.ts +1 -8
- package/lib/db/repositories/blockArchive.d.ts.map +1 -1
- package/lib/db/repositories/blockArchive.js +28 -65
- package/lib/db/repositories/blockArchive.js.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +2 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.js +7 -3
- package/lib/db/repositories/blockArchiveIndex.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +0 -18
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +1 -55
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/monitoring/clientStats.js +1 -1
- package/lib/monitoring/clientStats.js.map +1 -1
- package/lib/network/gossip/encoding.d.ts.map +1 -1
- package/lib/network/gossip/encoding.js +6 -0
- package/lib/network/gossip/encoding.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +1 -2
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +20 -4
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +7 -6
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +3 -49
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +98 -232
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +91 -112
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +0 -2
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/protocols.d.ts.map +1 -1
- package/lib/network/reqresp/protocols.js +22 -6
- package/lib/network/reqresp/protocols.js.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts +1 -2
- package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js +9 -14
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
- package/lib/node/nodejs.d.ts +1 -2
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +2 -4
- package/lib/node/nodejs.js.map +1 -1
- package/lib/util/sszBytes.d.ts +0 -6
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +1 -1
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +16 -16
- package/src/api/impl/beacon/blocks/index.ts +4 -8
- package/src/chain/archiveStore/archiveStore.ts +1 -6
- package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +0 -1
- package/src/chain/archiveStore/historicalState/metrics.ts +1 -14
- package/src/chain/archiveStore/historicalState/types.ts +0 -2
- package/src/chain/archiveStore/historicalState/worker.ts +1 -4
- package/src/chain/archiveStore/utils/archiveBlocks.ts +39 -34
- package/src/chain/blocks/index.ts +2 -13
- package/src/chain/blocks/writeBlockInputToDb.ts +17 -10
- package/src/chain/chain.ts +34 -75
- package/src/chain/errors/blockError.ts +10 -22
- package/src/chain/errors/dataColumnSidecarError.ts +8 -24
- package/src/chain/errors/executionPayloadEnvelope.ts +11 -14
- package/src/chain/interface.ts +2 -2
- package/src/chain/prepareNextSlot.ts +16 -16
- package/src/chain/validation/block.ts +70 -35
- package/src/chain/validation/dataColumnSidecar.ts +14 -47
- package/src/chain/validation/executionPayloadEnvelope.ts +37 -10
- package/src/db/beacon.ts +6 -33
- package/src/db/index.ts +0 -1
- package/src/db/interface.ts +1 -9
- package/src/db/repositories/blockArchive.ts +30 -89
- package/src/db/repositories/blockArchiveIndex.ts +9 -4
- package/src/metrics/metrics/lodestar.ts +1 -57
- package/src/monitoring/clientStats.ts +1 -1
- package/src/network/gossip/encoding.ts +6 -0
- package/src/network/gossip/topic.ts +25 -3
- package/src/network/processor/gossipHandlers.ts +11 -11
- package/src/network/processor/index.ts +148 -263
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +105 -139
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +0 -2
- package/src/network/reqresp/protocols.ts +24 -7
- package/src/network/reqresp/utils/dataColumnResponseValidation.ts +7 -15
- package/src/node/nodejs.ts +1 -6
- package/src/util/sszBytes.ts +1 -1
- package/lib/db/dataColumnStore.d.ts +0 -39
- package/lib/db/dataColumnStore.d.ts.map +0 -1
- package/lib/db/dataColumnStore.js +0 -81
- package/lib/db/dataColumnStore.js.map +0 -1
- package/lib/db/flatFileStore/atomicWrite.d.ts +0 -8
- package/lib/db/flatFileStore/atomicWrite.d.ts.map +0 -1
- package/lib/db/flatFileStore/atomicWrite.js +0 -61
- package/lib/db/flatFileStore/atomicWrite.js.map +0 -1
- package/lib/db/flatFileStore/dcolFormat.d.ts +0 -90
- package/lib/db/flatFileStore/dcolFormat.d.ts.map +0 -1
- package/lib/db/flatFileStore/dcolFormat.js +0 -286
- package/lib/db/flatFileStore/dcolFormat.js.map +0 -1
- package/lib/db/flatFileStore/errors.d.ts +0 -82
- package/lib/db/flatFileStore/errors.d.ts.map +0 -1
- package/lib/db/flatFileStore/errors.js +0 -32
- package/lib/db/flatFileStore/errors.js.map +0 -1
- package/lib/db/flatFileStore/flatFileStore.d.ts +0 -41
- package/lib/db/flatFileStore/flatFileStore.d.ts.map +0 -1
- package/lib/db/flatFileStore/flatFileStore.js +0 -251
- package/lib/db/flatFileStore/flatFileStore.js.map +0 -1
- package/lib/db/flatFileStore/index.d.ts +0 -4
- package/lib/db/flatFileStore/index.d.ts.map +0 -1
- package/lib/db/flatFileStore/index.js +0 -2
- package/lib/db/flatFileStore/index.js.map +0 -1
- package/lib/db/flatFileStore/interface.d.ts +0 -25
- package/lib/db/flatFileStore/interface.d.ts.map +0 -1
- package/lib/db/flatFileStore/interface.js +0 -2
- package/lib/db/flatFileStore/interface.js.map +0 -1
- package/lib/db/flatFileStore/metrics.d.ts +0 -24
- package/lib/db/flatFileStore/metrics.d.ts.map +0 -1
- package/lib/db/flatFileStore/metrics.js +0 -25
- package/lib/db/flatFileStore/metrics.js.map +0 -1
- package/lib/db/flatFileStore/path.d.ts +0 -9
- package/lib/db/flatFileStore/path.d.ts.map +0 -1
- package/lib/db/flatFileStore/path.js +0 -21
- package/lib/db/flatFileStore/path.js.map +0 -1
- package/lib/db/flatFileStore/slotIndex.d.ts +0 -14
- package/lib/db/flatFileStore/slotIndex.d.ts.map +0 -1
- package/lib/db/flatFileStore/slotIndex.js +0 -46
- package/lib/db/flatFileStore/slotIndex.js.map +0 -1
- package/lib/db/flatFileStore/snappy.d.ts +0 -3
- package/lib/db/flatFileStore/snappy.d.ts.map +0 -1
- package/lib/db/flatFileStore/snappy.js +0 -12
- package/lib/db/flatFileStore/snappy.js.map +0 -1
- package/src/db/dataColumnStore.ts +0 -113
- package/src/db/flatFileStore/atomicWrite.ts +0 -65
- package/src/db/flatFileStore/dcolFormat.ts +0 -389
- package/src/db/flatFileStore/errors.ts +0 -53
- package/src/db/flatFileStore/flatFileStore.ts +0 -310
- package/src/db/flatFileStore/index.ts +0 -3
- package/src/db/flatFileStore/interface.ts +0 -21
- package/src/db/flatFileStore/metrics.ts +0 -48
- package/src/db/flatFileStore/path.ts +0 -32
- package/src/db/flatFileStore/slotIndex.ts +0 -56
- package/src/db/flatFileStore/snappy.ts +0 -14
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TopicValidatorResult } from "@libp2p/gossipsub";
|
|
2
2
|
import { routes } from "@lodestar/api";
|
|
3
|
-
import { ForkSeq
|
|
3
|
+
import { ForkSeq } from "@lodestar/params";
|
|
4
4
|
import { computeStartSlotAtEpoch } from "@lodestar/state-transition";
|
|
5
5
|
import { MapDef, mapValues, sleep } from "@lodestar/utils";
|
|
6
6
|
import { BlockInputSource } from "../../chain/blocks/blockInput/types.js";
|
|
@@ -20,28 +20,6 @@ export * from "./types.js";
|
|
|
20
20
|
* Keep up to 3 slot of unknown roots, so we don't always emit to UnknownBlock sync.
|
|
21
21
|
*/
|
|
22
22
|
const MAX_UNKNOWN_ROOTS_SLOT_CACHE_SIZE = 3;
|
|
23
|
-
/**
|
|
24
|
-
* Max distinct roots we BUFFER messages for, per slot. Kept tight to avoid the OOM
|
|
25
|
-
* risk. We don't support super forky condition where there are more than this many roots per slot via gossip.
|
|
26
|
-
*/
|
|
27
|
-
export const MAX_BUFFERED_ROOTS_PER_SLOT = 5;
|
|
28
|
-
/**
|
|
29
|
-
* Max distinct roots we emit an unknown-root search for, per slot. Higher than
|
|
30
|
-
* the buffer budget because:
|
|
31
|
-
* - in the attack scenario, the genuine root may comes after the first MAX_BUFFERED_ROOTS_PER_SLOT roots
|
|
32
|
-
* - if we cannot search, we'll penalize peers in UnknownBlockInput, not in NetworkProcessor
|
|
33
|
-
*/
|
|
34
|
-
export const MAX_SEARCHED_ROOTS_PER_SLOT = 32;
|
|
35
|
-
/**
|
|
36
|
-
* Given the same root and topic, we'll ignore messages after the below cap. Each cap is the number of
|
|
37
|
-
* legitimate messages we expect for one block, plus headroom for some malformed messages that may arrives first
|
|
38
|
-
* they will be penalized by the gossip handler
|
|
39
|
-
*/
|
|
40
|
-
export const MAX_AWAITING_MESSAGES_PER_ROOT = {
|
|
41
|
-
[GossipType.data_column_sidecar]: 2 * NUMBER_OF_COLUMNS,
|
|
42
|
-
[GossipType.execution_payload]: 2,
|
|
43
|
-
[GossipType.execution_payload_bid]: 8,
|
|
44
|
-
};
|
|
45
23
|
/**
|
|
46
24
|
* This is respective to gossipsub seenTTL (which is 550 * 0.7 = 385s), also it's respective
|
|
47
25
|
* to beacon_attestation ATTESTATION_PROPAGATION_SLOT_RANGE (32 slots).
|
|
@@ -94,14 +72,6 @@ export var ReprocessRejectReason;
|
|
|
94
72
|
* There are too many gossip messages that have unknown block root.
|
|
95
73
|
*/
|
|
96
74
|
ReprocessRejectReason["reached_limit"] = "reached_limit";
|
|
97
|
-
/**
|
|
98
|
-
* Too many distinct unknown roots are already tracked for the message's slot (MAX_UNKNOWN_ROOTS_PER_SLOT).
|
|
99
|
-
*/
|
|
100
|
-
ReprocessRejectReason["reached_root_limit"] = "reached_root_limit";
|
|
101
|
-
/**
|
|
102
|
-
* Too many gossip messages are already buffered for this (root, topic) (MAX_AWAITING_MESSAGES_PER_ROOT).
|
|
103
|
-
*/
|
|
104
|
-
ReprocessRejectReason["reached_topic_limit"] = "reached_topic_limit";
|
|
105
75
|
/**
|
|
106
76
|
* The awaiting gossip message is pruned per clock slot.
|
|
107
77
|
*/
|
|
@@ -162,16 +132,15 @@ export class NetworkProcessor {
|
|
|
162
132
|
gossipTopicConcurrency;
|
|
163
133
|
extractBlockSlotRootFns = createExtractBlockSlotRootFns();
|
|
164
134
|
// we may not receive the block for messages like Attestation and SignedAggregateAndProof messages, in that case PendingGossipsubMessage needs
|
|
165
|
-
// to be stored in this Map and reprocessed once the block comes
|
|
166
|
-
// the number of buffered messages per (root, topic) - see MAX_AWAITING_MESSAGES_PER_ROOT.
|
|
135
|
+
// to be stored in this Map and reprocessed once the block comes
|
|
167
136
|
awaitingMessagesByBlockRoot;
|
|
168
137
|
awaitingBlockMessageCount = 0;
|
|
169
138
|
// we may not receive the payload for messages that require the FULL payload variant to be processed,
|
|
170
139
|
// in that case PendingGossipsubMessage needs to be stored in this Map and reprocessed once the payload comes
|
|
171
140
|
awaitingMessagesByPayloadBlockRoot;
|
|
172
141
|
awaitingPayloadMessageCount = 0;
|
|
173
|
-
|
|
174
|
-
|
|
142
|
+
unknownBlocksBySlot = new MapDef(() => new MapDef(() => new Set()));
|
|
143
|
+
unknownEnvelopesBySlot = new MapDef(() => new MapDef(() => new Set()));
|
|
175
144
|
constructor(modules, opts) {
|
|
176
145
|
this.opts = opts;
|
|
177
146
|
const { chain, events, logger, metrics } = modules;
|
|
@@ -188,8 +157,8 @@ export class NetworkProcessor {
|
|
|
188
157
|
this.chain.emitter.on(routes.events.EventType.block, this.onBlockProcessed);
|
|
189
158
|
this.chain.emitter.on(routes.events.EventType.executionPayload, this.onPayloadEnvelopeProcessed);
|
|
190
159
|
this.chain.clock.on(ClockEvent.slot, this.onClockSlot);
|
|
191
|
-
this.awaitingMessagesByBlockRoot = new MapDef(() => new
|
|
192
|
-
this.awaitingMessagesByPayloadBlockRoot = new MapDef(() => new
|
|
160
|
+
this.awaitingMessagesByBlockRoot = new MapDef(() => new Set());
|
|
161
|
+
this.awaitingMessagesByPayloadBlockRoot = new MapDef(() => new Set());
|
|
193
162
|
// TODO: Implement queues and priorization for ReqResp incoming requests
|
|
194
163
|
// Listens to NetworkEvent.reqRespIncomingRequest event
|
|
195
164
|
if (metrics) {
|
|
@@ -241,12 +210,9 @@ export class NetworkProcessor {
|
|
|
241
210
|
if (this.chain.seenBlock(root)) {
|
|
242
211
|
return;
|
|
243
212
|
}
|
|
244
|
-
const
|
|
245
|
-
const alreadySearching =
|
|
246
|
-
|
|
247
|
-
entry.blockPeerIds = new Set();
|
|
248
|
-
}
|
|
249
|
-
const forwardedPeers = entry.blockPeerIds;
|
|
213
|
+
const peersForRoot = this.unknownBlocksBySlot.getOrDefault(slot);
|
|
214
|
+
const alreadySearching = peersForRoot.has(root) || this.awaitingMessagesByBlockRoot.has(root);
|
|
215
|
+
const forwardedPeers = peersForRoot.getOrDefault(root);
|
|
250
216
|
// brand-new search always emits (peer may be undefined)
|
|
251
217
|
let shouldEmit = !alreadySearching;
|
|
252
218
|
if (peer !== undefined && !forwardedPeers.has(peer) && forwardedPeers.size < MAX_PEERS_PER_ROOT) {
|
|
@@ -268,12 +234,10 @@ export class NetworkProcessor {
|
|
|
268
234
|
if (this.chain.seenPayloadEnvelope(root)) {
|
|
269
235
|
return;
|
|
270
236
|
}
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
const forwardedPeers = entry.envelopePeerIds;
|
|
237
|
+
const peersForRoot = this.unknownEnvelopesBySlot.getOrDefault(slot);
|
|
238
|
+
// capture "already searching" BEFORE getOrDefault(root) creates the entry
|
|
239
|
+
const alreadySearching = peersForRoot.has(root) || this.awaitingMessagesByPayloadBlockRoot.has(root);
|
|
240
|
+
const forwardedPeers = peersForRoot.getOrDefault(root);
|
|
277
241
|
let shouldEmit = !alreadySearching; // brand-new search always emits (peer may be undefined)
|
|
278
242
|
if (peer !== undefined && !forwardedPeers.has(peer) && forwardedPeers.size < MAX_PEERS_PER_ROOT) {
|
|
279
243
|
// First time we forward THIS peer for THIS root: emit so BlockInputSync accumulates it.
|
|
@@ -328,14 +292,13 @@ export class NetworkProcessor {
|
|
|
328
292
|
return;
|
|
329
293
|
}
|
|
330
294
|
message.msgSlot = slot;
|
|
331
|
-
const peerId = message.propagationSource.toString();
|
|
332
295
|
// this determines whether this message needs to wait for a Block or Envelope
|
|
333
|
-
// a message should only wait for what it voted for, hence we don't want to put it on both queues
|
|
296
|
+
// a message should only wait for what it voted for, hence we don't want to put it on both queues
|
|
334
297
|
let preprocessResult = { action: PreprocessAction.PushToQueue };
|
|
335
298
|
// no need to check if root is a descendant of the current finalized block, it will be checked once we validate the message if needed
|
|
336
299
|
if (root && !this.chain.forkChoice.hasBlockHexUnsafe(root)) {
|
|
337
300
|
// starting from GLOAS, unknown root from data_column_sidecar also falls into this case
|
|
338
|
-
this.
|
|
301
|
+
this.searchUnknownBlock({ slot, root }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
339
302
|
// for beacon_attestation and beacon_aggregate_and_proof messages, this is only temporary.
|
|
340
303
|
// if "index = 1" we need to await for the Envelope instead
|
|
341
304
|
preprocessResult = { action: PreprocessAction.AwaitBlock, root };
|
|
@@ -343,32 +306,28 @@ export class NetworkProcessor {
|
|
|
343
306
|
// 2nd extract round for some specific topics
|
|
344
307
|
// we separate the search action from the await action
|
|
345
308
|
// beacon_block: proactively search for parent block/envelope across all forks, but never queue.
|
|
346
|
-
// BlockInputSync handles cascading recovery if the gossip handler throws.
|
|
347
|
-
// the message root and this message never awaits, so its search flushes inline here (gated by the budget).
|
|
309
|
+
// BlockInputSync handles cascading recovery if the gossip handler throws.
|
|
348
310
|
if (topicType === GossipType.beacon_block) {
|
|
349
311
|
const parentRoot = getParentRootFromSignedBeaconBlockSerialized(message.msg.data);
|
|
350
312
|
if (parentRoot) {
|
|
351
|
-
let searchParentBlock = false;
|
|
352
|
-
let searchParentEnvelope = false;
|
|
353
313
|
if (ForkSeq[fork] >= ForkSeq.gloas) {
|
|
354
314
|
// GLOAS: also check parent envelope, same logic as execution_payload_bid
|
|
355
315
|
const parentBlockHash = getParentBlockHashFromGloasSignedBeaconBlockSerialized(message.msg.data);
|
|
356
316
|
if (parentBlockHash && !this.chain.forkChoice.getBlockHexAndBlockHash(parentRoot, parentBlockHash)) {
|
|
357
317
|
const protoBlock = this.chain.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
358
318
|
if (protoBlock === null) {
|
|
359
|
-
|
|
319
|
+
this.searchUnknownBlock({ slot, root: parentRoot }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
360
320
|
}
|
|
361
321
|
else if (protoBlock.executionPayloadBlockHash &&
|
|
362
322
|
protoBlock.executionPayloadBlockHash !== parentBlockHash) {
|
|
363
323
|
// only search for the envelope by block root if we're sure there is one. Otherwise UnknownBlockSync will penalize the peer.
|
|
364
|
-
|
|
324
|
+
this.searchUnknownEnvelope({ slot, root: parentRoot }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
365
325
|
}
|
|
366
326
|
}
|
|
367
327
|
}
|
|
368
328
|
else if (!this.chain.forkChoice.hasBlockHexUnsafe(parentRoot)) {
|
|
369
|
-
|
|
329
|
+
this.searchUnknownBlock({ slot, root: parentRoot }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
370
330
|
}
|
|
371
|
-
this.searchUnknownRoot({ slot, root: parentRoot }, searchParentBlock, searchParentEnvelope, peerId);
|
|
372
331
|
}
|
|
373
332
|
preprocessResult = { action: PreprocessAction.PushToQueue };
|
|
374
333
|
}
|
|
@@ -386,7 +345,7 @@ export class NetworkProcessor {
|
|
|
386
345
|
: getDataIndexFromSignedAggregateAndProofSerialized(message.msg.data);
|
|
387
346
|
if (attIndex === 1 && !this.chain.forkChoice.hasPayloadHexUnsafe(root)) {
|
|
388
347
|
// attestation votes that the payload is available but it is not yet known
|
|
389
|
-
this.
|
|
348
|
+
this.searchUnknownEnvelope({ slot, root }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
390
349
|
preprocessResult = { action: PreprocessAction.AwaitEnvelope, root };
|
|
391
350
|
}
|
|
392
351
|
break;
|
|
@@ -397,7 +356,7 @@ export class NetworkProcessor {
|
|
|
397
356
|
const payloadPresent = getPayloadPresentFromPayloadAttestationMessageSerialized(message.msg.data);
|
|
398
357
|
if (payloadPresent && !this.chain.forkChoice.hasPayloadHexUnsafe(root)) {
|
|
399
358
|
// payload attestation votes that the payload is available but it is not yet known
|
|
400
|
-
this.
|
|
359
|
+
this.searchUnknownEnvelope({ slot, root }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
401
360
|
// do not await the envelope, payload attestation processing only requires that the block is known
|
|
402
361
|
// also do not reset preprocessResult, we may already await for the block
|
|
403
362
|
}
|
|
@@ -407,7 +366,7 @@ export class NetworkProcessor {
|
|
|
407
366
|
if (root == null)
|
|
408
367
|
break;
|
|
409
368
|
if (!this.chain.forkChoice.hasPayloadHexUnsafe(root)) {
|
|
410
|
-
this.
|
|
369
|
+
this.searchUnknownEnvelope({ slot, root }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
411
370
|
// do not await the envelope, we can do gossip validation
|
|
412
371
|
// also do not reset preprocessResult, we may already await for the block
|
|
413
372
|
}
|
|
@@ -418,7 +377,7 @@ export class NetworkProcessor {
|
|
|
418
377
|
// Extract beacon_block_root directly
|
|
419
378
|
const blockRoot = getBeaconBlockRootFromExecutionPayloadEnvelopeSerialized(message.msg.data);
|
|
420
379
|
if (blockRoot && !this.chain.forkChoice.hasBlockHexUnsafe(blockRoot)) {
|
|
421
|
-
this.
|
|
380
|
+
this.searchUnknownBlock({ slot, root: blockRoot }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
422
381
|
// We always want to await the block
|
|
423
382
|
// This allows us to properly forward the payload envelope
|
|
424
383
|
preprocessResult = { action: PreprocessAction.AwaitBlock, root: blockRoot };
|
|
@@ -435,12 +394,12 @@ export class NetworkProcessor {
|
|
|
435
394
|
!this.chain.forkChoice.getBlockHexAndBlockHash(parentBlockRoot, parentBlockHash)) {
|
|
436
395
|
const protoBlock = this.chain.forkChoice.getBlockHexDefaultStatus(parentBlockRoot);
|
|
437
396
|
if (protoBlock === null) {
|
|
438
|
-
this.
|
|
397
|
+
this.searchUnknownBlock({ slot, root: parentBlockRoot }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
439
398
|
preprocessResult = { action: PreprocessAction.AwaitBlock, root: parentBlockRoot };
|
|
440
399
|
}
|
|
441
400
|
else if (protoBlock.executionPayloadBlockHash &&
|
|
442
401
|
protoBlock.executionPayloadBlockHash !== parentBlockHash) {
|
|
443
|
-
this.
|
|
402
|
+
this.searchUnknownEnvelope({ slot, root: parentBlockRoot }, BlockInputSource.network_processor, message.propagationSource.toString());
|
|
444
403
|
preprocessResult = { action: PreprocessAction.AwaitEnvelope, root: parentBlockRoot };
|
|
445
404
|
}
|
|
446
405
|
}
|
|
@@ -452,96 +411,37 @@ export class NetworkProcessor {
|
|
|
452
411
|
case PreprocessAction.PushToQueue:
|
|
453
412
|
this.pushPendingGossipsubMessageToQueue(message);
|
|
454
413
|
break;
|
|
455
|
-
case PreprocessAction.AwaitBlock:
|
|
456
|
-
this.
|
|
414
|
+
case PreprocessAction.AwaitBlock: {
|
|
415
|
+
if (this.awaitingBlockMessageCount > MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS) {
|
|
416
|
+
// No need to report the dropped job to gossip. It will be eventually pruned from the mcache
|
|
417
|
+
this.metrics?.awaitingBlockGossipMessages.reject.inc({
|
|
418
|
+
reason: ReprocessRejectReason.reached_limit,
|
|
419
|
+
topic: topicType,
|
|
420
|
+
});
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
this.metrics?.awaitingBlockGossipMessages.queue.inc({ topic: topicType });
|
|
424
|
+
const awaitingGossipsubMessages = this.awaitingMessagesByBlockRoot.getOrDefault(preprocessResult.root);
|
|
425
|
+
awaitingGossipsubMessages.add(message);
|
|
426
|
+
this.awaitingBlockMessageCount++;
|
|
457
427
|
break;
|
|
458
|
-
|
|
459
|
-
|
|
428
|
+
}
|
|
429
|
+
case PreprocessAction.AwaitEnvelope: {
|
|
430
|
+
if (this.awaitingPayloadMessageCount > MAX_QUEUED_UNKNOWN_PAYLOAD_GOSSIP_OBJECTS) {
|
|
431
|
+
this.metrics?.awaitingPayloadGossipMessages.reject.inc({
|
|
432
|
+
reason: ReprocessRejectReason.reached_limit,
|
|
433
|
+
topic: topicType,
|
|
434
|
+
});
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
this.metrics?.awaitingPayloadGossipMessages.queue.inc({ topic: topicType });
|
|
438
|
+
const awaitingPayloadGossipsubMessages = this.awaitingMessagesByPayloadBlockRoot.getOrDefault(preprocessResult.root);
|
|
439
|
+
awaitingPayloadGossipsubMessages.add(message);
|
|
440
|
+
this.awaitingPayloadMessageCount++;
|
|
460
441
|
break;
|
|
442
|
+
}
|
|
461
443
|
}
|
|
462
444
|
};
|
|
463
|
-
/**
|
|
464
|
-
* Buffer a gossip message that must wait for an unknown block before it can be validated.
|
|
465
|
-
*
|
|
466
|
-
* For DOS protection, the message is ignored (reject metric incremented) when any cap is hit:
|
|
467
|
-
* - MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS: global awaiting-block message count
|
|
468
|
-
* - MAX_BUFFERED_ROOTS_PER_SLOT: distinct roots we buffer messages for, per slot
|
|
469
|
-
* - MAX_AWAITING_MESSAGES_PER_ROOT[topic]: messages buffered per (root, topic)
|
|
470
|
-
*/
|
|
471
|
-
maybeAwaitBlock(root, topicType, slot, message) {
|
|
472
|
-
const metric = this.metrics?.awaitingBlockGossipMessages;
|
|
473
|
-
// global message-count cap - cheapest check first
|
|
474
|
-
if (this.awaitingBlockMessageCount > MAX_QUEUED_UNKNOWN_BLOCK_GOSSIP_OBJECTS) {
|
|
475
|
-
metric?.reject.inc({ reason: ReprocessRejectReason.reached_limit, topic: topicType });
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
// per-(root, topic) message cap: e.g. <= NUMBER_OF_COLUMNS columns per root
|
|
479
|
-
const perRootCap = MAX_AWAITING_MESSAGES_PER_ROOT[topicType];
|
|
480
|
-
if (perRootCap !== undefined &&
|
|
481
|
-
(this.awaitingMessagesByBlockRoot.get(root)?.get(topicType)?.size ?? 0) >= perRootCap) {
|
|
482
|
-
metric?.reject.inc({ reason: ReprocessRejectReason.reached_topic_limit, topic: topicType });
|
|
483
|
-
return;
|
|
484
|
-
}
|
|
485
|
-
if (!this.tryReserveBufferedRoot(slot, root)) {
|
|
486
|
-
metric?.reject.inc({ reason: ReprocessRejectReason.reached_root_limit, topic: topicType });
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
metric?.queue.inc({ topic: topicType });
|
|
490
|
-
this.awaitingMessagesByBlockRoot.getOrDefault(root).getOrDefault(topicType).add(message);
|
|
491
|
-
this.awaitingBlockMessageCount++;
|
|
492
|
-
}
|
|
493
|
-
/** Payload counterpart of maybeAwaitBlock */
|
|
494
|
-
maybeAwaitPayload(root, topicType, slot, message) {
|
|
495
|
-
const metric = this.metrics?.awaitingPayloadGossipMessages;
|
|
496
|
-
if (this.awaitingPayloadMessageCount > MAX_QUEUED_UNKNOWN_PAYLOAD_GOSSIP_OBJECTS) {
|
|
497
|
-
metric?.reject.inc({ reason: ReprocessRejectReason.reached_limit, topic: topicType });
|
|
498
|
-
return;
|
|
499
|
-
}
|
|
500
|
-
const perRootCap = MAX_AWAITING_MESSAGES_PER_ROOT[topicType];
|
|
501
|
-
if (perRootCap !== undefined &&
|
|
502
|
-
(this.awaitingMessagesByPayloadBlockRoot.get(root)?.get(topicType)?.size ?? 0) >= perRootCap) {
|
|
503
|
-
metric?.reject.inc({ reason: ReprocessRejectReason.reached_topic_limit, topic: topicType });
|
|
504
|
-
return;
|
|
505
|
-
}
|
|
506
|
-
if (!this.tryReserveBufferedRoot(slot, root)) {
|
|
507
|
-
metric?.reject.inc({ reason: ReprocessRejectReason.reached_root_limit, topic: topicType });
|
|
508
|
-
return;
|
|
509
|
-
}
|
|
510
|
-
metric?.queue.inc({ topic: topicType });
|
|
511
|
-
this.awaitingMessagesByPayloadBlockRoot.getOrDefault(root).getOrDefault(topicType).add(message);
|
|
512
|
-
this.awaitingPayloadMessageCount++;
|
|
513
|
-
}
|
|
514
|
-
/**
|
|
515
|
-
* Cap distinct roots we emit an unknown-root search for, an already-tracked root (dedup) never counts as "too many".
|
|
516
|
-
*/
|
|
517
|
-
tooManySearchedRoots(slot, root) {
|
|
518
|
-
const roots = this.searchedRootsBySlot.get(slot);
|
|
519
|
-
if (roots === undefined)
|
|
520
|
-
return false;
|
|
521
|
-
return !roots.has(root) && roots.size >= MAX_SEARCHED_ROOTS_PER_SLOT;
|
|
522
|
-
}
|
|
523
|
-
/**
|
|
524
|
-
* Cap distinct roots we buffer per slot.
|
|
525
|
-
*/
|
|
526
|
-
tryReserveBufferedRoot(slot, root) {
|
|
527
|
-
const roots = this.bufferedRootsBySlot.get(slot);
|
|
528
|
-
if (roots?.has(root))
|
|
529
|
-
return true;
|
|
530
|
-
if ((roots?.size ?? 0) >= MAX_BUFFERED_ROOTS_PER_SLOT)
|
|
531
|
-
return false;
|
|
532
|
-
this.bufferedRootsBySlot.getOrDefault(slot).add(root);
|
|
533
|
-
return true;
|
|
534
|
-
}
|
|
535
|
-
searchUnknownRoot(slotRoot, searchBlock, searchEnvelope, peerId) {
|
|
536
|
-
if (!searchBlock && !searchEnvelope)
|
|
537
|
-
return;
|
|
538
|
-
if (this.tooManySearchedRoots(slotRoot.slot, slotRoot.root))
|
|
539
|
-
return;
|
|
540
|
-
if (searchBlock)
|
|
541
|
-
this.searchUnknownBlock(slotRoot, BlockInputSource.network_processor, peerId);
|
|
542
|
-
if (searchEnvelope)
|
|
543
|
-
this.searchUnknownEnvelope(slotRoot, BlockInputSource.network_processor, peerId);
|
|
544
|
-
}
|
|
545
445
|
pushPendingGossipsubMessageToQueue(message) {
|
|
546
446
|
const topicType = message.topic.type;
|
|
547
447
|
message.queueAddedMs = Date.now();
|
|
@@ -554,92 +454,66 @@ export class NetworkProcessor {
|
|
|
554
454
|
this.executeWork();
|
|
555
455
|
}
|
|
556
456
|
onBlockProcessed = async ({ block: rootHex }) => {
|
|
557
|
-
const
|
|
558
|
-
if (
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
let total = 0;
|
|
562
|
-
for (const messages of messagesByTopic.values()) {
|
|
563
|
-
total += messages.size;
|
|
564
|
-
}
|
|
565
|
-
if (total === 0) {
|
|
457
|
+
const waitingGossipsubMessages = this.awaitingMessagesByBlockRoot.get(rootHex);
|
|
458
|
+
if (!waitingGossipsubMessages || waitingGossipsubMessages.size === 0) {
|
|
566
459
|
return;
|
|
567
460
|
}
|
|
568
461
|
// Atomically remove from map and update counter before async iteration to
|
|
569
462
|
// prevent double-decrement race with onClockSlot during yield points below
|
|
570
463
|
if (this.awaitingMessagesByBlockRoot.delete(rootHex)) {
|
|
571
|
-
this.awaitingBlockMessageCount -=
|
|
464
|
+
this.awaitingBlockMessageCount -= waitingGossipsubMessages.size;
|
|
572
465
|
}
|
|
573
466
|
const nowSec = Date.now() / 1000;
|
|
574
467
|
let count = 0;
|
|
575
468
|
// TODO: we can group attestations to process in batches but since we have the SeenAttestationDatas
|
|
576
469
|
// cache, it may not be necessary at this time
|
|
577
|
-
for (const
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
await sleep(AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS);
|
|
588
|
-
}
|
|
470
|
+
for (const message of waitingGossipsubMessages) {
|
|
471
|
+
const topicType = message.topic.type;
|
|
472
|
+
this.metrics?.awaitingBlockGossipMessages.waitSecBeforeResolve.set({ topic: topicType }, nowSec - message.seenTimestampSec);
|
|
473
|
+
this.metrics?.awaitingBlockGossipMessages.resolve.inc({ topic: topicType });
|
|
474
|
+
this.pushPendingGossipsubMessageToQueue(message);
|
|
475
|
+
count++;
|
|
476
|
+
// don't want to block the event loop, worse case it'd wait for 16_084 / 1024 * 50ms = 800ms which is not a big deal
|
|
477
|
+
if (count === MAX_AWAITING_GOSSIP_OBJECTS_PER_TICK) {
|
|
478
|
+
count = 0;
|
|
479
|
+
await sleep(AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS);
|
|
589
480
|
}
|
|
590
481
|
}
|
|
591
482
|
};
|
|
592
483
|
onPayloadEnvelopeProcessed = async ({ blockRoot: rootHex }) => {
|
|
593
|
-
const
|
|
594
|
-
if (
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
let total = 0;
|
|
598
|
-
for (const messages of messagesByTopic.values()) {
|
|
599
|
-
total += messages.size;
|
|
600
|
-
}
|
|
601
|
-
if (total === 0) {
|
|
484
|
+
const waitingGossipsubMessages = this.awaitingMessagesByPayloadBlockRoot.get(rootHex);
|
|
485
|
+
if (!waitingGossipsubMessages || waitingGossipsubMessages.size === 0) {
|
|
602
486
|
return;
|
|
603
487
|
}
|
|
604
488
|
// Atomically remove from map and update counter before async iteration to
|
|
605
489
|
// prevent double-decrement race with onClockSlot during yield points below
|
|
606
490
|
if (this.awaitingMessagesByPayloadBlockRoot.delete(rootHex)) {
|
|
607
|
-
this.awaitingPayloadMessageCount -=
|
|
491
|
+
this.awaitingPayloadMessageCount -= waitingGossipsubMessages.size;
|
|
608
492
|
}
|
|
609
493
|
const nowSec = Date.now() / 1000;
|
|
610
494
|
let count = 0;
|
|
611
|
-
for (const
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
await sleep(AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS);
|
|
621
|
-
}
|
|
495
|
+
for (const message of waitingGossipsubMessages) {
|
|
496
|
+
const topicType = message.topic.type;
|
|
497
|
+
this.metrics?.awaitingPayloadGossipMessages.waitSecBeforeResolve.set({ topic: topicType }, nowSec - message.seenTimestampSec);
|
|
498
|
+
this.metrics?.awaitingPayloadGossipMessages.resolve.inc({ topic: topicType });
|
|
499
|
+
this.pushPendingGossipsubMessageToQueue(message);
|
|
500
|
+
count++;
|
|
501
|
+
if (count === MAX_AWAITING_GOSSIP_OBJECTS_PER_TICK) {
|
|
502
|
+
count = 0;
|
|
503
|
+
await sleep(AWAITING_GOSSIP_OBJECTS_YIELD_EVERY_MS);
|
|
622
504
|
}
|
|
623
505
|
}
|
|
624
506
|
};
|
|
625
507
|
onClockSlot = (clockSlot) => {
|
|
626
508
|
const nowSec = Date.now() / 1000;
|
|
627
509
|
const minSlot = clockSlot - MAX_UNKNOWN_ROOTS_SLOT_CACHE_SIZE;
|
|
628
|
-
for (const [slot,
|
|
510
|
+
for (const [slot, roots] of this.unknownBlocksBySlot) {
|
|
629
511
|
if (slot > minSlot)
|
|
630
512
|
continue;
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
if (entry.blockPeerIds === undefined)
|
|
636
|
-
continue;
|
|
637
|
-
const messagesByTopic = this.awaitingMessagesByBlockRoot.get(rootHex);
|
|
638
|
-
if (messagesByTopic === undefined)
|
|
639
|
-
continue;
|
|
640
|
-
let removed = 0;
|
|
641
|
-
for (const messages of messagesByTopic.values()) {
|
|
642
|
-
for (const message of messages) {
|
|
513
|
+
for (const rootHex of roots.keys()) {
|
|
514
|
+
const gossipMessages = this.awaitingMessagesByBlockRoot.get(rootHex);
|
|
515
|
+
if (gossipMessages !== undefined) {
|
|
516
|
+
for (const message of gossipMessages) {
|
|
643
517
|
const topicType = message.topic.type;
|
|
644
518
|
this.metrics?.awaitingBlockGossipMessages.reject.inc({
|
|
645
519
|
topic: topicType,
|
|
@@ -648,23 +522,20 @@ export class NetworkProcessor {
|
|
|
648
522
|
this.metrics?.awaitingBlockGossipMessages.waitSecBeforeReject.set({ topic: topicType, reason: ReprocessRejectReason.expired }, nowSec - message.seenTimestampSec);
|
|
649
523
|
// No need to report the dropped job to gossip. It will be eventually pruned from the mcache
|
|
650
524
|
}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
this.awaitingBlockMessageCount -= removed;
|
|
525
|
+
if (this.awaitingMessagesByBlockRoot.delete(rootHex)) {
|
|
526
|
+
this.awaitingBlockMessageCount -= gossipMessages.size;
|
|
527
|
+
}
|
|
655
528
|
}
|
|
656
529
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
for (const messages of messagesByTopic.values()) {
|
|
667
|
-
for (const message of messages) {
|
|
530
|
+
this.unknownBlocksBySlot.delete(slot);
|
|
531
|
+
}
|
|
532
|
+
for (const [slot, roots] of this.unknownEnvelopesBySlot) {
|
|
533
|
+
if (slot > minSlot)
|
|
534
|
+
continue;
|
|
535
|
+
for (const rootHex of roots.keys()) {
|
|
536
|
+
const gossipMessages = this.awaitingMessagesByPayloadBlockRoot.get(rootHex);
|
|
537
|
+
if (gossipMessages !== undefined) {
|
|
538
|
+
for (const message of gossipMessages) {
|
|
668
539
|
const topicType = message.topic.type;
|
|
669
540
|
this.metrics?.awaitingPayloadGossipMessages.reject.inc({
|
|
670
541
|
topic: topicType,
|
|
@@ -673,17 +544,12 @@ export class NetworkProcessor {
|
|
|
673
544
|
this.metrics?.awaitingPayloadGossipMessages.waitSecBeforeReject.set({ topic: topicType, reason: ReprocessRejectReason.expired }, nowSec - message.seenTimestampSec);
|
|
674
545
|
// No need to report the dropped job to gossip. It will be eventually pruned from the mcache
|
|
675
546
|
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
this.awaitingPayloadMessageCount -= removed;
|
|
547
|
+
if (this.awaitingMessagesByPayloadBlockRoot.delete(rootHex)) {
|
|
548
|
+
this.awaitingPayloadMessageCount -= gossipMessages.size;
|
|
549
|
+
}
|
|
680
550
|
}
|
|
681
551
|
}
|
|
682
|
-
this.
|
|
683
|
-
}
|
|
684
|
-
for (const slot of this.bufferedRootsBySlot.keys()) {
|
|
685
|
-
if (slot <= minSlot)
|
|
686
|
-
this.bufferedRootsBySlot.delete(slot);
|
|
552
|
+
this.unknownEnvelopesBySlot.delete(slot);
|
|
687
553
|
}
|
|
688
554
|
};
|
|
689
555
|
executeWork() {
|