@lodestar/beacon-node 1.44.0-dev.d0a9d4a547 → 1.44.0-dev.d730eae4b6
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/config/constants.d.ts +1 -0
- package/lib/api/impl/config/constants.d.ts.map +1 -1
- package/lib/api/impl/config/constants.js +2 -1
- package/lib/api/impl/config/constants.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +69 -12
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +0 -4
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +0 -1
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/queued.d.ts +0 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +0 -4
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +0 -5
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +0 -5
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -4
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +5 -2
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +0 -2
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/stateCache/types.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +749 -2
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +9 -5
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +8 -3
- 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/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts +2 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +16 -6
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/index.js +2 -2
- package/lib/network/reqresp/handlers/index.js.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js +14 -3
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
- package/package.json +14 -16
- package/src/api/impl/config/constants.ts +2 -0
- package/src/api/impl/debug/index.ts +73 -12
- package/src/chain/archiveStore/archiveStore.ts +0 -5
- package/src/chain/regen/interface.ts +0 -1
- package/src/chain/regen/queued.ts +0 -5
- package/src/chain/stateCache/fifoBlockStateCache.ts +0 -6
- package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
- package/src/chain/stateCache/types.ts +0 -2
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +12 -5
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +11 -3
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -1
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +22 -6
- package/src/network/reqresp/handlers/index.ts +2 -2
- package/src/network/reqresp/utils/dataColumnResponseValidation.ts +13 -3
|
@@ -30,7 +30,6 @@ export interface BlockStateCache {
|
|
|
30
30
|
clear(): void;
|
|
31
31
|
size: number;
|
|
32
32
|
prune(headStateRootHex: RootHex): void;
|
|
33
|
-
deleteAllBeforeEpoch(finalizedEpoch: Epoch): void;
|
|
34
33
|
dumpSummary(): routes.lodestar.StateCacheItem[];
|
|
35
34
|
/** Expose beacon states stored in cache. Use with caution */
|
|
36
35
|
getStates(): IterableIterator<IBeaconStateView>;
|
|
@@ -67,7 +66,6 @@ export interface CheckpointStateCache {
|
|
|
67
66
|
getOrReloadLatest(rootHex: RootHex, maxEpoch: Epoch): Promise<IBeaconStateView | null>;
|
|
68
67
|
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
|
|
69
68
|
prune(finalizedEpoch: Epoch, justifiedEpoch: Epoch): void;
|
|
70
|
-
pruneFinalized(finalizedEpoch: Epoch): void;
|
|
71
69
|
processState(blockRootHex: RootHex, state: IBeaconStateView): Promise<number>;
|
|
72
70
|
clear(): void;
|
|
73
71
|
dumpSummary(): routes.lodestar.StateCacheItem[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {PeerId} from "@libp2p/interface";
|
|
2
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
|
-
import {GENESIS_SLOT, isForkPostDeneb
|
|
3
|
+
import {GENESIS_SLOT, isForkPostDeneb} from "@lodestar/params";
|
|
4
4
|
import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
|
|
5
5
|
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
6
6
|
import {deneb, phase0} from "@lodestar/types";
|
|
@@ -29,13 +29,20 @@ export async function* onBeaconBlocksByRange(
|
|
|
29
29
|
// starts above it to avoid duplicate yields. See archiveBlocks.ts for the migration logic.
|
|
30
30
|
const archiveMaxSlot = finalizedSlot;
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
// endSlot is exclusive, so highest served slot is endSlot - 1.
|
|
33
|
+
// Throw only when the entire requested range is below earliestAvailableSlot.
|
|
34
|
+
if (endSlot - 1 < chain.earliestAvailableSlot) {
|
|
35
|
+
chain.logger.verbose("Peer requested range before earliestAvailableSlot for BeaconBlocksByRange", {
|
|
35
36
|
peer: prettyPrintPeerId(peerId),
|
|
36
37
|
client: peerClient,
|
|
38
|
+
startSlot,
|
|
39
|
+
count,
|
|
40
|
+
earliestAvailableSlot: chain.earliestAvailableSlot,
|
|
37
41
|
});
|
|
38
|
-
|
|
42
|
+
throw new ResponseError(
|
|
43
|
+
RespStatus.RESOURCE_UNAVAILABLE,
|
|
44
|
+
`Requested range is before earliestAvailableSlot startSlot=${startSlot} count=${count} earliestAvailableSlot=${chain.earliestAvailableSlot}`
|
|
45
|
+
);
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
// Finalized range of blocks
|
|
@@ -34,12 +34,20 @@ export async function* onDataColumnSidecarsByRange(
|
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
// endSlot is exclusive, so highest served slot is endSlot - 1.
|
|
38
|
+
// Throw only when the entire requested range is below earliestAvailableSlot.
|
|
39
|
+
if (endSlot - 1 < chain.earliestAvailableSlot) {
|
|
40
|
+
chain.logger.verbose("Peer requested range before earliestAvailableSlot for DataColumnSidecarsByRange", {
|
|
39
41
|
peer: prettyPrintPeerId(peerId),
|
|
40
42
|
client: peerClient,
|
|
43
|
+
startSlot,
|
|
44
|
+
count,
|
|
45
|
+
earliestAvailableSlot: chain.earliestAvailableSlot,
|
|
41
46
|
});
|
|
42
|
-
|
|
47
|
+
throw new ResponseError(
|
|
48
|
+
RespStatus.RESOURCE_UNAVAILABLE,
|
|
49
|
+
`Requested range is before earliestAvailableSlot startSlot=${startSlot} count=${count} earliestAvailableSlot=${chain.earliestAvailableSlot}`
|
|
50
|
+
);
|
|
43
51
|
}
|
|
44
52
|
|
|
45
53
|
const finalized = db.dataColumnSidecarArchive;
|
|
@@ -30,7 +30,7 @@ export async function* onDataColumnSidecarsByRoot(
|
|
|
30
30
|
const {blockRoot, columns: requestedColumns} = dataColumnsByRootIdentifier;
|
|
31
31
|
const availableColumns = validateRequestedDataColumns(chain, requestedColumns);
|
|
32
32
|
if (availableColumns.length === 0) {
|
|
33
|
-
|
|
33
|
+
continue;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
const blockRootHex = toRootHex(blockRoot);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {PeerId} from "@libp2p/interface";
|
|
1
2
|
import {ChainConfig} from "@lodestar/config";
|
|
2
3
|
import {PayloadStatus} from "@lodestar/fork-choice";
|
|
3
4
|
import {GENESIS_SLOT} from "@lodestar/params";
|
|
@@ -6,23 +7,38 @@ import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
|
6
7
|
import {gloas} from "@lodestar/types";
|
|
7
8
|
import {IBeaconChain} from "../../../chain/index.js";
|
|
8
9
|
import {IBeaconDb} from "../../../db/index.js";
|
|
10
|
+
import {prettyPrintPeerId} from "../../util.js";
|
|
9
11
|
|
|
10
12
|
export async function* onExecutionPayloadEnvelopesByRange(
|
|
11
13
|
request: gloas.ExecutionPayloadEnvelopesByRangeRequest,
|
|
12
14
|
chain: IBeaconChain,
|
|
13
|
-
db: IBeaconDb
|
|
15
|
+
db: IBeaconDb,
|
|
16
|
+
peerId: PeerId,
|
|
17
|
+
peerClient: string
|
|
14
18
|
): AsyncIterable<ResponseOutgoing> {
|
|
15
19
|
const {startSlot, count} = validateExecutionPayloadEnvelopesByRangeRequest(chain.config, request);
|
|
16
20
|
const endSlot = startSlot + count;
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
// endSlot is exclusive, so highest served slot is endSlot - 1.
|
|
23
|
+
// Throw only when the entire requested range is below earliestAvailableSlot.
|
|
24
|
+
if (endSlot - 1 < chain.earliestAvailableSlot) {
|
|
25
|
+
chain.logger.verbose("Peer requested range before earliestAvailableSlot for ExecutionPayloadEnvelopesByRange", {
|
|
26
|
+
peer: prettyPrintPeerId(peerId),
|
|
27
|
+
client: peerClient,
|
|
28
|
+
startSlot,
|
|
29
|
+
count,
|
|
30
|
+
earliestAvailableSlot: chain.earliestAvailableSlot,
|
|
31
|
+
});
|
|
32
|
+
throw new ResponseError(
|
|
33
|
+
RespStatus.RESOURCE_UNAVAILABLE,
|
|
34
|
+
`Requested range is before earliestAvailableSlot startSlot=${startSlot} count=${count} earliestAvailableSlot=${chain.earliestAvailableSlot}`
|
|
35
|
+
);
|
|
20
36
|
}
|
|
21
37
|
|
|
22
38
|
const finalized = db.executionPayloadEnvelopeArchive;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// in the next finalization run
|
|
39
|
+
// Use the finalized block's actual slot as the checkpoint epoch-boundary slot may be skipped
|
|
40
|
+
const finalizedSlot = chain.forkChoice.getFinalizedBlock().slot;
|
|
41
|
+
// The finalized block's envelope stays in the hot db until the next finalization run
|
|
26
42
|
const archiveMaxSlot = finalizedSlot - 1;
|
|
27
43
|
|
|
28
44
|
// Finalized range of envelopes
|
|
@@ -74,9 +74,9 @@ export function getReqRespHandlers({db, chain}: {db: IBeaconDb; chain: IBeaconCh
|
|
|
74
74
|
const body = ExecutionPayloadEnvelopesByRootRequestType(chain.config).deserialize(req.data);
|
|
75
75
|
return onExecutionPayloadEnvelopesByRoot(body, chain, db, peerId, peerClient);
|
|
76
76
|
},
|
|
77
|
-
[ReqRespMethod.ExecutionPayloadEnvelopesByRange]: (req) => {
|
|
77
|
+
[ReqRespMethod.ExecutionPayloadEnvelopesByRange]: (req, peerId, peerClient) => {
|
|
78
78
|
const body = ssz.gloas.ExecutionPayloadEnvelopesByRangeRequest.deserialize(req.data);
|
|
79
|
-
return onExecutionPayloadEnvelopesByRange(body, chain, db);
|
|
79
|
+
return onExecutionPayloadEnvelopesByRange(body, chain, db, peerId, peerClient);
|
|
80
80
|
},
|
|
81
81
|
|
|
82
82
|
[ReqRespMethod.LightClientBootstrap]: (req) => {
|
|
@@ -79,9 +79,19 @@ export function validateRequestedDataColumns(chain: IBeaconChain, requestedColum
|
|
|
79
79
|
throw new ResponseError(RespStatus.INVALID_REQUEST, "dataColumnSidecar requested without column indices");
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
const custodyColumns = chain.custodyConfig
|
|
83
|
-
const availableColumns =
|
|
84
|
-
const missingColumns =
|
|
82
|
+
const {custodyColumns, custodyColumnsIndex} = chain.custodyConfig;
|
|
83
|
+
const availableColumns: ColumnIndex[] = [];
|
|
84
|
+
const missingColumns: ColumnIndex[] = [];
|
|
85
|
+
for (const c of requestedColumns) {
|
|
86
|
+
// `c` is peer-controlled and SSZ-deserialized as `uint64`, so it may exceed
|
|
87
|
+
// `NUMBER_OF_COLUMNS - 1`; `Uint8Array` returns `undefined` for OOB reads,
|
|
88
|
+
// and `undefined !== 0` would silently classify OOB indices as custodied.
|
|
89
|
+
if ((custodyColumnsIndex[c] ?? 0) !== 0) {
|
|
90
|
+
availableColumns.push(c);
|
|
91
|
+
} else {
|
|
92
|
+
missingColumns.push(c);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
85
95
|
|
|
86
96
|
if (missingColumns.length > 0) {
|
|
87
97
|
chain.logger.verbose("Requested dataColumnSidecar for non-custody columns", {
|