@lodestar/beacon-node 1.41.0-dev.afd446235e → 1.41.0-dev.b847afb846
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 +3 -2
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +1 -0
- 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 +26 -10
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +3 -8
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/archiveStore/utils/updateBackfillRange.js +1 -1
- package/lib/chain/archiveStore/utils/updateBackfillRange.js.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.d.ts +25 -2
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +71 -0
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/blockInput/types.d.ts +18 -1
- package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/types.js +1 -0
- package/lib/chain/blocks/blockInput/types.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +27 -4
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksDataAvailability.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksDataAvailability.js +3 -0
- package/lib/chain/blocks/verifyBlocksDataAvailability.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts +4 -0
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js +5 -1
- package/lib/chain/blocks/verifyBlocksExecutionPayloads.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +4 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts +12 -3
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +92 -98
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts +1 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +13 -12
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +3 -3
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +2 -2
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +30 -24
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +1 -2
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +4 -1
- 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 +6 -2
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts +5 -1
- package/lib/chain/seenCache/seenGossipBlockInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +36 -15
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/validation/aggregateAndProof.js +1 -1
- package/lib/chain/validation/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/attestation.js +3 -3
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +8 -1
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/blobSidecar.js +2 -2
- package/lib/chain/validation/blobSidecar.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +6 -3
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js +1 -1
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +1 -2
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +4 -4
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +1 -2
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/constants/network.d.ts +1 -2
- package/lib/constants/network.d.ts.map +1 -1
- package/lib/constants/network.js +0 -1
- package/lib/constants/network.js.map +1 -1
- 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/network.d.ts.map +1 -1
- package/lib/network/network.js +1 -1
- package/lib/network/network.js.map +1 -1
- package/lib/network/peers/peerManager.d.ts +0 -8
- package/lib/network/peers/peerManager.d.ts.map +1 -1
- package/lib/network/peers/peerManager.js +3 -48
- package/lib/network/peers/peerManager.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +4 -1
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +3 -2
- 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 +3 -2
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +3 -2
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/util/clock.d.ts +6 -0
- package/lib/util/clock.d.ts.map +1 -1
- package/lib/util/clock.js +9 -3
- package/lib/util/clock.js.map +1 -1
- package/lib/util/serializedCache.d.ts +4 -4
- package/lib/util/serializedCache.d.ts.map +1 -1
- package/lib/util/serializedCache.js +6 -4
- package/lib/util/serializedCache.js.map +1 -1
- package/package.json +26 -26
- package/src/api/impl/beacon/blocks/index.ts +3 -2
- package/src/api/impl/debug/index.ts +1 -0
- package/src/api/impl/validator/index.ts +26 -12
- package/src/chain/archiveStore/archiveStore.ts +5 -5
- package/src/chain/archiveStore/utils/archiveBlocks.ts +4 -5
- package/src/chain/archiveStore/utils/updateBackfillRange.ts +1 -1
- package/src/chain/blocks/blockInput/blockInput.ts +103 -3
- package/src/chain/blocks/blockInput/types.ts +18 -0
- package/src/chain/blocks/importBlock.ts +35 -4
- package/src/chain/blocks/verifyBlocksDataAvailability.ts +3 -0
- package/src/chain/blocks/verifyBlocksExecutionPayloads.ts +9 -2
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +7 -2
- package/src/chain/blocks/writeBlockInputToDb.ts +105 -104
- package/src/chain/chain.ts +28 -16
- package/src/chain/emitter.ts +3 -3
- package/src/chain/errors/executionPayloadEnvelope.ts +6 -2
- package/src/chain/forkChoice/index.ts +39 -21
- package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
- package/src/chain/produceBlock/produceBlockBody.ts +1 -2
- package/src/chain/regen/queued.ts +7 -2
- package/src/chain/regen/regen.ts +9 -3
- package/src/chain/seenCache/seenGossipBlockInput.ts +54 -17
- package/src/chain/validation/aggregateAndProof.ts +1 -1
- package/src/chain/validation/attestation.ts +3 -3
- package/src/chain/validation/attesterSlashing.ts +9 -0
- package/src/chain/validation/blobSidecar.ts +2 -2
- package/src/chain/validation/block.ts +9 -4
- package/src/chain/validation/dataColumnSidecar.ts +1 -1
- package/src/chain/validation/executionPayloadBid.ts +1 -2
- package/src/chain/validation/executionPayloadEnvelope.ts +4 -4
- package/src/chain/validation/payloadAttestationMessage.ts +1 -2
- package/src/constants/network.ts +0 -1
- package/src/metrics/metrics/lodestar.ts +4 -0
- package/src/network/network.ts +2 -1
- package/src/network/peers/peerManager.ts +4 -61
- package/src/network/processor/gossipHandlers.ts +12 -3
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +3 -2
- package/src/network/reqresp/handlers/blobSidecarsByRange.ts +3 -2
- package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +1 -1
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +3 -2
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -1
- package/src/util/clock.ts +9 -4
- package/src/util/serializedCache.ts +7 -5
package/src/chain/regen/regen.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
processSlots,
|
|
12
12
|
stateTransition,
|
|
13
13
|
} from "@lodestar/state-transition";
|
|
14
|
-
import {BeaconBlock, RootHex, SignedBeaconBlock, Slot} from "@lodestar/types";
|
|
14
|
+
import {BeaconBlock, RootHex, SignedBeaconBlock, Slot, isGloasBeaconBlock} from "@lodestar/types";
|
|
15
15
|
import {Logger, fromHex, toRootHex} from "@lodestar/utils";
|
|
16
16
|
import {IBeaconDb} from "../../db/index.js";
|
|
17
17
|
import {Metrics} from "../../metrics/index.js";
|
|
@@ -58,7 +58,13 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
58
58
|
opts: StateRegenerationOpts,
|
|
59
59
|
regenCaller: RegenCaller
|
|
60
60
|
): Promise<CachedBeaconStateAllForks> {
|
|
61
|
-
const
|
|
61
|
+
const parentRoot = toRootHex(block.parentRoot);
|
|
62
|
+
const parentBlock = isGloasBeaconBlock(block)
|
|
63
|
+
? this.modules.forkChoice.getBlockHexAndBlockHash(
|
|
64
|
+
parentRoot,
|
|
65
|
+
toRootHex(block.body.signedExecutionPayloadBid.message.parentBlockHash)
|
|
66
|
+
)
|
|
67
|
+
: this.modules.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
62
68
|
if (!parentBlock) {
|
|
63
69
|
throw new RegenError({
|
|
64
70
|
code: RegenErrorCode.BLOCK_NOT_IN_FORKCHOICE,
|
|
@@ -152,7 +158,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
152
158
|
|
|
153
159
|
const getSeedStateTimer = this.modules.metrics?.regenGetState.getSeedState.startTimer({caller});
|
|
154
160
|
// iterateAncestorBlocks only returns ancestor blocks, not the block itself
|
|
155
|
-
for (const b of this.modules.forkChoice.iterateAncestorBlocks(block.blockRoot)) {
|
|
161
|
+
for (const b of this.modules.forkChoice.iterateAncestorBlocks(block.blockRoot, block.payloadStatus)) {
|
|
156
162
|
state = this.modules.blockStateCache.get(b.stateRoot);
|
|
157
163
|
if (state) {
|
|
158
164
|
break;
|
|
@@ -3,6 +3,7 @@ import {CheckpointWithHex} from "@lodestar/fork-choice";
|
|
|
3
3
|
import {
|
|
4
4
|
ForkName,
|
|
5
5
|
ForkPostFulu,
|
|
6
|
+
ForkPostGloas,
|
|
6
7
|
ForkPreGloas,
|
|
7
8
|
SLOTS_PER_EPOCH,
|
|
8
9
|
isForkPostDeneb,
|
|
@@ -16,10 +17,12 @@ import {Metrics} from "../../metrics/metrics.js";
|
|
|
16
17
|
import {MAX_LOOK_AHEAD_EPOCHS} from "../../sync/constants.js";
|
|
17
18
|
import {IClock} from "../../util/clock.js";
|
|
18
19
|
import {CustodyConfig} from "../../util/dataColumns.js";
|
|
20
|
+
import {SerializedCache} from "../../util/serializedCache.js";
|
|
19
21
|
import {
|
|
20
22
|
BlockInput,
|
|
21
23
|
BlockInputBlobs,
|
|
22
24
|
BlockInputColumns,
|
|
25
|
+
BlockInputNoData,
|
|
23
26
|
BlockInputPreData,
|
|
24
27
|
BlockWithSource,
|
|
25
28
|
DAType,
|
|
@@ -53,6 +56,7 @@ export type SeenBlockInputCacheModules = {
|
|
|
53
56
|
chainEvents: ChainEventEmitter;
|
|
54
57
|
signal: AbortSignal;
|
|
55
58
|
custodyConfig: CustodyConfig;
|
|
59
|
+
serializedCache: SerializedCache;
|
|
56
60
|
metrics: Metrics | null;
|
|
57
61
|
logger?: Logger;
|
|
58
62
|
};
|
|
@@ -99,6 +103,7 @@ export class SeenBlockInput {
|
|
|
99
103
|
private readonly clock: IClock;
|
|
100
104
|
private readonly chainEvents: ChainEventEmitter;
|
|
101
105
|
private readonly signal: AbortSignal;
|
|
106
|
+
private readonly serializedCache: SerializedCache;
|
|
102
107
|
private readonly metrics: Metrics | null;
|
|
103
108
|
private readonly logger?: Logger;
|
|
104
109
|
private blockInputs = new Map<RootHex, IBlockInput>();
|
|
@@ -107,19 +112,35 @@ export class SeenBlockInput {
|
|
|
107
112
|
// and the signature to ensure we only skip verification if both match
|
|
108
113
|
private verifiedProposerSignatures = new Map<Slot, Map<RootHex, BLSSignature>>();
|
|
109
114
|
|
|
110
|
-
constructor({
|
|
115
|
+
constructor({
|
|
116
|
+
config,
|
|
117
|
+
custodyConfig,
|
|
118
|
+
clock,
|
|
119
|
+
chainEvents,
|
|
120
|
+
signal,
|
|
121
|
+
serializedCache,
|
|
122
|
+
metrics,
|
|
123
|
+
logger,
|
|
124
|
+
}: SeenBlockInputCacheModules) {
|
|
111
125
|
this.config = config;
|
|
112
126
|
this.custodyConfig = custodyConfig;
|
|
113
127
|
this.clock = clock;
|
|
114
128
|
this.chainEvents = chainEvents;
|
|
115
129
|
this.signal = signal;
|
|
130
|
+
this.serializedCache = serializedCache;
|
|
116
131
|
this.metrics = metrics;
|
|
117
132
|
this.logger = logger;
|
|
118
133
|
|
|
119
134
|
if (metrics) {
|
|
120
|
-
metrics.seenCache.blockInput.blockInputCount.addCollect(() =>
|
|
121
|
-
metrics.seenCache.blockInput.blockInputCount.set(this.blockInputs.size)
|
|
122
|
-
|
|
135
|
+
metrics.seenCache.blockInput.blockInputCount.addCollect(() => {
|
|
136
|
+
metrics.seenCache.blockInput.blockInputCount.set(this.blockInputs.size);
|
|
137
|
+
metrics.seenCache.blockInput.serializedObjectCount.set(
|
|
138
|
+
Array.from(this.blockInputs.values()).reduce(
|
|
139
|
+
(count, blockInput) => count + blockInput.getSerializedCacheKeys().length,
|
|
140
|
+
0
|
|
141
|
+
)
|
|
142
|
+
);
|
|
143
|
+
});
|
|
123
144
|
}
|
|
124
145
|
|
|
125
146
|
this.chainEvents.on(ChainEvent.forkChoiceFinalized, this.onFinalized);
|
|
@@ -140,7 +161,10 @@ export class SeenBlockInput {
|
|
|
140
161
|
* Removes the single BlockInput from the cache
|
|
141
162
|
*/
|
|
142
163
|
remove(rootHex: RootHex): void {
|
|
143
|
-
this.blockInputs.
|
|
164
|
+
const blockInput = this.blockInputs.get(rootHex);
|
|
165
|
+
if (blockInput) {
|
|
166
|
+
this.evictBlockInput(blockInput);
|
|
167
|
+
}
|
|
144
168
|
}
|
|
145
169
|
|
|
146
170
|
/**
|
|
@@ -152,7 +176,7 @@ export class SeenBlockInput {
|
|
|
152
176
|
let deletedCount = 0;
|
|
153
177
|
while (blockInput) {
|
|
154
178
|
deletedCount++;
|
|
155
|
-
this.
|
|
179
|
+
this.evictBlockInput(blockInput);
|
|
156
180
|
blockInput = this.blockInputs.get(parentRootHex ?? "");
|
|
157
181
|
parentRootHex = blockInput?.parentRootHex;
|
|
158
182
|
}
|
|
@@ -163,10 +187,10 @@ export class SeenBlockInput {
|
|
|
163
187
|
onFinalized = (checkpoint: CheckpointWithHex) => {
|
|
164
188
|
let deletedCount = 0;
|
|
165
189
|
const cutoffSlot = computeStartSlotAtEpoch(checkpoint.epoch);
|
|
166
|
-
for (const [
|
|
190
|
+
for (const [, blockInput] of this.blockInputs) {
|
|
167
191
|
if (blockInput.slot < cutoffSlot) {
|
|
168
192
|
deletedCount++;
|
|
169
|
-
this.
|
|
193
|
+
this.evictBlockInput(blockInput);
|
|
170
194
|
}
|
|
171
195
|
}
|
|
172
196
|
this.logger?.debug(`BlockInputCache.onFinalized deleted ${deletedCount} cached BlockInputs`);
|
|
@@ -179,12 +203,19 @@ export class SeenBlockInput {
|
|
|
179
203
|
if (!blockInput) {
|
|
180
204
|
const {forkName, daOutOfRange} = this.buildCommonProps(block.message.slot);
|
|
181
205
|
|
|
182
|
-
// TODO GLOAS: Implement
|
|
183
206
|
if (isForkPostGloas(forkName)) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
207
|
+
// Post-gloas
|
|
208
|
+
blockInput = BlockInputNoData.createFromBlock({
|
|
209
|
+
block: block as SignedBeaconBlock<ForkPostGloas>,
|
|
210
|
+
blockRootHex,
|
|
211
|
+
daOutOfRange,
|
|
212
|
+
forkName,
|
|
213
|
+
source,
|
|
214
|
+
seenTimestampSec,
|
|
215
|
+
peerIdStr,
|
|
216
|
+
});
|
|
217
|
+
} else if (!isForkPostDeneb(forkName)) {
|
|
218
|
+
// Pre-deneb
|
|
188
219
|
blockInput = BlockInputPreData.createFromBlock({
|
|
189
220
|
block,
|
|
190
221
|
blockRootHex,
|
|
@@ -194,8 +225,8 @@ export class SeenBlockInput {
|
|
|
194
225
|
seenTimestampSec,
|
|
195
226
|
peerIdStr,
|
|
196
227
|
});
|
|
197
|
-
// Fulu Only
|
|
198
228
|
} else if (isForkPostFulu(forkName)) {
|
|
229
|
+
// Fulu Only
|
|
199
230
|
blockInput = BlockInputColumns.createFromBlock({
|
|
200
231
|
block: block as SignedBeaconBlock<ForkPostFulu & ForkPreGloas>,
|
|
201
232
|
blockRootHex,
|
|
@@ -207,8 +238,8 @@ export class SeenBlockInput {
|
|
|
207
238
|
seenTimestampSec,
|
|
208
239
|
peerIdStr,
|
|
209
240
|
});
|
|
210
|
-
// Deneb and Electra
|
|
211
241
|
} else {
|
|
242
|
+
// Deneb and Electra
|
|
212
243
|
blockInput = BlockInputBlobs.createFromBlock({
|
|
213
244
|
block: block as SignedBeaconBlock<ForkBlobsDA>,
|
|
214
245
|
blockRootHex,
|
|
@@ -399,14 +430,20 @@ export class SeenBlockInput {
|
|
|
399
430
|
|
|
400
431
|
if (itemsToDelete > 0) {
|
|
401
432
|
const sorted = [...this.blockInputs.entries()].sort((a, b) => a[1].slot - b[1].slot);
|
|
402
|
-
for (const [
|
|
403
|
-
this.
|
|
433
|
+
for (const [, blockInput] of sorted) {
|
|
434
|
+
this.evictBlockInput(blockInput);
|
|
404
435
|
itemsToDelete--;
|
|
405
436
|
if (itemsToDelete <= 0) return;
|
|
406
437
|
}
|
|
407
438
|
}
|
|
408
439
|
pruneSetToMax(this.verifiedProposerSignatures, MAX_BLOCK_INPUT_CACHE_SIZE);
|
|
409
440
|
}
|
|
441
|
+
|
|
442
|
+
private evictBlockInput(blockInput: IBlockInput): void {
|
|
443
|
+
// Without forcefully clearing this cache, we would rely on WeakMap to evict memory which is not reliable
|
|
444
|
+
this.serializedCache.delete(blockInput.getSerializedCacheKeys());
|
|
445
|
+
this.blockInputs.delete(blockInput.blockRootHex);
|
|
446
|
+
}
|
|
410
447
|
}
|
|
411
448
|
|
|
412
449
|
enum SeenBlockInputCacheErrorCode {
|
|
@@ -81,7 +81,7 @@ async function validateAggregateAndProof(
|
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
83
|
// [REJECT] `aggregate.data.index == 0` if `block.slot == aggregate.data.slot`.
|
|
84
|
-
const block = chain.forkChoice.
|
|
84
|
+
const block = chain.forkChoice.getBlockDefaultStatus(attData.beaconBlockRoot);
|
|
85
85
|
|
|
86
86
|
// If block is unknown, we don't handle it here. It will throw error later on at `verifyHeadBlockAndTargetRoot()`
|
|
87
87
|
if (block !== null && block.slot === attData.slot && attData.index !== 0) {
|
|
@@ -186,7 +186,7 @@ export async function validateGossipAttestationsSameAttData(
|
|
|
186
186
|
chain.seenAttesters.add(targetEpoch, validatorIndex);
|
|
187
187
|
} else {
|
|
188
188
|
step0ResultOrErrors[oldIndex] = {
|
|
189
|
-
err: new AttestationError(GossipAction.
|
|
189
|
+
err: new AttestationError(GossipAction.REJECT, {
|
|
190
190
|
code: AttestationErrorCode.INVALID_SIGNATURE,
|
|
191
191
|
}),
|
|
192
192
|
};
|
|
@@ -307,7 +307,7 @@ async function validateAttestationNoSignatureCheck(
|
|
|
307
307
|
}
|
|
308
308
|
|
|
309
309
|
// [REJECT] `attestation.data.index == 0` if `block.slot == attestation.data.slot`.
|
|
310
|
-
const block = chain.forkChoice.
|
|
310
|
+
const block = chain.forkChoice.getBlockDefaultStatus(attData.beaconBlockRoot);
|
|
311
311
|
|
|
312
312
|
// block being null will be handled by `verifyHeadBlockAndTargetRoot`
|
|
313
313
|
if (block !== null && block.slot === attSlot && attData.index !== 0) {
|
|
@@ -756,7 +756,7 @@ export function getAttestationDataSigningRoot(config: BeaconConfig, data: phase0
|
|
|
756
756
|
function verifyHeadBlockIsKnown(chain: IBeaconChain, beaconBlockRoot: Root): ProtoBlock {
|
|
757
757
|
// TODO (LH): Enforce a maximum skip distance for unaggregated attestations.
|
|
758
758
|
|
|
759
|
-
const headBlock = chain.forkChoice.
|
|
759
|
+
const headBlock = chain.forkChoice.getBlockDefaultStatus(beaconBlockRoot);
|
|
760
760
|
if (headBlock === null) {
|
|
761
761
|
throw new AttestationError(GossipAction.IGNORE, {
|
|
762
762
|
code: AttestationErrorCode.UNKNOWN_OR_PREFINALIZED_BEACON_BLOCK_ROOT,
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
assertValidAttesterSlashing,
|
|
3
3
|
getAttesterSlashableIndices,
|
|
4
4
|
getAttesterSlashingSignatureSets,
|
|
5
|
+
isSlashableValidator,
|
|
5
6
|
} from "@lodestar/state-transition";
|
|
6
7
|
import {AttesterSlashing} from "@lodestar/types";
|
|
7
8
|
import {AttesterSlashingError, AttesterSlashingErrorCode, GossipAction} from "../errors/index.js";
|
|
@@ -58,6 +59,14 @@ export async function validateAttesterSlashing(
|
|
|
58
59
|
});
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
const currentEpoch = state.epochCtx.epoch;
|
|
63
|
+
if (!intersectingIndices.some((index) => isSlashableValidator(state.validators.getReadonly(index), currentEpoch))) {
|
|
64
|
+
throw new AttesterSlashingError(GossipAction.REJECT, {
|
|
65
|
+
code: AttesterSlashingErrorCode.INVALID,
|
|
66
|
+
error: Error("AttesterSlashing has no slashable validators"),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
61
70
|
const signatureSets = getAttesterSlashingSignatureSets(chain.config, state.slot, attesterSlashing);
|
|
62
71
|
if (!(await chain.bls.verifySignatureSets(signatureSets, {batchable: true, priority: prioritizeBls}))) {
|
|
63
72
|
throw new AttesterSlashingError(GossipAction.REJECT, {
|
|
@@ -78,7 +78,7 @@ export async function validateGossipBlobSidecar(
|
|
|
78
78
|
// already know this block.
|
|
79
79
|
const blockRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(blobSidecar.signedBlockHeader.message);
|
|
80
80
|
const blockHex = toRootHex(blockRoot);
|
|
81
|
-
if (chain.forkChoice.
|
|
81
|
+
if (chain.forkChoice.getBlockHexDefaultStatus(blockHex) !== null) {
|
|
82
82
|
throw new BlobSidecarGossipError(GossipAction.IGNORE, {code: BlobSidecarErrorCode.ALREADY_KNOWN, root: blockHex});
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -89,7 +89,7 @@ export async function validateGossipBlobSidecar(
|
|
|
89
89
|
// gossip and non-gossip sources) (a client MAY queue blocks for processing once the parent block is
|
|
90
90
|
// retrieved).
|
|
91
91
|
const parentRoot = toRootHex(blobSidecar.signedBlockHeader.message.parentRoot);
|
|
92
|
-
const parentBlock = chain.forkChoice.
|
|
92
|
+
const parentBlock = chain.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
93
93
|
if (parentBlock === null) {
|
|
94
94
|
// If fork choice does *not* consider the parent to be a descendant of the finalized block,
|
|
95
95
|
// then there are two more cases:
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
isExecutionEnabled,
|
|
10
10
|
isExecutionStateType,
|
|
11
11
|
} from "@lodestar/state-transition";
|
|
12
|
-
import {SignedBeaconBlock, deneb, gloas} from "@lodestar/types";
|
|
12
|
+
import {SignedBeaconBlock, deneb, gloas, isGloasBeaconBlock} from "@lodestar/types";
|
|
13
13
|
import {byteArrayEquals, sleep, toRootHex} from "@lodestar/utils";
|
|
14
14
|
import {BlockErrorCode, BlockGossipError, GossipAction} from "../errors/index.js";
|
|
15
15
|
import {IBeaconChain} from "../interface.js";
|
|
@@ -56,7 +56,7 @@ export async function validateGossipBlock(
|
|
|
56
56
|
// check, we will load the parent and state from disk only to find out later that we
|
|
57
57
|
// already know this block.
|
|
58
58
|
const blockRoot = toRootHex(config.getForkTypes(blockSlot).BeaconBlock.hashTreeRoot(block));
|
|
59
|
-
if (chain.forkChoice.
|
|
59
|
+
if (chain.forkChoice.getBlockHexDefaultStatus(blockRoot) !== null) {
|
|
60
60
|
throw new BlockGossipError(GossipAction.IGNORE, {code: BlockErrorCode.ALREADY_KNOWN, root: blockRoot});
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -72,7 +72,12 @@ export async function validateGossipBlock(
|
|
|
72
72
|
// [REJECT] The current finalized_checkpoint is an ancestor of block -- i.e.
|
|
73
73
|
// get_ancestor(store, block.parent_root, compute_start_slot_at_epoch(store.finalized_checkpoint.epoch)) == store.finalized_checkpoint.root
|
|
74
74
|
const parentRoot = toRootHex(block.parentRoot);
|
|
75
|
-
const parentBlock =
|
|
75
|
+
const parentBlock = isGloasBeaconBlock(block)
|
|
76
|
+
? chain.forkChoice.getBlockHexAndBlockHash(
|
|
77
|
+
parentRoot,
|
|
78
|
+
toRootHex(block.body.signedExecutionPayloadBid.message.parentBlockHash)
|
|
79
|
+
)
|
|
80
|
+
: chain.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
76
81
|
if (parentBlock === null) {
|
|
77
82
|
// If fork choice does *not* consider the parent to be a descendant of the finalized block,
|
|
78
83
|
// then there are two more cases:
|
|
@@ -104,7 +109,7 @@ export async function validateGossipBlock(
|
|
|
104
109
|
|
|
105
110
|
// [REJECT] The block is from a higher slot than its parent.
|
|
106
111
|
if (parentBlock.slot >= blockSlot) {
|
|
107
|
-
throw new BlockGossipError(GossipAction.
|
|
112
|
+
throw new BlockGossipError(GossipAction.REJECT, {
|
|
108
113
|
code: BlockErrorCode.NOT_LATER_THAN_PARENT,
|
|
109
114
|
parentSlot: parentBlock.slot,
|
|
110
115
|
slot: blockSlot,
|
|
@@ -73,7 +73,7 @@ export async function validateGossipDataColumnSidecar(
|
|
|
73
73
|
// 6) [IGNORE] The sidecar's block's parent (defined by block_header.parent_root) has been seen (via gossip
|
|
74
74
|
// or non-gossip sources)
|
|
75
75
|
const parentRoot = toRootHex(blockHeader.parentRoot);
|
|
76
|
-
const parentBlock = chain.forkChoice.
|
|
76
|
+
const parentBlock = chain.forkChoice.getBlockHexDefaultStatus(parentRoot);
|
|
77
77
|
if (parentBlock === null) {
|
|
78
78
|
// If fork choice does *not* consider the parent to be a descendant of the finalized block,
|
|
79
79
|
// then there are two more cases:
|
|
@@ -113,8 +113,7 @@ async function validateExecutionPayloadBid(
|
|
|
113
113
|
|
|
114
114
|
// [IGNORE] `bid.parent_block_root` is the hash tree root of a known beacon
|
|
115
115
|
// block in fork choice.
|
|
116
|
-
|
|
117
|
-
if (block === null) {
|
|
116
|
+
if (!chain.forkChoice.hasBlock(bid.parentBlockRoot)) {
|
|
118
117
|
throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
|
|
119
118
|
code: ExecutionPayloadBidErrorCode.UNKNOWN_BLOCK_ROOT,
|
|
120
119
|
parentBlockRoot: parentBlockRootHex,
|
|
@@ -37,7 +37,7 @@ async function validateExecutionPayloadEnvelope(
|
|
|
37
37
|
// the block is retrieved).
|
|
38
38
|
// TODO GLOAS: Need to review this, we should queue the envelope for later
|
|
39
39
|
// processing if the block is not yet known, otherwise we would ignore it here
|
|
40
|
-
const block = chain.forkChoice.
|
|
40
|
+
const block = chain.forkChoice.getBlockDefaultStatus(envelope.beaconBlockRoot);
|
|
41
41
|
if (block === null) {
|
|
42
42
|
throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
|
|
43
43
|
code: ExecutionPayloadEnvelopeErrorCode.BLOCK_ROOT_UNKNOWN,
|
|
@@ -79,7 +79,7 @@ async function validateExecutionPayloadEnvelope(
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
if (block.builderIndex
|
|
82
|
+
if (block.builderIndex == null || block.blockHashFromBid == null) {
|
|
83
83
|
// This indicates this block is a pre-gloas block which is wrong
|
|
84
84
|
throw new ExecutionPayloadEnvelopeError(GossipAction.IGNORE, {
|
|
85
85
|
code: ExecutionPayloadEnvelopeErrorCode.CACHE_FAIL,
|
|
@@ -97,11 +97,11 @@ async function validateExecutionPayloadEnvelope(
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// [REJECT] `payload.block_hash == bid.block_hash`
|
|
100
|
-
if (toRootHex(payload.blockHash) !== block.
|
|
100
|
+
if (toRootHex(payload.blockHash) !== block.blockHashFromBid) {
|
|
101
101
|
throw new ExecutionPayloadEnvelopeError(GossipAction.REJECT, {
|
|
102
102
|
code: ExecutionPayloadEnvelopeErrorCode.BLOCK_HASH_MISMATCH,
|
|
103
103
|
envelopeBlockHash: toRootHex(payload.blockHash),
|
|
104
|
-
bidBlockHash: block.
|
|
104
|
+
bidBlockHash: block.blockHashFromBid,
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
|
|
@@ -59,8 +59,7 @@ async function validatePayloadAttestationMessage(
|
|
|
59
59
|
// [IGNORE] The message's block `data.beacon_block_root` has been seen (via
|
|
60
60
|
// gossip or non-gossip sources) (a client MAY queue attestation for processing
|
|
61
61
|
// once the block is retrieved. Note a client might want to request payload after).
|
|
62
|
-
|
|
63
|
-
if (block === null) {
|
|
62
|
+
if (!chain.forkChoice.hasBlock(data.beaconBlockRoot)) {
|
|
64
63
|
throw new PayloadAttestationError(GossipAction.IGNORE, {
|
|
65
64
|
code: PayloadAttestationErrorCode.UNKNOWN_BLOCK_ROOT,
|
|
66
65
|
blockRoot: toRootHex(data.beaconBlockRoot),
|
package/src/constants/network.ts
CHANGED
|
@@ -1461,6 +1461,10 @@ export function createLodestarMetrics(
|
|
|
1461
1461
|
name: "lodestar_seen_block_input_cache_size",
|
|
1462
1462
|
help: "Number of cached BlockInputs",
|
|
1463
1463
|
}),
|
|
1464
|
+
serializedObjectCount: register.gauge({
|
|
1465
|
+
name: "lodestar_seen_block_input_cache_serialized_object_count",
|
|
1466
|
+
help: "Number of serialized objects retained by cached BlockInputs",
|
|
1467
|
+
}),
|
|
1464
1468
|
duplicateBlockCount: register.gauge<{source: BlockInputSource}>({
|
|
1465
1469
|
name: "lodestar_seen_block_input_cache_duplicate_block_count",
|
|
1466
1470
|
help: "Total number of duplicate blocks that pass validation and attempt to be cached but are known",
|
package/src/network/network.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Connection,
|
|
1
|
+
import {Connection, PeerId, PrivateKey} from "@libp2p/interface";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
3
|
import {BeaconConfig} from "@lodestar/config";
|
|
4
4
|
import {LoggerNode} from "@lodestar/logger/node";
|
|
@@ -162,9 +162,6 @@ export class PeerManager {
|
|
|
162
162
|
|
|
163
163
|
// A single map of connected peers with all necessary data to handle PINGs, STATUS, and metrics
|
|
164
164
|
private connectedPeers: Map<PeerIdStr, PeerData>;
|
|
165
|
-
/** Track one in-flight identify call per peer/connection id */
|
|
166
|
-
private readonly identifyInProgress = new Map<PeerIdStr, string>();
|
|
167
|
-
|
|
168
165
|
private opts: PeerManagerOpts;
|
|
169
166
|
private intervals: NodeJS.Timeout[] = [];
|
|
170
167
|
|
|
@@ -195,7 +192,6 @@ export class PeerManager {
|
|
|
195
192
|
|
|
196
193
|
this.libp2p.services.components.events.addEventListener(Libp2pEvent.connectionOpen, this.onLibp2pPeerConnect);
|
|
197
194
|
this.libp2p.services.components.events.addEventListener(Libp2pEvent.connectionClose, this.onLibp2pPeerDisconnect);
|
|
198
|
-
this.libp2p.services.components.events.addEventListener(Libp2pEvent.peerIdentify, this.onPeerIdentify);
|
|
199
195
|
this.networkEventBus.on(NetworkEvent.reqRespRequest, this.onRequest);
|
|
200
196
|
|
|
201
197
|
this.lastStatus = this.statusCache.get();
|
|
@@ -239,7 +235,6 @@ export class PeerManager {
|
|
|
239
235
|
Libp2pEvent.connectionClose,
|
|
240
236
|
this.onLibp2pPeerDisconnect
|
|
241
237
|
);
|
|
242
|
-
this.libp2p.services.components.events.removeEventListener(Libp2pEvent.peerIdentify, this.onPeerIdentify);
|
|
243
238
|
this.networkEventBus.off(NetworkEvent.reqRespRequest, this.onRequest);
|
|
244
239
|
for (const interval of this.intervals) clearInterval(interval);
|
|
245
240
|
}
|
|
@@ -490,25 +485,7 @@ export class PeerManager {
|
|
|
490
485
|
// peers that close identify right after connection open or turn out to be
|
|
491
486
|
// irrelevant.
|
|
492
487
|
if (peerData?.agentVersion === null) {
|
|
493
|
-
|
|
494
|
-
const connection = getConnection(this.libp2p, peerIdStr);
|
|
495
|
-
if (!connection || connection.status !== "open") {
|
|
496
|
-
this.logger.debug("Peer has no open connection for identify", {peerId: prettyPrintPeerId(peer)});
|
|
497
|
-
return;
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
const identifyKey = connection.id;
|
|
501
|
-
if (this.identifyInProgress.get(peerIdStr) === identifyKey) {
|
|
502
|
-
return;
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
this.identifyInProgress.set(peerIdStr, identifyKey);
|
|
506
|
-
void this.identifyPeer(peerIdStr, prettyPrintPeerId(peer), connection, identifyKey).finally(() => {
|
|
507
|
-
// Clear only if this identify attempt is still the active one for this peer
|
|
508
|
-
if (this.identifyInProgress.get(peerIdStr) === identifyKey) {
|
|
509
|
-
this.identifyInProgress.delete(peerIdStr);
|
|
510
|
-
}
|
|
511
|
-
});
|
|
488
|
+
void this.identifyPeer(peer.toString(), prettyPrintPeerId(peer), getConnection(this.libp2p, peer.toString()));
|
|
512
489
|
}
|
|
513
490
|
}
|
|
514
491
|
}
|
|
@@ -867,7 +844,6 @@ export class PeerManager {
|
|
|
867
844
|
|
|
868
845
|
// remove the ping and status timer for the peer
|
|
869
846
|
this.connectedPeers.delete(peerIdStr);
|
|
870
|
-
this.identifyInProgress.delete(peerIdStr);
|
|
871
847
|
|
|
872
848
|
this.logger.verbose(logMessage, logContext);
|
|
873
849
|
this.networkEventBus.emit(NetworkEvent.peerDisconnected, {peer: peerIdStr});
|
|
@@ -885,47 +861,14 @@ export class PeerManager {
|
|
|
885
861
|
}
|
|
886
862
|
}
|
|
887
863
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
* This captures agentVersion from identify-push or successful inbound/outbound identify,
|
|
891
|
-
* even if our explicit identify request failed earlier.
|
|
892
|
-
*/
|
|
893
|
-
private onPeerIdentify = (evt: CustomEvent<IdentifyResult>): void => {
|
|
894
|
-
const {peerId, agentVersion} = evt.detail;
|
|
895
|
-
if (!agentVersion) return;
|
|
896
|
-
|
|
897
|
-
const peerIdStr = peerId.toString();
|
|
898
|
-
const peerData = this.connectedPeers.get(peerIdStr);
|
|
899
|
-
if (!peerData) return;
|
|
900
|
-
|
|
901
|
-
peerData.agentVersion = agentVersion;
|
|
902
|
-
peerData.agentClient = getKnownClientFromAgentVersion(agentVersion);
|
|
903
|
-
this.identifyInProgress.delete(peerIdStr);
|
|
904
|
-
};
|
|
905
|
-
|
|
906
|
-
private async identifyPeer(
|
|
907
|
-
peerIdStr: string,
|
|
908
|
-
peerIdPretty: string,
|
|
909
|
-
connection: Connection,
|
|
910
|
-
identifyKey: string
|
|
911
|
-
): Promise<void> {
|
|
912
|
-
if (this.identifyInProgress.get(peerIdStr) !== identifyKey) {
|
|
913
|
-
return;
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
if (connection.status !== "open") {
|
|
864
|
+
private async identifyPeer(peerIdStr: string, peerIdPretty: string, connection?: Connection): Promise<void> {
|
|
865
|
+
if (!connection || connection.status !== "open") {
|
|
917
866
|
this.logger.debug("Peer has no open connection for identify", {peerId: peerIdPretty});
|
|
918
867
|
return;
|
|
919
868
|
}
|
|
920
869
|
|
|
921
870
|
try {
|
|
922
871
|
const result = await this.libp2p.services.identify.identify(connection);
|
|
923
|
-
|
|
924
|
-
// A newer identify attempt may have superseded this one (e.g. reconnect).
|
|
925
|
-
if (this.identifyInProgress.get(peerIdStr) !== identifyKey) {
|
|
926
|
-
return;
|
|
927
|
-
}
|
|
928
|
-
|
|
929
872
|
const agentVersion = result.agentVersion;
|
|
930
873
|
if (agentVersion) {
|
|
931
874
|
const connectedPeerData = this.connectedPeers.get(peerIdStr);
|
|
@@ -2,6 +2,7 @@ import {routes} from "@lodestar/api";
|
|
|
2
2
|
import {BeaconConfig, ChainForkConfig} from "@lodestar/config";
|
|
3
3
|
import {
|
|
4
4
|
ForkName,
|
|
5
|
+
ForkPostDeneb,
|
|
5
6
|
ForkPostElectra,
|
|
6
7
|
ForkPreElectra,
|
|
7
8
|
ForkSeq,
|
|
@@ -70,6 +71,7 @@ import {validateGossipPayloadAttestationMessage} from "../../chain/validation/pa
|
|
|
70
71
|
import {OpSource} from "../../chain/validatorMonitor.js";
|
|
71
72
|
import {Metrics} from "../../metrics/index.js";
|
|
72
73
|
import {kzgCommitmentToVersionedHash} from "../../util/blobs.js";
|
|
74
|
+
import {getBlobKzgCommitments} from "../../util/dataColumns.ts";
|
|
73
75
|
import {INetworkCore} from "../core/index.js";
|
|
74
76
|
import {NetworkEventBus} from "../events.js";
|
|
75
77
|
import {
|
|
@@ -417,9 +419,11 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
417
419
|
chain.getBlobsTracker.triggerGetBlobs(blockInput);
|
|
418
420
|
} else {
|
|
419
421
|
metrics?.blockInputFetchStats.totalDataAvailableBlockInputs.inc();
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
422
|
+
const blobCount = getBlobKzgCommitments(
|
|
423
|
+
blockInput.forkName,
|
|
424
|
+
signedBlock as SignedBeaconBlock<ForkPostDeneb>
|
|
425
|
+
).length;
|
|
426
|
+
metrics?.blockInputFetchStats.totalDataAvailableBlockInputBlobs.inc(blobCount);
|
|
423
427
|
}
|
|
424
428
|
|
|
425
429
|
chain
|
|
@@ -852,6 +856,11 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
852
856
|
} catch (e) {
|
|
853
857
|
logger.error("Error adding to payloadAttestation pool", {}, e as Error);
|
|
854
858
|
}
|
|
859
|
+
chain.forkChoice.notifyPtcMessages(
|
|
860
|
+
toRootHex(payloadAttestationMessage.data.beaconBlockRoot),
|
|
861
|
+
[validationResult.validatorCommitteeIndex],
|
|
862
|
+
payloadAttestationMessage.data.payloadPresent
|
|
863
|
+
);
|
|
855
864
|
},
|
|
856
865
|
[GossipType.execution_payload_bid]: async ({
|
|
857
866
|
gossipData,
|
|
@@ -47,9 +47,10 @@ export async function* onBeaconBlocksByRange(
|
|
|
47
47
|
|
|
48
48
|
// Non-finalized range of blocks
|
|
49
49
|
if (endSlot > finalizedSlot) {
|
|
50
|
-
const
|
|
50
|
+
const headBlock = chain.forkChoice.getHead();
|
|
51
|
+
const headRoot = headBlock.blockRoot;
|
|
51
52
|
// TODO DENEB: forkChoice should mantain an array of canonical blocks, and change only on reorg
|
|
52
|
-
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot);
|
|
53
|
+
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot, headBlock.payloadStatus);
|
|
53
54
|
// getAllAncestorBlocks response includes the head node, so it's the full chain.
|
|
54
55
|
|
|
55
56
|
// Iterate head chain with ascending block numbers
|
|
@@ -34,9 +34,10 @@ export async function* onBlobSidecarsByRange(
|
|
|
34
34
|
|
|
35
35
|
// Non-finalized range of blobs
|
|
36
36
|
if (endSlot > finalizedSlot) {
|
|
37
|
-
const
|
|
37
|
+
const headBlock = chain.forkChoice.getHead();
|
|
38
|
+
const headRoot = headBlock.blockRoot;
|
|
38
39
|
// TODO DENEB: forkChoice should mantain an array of canonical blocks, and change only on reorg
|
|
39
|
-
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot);
|
|
40
|
+
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot, headBlock.payloadStatus);
|
|
40
41
|
|
|
41
42
|
// Iterate head chain with ascending block numbers
|
|
42
43
|
for (let i = headChain.length - 1; i >= 0; i--) {
|
|
@@ -20,7 +20,7 @@ export async function* onBlobSidecarsByRoot(
|
|
|
20
20
|
for (const blobIdentifier of requestBody) {
|
|
21
21
|
const {blockRoot, index} = blobIdentifier;
|
|
22
22
|
const blockRootHex = toRootHex(blockRoot);
|
|
23
|
-
const block = chain.forkChoice.
|
|
23
|
+
const block = chain.forkChoice.getBlockHexDefaultStatus(blockRootHex);
|
|
24
24
|
|
|
25
25
|
// NOTE: Only support non-finalized blocks.
|
|
26
26
|
// SPEC: Clients MUST support requesting blocks and sidecars since the latest finalized epoch.
|
|
@@ -78,8 +78,9 @@ export async function* onDataColumnSidecarsByRange(
|
|
|
78
78
|
|
|
79
79
|
// Non-finalized range of columns
|
|
80
80
|
if (endSlot > finalizedSlot) {
|
|
81
|
-
const
|
|
82
|
-
const
|
|
81
|
+
const headBlock = chain.forkChoice.getHead();
|
|
82
|
+
const headRoot = headBlock.blockRoot;
|
|
83
|
+
const headChain = chain.forkChoice.getAllAncestorBlocks(headRoot, headBlock.payloadStatus);
|
|
83
84
|
|
|
84
85
|
// Iterate head chain with ascending block numbers
|
|
85
86
|
for (let i = headChain.length - 1; i >= 0; i--) {
|
|
@@ -34,7 +34,7 @@ export async function* onDataColumnSidecarsByRoot(
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
const blockRootHex = toRootHex(blockRoot);
|
|
37
|
-
const block = chain.forkChoice.
|
|
37
|
+
const block = chain.forkChoice.getBlockHexDefaultStatus(blockRootHex);
|
|
38
38
|
// If the block is not in fork choice, it may be finalized. Attempt to find its slot in block archive
|
|
39
39
|
const slot = block ? block.slot : await db.blockArchive.getSlotByRoot(blockRoot);
|
|
40
40
|
|