@lodestar/beacon-node 1.43.0-dev.87cbe69c66 → 1.43.0-dev.8ad5d8be4c
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/chain/blocks/blockInput/blockInput.d.ts +3 -0
- package/lib/chain/blocks/blockInput/blockInput.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/blockInput.js +4 -1
- package/lib/chain/blocks/blockInput/blockInput.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +0 -16
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +4 -0
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +12 -1
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +6 -7
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +11 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +23 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +16 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts +1 -3
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +29 -26
- package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +5 -4
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +25 -10
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/initState.d.ts.map +1 -1
- package/lib/chain/initState.js +6 -1
- package/lib/chain/initState.js.map +1 -1
- package/lib/chain/prepareNextSlot.js +1 -1
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +14 -10
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +51 -17
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/seenCache/seenProposerPreferences.d.ts +1 -1
- package/lib/chain/seenCache/seenProposerPreferences.d.ts.map +1 -1
- package/lib/chain/seenCache/seenProposerPreferences.js +6 -11
- package/lib/chain/seenCache/seenProposerPreferences.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +4 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +5 -0
- package/lib/metrics/metrics/lodestar.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/interface.d.ts +1 -0
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +1 -0
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +3 -0
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +45 -1
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.d.ts.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts +9 -0
- package/lib/network/reqresp/handlers/beaconBlocksByHead.d.ts.map +1 -0
- package/lib/network/reqresp/handlers/beaconBlocksByHead.js +61 -0
- package/lib/network/reqresp/handlers/beaconBlocksByHead.js.map +1 -0
- package/lib/network/reqresp/handlers/index.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/index.js +5 -0
- package/lib/network/reqresp/handlers/index.js.map +1 -1
- package/lib/network/reqresp/interface.d.ts +1 -1
- package/lib/network/reqresp/interface.js +1 -1
- package/lib/network/reqresp/protocols.d.ts +1 -0
- package/lib/network/reqresp/protocols.d.ts.map +1 -1
- package/lib/network/reqresp/protocols.js +5 -0
- package/lib/network/reqresp/protocols.js.map +1 -1
- package/lib/network/reqresp/rateLimit.d.ts.map +1 -1
- package/lib/network/reqresp/rateLimit.js +4 -0
- package/lib/network/reqresp/rateLimit.js.map +1 -1
- package/lib/network/reqresp/score.d.ts.map +1 -1
- package/lib/network/reqresp/score.js +1 -0
- package/lib/network/reqresp/score.js.map +1 -1
- package/lib/network/reqresp/types.d.ts +3 -0
- package/lib/network/reqresp/types.d.ts.map +1 -1
- package/lib/network/reqresp/types.js +3 -0
- package/lib/network/reqresp/types.js.map +1 -1
- package/lib/sync/constants.d.ts +7 -1
- package/lib/sync/constants.d.ts.map +1 -1
- package/lib/sync/constants.js +7 -4
- package/lib/sync/constants.js.map +1 -1
- package/lib/sync/range/batch.d.ts +32 -6
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +215 -41
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +16 -2
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +77 -4
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/range.d.ts.map +1 -1
- package/lib/sync/range/range.js +54 -5
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/range/utils/peerBalancer.d.ts +2 -1
- package/lib/sync/range/utils/peerBalancer.d.ts.map +1 -1
- package/lib/sync/range/utils/peerBalancer.js +8 -4
- package/lib/sync/range/utils/peerBalancer.js.map +1 -1
- package/lib/sync/sync.d.ts.map +1 -1
- package/lib/sync/sync.js +13 -0
- package/lib/sync/sync.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +7 -0
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +127 -10
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +36 -9
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +89 -42
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/rateLimit.d.ts +2 -0
- package/lib/sync/utils/rateLimit.d.ts.map +1 -0
- package/lib/sync/utils/rateLimit.js +15 -0
- package/lib/sync/utils/rateLimit.js.map +1 -0
- package/package.json +16 -16
- package/src/chain/blocks/blockInput/blockInput.ts +4 -1
- package/src/chain/blocks/importBlock.ts +0 -18
- package/src/chain/blocks/importExecutionPayload.ts +18 -6
- package/src/chain/blocks/index.ts +5 -7
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +31 -2
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +17 -0
- package/src/chain/blocks/utils/chainSegment.ts +30 -27
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +7 -4
- package/src/chain/chain.ts +29 -9
- package/src/chain/initState.ts +9 -1
- package/src/chain/prepareNextSlot.ts +1 -1
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +66 -20
- package/src/chain/seenCache/seenProposerPreferences.ts +7 -12
- package/src/metrics/metrics/lodestar.ts +6 -0
- package/src/network/interface.ts +1 -0
- package/src/network/network.ts +12 -0
- package/src/network/processor/gossipHandlers.ts +53 -1
- package/src/network/reqresp/ReqRespBeaconNode.ts +1 -0
- package/src/network/reqresp/handlers/beaconBlocksByHead.ts +91 -0
- package/src/network/reqresp/handlers/index.ts +5 -0
- package/src/network/reqresp/interface.ts +1 -1
- package/src/network/reqresp/protocols.ts +6 -0
- package/src/network/reqresp/rateLimit.ts +4 -0
- package/src/network/reqresp/score.ts +1 -0
- package/src/network/reqresp/types.ts +5 -0
- package/src/sync/constants.ts +8 -4
- package/src/sync/range/batch.ts +256 -47
- package/src/sync/range/chain.ts +94 -5
- package/src/sync/range/range.ts +68 -5
- package/src/sync/range/utils/peerBalancer.ts +9 -3
- package/src/sync/sync.ts +13 -1
- package/src/sync/unknownBlock.ts +157 -10
- package/src/sync/utils/downloadByRange.ts +156 -44
- package/src/sync/utils/rateLimit.ts +16 -0
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
IBlockInput,
|
|
36
36
|
isBlockInputColumns,
|
|
37
37
|
} from "../../chain/blocks/blockInput/index.js";
|
|
38
|
+
import {PayloadError, PayloadErrorCode} from "../../chain/blocks/importExecutionPayload.js";
|
|
38
39
|
import {PayloadEnvelopeInput, PayloadEnvelopeInputSource} from "../../chain/blocks/payloadEnvelopeInput/index.js";
|
|
39
40
|
import {BlobSidecarValidation} from "../../chain/blocks/types.js";
|
|
40
41
|
import {ChainEvent} from "../../chain/emitter.js";
|
|
@@ -607,6 +608,24 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
607
608
|
// Returns the delay between the start of `block.slot` and `current time`
|
|
608
609
|
const delaySec = chain.clock.secFromSlot(slot);
|
|
609
610
|
metrics?.gossipBlock.elapsedTimeTillProcessed.observe(delaySec);
|
|
611
|
+
|
|
612
|
+
if (isForkPostGloas(blockInput.forkName)) {
|
|
613
|
+
const payloadInput = chain.seenPayloadEnvelopeInputCache.get(blockInput.blockRootHex);
|
|
614
|
+
// This payloadInput should have been created just after gossip validation
|
|
615
|
+
if (!payloadInput) {
|
|
616
|
+
throw Error(
|
|
617
|
+
`PayloadEnvelopeInput not seeded for block ${blockInput.blockRootHex} during gossip processing`
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// Immediately attempt fetch of data columns from execution engine as the bid contains kzg commitments
|
|
622
|
+
// which is all the information we need so there is no reason to delay until execution payload arrives
|
|
623
|
+
// TODO GLOAS: If we want EL retries after this initial attempt, add an explicit retry policy here
|
|
624
|
+
// (for example later in the slot). Do not couple retries to incoming gossip columns.
|
|
625
|
+
// Columns fetched here feed payloadInput.addColumn, which resolves waitForAllData for any
|
|
626
|
+
// in-flight importExecutionPayload. No processExecutionPayload trigger needed from this path.
|
|
627
|
+
chain.getBlobsTracker.triggerGetBlobs(payloadInput);
|
|
628
|
+
}
|
|
610
629
|
})
|
|
611
630
|
.catch((e) => {
|
|
612
631
|
// Adjust verbosity based on error type
|
|
@@ -1130,7 +1149,40 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
1130
1149
|
});
|
|
1131
1150
|
|
|
1132
1151
|
chain.processExecutionPayload(payloadInput, {validSignature: true}).catch((e) => {
|
|
1133
|
-
|
|
1152
|
+
// Adjust verbosity based on error type
|
|
1153
|
+
let logLevel: LogLevel;
|
|
1154
|
+
|
|
1155
|
+
if (e instanceof PayloadError) {
|
|
1156
|
+
switch (e.type.code) {
|
|
1157
|
+
// BLOCK_NOT_IN_FORK_CHOICE should not happen, validateGossipExecutionPayloadEnvelope above
|
|
1158
|
+
// already verified the block is in fork choice
|
|
1159
|
+
case PayloadErrorCode.BLOCK_NOT_IN_FORK_CHOICE:
|
|
1160
|
+
case PayloadErrorCode.MISS_BLOCK_STATE:
|
|
1161
|
+
case PayloadErrorCode.EXECUTION_ENGINE_ERROR:
|
|
1162
|
+
// Errors might indicate an issue with our node or the connected EL client
|
|
1163
|
+
logLevel = LogLevel.error;
|
|
1164
|
+
break;
|
|
1165
|
+
// INVALID_SIGNATURE should not happen, signature is verified during gossip validation
|
|
1166
|
+
case PayloadErrorCode.INVALID_SIGNATURE:
|
|
1167
|
+
case PayloadErrorCode.ENVELOPE_VERIFICATION_ERROR:
|
|
1168
|
+
case PayloadErrorCode.EXECUTION_ENGINE_INVALID:
|
|
1169
|
+
core.reportPeer(peerIdStr, PeerAction.LowToleranceError, "BadGossipPayload");
|
|
1170
|
+
// Misbehaving peer, but could highlight an issue in another client
|
|
1171
|
+
logLevel = LogLevel.warn;
|
|
1172
|
+
break;
|
|
1173
|
+
}
|
|
1174
|
+
} else {
|
|
1175
|
+
// Any unexpected error
|
|
1176
|
+
logLevel = LogLevel.error;
|
|
1177
|
+
}
|
|
1178
|
+
metrics?.gossipExecutionPayloadEnvelope.processPayloadErrors.inc({
|
|
1179
|
+
error: e instanceof PayloadError ? e.type.code : "NOT_PAYLOAD_ERROR",
|
|
1180
|
+
});
|
|
1181
|
+
chain.logger[logLevel](
|
|
1182
|
+
"Error processing execution payload from gossip",
|
|
1183
|
+
{slot, peer: peerIdStr, root: blockRootHex},
|
|
1184
|
+
e as Error
|
|
1185
|
+
);
|
|
1134
1186
|
});
|
|
1135
1187
|
},
|
|
1136
1188
|
[GossipType.payload_attestation_message]: async ({
|
|
@@ -286,6 +286,7 @@ export class ReqRespBeaconNode extends ReqResp {
|
|
|
286
286
|
// instead of protocol version. This is not easily fixable with our current architecture.
|
|
287
287
|
// See https://github.com/ChainSafe/lodestar/pull/8168 for more details.
|
|
288
288
|
[protocols.StatusV2(fork, this.config), this.onStatus.bind(this)],
|
|
289
|
+
[protocols.BeaconBlocksByHead(fork, this.config), this.getHandler(ReqRespMethod.BeaconBlocksByHead)],
|
|
289
290
|
[
|
|
290
291
|
protocols.DataColumnSidecarsByRoot(fork, this.config),
|
|
291
292
|
this.getHandler(ReqRespMethod.DataColumnSidecarsByRoot),
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import {PeerId} from "@libp2p/interface";
|
|
2
|
+
import {BeaconConfig} from "@lodestar/config";
|
|
3
|
+
import {ForkName, GENESIS_EPOCH, GENESIS_SLOT, isForkPostDeneb} from "@lodestar/params";
|
|
4
|
+
import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
|
|
5
|
+
import {computeEpochAtSlot, computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
6
|
+
import {fulu} from "@lodestar/types";
|
|
7
|
+
import {toRootHex} from "@lodestar/utils";
|
|
8
|
+
import {IBeaconChain} from "../../../chain/index.js";
|
|
9
|
+
import {getParentRootFromSignedBeaconBlockSerialized} from "../../../util/sszBytes.js";
|
|
10
|
+
import {prettyPrintPeerId} from "../../util.js";
|
|
11
|
+
|
|
12
|
+
// See https://github.com/ethereum/consensus-specs/pull/5181
|
|
13
|
+
export async function* onBeaconBlocksByHead(
|
|
14
|
+
request: fulu.BeaconBlocksByHeadRequest,
|
|
15
|
+
chain: IBeaconChain,
|
|
16
|
+
peerId: PeerId,
|
|
17
|
+
peerClient: string
|
|
18
|
+
): AsyncIterable<ResponseOutgoing> {
|
|
19
|
+
const currentFork = chain.config.getForkName(chain.clock.currentSlot);
|
|
20
|
+
const {beaconRoot, count} = validateBeaconBlocksByHeadRequest(currentFork, chain.config, request);
|
|
21
|
+
|
|
22
|
+
const requestedRootHex = toRootHex(beaconRoot);
|
|
23
|
+
let blockRootHex = requestedRootHex;
|
|
24
|
+
const minimumRequestEpoch = Math.max(
|
|
25
|
+
GENESIS_EPOCH,
|
|
26
|
+
chain.clock.currentEpoch - chain.config.MIN_EPOCHS_FOR_BLOCK_REQUESTS
|
|
27
|
+
);
|
|
28
|
+
const minimumRequestSlot = computeStartSlotAtEpoch(minimumRequestEpoch);
|
|
29
|
+
|
|
30
|
+
for (let blocksSent = 0; blocksSent < count; blocksSent++) {
|
|
31
|
+
const blockBytes = await chain.getSerializedBlockByRoot(blockRootHex);
|
|
32
|
+
if (!blockBytes) {
|
|
33
|
+
if (blocksSent === 0) {
|
|
34
|
+
throw new ResponseError(RespStatus.RESOURCE_UNAVAILABLE, `Unknown block root ${requestedRootHex}`);
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (blockBytes.slot < minimumRequestSlot) {
|
|
40
|
+
if (blocksSent === 0) {
|
|
41
|
+
chain.logger.verbose("Peer requested unavailable block for BeaconBlocksByHead", {
|
|
42
|
+
peer: prettyPrintPeerId(peerId),
|
|
43
|
+
client: peerClient,
|
|
44
|
+
requestedRoot: requestedRootHex,
|
|
45
|
+
slot: blockBytes.slot,
|
|
46
|
+
minimumRequestSlot,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
yield {
|
|
53
|
+
data: blockBytes.block,
|
|
54
|
+
boundary: chain.config.getForkBoundaryAtEpoch(computeEpochAtSlot(blockBytes.slot)),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
if (blockBytes.slot === GENESIS_SLOT) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const parentRootHex = getParentRootFromSignedBeaconBlockSerialized(blockBytes.block);
|
|
62
|
+
if (parentRootHex === null) {
|
|
63
|
+
throw new ResponseError(
|
|
64
|
+
RespStatus.SERVER_ERROR,
|
|
65
|
+
`Invalid block bytes for root ${blockRootHex} slot ${blockBytes.slot}`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
blockRootHex = parentRootHex;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function validateBeaconBlocksByHeadRequest(
|
|
73
|
+
fork: ForkName,
|
|
74
|
+
config: BeaconConfig,
|
|
75
|
+
request: fulu.BeaconBlocksByHeadRequest
|
|
76
|
+
): fulu.BeaconBlocksByHeadRequest {
|
|
77
|
+
const {beaconRoot} = request;
|
|
78
|
+
let {count} = request;
|
|
79
|
+
|
|
80
|
+
if (count < 1) {
|
|
81
|
+
throw new ResponseError(RespStatus.INVALID_REQUEST, "count < 1");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const maxRequestBlocks = isForkPostDeneb(fork) ? config.MAX_REQUEST_BLOCKS_DENEB : config.MAX_REQUEST_BLOCKS;
|
|
85
|
+
|
|
86
|
+
if (count > maxRequestBlocks) {
|
|
87
|
+
count = maxRequestBlocks;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {beaconRoot, count};
|
|
91
|
+
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
ExecutionPayloadEnvelopesByRootRequestType,
|
|
10
10
|
} from "../../../util/types.js";
|
|
11
11
|
import {GetReqRespHandlerFn, ReqRespMethod} from "../types.js";
|
|
12
|
+
import {onBeaconBlocksByHead} from "./beaconBlocksByHead.js";
|
|
12
13
|
import {onBeaconBlocksByRange} from "./beaconBlocksByRange.js";
|
|
13
14
|
import {onBeaconBlocksByRoot} from "./beaconBlocksByRoot.js";
|
|
14
15
|
import {onBlobSidecarsByRange} from "./blobSidecarsByRange.js";
|
|
@@ -47,6 +48,10 @@ export function getReqRespHandlers({db, chain}: {db: IBeaconDb; chain: IBeaconCh
|
|
|
47
48
|
const body = BeaconBlocksByRootRequestType(fork, chain.config).deserialize(req.data);
|
|
48
49
|
return onBeaconBlocksByRoot(body, chain);
|
|
49
50
|
},
|
|
51
|
+
[ReqRespMethod.BeaconBlocksByHead]: (req, peerId, peerClient) => {
|
|
52
|
+
const body = ssz.fulu.BeaconBlocksByHeadRequest.deserialize(req.data);
|
|
53
|
+
return onBeaconBlocksByHead(body, chain, peerId, peerClient);
|
|
54
|
+
},
|
|
50
55
|
[ReqRespMethod.BlobSidecarsByRoot]: (req) => {
|
|
51
56
|
const fork = chain.config.getForkName(chain.clock.currentSlot);
|
|
52
57
|
const body = BlobSidecarsByRootRequestType(fork, chain.config).deserialize(req.data);
|
|
@@ -33,7 +33,7 @@ export enum RespStatus {
|
|
|
33
33
|
*/
|
|
34
34
|
SERVER_ERROR = 2,
|
|
35
35
|
/**
|
|
36
|
-
* The responder does not have requested resource.
|
|
36
|
+
* The responder does not have requested resource. The response payload adheres to the ErrorMessage schema.
|
|
37
37
|
*/
|
|
38
38
|
RESOURCE_UNAVAILABLE = 3,
|
|
39
39
|
/**
|
|
@@ -70,6 +70,12 @@ export const BeaconBlocksByRootV2 = toProtocol({
|
|
|
70
70
|
contextBytesType: ContextBytesType.ForkDigest,
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
+
export const BeaconBlocksByHead = toProtocol({
|
|
74
|
+
method: ReqRespMethod.BeaconBlocksByHead,
|
|
75
|
+
version: Version.V1,
|
|
76
|
+
contextBytesType: ContextBytesType.ForkDigest,
|
|
77
|
+
});
|
|
78
|
+
|
|
73
79
|
export const BlobSidecarsByRange = toProtocol({
|
|
74
80
|
method: ReqRespMethod.BlobSidecarsByRange,
|
|
75
81
|
version: Version.V1,
|
|
@@ -40,6 +40,10 @@ export const rateLimitQuotas: (fork: ForkName, config: BeaconConfig) => Record<R
|
|
|
40
40
|
},
|
|
41
41
|
getRequestCount: getRequestCountFn(fork, config, ReqRespMethod.BeaconBlocksByRoot, (req) => req.length),
|
|
42
42
|
},
|
|
43
|
+
[ReqRespMethod.BeaconBlocksByHead]: {
|
|
44
|
+
byPeer: {quota: config.MAX_REQUEST_BLOCKS_DENEB, quotaTimeMs: 10_000},
|
|
45
|
+
getRequestCount: getRequestCountFn(fork, config, ReqRespMethod.BeaconBlocksByHead, (req) => req.count),
|
|
46
|
+
},
|
|
43
47
|
[ReqRespMethod.BlobSidecarsByRange]: {
|
|
44
48
|
// Rationale: MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK
|
|
45
49
|
byPeer: {
|
|
@@ -46,6 +46,7 @@ export function onOutgoingReqRespError(e: RequestError, method: ReqRespMethod):
|
|
|
46
46
|
return PeerAction.LowToleranceError;
|
|
47
47
|
case ReqRespMethod.BeaconBlocksByRange:
|
|
48
48
|
case ReqRespMethod.BeaconBlocksByRoot:
|
|
49
|
+
case ReqRespMethod.BeaconBlocksByHead:
|
|
49
50
|
case ReqRespMethod.ExecutionPayloadEnvelopesByRoot:
|
|
50
51
|
case ReqRespMethod.ExecutionPayloadEnvelopesByRange:
|
|
51
52
|
return PeerAction.MidToleranceError;
|
|
@@ -42,6 +42,7 @@ export enum ReqRespMethod {
|
|
|
42
42
|
Metadata = "metadata",
|
|
43
43
|
BeaconBlocksByRange = "beacon_blocks_by_range",
|
|
44
44
|
BeaconBlocksByRoot = "beacon_blocks_by_root",
|
|
45
|
+
BeaconBlocksByHead = "beacon_blocks_by_head",
|
|
45
46
|
BlobSidecarsByRange = "blob_sidecars_by_range",
|
|
46
47
|
BlobSidecarsByRoot = "blob_sidecars_by_root",
|
|
47
48
|
DataColumnSidecarsByRange = "data_column_sidecars_by_range",
|
|
@@ -62,6 +63,7 @@ export type RequestBodyByMethod = {
|
|
|
62
63
|
[ReqRespMethod.Metadata]: null;
|
|
63
64
|
[ReqRespMethod.BeaconBlocksByRange]: phase0.BeaconBlocksByRangeRequest;
|
|
64
65
|
[ReqRespMethod.BeaconBlocksByRoot]: BeaconBlocksByRootRequest;
|
|
66
|
+
[ReqRespMethod.BeaconBlocksByHead]: fulu.BeaconBlocksByHeadRequest;
|
|
65
67
|
[ReqRespMethod.BlobSidecarsByRange]: deneb.BlobSidecarsByRangeRequest;
|
|
66
68
|
[ReqRespMethod.BlobSidecarsByRoot]: BlobSidecarsByRootRequest;
|
|
67
69
|
[ReqRespMethod.DataColumnSidecarsByRange]: fulu.DataColumnSidecarsByRangeRequest;
|
|
@@ -82,6 +84,7 @@ type ResponseBodyByMethod = {
|
|
|
82
84
|
// Do not matter
|
|
83
85
|
[ReqRespMethod.BeaconBlocksByRange]: SignedBeaconBlock;
|
|
84
86
|
[ReqRespMethod.BeaconBlocksByRoot]: SignedBeaconBlock;
|
|
87
|
+
[ReqRespMethod.BeaconBlocksByHead]: SignedBeaconBlock;
|
|
85
88
|
[ReqRespMethod.BlobSidecarsByRange]: deneb.BlobSidecar;
|
|
86
89
|
[ReqRespMethod.BlobSidecarsByRoot]: deneb.BlobSidecar;
|
|
87
90
|
[ReqRespMethod.DataColumnSidecarsByRange]: DataColumnSidecar;
|
|
@@ -111,6 +114,7 @@ export const requestSszTypeByMethod: (
|
|
|
111
114
|
|
|
112
115
|
[ReqRespMethod.BeaconBlocksByRange]: ssz.phase0.BeaconBlocksByRangeRequest,
|
|
113
116
|
[ReqRespMethod.BeaconBlocksByRoot]: BeaconBlocksByRootRequestType(fork, config),
|
|
117
|
+
[ReqRespMethod.BeaconBlocksByHead]: ssz.fulu.BeaconBlocksByHeadRequest,
|
|
114
118
|
[ReqRespMethod.BlobSidecarsByRange]: ssz.deneb.BlobSidecarsByRangeRequest,
|
|
115
119
|
[ReqRespMethod.BlobSidecarsByRoot]: BlobSidecarsByRootRequestType(fork, config),
|
|
116
120
|
[ReqRespMethod.DataColumnSidecarsByRange]: ssz.fulu.DataColumnSidecarsByRangeRequest,
|
|
@@ -142,6 +146,7 @@ export const responseSszTypeByMethod: {[K in ReqRespMethod]: ResponseTypeGetter<
|
|
|
142
146
|
version === Version.V1 ? ssz.phase0.Metadata : version === Version.V2 ? ssz.altair.Metadata : ssz.fulu.Metadata,
|
|
143
147
|
[ReqRespMethod.BeaconBlocksByRange]: blocksResponseType,
|
|
144
148
|
[ReqRespMethod.BeaconBlocksByRoot]: blocksResponseType,
|
|
149
|
+
[ReqRespMethod.BeaconBlocksByHead]: (fork) => ssz[fork].SignedBeaconBlock,
|
|
145
150
|
[ReqRespMethod.BlobSidecarsByRange]: () => ssz.deneb.BlobSidecar,
|
|
146
151
|
[ReqRespMethod.BlobSidecarsByRoot]: () => ssz.deneb.BlobSidecar,
|
|
147
152
|
[ReqRespMethod.LightClientBootstrap]: (fork) => sszTypesFor(onlyPostAltairFork(fork)).LightClientBootstrap,
|
package/src/sync/constants.ts
CHANGED
|
@@ -5,10 +5,14 @@ export const PARALLEL_HEAD_CHAINS = 2;
|
|
|
5
5
|
export const MIN_FINALIZED_CHAIN_VALIDATED_EPOCHS = 10;
|
|
6
6
|
|
|
7
7
|
/** The number of times to retry a batch before it is considered failed. */
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
export const MAX_BATCH_DOWNLOAD_ATTEMPTS = 5;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Backoff before assigning more range-sync batches to a peer that rate-limited us.
|
|
12
|
+
*
|
|
13
|
+
* Note: this is used when rate limited due to MAX_CONCURRENT_REQUESTS
|
|
14
|
+
*/
|
|
15
|
+
export const RATE_LIMITED_PEER_BACKOFF_MS = 5_000;
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
18
|
* Consider batch faulty after downloading and processing this number of times
|