@lodestar/beacon-node 1.36.0-dev.6604fa5719 → 1.36.0-dev.6d67a79656
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 +4 -2
- package/lib/api/impl/config/constants.d.ts.map +1 -1
- package/lib/api/impl/config/constants.js +6 -3
- package/lib/api/impl/config/constants.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +2 -2
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +9 -0
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +24 -0
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +7 -0
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +25 -4
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
- package/lib/chain/beaconProposerCache.d.ts +3 -0
- package/lib/chain/beaconProposerCache.d.ts.map +1 -1
- package/lib/chain/beaconProposerCache.js +4 -6
- package/lib/chain/beaconProposerCache.js.map +1 -1
- package/lib/chain/chain.js +1 -1
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/voluntaryExitError.d.ts +16 -2
- package/lib/chain/errors/voluntaryExitError.d.ts.map +1 -1
- package/lib/chain/errors/voluntaryExitError.js +22 -1
- package/lib/chain/errors/voluntaryExitError.js.map +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.d.ts +3 -1
- package/lib/chain/opPools/syncContributionAndProofPool.d.ts.map +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js +4 -3
- package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +6 -7
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +1 -2
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/lightClientOptimisticUpdate.d.ts.map +1 -1
- package/lib/chain/validation/lightClientOptimisticUpdate.js +1 -2
- package/lib/chain/validation/lightClientOptimisticUpdate.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +5 -4
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/constants/constants.d.ts +0 -5
- package/lib/constants/constants.d.ts.map +1 -1
- package/lib/constants/constants.js +0 -5
- package/lib/constants/constants.js.map +1 -1
- package/lib/constants/network.d.ts +0 -14
- package/lib/constants/network.d.ts.map +1 -1
- package/lib/constants/network.js +0 -15
- package/lib/constants/network.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +10 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +14 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/discv5/utils.d.ts.map +1 -1
- package/lib/network/discv5/utils.js +1 -2
- package/lib/network/discv5/utils.js.map +1 -1
- package/lib/network/gossip/gossipsub.d.ts.map +1 -1
- package/lib/network/gossip/gossipsub.js +1 -7
- package/lib/network/gossip/gossipsub.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js +5 -5
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRoot.js +4 -4
- package/lib/network/reqresp/handlers/blobSidecarsByRoot.js.map +1 -1
- package/lib/network/subnets/attnetsService.d.ts +1 -1
- package/lib/network/subnets/attnetsService.js +6 -6
- package/lib/network/subnets/attnetsService.js.map +1 -1
- package/lib/network/subnets/util.d.ts +3 -2
- package/lib/network/subnets/util.d.ts.map +1 -1
- package/lib/network/subnets/util.js +6 -6
- package/lib/network/subnets/util.js.map +1 -1
- package/lib/util/clock.d.ts.map +1 -1
- package/lib/util/clock.js +3 -4
- package/lib/util/clock.js.map +1 -1
- package/package.json +14 -14
- package/src/api/impl/config/constants.ts +10 -4
- package/src/api/impl/validator/index.ts +5 -2
- package/src/chain/archiveStore/archiveStore.ts +27 -0
- package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +27 -4
- package/src/chain/beaconProposerCache.ts +4 -8
- package/src/chain/chain.ts +1 -1
- package/src/chain/errors/voluntaryExitError.ts +30 -2
- package/src/chain/opPools/syncContributionAndProofPool.ts +3 -2
- package/src/chain/validation/attestation.ts +6 -7
- package/src/chain/validation/block.ts +1 -2
- package/src/chain/validation/lightClientOptimisticUpdate.ts +3 -2
- package/src/chain/validation/voluntaryExit.ts +14 -4
- package/src/constants/constants.ts +0 -6
- package/src/constants/network.ts +0 -19
- package/src/metrics/metrics/lodestar.ts +17 -0
- package/src/network/discv5/utils.ts +1 -2
- package/src/network/gossip/gossipsub.ts +1 -10
- package/src/network/reqresp/handlers/blobSidecarsByRange.ts +6 -6
- package/src/network/reqresp/handlers/blobSidecarsByRoot.ts +5 -5
- package/src/network/subnets/attnetsService.ts +6 -6
- package/src/network/subnets/util.ts +12 -12
- package/src/util/clock.ts +3 -4
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
3
4
|
import {SYNC_COMMITTEE_SIZE, SYNC_COMMITTEE_SUBNET_SIZE} from "@lodestar/params";
|
|
4
5
|
import {G2_POINT_AT_INFINITY} from "@lodestar/state-transition";
|
|
5
6
|
import {Root, Slot, SubnetID, altair, ssz} from "@lodestar/types";
|
|
6
7
|
import {Logger, MapDef, toRootHex} from "@lodestar/utils";
|
|
7
|
-
import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../../constants/constants.js";
|
|
8
8
|
import {Metrics} from "../../metrics/metrics.js";
|
|
9
9
|
import {IClock} from "../../util/clock.js";
|
|
10
10
|
import {InsertOutcome, OpPoolError, OpPoolErrorCode} from "./types.js";
|
|
@@ -51,6 +51,7 @@ export class SyncContributionAndProofPool {
|
|
|
51
51
|
private lowestPermissibleSlot = 0;
|
|
52
52
|
|
|
53
53
|
constructor(
|
|
54
|
+
private readonly config: ChainForkConfig,
|
|
54
55
|
private readonly clock: IClock,
|
|
55
56
|
private readonly metrics: Metrics | null = null,
|
|
56
57
|
private logger: Logger | null = null
|
|
@@ -92,7 +93,7 @@ export class SyncContributionAndProofPool {
|
|
|
92
93
|
|
|
93
94
|
// Reject ContributionAndProofs of previous slots
|
|
94
95
|
// for api ContributionAndProofs, we allow them to be added to the pool
|
|
95
|
-
if (!priority && slot < this.clock.slotWithPastTolerance(MAXIMUM_GOSSIP_CLOCK_DISPARITY)) {
|
|
96
|
+
if (!priority && slot < this.clock.slotWithPastTolerance(this.config.MAXIMUM_GOSSIP_CLOCK_DISPARITY / 1000)) {
|
|
96
97
|
return InsertOutcome.Late;
|
|
97
98
|
}
|
|
98
99
|
|
|
@@ -36,7 +36,6 @@ import {
|
|
|
36
36
|
ssz,
|
|
37
37
|
} from "@lodestar/types";
|
|
38
38
|
import {assert, toRootHex} from "@lodestar/utils";
|
|
39
|
-
import {MAXIMUM_GOSSIP_CLOCK_DISPARITY_SEC} from "../../constants/index.js";
|
|
40
39
|
import {sszDeserializeSingleAttestation} from "../../network/gossip/topic.js";
|
|
41
40
|
import {getShufflingDependentRoot} from "../../util/dependentRoot.js";
|
|
42
41
|
import {
|
|
@@ -570,8 +569,8 @@ async function validateAttestationNoSignatureCheck(
|
|
|
570
569
|
* Note: We do not queue future attestations for later processing
|
|
571
570
|
*/
|
|
572
571
|
export function verifyPropagationSlotRange(fork: ForkName, chain: IBeaconChain, attestationSlot: Slot): void {
|
|
573
|
-
// slot with future tolerance of
|
|
574
|
-
const latestPermissibleSlot = chain.clock.slotWithFutureTolerance(
|
|
572
|
+
// slot with future tolerance of MAXIMUM_GOSSIP_CLOCK_DISPARITY
|
|
573
|
+
const latestPermissibleSlot = chain.clock.slotWithFutureTolerance(chain.config.MAXIMUM_GOSSIP_CLOCK_DISPARITY / 1000);
|
|
575
574
|
if (attestationSlot > latestPermissibleSlot) {
|
|
576
575
|
throw new AttestationError(GossipAction.IGNORE, {
|
|
577
576
|
code: AttestationErrorCode.FUTURE_SLOT,
|
|
@@ -586,9 +585,9 @@ export function verifyPropagationSlotRange(fork: ForkName, chain: IBeaconChain,
|
|
|
586
585
|
// see: https://github.com/ethereum/consensus-specs/pull/3360
|
|
587
586
|
if (ForkSeq[fork] < ForkSeq.deneb) {
|
|
588
587
|
const earliestPermissibleSlot = Math.max(
|
|
589
|
-
// slot with past tolerance of
|
|
590
|
-
|
|
591
|
-
|
|
588
|
+
// slot with past tolerance of MAXIMUM_GOSSIP_CLOCK_DISPARITY
|
|
589
|
+
chain.clock.slotWithPastTolerance(chain.config.MAXIMUM_GOSSIP_CLOCK_DISPARITY / 1000) -
|
|
590
|
+
chain.config.ATTESTATION_PROPAGATION_SLOT_RANGE,
|
|
592
591
|
0
|
|
593
592
|
);
|
|
594
593
|
|
|
@@ -614,7 +613,7 @@ export function verifyPropagationSlotRange(fork: ForkName, chain: IBeaconChain,
|
|
|
614
613
|
|
|
615
614
|
// lower bound for previous epoch is same as epoch of earliestPermissibleSlot
|
|
616
615
|
const currentEpochWithPastTolerance = computeEpochAtSlot(
|
|
617
|
-
chain.clock.slotWithPastTolerance(
|
|
616
|
+
chain.clock.slotWithPastTolerance(chain.config.MAXIMUM_GOSSIP_CLOCK_DISPARITY / 1000)
|
|
618
617
|
);
|
|
619
618
|
|
|
620
619
|
const earliestPermissiblePreviousEpoch = Math.max(currentEpochWithPastTolerance - 1, 0);
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
} from "@lodestar/state-transition";
|
|
12
12
|
import {SignedBeaconBlock, deneb} from "@lodestar/types";
|
|
13
13
|
import {sleep, toRootHex} from "@lodestar/utils";
|
|
14
|
-
import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../../constants/index.js";
|
|
15
14
|
import {BlockErrorCode, BlockGossipError, GossipAction} from "../errors/index.js";
|
|
16
15
|
import {IBeaconChain} from "../interface.js";
|
|
17
16
|
import {RegenCaller} from "../regen/index.js";
|
|
@@ -179,7 +178,7 @@ export async function validateGossipBlock(
|
|
|
179
178
|
// gossip validation promise without any extra infrastructure.
|
|
180
179
|
// Do the sleep at the end, since regen and signature validation can already take longer than `msToBlockSlot`.
|
|
181
180
|
const msToBlockSlot = computeTimeAtSlot(config, blockSlot, chain.genesisTime) * 1000 - Date.now();
|
|
182
|
-
if (msToBlockSlot <= MAXIMUM_GOSSIP_CLOCK_DISPARITY && msToBlockSlot > 0) {
|
|
181
|
+
if (msToBlockSlot <= config.MAXIMUM_GOSSIP_CLOCK_DISPARITY && msToBlockSlot > 0) {
|
|
183
182
|
// If block is between 0 and 500 ms early, hold it in a promise. Equivalent to a pending queue.
|
|
184
183
|
await sleep(msToBlockSlot);
|
|
185
184
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {LightClientOptimisticUpdate} from "@lodestar/types";
|
|
3
|
-
import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../../constants/index.js";
|
|
4
3
|
import {assertLightClientServer} from "../../node/utils/lightclient.js";
|
|
5
4
|
import {IClock} from "../../util/clock.js";
|
|
6
5
|
import {GossipAction} from "../errors/index.js";
|
|
@@ -64,5 +63,7 @@ export function updateReceivedTooEarly(
|
|
|
64
63
|
update: Pick<LightClientOptimisticUpdate, "signatureSlot">
|
|
65
64
|
): boolean {
|
|
66
65
|
const fork = config.getForkName(update.signatureSlot);
|
|
67
|
-
return
|
|
66
|
+
return (
|
|
67
|
+
clock.msFromSlot(update.signatureSlot) < config.getSyncMessageDueMs(fork) - config.MAXIMUM_GOSSIP_CLOCK_DISPARITY
|
|
68
|
+
);
|
|
68
69
|
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
VoluntaryExitValidity,
|
|
3
|
+
getVoluntaryExitSignatureSet,
|
|
4
|
+
getVoluntaryExitValidity,
|
|
5
|
+
} from "@lodestar/state-transition";
|
|
2
6
|
import {phase0} from "@lodestar/types";
|
|
3
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
GossipAction,
|
|
9
|
+
VoluntaryExitError,
|
|
10
|
+
VoluntaryExitErrorCode,
|
|
11
|
+
voluntaryExitValidityToErrorCode,
|
|
12
|
+
} from "../errors/index.js";
|
|
4
13
|
import {IBeaconChain} from "../index.js";
|
|
5
14
|
import {RegenCaller} from "../regen/index.js";
|
|
6
15
|
|
|
@@ -43,9 +52,10 @@ async function validateVoluntaryExit(
|
|
|
43
52
|
|
|
44
53
|
// [REJECT] All of the conditions within process_voluntary_exit pass validation.
|
|
45
54
|
// verifySignature = false, verified in batch below
|
|
46
|
-
|
|
55
|
+
const validity = getVoluntaryExitValidity(chain.config.getForkSeq(state.slot), state, voluntaryExit, false);
|
|
56
|
+
if (validity !== VoluntaryExitValidity.valid) {
|
|
47
57
|
throw new VoluntaryExitError(GossipAction.REJECT, {
|
|
48
|
-
code:
|
|
58
|
+
code: voluntaryExitValidityToErrorCode(validity),
|
|
49
59
|
});
|
|
50
60
|
}
|
|
51
61
|
|
|
@@ -7,9 +7,3 @@ export const ZERO_HASH = Buffer.alloc(32, 0);
|
|
|
7
7
|
export const ZERO_HASH_HEX = "0x" + "00".repeat(32);
|
|
8
8
|
export const EMPTY_SIGNATURE = Buffer.alloc(96, 0);
|
|
9
9
|
export const GRAFFITI_SIZE = 32;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* The maximum milliseconds of clock disparity assumed between honest nodes.
|
|
13
|
-
*/
|
|
14
|
-
export const MAXIMUM_GOSSIP_CLOCK_DISPARITY = 500;
|
|
15
|
-
export const MAXIMUM_GOSSIP_CLOCK_DISPARITY_SEC = MAXIMUM_GOSSIP_CLOCK_DISPARITY / 1000;
|
package/src/constants/network.ts
CHANGED
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* For more info on some of these constants:
|
|
3
|
-
* https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#configuration
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Gossip constants
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* The maximum number of slots during which an attestation can be propagated.
|
|
10
|
-
*/
|
|
11
|
-
export const ATTESTATION_PROPAGATION_SLOT_RANGE = 32;
|
|
12
|
-
|
|
13
|
-
/** The maximum allowed size of uncompressed gossip messages. */
|
|
14
|
-
export const GOSSIP_MAX_SIZE = 2 ** 20;
|
|
15
|
-
export const GOSSIP_MAX_SIZE_BELLATRIX = 10 * GOSSIP_MAX_SIZE;
|
|
16
|
-
/** The maximum allowed size of uncompressed req/resp chunked responses. */
|
|
17
|
-
export const MAX_CHUNK_SIZE = 2 ** 20;
|
|
18
|
-
export const MAX_CHUNK_SIZE_BELLATRIX = 10 * MAX_CHUNK_SIZE;
|
|
19
|
-
|
|
20
1
|
export enum GoodByeReasonCode {
|
|
21
2
|
INBOUND_DISCONNECT = -1,
|
|
22
3
|
CLIENT_SHUTDOWN = 1,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** biome-ignore-all lint/suspicious/noTemplateCurlyInString: The metric templates requires to have `${}` in a normal string */
|
|
2
2
|
import {NotReorgedReason} from "@lodestar/fork-choice";
|
|
3
|
+
import {ArchiveStoreTask} from "../../chain/archiveStore/archiveStore.js";
|
|
4
|
+
import {FrequencyStateArchiveStep} from "../../chain/archiveStore/strategies/frequencyStateArchiveStrategy.js";
|
|
3
5
|
import {BlockInputSource} from "../../chain/blocks/blockInput/index.js";
|
|
4
6
|
import {JobQueueItemType} from "../../chain/bls/index.js";
|
|
5
7
|
import {AttestationErrorCode, BlockErrorCode} from "../../chain/errors/index.js";
|
|
@@ -1420,6 +1422,21 @@ export function createLodestarMetrics(
|
|
|
1420
1422
|
},
|
|
1421
1423
|
},
|
|
1422
1424
|
|
|
1425
|
+
processFinalizedCheckpoint: {
|
|
1426
|
+
durationByTask: register.histogram<{source: ArchiveStoreTask}>({
|
|
1427
|
+
name: "lodestar_process_finalized_checkpoint_seconds",
|
|
1428
|
+
help: "Histogram of time to process finalized checkpoint",
|
|
1429
|
+
buckets: [0.1, 0.5, 1, 2, 4, 8],
|
|
1430
|
+
labelNames: ["source"],
|
|
1431
|
+
}),
|
|
1432
|
+
frequencyStateArchive: register.histogram<{step: FrequencyStateArchiveStep}>({
|
|
1433
|
+
name: "lodestar_process_finalized_checkpoint_frequency_state_archive_seconds",
|
|
1434
|
+
help: "Histogram of FrequencyStateArchive duration by step",
|
|
1435
|
+
buckets: [0.1, 0.5, 1, 2, 4, 8],
|
|
1436
|
+
labelNames: ["step"],
|
|
1437
|
+
}),
|
|
1438
|
+
},
|
|
1439
|
+
|
|
1423
1440
|
regenFnCallTotal: register.gauge<{entrypoint: RegenFnName; caller: RegenCaller}>({
|
|
1424
1441
|
name: "lodestar_regen_fn_call_total",
|
|
1425
1442
|
help: "Total number of calls for regen functions",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {ENR} from "@chainsafe/enr";
|
|
2
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
|
-
import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../../constants/constants.js";
|
|
4
3
|
import {IClock} from "../../util/clock.js";
|
|
5
4
|
import {ENRKey} from "../metadata.js";
|
|
6
5
|
|
|
@@ -35,7 +34,7 @@ export function enrRelevance(enr: ENR, config: BeaconConfig, clock: IClock): ENR
|
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
// Check if fork digest's fork matches ours
|
|
38
|
-
const currentSlot = clock.slotWithFutureTolerance(MAXIMUM_GOSSIP_CLOCK_DISPARITY);
|
|
37
|
+
const currentSlot = clock.slotWithFutureTolerance(config.MAXIMUM_GOSSIP_CLOCK_DISPARITY / 1000);
|
|
39
38
|
const localForkInfo = config.getForkInfo(currentSlot);
|
|
40
39
|
// We only connect if the ENR's fork matches our current fork.
|
|
41
40
|
// We also allow it to be the previous fork due to delay and infrequent update of DHT.
|
|
@@ -6,7 +6,6 @@ import {BeaconConfig, ForkBoundary} from "@lodestar/config";
|
|
|
6
6
|
import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH, SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
|
|
7
7
|
import {SubnetID} from "@lodestar/types";
|
|
8
8
|
import {Logger, Map2d, Map2dArr} from "@lodestar/utils";
|
|
9
|
-
import {GOSSIP_MAX_SIZE, GOSSIP_MAX_SIZE_BELLATRIX} from "../../constants/network.js";
|
|
10
9
|
import {RegistryMetricCreator} from "../../metrics/index.js";
|
|
11
10
|
import {callInNextEventLoop} from "../../util/eventLoop.js";
|
|
12
11
|
import {NetworkEvent, NetworkEventBus, NetworkEventData} from "../events.js";
|
|
@@ -117,15 +116,7 @@ export class Eth2Gossipsub extends GossipSub {
|
|
|
117
116
|
fastMsgIdFn: fastMsgIdFn,
|
|
118
117
|
msgIdFn: msgIdFn.bind(msgIdFn, gossipTopicCache),
|
|
119
118
|
msgIdToStrFn: msgIdToStrFn,
|
|
120
|
-
|
|
121
|
-
// could only be an issue on outgoing payloads, its highly unlikely we will send out
|
|
122
|
-
// a chunk bigger than GOSSIP_MAX_SIZE pre merge even on mainnet network.
|
|
123
|
-
//
|
|
124
|
-
// TODO: figure out a way to dynamically transition to the size
|
|
125
|
-
dataTransform: new DataTransformSnappy(
|
|
126
|
-
gossipTopicCache,
|
|
127
|
-
Number.isFinite(config.BELLATRIX_FORK_EPOCH) ? GOSSIP_MAX_SIZE_BELLATRIX : GOSSIP_MAX_SIZE
|
|
128
|
-
),
|
|
119
|
+
dataTransform: new DataTransformSnappy(gossipTopicCache, config.MAX_PAYLOAD_SIZE),
|
|
129
120
|
metricsRegister: metricsRegister as MetricsRegister | null,
|
|
130
121
|
metricsTopicStrToLabel: metricsRegister
|
|
131
122
|
? getMetricsTopicStrToLabel(networkConfig, {disableLightClientServer: opts.disableLightClientServer ?? false})
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ChainConfig} from "@lodestar/config";
|
|
2
|
-
import {
|
|
2
|
+
import {BLOB_SIDECAR_FIXED_SIZE, GENESIS_SLOT} from "@lodestar/params";
|
|
3
3
|
import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
|
|
4
4
|
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
5
5
|
import {Slot, deneb} from "@lodestar/types";
|
|
@@ -71,17 +71,17 @@ export function* iterateBlobBytesFromWrapper(
|
|
|
71
71
|
blockSlot: Slot
|
|
72
72
|
): Iterable<ResponseOutgoing> {
|
|
73
73
|
const allBlobSideCarsBytes = blobSideCarsBytesWrapped.slice(BLOB_SIDECARS_IN_WRAPPER_INDEX);
|
|
74
|
-
const blobsLen = allBlobSideCarsBytes.length /
|
|
74
|
+
const blobsLen = allBlobSideCarsBytes.length / BLOB_SIDECAR_FIXED_SIZE;
|
|
75
75
|
|
|
76
76
|
for (let index = 0; index < blobsLen; index++) {
|
|
77
77
|
const blobSideCarBytes = allBlobSideCarsBytes.slice(
|
|
78
|
-
index *
|
|
79
|
-
(index + 1) *
|
|
78
|
+
index * BLOB_SIDECAR_FIXED_SIZE,
|
|
79
|
+
(index + 1) * BLOB_SIDECAR_FIXED_SIZE
|
|
80
80
|
);
|
|
81
|
-
if (blobSideCarBytes.length !==
|
|
81
|
+
if (blobSideCarBytes.length !== BLOB_SIDECAR_FIXED_SIZE) {
|
|
82
82
|
throw new ResponseError(
|
|
83
83
|
RespStatus.SERVER_ERROR,
|
|
84
|
-
`Invalid blobSidecar index=${index} bytes length=${blobSideCarBytes.length} expected=${
|
|
84
|
+
`Invalid blobSidecar index=${index} bytes length=${blobSideCarBytes.length} expected=${BLOB_SIDECAR_FIXED_SIZE} for slot ${blockSlot} blobsLen=${blobsLen}`
|
|
85
85
|
);
|
|
86
86
|
}
|
|
87
87
|
yield {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {BLOB_SIDECAR_FIXED_SIZE} from "@lodestar/params";
|
|
2
2
|
import {RespStatus, ResponseError, ResponseOutgoing} from "@lodestar/reqresp";
|
|
3
3
|
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
4
4
|
import {RootHex} from "@lodestar/types";
|
|
@@ -45,12 +45,12 @@ export async function* onBlobSidecarsByRoot(
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
const blobSidecarBytes = lastFetchedSideCars.bytes.slice(
|
|
48
|
-
index *
|
|
49
|
-
(index + 1) *
|
|
48
|
+
index * BLOB_SIDECAR_FIXED_SIZE,
|
|
49
|
+
(index + 1) * BLOB_SIDECAR_FIXED_SIZE
|
|
50
50
|
);
|
|
51
|
-
if (blobSidecarBytes.length !==
|
|
51
|
+
if (blobSidecarBytes.length !== BLOB_SIDECAR_FIXED_SIZE) {
|
|
52
52
|
throw Error(
|
|
53
|
-
`Inconsistent state, blobSidecar blockRoot=${blockRootHex} index=${index} blobSidecarBytes=${blobSidecarBytes.length} expected=${
|
|
53
|
+
`Inconsistent state, blobSidecar blockRoot=${blockRootHex} index=${index} blobSidecarBytes=${blobSidecarBytes.length} expected=${BLOB_SIDECAR_FIXED_SIZE}`
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {BeaconConfig, ForkBoundary} from "@lodestar/config";
|
|
2
|
-
import {ATTESTATION_SUBNET_COUNT,
|
|
2
|
+
import {ATTESTATION_SUBNET_COUNT, SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
3
3
|
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
4
4
|
import {Epoch, Slot, SubnetID, ssz} from "@lodestar/types";
|
|
5
5
|
import {Logger, MapDef} from "@lodestar/utils";
|
|
@@ -92,8 +92,8 @@ export class AttnetsService implements IAttnetsService {
|
|
|
92
92
|
const shortLivedSubnets = this.committeeSubnets.getActiveTtl(this.clock.currentSlot);
|
|
93
93
|
|
|
94
94
|
const longLivedSubscriptionsToSlot =
|
|
95
|
-
(Math.floor(this.clock.currentEpoch /
|
|
96
|
-
|
|
95
|
+
(Math.floor(this.clock.currentEpoch / this.config.EPOCHS_PER_SUBNET_SUBSCRIPTION) + 1) *
|
|
96
|
+
this.config.EPOCHS_PER_SUBNET_SUBSCRIPTION *
|
|
97
97
|
SLOTS_PER_EPOCH;
|
|
98
98
|
const longLivedSubnets = Array.from(this.longLivedSubscriptions).map((subnet) => ({
|
|
99
99
|
subnet,
|
|
@@ -234,11 +234,11 @@ export class AttnetsService implements IAttnetsService {
|
|
|
234
234
|
|
|
235
235
|
/**
|
|
236
236
|
* Run per epoch, clean-up operations that are not urgent
|
|
237
|
-
* Subscribe to new random subnets every
|
|
237
|
+
* Subscribe to new random subnets every EPOCHS_PER_SUBNET_SUBSCRIPTION epochs
|
|
238
238
|
*/
|
|
239
239
|
private onEpoch = (epoch: Epoch): void => {
|
|
240
240
|
try {
|
|
241
|
-
if (epoch %
|
|
241
|
+
if (epoch % this.config.EPOCHS_PER_SUBNET_SUBSCRIPTION === 0) {
|
|
242
242
|
this.recomputeLongLivedSubnets();
|
|
243
243
|
}
|
|
244
244
|
} catch (e) {
|
|
@@ -253,7 +253,7 @@ export class AttnetsService implements IAttnetsService {
|
|
|
253
253
|
}
|
|
254
254
|
|
|
255
255
|
const oldSubnets = this.longLivedSubscriptions;
|
|
256
|
-
const newSubnets = computeSubscribedSubnet(this.nodeId, this.clock.currentEpoch);
|
|
256
|
+
const newSubnets = computeSubscribedSubnet(this.config, this.nodeId, this.clock.currentEpoch);
|
|
257
257
|
this.logger.verbose("Recomputing long-lived subscriptions", {
|
|
258
258
|
epoch: this.clock.currentEpoch,
|
|
259
259
|
oldSubnets: Array.from(oldSubnets).join(","),
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import {digest} from "@chainsafe/as-sha256";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
ATTESTATION_SUBNET_PREFIX_BITS,
|
|
5
|
-
EPOCHS_PER_SUBNET_SUBSCRIPTION,
|
|
6
|
-
NODE_ID_BITS,
|
|
7
|
-
SUBNETS_PER_NODE,
|
|
8
|
-
} from "@lodestar/params";
|
|
2
|
+
import {ChainConfig} from "@lodestar/config";
|
|
3
|
+
import {ATTESTATION_SUBNET_COUNT, ATTESTATION_SUBNET_PREFIX_BITS, NODE_ID_BITS} from "@lodestar/params";
|
|
9
4
|
import {computeShuffledIndex} from "@lodestar/state-transition";
|
|
10
5
|
import {Epoch, ssz} from "@lodestar/types";
|
|
11
6
|
import {NodeId} from "./interface.js";
|
|
@@ -13,10 +8,10 @@ import {NodeId} from "./interface.js";
|
|
|
13
8
|
/**
|
|
14
9
|
* Spec https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/p2p-interface.md
|
|
15
10
|
*/
|
|
16
|
-
export function computeSubscribedSubnet(nodeId: NodeId, epoch: Epoch): number[] {
|
|
11
|
+
export function computeSubscribedSubnet(config: ChainConfig, nodeId: NodeId, epoch: Epoch): number[] {
|
|
17
12
|
const subnets: number[] = [];
|
|
18
|
-
for (let index = 0; index < SUBNETS_PER_NODE; index++) {
|
|
19
|
-
subnets.push(computeSubscribedSubnetByIndex(nodeId, epoch, index));
|
|
13
|
+
for (let index = 0; index < config.SUBNETS_PER_NODE; index++) {
|
|
14
|
+
subnets.push(computeSubscribedSubnetByIndex(config, nodeId, epoch, index));
|
|
20
15
|
}
|
|
21
16
|
return subnets;
|
|
22
17
|
}
|
|
@@ -24,11 +19,16 @@ export function computeSubscribedSubnet(nodeId: NodeId, epoch: Epoch): number[]
|
|
|
24
19
|
/**
|
|
25
20
|
* Spec https://github.com/ethereum/consensus-specs/blob/v1.4.0-alpha.3/specs/phase0/p2p-interface.md
|
|
26
21
|
*/
|
|
27
|
-
export function computeSubscribedSubnetByIndex(
|
|
22
|
+
export function computeSubscribedSubnetByIndex(
|
|
23
|
+
config: ChainConfig,
|
|
24
|
+
nodeId: NodeId,
|
|
25
|
+
epoch: Epoch,
|
|
26
|
+
index: number
|
|
27
|
+
): number {
|
|
28
28
|
const nodeIdPrefix = getNodeIdPrefix(nodeId);
|
|
29
29
|
const nodeOffset = getNodeOffset(nodeId);
|
|
30
30
|
const permutationSeed = digest(
|
|
31
|
-
ssz.UintNum64.serialize(Math.floor((epoch + nodeOffset) / EPOCHS_PER_SUBNET_SUBSCRIPTION))
|
|
31
|
+
ssz.UintNum64.serialize(Math.floor((epoch + nodeOffset) / config.EPOCHS_PER_SUBNET_SUBSCRIPTION))
|
|
32
32
|
);
|
|
33
33
|
const permutatedPrefix = computeShuffledIndex(nodeIdPrefix, 1 << ATTESTATION_SUBNET_PREFIX_BITS, permutationSeed);
|
|
34
34
|
return (permutatedPrefix + index) % ATTESTATION_SUBNET_COUNT;
|
package/src/util/clock.ts
CHANGED
|
@@ -4,7 +4,6 @@ import {ChainForkConfig} from "@lodestar/config";
|
|
|
4
4
|
import {computeEpochAtSlot, computeTimeAtSlot, getCurrentSlot} from "@lodestar/state-transition";
|
|
5
5
|
import type {Epoch, Slot} from "@lodestar/types";
|
|
6
6
|
import {ErrorAborted} from "@lodestar/utils";
|
|
7
|
-
import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../constants/constants.js";
|
|
8
7
|
|
|
9
8
|
export enum ClockEvent {
|
|
10
9
|
/**
|
|
@@ -101,7 +100,7 @@ export class Clock extends EventEmitter implements IClock {
|
|
|
101
100
|
get currentSlotWithGossipDisparity(): Slot {
|
|
102
101
|
const currentSlot = this.currentSlot;
|
|
103
102
|
const nextSlotTime = computeTimeAtSlot(this.config, currentSlot + 1, this.genesisTime) * 1000;
|
|
104
|
-
return nextSlotTime - Date.now() < MAXIMUM_GOSSIP_CLOCK_DISPARITY ? currentSlot + 1 : currentSlot;
|
|
103
|
+
return nextSlotTime - Date.now() < this.config.MAXIMUM_GOSSIP_CLOCK_DISPARITY ? currentSlot + 1 : currentSlot;
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
get currentEpoch(): Epoch {
|
|
@@ -130,12 +129,12 @@ export class Clock extends EventEmitter implements IClock {
|
|
|
130
129
|
}
|
|
131
130
|
const nextSlotTime = computeTimeAtSlot(this.config, currentSlot + 1, this.genesisTime) * 1000;
|
|
132
131
|
// we're too close to next slot, accept next slot
|
|
133
|
-
if (nextSlotTime - Date.now() < MAXIMUM_GOSSIP_CLOCK_DISPARITY) {
|
|
132
|
+
if (nextSlotTime - Date.now() < this.config.MAXIMUM_GOSSIP_CLOCK_DISPARITY) {
|
|
134
133
|
return slot === currentSlot + 1;
|
|
135
134
|
}
|
|
136
135
|
const currentSlotTime = computeTimeAtSlot(this.config, currentSlot, this.genesisTime) * 1000;
|
|
137
136
|
// we've just passed the current slot, accept previous slot
|
|
138
|
-
if (Date.now() - currentSlotTime < MAXIMUM_GOSSIP_CLOCK_DISPARITY) {
|
|
137
|
+
if (Date.now() - currentSlotTime < this.config.MAXIMUM_GOSSIP_CLOCK_DISPARITY) {
|
|
139
138
|
return slot === currentSlot - 1;
|
|
140
139
|
}
|
|
141
140
|
return false;
|