@lodestar/beacon-node 1.43.0-dev.a140dd987e → 1.43.0-dev.a45ba75824
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 +16 -5
- 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/lodestar/index.js +1 -1
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +66 -1
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +10 -18
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +19 -6
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +43 -19
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts +5 -3
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +31 -10
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +5 -1
- 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/payloadEnvelopeProcessor.js +2 -2
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +2 -2
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +81 -12
- package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts +5 -3
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +51 -7
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +15 -4
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +2 -2
- 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 +3 -2
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +12 -4
- 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/blockError.d.ts +8 -1
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +2 -0
- package/lib/chain/errors/blockError.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 +33 -0
- package/lib/chain/errors/proposerPreferences.d.ts.map +1 -0
- package/lib/chain/errors/proposerPreferences.js +13 -0
- package/lib/chain/errors/proposerPreferences.js.map +1 -0
- package/lib/chain/interface.d.ts +3 -2
- 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 +11 -3
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +41 -18
- 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/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 +15 -0
- package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -0
- package/lib/chain/seenCache/seenProposerPreferences.js +25 -0
- package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -0
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +1 -0
- package/lib/chain/validation/block.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 +69 -0
- package/lib/chain/validation/proposerPreferences.js.map +1 -0
- package/lib/metrics/metrics/lodestar.d.ts +1 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +4 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- 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 +8 -0
- 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 +24 -16
- 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/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
- package/lib/node/notifier.js +7 -1
- package/lib/node/notifier.js.map +1 -1
- package/lib/sync/range/batch.d.ts +23 -2
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +84 -33
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +6 -2
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +26 -7
- 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 +17 -6
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/types.d.ts +34 -0
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +34 -0
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +22 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +602 -53
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +46 -10
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +153 -24
- 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 +16 -2
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.js +0 -9
- package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +21 -5
- package/src/api/impl/beacon/pool/index.ts +83 -1
- package/src/api/impl/lodestar/index.ts +1 -1
- package/src/api/impl/validator/index.ts +80 -0
- package/src/chain/blocks/importBlock.ts +10 -35
- package/src/chain/blocks/importExecutionPayload.ts +57 -21
- package/src/chain/blocks/index.ts +54 -14
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +6 -1
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +1 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +2 -2
- package/src/chain/blocks/types.ts +2 -2
- package/src/chain/blocks/utils/chainSegment.ts +106 -17
- package/src/chain/blocks/verifyBlock.ts +68 -9
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +16 -7
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +2 -2
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +7 -4
- package/src/chain/chain.ts +16 -3
- package/src/chain/emitter.ts +0 -11
- package/src/chain/errors/blockError.ts +4 -1
- package/src/chain/errors/index.ts +1 -0
- package/src/chain/errors/proposerPreferences.ts +39 -0
- package/src/chain/interface.ts +7 -1
- package/src/chain/opPools/payloadAttestationPool.ts +29 -8
- package/src/chain/prepareNextSlot.ts +20 -28
- package/src/chain/produceBlock/produceBlockBody.ts +51 -23
- package/src/chain/regen/interface.ts +1 -0
- package/src/chain/seenCache/index.ts +1 -0
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +25 -5
- package/src/chain/seenCache/seenProposerPreferences.ts +29 -0
- package/src/chain/validation/block.ts +1 -0
- package/src/chain/validation/proposerPreferences.ts +91 -0
- package/src/metrics/metrics/lodestar.ts +4 -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 +35 -17
- package/src/network/processor/gossipQueues/index.ts +5 -0
- package/src/network/processor/index.ts +6 -5
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
- package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
- package/src/node/notifier.ts +8 -1
- package/src/sync/range/batch.ts +142 -38
- package/src/sync/range/chain.ts +37 -9
- package/src/sync/range/range.ts +18 -6
- package/src/sync/types.ts +72 -0
- package/src/sync/unknownBlock.ts +760 -57
- package/src/sync/utils/downloadByRange.ts +262 -39
- package/src/sync/utils/downloadByRoot.ts +24 -2
- package/src/sync/utils/pendingBlocksTree.ts +0 -15
package/src/sync/range/batch.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {ForkName, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
|
|
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";
|
|
8
|
+
import {PayloadEnvelopeInput} from "../../chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
8
9
|
import {BlockError, BlockErrorCode} from "../../chain/errors/index.js";
|
|
9
10
|
import {PeerSyncMeta} from "../../network/peers/peersData.js";
|
|
10
11
|
import {IClock} from "../../util/clock.js";
|
|
@@ -46,25 +47,68 @@ export type Attempt = {
|
|
|
46
47
|
export type AwaitingDownloadState = {
|
|
47
48
|
status: BatchStatus.AwaitingDownload;
|
|
48
49
|
blocks: IBlockInput[];
|
|
50
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
|
|
49
51
|
};
|
|
50
52
|
|
|
51
53
|
export type DownloadSuccessState = {
|
|
52
54
|
status: BatchStatus.AwaitingProcessing;
|
|
53
55
|
blocks: IBlockInput[];
|
|
56
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
|
|
54
57
|
};
|
|
55
58
|
|
|
56
59
|
export type BatchState =
|
|
57
60
|
| AwaitingDownloadState
|
|
58
|
-
| {
|
|
61
|
+
| {
|
|
62
|
+
status: BatchStatus.Downloading;
|
|
63
|
+
peer: PeerIdStr;
|
|
64
|
+
blocks: IBlockInput[];
|
|
65
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
|
|
66
|
+
}
|
|
59
67
|
| DownloadSuccessState
|
|
60
|
-
| {
|
|
61
|
-
|
|
68
|
+
| {
|
|
69
|
+
status: BatchStatus.Processing;
|
|
70
|
+
blocks: IBlockInput[];
|
|
71
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
|
|
72
|
+
attempt: Attempt;
|
|
73
|
+
}
|
|
74
|
+
| {
|
|
75
|
+
status: BatchStatus.AwaitingValidation;
|
|
76
|
+
blocks: IBlockInput[];
|
|
77
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
|
|
78
|
+
attempt: Attempt;
|
|
79
|
+
};
|
|
62
80
|
|
|
63
81
|
export type BatchMetadata = {
|
|
82
|
+
// Batch-level slot window (always present)
|
|
64
83
|
startEpoch: Epoch;
|
|
84
|
+
startSlot: Slot;
|
|
85
|
+
count: number;
|
|
65
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;
|
|
66
102
|
};
|
|
67
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
|
+
|
|
68
112
|
/**
|
|
69
113
|
* Batches are downloaded at the first block of the epoch.
|
|
70
114
|
*
|
|
@@ -85,7 +129,7 @@ export class Batch {
|
|
|
85
129
|
/** Block, blob and column requests that are used to determine the best peer and are used in downloadByRange */
|
|
86
130
|
requests: DownloadByRangeRequests;
|
|
87
131
|
/** State of the batch. */
|
|
88
|
-
state: BatchState = {status: BatchStatus.AwaitingDownload, blocks: []};
|
|
132
|
+
state: BatchState = {status: BatchStatus.AwaitingDownload, blocks: [], payloadEnvelopes: null};
|
|
89
133
|
/** Peers that provided good data */
|
|
90
134
|
goodPeers: PeerIdStr[] = [];
|
|
91
135
|
/** The `Attempts` that have been made and failed to send us this batch. */
|
|
@@ -129,35 +173,33 @@ export class Batch {
|
|
|
129
173
|
count: this.count,
|
|
130
174
|
step: 1,
|
|
131
175
|
};
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
count: this.count,
|
|
138
|
-
columns: this.custodyConfig.sampledColumns,
|
|
139
|
-
},
|
|
140
|
-
};
|
|
176
|
+
const requests: DownloadByRangeRequests = {blocksRequest};
|
|
177
|
+
|
|
178
|
+
// Post-Gloas envelopes are required for block processing, independent of DA retention window.
|
|
179
|
+
if (isForkPostGloas(this.forkName)) {
|
|
180
|
+
requests.envelopesRequest = {startSlot: this.startSlot, count: this.count};
|
|
141
181
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
},
|
|
182
|
+
|
|
183
|
+
if (isForkPostFulu(this.forkName) && withinValidRequestWindow) {
|
|
184
|
+
requests.columnsRequest = {
|
|
185
|
+
startSlot: this.startSlot,
|
|
186
|
+
count: this.count,
|
|
187
|
+
columns: this.custodyConfig.sampledColumns,
|
|
149
188
|
};
|
|
189
|
+
} else if (isForkPostDeneb(this.forkName) && withinValidRequestWindow) {
|
|
190
|
+
requests.blobsRequest = {startSlot: this.startSlot, count: this.count};
|
|
150
191
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
};
|
|
192
|
+
|
|
193
|
+
return requests;
|
|
154
194
|
}
|
|
155
195
|
|
|
156
196
|
// subsequent request where part of the epoch has already been downloaded. Need to figure out what is the beginning
|
|
157
197
|
// of the range where download needs to resume
|
|
158
198
|
let blockStartSlot = this.startSlot;
|
|
159
199
|
let dataStartSlot = this.startSlot;
|
|
200
|
+
let envelopeStartSlot = this.startSlot;
|
|
160
201
|
const neededColumns = new Set<number>();
|
|
202
|
+
const envelopesBySlot = this.state.payloadEnvelopes ?? new Map<Slot, PayloadEnvelopeInput>();
|
|
161
203
|
|
|
162
204
|
// ensure blocks are in slot-wise order
|
|
163
205
|
for (const blockInput of blocks) {
|
|
@@ -175,6 +217,13 @@ export class Batch {
|
|
|
175
217
|
if (blockInput.hasBlock() && blockStartSlot === blockSlot) {
|
|
176
218
|
blockStartSlot = blockSlot + 1;
|
|
177
219
|
}
|
|
220
|
+
if (
|
|
221
|
+
blockInput.hasBlock() &&
|
|
222
|
+
envelopeStartSlot === blockSlot &&
|
|
223
|
+
envelopesBySlot.get(blockSlot)?.hasPayloadEnvelope()
|
|
224
|
+
) {
|
|
225
|
+
envelopeStartSlot = blockSlot + 1;
|
|
226
|
+
}
|
|
178
227
|
if (!blockInput.hasAllData()) {
|
|
179
228
|
if (isBlockInputColumns(blockInput)) {
|
|
180
229
|
for (const index of blockInput.getMissingSampledColumnMeta().missing) {
|
|
@@ -216,6 +265,13 @@ export class Batch {
|
|
|
216
265
|
// dataSlot will still have a value but do not create a request for preDeneb forks
|
|
217
266
|
}
|
|
218
267
|
|
|
268
|
+
if (isForkPostGloas(this.forkName) && envelopeStartSlot <= endSlot) {
|
|
269
|
+
requests.envelopesRequest = {
|
|
270
|
+
startSlot: envelopeStartSlot,
|
|
271
|
+
count: endSlot - envelopeStartSlot + 1,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
219
275
|
return requests;
|
|
220
276
|
}
|
|
221
277
|
|
|
@@ -256,13 +312,36 @@ export class Batch {
|
|
|
256
312
|
}
|
|
257
313
|
|
|
258
314
|
getMetadata(): BatchMetadata {
|
|
259
|
-
|
|
315
|
+
const {blocksRequest, blobsRequest, columnsRequest, envelopesRequest} = this.requests;
|
|
316
|
+
const failedProcessingPeerList = this.failedProcessingAttempts.flatMap((a) => a.peers);
|
|
317
|
+
return {
|
|
318
|
+
startEpoch: this.startEpoch,
|
|
319
|
+
startSlot: this.startSlot,
|
|
320
|
+
count: this.count,
|
|
321
|
+
status: this.state.status,
|
|
322
|
+
...(blocksRequest && {blocksReq: formatRangeReq(blocksRequest)}),
|
|
323
|
+
...(blobsRequest && {blobsReq: formatRangeReq(blobsRequest)}),
|
|
324
|
+
...(columnsRequest && {columnsReq: formatColumnsReq(columnsRequest)}),
|
|
325
|
+
...(envelopesRequest && {envelopesReq: formatRangeReq(envelopesRequest)}),
|
|
326
|
+
downloadAttempts: this.failedDownloadAttempts.length,
|
|
327
|
+
processingAttempts: this.failedProcessingAttempts.length,
|
|
328
|
+
...(this.failedDownloadAttempts.length > 0 && {
|
|
329
|
+
failedDownloadPeers: this.failedDownloadAttempts.join(","),
|
|
330
|
+
}),
|
|
331
|
+
...(failedProcessingPeerList.length > 0 && {
|
|
332
|
+
failedProcessingPeers: failedProcessingPeerList.join(","),
|
|
333
|
+
}),
|
|
334
|
+
};
|
|
260
335
|
}
|
|
261
336
|
|
|
262
337
|
getBlocks(): IBlockInput[] {
|
|
263
338
|
return this.state.blocks;
|
|
264
339
|
}
|
|
265
340
|
|
|
341
|
+
getPayloadEnvelopes(): Map<Slot, PayloadEnvelopeInput> | null {
|
|
342
|
+
return this.state.payloadEnvelopes;
|
|
343
|
+
}
|
|
344
|
+
|
|
266
345
|
/**
|
|
267
346
|
* AwaitingDownload -> Downloading
|
|
268
347
|
*/
|
|
@@ -271,13 +350,22 @@ export class Batch {
|
|
|
271
350
|
throw new BatchError(this.wrongStatusErrorType(BatchStatus.AwaitingDownload));
|
|
272
351
|
}
|
|
273
352
|
|
|
274
|
-
this.state = {
|
|
353
|
+
this.state = {
|
|
354
|
+
status: BatchStatus.Downloading,
|
|
355
|
+
peer,
|
|
356
|
+
blocks: this.state.blocks,
|
|
357
|
+
payloadEnvelopes: this.state.payloadEnvelopes,
|
|
358
|
+
};
|
|
275
359
|
}
|
|
276
360
|
|
|
277
361
|
/**
|
|
278
362
|
* Downloading -> AwaitingProcessing
|
|
279
363
|
*/
|
|
280
|
-
downloadingSuccess(
|
|
364
|
+
downloadingSuccess(
|
|
365
|
+
peer: PeerIdStr,
|
|
366
|
+
blocks: IBlockInput[],
|
|
367
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null
|
|
368
|
+
): DownloadSuccessState {
|
|
281
369
|
if (this.state.status !== BatchStatus.Downloading) {
|
|
282
370
|
throw new BatchError(this.wrongStatusErrorType(BatchStatus.Downloading));
|
|
283
371
|
}
|
|
@@ -305,11 +393,13 @@ export class Batch {
|
|
|
305
393
|
status: this.state.status,
|
|
306
394
|
});
|
|
307
395
|
}
|
|
396
|
+
const newPayloadEnvelopes = payloadEnvelopes ?? this.state.payloadEnvelopes;
|
|
397
|
+
|
|
308
398
|
if (allComplete) {
|
|
309
|
-
this.state = {status: BatchStatus.AwaitingProcessing, blocks};
|
|
399
|
+
this.state = {status: BatchStatus.AwaitingProcessing, blocks, payloadEnvelopes: newPayloadEnvelopes};
|
|
310
400
|
} else {
|
|
311
401
|
this.requests = this.getRequests(blocks);
|
|
312
|
-
this.state = {status: BatchStatus.AwaitingDownload, blocks};
|
|
402
|
+
this.state = {status: BatchStatus.AwaitingDownload, blocks, payloadEnvelopes: newPayloadEnvelopes};
|
|
313
403
|
}
|
|
314
404
|
|
|
315
405
|
return this.state as DownloadSuccessState;
|
|
@@ -328,25 +418,34 @@ export class Batch {
|
|
|
328
418
|
throw new BatchError(this.errorType({code: BatchErrorCode.MAX_DOWNLOAD_ATTEMPTS}));
|
|
329
419
|
}
|
|
330
420
|
|
|
331
|
-
this.state = {
|
|
421
|
+
this.state = {
|
|
422
|
+
status: BatchStatus.AwaitingDownload,
|
|
423
|
+
blocks: this.state.blocks,
|
|
424
|
+
payloadEnvelopes: this.state.payloadEnvelopes,
|
|
425
|
+
};
|
|
332
426
|
}
|
|
333
427
|
|
|
334
428
|
/**
|
|
335
429
|
* AwaitingProcessing -> Processing
|
|
336
430
|
*/
|
|
337
|
-
startProcessing():
|
|
431
|
+
startProcessing(): {
|
|
432
|
+
blocks: IBlockInput[];
|
|
433
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
|
|
434
|
+
peers: PeerIdStr[];
|
|
435
|
+
} {
|
|
338
436
|
if (this.state.status !== BatchStatus.AwaitingProcessing) {
|
|
339
437
|
throw new BatchError(this.wrongStatusErrorType(BatchStatus.AwaitingProcessing));
|
|
340
438
|
}
|
|
341
439
|
|
|
342
440
|
const blocks = this.state.blocks;
|
|
441
|
+
const payloadEnvelopes = this.state.payloadEnvelopes;
|
|
343
442
|
const hash = hashBlocks(blocks, this.config); // tracks blocks to report peer on processing error
|
|
344
443
|
// Reset goodPeers in case another download attempt needs to be made. When Attempt is successful or not the peers
|
|
345
444
|
// that the data came from will be handled by the Attempt that goes for processing
|
|
346
445
|
const peers = this.goodPeers;
|
|
347
446
|
this.goodPeers = [];
|
|
348
|
-
this.state = {status: BatchStatus.Processing, blocks, attempt: {peers, hash}};
|
|
349
|
-
return blocks;
|
|
447
|
+
this.state = {status: BatchStatus.Processing, blocks, payloadEnvelopes, attempt: {peers, hash}};
|
|
448
|
+
return {blocks, payloadEnvelopes, peers};
|
|
350
449
|
}
|
|
351
450
|
|
|
352
451
|
/**
|
|
@@ -357,7 +456,12 @@ export class Batch {
|
|
|
357
456
|
throw new BatchError(this.wrongStatusErrorType(BatchStatus.Processing));
|
|
358
457
|
}
|
|
359
458
|
|
|
360
|
-
this.state = {
|
|
459
|
+
this.state = {
|
|
460
|
+
status: BatchStatus.AwaitingValidation,
|
|
461
|
+
blocks: this.state.blocks,
|
|
462
|
+
payloadEnvelopes: this.state.payloadEnvelopes,
|
|
463
|
+
attempt: this.state.attempt,
|
|
464
|
+
};
|
|
361
465
|
}
|
|
362
466
|
|
|
363
467
|
/**
|
|
@@ -408,7 +512,7 @@ export class Batch {
|
|
|
408
512
|
|
|
409
513
|
// remove any downloaded blocks and re-attempt
|
|
410
514
|
// TODO(fulu): need to remove the bad blocks from the SeenBlockInputCache
|
|
411
|
-
this.state = {status: BatchStatus.AwaitingDownload, blocks: []};
|
|
515
|
+
this.state = {status: BatchStatus.AwaitingDownload, blocks: [], payloadEnvelopes: null};
|
|
412
516
|
}
|
|
413
517
|
|
|
414
518
|
private onProcessingError(attempt: Attempt): void {
|
|
@@ -419,12 +523,12 @@ export class Batch {
|
|
|
419
523
|
|
|
420
524
|
// remove any downloaded blocks and re-attempt
|
|
421
525
|
// TODO(fulu): need to remove the bad blocks from the SeenBlockInputCache
|
|
422
|
-
this.state = {status: BatchStatus.AwaitingDownload, blocks: []};
|
|
526
|
+
this.state = {status: BatchStatus.AwaitingDownload, blocks: [], payloadEnvelopes: null};
|
|
423
527
|
}
|
|
424
528
|
|
|
425
529
|
/** Helper to construct typed BatchError. Stack traces are correct as the error is thrown above */
|
|
426
530
|
private errorType(type: BatchErrorType): BatchErrorType & BatchErrorMetadata {
|
|
427
|
-
return {...type,
|
|
531
|
+
return {...type, startEpoch: this.startEpoch, status: this.state.status};
|
|
428
532
|
}
|
|
429
533
|
|
|
430
534
|
private wrongStatusErrorType(expectedStatus: BatchStatus): BatchErrorType & BatchErrorMetadata {
|
package/src/sync/range/chain.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
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";
|
|
7
|
+
import {PayloadEnvelopeInput} from "../../chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
7
8
|
import {BlobSidecarErrorCode} from "../../chain/errors/blobSidecarError.js";
|
|
8
9
|
import {DataColumnSidecarErrorCode} from "../../chain/errors/dataColumnSidecarError.js";
|
|
9
10
|
import {Metrics} from "../../metrics/metrics.js";
|
|
@@ -44,13 +45,19 @@ export type SyncChainFns = {
|
|
|
44
45
|
* Must return if ALL blocks are processed successfully
|
|
45
46
|
* If SOME blocks are processed must throw BlockProcessorError()
|
|
46
47
|
*/
|
|
47
|
-
processChainSegment: (
|
|
48
|
+
processChainSegment: (
|
|
49
|
+
blocks: IBlockInput[],
|
|
50
|
+
payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null,
|
|
51
|
+
syncType: RangeSyncType
|
|
52
|
+
) => Promise<void>;
|
|
48
53
|
/** Must download blocks, and validate their range */
|
|
49
54
|
downloadByRange: (
|
|
50
55
|
peer: PeerSyncMeta,
|
|
51
56
|
batch: Batch,
|
|
52
57
|
syncType: RangeSyncType
|
|
53
|
-
) => Promise<
|
|
58
|
+
) => Promise<
|
|
59
|
+
WarnResult<{blocks: IBlockInput[]; payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null}, DownloadByRangeError>
|
|
60
|
+
>;
|
|
54
61
|
/** Report peer for negative actions. Decouples from the full network instance */
|
|
55
62
|
reportPeer: (peer: PeerIdStr, action: PeerAction, actionName: string) => void;
|
|
56
63
|
/** Gets current peer custodyColumns and earliestAvailableSlot */
|
|
@@ -215,12 +222,14 @@ export class SyncChain {
|
|
|
215
222
|
*/
|
|
216
223
|
stopSyncing(): void {
|
|
217
224
|
this.status = SyncChainStatus.Stopped;
|
|
225
|
+
this.logger.debug("SyncChain stopSyncing", {id: this.logId});
|
|
218
226
|
}
|
|
219
227
|
|
|
220
228
|
/**
|
|
221
229
|
* Permanently remove this chain. Throws the main AsyncIterable
|
|
222
230
|
*/
|
|
223
231
|
remove(): void {
|
|
232
|
+
this.logger.debug("SyncChain remove", {id: this.logId});
|
|
224
233
|
this.batchProcessor.end(new ErrorAborted("SyncChain"));
|
|
225
234
|
}
|
|
226
235
|
|
|
@@ -516,7 +525,8 @@ export class SyncChain {
|
|
|
516
525
|
});
|
|
517
526
|
this.metrics?.syncRange.downloadByRange.success.inc();
|
|
518
527
|
const {warnings, result} = res.result;
|
|
519
|
-
const
|
|
528
|
+
const {blocks: downloadedBlocks, payloadEnvelopes} = result;
|
|
529
|
+
const downloadSuccessOutput = batch.downloadingSuccess(peer.peerId, downloadedBlocks, payloadEnvelopes);
|
|
520
530
|
const logMeta: Record<string, number> = {
|
|
521
531
|
blockCount: downloadSuccessOutput.blocks.length,
|
|
522
532
|
};
|
|
@@ -526,7 +536,7 @@ export class SyncChain {
|
|
|
526
536
|
this.metrics?.syncRange.downloadByRange.warn.inc({client: peer.client, code: warning.type.code});
|
|
527
537
|
this.logger.debug(
|
|
528
538
|
"Batch downloaded with warning",
|
|
529
|
-
{id: this.logId,
|
|
539
|
+
{id: this.logId, ...batch.getMetadata(), ...logMeta, peer: prettyPrintPeerIdStr(peer.peerId)},
|
|
530
540
|
warning
|
|
531
541
|
);
|
|
532
542
|
}
|
|
@@ -552,10 +562,17 @@ export class SyncChain {
|
|
|
552
562
|
// the flow will continue to call triggerBatchDownloader() below
|
|
553
563
|
}
|
|
554
564
|
|
|
565
|
+
const blockSlots = downloadSuccessOutput.blocks.map((b) => b.slot);
|
|
566
|
+
const envelopeSlots = downloadSuccessOutput.payloadEnvelopes
|
|
567
|
+
? Array.from(downloadSuccessOutput.payloadEnvelopes.keys())
|
|
568
|
+
: null;
|
|
569
|
+
|
|
555
570
|
this.logger.debug(logMessage, {
|
|
556
571
|
id: this.logId,
|
|
557
|
-
|
|
572
|
+
...batch.getMetadata(),
|
|
558
573
|
...logMeta,
|
|
574
|
+
blockSlots: prettyPrintIndices(blockSlots),
|
|
575
|
+
...(envelopeSlots ? {envelopeSlots: prettyPrintIndices(envelopeSlots)} : {}),
|
|
559
576
|
peer: prettyPrintPeerIdStr(peer.peerId),
|
|
560
577
|
});
|
|
561
578
|
}
|
|
@@ -578,13 +595,24 @@ export class SyncChain {
|
|
|
578
595
|
* Sends `batch` to the processor. Note: batch may be empty
|
|
579
596
|
*/
|
|
580
597
|
private async processBatch(batch: Batch): Promise<void> {
|
|
581
|
-
const blocks = 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);
|
|
582
609
|
|
|
583
610
|
// wrapError ensures to never call both batch success() and batch error()
|
|
584
|
-
const res = await wrapError(this.processChainSegment(blocks, this.syncType));
|
|
611
|
+
const res = await wrapError(this.processChainSegment(blocks, payloadEnvelopes, this.syncType));
|
|
585
612
|
|
|
586
613
|
if (!res.err) {
|
|
587
614
|
batch.processingSuccess();
|
|
615
|
+
this.logger.verbose("Processed batch", {...logCtx, ...batch.getMetadata()});
|
|
588
616
|
|
|
589
617
|
// If the processed batch is not empty, validate previous AwaitingValidation blocks.
|
|
590
618
|
if (blocks.length > 0) {
|
|
@@ -594,7 +622,7 @@ export class SyncChain {
|
|
|
594
622
|
// Potentially process next AwaitingProcessing batch
|
|
595
623
|
this.triggerBatchProcessor();
|
|
596
624
|
} else {
|
|
597
|
-
this.logger.verbose("Batch process error",
|
|
625
|
+
this.logger.verbose("Batch process error", logCtx, res.err);
|
|
598
626
|
batch.processingError(res.err); // Throws after MAX_BATCH_PROCESSING_ATTEMPTS
|
|
599
627
|
|
|
600
628
|
// At least one block was successfully verified and imported, so we can be sure all
|
package/src/sync/range/range.ts
CHANGED
|
@@ -172,7 +172,7 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
|
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
/** Convenience method for `SyncChain` */
|
|
175
|
-
private processChainSegment: SyncChainFns["processChainSegment"] = async (blocks, syncType) => {
|
|
175
|
+
private processChainSegment: SyncChainFns["processChainSegment"] = async (blocks, payloadEnvelopes, syncType) => {
|
|
176
176
|
// Not trusted, verify signatures
|
|
177
177
|
const flags: ImportBlockOpts = {
|
|
178
178
|
// Only skip importing attestations for finalized sync. For head sync attestation are valuable.
|
|
@@ -192,9 +192,15 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
|
|
|
192
192
|
|
|
193
193
|
if (this.opts?.disableProcessAsChainSegment) {
|
|
194
194
|
// Should only be used for debugging or testing
|
|
195
|
-
for (const block of blocks)
|
|
195
|
+
for (const block of blocks) {
|
|
196
|
+
await this.chain.processBlock(block, flags);
|
|
197
|
+
const payloadEnvelope = payloadEnvelopes?.get(block.slot);
|
|
198
|
+
if (payloadEnvelope) {
|
|
199
|
+
await this.chain.processExecutionPayload(payloadEnvelope);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
196
202
|
} else {
|
|
197
|
-
await this.chain.processChainSegment(blocks, flags);
|
|
203
|
+
await this.chain.processChainSegment(blocks, payloadEnvelopes, flags);
|
|
198
204
|
}
|
|
199
205
|
};
|
|
200
206
|
|
|
@@ -209,13 +215,19 @@ export class RangeSync extends (EventEmitter as {new (): RangeSyncEmitter}) {
|
|
|
209
215
|
peerDasMetrics: this.chain.metrics?.peerDas,
|
|
210
216
|
...batch.getRequestsForPeer(peer),
|
|
211
217
|
});
|
|
212
|
-
const
|
|
218
|
+
const {responses, payloadEnvelopes: downloadedPayloadEnvelopes} = result;
|
|
219
|
+
const {blocks, payloadEnvelopes} = cacheByRangeResponses({
|
|
213
220
|
cache: this.chain.seenBlockInputCache,
|
|
221
|
+
seenPayloadEnvelopeInputCache: this.chain.seenPayloadEnvelopeInputCache,
|
|
214
222
|
peerIdStr: peer.peerId,
|
|
215
|
-
responses
|
|
223
|
+
responses,
|
|
216
224
|
batchBlocks,
|
|
225
|
+
downloadedPayloadEnvelopes,
|
|
226
|
+
existingPayloadEnvelopes: batch.getPayloadEnvelopes(),
|
|
227
|
+
custodyConfig: this.chain.custodyConfig,
|
|
228
|
+
seenTimestampSec: Date.now() / 1000,
|
|
217
229
|
});
|
|
218
|
-
return {result:
|
|
230
|
+
return {result: {blocks, payloadEnvelopes}, warnings};
|
|
219
231
|
};
|
|
220
232
|
|
|
221
233
|
private pruneBlockInputs: SyncChainFns["pruneBlockInputs"] = (blocks: IBlockInput[]) => {
|
package/src/sync/types.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import {RootHex, Slot} from "@lodestar/types";
|
|
2
|
+
import {SignedExecutionPayloadEnvelope} from "@lodestar/types/gloas";
|
|
3
|
+
import {toRootHex} from "@lodestar/utils";
|
|
2
4
|
import {IBlockInput} from "../chain/blocks/blockInput/index.js";
|
|
5
|
+
import {PayloadEnvelopeInput} from "../chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
3
6
|
|
|
4
7
|
export enum PendingBlockType {
|
|
5
8
|
/**
|
|
@@ -26,6 +29,14 @@ export enum PendingBlockInputStatus {
|
|
|
26
29
|
processing = "processing",
|
|
27
30
|
}
|
|
28
31
|
|
|
32
|
+
export enum PendingPayloadInputStatus {
|
|
33
|
+
pending = "pending",
|
|
34
|
+
fetching = "fetching",
|
|
35
|
+
waitingForBlock = "waiting_for_block",
|
|
36
|
+
downloaded = "downloaded",
|
|
37
|
+
processing = "processing",
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
export type PendingBlockInput = {
|
|
30
41
|
status: PendingBlockInputStatus;
|
|
31
42
|
blockInput: IBlockInput;
|
|
@@ -44,10 +55,47 @@ export type PendingRootHex = {
|
|
|
44
55
|
|
|
45
56
|
export type BlockInputSyncCacheItem = PendingBlockInput | PendingRootHex;
|
|
46
57
|
|
|
58
|
+
export type PendingPayloadInput = {
|
|
59
|
+
status:
|
|
60
|
+
| PendingPayloadInputStatus.pending
|
|
61
|
+
| PendingPayloadInputStatus.fetching
|
|
62
|
+
| PendingPayloadInputStatus.downloaded
|
|
63
|
+
| PendingPayloadInputStatus.processing;
|
|
64
|
+
payloadInput: PayloadEnvelopeInput;
|
|
65
|
+
timeAddedSec: number;
|
|
66
|
+
timeSyncedSec?: number;
|
|
67
|
+
peerIdStrings: Set<string>;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type PendingPayloadRootHex = {
|
|
71
|
+
status: PendingPayloadInputStatus.pending | PendingPayloadInputStatus.fetching;
|
|
72
|
+
rootHex: RootHex;
|
|
73
|
+
timeAddedSec: number;
|
|
74
|
+
timeSyncedSec?: number;
|
|
75
|
+
peerIdStrings: Set<string>;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type PendingPayloadEnvelope = {
|
|
79
|
+
status: PendingPayloadInputStatus.waitingForBlock;
|
|
80
|
+
envelope: SignedExecutionPayloadEnvelope;
|
|
81
|
+
timeAddedSec: number;
|
|
82
|
+
peerIdStrings: Set<string>;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export type PayloadSyncCacheItem = PendingPayloadInput | PendingPayloadRootHex | PendingPayloadEnvelope;
|
|
86
|
+
|
|
47
87
|
export function isPendingBlockInput(pending: BlockInputSyncCacheItem): pending is PendingBlockInput {
|
|
48
88
|
return "blockInput" in pending;
|
|
49
89
|
}
|
|
50
90
|
|
|
91
|
+
export function isPendingPayloadInput(pending: PayloadSyncCacheItem): pending is PendingPayloadInput {
|
|
92
|
+
return "payloadInput" in pending;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function isPendingPayloadEnvelope(pending: PayloadSyncCacheItem): pending is PendingPayloadEnvelope {
|
|
96
|
+
return "envelope" in pending;
|
|
97
|
+
}
|
|
98
|
+
|
|
51
99
|
export function getBlockInputSyncCacheItemRootHex(block: BlockInputSyncCacheItem): RootHex {
|
|
52
100
|
return isPendingBlockInput(block) ? block.blockInput.blockRootHex : block.rootHex;
|
|
53
101
|
}
|
|
@@ -55,3 +103,27 @@ export function getBlockInputSyncCacheItemRootHex(block: BlockInputSyncCacheItem
|
|
|
55
103
|
export function getBlockInputSyncCacheItemSlot(block: BlockInputSyncCacheItem): Slot | string {
|
|
56
104
|
return isPendingBlockInput(block) ? block.blockInput.slot : "unknown";
|
|
57
105
|
}
|
|
106
|
+
|
|
107
|
+
export function getPayloadSyncCacheItemRootHex(payload: PayloadSyncCacheItem): RootHex {
|
|
108
|
+
if (isPendingPayloadInput(payload)) {
|
|
109
|
+
return payload.payloadInput.blockRootHex;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (isPendingPayloadEnvelope(payload)) {
|
|
113
|
+
return toRootHex(payload.envelope.message.beaconBlockRoot);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return payload.rootHex;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function getPayloadSyncCacheItemSlot(payload: PayloadSyncCacheItem): Slot | string {
|
|
120
|
+
if (isPendingPayloadInput(payload)) {
|
|
121
|
+
return payload.payloadInput.slot;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (isPendingPayloadEnvelope(payload)) {
|
|
125
|
+
return payload.envelope.message.payload.slotNumber;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return "unknown";
|
|
129
|
+
}
|