@lodestar/beacon-node 1.41.0-dev.702f7932c2 → 1.41.0-dev.95cf2edc4c
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 +121 -3
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/state/index.js +8 -8
- package/lib/api/impl/beacon/state/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +3 -4
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js +5 -24
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +5 -2
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/lightclient/index.d.ts.map +1 -1
- package/lib/api/impl/lightclient/index.js +19 -2
- package/lib/api/impl/lightclient/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +104 -6
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +1 -0
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +9 -0
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts +5 -6
- package/lib/chain/archiveStore/historicalState/getHistoricalState.d.ts.map +1 -1
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js +9 -10
- package/lib/chain/archiveStore/historicalState/getHistoricalState.js.map +1 -1
- package/lib/chain/archiveStore/historicalState/worker.js +3 -3
- package/lib/chain/archiveStore/historicalState/worker.js.map +1 -1
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts +7 -0
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +1 -0
- package/lib/chain/archiveStore/utils/archivePayloads.js +10 -0
- package/lib/chain/archiveStore/utils/archivePayloads.js.map +1 -0
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +0 -2
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +2 -1
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writeBlockInputToDb.js +3 -0
- package/lib/chain/blocks/writeBlockInputToDb.js.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts +3 -3
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +5 -5
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/jobItem.d.ts +2 -2
- package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
- package/lib/chain/bls/multithread/jobItem.js +2 -2
- package/lib/chain/bls/multithread/jobItem.js.map +1 -1
- package/lib/chain/bls/singleThread.d.ts +4 -4
- package/lib/chain/bls/singleThread.d.ts.map +1 -1
- package/lib/chain/bls/singleThread.js +4 -4
- package/lib/chain/bls/singleThread.js.map +1 -1
- package/lib/chain/bls/utils.d.ts +2 -2
- package/lib/chain/bls/utils.d.ts.map +1 -1
- package/lib/chain/bls/utils.js +7 -4
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/chain.d.ts +6 -9
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +32 -16
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +2 -2
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/errors/blockError.d.ts +7 -1
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +2 -0
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/interface.d.ts +4 -6
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/lightClient/index.d.ts.map +1 -1
- package/lib/chain/lightClient/index.js +1 -1
- package/lib/chain/lightClient/index.js.map +1 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.js +3 -3
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts +10 -2
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +24 -2
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +22 -7
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +110 -10
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +4 -1
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +1 -1
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +27 -3
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.d.ts +2 -2
- package/lib/chain/validation/dataColumnSidecar.d.ts.map +1 -1
- package/lib/chain/validation/dataColumnSidecar.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +2 -1
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +8 -1
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js +1 -1
- package/lib/db/beacon.d.ts +3 -1
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +5 -1
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/buckets.d.ts +3 -1
- package/lib/db/buckets.d.ts.map +1 -1
- package/lib/db/buckets.js +2 -0
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/interface.d.ts +3 -1
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/blockArchiveIndex.d.ts +2 -2
- package/lib/db/repositories/blockArchiveIndex.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecar.d.ts +5 -3
- package/lib/db/repositories/dataColumnSidecar.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecar.js +14 -1
- package/lib/db/repositories/dataColumnSidecar.js.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.d.ts +5 -3
- package/lib/db/repositories/dataColumnSidecarArchive.d.ts.map +1 -1
- package/lib/db/repositories/dataColumnSidecarArchive.js +14 -1
- package/lib/db/repositories/dataColumnSidecarArchive.js.map +1 -1
- package/lib/db/repositories/executionPayloadEnvelope.d.ts +19 -0
- package/lib/db/repositories/executionPayloadEnvelope.d.ts.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelope.js +22 -0
- package/lib/db/repositories/executionPayloadEnvelope.js.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts +18 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.d.ts.map +1 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js +28 -0
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -0
- package/lib/db/repositories/index.d.ts +2 -0
- package/lib/db/repositories/index.d.ts.map +1 -1
- package/lib/db/repositories/index.js +2 -0
- package/lib/db/repositories/index.js.map +1 -1
- package/lib/metrics/metrics/beacon.d.ts +1 -0
- package/lib/metrics/metrics/beacon.d.ts.map +1 -1
- package/lib/metrics/metrics/beacon.js +5 -0
- package/lib/metrics/metrics/beacon.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +5 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +9 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/metrics/metrics.d.ts.map +1 -1
- package/lib/metrics/metrics.js +8 -3
- package/lib/metrics/metrics.js.map +1 -1
- package/lib/monitoring/service.d.ts +2 -2
- package/lib/monitoring/service.d.ts.map +1 -1
- package/lib/monitoring/service.js +3 -2
- package/lib/monitoring/service.js.map +1 -1
- package/lib/network/gossip/interface.d.ts +3 -3
- package/lib/network/gossip/interface.d.ts.map +1 -1
- package/lib/network/gossip/topic.d.ts +114 -65
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +2 -2
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/interface.d.ts +3 -2
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +3 -2
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +10 -1
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +5 -1
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/reqresp/handlers/lightClientUpdatesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js +7 -1
- package/lib/network/reqresp/handlers/lightClientUpdatesByRange.js.map +1 -1
- package/lib/node/nodejs.d.ts +3 -5
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +6 -4
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +3 -9
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +4 -4
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/util/blobs.d.ts +2 -2
- package/lib/util/blobs.d.ts.map +1 -1
- package/lib/util/blobs.js.map +1 -1
- package/lib/util/dataColumns.d.ts +15 -2
- package/lib/util/dataColumns.d.ts.map +1 -1
- package/lib/util/dataColumns.js +40 -5
- package/lib/util/dataColumns.js.map +1 -1
- package/lib/util/multifork.d.ts +8 -0
- package/lib/util/multifork.d.ts.map +1 -1
- package/lib/util/multifork.js +37 -0
- package/lib/util/multifork.js.map +1 -1
- package/lib/util/serializedCache.d.ts +5 -0
- package/lib/util/serializedCache.d.ts.map +1 -1
- package/lib/util/serializedCache.js +5 -0
- package/lib/util/serializedCache.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +145 -2
- package/src/api/impl/beacon/state/index.ts +8 -8
- package/src/api/impl/beacon/state/utils.ts +15 -29
- package/src/api/impl/debug/index.ts +8 -5
- package/src/api/impl/lightclient/index.ts +19 -2
- package/src/api/impl/validator/index.ts +127 -5
- package/src/chain/archiveStore/archiveStore.ts +10 -0
- package/src/chain/archiveStore/historicalState/getHistoricalState.ts +10 -11
- package/src/chain/archiveStore/historicalState/worker.ts +3 -3
- package/src/chain/archiveStore/utils/archivePayloads.ts +15 -0
- package/src/chain/blocks/importBlock.ts +0 -3
- package/src/chain/blocks/index.ts +2 -1
- package/src/chain/blocks/writeBlockInputToDb.ts +3 -0
- package/src/chain/bls/multithread/index.ts +7 -7
- package/src/chain/bls/multithread/jobItem.ts +3 -3
- package/src/chain/bls/singleThread.ts +5 -5
- package/src/chain/bls/utils.ts +8 -5
- package/src/chain/chain.ts +51 -26
- package/src/chain/emitter.ts +2 -2
- package/src/chain/errors/blockError.ts +4 -1
- package/src/chain/interface.ts +4 -11
- package/src/chain/lightClient/index.ts +4 -1
- package/src/chain/options.ts +1 -0
- package/src/chain/prepareNextSlot.ts +5 -5
- package/src/chain/produceBlock/computeNewStateRoot.ts +35 -3
- package/src/chain/produceBlock/produceBlockBody.ts +163 -13
- package/src/chain/validation/attestation.ts +4 -1
- package/src/chain/validation/attesterSlashing.ts +1 -1
- package/src/chain/validation/block.ts +32 -4
- package/src/chain/validation/dataColumnSidecar.ts +2 -5
- package/src/chain/validation/executionPayloadEnvelope.ts +2 -1
- package/src/chain/validation/payloadAttestationMessage.ts +10 -2
- package/src/chain/validation/proposerSlashing.ts +1 -1
- package/src/chain/validation/syncCommitteeContributionAndProof.ts +1 -1
- package/src/db/beacon.ts +8 -0
- package/src/db/buckets.ts +3 -0
- package/src/db/interface.ts +5 -0
- package/src/db/repositories/dataColumnSidecar.ts +18 -3
- package/src/db/repositories/dataColumnSidecarArchive.ts +18 -3
- package/src/db/repositories/executionPayloadEnvelope.ts +26 -0
- package/src/db/repositories/executionPayloadEnvelopeArchive.ts +32 -0
- package/src/db/repositories/index.ts +2 -0
- package/src/metrics/metrics/beacon.ts +5 -0
- package/src/metrics/metrics/lodestar.ts +9 -0
- package/src/metrics/metrics.ts +8 -3
- package/src/monitoring/service.ts +3 -2
- package/src/network/gossip/interface.ts +3 -3
- package/src/network/gossip/topic.ts +2 -1
- package/src/network/interface.ts +4 -1
- package/src/network/network.ts +21 -3
- package/src/network/processor/gossipHandlers.ts +7 -1
- package/src/network/reqresp/handlers/lightClientUpdatesByRange.ts +6 -1
- package/src/node/nodejs.ts +8 -9
- package/src/sync/utils/downloadByRange.ts +3 -15
- package/src/sync/utils/downloadByRoot.ts +5 -11
- package/src/util/blobs.ts +3 -3
- package/src/util/dataColumns.ts +54 -5
- package/src/util/multifork.ts +45 -0
- package/src/util/serializedCache.ts +5 -0
|
@@ -827,6 +827,15 @@ export function createLodestarMetrics(
|
|
|
827
827
|
help: "Total number of blobs retrieved from execution engine and published to gossip",
|
|
828
828
|
}),
|
|
829
829
|
},
|
|
830
|
+
// Gossip execution payload envelope
|
|
831
|
+
gossipExecutionPayloadEnvelope: {
|
|
832
|
+
elapsedTimeTillReceived: register.histogram<{source: OpSource}>({
|
|
833
|
+
name: "lodestar_gossip_execution_payload_envelope_elapsed_time_till_received",
|
|
834
|
+
help: "Time elapsed between slot time and the time execution payload envelope received",
|
|
835
|
+
labelNames: ["source"],
|
|
836
|
+
buckets: [0.5, 1, 2, 4, 6, 12],
|
|
837
|
+
}),
|
|
838
|
+
},
|
|
830
839
|
recoverDataColumnSidecars: {
|
|
831
840
|
recoverTime: register.histogram({
|
|
832
841
|
name: "lodestar_recover_data_column_sidecar_recover_time_seconds",
|
package/src/metrics/metrics.ts
CHANGED
|
@@ -19,11 +19,16 @@ export function createMetrics(opts: MetricsOptions, genesisTime: number, externa
|
|
|
19
19
|
const lodestar = createLodestarMetrics(register, opts.metadata, genesisTime);
|
|
20
20
|
const stateTransition = getMetrics(register);
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
const onUnhandledRejection = (_error: unknown): void => {
|
|
23
23
|
lodestar.unhandledPromiseRejections.inc();
|
|
24
|
-
}
|
|
24
|
+
};
|
|
25
|
+
process.on("unhandledRejection", onUnhandledRejection);
|
|
25
26
|
|
|
26
|
-
const
|
|
27
|
+
const nodeJsMetricsClose = collectNodeJSMetrics(register);
|
|
28
|
+
const close = (): void => {
|
|
29
|
+
process.removeListener("unhandledRejection", onUnhandledRejection);
|
|
30
|
+
nodeJsMetricsClose();
|
|
31
|
+
};
|
|
27
32
|
|
|
28
33
|
// Merge external registries
|
|
29
34
|
for (const externalRegister of externalRegistries) {
|
|
@@ -89,9 +89,9 @@ export class MonitoringService {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
|
-
* Stop sending client stats
|
|
92
|
+
* Stop sending client stats and wait for any pending request to complete
|
|
93
93
|
*/
|
|
94
|
-
close(): void {
|
|
94
|
+
async close(): Promise<void> {
|
|
95
95
|
if (this.status === Status.Closed) return;
|
|
96
96
|
this.status = Status.Closed;
|
|
97
97
|
|
|
@@ -103,6 +103,7 @@ export class MonitoringService {
|
|
|
103
103
|
}
|
|
104
104
|
if (this.pendingRequest) {
|
|
105
105
|
this.fetchAbortController?.abort(FetchAbortReason.Close);
|
|
106
|
+
await this.pendingRequest;
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
@@ -4,6 +4,7 @@ import {PeerIdStr} from "@chainsafe/libp2p-gossipsub/types";
|
|
|
4
4
|
import {BeaconConfig, ForkBoundary} from "@lodestar/config";
|
|
5
5
|
import {
|
|
6
6
|
AttesterSlashing,
|
|
7
|
+
DataColumnSidecar,
|
|
7
8
|
LightClientFinalityUpdate,
|
|
8
9
|
LightClientOptimisticUpdate,
|
|
9
10
|
SignedAggregateAndProof,
|
|
@@ -14,7 +15,6 @@ import {
|
|
|
14
15
|
altair,
|
|
15
16
|
capella,
|
|
16
17
|
deneb,
|
|
17
|
-
fulu,
|
|
18
18
|
gloas,
|
|
19
19
|
phase0,
|
|
20
20
|
} from "@lodestar/types";
|
|
@@ -98,7 +98,7 @@ export type GossipTypeMap = {
|
|
|
98
98
|
[GossipType.blob_sidecar]: deneb.BlobSidecar;
|
|
99
99
|
[GossipType.beacon_aggregate_and_proof]: SignedAggregateAndProof;
|
|
100
100
|
[GossipType.beacon_attestation]: SingleAttestation;
|
|
101
|
-
[GossipType.data_column_sidecar]:
|
|
101
|
+
[GossipType.data_column_sidecar]: DataColumnSidecar;
|
|
102
102
|
[GossipType.voluntary_exit]: phase0.SignedVoluntaryExit;
|
|
103
103
|
[GossipType.proposer_slashing]: phase0.ProposerSlashing;
|
|
104
104
|
[GossipType.attester_slashing]: AttesterSlashing;
|
|
@@ -117,7 +117,7 @@ export type GossipFnByType = {
|
|
|
117
117
|
[GossipType.blob_sidecar]: (blobSidecar: deneb.BlobSidecar) => Promise<void> | void;
|
|
118
118
|
[GossipType.beacon_aggregate_and_proof]: (aggregateAndProof: SignedAggregateAndProof) => Promise<void> | void;
|
|
119
119
|
[GossipType.beacon_attestation]: (attestation: SingleAttestation) => Promise<void> | void;
|
|
120
|
-
[GossipType.data_column_sidecar]: (dataColumnSidecar:
|
|
120
|
+
[GossipType.data_column_sidecar]: (dataColumnSidecar: DataColumnSidecar) => Promise<void> | void;
|
|
121
121
|
[GossipType.voluntary_exit]: (voluntaryExit: phase0.SignedVoluntaryExit) => Promise<void> | void;
|
|
122
122
|
[GossipType.proposer_slashing]: (proposerSlashing: phase0.ProposerSlashing) => Promise<void> | void;
|
|
123
123
|
[GossipType.attester_slashing]: (attesterSlashing: AttesterSlashing) => Promise<void> | void;
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
SYNC_COMMITTEE_SUBNET_COUNT,
|
|
7
7
|
isForkPostAltair,
|
|
8
8
|
isForkPostElectra,
|
|
9
|
+
isForkPostFulu,
|
|
9
10
|
} from "@lodestar/params";
|
|
10
11
|
import {Attestation, SingleAttestation, ssz, sszTypesFor} from "@lodestar/types";
|
|
11
12
|
import {GossipAction, GossipActionError, GossipErrorCode} from "../../chain/errors/gossipValidation.js";
|
|
@@ -92,7 +93,7 @@ export function getGossipSSZType(topic: GossipTopic) {
|
|
|
92
93
|
case GossipType.blob_sidecar:
|
|
93
94
|
return ssz.deneb.BlobSidecar;
|
|
94
95
|
case GossipType.data_column_sidecar:
|
|
95
|
-
return ssz.fulu.DataColumnSidecar;
|
|
96
|
+
return isForkPostFulu(fork) ? sszTypesFor(fork).DataColumnSidecar : ssz.fulu.DataColumnSidecar;
|
|
96
97
|
case GossipType.beacon_aggregate_and_proof:
|
|
97
98
|
return sszTypesFor(fork).SignedAggregateAndProof;
|
|
98
99
|
case GossipType.beacon_attestation:
|
package/src/network/interface.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type {Datastore} from "interface-datastore";
|
|
|
19
19
|
import {Libp2p as ILibp2p} from "libp2p";
|
|
20
20
|
import {
|
|
21
21
|
AttesterSlashing,
|
|
22
|
+
DataColumnSidecar,
|
|
22
23
|
LightClientFinalityUpdate,
|
|
23
24
|
LightClientOptimisticUpdate,
|
|
24
25
|
SignedAggregateAndProof,
|
|
@@ -31,6 +32,7 @@ import {
|
|
|
31
32
|
capella,
|
|
32
33
|
deneb,
|
|
33
34
|
fulu,
|
|
35
|
+
gloas,
|
|
34
36
|
phase0,
|
|
35
37
|
} from "@lodestar/types";
|
|
36
38
|
import {BlockInputSource} from "../chain/blocks/blockInput/types.js";
|
|
@@ -86,7 +88,7 @@ export interface INetwork extends INetworkCorePublic {
|
|
|
86
88
|
publishBlobSidecar(blobSidecar: deneb.BlobSidecar): Promise<number>;
|
|
87
89
|
publishBeaconAggregateAndProof(aggregateAndProof: SignedAggregateAndProof): Promise<number>;
|
|
88
90
|
publishBeaconAttestation(attestation: SingleAttestation, subnet: SubnetID): Promise<number>;
|
|
89
|
-
publishDataColumnSidecar(dataColumnSideCar:
|
|
91
|
+
publishDataColumnSidecar(dataColumnSideCar: DataColumnSidecar): Promise<number>;
|
|
90
92
|
publishVoluntaryExit(voluntaryExit: phase0.SignedVoluntaryExit): Promise<number>;
|
|
91
93
|
publishBlsToExecutionChange(blsToExecutionChange: capella.SignedBLSToExecutionChange): Promise<number>;
|
|
92
94
|
publishProposerSlashing(proposerSlashing: phase0.ProposerSlashing): Promise<number>;
|
|
@@ -95,6 +97,7 @@ export interface INetwork extends INetworkCorePublic {
|
|
|
95
97
|
publishContributionAndProof(contributionAndProof: altair.SignedContributionAndProof): Promise<number>;
|
|
96
98
|
publishLightClientFinalityUpdate(update: LightClientFinalityUpdate): Promise<number>;
|
|
97
99
|
publishLightClientOptimisticUpdate(update: LightClientOptimisticUpdate): Promise<number>;
|
|
100
|
+
publishSignedExecutionPayloadEnvelope(signedEnvelope: gloas.SignedExecutionPayloadEnvelope): Promise<number>;
|
|
98
101
|
|
|
99
102
|
// Debug
|
|
100
103
|
dumpGossipQueue(gossipType: GossipType): Promise<PendingGossipsubMessage[]>;
|
package/src/network/network.ts
CHANGED
|
@@ -10,6 +10,8 @@ import {ResponseIncoming} from "@lodestar/reqresp";
|
|
|
10
10
|
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
|
11
11
|
import {
|
|
12
12
|
AttesterSlashing,
|
|
13
|
+
DataColumnSidecar,
|
|
14
|
+
DataColumnSidecars,
|
|
13
15
|
LightClientBootstrap,
|
|
14
16
|
LightClientFinalityUpdate,
|
|
15
17
|
LightClientOptimisticUpdate,
|
|
@@ -24,6 +26,8 @@ import {
|
|
|
24
26
|
capella,
|
|
25
27
|
deneb,
|
|
26
28
|
fulu,
|
|
29
|
+
gloas,
|
|
30
|
+
isGloasDataColumnSidecar,
|
|
27
31
|
phase0,
|
|
28
32
|
} from "@lodestar/types";
|
|
29
33
|
import {prettyPrintIndices, sleep} from "@lodestar/utils";
|
|
@@ -354,8 +358,11 @@ export class Network implements INetwork {
|
|
|
354
358
|
});
|
|
355
359
|
}
|
|
356
360
|
|
|
357
|
-
async publishDataColumnSidecar(dataColumnSidecar:
|
|
358
|
-
const
|
|
361
|
+
async publishDataColumnSidecar(dataColumnSidecar: DataColumnSidecar): Promise<number> {
|
|
362
|
+
const slot = isGloasDataColumnSidecar(dataColumnSidecar)
|
|
363
|
+
? dataColumnSidecar.slot
|
|
364
|
+
: dataColumnSidecar.signedBlockHeader.message.slot;
|
|
365
|
+
const epoch = computeEpochAtSlot(slot);
|
|
359
366
|
const boundary = this.config.getForkBoundaryAtEpoch(epoch);
|
|
360
367
|
|
|
361
368
|
const subnet = computeSubnetForDataColumnSidecar(this.config, dataColumnSidecar);
|
|
@@ -489,6 +496,17 @@ export class Network implements INetwork {
|
|
|
489
496
|
);
|
|
490
497
|
}
|
|
491
498
|
|
|
499
|
+
async publishSignedExecutionPayloadEnvelope(signedEnvelope: gloas.SignedExecutionPayloadEnvelope): Promise<number> {
|
|
500
|
+
const epoch = computeEpochAtSlot(signedEnvelope.message.slot);
|
|
501
|
+
const boundary = this.config.getForkBoundaryAtEpoch(epoch);
|
|
502
|
+
|
|
503
|
+
return this.publishGossip<GossipType.execution_payload>(
|
|
504
|
+
{type: GossipType.execution_payload, boundary},
|
|
505
|
+
signedEnvelope,
|
|
506
|
+
{ignoreDuplicatePublishError: true}
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
|
|
492
510
|
private async publishGossip<K extends GossipType>(
|
|
493
511
|
topic: GossipTopicMap[K],
|
|
494
512
|
object: GossipTypeMap[K],
|
|
@@ -765,7 +783,7 @@ export class Network implements INetwork {
|
|
|
765
783
|
this.core.setTargetGroupCount(count);
|
|
766
784
|
};
|
|
767
785
|
|
|
768
|
-
private onPublishDataColumns = (sidecars:
|
|
786
|
+
private onPublishDataColumns = (sidecars: DataColumnSidecars): Promise<number[]> => {
|
|
769
787
|
return promiseAllMaybeAsync(sidecars.map((sidecar) => () => this.publishDataColumnSidecar(sidecar)));
|
|
770
788
|
};
|
|
771
789
|
|
|
@@ -548,7 +548,8 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
548
548
|
seenTimestampSec,
|
|
549
549
|
}: GossipHandlerParamGeneric<GossipType.data_column_sidecar>) => {
|
|
550
550
|
const {serializedData} = gossipData;
|
|
551
|
-
|
|
551
|
+
// TODO GLOAS: handle gloas.DataColumnSidecar
|
|
552
|
+
const dataColumnSidecar = sszDeserialize(topic, serializedData) as fulu.DataColumnSidecar;
|
|
552
553
|
const dataColumnSlot = dataColumnSidecar.signedBlockHeader.message.slot;
|
|
553
554
|
const index = dataColumnSidecar.index;
|
|
554
555
|
|
|
@@ -821,11 +822,16 @@ function getSequentialHandlers(modules: ValidatorFnsModules, options: GossipHand
|
|
|
821
822
|
[GossipType.execution_payload]: async ({
|
|
822
823
|
gossipData,
|
|
823
824
|
topic,
|
|
825
|
+
seenTimestampSec,
|
|
824
826
|
}: GossipHandlerParamGeneric<GossipType.execution_payload>) => {
|
|
825
827
|
const {serializedData} = gossipData;
|
|
826
828
|
const executionPayloadEnvelope = sszDeserialize(topic, serializedData);
|
|
827
829
|
await validateGossipExecutionPayloadEnvelope(chain, executionPayloadEnvelope);
|
|
828
830
|
|
|
831
|
+
const slot = executionPayloadEnvelope.message.slot;
|
|
832
|
+
const delaySec = seenTimestampSec - computeTimeAtSlot(config, slot, chain.genesisTime);
|
|
833
|
+
metrics?.gossipExecutionPayloadEnvelope.elapsedTimeTillReceived.observe({source: OpSource.gossip}, delaySec);
|
|
834
|
+
|
|
829
835
|
// TODO GLOAS: Handle valid envelope. Need an import flow that calls `processExecutionPayloadEnvelope` and fork choice
|
|
830
836
|
},
|
|
831
837
|
[GossipType.payload_attestation_message]: async ({
|
|
@@ -19,6 +19,7 @@ export async function* onLightClientUpdatesByRange(
|
|
|
19
19
|
assertLightClientServer(chain.lightClientServer);
|
|
20
20
|
|
|
21
21
|
const count = Math.min(MAX_REQUEST_LIGHT_CLIENT_UPDATES, requestBody.count);
|
|
22
|
+
let started = false;
|
|
22
23
|
for (let period = requestBody.startPeriod; period < requestBody.startPeriod + count; period++) {
|
|
23
24
|
try {
|
|
24
25
|
const update = await chain.lightClientServer.getUpdate(period);
|
|
@@ -29,9 +30,13 @@ export async function* onLightClientUpdatesByRange(
|
|
|
29
30
|
data: type.serialize(update),
|
|
30
31
|
boundary,
|
|
31
32
|
};
|
|
33
|
+
started = true;
|
|
32
34
|
} catch (e) {
|
|
33
35
|
if ((e as LightClientServerError).type?.code === LightClientServerErrorCode.RESOURCE_UNAVAILABLE) {
|
|
34
|
-
|
|
36
|
+
// Period not available, if we already started yielding, stop to
|
|
37
|
+
// preserve consecutive order. Otherwise skip leading gaps.
|
|
38
|
+
if (started) return;
|
|
39
|
+
continue;
|
|
35
40
|
}
|
|
36
41
|
throw new ResponseError(RespStatus.SERVER_ERROR, (e as Error).message);
|
|
37
42
|
}
|
package/src/node/nodejs.ts
CHANGED
|
@@ -2,12 +2,11 @@ import {setMaxListeners} from "node:events";
|
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
3
|
import {Registry} from "prom-client";
|
|
4
4
|
import {hasher} from "@chainsafe/persistent-merkle-tree";
|
|
5
|
-
import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
|
|
6
5
|
import {BeaconApiMethods} from "@lodestar/api/beacon/server";
|
|
7
6
|
import {BeaconConfig} from "@lodestar/config";
|
|
8
7
|
import type {LoggerNode} from "@lodestar/logger/node";
|
|
9
8
|
import {ZERO_HASH_HEX} from "@lodestar/params";
|
|
10
|
-
import {CachedBeaconStateAllForks,
|
|
9
|
+
import {CachedBeaconStateAllForks, PubkeyCache, isExecutionCachedStateType} from "@lodestar/state-transition";
|
|
11
10
|
import {phase0} from "@lodestar/types";
|
|
12
11
|
import {sleep, toRootHex} from "@lodestar/utils";
|
|
13
12
|
import {ProcessShutdownCallback} from "@lodestar/validator";
|
|
@@ -47,8 +46,7 @@ export type BeaconNodeModules = {
|
|
|
47
46
|
export type BeaconNodeInitModules = {
|
|
48
47
|
opts: IBeaconNodeOptions;
|
|
49
48
|
config: BeaconConfig;
|
|
50
|
-
|
|
51
|
-
index2pubkey: Index2PubkeyCache;
|
|
49
|
+
pubkeyCache: PubkeyCache;
|
|
52
50
|
db: IBeaconDb;
|
|
53
51
|
logger: LoggerNode;
|
|
54
52
|
processShutdownCallback: ProcessShutdownCallback;
|
|
@@ -150,8 +148,7 @@ export class BeaconNode {
|
|
|
150
148
|
static async init<T extends BeaconNode = BeaconNode>({
|
|
151
149
|
opts,
|
|
152
150
|
config,
|
|
153
|
-
|
|
154
|
-
index2pubkey,
|
|
151
|
+
pubkeyCache,
|
|
155
152
|
db,
|
|
156
153
|
logger,
|
|
157
154
|
processShutdownCallback,
|
|
@@ -240,8 +237,7 @@ export class BeaconNode {
|
|
|
240
237
|
privateKey,
|
|
241
238
|
config,
|
|
242
239
|
clock,
|
|
243
|
-
|
|
244
|
-
index2pubkey,
|
|
240
|
+
pubkeyCache,
|
|
245
241
|
dataDir,
|
|
246
242
|
db,
|
|
247
243
|
dbName: opts.db.name,
|
|
@@ -364,9 +360,12 @@ export class BeaconNode {
|
|
|
364
360
|
if (this.restApi) await this.restApi.close();
|
|
365
361
|
await this.network.close();
|
|
366
362
|
if (this.metricsServer) await this.metricsServer.close();
|
|
367
|
-
if (this.monitoring) this.monitoring.close();
|
|
363
|
+
if (this.monitoring) await this.monitoring.close();
|
|
368
364
|
await this.chain.persistToDisk();
|
|
369
365
|
await this.chain.close();
|
|
366
|
+
// Abort signal last: close() calls above clear intervals/timeouts so no new
|
|
367
|
+
// operations get scheduled. If we aborted first, a still-pending interval could
|
|
368
|
+
// fire and schedule a new operation after abort, leaving it stuck and delaying shutdown.
|
|
370
369
|
if (this.controller) this.controller.abort();
|
|
371
370
|
await sleep(DELAY_BEFORE_CLOSING_DB_MS);
|
|
372
371
|
await this.db.close();
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {
|
|
3
|
-
ForkPostDeneb,
|
|
4
|
-
ForkPostFulu,
|
|
5
|
-
ForkPreFulu,
|
|
6
|
-
ForkPreGloas,
|
|
7
|
-
isForkPostFulu,
|
|
8
|
-
isForkPostGloas,
|
|
9
|
-
} from "@lodestar/params";
|
|
2
|
+
import {ForkPostDeneb, ForkPostFulu, ForkPreFulu, isForkPostFulu} from "@lodestar/params";
|
|
10
3
|
import {SignedBeaconBlock, Slot, deneb, fulu, phase0} from "@lodestar/types";
|
|
11
4
|
import {LodestarError, Logger, byteArrayEquals, fromHex, prettyPrintIndices, toRootHex} from "@lodestar/utils";
|
|
12
5
|
import {
|
|
@@ -20,6 +13,7 @@ import {SeenBlockInput} from "../../chain/seenCache/seenGossipBlockInput.js";
|
|
|
20
13
|
import {validateBlockBlobSidecars} from "../../chain/validation/blobSidecar.js";
|
|
21
14
|
import {validateBlockDataColumnSidecars} from "../../chain/validation/dataColumnSidecar.js";
|
|
22
15
|
import {INetwork} from "../../network/index.js";
|
|
16
|
+
import {getBlobKzgCommitments} from "../../util/dataColumns.js";
|
|
23
17
|
import {PeerIdStr} from "../../util/peerId.js";
|
|
24
18
|
import {WarnResult} from "../../util/wrapError.js";
|
|
25
19
|
|
|
@@ -695,13 +689,7 @@ export async function validateColumnsByRangeResponse(
|
|
|
695
689
|
dataFork: dataSlot ? config.getForkName(dataSlot) : "unknown",
|
|
696
690
|
});
|
|
697
691
|
}
|
|
698
|
-
|
|
699
|
-
// TODO GLOAS: Post-gloas's blobKzgCommitments is not in beacon block body. Need to source it from somewhere else.
|
|
700
|
-
// if block without columns is passed default to zero and throw below
|
|
701
|
-
blobCount = 0;
|
|
702
|
-
} else {
|
|
703
|
-
blobCount = (block as SignedBeaconBlock<ForkPostFulu & ForkPreGloas>).message.body.blobKzgCommitments.length;
|
|
704
|
-
}
|
|
692
|
+
blobCount = getBlobKzgCommitments(forkName, block as SignedBeaconBlock<ForkPostFulu>).length;
|
|
705
693
|
|
|
706
694
|
if (columnSidecars.length === 0) {
|
|
707
695
|
if (!blobCount) {
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
2
|
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
ForkPostFulu,
|
|
6
|
-
ForkPreFulu,
|
|
7
|
-
ForkPreGloas,
|
|
8
|
-
isForkPostDeneb,
|
|
9
|
-
isForkPostFulu,
|
|
10
|
-
} from "@lodestar/params";
|
|
11
|
-
import {BeaconBlockBody, BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
3
|
+
import {ForkPostDeneb, ForkPostFulu, ForkPreFulu, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
|
|
4
|
+
import {BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
|
|
12
5
|
import {LodestarError, byteArrayEquals, fromHex, prettyPrintIndices, toHex, toRootHex} from "@lodestar/utils";
|
|
13
6
|
import {isBlockInputBlobs, isBlockInputColumns} from "../../chain/blocks/blockInput/blockInput.js";
|
|
14
7
|
import {BlockInputSource, IBlockInput} from "../../chain/blocks/blockInput/types.js";
|
|
@@ -19,6 +12,7 @@ import {validateBlockDataColumnSidecars} from "../../chain/validation/dataColumn
|
|
|
19
12
|
import {INetwork} from "../../network/interface.js";
|
|
20
13
|
import {PeerSyncMeta} from "../../network/peers/peersData.js";
|
|
21
14
|
import {prettyPrintPeerIdStr} from "../../network/util.js";
|
|
15
|
+
import {getBlobKzgCommitments} from "../../util/dataColumns.js";
|
|
22
16
|
import {PeerIdStr} from "../../util/peerId.js";
|
|
23
17
|
import {WarnResult} from "../../util/wrapError.js";
|
|
24
18
|
import {
|
|
@@ -378,14 +372,14 @@ export async function fetchAndValidateColumns({
|
|
|
378
372
|
chain,
|
|
379
373
|
network,
|
|
380
374
|
peerMeta,
|
|
375
|
+
forkName,
|
|
381
376
|
block,
|
|
382
377
|
blockRoot,
|
|
383
378
|
missing,
|
|
384
379
|
}: FetchByRootAndValidateColumnsProps): Promise<WarnResult<fulu.DataColumnSidecars, DownloadByRootError>> {
|
|
385
380
|
const {peerId: peerIdStr} = peerMeta;
|
|
386
381
|
const slot = block.message.slot;
|
|
387
|
-
|
|
388
|
-
const blobCount = (block.message.body as BeaconBlockBody<ForkPostFulu & ForkPreGloas>).blobKzgCommitments.length;
|
|
382
|
+
const blobCount = getBlobKzgCommitments(forkName, block).length;
|
|
389
383
|
if (blobCount === 0) {
|
|
390
384
|
return {result: [], warnings: null};
|
|
391
385
|
}
|
package/src/util/blobs.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
VERSIONED_HASH_VERSION_KZG,
|
|
14
14
|
} from "@lodestar/params";
|
|
15
15
|
import {signedBlockToSignedHeader} from "@lodestar/state-transition";
|
|
16
|
-
import {BeaconBlockBody, SSZTypesFor, SignedBeaconBlock, deneb, fulu, ssz} from "@lodestar/types";
|
|
16
|
+
import {BeaconBlockBody, DataColumnSidecars, SSZTypesFor, SignedBeaconBlock, deneb, fulu, ssz} from "@lodestar/types";
|
|
17
17
|
import {kzg} from "./kzg.js";
|
|
18
18
|
|
|
19
19
|
type VersionHash = Uint8Array;
|
|
@@ -149,7 +149,7 @@ export async function dataColumnMatrixRecovery(
|
|
|
149
149
|
* Reconstruct blobs from a set of data columns, at least 50%+ of all the columns
|
|
150
150
|
* must be provided to allow to reconstruct the full data matrix
|
|
151
151
|
*/
|
|
152
|
-
export async function reconstructBlobs(sidecars:
|
|
152
|
+
export async function reconstructBlobs(sidecars: DataColumnSidecars, indices?: number[]): Promise<deneb.Blobs> {
|
|
153
153
|
if (sidecars.length < NUMBER_OF_COLUMNS / 2) {
|
|
154
154
|
throw Error(
|
|
155
155
|
`Expected at least ${NUMBER_OF_COLUMNS / 2} data columns to reconstruct blobs, received ${sidecars.length}`
|
|
@@ -188,7 +188,7 @@ export async function reconstructBlobs(sidecars: fulu.DataColumnSidecars, indice
|
|
|
188
188
|
* Recover cells for specific blob indices from a set of data columns
|
|
189
189
|
*/
|
|
190
190
|
async function recoverBlobCells(
|
|
191
|
-
partialSidecars:
|
|
191
|
+
partialSidecars: DataColumnSidecars,
|
|
192
192
|
blobIndices: number[]
|
|
193
193
|
): Promise<Map<number, fulu.Cell[]> | null> {
|
|
194
194
|
const columnCount = partialSidecars.length;
|
package/src/util/dataColumns.ts
CHANGED
|
@@ -4,21 +4,26 @@ import {ChainForkConfig} from "@lodestar/config";
|
|
|
4
4
|
import {
|
|
5
5
|
ForkAll,
|
|
6
6
|
ForkName,
|
|
7
|
+
ForkPostDeneb,
|
|
7
8
|
ForkPostFulu,
|
|
8
9
|
ForkPreGloas,
|
|
9
10
|
KZG_COMMITMENTS_GINDEX,
|
|
10
11
|
NUMBER_OF_COLUMNS,
|
|
12
|
+
isForkPostGloas,
|
|
11
13
|
} from "@lodestar/params";
|
|
12
14
|
import {signedBlockToSignedHeader} from "@lodestar/state-transition";
|
|
13
15
|
import {
|
|
14
16
|
BeaconBlockBody,
|
|
15
17
|
ColumnIndex,
|
|
16
18
|
CustodyIndex,
|
|
19
|
+
Root,
|
|
17
20
|
SSZTypesFor,
|
|
18
21
|
SignedBeaconBlock,
|
|
19
22
|
SignedBeaconBlockHeader,
|
|
23
|
+
Slot,
|
|
20
24
|
deneb,
|
|
21
25
|
fulu,
|
|
26
|
+
gloas,
|
|
22
27
|
ssz,
|
|
23
28
|
} from "@lodestar/types";
|
|
24
29
|
import {bytesToBigInt} from "@lodestar/utils";
|
|
@@ -261,6 +266,20 @@ export async function getCellsAndProofs(
|
|
|
261
266
|
return blobsAndProofs;
|
|
262
267
|
}
|
|
263
268
|
|
|
269
|
+
/**
|
|
270
|
+
* Get blob KZG commitments from a signed block, handling the different locations
|
|
271
|
+
* in pre-Gloas (directly in block body) vs post-Gloas (in execution payload bid).
|
|
272
|
+
*/
|
|
273
|
+
export function getBlobKzgCommitments(
|
|
274
|
+
fork: ForkName,
|
|
275
|
+
signedBlock: SignedBeaconBlock<ForkPostDeneb>
|
|
276
|
+
): deneb.KZGCommitment[] {
|
|
277
|
+
if (isForkPostGloas(fork)) {
|
|
278
|
+
return (signedBlock as gloas.SignedBeaconBlock).message.body.signedExecutionPayloadBid.message.blobKzgCommitments;
|
|
279
|
+
}
|
|
280
|
+
return (signedBlock.message.body as BeaconBlockBody<ForkPostFulu & ForkPreGloas>).blobKzgCommitments;
|
|
281
|
+
}
|
|
282
|
+
|
|
264
283
|
/**
|
|
265
284
|
* Given a signed block header and the commitments, inclusion proof, cells/proofs associated with
|
|
266
285
|
* each blob in the block, assemble the sidecars which can be distributed to peers.
|
|
@@ -310,16 +329,13 @@ export function getDataColumnSidecarsFromBlock(
|
|
|
310
329
|
signedBlock: SignedBeaconBlock<ForkPostFulu>,
|
|
311
330
|
cellsAndKzgProofs: {cells: Uint8Array[]; proofs: Uint8Array[]}[]
|
|
312
331
|
): fulu.DataColumnSidecars {
|
|
313
|
-
|
|
314
|
-
const blobKzgCommitments = (signedBlock
|
|
315
|
-
.blobKzgCommitments;
|
|
332
|
+
const fork = config.getForkName(signedBlock.message.slot);
|
|
333
|
+
const blobKzgCommitments = getBlobKzgCommitments(fork, signedBlock);
|
|
316
334
|
|
|
317
335
|
// No need to create data column sidecars if there are no blobs
|
|
318
336
|
if (blobKzgCommitments.length === 0) {
|
|
319
337
|
return [];
|
|
320
338
|
}
|
|
321
|
-
|
|
322
|
-
const fork = config.getForkName(signedBlock.message.slot);
|
|
323
339
|
const signedBlockHeader = signedBlockToSignedHeader(config, signedBlock);
|
|
324
340
|
|
|
325
341
|
const kzgCommitmentsInclusionProof = computePostFuluKzgCommitmentsInclusionProof(fork, signedBlock.message.body);
|
|
@@ -346,6 +362,39 @@ export function getDataColumnSidecarsFromColumnSidecar(
|
|
|
346
362
|
);
|
|
347
363
|
}
|
|
348
364
|
|
|
365
|
+
/**
|
|
366
|
+
* In Gloas, data column sidecars have a simplified structure with `slot` and `beaconBlockRoot`
|
|
367
|
+
* instead of `signedBlockHeader`, `kzgCommitments`, and `kzgCommitmentsInclusionProof`.
|
|
368
|
+
*/
|
|
369
|
+
export function getDataColumnSidecarsForGloas(
|
|
370
|
+
slot: Slot,
|
|
371
|
+
beaconBlockRoot: Root,
|
|
372
|
+
cellsAndKzgProofs: {cells: Uint8Array[]; proofs: Uint8Array[]}[]
|
|
373
|
+
): gloas.DataColumnSidecars {
|
|
374
|
+
// No need to create data column sidecars if there are no blobs
|
|
375
|
+
if (cellsAndKzgProofs.length === 0) {
|
|
376
|
+
return [];
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const sidecars: gloas.DataColumnSidecars = [];
|
|
380
|
+
for (let columnIndex = 0; columnIndex < NUMBER_OF_COLUMNS; columnIndex++) {
|
|
381
|
+
const column: Uint8Array[] = [];
|
|
382
|
+
const kzgProofs: Uint8Array[] = [];
|
|
383
|
+
for (const {cells, proofs} of cellsAndKzgProofs) {
|
|
384
|
+
column.push(cells[columnIndex]);
|
|
385
|
+
kzgProofs.push(proofs[columnIndex]);
|
|
386
|
+
}
|
|
387
|
+
sidecars.push({
|
|
388
|
+
index: columnIndex,
|
|
389
|
+
column,
|
|
390
|
+
kzgProofs,
|
|
391
|
+
slot,
|
|
392
|
+
beaconBlockRoot,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
return sidecars;
|
|
396
|
+
}
|
|
397
|
+
|
|
349
398
|
/**
|
|
350
399
|
* If we receive more than half of NUMBER_OF_COLUMNS (64) we should recover all remaining columns
|
|
351
400
|
*/
|
package/src/util/multifork.ts
CHANGED
|
@@ -9,6 +9,11 @@ import {getSlotFromSignedBeaconBlockSerialized} from "./sszBytes.js";
|
|
|
9
9
|
*/
|
|
10
10
|
const SLOT_BYTE_COUNT = 8;
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* SSZ offset uint32
|
|
14
|
+
*/
|
|
15
|
+
const OFFSET_BYTE_COUNT = 4;
|
|
16
|
+
|
|
12
17
|
/**
|
|
13
18
|
* 8 + 32 = 40
|
|
14
19
|
* ```
|
|
@@ -67,3 +72,43 @@ export function getLightClientHeaderTypeFromBytes(
|
|
|
67
72
|
);
|
|
68
73
|
return config.getPostAltairForkTypes(slot).LightClientHeader;
|
|
69
74
|
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Position of first offset in DataColumnSidecar (after index field)
|
|
78
|
+
*
|
|
79
|
+
* Fulu DataColumnSidecar (6 fields):
|
|
80
|
+
* index: uint64 [fixed - 8 bytes]
|
|
81
|
+
* column: List [variable - 4-byte offset]
|
|
82
|
+
* kzgCommitments: List [variable - 4-byte offset]
|
|
83
|
+
* kzgProofs: List [variable - 4-byte offset]
|
|
84
|
+
* signedBlockHeader: Container [fixed - 208 bytes]
|
|
85
|
+
* kzgCommitmentsInclusionProof: Vector[Bytes32, 4] [fixed - 128 bytes]
|
|
86
|
+
* => First offset value = 8 + 4 + 4 + 4 + 208 + 128 = 356
|
|
87
|
+
*
|
|
88
|
+
* Gloas DataColumnSidecar (5 fields):
|
|
89
|
+
* index: uint64 [fixed - 8 bytes]
|
|
90
|
+
* column: List [variable - 4-byte offset]
|
|
91
|
+
* kzgProofs: List [variable - 4-byte offset]
|
|
92
|
+
* slot: uint64 [fixed - 8 bytes]
|
|
93
|
+
* beaconBlockRoot: Bytes32 [fixed - 32 bytes]
|
|
94
|
+
* => First offset value = 8 + 4 + 4 + 8 + 32 = 56
|
|
95
|
+
*/
|
|
96
|
+
const FIRST_OFFSET_POSITION_IN_DATA_COLUMN_SIDECAR = 8;
|
|
97
|
+
const GLOAS_DATA_COLUMN_SIDECAR_FIRST_OFFSET = 56;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Determines if DataColumnSidecar bytes are from Gloas fork by checking the SSZ offset structure.
|
|
101
|
+
*
|
|
102
|
+
* The first offset (bytes 8-12) indicates where variable-size data begins:
|
|
103
|
+
* - Gloas: 56 (small fixed section)
|
|
104
|
+
* - Fulu: 356
|
|
105
|
+
*/
|
|
106
|
+
export function isGloasDataColumnSidecarBytes(bytes: Uint8Array): boolean {
|
|
107
|
+
const firstOffset = bytesToInt(
|
|
108
|
+
bytes.subarray(
|
|
109
|
+
FIRST_OFFSET_POSITION_IN_DATA_COLUMN_SIDECAR,
|
|
110
|
+
FIRST_OFFSET_POSITION_IN_DATA_COLUMN_SIDECAR + OFFSET_BYTE_COUNT
|
|
111
|
+
)
|
|
112
|
+
);
|
|
113
|
+
return firstOffset === GLOAS_DATA_COLUMN_SIDECAR_FIRST_OFFSET;
|
|
114
|
+
}
|
|
@@ -14,6 +14,11 @@ export class SerializedCache {
|
|
|
14
14
|
this.map.set(obj, serialized);
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Replace the internal WeakMap to force GC of all cached entries.
|
|
19
|
+
* Must only be called after all DB writes that may read from this cache have completed,
|
|
20
|
+
* otherwise cached serialized bytes will be unavailable and data will be re-serialized unnecessarily.
|
|
21
|
+
*/
|
|
17
22
|
clear(): void {
|
|
18
23
|
this.map = new WeakMap();
|
|
19
24
|
}
|