@lodestar/beacon-node 1.47.0-dev.9572bcc698 → 1.47.0-dev.9ba9a5ce85
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 +41 -10
- package/lib/api/impl/beacon/blocks/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 +237 -49
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/api/impl/validator/utils.js +1 -1
- package/lib/api/impl/validator/utils.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +1 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/blocks/index.js +7 -7
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +5 -2
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/chain.d.ts +5 -2
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +6 -2
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +5 -0
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +1 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +4 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/executionPayloadBidPool.d.ts +7 -2
- package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
- package/lib/chain/opPools/executionPayloadBidPool.js +4 -4
- package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
- package/lib/chain/opPools/index.d.ts +1 -1
- package/lib/chain/opPools/index.d.ts.map +1 -1
- package/lib/chain/opPools/index.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts +5 -0
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +47 -6
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +3 -25
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +3 -2
- 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/regen/queued.d.ts +2 -2
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +5 -5
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +5 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +6 -0
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +47 -5
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +117 -7
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +3 -3
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +40 -10
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts +15 -3
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +165 -10
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/execution/builder/apiClient.d.ts +70 -0
- package/lib/execution/builder/apiClient.d.ts.map +1 -0
- package/lib/execution/builder/apiClient.js +202 -0
- package/lib/execution/builder/apiClient.js.map +1 -0
- package/lib/execution/builder/validateBid.d.ts +23 -0
- package/lib/execution/builder/validateBid.d.ts.map +1 -0
- package/lib/execution/builder/validateBid.js +119 -0
- package/lib/execution/builder/validateBid.js.map +1 -0
- package/lib/metrics/metrics/lodestar.d.ts +29 -1
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +61 -3
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +5 -4
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/constants.d.ts +7 -0
- package/lib/network/processor/constants.d.ts.map +1 -0
- package/lib/network/processor/constants.js +7 -0
- package/lib/network/processor/constants.js.map +1 -0
- package/lib/network/processor/gossipHandlers.js +1 -1
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipQueues/indexed.d.ts.map +1 -1
- package/lib/network/processor/gossipQueues/indexed.js +0 -1
- package/lib/network/processor/gossipQueues/indexed.js.map +1 -1
- package/lib/network/processor/index.d.ts +3 -0
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +52 -23
- package/lib/network/processor/index.js.map +1 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +5 -0
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +9 -2
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/range.js +1 -1
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +6 -2
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +48 -17
- package/lib/sync/unknownBlock.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +48 -13
- package/src/api/impl/lodestar/index.ts +1 -1
- package/src/api/impl/validator/index.ts +290 -49
- package/src/api/impl/validator/utils.ts +1 -1
- package/src/chain/archiveStore/archiveStore.ts +1 -1
- package/src/chain/blocks/index.ts +7 -7
- package/src/chain/blocks/verifyBlock.ts +5 -2
- package/src/chain/chain.ts +8 -1
- package/src/chain/errors/executionPayloadBid.ts +6 -0
- package/src/chain/forkChoice/index.ts +4 -0
- package/src/chain/interface.ts +4 -2
- package/src/chain/opPools/executionPayloadBidPool.ts +13 -7
- package/src/chain/opPools/index.ts +1 -1
- package/src/chain/prepareNextSlot.ts +49 -6
- package/src/chain/produceBlock/computeNewStateRoot.ts +3 -38
- package/src/chain/produceBlock/produceBlockBody.ts +1 -1
- package/src/chain/regen/interface.ts +3 -2
- package/src/chain/regen/queued.ts +5 -5
- package/src/chain/stateCache/fifoBlockStateCache.ts +8 -1
- package/src/chain/stateCache/persistentCheckpointsCache.ts +133 -8
- package/src/chain/stateCache/types.ts +3 -3
- package/src/chain/validation/block.ts +43 -10
- package/src/chain/validation/executionPayloadBid.ts +192 -12
- package/src/execution/builder/apiClient.ts +264 -0
- package/src/execution/builder/validateBid.ts +181 -0
- package/src/metrics/metrics/lodestar.ts +64 -4
- package/src/network/network.ts +7 -4
- package/src/network/processor/constants.ts +6 -0
- package/src/network/processor/gossipHandlers.ts +1 -1
- package/src/network/processor/gossipQueues/indexed.ts +0 -1
- package/src/network/processor/index.ts +67 -30
- package/src/node/nodejs.ts +5 -0
- package/src/sync/range/chain.ts +9 -2
- package/src/sync/range/range.ts +1 -1
- package/src/sync/unknownBlock.ts +62 -18
package/src/sync/unknownBlock.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {validateGossipExecutionPayloadEnvelope} from "../chain/validation/execut
|
|
|
17
17
|
import {Metrics} from "../metrics/index.js";
|
|
18
18
|
import {INetwork, NetworkEvent, NetworkEventData, prettyPrintPeerIdStr} from "../network/index.js";
|
|
19
19
|
import {PeerSyncMeta} from "../network/peers/peersData.js";
|
|
20
|
+
import {MAX_PEERS_PER_ROOT} from "../network/processor/constants.js";
|
|
20
21
|
import {PeerIdStr} from "../util/peerId.js";
|
|
21
22
|
import {shuffle} from "../util/shuffle.js";
|
|
22
23
|
import {sortBy} from "../util/sortBy.js";
|
|
@@ -165,6 +166,16 @@ export class BlockInputSync {
|
|
|
165
166
|
this.chain.emitter.on(routes.events.EventType.executionPayload, this.onPayloadImported);
|
|
166
167
|
this.network.events.on(NetworkEvent.peerConnected, this.onPeerConnected);
|
|
167
168
|
this.network.events.on(NetworkEvent.peerDisconnected, this.onPeerDisconnected);
|
|
169
|
+
|
|
170
|
+
// Seed the balancer with peers that connected before we subscribed
|
|
171
|
+
for (const peerId of this.network.getConnectedPeers()) {
|
|
172
|
+
try {
|
|
173
|
+
this.peerBalancer.onPeerConnected(peerId, this.network.getConnectedPeerSyncMeta(peerId));
|
|
174
|
+
} catch (e) {
|
|
175
|
+
this.logger.debug("Failed to seed connected peer into BlockInputSync balancer", {peerId}, e as Error);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
168
179
|
this.subscribedToNetworkEvents = true;
|
|
169
180
|
}
|
|
170
181
|
}
|
|
@@ -182,6 +193,7 @@ export class BlockInputSync {
|
|
|
182
193
|
this.chain.emitter.off(routes.events.EventType.executionPayload, this.onPayloadImported);
|
|
183
194
|
this.network.events.off(NetworkEvent.peerConnected, this.onPeerConnected);
|
|
184
195
|
this.network.events.off(NetworkEvent.peerDisconnected, this.onPeerDisconnected);
|
|
196
|
+
this.peerBalancer.clear();
|
|
185
197
|
this.subscribedToNetworkEvents = false;
|
|
186
198
|
}
|
|
187
199
|
|
|
@@ -198,10 +210,12 @@ export class BlockInputSync {
|
|
|
198
210
|
*/
|
|
199
211
|
private onUnknownBlockRoot = (data: ChainEventData[ChainEvent.unknownBlockRoot]): void => {
|
|
200
212
|
try {
|
|
201
|
-
this.addByRootHex(data.rootHex, data.peer);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
213
|
+
const isNewRoot = this.addByRootHex(data.rootHex, data.peer);
|
|
214
|
+
if (isNewRoot) {
|
|
215
|
+
this.triggerUnknownBlockSearch();
|
|
216
|
+
this.metrics?.blockInputSync.requests.inc({type: PendingBlockType.UNKNOWN_BLOCK_ROOT});
|
|
217
|
+
this.metrics?.blockInputSync.source.inc({source: data.source});
|
|
218
|
+
}
|
|
205
219
|
} catch (e) {
|
|
206
220
|
this.logger.debug("Error handling unknownBlockRoot event", {}, e as Error);
|
|
207
221
|
}
|
|
@@ -223,10 +237,12 @@ export class BlockInputSync {
|
|
|
223
237
|
|
|
224
238
|
private onUnknownEnvelopeBlockRoot = (data: ChainEventData[ChainEvent.unknownEnvelopeBlockRoot]): void => {
|
|
225
239
|
try {
|
|
226
|
-
this.addByPayloadRootHex(data.rootHex, data.peer, this.resolvePayloadSlot(data.rootHex));
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
240
|
+
const isNewRoot = this.addByPayloadRootHex(data.rootHex, data.peer, this.resolvePayloadSlot(data.rootHex));
|
|
241
|
+
if (isNewRoot) {
|
|
242
|
+
this.triggerUnknownBlockSearch();
|
|
243
|
+
this.metrics?.blockInputSync.requests.inc({type: PendingBlockType.UNKNOWN_PAYLOAD_BLOCK_ROOT});
|
|
244
|
+
this.metrics?.blockInputSync.payloadSource.inc({source: data.source});
|
|
245
|
+
}
|
|
230
246
|
} catch (e) {
|
|
231
247
|
this.logger.debug("Error handling unknownEnvelopeBlockRoot event", {}, e as Error);
|
|
232
248
|
}
|
|
@@ -385,7 +401,9 @@ export class BlockInputSync {
|
|
|
385
401
|
});
|
|
386
402
|
}
|
|
387
403
|
|
|
388
|
-
|
|
404
|
+
// bound peers tracked per root: propagationSource is recorded pre-validation, so cap the set (#9923).
|
|
405
|
+
// Once at the cap, ignore further peers rather than evicting already-tracked ones.
|
|
406
|
+
if (peerIdStr && pendingBlock.peerIdStrings.size < MAX_PEERS_PER_ROOT) {
|
|
389
407
|
pendingBlock.peerIdStrings.add(peerIdStr);
|
|
390
408
|
}
|
|
391
409
|
|
|
@@ -420,7 +438,9 @@ export class BlockInputSync {
|
|
|
420
438
|
});
|
|
421
439
|
}
|
|
422
440
|
|
|
423
|
-
|
|
441
|
+
// bound peers tracked per root: propagationSource is recorded pre-validation, so cap the set (#9923).
|
|
442
|
+
// Once at the cap, ignore further peers rather than evicting already-tracked ones.
|
|
443
|
+
if (peerIdStr && pendingBlock.peerIdStrings.size < MAX_PEERS_PER_ROOT) {
|
|
424
444
|
pendingBlock.peerIdStrings.add(peerIdStr);
|
|
425
445
|
}
|
|
426
446
|
|
|
@@ -462,8 +482,7 @@ export class BlockInputSync {
|
|
|
462
482
|
) {
|
|
463
483
|
pendingPayload.slot = slot;
|
|
464
484
|
}
|
|
465
|
-
|
|
466
|
-
if (peerIdStr) {
|
|
485
|
+
if (peerIdStr && pendingPayload.peerIdStrings.size < MAX_PEERS_PER_ROOT) {
|
|
467
486
|
pendingPayload.peerIdStrings.add(peerIdStr);
|
|
468
487
|
}
|
|
469
488
|
|
|
@@ -509,7 +528,7 @@ export class BlockInputSync {
|
|
|
509
528
|
envelope
|
|
510
529
|
);
|
|
511
530
|
|
|
512
|
-
if (peerIdStr) {
|
|
531
|
+
if (peerIdStr && pendingPayload.peerIdStrings.size < MAX_PEERS_PER_ROOT) {
|
|
513
532
|
pendingPayload.peerIdStrings.add(peerIdStr);
|
|
514
533
|
}
|
|
515
534
|
|
|
@@ -1235,7 +1254,12 @@ export class BlockInputSync {
|
|
|
1235
1254
|
const pendingColumns = payloadInput?.hasAllData()
|
|
1236
1255
|
? new Set<number>()
|
|
1237
1256
|
: new Set(payloadInput?.getMissingSampledColumnMeta().missing ?? []);
|
|
1238
|
-
|
|
1257
|
+
// prefer peers that gossiped this payload root to us (#9923)
|
|
1258
|
+
const peerMeta = this.peerBalancer.bestPeerForPendingColumns(
|
|
1259
|
+
pendingColumns,
|
|
1260
|
+
excludedPeers,
|
|
1261
|
+
cacheItem.peerIdStrings
|
|
1262
|
+
);
|
|
1239
1263
|
if (peerMeta === null) {
|
|
1240
1264
|
if (this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers) !== null) {
|
|
1241
1265
|
throw new UnknownBlockRateLimitedError(
|
|
@@ -1444,7 +1468,12 @@ export class BlockInputSync {
|
|
|
1444
1468
|
isPendingBlockInput(cacheItem) && isBlockInputColumns(cacheItem.blockInput)
|
|
1445
1469
|
? new Set(cacheItem.blockInput.getMissingSampledColumnMeta().missing)
|
|
1446
1470
|
: defaultPendingColumns;
|
|
1447
|
-
|
|
1471
|
+
// prefer peers that gossiped this block root to us (#9923)
|
|
1472
|
+
const peerMeta = this.peerBalancer.bestPeerForPendingColumns(
|
|
1473
|
+
pendingColumns,
|
|
1474
|
+
excludedPeers,
|
|
1475
|
+
cacheItem.peerIdStrings
|
|
1476
|
+
);
|
|
1448
1477
|
if (peerMeta === null) {
|
|
1449
1478
|
if (this.peerBalancer.getNextRateLimitRetryAt(pendingColumns, excludedPeers) !== null) {
|
|
1450
1479
|
throw new UnknownBlockRateLimitedError(
|
|
@@ -1720,6 +1749,13 @@ export class UnknownBlockPeerBalancer {
|
|
|
1720
1749
|
this.rateLimitedUntilByPeer.delete(peerId);
|
|
1721
1750
|
}
|
|
1722
1751
|
|
|
1752
|
+
/** Reset all tracked peer state, e.g. when BlockInputSync unsubscribes from the network. */
|
|
1753
|
+
clear(): void {
|
|
1754
|
+
this.peersMeta.clear();
|
|
1755
|
+
this.activeRequests.clear();
|
|
1756
|
+
this.rateLimitedUntilByPeer.clear();
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1723
1759
|
onRateLimited(peerId: PeerIdStr, rateLimitedUntilMs: number): void {
|
|
1724
1760
|
this.rateLimitedUntilByPeer.set(peerId, rateLimitedUntilMs);
|
|
1725
1761
|
}
|
|
@@ -1755,11 +1791,17 @@ export class UnknownBlockPeerBalancer {
|
|
|
1755
1791
|
}
|
|
1756
1792
|
|
|
1757
1793
|
/**
|
|
1758
|
-
* called from fetchBlockInput()
|
|
1794
|
+
* called from fetchBlockInput()/fetchPayloadInput() with a block/payload root.
|
|
1759
1795
|
* excludedPeers are the peers that we requested already so we don't want to try again
|
|
1760
1796
|
* pendingColumns is empty for prefulu, or the 1st time we we download a block by root
|
|
1797
|
+
* preferredPeers are the peers NetworkProcessor told us gossiped this root (from
|
|
1798
|
+
* pendingBlock/cacheItem.peerIdStrings). They are preferred but not required.
|
|
1761
1799
|
*/
|
|
1762
|
-
bestPeerForPendingColumns(
|
|
1800
|
+
bestPeerForPendingColumns(
|
|
1801
|
+
pendingColumns: Set<number>,
|
|
1802
|
+
excludedPeers: Set<PeerIdStr>,
|
|
1803
|
+
preferredPeers?: Set<PeerIdStr>
|
|
1804
|
+
): PeerSyncMeta | null {
|
|
1763
1805
|
const eligiblePeers = this.filterPeers(pendingColumns, excludedPeers);
|
|
1764
1806
|
if (eligiblePeers.length === 0) {
|
|
1765
1807
|
return null;
|
|
@@ -1767,7 +1809,9 @@ export class UnknownBlockPeerBalancer {
|
|
|
1767
1809
|
|
|
1768
1810
|
const sortedEligiblePeers = sortBy(
|
|
1769
1811
|
shuffle(eligiblePeers),
|
|
1770
|
-
// prefer peers
|
|
1812
|
+
// 1st key: prefer peers we heard about this root from
|
|
1813
|
+
(peerId) => (preferredPeers?.has(peerId) ? 0 : 1),
|
|
1814
|
+
// 2nd key (tiebreak): prefer peers with least active req
|
|
1771
1815
|
(peerId) => this.activeRequests.get(peerId) ?? 0
|
|
1772
1816
|
);
|
|
1773
1817
|
|