@lodestar/beacon-node 1.43.0-dev.a142c56215 → 1.43.0-dev.a691e9b4dd
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 +13 -3
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +45 -2
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +0 -1
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +68 -2
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +3 -0
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +4 -1
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +23 -22
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +5 -3
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +25 -14
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +36 -21
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +4 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +9 -2
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/types.d.ts +2 -1
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +8 -0
- package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts +2 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +30 -12
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +0 -4
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -2
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts +2 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +16 -7
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +7 -4
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -1
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js +8 -3
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -1
- package/lib/chain/chain.d.ts +2 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +5 -1
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +0 -11
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +0 -4
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/index.d.ts +1 -0
- package/lib/chain/errors/index.d.ts.map +1 -1
- package/lib/chain/errors/index.js +1 -0
- package/lib/chain/errors/index.js.map +1 -1
- package/lib/chain/errors/proposerPreferences.d.ts +40 -0
- package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/errors/proposerPreferences.js +14 -0
- package/lib/chain/errors/proposerPreferences.js.map +1 -0
- package/lib/chain/interface.d.ts +2 -1
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.d.ts +3 -2
- package/lib/chain/opPools/payloadAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +26 -4
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +15 -17
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +12 -3
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +34 -22
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +1 -0
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +1 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +1 -4
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +1 -4
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/index.d.ts +1 -0
- package/lib/chain/seenCache/index.d.ts.map +1 -1
- package/lib/chain/seenCache/index.js +1 -0
- package/lib/chain/seenCache/index.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +8 -2
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +20 -4
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/seenCache/seenProposerPreferences.d.ts +16 -0
- package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
- package/lib/chain/seenCache/seenProposerPreferences.js +31 -0
- package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
- package/lib/chain/validation/executionPayloadBid.js +11 -8
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/proposerPreferences.d.ts +8 -0
- package/lib/chain/validation/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/validation/proposerPreferences.js +91 -0
- package/lib/chain/validation/proposerPreferences.js.map +1 -0
- package/lib/network/gossip/interface.d.ts +7 -1
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/interface.js +1 -0
- package/lib/network/gossip/interface.js.map +1 -1
- package/lib/network/gossip/scoringParameters.d.ts.map +1 -1
- package/lib/network/gossip/scoringParameters.js +12 -1
- package/lib/network/gossip/scoringParameters.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +29 -766
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +6 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/interface.d.ts +1 -0
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +1 -0
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +5 -0
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +22 -15
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipQueues/index.d.ts.map +1 -1
- package/lib/network/processor/gossipQueues/index.js +5 -0
- package/lib/network/processor/gossipQueues/index.js.map +1 -1
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +6 -5
- package/lib/network/processor/index.js.map +1 -1
- package/lib/node/nodejs.js +2 -2
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/notifier.js +1 -7
- package/lib/node/notifier.js.map +1 -1
- package/lib/sync/range/batch.d.ts +11 -0
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +83 -21
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +23 -5
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +0 -2
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +0 -47
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +36 -21
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +10 -0
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +8 -6
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +16 -3
- package/src/api/impl/beacon/pool/index.ts +83 -1
- package/src/api/impl/debug/index.ts +0 -1
- package/src/api/impl/validator/index.ts +82 -1
- package/src/chain/blocks/blockInput/blockInput.ts +4 -1
- package/src/chain/blocks/importBlock.ts +23 -39
- package/src/chain/blocks/importExecutionPayload.ts +33 -14
- package/src/chain/blocks/index.ts +34 -15
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +10 -2
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -0
- package/src/chain/blocks/types.ts +2 -1
- package/src/chain/blocks/utils/chainSegment.ts +8 -0
- package/src/chain/blocks/verifyBlock.ts +45 -13
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +6 -4
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +16 -6
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +9 -4
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +7 -4
- package/src/chain/chain.ts +5 -0
- package/src/chain/emitter.ts +0 -11
- package/src/chain/errors/index.ts +1 -0
- package/src/chain/errors/proposerPreferences.ts +47 -0
- package/src/chain/interface.ts +2 -0
- package/src/chain/opPools/payloadAttestationPool.ts +29 -8
- package/src/chain/prepareNextSlot.ts +20 -28
- package/src/chain/produceBlock/produceBlockBody.ts +45 -27
- package/src/chain/regen/interface.ts +1 -0
- package/src/chain/regen/queued.ts +2 -7
- package/src/chain/regen/regen.ts +2 -7
- package/src/chain/seenCache/index.ts +1 -0
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +25 -5
- package/src/chain/seenCache/seenProposerPreferences.ts +37 -0
- package/src/chain/validation/executionPayloadBid.ts +11 -8
- package/src/chain/validation/proposerPreferences.ts +110 -0
- package/src/network/gossip/interface.ts +6 -0
- package/src/network/gossip/scoringParameters.ts +14 -1
- package/src/network/gossip/topic.ts +6 -0
- package/src/network/interface.ts +1 -0
- package/src/network/network.ts +11 -0
- package/src/network/processor/gossipHandlers.ts +31 -16
- package/src/network/processor/gossipQueues/index.ts +5 -0
- package/src/network/processor/index.ts +6 -5
- package/src/node/nodejs.ts +2 -2
- package/src/node/notifier.ts +1 -8
- package/src/sync/range/batch.ts +108 -24
- package/src/sync/range/chain.ts +25 -5
- package/src/sync/unknownBlock.ts +0 -50
- package/src/sync/utils/downloadByRange.ts +37 -21
- package/src/sync/utils/downloadByRoot.ts +12 -0
- package/src/util/sszBytes.ts +8 -6
|
@@ -52,6 +52,8 @@ import {
|
|
|
52
52
|
ExecutionPayloadEnvelopeErrorCode,
|
|
53
53
|
GossipAction,
|
|
54
54
|
GossipActionError,
|
|
55
|
+
PayloadAttestationError,
|
|
56
|
+
PayloadAttestationErrorCode,
|
|
55
57
|
SyncCommitteeError,
|
|
56
58
|
} from "../../chain/errors/index.js";
|
|
57
59
|
import {IBeaconChain} from "../../chain/interface.js";
|
|
@@ -79,6 +81,7 @@ import {
|
|
|
79
81
|
import {validateLightClientFinalityUpdate} from "../../chain/validation/lightClientFinalityUpdate.js";
|
|
80
82
|
import {validateLightClientOptimisticUpdate} from "../../chain/validation/lightClientOptimisticUpdate.js";
|
|
81
83
|
import {validateGossipPayloadAttestationMessage} from "../../chain/validation/payloadAttestationMessage.js";
|
|
84
|
+
import {validateGossipProposerPreferences} from "../../chain/validation/proposerPreferences.js";
|
|
82
85
|
import {OpSource} from "../../chain/validatorMonitor.js";
|
|
83
86
|
import {Metrics} from "../../metrics/index.js";
|
|
84
87
|
import {kzgCommitmentToVersionedHash} from "../../util/blobs.js";
|
|
@@ -182,6 +185,18 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
182
185
|
});
|
|
183
186
|
try {
|
|
184
187
|
await validateGossipBlock(config, chain, signedBlock, fork);
|
|
188
|
+
|
|
189
|
+
if (isForkPostGloas(fork)) {
|
|
190
|
+
chain.seenPayloadEnvelopeInputCache.add({
|
|
191
|
+
blockRootHex,
|
|
192
|
+
block: signedBlock as SignedBeaconBlock<ForkPostGloas>,
|
|
193
|
+
forkName: fork,
|
|
194
|
+
sampledColumns: chain.custodyConfig.sampledColumns,
|
|
195
|
+
custodyColumns: chain.custodyConfig.custodyColumns,
|
|
196
|
+
timeCreatedSec: seenTimestampSec,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
185
200
|
const blockInputMeta = blockInput.getLogMeta();
|
|
186
201
|
|
|
187
202
|
const recvToValidation = Date.now() / 1000 - seenTimestampSec;
|
|
@@ -1060,10 +1075,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1060
1075
|
const signedEnvelope = sszDeserialize(topic, serializedData);
|
|
1061
1076
|
const envelope = signedEnvelope.message;
|
|
1062
1077
|
|
|
1063
|
-
//
|
|
1064
|
-
//
|
|
1065
|
-
// the problem now is we cannot create a PayloadEnvelopeInput without the beacon block being known, we need at least the proposer index
|
|
1066
|
-
// we can achieve that by looking into the EpochCache
|
|
1078
|
+
// unlike BlockInput, we send the envelope into UnknownBlockInput sync
|
|
1079
|
+
// inside the sync it'll reconcile into PayloadEnvelopeInput and share the same cache with gossip
|
|
1067
1080
|
try {
|
|
1068
1081
|
await validateGossipExecutionPayloadEnvelope(chain, signedEnvelope);
|
|
1069
1082
|
} catch (e) {
|
|
@@ -1071,14 +1084,6 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1071
1084
|
const {beaconBlockRoot} = signedEnvelope.message;
|
|
1072
1085
|
const slot = signedEnvelope.message.payload.slotNumber;
|
|
1073
1086
|
logger.debug("Gossip envelope has error", {slot, root: toRootHex(beaconBlockRoot), code: e.type.code});
|
|
1074
|
-
if (e.type.code === ExecutionPayloadEnvelopeErrorCode.BLOCK_ROOT_UNKNOWN) {
|
|
1075
|
-
// TODO GLOAS: UnknownBlockSync to handle this
|
|
1076
|
-
chain.emitter.emit(ChainEvent.envelopeUnknownBlock, {
|
|
1077
|
-
envelope: signedEnvelope,
|
|
1078
|
-
peer: peerIdStr,
|
|
1079
|
-
source: BlockInputSource.gossip,
|
|
1080
|
-
});
|
|
1081
|
-
}
|
|
1082
1087
|
|
|
1083
1088
|
if (e.action === GossipAction.REJECT) {
|
|
1084
1089
|
chain.persistInvalidSszValue(
|
|
@@ -1173,6 +1178,14 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1173
1178
|
data: executionPayloadBid,
|
|
1174
1179
|
});
|
|
1175
1180
|
},
|
|
1181
|
+
[GossipType.proposer_preferences]: async ({
|
|
1182
|
+
gossipData,
|
|
1183
|
+
topic,
|
|
1184
|
+
}: GossipHandlerParamGeneric<GossipType.proposer_preferences>) => {
|
|
1185
|
+
const {serializedData} = gossipData;
|
|
1186
|
+
const signedProposerPreferences = sszDeserialize(topic, serializedData);
|
|
1187
|
+
await validateGossipProposerPreferences(chain, signedProposerPreferences);
|
|
1188
|
+
},
|
|
1176
1189
|
};
|
|
1177
1190
|
}
|
|
1178
1191
|
|
|
@@ -1295,10 +1308,12 @@ export async function validateGossipFnRetryUnknownRoot<T>(
|
|
|
1295
1308
|
try {
|
|
1296
1309
|
return await fn();
|
|
1297
1310
|
} catch (e) {
|
|
1298
|
-
|
|
1299
|
-
e instanceof AttestationError &&
|
|
1300
|
-
|
|
1301
|
-
|
|
1311
|
+
const isUnknownAttestationRoot =
|
|
1312
|
+
e instanceof AttestationError && e.type.code === AttestationErrorCode.UNKNOWN_OR_PREFINALIZED_BEACON_BLOCK_ROOT;
|
|
1313
|
+
const isUnknownPayloadAttestationRoot =
|
|
1314
|
+
e instanceof PayloadAttestationError && e.type.code === PayloadAttestationErrorCode.UNKNOWN_BLOCK_ROOT;
|
|
1315
|
+
|
|
1316
|
+
if (isUnknownAttestationRoot || isUnknownPayloadAttestationRoot) {
|
|
1302
1317
|
if (unknownBlockRootRetries === 0) {
|
|
1303
1318
|
// Trigger unknown block root search here
|
|
1304
1319
|
const rootHex = toRootHex(blockRoot);
|
|
@@ -83,6 +83,11 @@ const linearGossipQueueOpts: {
|
|
|
83
83
|
type: QueueType.FIFO,
|
|
84
84
|
dropOpts: {type: DropType.count, count: 1},
|
|
85
85
|
},
|
|
86
|
+
[GossipType.proposer_preferences]: {
|
|
87
|
+
maxLength: 1024,
|
|
88
|
+
type: QueueType.FIFO,
|
|
89
|
+
dropOpts: {type: DropType.count, count: 1},
|
|
90
|
+
},
|
|
86
91
|
};
|
|
87
92
|
|
|
88
93
|
const indexedGossipQueueOpts: {
|
|
@@ -76,6 +76,7 @@ type WorkOpts = {
|
|
|
76
76
|
*/
|
|
77
77
|
const executeGossipWorkOrderObj: Record<GossipType, WorkOpts> = {
|
|
78
78
|
[GossipType.beacon_block]: {bypassQueue: true},
|
|
79
|
+
[GossipType.execution_payload]: {bypassQueue: true},
|
|
79
80
|
[GossipType.blob_sidecar]: {bypassQueue: true},
|
|
80
81
|
[GossipType.data_column_sidecar]: {bypassQueue: true},
|
|
81
82
|
[GossipType.beacon_aggregate_and_proof]: {},
|
|
@@ -88,9 +89,9 @@ const executeGossipWorkOrderObj: Record<GossipType, WorkOpts> = {
|
|
|
88
89
|
[GossipType.sync_committee]: {},
|
|
89
90
|
[GossipType.light_client_finality_update]: {},
|
|
90
91
|
[GossipType.light_client_optimistic_update]: {},
|
|
91
|
-
[GossipType.execution_payload]: {bypassQueue: true},
|
|
92
92
|
[GossipType.payload_attestation_message]: {},
|
|
93
93
|
[GossipType.execution_payload_bid]: {},
|
|
94
|
+
[GossipType.proposer_preferences]: {},
|
|
94
95
|
};
|
|
95
96
|
const executeGossipWorkOrder = Object.keys(executeGossipWorkOrderObj) as (keyof typeof executeGossipWorkOrderObj)[];
|
|
96
97
|
|
|
@@ -443,8 +444,7 @@ export class NetworkProcessor {
|
|
|
443
444
|
}
|
|
444
445
|
case GossipType.execution_payload: {
|
|
445
446
|
// extractBlockSlotRootFn does not return a root for this topic.
|
|
446
|
-
// Extract beacon_block_root directly
|
|
447
|
-
// Do NOT await the block — the handler runs immediately; BlockInputSync handles recovery.
|
|
447
|
+
// Extract beacon_block_root directly
|
|
448
448
|
const blockRoot = getBeaconBlockRootFromExecutionPayloadEnvelopeSerialized(message.msg.data);
|
|
449
449
|
if (blockRoot && !this.chain.forkChoice.hasBlockHexUnsafe(blockRoot)) {
|
|
450
450
|
this.searchUnknownBlock(
|
|
@@ -452,9 +452,10 @@ export class NetworkProcessor {
|
|
|
452
452
|
BlockInputSource.network_processor,
|
|
453
453
|
message.propagationSource.toString()
|
|
454
454
|
);
|
|
455
|
+
// We always want to await the block
|
|
456
|
+
// This allows us to properly forward the payload envelope
|
|
457
|
+
preprocessResult = {action: PreprocessAction.AwaitBlock, root: blockRoot};
|
|
455
458
|
}
|
|
456
|
-
// do not await the block, we want UnknownBlockSync to handle it.
|
|
457
|
-
preprocessResult = {action: PreprocessAction.PushToQueue};
|
|
458
459
|
break;
|
|
459
460
|
}
|
|
460
461
|
case GossipType.execution_payload_bid: {
|
package/src/node/nodejs.ts
CHANGED
|
@@ -221,7 +221,7 @@ export class BeaconNode {
|
|
|
221
221
|
|
|
222
222
|
let executionEngineOpts = opts.executionEngine;
|
|
223
223
|
if (opts.executionEngine.mode === "mock") {
|
|
224
|
-
const
|
|
224
|
+
const latestEth1BlockHash =
|
|
225
225
|
isStatePostBellatrix(anchorState) && anchorState.isExecutionStateType
|
|
226
226
|
? isStatePostGloas(anchorState)
|
|
227
227
|
? toRootHex(anchorState.latestBlockHash)
|
|
@@ -230,7 +230,7 @@ export class BeaconNode {
|
|
|
230
230
|
executionEngineOpts = {
|
|
231
231
|
...opts.executionEngine,
|
|
232
232
|
genesisBlockHash: ZERO_HASH_HEX,
|
|
233
|
-
eth1BlockHash,
|
|
233
|
+
eth1BlockHash: opts.executionEngine.eth1BlockHash ?? latestEth1BlockHash,
|
|
234
234
|
genesisTime: anchorState.genesisTime,
|
|
235
235
|
config,
|
|
236
236
|
};
|
package/src/node/notifier.ts
CHANGED
|
@@ -167,14 +167,7 @@ function getHeadExecutionInfo(
|
|
|
167
167
|
return [];
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
|
|
171
|
-
// arrives, in that case the exec-block row surfaces the inherited parent anchor (from the
|
|
172
|
-
// bid), which is already validated. Normalize to "valid" to avoid leaking internal
|
|
173
|
-
// fork-choice bookkeeping into the log. Once the payload envelope arrives and the FULL
|
|
174
|
-
// variant becomes head, executionStatus is Valid/Syncing naturally.
|
|
175
|
-
// TODO GLOAS: revisit once optimistic sync is implemented
|
|
176
|
-
const executionStatusStr =
|
|
177
|
-
headInfo.executionStatus === ExecutionStatus.PayloadSeparated ? "valid" : headInfo.executionStatus.toLowerCase();
|
|
170
|
+
const executionStatusStr = headInfo.executionStatus.toLowerCase();
|
|
178
171
|
|
|
179
172
|
// Add execution status to notifier only if head is on/post bellatrix
|
|
180
173
|
if (isStatePostBellatrix(headState) && headState.isExecutionStateType) {
|
package/src/sync/range/batch.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {ForkName, isForkPostDeneb, isForkPostFulu, isForkPostGloas} from "@lodestar/params";
|
|
3
3
|
import {Epoch, RootHex, Slot, phase0} from "@lodestar/types";
|
|
4
|
-
import {LodestarError} from "@lodestar/utils";
|
|
4
|
+
import {LodestarError, prettyPrintIndices} from "@lodestar/utils";
|
|
5
5
|
import {isBlockInputColumns} from "../../chain/blocks/blockInput/blockInput.js";
|
|
6
6
|
import {IBlockInput} from "../../chain/blocks/blockInput/types.js";
|
|
7
7
|
import {isDaOutOfRange} from "../../chain/blocks/blockInput/utils.js";
|
|
@@ -79,10 +79,36 @@ export type BatchState =
|
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
export type BatchMetadata = {
|
|
82
|
+
// Batch-level slot window (always present)
|
|
82
83
|
startEpoch: Epoch;
|
|
84
|
+
startSlot: Slot;
|
|
85
|
+
count: number;
|
|
83
86
|
status: BatchStatus;
|
|
87
|
+
|
|
88
|
+
// Per-type outstanding request shapes; only present when that sub-request exists.
|
|
89
|
+
// Format: "startSlot=<n>,count=<n>" (plus ",cols=<indices>" for columns).
|
|
90
|
+
blocksReq?: string;
|
|
91
|
+
blobsReq?: string;
|
|
92
|
+
columnsReq?: string;
|
|
93
|
+
envelopesReq?: string;
|
|
94
|
+
|
|
95
|
+
// Retry counters
|
|
96
|
+
downloadAttempts: number;
|
|
97
|
+
processingAttempts: number;
|
|
98
|
+
|
|
99
|
+
// Cumulative peer attribution for failed attempts (only present when non-empty)
|
|
100
|
+
failedDownloadPeers?: string;
|
|
101
|
+
failedProcessingPeers?: string;
|
|
84
102
|
};
|
|
85
103
|
|
|
104
|
+
function formatRangeReq(req: {startSlot: Slot; count: number}): string {
|
|
105
|
+
return `startSlot=${req.startSlot},count=${req.count}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function formatColumnsReq(req: {startSlot: Slot; count: number; columns: number[]}): string {
|
|
109
|
+
return `startSlot=${req.startSlot},count=${req.count},cols=${prettyPrintIndices(req.columns)}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
86
112
|
/**
|
|
87
113
|
* Batches are downloaded at the first block of the epoch.
|
|
88
114
|
*
|
|
@@ -176,6 +202,7 @@ export class Batch {
|
|
|
176
202
|
const envelopesBySlot = this.state.payloadEnvelopes ?? new Map<Slot, PayloadEnvelopeInput>();
|
|
177
203
|
|
|
178
204
|
// ensure blocks are in slot-wise order
|
|
205
|
+
const isPostGloas = isForkPostGloas(this.forkName);
|
|
179
206
|
for (const blockInput of blocks) {
|
|
180
207
|
const blockSlot = blockInput.slot;
|
|
181
208
|
// check if block/data is present (hasBlock/hasAllData). If present then check if startSlot is the same as
|
|
@@ -191,21 +218,36 @@ export class Batch {
|
|
|
191
218
|
if (blockInput.hasBlock() && blockStartSlot === blockSlot) {
|
|
192
219
|
blockStartSlot = blockSlot + 1;
|
|
193
220
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
221
|
+
|
|
222
|
+
// Range sync uses hasComputedAllData (all sampled columns physically present), not hasAllData
|
|
223
|
+
// which flips at the reconstruction threshold. Sync never triggers reconstruction, so accepting
|
|
224
|
+
// a half-downloaded block here makes writeBlockInputToDb later block on waitForComputedAllData.
|
|
225
|
+
if (isPostGloas) {
|
|
226
|
+
// Post-Gloas: column data lives on PayloadEnvelopeInput, not on BlockInputNoData.
|
|
227
|
+
const payloadInput = envelopesBySlot.get(blockSlot);
|
|
228
|
+
if (blockInput.hasBlock() && envelopeStartSlot === blockSlot && payloadInput?.hasPayloadEnvelope()) {
|
|
229
|
+
envelopeStartSlot = blockSlot + 1;
|
|
230
|
+
}
|
|
231
|
+
if (payloadInput && !payloadInput.hasComputedAllData()) {
|
|
232
|
+
for (const index of payloadInput.getMissingSampledColumnMeta().missing) {
|
|
204
233
|
neededColumns.add(index);
|
|
205
234
|
}
|
|
235
|
+
} else if (payloadInput?.hasComputedAllData() && dataStartSlot === blockSlot) {
|
|
236
|
+
// Only advance dataStartSlot when we know columns for this slot are complete. If
|
|
237
|
+
// payloadInput is missing entirely we cannot tell, so stop here so the next round
|
|
238
|
+
// re-requests columns (and envelopes) starting at this slot.
|
|
239
|
+
dataStartSlot = blockSlot + 1;
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
if (isBlockInputColumns(blockInput) ? !blockInput.hasComputedAllData() : !blockInput.hasAllData()) {
|
|
243
|
+
if (isBlockInputColumns(blockInput)) {
|
|
244
|
+
for (const index of blockInput.getMissingSampledColumnMeta().missing) {
|
|
245
|
+
neededColumns.add(index);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
} else if (dataStartSlot === blockSlot) {
|
|
249
|
+
dataStartSlot = blockSlot + 1;
|
|
206
250
|
}
|
|
207
|
-
} else if (dataStartSlot === blockSlot) {
|
|
208
|
-
dataStartSlot = blockSlot + 1;
|
|
209
251
|
}
|
|
210
252
|
}
|
|
211
253
|
|
|
@@ -225,11 +267,15 @@ export class Batch {
|
|
|
225
267
|
// range of 40 - 63, startSlot will be inclusive but subtraction will exclusive so need to + 1
|
|
226
268
|
const count = endSlot - dataStartSlot + 1;
|
|
227
269
|
if (isForkPostFulu(this.forkName) && withinValidRequestWindow) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
270
|
+
// Skip the column re-request when we have no specific column indices outstanding.
|
|
271
|
+
// Peer rejects an empty `columns` list
|
|
272
|
+
if (neededColumns.size > 0) {
|
|
273
|
+
requests.columnsRequest = {
|
|
274
|
+
count,
|
|
275
|
+
startSlot: dataStartSlot,
|
|
276
|
+
columns: Array.from(neededColumns),
|
|
277
|
+
};
|
|
278
|
+
}
|
|
233
279
|
} else if (isForkPostDeneb(this.forkName) && withinValidRequestWindow) {
|
|
234
280
|
requests.blobsRequest = {
|
|
235
281
|
count,
|
|
@@ -286,7 +332,26 @@ export class Batch {
|
|
|
286
332
|
}
|
|
287
333
|
|
|
288
334
|
getMetadata(): BatchMetadata {
|
|
289
|
-
|
|
335
|
+
const {blocksRequest, blobsRequest, columnsRequest, envelopesRequest} = this.requests;
|
|
336
|
+
const failedProcessingPeerList = this.failedProcessingAttempts.flatMap((a) => a.peers);
|
|
337
|
+
return {
|
|
338
|
+
startEpoch: this.startEpoch,
|
|
339
|
+
startSlot: this.startSlot,
|
|
340
|
+
count: this.count,
|
|
341
|
+
status: this.state.status,
|
|
342
|
+
...(blocksRequest && {blocksReq: formatRangeReq(blocksRequest)}),
|
|
343
|
+
...(blobsRequest && {blobsReq: formatRangeReq(blobsRequest)}),
|
|
344
|
+
...(columnsRequest && {columnsReq: formatColumnsReq(columnsRequest)}),
|
|
345
|
+
...(envelopesRequest && {envelopesReq: formatRangeReq(envelopesRequest)}),
|
|
346
|
+
downloadAttempts: this.failedDownloadAttempts.length,
|
|
347
|
+
processingAttempts: this.failedProcessingAttempts.length,
|
|
348
|
+
...(this.failedDownloadAttempts.length > 0 && {
|
|
349
|
+
failedDownloadPeers: this.failedDownloadAttempts.join(","),
|
|
350
|
+
}),
|
|
351
|
+
...(failedProcessingPeerList.length > 0 && {
|
|
352
|
+
failedProcessingPeers: failedProcessingPeerList.join(","),
|
|
353
|
+
}),
|
|
354
|
+
};
|
|
290
355
|
}
|
|
291
356
|
|
|
292
357
|
getBlocks(): IBlockInput[] {
|
|
@@ -334,7 +399,11 @@ export class Batch {
|
|
|
334
399
|
const slots = new Set<number>();
|
|
335
400
|
for (const block of blocks) {
|
|
336
401
|
slots.add(block.slot);
|
|
337
|
-
|
|
402
|
+
const dataComplete = isBlockInputColumns(block)
|
|
403
|
+
? // by_range needs to download all columns
|
|
404
|
+
block.hasBlock() && block.hasComputedAllData()
|
|
405
|
+
: block.hasBlockAndAllData();
|
|
406
|
+
if (!dataComplete) {
|
|
338
407
|
allComplete = false;
|
|
339
408
|
}
|
|
340
409
|
}
|
|
@@ -350,11 +419,22 @@ export class Batch {
|
|
|
350
419
|
}
|
|
351
420
|
const newPayloadEnvelopes = payloadEnvelopes ?? this.state.payloadEnvelopes;
|
|
352
421
|
|
|
422
|
+
if (allComplete && isForkPostGloas(this.forkName)) {
|
|
423
|
+
for (const block of blocks) {
|
|
424
|
+
const payloadInput = newPayloadEnvelopes?.get(block.slot);
|
|
425
|
+
// by_range needs to download all columns
|
|
426
|
+
if (!payloadInput?.hasPayloadEnvelope() || !payloadInput.hasComputedAllData()) {
|
|
427
|
+
allComplete = false;
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
353
433
|
if (allComplete) {
|
|
354
434
|
this.state = {status: BatchStatus.AwaitingProcessing, blocks, payloadEnvelopes: newPayloadEnvelopes};
|
|
355
435
|
} else {
|
|
356
|
-
this.requests = this.getRequests(blocks);
|
|
357
436
|
this.state = {status: BatchStatus.AwaitingDownload, blocks, payloadEnvelopes: newPayloadEnvelopes};
|
|
437
|
+
this.requests = this.getRequests(blocks);
|
|
358
438
|
}
|
|
359
439
|
|
|
360
440
|
return this.state as DownloadSuccessState;
|
|
@@ -383,7 +463,11 @@ export class Batch {
|
|
|
383
463
|
/**
|
|
384
464
|
* AwaitingProcessing -> Processing
|
|
385
465
|
*/
|
|
386
|
-
startProcessing(): {
|
|
466
|
+
startProcessing(): {
|
|
467
|
+
blocks: IBlockInput[];
|
|
468
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
|
|
469
|
+
peers: PeerIdStr[];
|
|
470
|
+
} {
|
|
387
471
|
if (this.state.status !== BatchStatus.AwaitingProcessing) {
|
|
388
472
|
throw new BatchError(this.wrongStatusErrorType(BatchStatus.AwaitingProcessing));
|
|
389
473
|
}
|
|
@@ -396,7 +480,7 @@ export class Batch {
|
|
|
396
480
|
const peers = this.goodPeers;
|
|
397
481
|
this.goodPeers = [];
|
|
398
482
|
this.state = {status: BatchStatus.Processing, blocks, payloadEnvelopes, attempt: {peers, hash}};
|
|
399
|
-
return {blocks, payloadEnvelopes};
|
|
483
|
+
return {blocks, payloadEnvelopes, peers};
|
|
400
484
|
}
|
|
401
485
|
|
|
402
486
|
/**
|
|
@@ -479,7 +563,7 @@ export class Batch {
|
|
|
479
563
|
|
|
480
564
|
/** Helper to construct typed BatchError. Stack traces are correct as the error is thrown above */
|
|
481
565
|
private errorType(type: BatchErrorType): BatchErrorType & BatchErrorMetadata {
|
|
482
|
-
return {...type,
|
|
566
|
+
return {...type, startEpoch: this.startEpoch, status: this.state.status};
|
|
483
567
|
}
|
|
484
568
|
|
|
485
569
|
private wrongStatusErrorType(expectedStatus: BatchStatus): BatchErrorType & BatchErrorMetadata {
|
package/src/sync/range/chain.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {Epoch, Root, Slot} from "@lodestar/types";
|
|
3
|
-
import {ErrorAborted, LodestarError, Logger, toRootHex} from "@lodestar/utils";
|
|
3
|
+
import {ErrorAborted, LodestarError, Logger, prettyPrintIndices, toRootHex} from "@lodestar/utils";
|
|
4
4
|
import {isBlockInputBlobs, isBlockInputColumns} from "../../chain/blocks/blockInput/blockInput.js";
|
|
5
5
|
import {BlockInputErrorCode} from "../../chain/blocks/blockInput/errors.js";
|
|
6
6
|
import {IBlockInput} from "../../chain/blocks/blockInput/types.js";
|
|
@@ -222,12 +222,14 @@ export class SyncChain {
|
|
|
222
222
|
*/
|
|
223
223
|
stopSyncing(): void {
|
|
224
224
|
this.status = SyncChainStatus.Stopped;
|
|
225
|
+
this.logger.debug("SyncChain stopSyncing", {id: this.logId});
|
|
225
226
|
}
|
|
226
227
|
|
|
227
228
|
/**
|
|
228
229
|
* Permanently remove this chain. Throws the main AsyncIterable
|
|
229
230
|
*/
|
|
230
231
|
remove(): void {
|
|
232
|
+
this.logger.debug("SyncChain remove", {id: this.logId});
|
|
231
233
|
this.batchProcessor.end(new ErrorAborted("SyncChain"));
|
|
232
234
|
}
|
|
233
235
|
|
|
@@ -534,7 +536,7 @@ export class SyncChain {
|
|
|
534
536
|
this.metrics?.syncRange.downloadByRange.warn.inc({client: peer.client, code: warning.type.code});
|
|
535
537
|
this.logger.debug(
|
|
536
538
|
"Batch downloaded with warning",
|
|
537
|
-
{id: this.logId,
|
|
539
|
+
{id: this.logId, ...batch.getMetadata(), ...logMeta, peer: prettyPrintPeerIdStr(peer.peerId)},
|
|
538
540
|
warning
|
|
539
541
|
);
|
|
540
542
|
}
|
|
@@ -560,10 +562,17 @@ export class SyncChain {
|
|
|
560
562
|
// the flow will continue to call triggerBatchDownloader() below
|
|
561
563
|
}
|
|
562
564
|
|
|
565
|
+
const blockSlots = downloadSuccessOutput.blocks.map((b) => b.slot);
|
|
566
|
+
const envelopeSlots = downloadSuccessOutput.payloadEnvelopes
|
|
567
|
+
? Array.from(downloadSuccessOutput.payloadEnvelopes.keys())
|
|
568
|
+
: null;
|
|
569
|
+
|
|
563
570
|
this.logger.debug(logMessage, {
|
|
564
571
|
id: this.logId,
|
|
565
|
-
|
|
572
|
+
...batch.getMetadata(),
|
|
566
573
|
...logMeta,
|
|
574
|
+
blockSlots: prettyPrintIndices(blockSlots),
|
|
575
|
+
...(envelopeSlots ? {envelopeSlots: prettyPrintIndices(envelopeSlots)} : {}),
|
|
567
576
|
peer: prettyPrintPeerIdStr(peer.peerId),
|
|
568
577
|
});
|
|
569
578
|
}
|
|
@@ -586,13 +595,24 @@ export class SyncChain {
|
|
|
586
595
|
* Sends `batch` to the processor. Note: batch may be empty
|
|
587
596
|
*/
|
|
588
597
|
private async processBatch(batch: Batch): Promise<void> {
|
|
589
|
-
const {blocks, payloadEnvelopes} = batch.startProcessing();
|
|
598
|
+
const {blocks, payloadEnvelopes, peers} = batch.startProcessing();
|
|
599
|
+
|
|
600
|
+
const logCtx = {
|
|
601
|
+
id: this.logId,
|
|
602
|
+
...batch.getMetadata(),
|
|
603
|
+
blockCount: blocks.length,
|
|
604
|
+
blockSlots: prettyPrintIndices(blocks.map((b) => b.slot)),
|
|
605
|
+
...(payloadEnvelopes ? {envelopeSlots: prettyPrintIndices(Array.from(payloadEnvelopes.keys()))} : {}),
|
|
606
|
+
peers: peers.map(prettyPrintPeerIdStr).join(","),
|
|
607
|
+
};
|
|
608
|
+
this.logger.verbose("Processing batch", logCtx);
|
|
590
609
|
|
|
591
610
|
// wrapError ensures to never call both batch success() and batch error()
|
|
592
611
|
const res = await wrapError(this.processChainSegment(blocks, payloadEnvelopes, this.syncType));
|
|
593
612
|
|
|
594
613
|
if (!res.err) {
|
|
595
614
|
batch.processingSuccess();
|
|
615
|
+
this.logger.verbose("Processed batch", {...logCtx, ...batch.getMetadata()});
|
|
596
616
|
|
|
597
617
|
// If the processed batch is not empty, validate previous AwaitingValidation blocks.
|
|
598
618
|
if (blocks.length > 0) {
|
|
@@ -602,7 +622,7 @@ export class SyncChain {
|
|
|
602
622
|
// Potentially process next AwaitingProcessing batch
|
|
603
623
|
this.triggerBatchProcessor();
|
|
604
624
|
} else {
|
|
605
|
-
this.logger.verbose("Batch process error",
|
|
625
|
+
this.logger.verbose("Batch process error", logCtx, res.err);
|
|
606
626
|
batch.processingError(res.err); // Throws after MAX_BATCH_PROCESSING_ATTEMPTS
|
|
607
627
|
|
|
608
628
|
// At least one block was successfully verified and imported, so we can be sure all
|
package/src/sync/unknownBlock.ts
CHANGED
|
@@ -145,7 +145,6 @@ export class BlockInputSync {
|
|
|
145
145
|
this.chain.emitter.on(ChainEvent.incompleteBlockInput, this.onIncompleteBlockInput);
|
|
146
146
|
this.chain.emitter.on(ChainEvent.incompletePayloadEnvelope, this.onIncompletePayloadEnvelope);
|
|
147
147
|
this.chain.emitter.on(ChainEvent.blockUnknownParent, this.onUnknownParent);
|
|
148
|
-
this.chain.emitter.on(ChainEvent.envelopeUnknownBlock, this.onEnvelopeUnknownBlock);
|
|
149
148
|
this.chain.emitter.on(routes.events.EventType.block, this.onBlockImported);
|
|
150
149
|
this.chain.emitter.on(routes.events.EventType.executionPayload, this.onPayloadImported);
|
|
151
150
|
this.network.events.on(NetworkEvent.peerConnected, this.onPeerConnected);
|
|
@@ -161,7 +160,6 @@ export class BlockInputSync {
|
|
|
161
160
|
this.chain.emitter.off(ChainEvent.incompleteBlockInput, this.onIncompleteBlockInput);
|
|
162
161
|
this.chain.emitter.off(ChainEvent.incompletePayloadEnvelope, this.onIncompletePayloadEnvelope);
|
|
163
162
|
this.chain.emitter.off(ChainEvent.blockUnknownParent, this.onUnknownParent);
|
|
164
|
-
this.chain.emitter.off(ChainEvent.envelopeUnknownBlock, this.onEnvelopeUnknownBlock);
|
|
165
163
|
this.chain.emitter.off(routes.events.EventType.block, this.onBlockImported);
|
|
166
164
|
this.chain.emitter.off(routes.events.EventType.executionPayload, this.onPayloadImported);
|
|
167
165
|
this.network.events.off(NetworkEvent.peerConnected, this.onPeerConnected);
|
|
@@ -263,19 +261,6 @@ export class BlockInputSync {
|
|
|
263
261
|
}
|
|
264
262
|
};
|
|
265
263
|
|
|
266
|
-
private onEnvelopeUnknownBlock = (data: ChainEventData[ChainEvent.envelopeUnknownBlock]): void => {
|
|
267
|
-
try {
|
|
268
|
-
const blockRootHex = toRootHex(data.envelope.message.beaconBlockRoot);
|
|
269
|
-
this.addByRootHex(blockRootHex, data.peer);
|
|
270
|
-
this.addByPayloadEnvelope(data.envelope, data.peer);
|
|
271
|
-
this.triggerUnknownBlockSearch();
|
|
272
|
-
this.metrics?.blockInputSync.requests.inc({type: PendingBlockType.UNKNOWN_DATA});
|
|
273
|
-
this.metrics?.blockInputSync.source.inc({source: data.source});
|
|
274
|
-
} catch (e) {
|
|
275
|
-
this.logger.debug("Error handling envelopeUnknownBlock event", {}, e as Error);
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
|
-
|
|
279
264
|
private onBlockImported = (): void => {
|
|
280
265
|
if (this.pendingPayloads.size > 0) {
|
|
281
266
|
this.triggerUnknownBlockSearch();
|
|
@@ -381,41 +366,6 @@ export class BlockInputSync {
|
|
|
381
366
|
return added;
|
|
382
367
|
};
|
|
383
368
|
|
|
384
|
-
private addByPayloadEnvelope = (envelope: gloas.SignedExecutionPayloadEnvelope, peerIdStr?: PeerIdStr): void => {
|
|
385
|
-
const rootHex = toRootHex(envelope.message.beaconBlockRoot);
|
|
386
|
-
const existingPendingPayload = this.pendingPayloads.get(rootHex);
|
|
387
|
-
let pendingPayload = this.pendingPayloads.get(rootHex);
|
|
388
|
-
if (!pendingPayload || !isPendingPayloadEnvelope(pendingPayload)) {
|
|
389
|
-
pendingPayload = {
|
|
390
|
-
status: PendingPayloadInputStatus.waitingForBlock,
|
|
391
|
-
envelope,
|
|
392
|
-
peerIdStrings: new Set(existingPendingPayload?.peerIdStrings ?? []),
|
|
393
|
-
timeAddedSec: existingPendingPayload?.timeAddedSec ?? Date.now() / 1000,
|
|
394
|
-
};
|
|
395
|
-
this.pendingPayloads.set(rootHex, pendingPayload);
|
|
396
|
-
|
|
397
|
-
this.logger.verbose("Added payload envelope to BlockInputSync.pendingPayloads", {
|
|
398
|
-
slot: envelope.message.payload.slotNumber,
|
|
399
|
-
root: rootHex,
|
|
400
|
-
});
|
|
401
|
-
} else {
|
|
402
|
-
this.logger.debug("Overwriting pending payload envelope for root already waiting for block", {
|
|
403
|
-
slot: envelope.message.payload.slotNumber,
|
|
404
|
-
root: rootHex,
|
|
405
|
-
});
|
|
406
|
-
pendingPayload.envelope = envelope;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
if (peerIdStr) {
|
|
410
|
-
pendingPayload.peerIdStrings.add(peerIdStr);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
const prunedItemCount = pruneSetToMax(this.pendingPayloads, this.maxPendingBlocks);
|
|
414
|
-
if (prunedItemCount > 0) {
|
|
415
|
-
this.logger.verbose(`Pruned ${prunedItemCount} items from BlockInputSync.pendingPayloads`);
|
|
416
|
-
}
|
|
417
|
-
};
|
|
418
|
-
|
|
419
369
|
private addByPayloadInput = (
|
|
420
370
|
payloadInput: PayloadEnvelopeInput,
|
|
421
371
|
peerIdStr?: PeerIdStr,
|