@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
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
ForkPostDeneb,
|
|
4
|
+
ForkPostFulu,
|
|
5
|
+
ForkPostGloas,
|
|
6
|
+
ForkPreFulu,
|
|
7
|
+
isForkPostFulu,
|
|
8
|
+
isForkPostGloas,
|
|
9
|
+
} from "@lodestar/params";
|
|
10
|
+
import {
|
|
11
|
+
DataColumnSidecar,
|
|
12
|
+
SignedBeaconBlock,
|
|
13
|
+
Slot,
|
|
14
|
+
deneb,
|
|
15
|
+
fulu,
|
|
16
|
+
gloas,
|
|
17
|
+
isGloasDataColumnSidecar,
|
|
18
|
+
phase0,
|
|
19
|
+
} from "@lodestar/types";
|
|
4
20
|
import {LodestarError, Logger, byteArrayEquals, fromHex, prettyPrintIndices, toRootHex} from "@lodestar/utils";
|
|
5
21
|
import {
|
|
6
22
|
BlockInputSource,
|
|
@@ -9,12 +25,18 @@ import {
|
|
|
9
25
|
isBlockInputBlobs,
|
|
10
26
|
isBlockInputColumns,
|
|
11
27
|
} from "../../chain/blocks/blockInput/index.js";
|
|
28
|
+
import {PayloadEnvelopeInput} from "../../chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
29
|
+
import {PayloadEnvelopeInputSource} from "../../chain/blocks/payloadEnvelopeInput/types.js";
|
|
12
30
|
import {SeenBlockInput} from "../../chain/seenCache/seenGossipBlockInput.js";
|
|
31
|
+
import {SeenPayloadEnvelopeInput} from "../../chain/seenCache/seenPayloadEnvelopeInput.js";
|
|
13
32
|
import {validateBlockBlobSidecars} from "../../chain/validation/blobSidecar.js";
|
|
14
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
validateFuluBlockDataColumnSidecars,
|
|
35
|
+
validateGloasBlockDataColumnSidecars,
|
|
36
|
+
} from "../../chain/validation/dataColumnSidecar.js";
|
|
15
37
|
import {BeaconMetrics} from "../../metrics/metrics/beacon.js";
|
|
16
38
|
import {INetwork} from "../../network/index.js";
|
|
17
|
-
import {getBlobKzgCommitments} from "../../util/dataColumns.js";
|
|
39
|
+
import {CustodyConfig, getBlobKzgCommitments} from "../../util/dataColumns.js";
|
|
18
40
|
import {PeerIdStr} from "../../util/peerId.js";
|
|
19
41
|
import {WarnResult} from "../../util/wrapError.js";
|
|
20
42
|
|
|
@@ -22,12 +44,14 @@ export type DownloadByRangeRequests = {
|
|
|
22
44
|
blocksRequest?: phase0.BeaconBlocksByRangeRequest;
|
|
23
45
|
blobsRequest?: deneb.BlobSidecarsByRangeRequest;
|
|
24
46
|
columnsRequest?: fulu.DataColumnSidecarsByRangeRequest;
|
|
47
|
+
envelopesRequest?: gloas.ExecutionPayloadEnvelopesByRangeRequest;
|
|
25
48
|
};
|
|
26
49
|
|
|
27
50
|
export type DownloadByRangeResponses = {
|
|
28
51
|
blocks?: SignedBeaconBlock[];
|
|
29
52
|
blobSidecars?: deneb.BlobSidecars;
|
|
30
|
-
columnSidecars?:
|
|
53
|
+
columnSidecars?: DataColumnSidecar[];
|
|
54
|
+
payloadEnvelopes?: gloas.SignedExecutionPayloadEnvelope[];
|
|
31
55
|
};
|
|
32
56
|
|
|
33
57
|
export type DownloadAndCacheByRangeProps = DownloadByRangeRequests & {
|
|
@@ -41,9 +65,17 @@ export type DownloadAndCacheByRangeProps = DownloadByRangeRequests & {
|
|
|
41
65
|
|
|
42
66
|
export type CacheByRangeResponsesProps = {
|
|
43
67
|
cache: SeenBlockInput;
|
|
68
|
+
seenPayloadEnvelopeInputCache: SeenPayloadEnvelopeInput;
|
|
44
69
|
peerIdStr: string;
|
|
45
70
|
responses: ValidatedResponses;
|
|
46
71
|
batchBlocks: IBlockInput[];
|
|
72
|
+
/** Raw envelopes downloaded in this batch, keyed by slot (from downloadByRange return) */
|
|
73
|
+
downloadedPayloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null;
|
|
74
|
+
/** Envelopes already wrapped from previous partial downloads on this batch */
|
|
75
|
+
existingPayloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null;
|
|
76
|
+
/** Sampled/custody column indices for building PayloadEnvelopeInputs */
|
|
77
|
+
custodyConfig: Pick<CustodyConfig, "sampledColumns" | "custodyColumns">;
|
|
78
|
+
seenTimestampSec: number;
|
|
47
79
|
};
|
|
48
80
|
|
|
49
81
|
export type ValidatedBlock = {
|
|
@@ -58,7 +90,7 @@ export type ValidatedBlobSidecars = {
|
|
|
58
90
|
|
|
59
91
|
export type ValidatedColumnSidecars = {
|
|
60
92
|
blockRoot: Uint8Array;
|
|
61
|
-
columnSidecars:
|
|
93
|
+
columnSidecars: DataColumnSidecar[];
|
|
62
94
|
};
|
|
63
95
|
|
|
64
96
|
export type ValidatedResponses = {
|
|
@@ -72,12 +104,16 @@ export type ValidatedResponses = {
|
|
|
72
104
|
*/
|
|
73
105
|
export function cacheByRangeResponses({
|
|
74
106
|
cache,
|
|
107
|
+
seenPayloadEnvelopeInputCache,
|
|
75
108
|
peerIdStr,
|
|
76
109
|
responses,
|
|
77
110
|
batchBlocks,
|
|
78
|
-
|
|
111
|
+
downloadedPayloadEnvelopes,
|
|
112
|
+
existingPayloadEnvelopes,
|
|
113
|
+
custodyConfig,
|
|
114
|
+
seenTimestampSec,
|
|
115
|
+
}: CacheByRangeResponsesProps): {blocks: IBlockInput[]; payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null} {
|
|
79
116
|
const source = BlockInputSource.byRange;
|
|
80
|
-
const seenTimestampSec = Date.now() / 1000;
|
|
81
117
|
const updatedBatchBlocks = new Map<Slot, IBlockInput>(batchBlocks.map((block) => [block.slot, block]));
|
|
82
118
|
|
|
83
119
|
const blocks = responses.validatedBlocks ?? [];
|
|
@@ -149,16 +185,88 @@ export function cacheByRangeResponses({
|
|
|
149
185
|
}
|
|
150
186
|
}
|
|
151
187
|
|
|
188
|
+
// Seed seenPayloadEnvelopeInputCache for every gloas block in the batch, regardless of whether
|
|
189
|
+
// the peer returned its envelope. Without this, a block returned without its envelope would be
|
|
190
|
+
// imported with no cache entry, and later payload-by-root sync would throw
|
|
191
|
+
// "Missing PayloadEnvelopeInput for known block" (see issue #9306).
|
|
192
|
+
for (const blockInput of updatedBatchBlocks.values()) {
|
|
193
|
+
if (!blockInput.hasBlock() || !isForkPostGloas(blockInput.forkName)) continue;
|
|
194
|
+
seenPayloadEnvelopeInputCache.add({
|
|
195
|
+
blockRootHex: blockInput.blockRootHex,
|
|
196
|
+
block: blockInput.getBlock() as SignedBeaconBlock<ForkPostGloas>,
|
|
197
|
+
forkName: blockInput.forkName,
|
|
198
|
+
sampledColumns: custodyConfig.sampledColumns,
|
|
199
|
+
custodyColumns: custodyConfig.custodyColumns,
|
|
200
|
+
timeCreatedSec: seenTimestampSec,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Attach envelopes to entries whose envelope was returned by the peer. The returned
|
|
205
|
+
// payloadEnvelopes map only contains entries with envelopes ready for importExecutionPayload.
|
|
206
|
+
let payloadEnvelopes: Map<Slot, PayloadEnvelopeInput> | null = null;
|
|
207
|
+
if (downloadedPayloadEnvelopes !== null) {
|
|
208
|
+
payloadEnvelopes = new Map(existingPayloadEnvelopes ?? []);
|
|
209
|
+
|
|
210
|
+
for (const [slot, envelope] of downloadedPayloadEnvelopes) {
|
|
211
|
+
const blockInput = updatedBatchBlocks.get(slot);
|
|
212
|
+
if (!blockInput?.hasBlock() || !isForkPostGloas(blockInput.forkName)) {
|
|
213
|
+
// No block to pair this envelope with; drop silently
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const payloadInput = seenPayloadEnvelopeInputCache.get(blockInput.blockRootHex);
|
|
218
|
+
if (payloadInput === undefined) {
|
|
219
|
+
// Unreachable given the loop above seeded an entry for every gloas block in the batch.
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (!payloadInput.hasPayloadEnvelope()) {
|
|
224
|
+
payloadInput.addPayloadEnvelope({
|
|
225
|
+
envelope,
|
|
226
|
+
source: PayloadEnvelopeInputSource.byRange,
|
|
227
|
+
seenTimestampSec,
|
|
228
|
+
peerIdStr,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
payloadEnvelopes.set(slot, payloadInput);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
152
236
|
for (const {blockRoot, columnSidecars} of responses.validatedColumnSidecars ?? []) {
|
|
153
|
-
const
|
|
154
|
-
if (
|
|
237
|
+
const firstColumn = columnSidecars[0];
|
|
238
|
+
if (!firstColumn) {
|
|
155
239
|
throw new Error(
|
|
156
240
|
`Coding Error: empty columnSidecars returned for blockRoot=${toRootHex(blockRoot)} from validation functions`
|
|
157
241
|
);
|
|
158
242
|
}
|
|
159
|
-
|
|
243
|
+
|
|
160
244
|
const blockRootHex = toRootHex(blockRoot);
|
|
161
245
|
|
|
246
|
+
if (isGloasDataColumnSidecar(firstColumn)) {
|
|
247
|
+
// Gloas columns are attached to the matching PayloadEnvelopeInput, NOT to IBlockInput.
|
|
248
|
+
// Gloas DataColumnSidecar has `slot` directly (no signedBlockHeader).
|
|
249
|
+
const dataSlot = firstColumn.slot;
|
|
250
|
+
const payloadInput = payloadEnvelopes?.get(dataSlot);
|
|
251
|
+
if (!payloadInput) {
|
|
252
|
+
// Should not happen: we built payloadInputs for all gloas blocks above
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
for (const columnSidecar of columnSidecars as gloas.DataColumnSidecar[]) {
|
|
256
|
+
payloadInput.addColumn({
|
|
257
|
+
columnSidecar,
|
|
258
|
+
seenTimestampSec,
|
|
259
|
+
peerIdStr,
|
|
260
|
+
source: PayloadEnvelopeInputSource.byRange,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const fuluColumns = columnSidecars as fulu.DataColumnSidecar[];
|
|
267
|
+
const dataSlot = fuluColumns[0].signedBlockHeader.message.slot;
|
|
268
|
+
const existing = updatedBatchBlocks.get(dataSlot);
|
|
269
|
+
|
|
162
270
|
if (!existing) {
|
|
163
271
|
throw new Error("Coding error: blockInput must exist when adding columns");
|
|
164
272
|
}
|
|
@@ -172,7 +280,7 @@ export function cacheByRangeResponses({
|
|
|
172
280
|
actual: existing.type,
|
|
173
281
|
});
|
|
174
282
|
}
|
|
175
|
-
for (const columnSidecar of
|
|
283
|
+
for (const columnSidecar of fuluColumns) {
|
|
176
284
|
// will throw if root hex does not match (meaning we are following the wrong chain)
|
|
177
285
|
existing.addColumn(
|
|
178
286
|
{
|
|
@@ -187,7 +295,7 @@ export function cacheByRangeResponses({
|
|
|
187
295
|
}
|
|
188
296
|
}
|
|
189
297
|
|
|
190
|
-
return Array.from(updatedBatchBlocks.values());
|
|
298
|
+
return {blocks: Array.from(updatedBatchBlocks.values()), payloadEnvelopes};
|
|
191
299
|
}
|
|
192
300
|
|
|
193
301
|
export async function downloadByRange({
|
|
@@ -198,8 +306,14 @@ export async function downloadByRange({
|
|
|
198
306
|
blocksRequest,
|
|
199
307
|
blobsRequest,
|
|
200
308
|
columnsRequest,
|
|
309
|
+
envelopesRequest,
|
|
201
310
|
peerDasMetrics,
|
|
202
|
-
}: DownloadAndCacheByRangeProps): Promise<
|
|
311
|
+
}: DownloadAndCacheByRangeProps): Promise<
|
|
312
|
+
WarnResult<
|
|
313
|
+
{responses: ValidatedResponses; payloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null},
|
|
314
|
+
DownloadByRangeError
|
|
315
|
+
>
|
|
316
|
+
> {
|
|
203
317
|
let response: DownloadByRangeResponses;
|
|
204
318
|
try {
|
|
205
319
|
response = await requestByRange({
|
|
@@ -208,6 +322,7 @@ export async function downloadByRange({
|
|
|
208
322
|
blocksRequest,
|
|
209
323
|
blobsRequest,
|
|
210
324
|
columnsRequest,
|
|
325
|
+
envelopesRequest,
|
|
211
326
|
});
|
|
212
327
|
} catch (err) {
|
|
213
328
|
throw new DownloadByRangeError({
|
|
@@ -217,17 +332,16 @@ export async function downloadByRange({
|
|
|
217
332
|
});
|
|
218
333
|
}
|
|
219
334
|
|
|
220
|
-
|
|
335
|
+
return validateResponses({
|
|
221
336
|
config,
|
|
222
337
|
batchBlocks,
|
|
223
338
|
blocksRequest,
|
|
224
339
|
blobsRequest,
|
|
225
340
|
columnsRequest,
|
|
341
|
+
envelopesRequest,
|
|
226
342
|
peerDasMetrics,
|
|
227
343
|
...response,
|
|
228
344
|
});
|
|
229
|
-
|
|
230
|
-
return validated;
|
|
231
345
|
}
|
|
232
346
|
|
|
233
347
|
/**
|
|
@@ -239,13 +353,15 @@ export async function requestByRange({
|
|
|
239
353
|
blocksRequest,
|
|
240
354
|
blobsRequest,
|
|
241
355
|
columnsRequest,
|
|
356
|
+
envelopesRequest,
|
|
242
357
|
}: DownloadByRangeRequests & {
|
|
243
358
|
network: INetwork;
|
|
244
359
|
peerIdStr: PeerIdStr;
|
|
245
360
|
}): Promise<DownloadByRangeResponses> {
|
|
246
361
|
let blocks: undefined | SignedBeaconBlock[];
|
|
247
362
|
let blobSidecars: undefined | deneb.BlobSidecars;
|
|
248
|
-
let columnSidecars: undefined |
|
|
363
|
+
let columnSidecars: undefined | DataColumnSidecar[];
|
|
364
|
+
let payloadEnvelopes: undefined | gloas.SignedExecutionPayloadEnvelope[];
|
|
249
365
|
|
|
250
366
|
const requests: Promise<unknown>[] = [];
|
|
251
367
|
|
|
@@ -268,7 +384,15 @@ export async function requestByRange({
|
|
|
268
384
|
if (columnsRequest) {
|
|
269
385
|
requests.push(
|
|
270
386
|
network.sendDataColumnSidecarsByRange(peerIdStr, columnsRequest).then((columnResponse) => {
|
|
271
|
-
columnSidecars = columnResponse
|
|
387
|
+
columnSidecars = columnResponse;
|
|
388
|
+
})
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (envelopesRequest) {
|
|
393
|
+
requests.push(
|
|
394
|
+
network.sendExecutionPayloadEnvelopesByRange(peerIdStr, envelopesRequest).then((envelopeResponse) => {
|
|
395
|
+
payloadEnvelopes = envelopeResponse;
|
|
272
396
|
})
|
|
273
397
|
);
|
|
274
398
|
}
|
|
@@ -279,6 +403,7 @@ export async function requestByRange({
|
|
|
279
403
|
blocks,
|
|
280
404
|
blobSidecars,
|
|
281
405
|
columnSidecars,
|
|
406
|
+
payloadEnvelopes,
|
|
282
407
|
};
|
|
283
408
|
}
|
|
284
409
|
|
|
@@ -291,16 +416,23 @@ export async function validateResponses({
|
|
|
291
416
|
blocksRequest,
|
|
292
417
|
blobsRequest,
|
|
293
418
|
columnsRequest,
|
|
419
|
+
envelopesRequest,
|
|
294
420
|
blocks,
|
|
295
421
|
blobSidecars,
|
|
296
422
|
columnSidecars,
|
|
423
|
+
payloadEnvelopes,
|
|
297
424
|
peerDasMetrics,
|
|
298
425
|
}: DownloadByRangeRequests &
|
|
299
426
|
DownloadByRangeResponses & {
|
|
300
427
|
config: ChainForkConfig;
|
|
301
428
|
batchBlocks?: IBlockInput[];
|
|
302
429
|
peerDasMetrics?: BeaconMetrics["peerDas"] | null;
|
|
303
|
-
}): Promise<
|
|
430
|
+
}): Promise<
|
|
431
|
+
WarnResult<
|
|
432
|
+
{responses: ValidatedResponses; payloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null},
|
|
433
|
+
DownloadByRangeError
|
|
434
|
+
>
|
|
435
|
+
> {
|
|
304
436
|
// Blocks are always required for blob/column validation
|
|
305
437
|
// If a blocksRequest is provided, blocks have just been downloaded
|
|
306
438
|
// If no blocksRequest is provided, batchBlocks must have been provided from cache
|
|
@@ -326,8 +458,21 @@ export async function validateResponses({
|
|
|
326
458
|
}
|
|
327
459
|
|
|
328
460
|
const dataRequest = blobsRequest ?? columnsRequest;
|
|
461
|
+
if (!dataRequest && !envelopesRequest) {
|
|
462
|
+
return {result: {responses: validatedResponses, payloadEnvelopes: null}, warnings};
|
|
463
|
+
}
|
|
464
|
+
|
|
329
465
|
if (!dataRequest) {
|
|
330
|
-
|
|
466
|
+
// Only envelope validation needed
|
|
467
|
+
let validatedPayloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null = null;
|
|
468
|
+
if (envelopesRequest) {
|
|
469
|
+
validatedPayloadEnvelopes = validateEnvelopesByRangeResponse(
|
|
470
|
+
validatedResponses.validatedBlocks ?? [],
|
|
471
|
+
batchBlocks,
|
|
472
|
+
payloadEnvelopes ?? []
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
return {result: {responses: validatedResponses, payloadEnvelopes: validatedPayloadEnvelopes}, warnings};
|
|
331
476
|
}
|
|
332
477
|
|
|
333
478
|
const blocksForDataValidation = getBlocksForDataValidation(
|
|
@@ -385,7 +530,17 @@ export async function validateResponses({
|
|
|
385
530
|
warnings = validatedColumnSidecarsResult.warnings;
|
|
386
531
|
}
|
|
387
532
|
|
|
388
|
-
|
|
533
|
+
// Validate envelopes if an envelopes request was made
|
|
534
|
+
let validatedPayloadEnvelopes: Map<Slot, gloas.SignedExecutionPayloadEnvelope> | null = null;
|
|
535
|
+
if (envelopesRequest) {
|
|
536
|
+
validatedPayloadEnvelopes = validateEnvelopesByRangeResponse(
|
|
537
|
+
validatedResponses.validatedBlocks ?? [],
|
|
538
|
+
batchBlocks,
|
|
539
|
+
payloadEnvelopes ?? []
|
|
540
|
+
);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return {result: {responses: validatedResponses, payloadEnvelopes: validatedPayloadEnvelopes}, warnings};
|
|
389
544
|
}
|
|
390
545
|
|
|
391
546
|
/**
|
|
@@ -615,19 +770,19 @@ export async function validateColumnsByRangeResponse(
|
|
|
615
770
|
config: ChainForkConfig,
|
|
616
771
|
request: fulu.DataColumnSidecarsByRangeRequest,
|
|
617
772
|
blocks: ValidatedBlock[],
|
|
618
|
-
columnSidecars:
|
|
773
|
+
columnSidecars: DataColumnSidecar[],
|
|
619
774
|
peerDasMetrics?: BeaconMetrics["peerDas"] | null
|
|
620
775
|
): Promise<WarnResult<ValidatedColumnSidecars[], DownloadByRangeError>> {
|
|
621
776
|
const warnings: DownloadByRangeError[] = [];
|
|
622
777
|
|
|
623
|
-
|
|
624
|
-
// validate against the block bid commitments instead of the fulu signed header shape
|
|
625
|
-
const seenColumns = new Map<Slot, Map<number, fulu.DataColumnSidecar>>();
|
|
778
|
+
const seenColumns = new Map<Slot, Map<number, DataColumnSidecar>>();
|
|
626
779
|
let currentSlot = -1;
|
|
627
780
|
let currentIndex = -1;
|
|
628
781
|
// Check for duplicates and order
|
|
629
782
|
for (const columnSidecar of columnSidecars) {
|
|
630
|
-
const slot = columnSidecar
|
|
783
|
+
const slot = isGloasDataColumnSidecar(columnSidecar)
|
|
784
|
+
? columnSidecar.slot
|
|
785
|
+
: columnSidecar.signedBlockHeader.message.slot;
|
|
631
786
|
let seenSlotColumns = seenColumns.get(slot);
|
|
632
787
|
if (!seenSlotColumns) {
|
|
633
788
|
seenSlotColumns = new Map();
|
|
@@ -686,20 +841,20 @@ export async function validateColumnsByRangeResponse(
|
|
|
686
841
|
const slot = block.message.slot;
|
|
687
842
|
const rootHex = toRootHex(blockRoot);
|
|
688
843
|
const forkName = config.getForkName(slot);
|
|
689
|
-
const columnSidecarsMap: Map<number,
|
|
844
|
+
const columnSidecarsMap: Map<number, DataColumnSidecar> = seenColumns.get(slot) ?? new Map();
|
|
690
845
|
const columnSidecars = Array.from(columnSidecarsMap.values()).sort((a, b) => a.index - b.index);
|
|
691
846
|
|
|
692
847
|
let blobCount: number;
|
|
693
848
|
if (!isForkPostFulu(forkName)) {
|
|
694
|
-
const dataSlot = columnSidecars.at(0)?.signedBlockHeader.message.slot;
|
|
695
849
|
throw new DownloadByRangeError({
|
|
696
850
|
code: DownloadByRangeErrorCode.MISMATCH_BLOCK_FORK,
|
|
697
851
|
slot,
|
|
698
852
|
blockFork: forkName,
|
|
699
|
-
dataFork:
|
|
853
|
+
dataFork: "unknown",
|
|
700
854
|
});
|
|
701
855
|
}
|
|
702
|
-
|
|
856
|
+
const kzgCommitments = getBlobKzgCommitments(forkName, block as SignedBeaconBlock<ForkPostFulu>);
|
|
857
|
+
blobCount = kzgCommitments.length;
|
|
703
858
|
|
|
704
859
|
if (columnSidecars.length === 0) {
|
|
705
860
|
if (!blobCount) {
|
|
@@ -768,15 +923,25 @@ export async function validateColumnsByRangeResponse(
|
|
|
768
923
|
);
|
|
769
924
|
}
|
|
770
925
|
|
|
926
|
+
const validatePromise = isForkPostGloas(forkName)
|
|
927
|
+
? validateGloasBlockDataColumnSidecars(
|
|
928
|
+
slot,
|
|
929
|
+
blockRoot,
|
|
930
|
+
kzgCommitments,
|
|
931
|
+
columnSidecars as gloas.DataColumnSidecar[],
|
|
932
|
+
peerDasMetrics
|
|
933
|
+
)
|
|
934
|
+
: validateFuluBlockDataColumnSidecars(
|
|
935
|
+
null, // do not pass chain here so we do not validate header signature
|
|
936
|
+
slot,
|
|
937
|
+
blockRoot,
|
|
938
|
+
blobCount,
|
|
939
|
+
columnSidecars as fulu.DataColumnSidecar[],
|
|
940
|
+
peerDasMetrics
|
|
941
|
+
);
|
|
942
|
+
|
|
771
943
|
validationPromises.push(
|
|
772
|
-
|
|
773
|
-
null, // do not pass chain here so we do not validate header signature
|
|
774
|
-
slot,
|
|
775
|
-
blockRoot,
|
|
776
|
-
blobCount,
|
|
777
|
-
columnSidecars,
|
|
778
|
-
peerDasMetrics
|
|
779
|
-
).then(() => ({
|
|
944
|
+
validatePromise.then(() => ({
|
|
780
945
|
blockRoot,
|
|
781
946
|
columnSidecars,
|
|
782
947
|
}))
|
|
@@ -882,6 +1047,9 @@ export enum DownloadByRangeErrorCode {
|
|
|
882
1047
|
/** Cached block input type mismatches new data */
|
|
883
1048
|
MISMATCH_BLOCK_FORK = "DOWNLOAD_BY_RANGE_ERROR_MISMATCH_BLOCK_FORK",
|
|
884
1049
|
MISMATCH_BLOCK_INPUT_TYPE = "DOWNLOAD_BY_RANGE_ERROR_MISMATCH_BLOCK_INPUT_TYPE",
|
|
1050
|
+
|
|
1051
|
+
/** Envelope beaconBlockRoot does not match the block's root */
|
|
1052
|
+
INVALID_ENVELOPE_BEACON_BLOCK_ROOT = "DOWNLOAD_BY_RANGE_ERROR_INVALID_ENVELOPE_BEACON_BLOCK_ROOT",
|
|
885
1053
|
}
|
|
886
1054
|
|
|
887
1055
|
export type DownloadByRangeErrorType =
|
|
@@ -973,6 +1141,61 @@ export type DownloadByRangeErrorType =
|
|
|
973
1141
|
blockRoot: string;
|
|
974
1142
|
expected: DAType;
|
|
975
1143
|
actual: DAType;
|
|
1144
|
+
}
|
|
1145
|
+
| {
|
|
1146
|
+
code: DownloadByRangeErrorCode.INVALID_ENVELOPE_BEACON_BLOCK_ROOT;
|
|
1147
|
+
slot: Slot;
|
|
1148
|
+
expected: string;
|
|
1149
|
+
actual: string;
|
|
976
1150
|
};
|
|
977
1151
|
|
|
978
1152
|
export class DownloadByRangeError extends LodestarError<DownloadByRangeErrorType> {}
|
|
1153
|
+
|
|
1154
|
+
/**
|
|
1155
|
+
* Validates SignedExecutionPayloadEnvelopes received for a range request.
|
|
1156
|
+
* For each envelope whose slot appears in the downloaded blocks, verifies that
|
|
1157
|
+
* envelope.message.beaconBlockRoot matches the corresponding block's root.
|
|
1158
|
+
* Envelopes for slots not in the batch (orphaned payloads) are silently ignored.
|
|
1159
|
+
*/
|
|
1160
|
+
export function validateEnvelopesByRangeResponse(
|
|
1161
|
+
validatedBlocks: ValidatedBlock[],
|
|
1162
|
+
batchBlocks: IBlockInput[] | undefined,
|
|
1163
|
+
payloadEnvelopes: gloas.SignedExecutionPayloadEnvelope[]
|
|
1164
|
+
): Map<Slot, gloas.SignedExecutionPayloadEnvelope> {
|
|
1165
|
+
// Build a map of slot -> blockRoot for all blocks in the batch
|
|
1166
|
+
const batchBlockRoots = new Map<Slot, Uint8Array>();
|
|
1167
|
+
if (batchBlocks) {
|
|
1168
|
+
for (const blockInput of batchBlocks) {
|
|
1169
|
+
batchBlockRoots.set(blockInput.slot, fromHex(blockInput.blockRootHex));
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
for (const {block, blockRoot} of validatedBlocks) {
|
|
1173
|
+
batchBlockRoots.set(block.message.slot, blockRoot);
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
const payloadEnvelopeMap = new Map<Slot, gloas.SignedExecutionPayloadEnvelope>();
|
|
1177
|
+
|
|
1178
|
+
for (const payloadEnvelope of payloadEnvelopes) {
|
|
1179
|
+
const slot = payloadEnvelope.message.payload.slotNumber;
|
|
1180
|
+
const batchBlockRoot = batchBlockRoots.get(slot);
|
|
1181
|
+
|
|
1182
|
+
// Envelopes for slots not in the batch are silently ignored (orphaned payloads)
|
|
1183
|
+
if (batchBlockRoot === undefined) {
|
|
1184
|
+
continue;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
// Verify beaconBlockRoot matches the block's root
|
|
1188
|
+
if (!byteArrayEquals(payloadEnvelope.message.beaconBlockRoot, batchBlockRoot)) {
|
|
1189
|
+
throw new DownloadByRangeError({
|
|
1190
|
+
code: DownloadByRangeErrorCode.INVALID_ENVELOPE_BEACON_BLOCK_ROOT,
|
|
1191
|
+
slot,
|
|
1192
|
+
expected: toRootHex(batchBlockRoot),
|
|
1193
|
+
actual: toRootHex(payloadEnvelope.message.beaconBlockRoot),
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
payloadEnvelopeMap.set(slot, payloadEnvelope);
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
return payloadEnvelopeMap;
|
|
1201
|
+
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
2
|
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ForkPostDeneb,
|
|
5
|
+
ForkPostFulu,
|
|
6
|
+
ForkPostGloas,
|
|
7
|
+
ForkPreFulu,
|
|
8
|
+
isForkPostDeneb,
|
|
9
|
+
isForkPostFulu,
|
|
10
|
+
isForkPostGloas,
|
|
11
|
+
} from "@lodestar/params";
|
|
4
12
|
import {BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
5
13
|
import {LodestarError, byteArrayEquals, fromHex, prettyPrintIndices, toHex, toRootHex} from "@lodestar/utils";
|
|
6
14
|
import {isBlockInputBlobs, isBlockInputColumns} from "../../chain/blocks/blockInput/blockInput.js";
|
|
@@ -107,6 +115,17 @@ export async function downloadByRoot({
|
|
|
107
115
|
});
|
|
108
116
|
}
|
|
109
117
|
|
|
118
|
+
if (isForkPostGloas(blockInput.forkName)) {
|
|
119
|
+
chain.seenPayloadEnvelopeInputCache.add({
|
|
120
|
+
blockRootHex: rootHex,
|
|
121
|
+
block: blockInput.getBlock() as SignedBeaconBlock<ForkPostGloas>,
|
|
122
|
+
forkName: blockInput.forkName,
|
|
123
|
+
sampledColumns: chain.custodyConfig.sampledColumns,
|
|
124
|
+
custodyColumns: chain.custodyConfig.custodyColumns,
|
|
125
|
+
timeCreatedSec: Date.now() / 1000,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
110
129
|
const hasAllDataPreDownload = blockInput.hasBlockAndAllData();
|
|
111
130
|
|
|
112
131
|
if (isBlockInputBlobs(blockInput) && !hasAllDataPreDownload) {
|
|
@@ -263,7 +282,10 @@ export async function fetchByRoot({
|
|
|
263
282
|
blockRoot,
|
|
264
283
|
});
|
|
265
284
|
const forkName = config.getForkName(block.message.slot);
|
|
266
|
-
if (
|
|
285
|
+
if (isForkPostGloas(forkName)) {
|
|
286
|
+
// Post-gloas block sync only needs the block body. Payload columns stay on the
|
|
287
|
+
// payload/envelope path and are queued independently in the network processor.
|
|
288
|
+
} else if (isForkPostFulu(forkName)) {
|
|
267
289
|
columnSidecarResult = await fetchAndValidateColumns({
|
|
268
290
|
config,
|
|
269
291
|
chain,
|
|
@@ -40,21 +40,6 @@ function addToDescendantBlocks(
|
|
|
40
40
|
return descendantBlocks;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
export function getDescendantBlocks(
|
|
44
|
-
blockRootHex: RootHex,
|
|
45
|
-
blocks: Map<RootHex, BlockInputSyncCacheItem>
|
|
46
|
-
): BlockInputSyncCacheItem[] {
|
|
47
|
-
const descendantBlocks: BlockInputSyncCacheItem[] = [];
|
|
48
|
-
|
|
49
|
-
for (const block of blocks.values()) {
|
|
50
|
-
if ((isPendingBlockInput(block) ? block.blockInput.parentRootHex : undefined) === blockRootHex) {
|
|
51
|
-
descendantBlocks.push(block);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return descendantBlocks;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
43
|
export type UnknownAndAncestorBlocks = {
|
|
59
44
|
unknowns: BlockInputSyncCacheItem[];
|
|
60
45
|
ancestors: PendingBlockInput[];
|