@lodestar/beacon-node 1.41.0-dev.09945f6589 → 1.41.0-dev.0df187678b
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/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +24 -8
- 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/blocks/blockInput/types.d.ts +11 -0
- package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +1 -1
- package/lib/chain/blocks/importBlock.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 +101 -96
- 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 +5 -5
- 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/regen/regen.js +1 -1
- package/lib/chain/regen/regen.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/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/package.json +26 -26
- package/src/api/impl/validator/index.ts +24 -10
- package/src/chain/archiveStore/archiveStore.ts +5 -5
- package/src/chain/archiveStore/utils/archiveBlocks.ts +4 -5
- package/src/chain/blocks/blockInput/types.ts +12 -0
- package/src/chain/blocks/importBlock.ts +1 -1
- package/src/chain/blocks/writeBlockInputToDb.ts +119 -101
- package/src/chain/chain.ts +20 -8
- package/src/chain/emitter.ts +3 -3
- package/src/chain/regen/regen.ts +1 -1
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +3 -2
- package/src/network/reqresp/handlers/blobSidecarsByRange.ts +3 -2
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +3 -2
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {ForkPostDeneb, isForkPostDeneb} from "@lodestar/params";
|
|
2
|
+
import {SignedBeaconBlock} from "@lodestar/types";
|
|
3
|
+
import {fromHex, toRootHex} from "@lodestar/utils";
|
|
4
|
+
import {getBlobKzgCommitments} from "../../util/dataColumns.js";
|
|
3
5
|
import {BeaconChain} from "../chain.js";
|
|
4
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
IBlockInput,
|
|
8
|
+
IDataColumnsInput,
|
|
9
|
+
isBlockInputBlobs,
|
|
10
|
+
isBlockInputColumns,
|
|
11
|
+
isBlockInputNoData,
|
|
12
|
+
} from "./blockInput/index.js";
|
|
5
13
|
import {BLOB_AVAILABILITY_TIMEOUT} from "./verifyBlocksDataAvailability.js";
|
|
6
14
|
|
|
7
15
|
/**
|
|
@@ -10,129 +18,139 @@ import {BLOB_AVAILABILITY_TIMEOUT} from "./verifyBlocksDataAvailability.js";
|
|
|
10
18
|
*
|
|
11
19
|
* This operation may be performed before, during or after importing to the fork-choice. As long as errors
|
|
12
20
|
* are handled properly for eventual consistency.
|
|
21
|
+
*
|
|
22
|
+
* Block+blobs (pre-fulu) and data columns (fulu+) are written in parallel.
|
|
13
23
|
*/
|
|
14
|
-
export async function writeBlockInputToDb(this: BeaconChain,
|
|
15
|
-
const
|
|
16
|
-
// track slots for logging
|
|
17
|
-
const slots: number[] = [];
|
|
18
|
-
|
|
19
|
-
for (const blockInput of blocksInputs) {
|
|
20
|
-
const block = blockInput.getBlock();
|
|
21
|
-
const slot = block.message.slot;
|
|
22
|
-
slots.push(slot);
|
|
23
|
-
const blockRoot = this.config.getForkTypes(block.message.slot).BeaconBlock.hashTreeRoot(block.message);
|
|
24
|
-
const blockRootHex = toRootHex(blockRoot);
|
|
25
|
-
const blockBytes = this.serializedCache.get(block);
|
|
26
|
-
if (blockBytes) {
|
|
27
|
-
// skip serializing data if we already have it
|
|
28
|
-
this.metrics?.importBlock.persistBlockWithSerializedDataCount.inc();
|
|
29
|
-
fnPromises.push(this.db.block.putBinary(this.db.block.getId(block), blockBytes));
|
|
30
|
-
} else {
|
|
31
|
-
this.metrics?.importBlock.persistBlockNoSerializedDataCount.inc();
|
|
32
|
-
fnPromises.push(this.db.block.add(block));
|
|
33
|
-
}
|
|
24
|
+
export async function writeBlockInputToDb(this: BeaconChain, blockInput: IBlockInput): Promise<void> {
|
|
25
|
+
const promises: Promise<void>[] = [writeBlockAndBlobsToDb.call(this, blockInput)];
|
|
34
26
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
inputType: blockInput.type,
|
|
39
|
-
});
|
|
27
|
+
if (isBlockInputColumns(blockInput)) {
|
|
28
|
+
promises.push(writeDataColumnsToDb.call(this, blockInput));
|
|
29
|
+
}
|
|
40
30
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
await Promise.all(promises);
|
|
32
|
+
this.logger.debug("Persisted blockInput to db", {slot: blockInput.slot, root: blockInput.blockRootHex});
|
|
33
|
+
}
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
35
|
+
async function writeBlockAndBlobsToDb(this: BeaconChain, blockInput: IBlockInput): Promise<void> {
|
|
36
|
+
const block = blockInput.getBlock();
|
|
37
|
+
const slot = block.message.slot;
|
|
38
|
+
const blockRoot = this.config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block.message);
|
|
39
|
+
const blockRootHex = toRootHex(blockRoot);
|
|
40
|
+
const numBlobs = isForkPostDeneb(blockInput.forkName)
|
|
41
|
+
? getBlobKzgCommitments(blockInput.forkName, block as SignedBeaconBlock<ForkPostDeneb>).length
|
|
42
|
+
: undefined;
|
|
43
|
+
const fnPromises: Promise<void>[] = [];
|
|
55
44
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
45
|
+
const blockBytes = this.serializedCache.get(block);
|
|
46
|
+
if (blockBytes) {
|
|
47
|
+
// skip serializing data if we already have it
|
|
48
|
+
this.metrics?.importBlock.persistBlockWithSerializedDataCount.inc();
|
|
49
|
+
fnPromises.push(this.db.block.putBinary(this.db.block.getId(block), blockBytes));
|
|
50
|
+
} else {
|
|
51
|
+
this.metrics?.importBlock.persistBlockNoSerializedDataCount.inc();
|
|
52
|
+
fnPromises.push(this.db.block.add(block));
|
|
53
|
+
}
|
|
64
54
|
|
|
65
|
-
|
|
66
|
-
if (dataColumnSidecars.length !== dataColumnsLen) {
|
|
67
|
-
this.logger.debug(
|
|
68
|
-
`Invalid dataColumnSidecars=${dataColumnSidecars.length} for custody expected custodyColumnsLen=${dataColumnsLen}`
|
|
69
|
-
);
|
|
70
|
-
}
|
|
55
|
+
this.logger.debug("Persist block to hot DB", {slot, root: blockRootHex, inputType: blockInput.type, numBlobs});
|
|
71
56
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
if (serialized) {
|
|
78
|
-
binaryPuts.push({key: dataColumnSidecar.index, value: serialized});
|
|
79
|
-
} else {
|
|
80
|
-
nonbinaryPuts.push(dataColumnSidecar);
|
|
57
|
+
if (isBlockInputBlobs(blockInput)) {
|
|
58
|
+
fnPromises.push(
|
|
59
|
+
(async () => {
|
|
60
|
+
if (!blockInput.hasAllData()) {
|
|
61
|
+
await blockInput.waitForAllData(BLOB_AVAILABILITY_TIMEOUT);
|
|
81
62
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
} else if (isBlockInputBlobs(blockInput)) {
|
|
93
|
-
const blobSidecars = blockInput.getBlobs();
|
|
94
|
-
fnPromises.push(this.db.blobSidecars.add({blockRoot, slot: block.message.slot, blobSidecars}));
|
|
95
|
-
this.logger.debug("Persisted blobSidecars to hot DB", {
|
|
96
|
-
blobsLen: blobSidecars.length,
|
|
97
|
-
slot: block.message.slot,
|
|
98
|
-
root: blockRootHex,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
63
|
+
const blobSidecars = blockInput.getBlobs();
|
|
64
|
+
await this.db.blobSidecars.add({blockRoot, slot, blobSidecars});
|
|
65
|
+
this.logger.debug("Persisted blobSidecars to hot DB", {
|
|
66
|
+
slot,
|
|
67
|
+
root: blockRootHex,
|
|
68
|
+
numBlobs: blobSidecars.length,
|
|
69
|
+
});
|
|
70
|
+
})()
|
|
71
|
+
);
|
|
72
|
+
}
|
|
101
73
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
74
|
+
await Promise.all(fnPromises);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Persists data columns to DB for a given block. Accepts a narrow sub-interface of IBlockInput
|
|
79
|
+
* so it can be reused across forks (e.g. Fulu, Gloas).
|
|
80
|
+
*
|
|
81
|
+
* NOTE: Old data is pruned on archive.
|
|
82
|
+
*/
|
|
83
|
+
export async function writeDataColumnsToDb(this: BeaconChain, blockInput: IDataColumnsInput): Promise<void> {
|
|
84
|
+
const {slot, blockRootHex} = blockInput;
|
|
85
|
+
const blockRoot = fromHex(blockRootHex);
|
|
86
|
+
|
|
87
|
+
if (!blockInput.hasComputedAllData()) {
|
|
88
|
+
// Supernodes may only have a subset of the data columns by the time the block begins to be imported
|
|
89
|
+
// because full data availability can be assumed after NUMBER_OF_COLUMNS / 2 columns are available.
|
|
90
|
+
// Here, however, all data columns must be fully available/reconstructed before persisting to the DB.
|
|
91
|
+
await blockInput.waitForComputedAllData(BLOB_AVAILABILITY_TIMEOUT).catch(() => {
|
|
92
|
+
this.logger.debug("Failed to wait for computed all data", {slot, blockRoot: blockRootHex});
|
|
106
93
|
});
|
|
107
94
|
}
|
|
95
|
+
|
|
96
|
+
const {custodyColumns} = this.custodyConfig;
|
|
97
|
+
const dataColumnSidecars = blockInput.getCustodyColumns();
|
|
98
|
+
|
|
99
|
+
const binaryPuts: {key: number; value: Uint8Array}[] = [];
|
|
100
|
+
const nonbinaryPuts = [];
|
|
101
|
+
for (const dataColumnSidecar of dataColumnSidecars) {
|
|
102
|
+
// skip reserializing column if we already have it
|
|
103
|
+
const serialized = this.serializedCache.get(dataColumnSidecar);
|
|
104
|
+
if (serialized) {
|
|
105
|
+
binaryPuts.push({key: dataColumnSidecar.index, value: serialized});
|
|
106
|
+
} else {
|
|
107
|
+
nonbinaryPuts.push(dataColumnSidecar);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await Promise.all([
|
|
112
|
+
this.db.dataColumnSidecar.putManyBinary(blockRoot, binaryPuts),
|
|
113
|
+
this.db.dataColumnSidecar.putMany(blockRoot, nonbinaryPuts),
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
this.logger.debug("Persisted dataColumnSidecars to hot DB", {
|
|
117
|
+
slot,
|
|
118
|
+
root: blockRootHex,
|
|
119
|
+
dataColumnSidecars: dataColumnSidecars.length,
|
|
120
|
+
custodyColumns: custodyColumns.length,
|
|
121
|
+
numBlobs: dataColumnSidecars[0]?.column.length,
|
|
122
|
+
});
|
|
108
123
|
}
|
|
109
124
|
|
|
110
|
-
export async function
|
|
125
|
+
export async function persistBlockInput(this: BeaconChain, blockInput: IBlockInput): Promise<void> {
|
|
111
126
|
await writeBlockInputToDb
|
|
112
|
-
.call(this,
|
|
127
|
+
.call(this, blockInput)
|
|
113
128
|
.catch((e) => {
|
|
114
129
|
this.logger.debug(
|
|
115
130
|
"Error persisting block input in hot db",
|
|
116
131
|
{
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
root: blockInputs[0].blockRootHex,
|
|
132
|
+
slot: blockInput.slot,
|
|
133
|
+
root: blockInput.blockRootHex,
|
|
120
134
|
},
|
|
121
135
|
e
|
|
122
136
|
);
|
|
123
137
|
})
|
|
124
138
|
.finally(() => {
|
|
125
|
-
|
|
126
|
-
this.seenBlockInputCache.prune(blockInput.blockRootHex);
|
|
127
|
-
}
|
|
139
|
+
this.seenBlockInputCache.prune(blockInput.blockRootHex);
|
|
128
140
|
// Without forcefully clearing this cache, we would rely on WeakMap to evict memory which is not reliable.
|
|
129
141
|
// Clear here (after the DB write) so that writeBlockInputToDb can still use the cached serialized bytes.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
142
|
+
//
|
|
143
|
+
// For Gloas (BlockInputNoData), the execution payload and columns arrive separately after the beacon block.
|
|
144
|
+
// Do NOT clear the cache here — it must remain available for writeDataColumnsToDb when the payload arrives.
|
|
145
|
+
// The cache is cleared in the Gloas payload persistence path instead.
|
|
146
|
+
if (!isBlockInputNoData(blockInput)) {
|
|
147
|
+
// TODO: enhance this SerializedCache for Gloas because payload may not come
|
|
148
|
+
// see https://github.com/ChainSafe/lodestar/pull/8974#discussion_r2885598229
|
|
149
|
+
this.serializedCache.clear();
|
|
136
150
|
}
|
|
151
|
+
this.logger.debug("Pruned block input", {
|
|
152
|
+
slot: blockInput.slot,
|
|
153
|
+
root: blockInput.blockRootHex,
|
|
154
|
+
});
|
|
137
155
|
});
|
|
138
156
|
}
|
package/src/chain/chain.ts
CHANGED
|
@@ -2,7 +2,13 @@ import path from "node:path";
|
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
3
|
import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
|
|
4
4
|
import {BeaconConfig} from "@lodestar/config";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
CheckpointWithHex,
|
|
7
|
+
CheckpointWithPayloadStatus,
|
|
8
|
+
IForkChoice,
|
|
9
|
+
ProtoBlock,
|
|
10
|
+
UpdateHeadOpt,
|
|
11
|
+
} from "@lodestar/fork-choice";
|
|
6
12
|
import {LoggerNode} from "@lodestar/logger/node";
|
|
7
13
|
import {
|
|
8
14
|
BUILDER_INDEX_SELF_BUILD,
|
|
@@ -77,7 +83,7 @@ import {CheckpointBalancesCache} from "./balancesCache.js";
|
|
|
77
83
|
import {BeaconProposerCache} from "./beaconProposerCache.js";
|
|
78
84
|
import {IBlockInput, isBlockInputBlobs, isBlockInputColumns} from "./blocks/blockInput/index.js";
|
|
79
85
|
import {BlockProcessor, ImportBlockOpts} from "./blocks/index.js";
|
|
80
|
-
import {
|
|
86
|
+
import {persistBlockInput} from "./blocks/writeBlockInputToDb.ts";
|
|
81
87
|
import {BlsMultiThreadWorkerPool, BlsSingleThreadVerifier, IBlsVerifier} from "./bls/index.js";
|
|
82
88
|
import {ColumnReconstructionTracker} from "./ColumnReconstructionTracker.js";
|
|
83
89
|
import {ChainEvent, ChainEventEmitter} from "./emitter.js";
|
|
@@ -164,7 +170,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
164
170
|
readonly lightClientServer?: LightClientServer;
|
|
165
171
|
readonly reprocessController: ReprocessController;
|
|
166
172
|
readonly archiveStore: ArchiveStore;
|
|
167
|
-
readonly unfinalizedBlockWrites: JobItemQueue<[IBlockInput
|
|
173
|
+
readonly unfinalizedBlockWrites: JobItemQueue<[IBlockInput], void>;
|
|
168
174
|
|
|
169
175
|
// Ops pool
|
|
170
176
|
readonly attestationPool: AttestationPool;
|
|
@@ -429,7 +435,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
429
435
|
);
|
|
430
436
|
|
|
431
437
|
this.unfinalizedBlockWrites = new JobItemQueue(
|
|
432
|
-
|
|
438
|
+
persistBlockInput.bind(this),
|
|
433
439
|
{
|
|
434
440
|
maxLength: DEFAULT_MAX_PENDING_UNFINALIZED_BLOCK_WRITES,
|
|
435
441
|
signal,
|
|
@@ -1186,7 +1192,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1186
1192
|
* @param blockState state that declares justified checkpoint `checkpoint`
|
|
1187
1193
|
*/
|
|
1188
1194
|
private justifiedBalancesGetter(
|
|
1189
|
-
checkpoint:
|
|
1195
|
+
checkpoint: CheckpointWithPayloadStatus,
|
|
1190
1196
|
blockState: CachedBeaconStateAllForks
|
|
1191
1197
|
): EffectiveBalanceIncrements {
|
|
1192
1198
|
this.metrics?.balancesCache.requests.inc();
|
|
@@ -1225,7 +1231,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1225
1231
|
* @param blockState state that declares justified checkpoint `checkpoint`
|
|
1226
1232
|
*/
|
|
1227
1233
|
private closestJustifiedBalancesStateToCheckpoint(
|
|
1228
|
-
checkpoint:
|
|
1234
|
+
checkpoint: CheckpointWithPayloadStatus,
|
|
1229
1235
|
blockState: CachedBeaconStateAllForks
|
|
1230
1236
|
): {state: CachedBeaconStateAllForks; stateId: string; shouldWarn: boolean} {
|
|
1231
1237
|
const state = this.regen.getCheckpointStateSync(checkpoint);
|
|
@@ -1239,7 +1245,10 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1239
1245
|
}
|
|
1240
1246
|
|
|
1241
1247
|
// Find a state in the same branch of checkpoint at same epoch. Balances should exactly the same
|
|
1242
|
-
for (const descendantBlock of this.forkChoice.forwardIterateDescendants(
|
|
1248
|
+
for (const descendantBlock of this.forkChoice.forwardIterateDescendants(
|
|
1249
|
+
checkpoint.rootHex,
|
|
1250
|
+
checkpoint.payloadStatus
|
|
1251
|
+
)) {
|
|
1243
1252
|
if (computeEpochAtSlot(descendantBlock.slot) === checkpoint.epoch) {
|
|
1244
1253
|
const descendantBlockState = this.regen.getStateSync(descendantBlock.stateRoot);
|
|
1245
1254
|
if (descendantBlockState) {
|
|
@@ -1255,7 +1264,10 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1255
1264
|
|
|
1256
1265
|
// Find a state in the same branch of checkpoint at a latter epoch. Balances are not the same, but should be close
|
|
1257
1266
|
// Note: must call .forwardIterateDescendants() again since nodes are not sorted
|
|
1258
|
-
for (const descendantBlock of this.forkChoice.forwardIterateDescendants(
|
|
1267
|
+
for (const descendantBlock of this.forkChoice.forwardIterateDescendants(
|
|
1268
|
+
checkpoint.rootHex,
|
|
1269
|
+
checkpoint.payloadStatus
|
|
1270
|
+
)) {
|
|
1259
1271
|
if (computeEpochAtSlot(descendantBlock.slot) > checkpoint.epoch) {
|
|
1260
1272
|
const descendantBlockState = this.regen.getStateSync(descendantBlock.stateRoot);
|
|
1261
1273
|
if (descendantBlockState) {
|
package/src/chain/emitter.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {EventEmitter} from "node:events";
|
|
2
2
|
import {StrictEventEmitter} from "strict-event-emitter-types";
|
|
3
3
|
import {routes} from "@lodestar/api";
|
|
4
|
-
import {
|
|
4
|
+
import {CheckpointWithPayloadStatus} from "@lodestar/fork-choice";
|
|
5
5
|
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
|
|
6
6
|
import {DataColumnSidecars, RootHex, deneb, phase0} from "@lodestar/types";
|
|
7
7
|
import {PeerIdStr} from "../util/peerId.js";
|
|
@@ -83,8 +83,8 @@ export type ChainEventData = {
|
|
|
83
83
|
export type IChainEvents = ApiEvents & {
|
|
84
84
|
[ChainEvent.checkpoint]: (checkpoint: phase0.Checkpoint, state: CachedBeaconStateAllForks) => void;
|
|
85
85
|
|
|
86
|
-
[ChainEvent.forkChoiceJustified]: (checkpoint:
|
|
87
|
-
[ChainEvent.forkChoiceFinalized]: (checkpoint:
|
|
86
|
+
[ChainEvent.forkChoiceJustified]: (checkpoint: CheckpointWithPayloadStatus) => void;
|
|
87
|
+
[ChainEvent.forkChoiceFinalized]: (checkpoint: CheckpointWithPayloadStatus) => void;
|
|
88
88
|
|
|
89
89
|
[ChainEvent.updateTargetCustodyGroupCount]: (targetGroupCount: number) => void;
|
|
90
90
|
|
package/src/chain/regen/regen.ts
CHANGED
|
@@ -158,7 +158,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
|
|
|
158
158
|
|
|
159
159
|
const getSeedStateTimer = this.modules.metrics?.regenGetState.getSeedState.startTimer({caller});
|
|
160
160
|
// iterateAncestorBlocks only returns ancestor blocks, not the block itself
|
|
161
|
-
for (const b of this.modules.forkChoice.iterateAncestorBlocks(block.blockRoot)) {
|
|
161
|
+
for (const b of this.modules.forkChoice.iterateAncestorBlocks(block.blockRoot, block.payloadStatus)) {
|
|
162
162
|
state = this.modules.blockStateCache.get(b.stateRoot);
|
|
163
163
|
if (state) {
|
|
164
164
|
break;
|
|
@@ -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--) {
|
|
@@ -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--) {
|