@lodestar/beacon-node 1.50.0-dev.5866a397b6 → 1.50.0-dev.58d40975f9
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 +6 -1
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/index.js +13 -0
- package/lib/api/impl/beacon/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +4 -4
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/index.js +23 -3
- package/lib/api/impl/beacon/state/index.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +26 -18
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts +1 -0
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +23 -1
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +6 -0
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +18 -24
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +2 -2
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js +5 -7
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js +1 -1
- package/lib/chain/archiveStore/historicalState/historicalStateRegen.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/types.d.ts +2 -2
- package/lib/chain/archiveStore/historicalState/types.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +1 -1
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/pruneHistory.d.ts +4 -1
- package/lib/chain/archiveStore/utils/pruneHistory.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/pruneHistory.js +5 -3
- package/lib/chain/archiveStore/utils/pruneHistory.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +17 -6
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +2 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +7 -7
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts +2 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +5 -4
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/chain.d.ts +9 -5
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +90 -36
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +7 -1
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +5 -0
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/envelopeReconstructionError.d.ts +5 -0
- package/lib/chain/errors/envelopeReconstructionError.d.ts.map +1 -1
- package/lib/chain/errors/envelopeReconstructionError.js +2 -0
- package/lib/chain/errors/envelopeReconstructionError.js.map +1 -1
- package/lib/chain/errors/gossipValidation.d.ts +3 -1
- package/lib/chain/errors/gossipValidation.d.ts.map +1 -1
- package/lib/chain/errors/gossipValidation.js +2 -0
- package/lib/chain/errors/gossipValidation.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +2 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/initState.d.ts +2 -9
- package/lib/chain/initState.d.ts.map +1 -1
- package/lib/chain/initState.js +5 -38
- package/lib/chain/initState.js.map +1 -1
- package/lib/chain/interface.d.ts +3 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -2
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +30 -8
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/opPool.d.ts +5 -4
- package/lib/chain/opPools/opPool.d.ts.map +1 -1
- package/lib/chain/opPools/opPool.js +62 -18
- package/lib/chain/opPools/opPool.js.map +1 -1
- package/lib/chain/opPools/proposerPreferencesPool.d.ts +4 -4
- package/lib/chain/opPools/proposerPreferencesPool.d.ts.map +1 -1
- package/lib/chain/opPools/proposerPreferencesPool.js +14 -11
- package/lib/chain/opPools/proposerPreferencesPool.js.map +1 -1
- package/lib/chain/opPools/utils.d.ts +4 -1
- package/lib/chain/opPools/utils.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +11 -1
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/chain/options.d.ts +2 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +1 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +5 -2
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +3 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +6 -2
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +2 -0
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +10 -4
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts +7 -0
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +21 -0
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +9 -2
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +23 -13
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/shufflingCache.d.ts +18 -8
- package/lib/chain/shufflingCache.d.ts.map +1 -1
- package/lib/chain/shufflingCache.js +72 -18
- package/lib/chain/shufflingCache.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts +4 -4
- package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +3 -0
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.d.ts +3 -3
- package/lib/chain/validation/proposerSlashing.d.ts.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +3 -0
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts +5 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +64 -54
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/db/beacon.d.ts +2 -0
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +5 -0
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/buckets.d.ts +2 -1
- package/lib/db/buckets.d.ts.map +1 -1
- package/lib/db/buckets.js +1 -0
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/interface.d.ts +2 -0
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/earliestAvailableSlot.d.ts +11 -0
- package/lib/db/repositories/earliestAvailableSlot.d.ts.map +1 -0
- package/lib/db/repositories/earliestAvailableSlot.js +19 -0
- package/lib/db/repositories/earliestAvailableSlot.js.map +1 -0
- package/lib/db/repositories/proposerSlashing.d.ts +1 -0
- package/lib/db/repositories/proposerSlashing.d.ts.map +1 -1
- package/lib/db/repositories/proposerSlashing.js +5 -1
- package/lib/db/repositories/proposerSlashing.js.map +1 -1
- package/lib/execution/engine/disabled.d.ts +0 -2
- package/lib/execution/engine/disabled.d.ts.map +1 -1
- package/lib/execution/engine/disabled.js +0 -6
- package/lib/execution/engine/disabled.js.map +1 -1
- package/lib/execution/engine/http.d.ts +1 -3
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +2 -17
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +2 -4
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/mock.d.ts +0 -2
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +0 -8
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/types.d.ts +0 -8
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/metrics/metrics/beacon.d.ts +1 -1
- package/lib/metrics/metrics/beacon.d.ts.map +1 -1
- package/lib/metrics/metrics/beacon.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +7 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +17 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/metrics/metrics.d.ts +7 -3
- package/lib/metrics/metrics.d.ts.map +1 -1
- package/lib/metrics/metrics.js +4 -4
- package/lib/metrics/metrics.js.map +1 -1
- package/lib/network/metadata.d.ts +1 -1
- package/lib/network/metadata.d.ts.map +1 -1
- package/lib/network/metadata.js +17 -17
- package/lib/network/metadata.js.map +1 -1
- package/lib/network/peers/datastore.d.ts +9 -9
- package/lib/network/peers/datastore.d.ts.map +1 -1
- package/lib/network/peers/datastore.js +36 -36
- package/lib/network/peers/datastore.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +66 -67
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipValidatorFn.d.ts +7 -3
- package/lib/network/processor/gossipValidatorFn.d.ts.map +1 -1
- package/lib/network/processor/gossipValidatorFn.js +7 -3
- package/lib/network/processor/gossipValidatorFn.js.map +1 -1
- package/lib/network/processor/index.d.ts +9 -0
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +77 -10
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +41 -26
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
- package/lib/node/nodejs.d.ts +3 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +27 -4
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/range/batch.d.ts +11 -5
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +21 -17
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +4 -4
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +12 -6
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/range.d.ts.map +1 -1
- package/lib/sync/range/range.js +75 -29
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +14 -7
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +132 -66
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +38 -14
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +84 -39
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/util/execution.d.ts +11 -11
- package/lib/util/execution.d.ts.map +1 -1
- package/lib/util/execution.js +11 -7
- package/lib/util/execution.js.map +1 -1
- package/package.json +17 -17
- package/src/api/impl/beacon/blocks/index.ts +7 -4
- package/src/api/impl/beacon/index.ts +15 -0
- package/src/api/impl/beacon/pool/index.ts +4 -4
- package/src/api/impl/beacon/state/index.ts +31 -3
- package/src/api/impl/debug/index.ts +28 -19
- package/src/api/impl/validator/index.ts +24 -2
- package/src/chain/archiveStore/archiveStore.ts +26 -26
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +5 -7
- package/src/chain/archiveStore/historicalState/historicalStateRegen.ts +1 -1
- package/src/chain/archiveStore/historicalState/types.ts +2 -2
- package/src/chain/archiveStore/historicalState/worker.ts +1 -2
- package/src/chain/archiveStore/interface.ts +1 -1
- package/src/chain/archiveStore/utils/pruneHistory.ts +9 -4
- package/src/chain/blocks/importBlock.ts +20 -5
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +2 -1
- package/src/chain/blocks/verifyBlock.ts +8 -6
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +6 -3
- package/src/chain/chain.ts +118 -38
- package/src/chain/emitter.ts +7 -1
- package/src/chain/errors/envelopeReconstructionError.ts +3 -0
- package/src/chain/errors/gossipValidation.ts +2 -0
- package/src/chain/forkChoice/index.ts +2 -0
- package/src/chain/initState.ts +8 -60
- package/src/chain/interface.ts +3 -2
- package/src/chain/opPools/aggregatedAttestationPool.ts +34 -10
- package/src/chain/opPools/opPool.ts +91 -18
- package/src/chain/opPools/proposerPreferencesPool.ts +14 -10
- package/src/chain/opPools/utils.ts +31 -3
- package/src/chain/options.ts +3 -3
- package/src/chain/prepareNextSlot.ts +6 -3
- package/src/chain/produceBlock/computeNewStateRoot.ts +1 -1
- package/src/chain/produceBlock/produceBlockBody.ts +8 -1
- package/src/chain/regen/regen.ts +12 -4
- package/src/chain/seenCache/seenGossipBlockInput.ts +23 -0
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +31 -13
- package/src/chain/shufflingCache.ts +84 -22
- package/src/chain/validation/attesterSlashing.ts +7 -4
- package/src/chain/validation/proposerSlashing.ts +7 -4
- package/src/chain/validatorMonitor.ts +75 -57
- package/src/db/beacon.ts +5 -0
- package/src/db/buckets.ts +1 -0
- package/src/db/interface.ts +2 -0
- package/src/db/repositories/earliestAvailableSlot.ts +19 -0
- package/src/db/repositories/proposerSlashing.ts +6 -1
- package/src/execution/engine/disabled.ts +0 -8
- package/src/execution/engine/http.ts +1 -30
- package/src/execution/engine/interface.ts +2 -6
- package/src/execution/engine/mock.ts +1 -19
- package/src/execution/engine/types.ts +0 -10
- package/src/index.ts +1 -1
- package/src/metrics/metrics/beacon.ts +1 -1
- package/src/metrics/metrics/lodestar.ts +18 -0
- package/src/metrics/metrics.ts +21 -6
- package/src/network/metadata.ts +17 -17
- package/src/network/peers/datastore.ts +36 -36
- package/src/network/processor/gossipHandlers.ts +97 -80
- package/src/network/processor/gossipValidatorFn.ts +13 -3
- package/src/network/processor/index.ts +89 -10
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +42 -28
- package/src/node/nodejs.ts +35 -3
- package/src/sync/range/batch.ts +25 -19
- package/src/sync/range/chain.ts +15 -8
- package/src/sync/range/range.ts +76 -30
- package/src/sync/unknownBlock.ts +156 -71
- package/src/sync/utils/downloadByRange.ts +123 -58
- package/src/util/execution.ts +26 -14
package/src/sync/unknownBlock.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {ChainEvent, ChainEventData, IBeaconChain} from "../chain/index.js";
|
|
|
15
15
|
import {validateGloasBlockDataColumnSidecars} from "../chain/validation/dataColumnSidecar.js";
|
|
16
16
|
import {validateGossipExecutionPayloadEnvelope} from "../chain/validation/executionPayloadEnvelope.js";
|
|
17
17
|
import {Metrics} from "../metrics/index.js";
|
|
18
|
-
import {INetwork, NetworkEvent, NetworkEventData, prettyPrintPeerIdStr} from "../network/index.js";
|
|
18
|
+
import {INetwork, NetworkEvent, NetworkEventData, PeerAction, prettyPrintPeerIdStr} from "../network/index.js";
|
|
19
19
|
import {PeerSyncMeta} from "../network/peers/peersData.js";
|
|
20
20
|
import {MAX_PEERS_PER_ROOT} from "../network/processor/constants.js";
|
|
21
21
|
import {ClockEvent} from "../util/clock.js";
|
|
@@ -73,7 +73,11 @@ type AdvancePendingBlockResult =
|
|
|
73
73
|
| "removed";
|
|
74
74
|
|
|
75
75
|
class UnknownBlockRateLimitedError extends Error {
|
|
76
|
-
constructor(
|
|
76
|
+
constructor(
|
|
77
|
+
message: string,
|
|
78
|
+
/** Earliest backoff expiry seen when the download was deferred, it is retried once that has passed */
|
|
79
|
+
readonly retryAt: number
|
|
80
|
+
) {
|
|
77
81
|
super(message);
|
|
78
82
|
this.name = "UnknownBlockRateLimitedError";
|
|
79
83
|
}
|
|
@@ -442,6 +446,11 @@ export class BlockInputSync {
|
|
|
442
446
|
};
|
|
443
447
|
|
|
444
448
|
private addByRootHex = (rootHex: RootHex, peerIdStr?: PeerIdStr): boolean => {
|
|
449
|
+
if (this.knownBadBlocks.has(rootHex)) {
|
|
450
|
+
this.logger.debug("Ignoring known bad block root", {root: rootHex, peerIdStr: peerIdStr ?? "unknown peer"});
|
|
451
|
+
return false;
|
|
452
|
+
}
|
|
453
|
+
|
|
445
454
|
let pendingBlock = this.pendingBlocks.get(rootHex);
|
|
446
455
|
let added = false;
|
|
447
456
|
if (!pendingBlock) {
|
|
@@ -477,6 +486,11 @@ export class BlockInputSync {
|
|
|
477
486
|
};
|
|
478
487
|
|
|
479
488
|
private addByBlockInput = (blockInput: IBlockInput, peerIdStr?: string): void => {
|
|
489
|
+
if (this.knownBadBlocks.has(blockInput.blockRootHex)) {
|
|
490
|
+
this.logger.debug("Ignoring known bad block", {slot: blockInput.slot, root: blockInput.blockRootHex, peerIdStr});
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
|
|
480
494
|
let pendingBlock = this.pendingBlocks.get(blockInput.blockRootHex);
|
|
481
495
|
// if entry is missing or was added via rootHex and now we have more complete information overwrite
|
|
482
496
|
// the existing information with the more complete cache entry
|
|
@@ -513,6 +527,15 @@ export class BlockInputSync {
|
|
|
513
527
|
};
|
|
514
528
|
|
|
515
529
|
private addByPayloadRootHex = (rootHex: RootHex, peerIdStr?: PeerIdStr, slot?: Slot): boolean => {
|
|
530
|
+
if (this.knownBadBlocks.has(rootHex)) {
|
|
531
|
+
this.logger.debug("Ignoring payload for known bad block root", {
|
|
532
|
+
slot: slot ?? "unknown",
|
|
533
|
+
root: rootHex,
|
|
534
|
+
peerIdStr,
|
|
535
|
+
});
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
|
|
516
539
|
let pendingPayload = this.pendingPayloads.get(rootHex);
|
|
517
540
|
let added = false;
|
|
518
541
|
if (!pendingPayload) {
|
|
@@ -581,6 +604,15 @@ export class BlockInputSync {
|
|
|
581
604
|
peerIdStr?: PeerIdStr,
|
|
582
605
|
envelope?: gloas.SignedExecutionPayloadEnvelope
|
|
583
606
|
): void => {
|
|
607
|
+
if (this.knownBadBlocks.has(payloadInput.blockRootHex)) {
|
|
608
|
+
this.logger.debug("Ignoring payload input for known bad block root", {
|
|
609
|
+
slot: payloadInput.slot,
|
|
610
|
+
root: payloadInput.blockRootHex,
|
|
611
|
+
peerIdStr,
|
|
612
|
+
});
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
|
|
584
616
|
const pendingPayload = this.toPendingPayloadInput(
|
|
585
617
|
payloadInput,
|
|
586
618
|
this.pendingPayloads.get(payloadInput.blockRootHex),
|
|
@@ -654,6 +686,7 @@ export class BlockInputSync {
|
|
|
654
686
|
return {kind: "ready"};
|
|
655
687
|
}
|
|
656
688
|
|
|
689
|
+
// The parent's payload is known but does not match `parentBlockHashHex`
|
|
657
690
|
if (this.chain.forkChoice.hasPayloadHexUnsafe(parentRootHex)) {
|
|
658
691
|
return {kind: "invalidParentPayload", parentRootHex, parentBlockHashHex};
|
|
659
692
|
}
|
|
@@ -820,17 +853,20 @@ export class BlockInputSync {
|
|
|
820
853
|
}
|
|
821
854
|
};
|
|
822
855
|
|
|
823
|
-
|
|
856
|
+
/**
|
|
857
|
+
* Returns false if there is no backoff left to wait for, in which case no retry is scheduled.
|
|
858
|
+
*/
|
|
859
|
+
private scheduleRateLimitBackoffRetry(): boolean {
|
|
824
860
|
this.clearRateLimitBackoffTimer();
|
|
825
861
|
|
|
826
862
|
if (!this.subscribedToNetworkEvents || (this.pendingBlocks.size === 0 && this.pendingPayloads.size === 0)) {
|
|
827
|
-
return;
|
|
863
|
+
return false;
|
|
828
864
|
}
|
|
829
865
|
|
|
830
866
|
const now = Date.now();
|
|
831
867
|
const retryAt = this.peerBalancer.getNextRateLimitRetryAt();
|
|
832
868
|
if (retryAt === null) {
|
|
833
|
-
return;
|
|
869
|
+
return false;
|
|
834
870
|
}
|
|
835
871
|
|
|
836
872
|
this.rateLimitBackoffTimeout = setTimeout(
|
|
@@ -841,6 +877,7 @@ export class BlockInputSync {
|
|
|
841
877
|
},
|
|
842
878
|
Math.max(0, retryAt - now)
|
|
843
879
|
);
|
|
880
|
+
return true;
|
|
844
881
|
}
|
|
845
882
|
|
|
846
883
|
private clearRateLimitBackoffTimer(): void {
|
|
@@ -1032,7 +1069,8 @@ export class BlockInputSync {
|
|
|
1032
1069
|
}
|
|
1033
1070
|
} else if (blockSlot <= finalizedSlot) {
|
|
1034
1071
|
// the common ancestor of the downloading chain and canonical chain should be at least the finalized slot and
|
|
1035
|
-
// we should found it through forkchoice. If not,
|
|
1072
|
+
// we should found it through forkchoice. If not, drop the chain without penalizing peers because pending entries are
|
|
1073
|
+
// block retained on failed download, so finalization can pass the block while it is still pending
|
|
1036
1074
|
// 0 - 1 - ... - n - finalizedSlot
|
|
1037
1075
|
// \
|
|
1038
1076
|
// parent 1 - parent 2 - ... - unknownParent block
|
|
@@ -1040,7 +1078,7 @@ export class BlockInputSync {
|
|
|
1040
1078
|
...logCtx2,
|
|
1041
1079
|
finalizedSlot,
|
|
1042
1080
|
});
|
|
1043
|
-
this.
|
|
1081
|
+
this.removeAllDescendants(block, DroppedItemReason.belowFinalized);
|
|
1044
1082
|
} else {
|
|
1045
1083
|
this.onUnknownBlockRoot({rootHex: pending.blockInput.parentRootHex, source: BlockInputSource.byRoot});
|
|
1046
1084
|
}
|
|
@@ -1051,7 +1089,11 @@ export class BlockInputSync {
|
|
|
1051
1089
|
pendingBlock.status = PendingBlockInputStatus.pending;
|
|
1052
1090
|
}
|
|
1053
1091
|
this.logger.debug("Deferring unknown block download due to peer rate limit", logCtx, res.err);
|
|
1054
|
-
this.scheduleRateLimitBackoffRetry()
|
|
1092
|
+
if (!this.scheduleRateLimitBackoffRetry() || res.err.retryAt <= Date.now()) {
|
|
1093
|
+
// The backoff this download waited for expired in the meantime, a timer is only armed if another
|
|
1094
|
+
// peer is still in backoff and would retry it later than needed
|
|
1095
|
+
this.triggerUnknownBlockSearch();
|
|
1096
|
+
}
|
|
1055
1097
|
return;
|
|
1056
1098
|
}
|
|
1057
1099
|
|
|
@@ -1172,15 +1214,18 @@ export class BlockInputSync {
|
|
|
1172
1214
|
break;
|
|
1173
1215
|
|
|
1174
1216
|
case BlockErrorCode.EXECUTION_ENGINE_INVALID:
|
|
1175
|
-
//
|
|
1217
|
+
// Ban but do not downscore: optimistic-sync peers may forward and serve blocks whose payload is later
|
|
1218
|
+
// rejected by the execution engine. Per the spec, an INVALID execution payload SHOULD NOT cause a peer
|
|
1219
|
+
// to be down-scored or disconnected, only consensus-layer invalidity MAY.
|
|
1220
|
+
// https://github.com/ethereum/consensus-specs/blob/master/specs/bellatrix/p2p-interface.md#the-reqresp-domain
|
|
1176
1221
|
this.logger.debug("Execution engine rejected block from unknown parent sync", errorData, res.err);
|
|
1177
|
-
this.
|
|
1222
|
+
this.removeAndBanAllDescendants(pendingBlock, DroppedItemReason.elInvalid);
|
|
1178
1223
|
break;
|
|
1179
1224
|
|
|
1180
1225
|
default:
|
|
1181
1226
|
// Block is not correct with respect to our chain. Log error loudly
|
|
1182
1227
|
this.logger.debug("Error processing block from unknown parent sync", errorData, res.err);
|
|
1183
|
-
this.
|
|
1228
|
+
this.removeAllDescendants(pendingBlock, DroppedItemReason.invalidBlock);
|
|
1184
1229
|
}
|
|
1185
1230
|
}
|
|
1186
1231
|
|
|
@@ -1331,6 +1376,14 @@ export class BlockInputSync {
|
|
|
1331
1376
|
if (!isPendingPayloadEnvelope(payload)) {
|
|
1332
1377
|
payload.status = PendingPayloadInputStatus.pending;
|
|
1333
1378
|
}
|
|
1379
|
+
if (
|
|
1380
|
+
res.err instanceof UnknownBlockRateLimitedError &&
|
|
1381
|
+
(!this.scheduleRateLimitBackoffRetry() || res.err.retryAt <= Date.now())
|
|
1382
|
+
) {
|
|
1383
|
+
// The backoff this download waited for expired in the meantime, a timer is only armed if another
|
|
1384
|
+
// peer is still in backoff and would retry it later than needed
|
|
1385
|
+
this.triggerUnknownBlockSearch();
|
|
1386
|
+
}
|
|
1334
1387
|
}
|
|
1335
1388
|
|
|
1336
1389
|
private async processPayload(pendingPayload: PendingPayloadInput): Promise<void> {
|
|
@@ -1393,20 +1446,23 @@ export class BlockInputSync {
|
|
|
1393
1446
|
pendingPayload.status = PendingPayloadInputStatus.downloaded;
|
|
1394
1447
|
break;
|
|
1395
1448
|
|
|
1449
|
+
// The invalid envelope is evicted from the seen cache in the cases below, otherwise the next
|
|
1450
|
+
// attempt would reuse it instead of fetching another envelope from peers
|
|
1396
1451
|
case PayloadErrorCode.EXECUTION_ENGINE_INVALID:
|
|
1397
1452
|
this.logger.debug("Error processing payload from unknown sync", logCtx, res.err);
|
|
1453
|
+
this.chain.seenPayloadEnvelopeInputCache.removeInvalid(pendingPayload.payloadInput);
|
|
1398
1454
|
this.removePendingPayloadAndDescendants(rootHex, DroppedItemReason.elInvalid);
|
|
1399
1455
|
break;
|
|
1400
1456
|
|
|
1401
1457
|
case PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR:
|
|
1402
1458
|
this.logger.debug("Error processing payload from unknown sync", logCtx, res.err);
|
|
1459
|
+
this.chain.seenPayloadEnvelopeInputCache.removeInvalid(pendingPayload.payloadInput);
|
|
1403
1460
|
this.removePendingPayloadAndDescendants(rootHex, DroppedItemReason.invalidEnvelope);
|
|
1404
1461
|
break;
|
|
1405
1462
|
|
|
1406
1463
|
case PayloadErrorCode.INVALID_SIGNATURE:
|
|
1407
|
-
// TODO GLOAS: Decide how invalid payload inputs should eventually leave memory without
|
|
1408
|
-
// reintroducing envelope replacement / recreation flows.
|
|
1409
1464
|
this.logger.debug("Error processing payload from unknown sync", logCtx, res.err);
|
|
1465
|
+
this.chain.seenPayloadEnvelopeInputCache.removeInvalid(pendingPayload.payloadInput);
|
|
1410
1466
|
this.removePendingPayloadAndDescendants(rootHex, DroppedItemReason.invalidSignature);
|
|
1411
1467
|
break;
|
|
1412
1468
|
|
|
@@ -1452,16 +1508,21 @@ export class BlockInputSync {
|
|
|
1452
1508
|
const pendingColumns = payloadInput?.hasAllData()
|
|
1453
1509
|
? new Set<number>()
|
|
1454
1510
|
: new Set(payloadInput?.getMissingSampledColumnMeta().missing ?? []);
|
|
1511
|
+
// Same `now` for both calls, a backoff expiring in between would be reported as no peer available
|
|
1512
|
+
const now = Date.now();
|
|
1455
1513
|
// prefer peers that gossiped this payload root to us (#9923)
|
|
1456
1514
|
const peerMeta = this.peerBalancer.bestPeerForPendingColumns(
|
|
1457
1515
|
pendingColumns,
|
|
1458
1516
|
excludedPeers,
|
|
1459
|
-
cacheItem.peerIdStrings
|
|
1517
|
+
cacheItem.peerIdStrings,
|
|
1518
|
+
now
|
|
1460
1519
|
);
|
|
1461
1520
|
if (peerMeta === null) {
|
|
1462
|
-
|
|
1521
|
+
const retryAt = this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers, now);
|
|
1522
|
+
if (retryAt !== null) {
|
|
1463
1523
|
throw new UnknownBlockRateLimitedError(
|
|
1464
|
-
`Error fetching payload by root slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited
|
|
1524
|
+
`Error fetching payload by root slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited`,
|
|
1525
|
+
retryAt
|
|
1465
1526
|
);
|
|
1466
1527
|
}
|
|
1467
1528
|
|
|
@@ -1478,11 +1539,11 @@ export class BlockInputSync {
|
|
|
1478
1539
|
}
|
|
1479
1540
|
|
|
1480
1541
|
const {peerId, client: peerClient} = peerMeta;
|
|
1481
|
-
cacheItem.peerIdStrings.add(peerId);
|
|
1482
1542
|
|
|
1483
1543
|
try {
|
|
1484
1544
|
if (!envelope) {
|
|
1485
1545
|
envelope = await this.fetchExecutionPayloadEnvelope(peerId, blockRoot, rootHex);
|
|
1546
|
+
cacheItem.peerIdStrings.add(peerId);
|
|
1486
1547
|
const slotWasUnknown = typeof slot !== "number";
|
|
1487
1548
|
slot = envelope.message.payload.slotNumber;
|
|
1488
1549
|
if (slotWasUnknown) {
|
|
@@ -1524,6 +1585,8 @@ export class BlockInputSync {
|
|
|
1524
1585
|
const missing = pendingPayload.payloadInput.getMissingSampledColumnMeta().missing;
|
|
1525
1586
|
if (missing.length > 0) {
|
|
1526
1587
|
const columnSidecars = await this.fetchPayloadColumns(peerMeta, pendingPayload.payloadInput, missing);
|
|
1588
|
+
// toPendingPayloadInput copied cacheItem's set, so add to the object that is carried forward
|
|
1589
|
+
pendingPayload.peerIdStrings.add(peerId);
|
|
1527
1590
|
const seenTimestampSec = Date.now() / 1000;
|
|
1528
1591
|
for (const columnSidecar of columnSidecars) {
|
|
1529
1592
|
if (pendingPayload.payloadInput.hasColumn(columnSidecar.index)) {
|
|
@@ -1598,9 +1661,11 @@ export class BlockInputSync {
|
|
|
1598
1661
|
);
|
|
1599
1662
|
this.metrics?.blockInputSync.payloadFetchPeers.set({result: FetchResult.FailureMaxAttempts}, i - 1);
|
|
1600
1663
|
|
|
1601
|
-
|
|
1664
|
+
const retryAt = deferredByRateLimit ? this.peerBalancer.getNextRateLimitRetryAt() : null;
|
|
1665
|
+
if (retryAt !== null) {
|
|
1602
1666
|
throw new UnknownBlockRateLimitedError(
|
|
1603
|
-
`Error fetching payload with slot=${slot} root=${rootHex} after ${i - 1} attempts: peers are rate-limited
|
|
1667
|
+
`Error fetching payload with slot=${slot} root=${rootHex} after ${i - 1} attempts: peers are rate-limited`,
|
|
1668
|
+
retryAt
|
|
1604
1669
|
);
|
|
1605
1670
|
}
|
|
1606
1671
|
throw Error(`Error fetching payload with slot=${slot} root=${rootHex} after ${i - 1} attempts.`);
|
|
@@ -1692,16 +1757,21 @@ export class BlockInputSync {
|
|
|
1692
1757
|
isPendingBlockInput(cacheItem) && isBlockInputColumns(cacheItem.blockInput)
|
|
1693
1758
|
? new Set(cacheItem.blockInput.getMissingSampledColumnMeta().missing)
|
|
1694
1759
|
: defaultPendingColumns;
|
|
1760
|
+
// Same `now` for both calls, a backoff expiring in between would be reported as no peer available
|
|
1761
|
+
const now = Date.now();
|
|
1695
1762
|
// prefer peers that gossiped this block root to us (#9923)
|
|
1696
1763
|
const peerMeta = this.peerBalancer.bestPeerForPendingColumns(
|
|
1697
1764
|
pendingColumns,
|
|
1698
1765
|
excludedPeers,
|
|
1699
|
-
cacheItem.peerIdStrings
|
|
1766
|
+
cacheItem.peerIdStrings,
|
|
1767
|
+
now
|
|
1700
1768
|
);
|
|
1701
1769
|
if (peerMeta === null) {
|
|
1702
|
-
|
|
1770
|
+
const retryAt = this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers, now);
|
|
1771
|
+
if (retryAt !== null) {
|
|
1703
1772
|
throw new UnknownBlockRateLimitedError(
|
|
1704
|
-
`Error fetching UnknownBlockRoot slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited
|
|
1773
|
+
`Error fetching UnknownBlockRoot slot=${slot} root=${rootHex} after ${i}: peers with needed columns are rate-limited`,
|
|
1774
|
+
retryAt
|
|
1705
1775
|
);
|
|
1706
1776
|
}
|
|
1707
1777
|
|
|
@@ -1716,8 +1786,6 @@ export class BlockInputSync {
|
|
|
1716
1786
|
}
|
|
1717
1787
|
const {peerId, client: peerClient} = peerMeta;
|
|
1718
1788
|
|
|
1719
|
-
cacheItem.peerIdStrings.add(peerId);
|
|
1720
|
-
|
|
1721
1789
|
try {
|
|
1722
1790
|
const downloadResult = await downloadByRoot({
|
|
1723
1791
|
config: this.config,
|
|
@@ -1728,6 +1796,7 @@ export class BlockInputSync {
|
|
|
1728
1796
|
cacheItem,
|
|
1729
1797
|
});
|
|
1730
1798
|
cacheItem = downloadResult.result;
|
|
1799
|
+
cacheItem.peerIdStrings.add(peerId);
|
|
1731
1800
|
if (slot === undefined) {
|
|
1732
1801
|
slot = cacheItem.blockInput.slot;
|
|
1733
1802
|
// we were not able to observe the time into slot when starting the fetch, do it now
|
|
@@ -1808,8 +1877,9 @@ export class BlockInputSync {
|
|
|
1808
1877
|
|
|
1809
1878
|
const message = `Error fetching BlockInput with slot=${slot} root=${rootHex} after ${i - 1} attempts.`;
|
|
1810
1879
|
|
|
1811
|
-
|
|
1812
|
-
|
|
1880
|
+
const retryAt = deferredByRateLimit ? this.peerBalancer.getNextRateLimitRetryAt() : null;
|
|
1881
|
+
if (retryAt !== null) {
|
|
1882
|
+
throw new UnknownBlockRateLimitedError(`${message} Peers are rate-limited.`, retryAt);
|
|
1813
1883
|
}
|
|
1814
1884
|
|
|
1815
1885
|
if (!isPendingBlockInput(cacheItem)) {
|
|
@@ -1843,44 +1913,8 @@ export class BlockInputSync {
|
|
|
1843
1913
|
throw Error(message);
|
|
1844
1914
|
}
|
|
1845
1915
|
|
|
1846
|
-
/**
|
|
1847
|
-
* Gets all descendant blocks of `block` recursively from `pendingBlocks`.
|
|
1848
|
-
* Assumes that if a parent block does not exist or is not processable, all descendant blocks are bad too.
|
|
1849
|
-
* Downscore all peers that have referenced any of this bad blocks. May report peers multiple times if they have
|
|
1850
|
-
* referenced more than one bad block.
|
|
1851
|
-
*/
|
|
1852
|
-
private removeAndDownScoreAllDescendants(block: BlockInputSyncCacheItem, headReason: DroppedItemReason): void {
|
|
1853
|
-
// Get all blocks that are a descendant of this one
|
|
1854
|
-
const badPendingBlocks = this.removeAllDescendants(block, headReason, DroppedItemReason.invalidParent);
|
|
1855
|
-
// just console log and do not penalize on pending/bad blocks for debugging
|
|
1856
|
-
// console.log("removeAndDownscoreAllDescendants", {block});
|
|
1857
|
-
|
|
1858
|
-
for (const block of badPendingBlocks) {
|
|
1859
|
-
//
|
|
1860
|
-
// TODO(fulu): why is this commented out here?
|
|
1861
|
-
//
|
|
1862
|
-
// this.knownBadBlocks.add(block.blockRootHex);
|
|
1863
|
-
// for (const peerIdStr of block.peerIdStrings) {
|
|
1864
|
-
// // TODO: Refactor peerRpcScores to work with peerIdStr only
|
|
1865
|
-
// this.network.reportPeer(peerIdStr, PeerAction.LowToleranceError, "BadBlockByRoot");
|
|
1866
|
-
// }
|
|
1867
|
-
this.logger.debug("ignored Banning unknown block", {
|
|
1868
|
-
slot: getBlockInputSyncCacheItemSlot(block),
|
|
1869
|
-
root: getBlockInputSyncCacheItemRootHex(block),
|
|
1870
|
-
peerIdStrings: Array.from(block.peerIdStrings)
|
|
1871
|
-
.map((id) => prettyPrintPeerIdStr(id))
|
|
1872
|
-
.join(","),
|
|
1873
|
-
});
|
|
1874
|
-
}
|
|
1875
|
-
|
|
1876
|
-
// Prune knownBadBlocks
|
|
1877
|
-
pruneSetToMax(this.knownBadBlocks, MAX_KNOWN_BAD_BLOCKS);
|
|
1878
|
-
}
|
|
1879
|
-
|
|
1880
1916
|
// Once a parent payload is invalid, every descendant waiting on that payload lineage becomes unrecoverable too.
|
|
1881
1917
|
private removePendingPayloadAndDescendants(rootHex: RootHex, headReason: DroppedItemReason): void {
|
|
1882
|
-
// Keep PayloadEnvelopeInput resident in the seen cache. importBlock() owns that object and
|
|
1883
|
-
// later validation/finalization logic decides when it can leave memory.
|
|
1884
1918
|
if (this.pendingPayloads.delete(rootHex)) {
|
|
1885
1919
|
this.metrics?.blockInputSync.removedPayloads.inc({reason: headReason}, 1);
|
|
1886
1920
|
}
|
|
@@ -1903,13 +1937,61 @@ export class BlockInputSync {
|
|
|
1903
1937
|
}
|
|
1904
1938
|
}
|
|
1905
1939
|
|
|
1940
|
+
/**
|
|
1941
|
+
* Same as `removeAndBanAllDescendants`, and downscores every peer that referenced or served a banned item, once per
|
|
1942
|
+
* peer. Only call for consensus-layer invalidity, never for an INVALID execution payload:
|
|
1943
|
+
* https://github.com/ethereum/consensus-specs/blob/master/specs/bellatrix/p2p-interface.md#the-reqresp-domain
|
|
1944
|
+
*/
|
|
1945
|
+
private removeAndDownScoreAllDescendants(block: BlockInputSyncCacheItem, headReason: DroppedItemReason): void {
|
|
1946
|
+
const peersToReport = new Set<PeerIdStr>();
|
|
1947
|
+
for (const bannedBlock of this.removeAndBanAllDescendants(block, headReason)) {
|
|
1948
|
+
for (const peerIdStr of bannedBlock.peerIdStrings) {
|
|
1949
|
+
peersToReport.add(peerIdStr);
|
|
1950
|
+
}
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
for (const peerIdStr of peersToReport) {
|
|
1954
|
+
this.network.reportPeer(peerIdStr, PeerAction.LowToleranceError, headReason);
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
/**
|
|
1959
|
+
* Removes `block` and all its pending descendants and bans their roots in `knownBadBlocks`. Only call when the chain
|
|
1960
|
+
* is provably bad: a banned root is never searched for again. Returns the banned items.
|
|
1961
|
+
*/
|
|
1962
|
+
private removeAndBanAllDescendants(
|
|
1963
|
+
block: BlockInputSyncCacheItem,
|
|
1964
|
+
headReason: DroppedItemReason
|
|
1965
|
+
): BlockInputSyncCacheItem[] {
|
|
1966
|
+
const bannedBlocks: BlockInputSyncCacheItem[] = [];
|
|
1967
|
+
for (const badBlock of this.removeAllDescendants(block, headReason, DroppedItemReason.invalidParent)) {
|
|
1968
|
+
const rootHex = getBlockInputSyncCacheItemRootHex(badBlock);
|
|
1969
|
+
// a gossip import may race a failing sync path, never ban a root fork choice has imported
|
|
1970
|
+
if (this.chain.forkChoice.hasBlockHex(rootHex)) {
|
|
1971
|
+
continue;
|
|
1972
|
+
}
|
|
1973
|
+
this.knownBadBlocks.add(rootHex);
|
|
1974
|
+
bannedBlocks.push(badBlock);
|
|
1975
|
+
this.logger.debug("Banning unknown block", {
|
|
1976
|
+
slot: getBlockInputSyncCacheItemSlot(badBlock),
|
|
1977
|
+
root: rootHex,
|
|
1978
|
+
reason: headReason,
|
|
1979
|
+
peerIdStrings: Array.from(badBlock.peerIdStrings)
|
|
1980
|
+
.map((id) => prettyPrintPeerIdStr(id))
|
|
1981
|
+
.join(","),
|
|
1982
|
+
});
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
pruneSetToMax(this.knownBadBlocks, MAX_KNOWN_BAD_BLOCKS);
|
|
1986
|
+
return bannedBlocks;
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1906
1989
|
private removeAllDescendants(
|
|
1907
1990
|
block: BlockInputSyncCacheItem,
|
|
1908
1991
|
headReason: DroppedItemReason,
|
|
1909
1992
|
descendantReason: DroppedItemReason = DroppedItemReason.invalidParent
|
|
1910
1993
|
): BlockInputSyncCacheItem[] {
|
|
1911
1994
|
const rootHex = getBlockInputSyncCacheItemRootHex(block);
|
|
1912
|
-
const slot = getBlockInputSyncCacheItemSlot(block);
|
|
1913
1995
|
// Get all blocks that are a descendant of this one (index 0 is the head item itself)
|
|
1914
1996
|
const badPendingBlocks = [block, ...getAllDescendantBlocks(rootHex, this.pendingBlocks)];
|
|
1915
1997
|
|
|
@@ -1926,8 +2008,8 @@ export class BlockInputSync {
|
|
|
1926
2008
|
// Keep PayloadEnvelopeInput resident in the seen cache for consistency with the
|
|
1927
2009
|
// importBlock()-owned lifecycle.
|
|
1928
2010
|
this.logger.debug("Removing bad/unknown/incomplete BlockInputSyncCacheItem", {
|
|
1929
|
-
slot,
|
|
1930
|
-
|
|
2011
|
+
slot: getBlockInputSyncCacheItemSlot(block),
|
|
2012
|
+
root: rootHex,
|
|
1931
2013
|
});
|
|
1932
2014
|
}
|
|
1933
2015
|
|
|
@@ -1988,8 +2070,11 @@ export class UnknownBlockPeerBalancer {
|
|
|
1988
2070
|
this.rateLimitedUntilByPeer.set(peerId, rateLimitedUntilMs);
|
|
1989
2071
|
}
|
|
1990
2072
|
|
|
1991
|
-
getNextRateLimitRetryAt(
|
|
1992
|
-
|
|
2073
|
+
getNextRateLimitRetryAt(
|
|
2074
|
+
pendingColumns?: Set<number>,
|
|
2075
|
+
excludedPeers?: Set<PeerIdStr>,
|
|
2076
|
+
now = Date.now()
|
|
2077
|
+
): number | null {
|
|
1993
2078
|
let retryAt: number | null = null;
|
|
1994
2079
|
|
|
1995
2080
|
for (const [peerId, rateLimitedUntil] of this.rateLimitedUntilByPeer.entries()) {
|
|
@@ -2028,9 +2113,10 @@ export class UnknownBlockPeerBalancer {
|
|
|
2028
2113
|
bestPeerForPendingColumns(
|
|
2029
2114
|
pendingColumns: Set<number>,
|
|
2030
2115
|
excludedPeers: Set<PeerIdStr>,
|
|
2031
|
-
preferredPeers?: Set<PeerIdStr
|
|
2116
|
+
preferredPeers?: Set<PeerIdStr>,
|
|
2117
|
+
now = Date.now()
|
|
2032
2118
|
): PeerSyncMeta | null {
|
|
2033
|
-
const eligiblePeers = this.filterPeers(pendingColumns, excludedPeers);
|
|
2119
|
+
const eligiblePeers = this.filterPeers(pendingColumns, excludedPeers, now);
|
|
2034
2120
|
if (eligiblePeers.length === 0) {
|
|
2035
2121
|
return null;
|
|
2036
2122
|
}
|
|
@@ -2071,8 +2157,7 @@ export class UnknownBlockPeerBalancer {
|
|
|
2071
2157
|
return totalActiveRequests;
|
|
2072
2158
|
}
|
|
2073
2159
|
|
|
2074
|
-
private filterPeers(pendingDataColumns: Set<number>, excludedPeers: Set<PeerIdStr
|
|
2075
|
-
const now = Date.now();
|
|
2160
|
+
private filterPeers(pendingDataColumns: Set<number>, excludedPeers: Set<PeerIdStr>, now: number): PeerIdStr[] {
|
|
2076
2161
|
let maxColumnCount = 0;
|
|
2077
2162
|
const considerPeers: {peerId: PeerIdStr; columnCount: number}[] = [];
|
|
2078
2163
|
for (const [peerId, syncMeta] of this.peersMeta.entries()) {
|