@lodestar/beacon-node 1.41.0 → 1.42.0-dev.4118b5b440
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 +35 -16
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -2
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +6 -2
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +0 -9
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +4 -4
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +4 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +38 -0
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/blockInput/types.d.ts +4 -3
- package/lib/chain/blocks/blockInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/blockInput/types.js +1 -0
- package/lib/chain/blocks/blockInput/types.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +29 -9
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +48 -0
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -0
- package/lib/chain/blocks/importExecutionPayload.js +159 -0
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.d.ts +3 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.js +3 -0
- package/lib/chain/blocks/payloadEnvelopeInput/index.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +80 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +248 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +29 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.js +11 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.js.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +15 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +46 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -0
- package/lib/chain/blocks/types.d.ts +7 -0
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +12 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +40 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -0
- package/lib/chain/chain.d.ts +10 -5
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +44 -10
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +12 -2
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +3 -1
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +0 -10
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +8 -5
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +1 -1
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +6 -2
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +6 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/errors.d.ts +11 -1
- package/lib/chain/regen/errors.d.ts.map +1 -1
- package/lib/chain/regen/errors.js +2 -0
- package/lib/chain/regen/errors.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +14 -6
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +2 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +11 -6
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +40 -8
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +5 -0
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +33 -6
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/index.d.ts +1 -1
- package/lib/chain/seenCache/index.d.ts.map +1 -1
- package/lib/chain/seenCache/index.js +1 -1
- package/lib/chain/seenCache/index.js.map +1 -1
- package/lib/chain/seenCache/seenGossipBlockInput.js +2 -2
- package/lib/chain/seenCache/seenGossipBlockInput.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +38 -0
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -0
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +76 -0
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -0
- package/lib/chain/stateCache/datastore/db.d.ts +4 -5
- package/lib/chain/stateCache/datastore/db.d.ts.map +1 -1
- package/lib/chain/stateCache/datastore/db.js +32 -10
- package/lib/chain/stateCache/datastore/db.js.map +1 -1
- package/lib/chain/stateCache/datastore/file.d.ts +1 -1
- package/lib/chain/stateCache/datastore/file.d.ts.map +1 -1
- package/lib/chain/stateCache/datastore/file.js +5 -5
- package/lib/chain/stateCache/datastore/file.js.map +1 -1
- package/lib/chain/stateCache/datastore/types.d.ts +1 -1
- package/lib/chain/stateCache/datastore/types.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +7 -4
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +8 -3
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +33 -14
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +217 -119
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +15 -8
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/stateCache/types.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +30 -19
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/lightClientFinalityUpdate.js +1 -1
- package/lib/chain/validation/lightClientFinalityUpdate.js.map +1 -1
- package/lib/chain/validation/lightClientOptimisticUpdate.js +1 -1
- package/lib/chain/validation/lightClientOptimisticUpdate.js.map +1 -1
- package/lib/chain/validation/syncCommittee.d.ts +2 -2
- package/lib/chain/validation/syncCommittee.d.ts.map +1 -1
- package/lib/chain/validation/syncCommittee.js +12 -11
- package/lib/chain/validation/syncCommittee.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +2 -2
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts +2 -1
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +4 -1
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +2 -2
- package/lib/metrics/metrics/lodestar.d.ts +40 -4
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +93 -15
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/encoding.d.ts.map +1 -1
- package/lib/network/gossip/encoding.js +15 -0
- package/lib/network/gossip/encoding.js.map +1 -1
- package/lib/network/interface.d.ts +1 -1
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +1 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +4 -4
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/extractSlotRootFns.d.ts +1 -1
- package/lib/network/processor/extractSlotRootFns.d.ts.map +1 -1
- package/lib/network/processor/extractSlotRootFns.js +15 -5
- package/lib/network/processor/extractSlotRootFns.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +39 -9
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +12 -7
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +99 -78
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.d.ts +1 -1
- package/lib/network/reqresp/ReqRespBeaconNode.js +1 -1
- package/lib/sync/backfill/backfill.d.ts +1 -1
- package/lib/sync/backfill/backfill.js +1 -1
- package/lib/sync/constants.d.ts +1 -1
- package/lib/sync/constants.js +1 -1
- package/lib/sync/unknownBlock.d.ts +3 -9
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +8 -41
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/util/sszBytes.d.ts +4 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +69 -12
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +15 -15
- package/src/api/impl/beacon/blocks/index.ts +36 -17
- package/src/api/impl/beacon/state/utils.ts +2 -2
- package/src/api/impl/validator/index.ts +8 -4
- package/src/chain/archiveStore/archiveStore.ts +0 -10
- package/src/chain/archiveStore/interface.ts +4 -4
- package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +8 -5
- package/src/chain/archiveStore/utils/archiveBlocks.ts +59 -1
- package/src/chain/blocks/blockInput/types.ts +4 -3
- package/src/chain/blocks/importBlock.ts +47 -8
- package/src/chain/blocks/importExecutionPayload.ts +241 -0
- package/src/chain/blocks/payloadEnvelopeInput/index.ts +2 -0
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +336 -0
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +33 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +61 -0
- package/src/chain/blocks/types.ts +8 -0
- package/src/chain/blocks/verifyBlocksSignatures.ts +1 -1
- package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +55 -0
- package/src/chain/chain.ts +60 -15
- package/src/chain/errors/executionPayloadEnvelope.ts +6 -2
- package/src/chain/forkChoice/index.ts +0 -10
- package/src/chain/interface.ts +8 -5
- package/src/chain/opPools/utils.ts +1 -1
- package/src/chain/prepareNextSlot.ts +6 -2
- package/src/chain/produceBlock/computeNewStateRoot.ts +6 -1
- package/src/chain/produceBlock/produceBlockBody.ts +1 -1
- package/src/chain/regen/errors.ts +6 -1
- package/src/chain/regen/interface.ts +14 -6
- package/src/chain/regen/queued.ts +48 -12
- package/src/chain/regen/regen.ts +37 -7
- package/src/chain/seenCache/index.ts +1 -1
- package/src/chain/seenCache/seenGossipBlockInput.ts +2 -2
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +106 -0
- package/src/chain/stateCache/datastore/db.ts +33 -10
- package/src/chain/stateCache/datastore/file.ts +6 -5
- package/src/chain/stateCache/datastore/types.ts +3 -2
- package/src/chain/stateCache/fifoBlockStateCache.ts +10 -4
- package/src/chain/stateCache/persistentCheckpointsCache.ts +248 -139
- package/src/chain/stateCache/types.ts +18 -8
- package/src/chain/validation/executionPayloadEnvelope.ts +38 -25
- package/src/chain/validation/lightClientFinalityUpdate.ts +1 -1
- package/src/chain/validation/lightClientOptimisticUpdate.ts +1 -1
- package/src/chain/validation/syncCommittee.ts +15 -14
- package/src/chain/validation/voluntaryExit.ts +2 -1
- package/src/chain/validatorMonitor.ts +11 -1
- package/src/execution/engine/interface.ts +2 -2
- package/src/metrics/metrics/lodestar.ts +100 -19
- package/src/network/gossip/encoding.ts +16 -0
- package/src/network/interface.ts +1 -1
- package/src/network/network.ts +4 -4
- package/src/network/processor/extractSlotRootFns.ts +19 -6
- package/src/network/processor/gossipHandlers.ts +45 -8
- package/src/network/processor/index.ts +110 -89
- package/src/network/reqresp/ReqRespBeaconNode.ts +1 -1
- package/src/sync/backfill/backfill.ts +1 -1
- package/src/sync/constants.ts +1 -1
- package/src/sync/unknownBlock.ts +10 -50
- package/src/util/sszBytes.ts +90 -10
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts +0 -7
- package/lib/chain/archiveStore/utils/archivePayloads.d.ts.map +0 -1
- package/lib/chain/archiveStore/utils/archivePayloads.js +0 -10
- package/lib/chain/archiveStore/utils/archivePayloads.js.map +0 -1
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts +0 -15
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.d.ts.map +0 -1
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js +0 -28
- package/lib/chain/seenCache/seenExecutionPayloadEnvelope.js.map +0 -1
- package/src/chain/archiveStore/utils/archivePayloads.ts +0 -15
- package/src/chain/seenCache/seenExecutionPayloadEnvelope.ts +0 -34
package/src/chain/chain.ts
CHANGED
|
@@ -3,11 +3,12 @@ import {PrivateKey} from "@libp2p/interface";
|
|
|
3
3
|
import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
|
|
4
4
|
import {BeaconConfig} from "@lodestar/config";
|
|
5
5
|
import {
|
|
6
|
-
CheckpointWithHex,
|
|
7
6
|
CheckpointWithPayloadStatus,
|
|
8
7
|
IForkChoice,
|
|
8
|
+
PayloadStatus,
|
|
9
9
|
ProtoBlock,
|
|
10
10
|
UpdateHeadOpt,
|
|
11
|
+
getCheckpointPayloadStatus,
|
|
11
12
|
} from "@lodestar/fork-choice";
|
|
12
13
|
import {LoggerNode} from "@lodestar/logger/node";
|
|
13
14
|
import {
|
|
@@ -83,7 +84,10 @@ import {CheckpointBalancesCache} from "./balancesCache.js";
|
|
|
83
84
|
import {BeaconProposerCache} from "./beaconProposerCache.js";
|
|
84
85
|
import {IBlockInput, isBlockInputBlobs, isBlockInputColumns} from "./blocks/blockInput/index.js";
|
|
85
86
|
import {BlockProcessor, ImportBlockOpts} from "./blocks/index.js";
|
|
87
|
+
import {PayloadEnvelopeProcessor} from "./blocks/payloadEnvelopeProcessor.js";
|
|
88
|
+
import {ImportPayloadOpts} from "./blocks/types.js";
|
|
86
89
|
import {persistBlockInput} from "./blocks/writeBlockInputToDb.js";
|
|
90
|
+
import {persistPayloadEnvelopeInput} from "./blocks/writePayloadEnvelopeInputToDb.js";
|
|
87
91
|
import {BlsMultiThreadWorkerPool, BlsSingleThreadVerifier, IBlsVerifier} from "./bls/index.js";
|
|
88
92
|
import {ColumnReconstructionTracker} from "./ColumnReconstructionTracker.js";
|
|
89
93
|
import {ChainEvent, ChainEventEmitter} from "./emitter.js";
|
|
@@ -108,13 +112,14 @@ import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produ
|
|
|
108
112
|
import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
|
|
109
113
|
import {ReprocessController} from "./reprocess.js";
|
|
110
114
|
import {
|
|
115
|
+
PayloadEnvelopeInput,
|
|
111
116
|
SeenAggregators,
|
|
112
117
|
SeenAttesters,
|
|
113
118
|
SeenBlockProposers,
|
|
114
119
|
SeenContributionAndProof,
|
|
115
120
|
SeenExecutionPayloadBids,
|
|
116
|
-
SeenExecutionPayloadEnvelopes,
|
|
117
121
|
SeenPayloadAttesters,
|
|
122
|
+
SeenPayloadEnvelopeInput,
|
|
118
123
|
SeenSyncCommitteeMessages,
|
|
119
124
|
} from "./seenCache/index.js";
|
|
120
125
|
import {SeenAggregatedAttestations} from "./seenCache/seenAggregateAndProof.js";
|
|
@@ -126,7 +131,7 @@ import {DbCPStateDatastore, checkpointToDatastoreKey} from "./stateCache/datasto
|
|
|
126
131
|
import {FileCPStateDatastore} from "./stateCache/datastore/file.js";
|
|
127
132
|
import {CPStateDatastore} from "./stateCache/datastore/types.js";
|
|
128
133
|
import {FIFOBlockStateCache} from "./stateCache/fifoBlockStateCache.js";
|
|
129
|
-
import {PersistentCheckpointStateCache} from "./stateCache/persistentCheckpointsCache.js";
|
|
134
|
+
import {PersistentCheckpointStateCache, fcCheckpointToHexPayload} from "./stateCache/persistentCheckpointsCache.js";
|
|
130
135
|
import {CheckpointStateCache} from "./stateCache/types.js";
|
|
131
136
|
import {ValidatorMonitor} from "./validatorMonitor.js";
|
|
132
137
|
|
|
@@ -147,6 +152,13 @@ const DEFAULT_MAX_CACHED_PRODUCED_RESULTS = 4;
|
|
|
147
152
|
*/
|
|
148
153
|
const DEFAULT_MAX_PENDING_UNFINALIZED_BLOCK_WRITES = 16;
|
|
149
154
|
|
|
155
|
+
/**
|
|
156
|
+
* The maximum number of pending unfinalized payload envelope writes to the database before backpressure is applied.
|
|
157
|
+
* Payload envelope write queue entries hold references to payload inputs (including columns),
|
|
158
|
+
* keeping them in memory. Keep moderate to avoid OOM during sync.
|
|
159
|
+
*/
|
|
160
|
+
const DEFAULT_MAX_PENDING_UNFINALIZED_PAYLOAD_ENVELOPE_WRITES = 16;
|
|
161
|
+
|
|
150
162
|
export class BeaconChain implements IBeaconChain {
|
|
151
163
|
readonly genesisTime: UintNum64;
|
|
152
164
|
readonly genesisValidatorsRoot: Root;
|
|
@@ -171,6 +183,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
171
183
|
readonly reprocessController: ReprocessController;
|
|
172
184
|
readonly archiveStore: ArchiveStore;
|
|
173
185
|
readonly unfinalizedBlockWrites: JobItemQueue<[IBlockInput], void>;
|
|
186
|
+
readonly unfinalizedPayloadEnvelopeWrites: JobItemQueue<[PayloadEnvelopeInput], void>;
|
|
174
187
|
|
|
175
188
|
// Ops pool
|
|
176
189
|
readonly attestationPool: AttestationPool;
|
|
@@ -186,13 +199,13 @@ export class BeaconChain implements IBeaconChain {
|
|
|
186
199
|
readonly seenAggregators = new SeenAggregators();
|
|
187
200
|
readonly seenPayloadAttesters = new SeenPayloadAttesters();
|
|
188
201
|
readonly seenAggregatedAttestations: SeenAggregatedAttestations;
|
|
189
|
-
readonly seenExecutionPayloadEnvelopes = new SeenExecutionPayloadEnvelopes();
|
|
190
202
|
readonly seenExecutionPayloadBids = new SeenExecutionPayloadBids();
|
|
191
203
|
readonly seenBlockProposers = new SeenBlockProposers();
|
|
192
204
|
readonly seenSyncCommitteeMessages = new SeenSyncCommitteeMessages();
|
|
193
205
|
readonly seenContributionAndProof: SeenContributionAndProof;
|
|
194
206
|
readonly seenAttestationDatas: SeenAttestationDatas;
|
|
195
207
|
readonly seenBlockInputCache: SeenBlockInput;
|
|
208
|
+
readonly seenPayloadEnvelopeInputCache: SeenPayloadEnvelopeInput;
|
|
196
209
|
// Seen cache for liveness checks
|
|
197
210
|
readonly seenBlockAttesters = new SeenBlockAttesters();
|
|
198
211
|
|
|
@@ -220,6 +233,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
220
233
|
readonly opts: IChainOptions;
|
|
221
234
|
|
|
222
235
|
protected readonly blockProcessor: BlockProcessor;
|
|
236
|
+
protected readonly payloadEnvelopeProcessor: PayloadEnvelopeProcessor;
|
|
223
237
|
protected readonly db: IBeaconDb;
|
|
224
238
|
// this is only available if nHistoricalStates is enabled
|
|
225
239
|
private readonly cpStateDatastore?: CPStateDatastore;
|
|
@@ -333,6 +347,13 @@ export class BeaconChain implements IBeaconChain {
|
|
|
333
347
|
metrics,
|
|
334
348
|
logger,
|
|
335
349
|
});
|
|
350
|
+
this.seenPayloadEnvelopeInputCache = new SeenPayloadEnvelopeInput({
|
|
351
|
+
chainEvents: emitter,
|
|
352
|
+
signal,
|
|
353
|
+
serializedCache: this.serializedCache,
|
|
354
|
+
metrics,
|
|
355
|
+
logger,
|
|
356
|
+
});
|
|
336
357
|
|
|
337
358
|
this._earliestAvailableSlot = anchorState.slot;
|
|
338
359
|
|
|
@@ -375,7 +396,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
375
396
|
const {checkpoint} = computeAnchorCheckpoint(config, anchorState);
|
|
376
397
|
blockStateCache.add(anchorState);
|
|
377
398
|
blockStateCache.setHeadState(anchorState);
|
|
378
|
-
|
|
399
|
+
const payloadPresent = getCheckpointPayloadStatus(anchorState, checkpoint.epoch) === PayloadStatus.FULL;
|
|
400
|
+
checkpointStateCache.add(checkpoint, anchorState, payloadPresent);
|
|
379
401
|
|
|
380
402
|
const forkChoice = initializeForkChoice(
|
|
381
403
|
config,
|
|
@@ -409,6 +431,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
409
431
|
this.reprocessController = new ReprocessController(this.metrics);
|
|
410
432
|
|
|
411
433
|
this.blockProcessor = new BlockProcessor(this, metrics, opts, signal);
|
|
434
|
+
this.payloadEnvelopeProcessor = new PayloadEnvelopeProcessor(this, metrics, signal);
|
|
412
435
|
|
|
413
436
|
this.forkChoice = forkChoice;
|
|
414
437
|
this.clock = clock;
|
|
@@ -445,6 +468,15 @@ export class BeaconChain implements IBeaconChain {
|
|
|
445
468
|
metrics?.unfinalizedBlockWritesQueue
|
|
446
469
|
);
|
|
447
470
|
|
|
471
|
+
this.unfinalizedPayloadEnvelopeWrites = new JobItemQueue(
|
|
472
|
+
persistPayloadEnvelopeInput.bind(this),
|
|
473
|
+
{
|
|
474
|
+
maxLength: DEFAULT_MAX_PENDING_UNFINALIZED_PAYLOAD_ENVELOPE_WRITES,
|
|
475
|
+
signal,
|
|
476
|
+
},
|
|
477
|
+
metrics?.unfinalizedPayloadEnvelopeWritesQueue
|
|
478
|
+
);
|
|
479
|
+
|
|
448
480
|
// always run PrepareNextSlotScheduler except for fork_choice spec tests
|
|
449
481
|
if (!opts?.disablePrepareNextSlot) {
|
|
450
482
|
new PrepareNextSlotScheduler(this, this.config, metrics, this.logger, signal);
|
|
@@ -475,6 +507,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
475
507
|
// we can abort any ongoing unfinalized block writes.
|
|
476
508
|
// TODO: persist fork choice to disk and allow unfinalized block writes to complete.
|
|
477
509
|
this.unfinalizedBlockWrites.dropAllJobs();
|
|
510
|
+
this.unfinalizedPayloadEnvelopeWrites.dropAllJobs();
|
|
478
511
|
|
|
479
512
|
this.abortController.abort();
|
|
480
513
|
}
|
|
@@ -648,15 +681,18 @@ export class BeaconChain implements IBeaconChain {
|
|
|
648
681
|
return this.cpStateDatastore.readLatestSafe();
|
|
649
682
|
}
|
|
650
683
|
|
|
651
|
-
|
|
684
|
+
// TODO GLOAS: Need to revisit the design of this api. Currently we just retrieve FULL state of the checkpoint for backwards compatibility.
|
|
685
|
+
// because pre-gloas we always store FULL checkpoint state.
|
|
686
|
+
const persistedKey = checkpointToDatastoreKey(checkpoint, true);
|
|
652
687
|
return this.cpStateDatastore.read(persistedKey);
|
|
653
688
|
}
|
|
654
689
|
|
|
655
690
|
getStateByCheckpoint(
|
|
656
|
-
checkpoint:
|
|
691
|
+
checkpoint: CheckpointWithPayloadStatus
|
|
657
692
|
): {state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null {
|
|
658
693
|
// finalized or justified checkpoint states maynot be available with PersistentCheckpointStateCache, use getCheckpointStateOrBytes() api to get Uint8Array
|
|
659
|
-
const
|
|
694
|
+
const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
|
|
695
|
+
const cachedStateCtx = this.regen.getCheckpointStateSync(checkpointHexPayload);
|
|
660
696
|
if (cachedStateCtx) {
|
|
661
697
|
const block = this.forkChoice.getBlockDefaultStatus(cachedStateCtx.latestBlockHeader.hashTreeRoot());
|
|
662
698
|
const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
|
|
@@ -671,9 +707,10 @@ export class BeaconChain implements IBeaconChain {
|
|
|
671
707
|
}
|
|
672
708
|
|
|
673
709
|
async getStateOrBytesByCheckpoint(
|
|
674
|
-
checkpoint:
|
|
710
|
+
checkpoint: CheckpointWithPayloadStatus
|
|
675
711
|
): Promise<{state: CachedBeaconStateAllForks | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null> {
|
|
676
|
-
const
|
|
712
|
+
const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
|
|
713
|
+
const cachedStateCtx = await this.regen.getCheckpointStateOrBytes(checkpointHexPayload);
|
|
677
714
|
if (cachedStateCtx) {
|
|
678
715
|
const block = this.forkChoice.getBlockDefaultStatus(checkpoint.root);
|
|
679
716
|
const finalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
|
|
@@ -1004,6 +1041,10 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1004
1041
|
return this.blockProcessor.processBlocksJob(blocks, opts);
|
|
1005
1042
|
}
|
|
1006
1043
|
|
|
1044
|
+
async processExecutionPayload(payloadInput: PayloadEnvelopeInput, opts?: ImportPayloadOpts): Promise<void> {
|
|
1045
|
+
return this.payloadEnvelopeProcessor.processPayloadEnvelopeJob(payloadInput, opts);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1007
1048
|
getStatus(): Status {
|
|
1008
1049
|
const head = this.forkChoice.getHead();
|
|
1009
1050
|
const finalizedCheckpoint = this.forkChoice.getFinalizedCheckpoint();
|
|
@@ -1236,7 +1277,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1236
1277
|
checkpoint: CheckpointWithPayloadStatus,
|
|
1237
1278
|
blockState: CachedBeaconStateAllForks
|
|
1238
1279
|
): {state: CachedBeaconStateAllForks; stateId: string; shouldWarn: boolean} {
|
|
1239
|
-
const
|
|
1280
|
+
const checkpointHexPayload = fcCheckpointToHexPayload(checkpoint);
|
|
1281
|
+
const state = this.regen.getCheckpointStateSync(checkpointHexPayload);
|
|
1240
1282
|
if (state) {
|
|
1241
1283
|
return {state, stateId: "checkpoint_state", shouldWarn: false};
|
|
1242
1284
|
}
|
|
@@ -1363,6 +1405,10 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1363
1405
|
private onClockEpoch(epoch: Epoch): void {
|
|
1364
1406
|
this.metrics?.clockEpoch.set(epoch);
|
|
1365
1407
|
|
|
1408
|
+
if (epoch === this.config.GLOAS_FORK_EPOCH) {
|
|
1409
|
+
this.regen.upgradeForGloas(epoch);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1366
1412
|
this.seenAttesters.prune(epoch);
|
|
1367
1413
|
this.seenAggregators.prune(epoch);
|
|
1368
1414
|
this.seenPayloadAttesters.prune(epoch);
|
|
@@ -1376,7 +1422,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1376
1422
|
this.seenContributionAndProof.prune(head.slot);
|
|
1377
1423
|
}
|
|
1378
1424
|
|
|
1379
|
-
private onForkChoiceJustified(this: BeaconChain, cp:
|
|
1425
|
+
private onForkChoiceJustified(this: BeaconChain, cp: CheckpointWithPayloadStatus): void {
|
|
1380
1426
|
this.logger.verbose("Fork choice justified", {epoch: cp.epoch, root: cp.rootHex});
|
|
1381
1427
|
}
|
|
1382
1428
|
|
|
@@ -1387,11 +1433,10 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1387
1433
|
});
|
|
1388
1434
|
}
|
|
1389
1435
|
|
|
1390
|
-
private async onForkChoiceFinalized(this: BeaconChain, cp:
|
|
1436
|
+
private async onForkChoiceFinalized(this: BeaconChain, cp: CheckpointWithPayloadStatus): Promise<void> {
|
|
1391
1437
|
this.logger.verbose("Fork choice finalized", {epoch: cp.epoch, root: cp.rootHex});
|
|
1392
1438
|
const finalizedSlot = computeStartSlotAtEpoch(cp.epoch);
|
|
1393
1439
|
this.seenBlockProposers.prune(finalizedSlot);
|
|
1394
|
-
this.seenExecutionPayloadEnvelopes.prune(finalizedSlot);
|
|
1395
1440
|
|
|
1396
1441
|
// Update validator custody to account for effective balance changes
|
|
1397
1442
|
await this.updateValidatorsCustodyRequirement(cp);
|
|
@@ -1429,7 +1474,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1429
1474
|
}
|
|
1430
1475
|
}
|
|
1431
1476
|
|
|
1432
|
-
private async updateValidatorsCustodyRequirement(finalizedCheckpoint:
|
|
1477
|
+
private async updateValidatorsCustodyRequirement(finalizedCheckpoint: CheckpointWithPayloadStatus): Promise<void> {
|
|
1433
1478
|
if (this.custodyConfig.targetCustodyGroupCount === this.config.NUMBER_OF_CUSTODY_GROUPS) {
|
|
1434
1479
|
// Custody requirements can only be increased, we can disable dynamic custody updates
|
|
1435
1480
|
// if the node already maintains custody of all custody groups in case it is configured
|
|
@@ -4,17 +4,21 @@ import {GossipActionError} from "./gossipValidation.js";
|
|
|
4
4
|
export enum ExecutionPayloadEnvelopeErrorCode {
|
|
5
5
|
BELONG_TO_FINALIZED_BLOCK = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_BELONG_TO_FINALIZED_BLOCK",
|
|
6
6
|
BLOCK_ROOT_UNKNOWN = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_BLOCK_ROOT_UNKNOWN",
|
|
7
|
+
PARENT_UNKNOWN = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_PARENT_UNKNOWN",
|
|
8
|
+
UNKNOWN_BLOCK_STATE = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_UNKNOWN_BLOCK_STATE",
|
|
7
9
|
ENVELOPE_ALREADY_KNOWN = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_ALREADY_KNOWN",
|
|
8
10
|
INVALID_BLOCK = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_INVALID_BLOCK",
|
|
9
11
|
SLOT_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_SLOT_MISMATCH",
|
|
10
12
|
BUILDER_INDEX_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_BUILDER_INDEX_MISMATCH",
|
|
11
13
|
BLOCK_HASH_MISMATCH = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_BLOCK_HASH_MISMATCH",
|
|
12
14
|
INVALID_SIGNATURE = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_INVALID_SIGNATURE",
|
|
13
|
-
|
|
15
|
+
PAYLOAD_ENVELOPE_INPUT_MISSING = "EXECUTION_PAYLOAD_ENVELOPE_ERROR_PAYLOAD_ENVELOPE_INPUT_MISSING",
|
|
14
16
|
}
|
|
15
17
|
export type ExecutionPayloadEnvelopeErrorType =
|
|
16
18
|
| {code: ExecutionPayloadEnvelopeErrorCode.BELONG_TO_FINALIZED_BLOCK; envelopeSlot: Slot; finalizedSlot: Slot}
|
|
17
19
|
| {code: ExecutionPayloadEnvelopeErrorCode.BLOCK_ROOT_UNKNOWN; blockRoot: RootHex}
|
|
20
|
+
| {code: ExecutionPayloadEnvelopeErrorCode.PARENT_UNKNOWN; parentRoot: RootHex; slot: Slot}
|
|
21
|
+
| {code: ExecutionPayloadEnvelopeErrorCode.UNKNOWN_BLOCK_STATE; blockRoot: RootHex; slot: Slot}
|
|
18
22
|
| {
|
|
19
23
|
code: ExecutionPayloadEnvelopeErrorCode.ENVELOPE_ALREADY_KNOWN;
|
|
20
24
|
blockRoot: RootHex;
|
|
@@ -33,6 +37,6 @@ export type ExecutionPayloadEnvelopeErrorType =
|
|
|
33
37
|
bidBlockHash: RootHex | null;
|
|
34
38
|
}
|
|
35
39
|
| {code: ExecutionPayloadEnvelopeErrorCode.INVALID_SIGNATURE}
|
|
36
|
-
| {code: ExecutionPayloadEnvelopeErrorCode.
|
|
40
|
+
| {code: ExecutionPayloadEnvelopeErrorCode.PAYLOAD_ENVELOPE_INPUT_MISSING; blockRoot: RootHex};
|
|
37
41
|
|
|
38
42
|
export class ExecutionPayloadEnvelopeError extends GossipActionError<ExecutionPayloadEnvelopeErrorType> {}
|
|
@@ -158,10 +158,6 @@ export function initializeForkChoiceFromFinalizedState(
|
|
|
158
158
|
|
|
159
159
|
dataAvailabilityStatus: DataAvailabilityStatus.PreData,
|
|
160
160
|
payloadStatus: isForkPostGloas ? PayloadStatus.PENDING : PayloadStatus.FULL, // TODO GLOAS: Post-gloas how do we know if the checkpoint payload is FULL or EMPTY?
|
|
161
|
-
builderIndex: isForkPostGloas ? (state as CachedBeaconStateGloas).latestExecutionPayloadBid.builderIndex : null,
|
|
162
|
-
blockHashFromBid: isForkPostGloas
|
|
163
|
-
? toRootHex((state as CachedBeaconStateGloas).latestExecutionPayloadBid.blockHash)
|
|
164
|
-
: null,
|
|
165
161
|
parentBlockHash: isForkPostGloas ? toRootHex((state as CachedBeaconStateGloas).latestBlockHash) : null,
|
|
166
162
|
},
|
|
167
163
|
currentSlot
|
|
@@ -255,12 +251,6 @@ export function initializeForkChoiceFromUnfinalizedState(
|
|
|
255
251
|
|
|
256
252
|
dataAvailabilityStatus: DataAvailabilityStatus.PreData,
|
|
257
253
|
payloadStatus: isForkPostGloas ? PayloadStatus.PENDING : PayloadStatus.FULL, // TODO GLOAS: Post-gloas how do we know if the checkpoint payload is FULL or EMPTY?
|
|
258
|
-
builderIndex: isForkPostGloas
|
|
259
|
-
? (unfinalizedState as CachedBeaconStateGloas).latestExecutionPayloadBid.builderIndex
|
|
260
|
-
: null,
|
|
261
|
-
blockHashFromBid: isForkPostGloas
|
|
262
|
-
? toRootHex((unfinalizedState as CachedBeaconStateGloas).latestExecutionPayloadBid.blockHash)
|
|
263
|
-
: null,
|
|
264
254
|
parentBlockHash: isForkPostGloas ? toRootHex((unfinalizedState as CachedBeaconStateGloas).latestBlockHash) : null,
|
|
265
255
|
};
|
|
266
256
|
|
package/src/chain/interface.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
|
|
2
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
3
|
-
import {CheckpointWithHex, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
3
|
+
import {CheckpointWithHex, CheckpointWithPayloadStatus, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
4
4
|
import {BeaconStateAllForks, CachedBeaconStateAllForks, EpochShuffling, PubkeyCache} from "@lodestar/state-transition";
|
|
5
5
|
import {
|
|
6
6
|
BeaconBlock,
|
|
@@ -32,7 +32,7 @@ import {IArchiveStore} from "./archiveStore/interface.js";
|
|
|
32
32
|
import {CheckpointBalancesCache} from "./balancesCache.js";
|
|
33
33
|
import {BeaconProposerCache, ProposerPreparationData} from "./beaconProposerCache.js";
|
|
34
34
|
import {IBlockInput} from "./blocks/blockInput/index.js";
|
|
35
|
-
import {ImportBlockOpts} from "./blocks/types.js";
|
|
35
|
+
import {ImportBlockOpts, ImportPayloadOpts} from "./blocks/types.js";
|
|
36
36
|
import {IBlsVerifier} from "./bls/index.js";
|
|
37
37
|
import {ColumnReconstructionTracker} from "./ColumnReconstructionTracker.js";
|
|
38
38
|
import {ChainEventEmitter} from "./emitter.js";
|
|
@@ -58,7 +58,6 @@ import {
|
|
|
58
58
|
SeenBlockProposers,
|
|
59
59
|
SeenContributionAndProof,
|
|
60
60
|
SeenExecutionPayloadBids,
|
|
61
|
-
SeenExecutionPayloadEnvelopes,
|
|
62
61
|
SeenPayloadAttesters,
|
|
63
62
|
SeenSyncCommitteeMessages,
|
|
64
63
|
} from "./seenCache/index.js";
|
|
@@ -66,6 +65,7 @@ import {SeenAggregatedAttestations} from "./seenCache/seenAggregateAndProof.js";
|
|
|
66
65
|
import {SeenAttestationDatas} from "./seenCache/seenAttestationData.js";
|
|
67
66
|
import {SeenBlockAttesters} from "./seenCache/seenBlockAttesters.js";
|
|
68
67
|
import {SeenBlockInput} from "./seenCache/seenGossipBlockInput.js";
|
|
68
|
+
import {PayloadEnvelopeInput, SeenPayloadEnvelopeInput} from "./seenCache/seenPayloadEnvelopeInput.js";
|
|
69
69
|
import {ShufflingCache} from "./shufflingCache.js";
|
|
70
70
|
import {ValidatorMonitor} from "./validatorMonitor.js";
|
|
71
71
|
|
|
@@ -128,13 +128,13 @@ export interface IBeaconChain {
|
|
|
128
128
|
readonly seenAggregators: SeenAggregators;
|
|
129
129
|
readonly seenPayloadAttesters: SeenPayloadAttesters;
|
|
130
130
|
readonly seenAggregatedAttestations: SeenAggregatedAttestations;
|
|
131
|
-
readonly seenExecutionPayloadEnvelopes: SeenExecutionPayloadEnvelopes;
|
|
132
131
|
readonly seenExecutionPayloadBids: SeenExecutionPayloadBids;
|
|
133
132
|
readonly seenBlockProposers: SeenBlockProposers;
|
|
134
133
|
readonly seenSyncCommitteeMessages: SeenSyncCommitteeMessages;
|
|
135
134
|
readonly seenContributionAndProof: SeenContributionAndProof;
|
|
136
135
|
readonly seenAttestationDatas: SeenAttestationDatas;
|
|
137
136
|
readonly seenBlockInputCache: SeenBlockInput;
|
|
137
|
+
readonly seenPayloadEnvelopeInputCache: SeenPayloadEnvelopeInput;
|
|
138
138
|
// Seen cache for liveness checks
|
|
139
139
|
readonly seenBlockAttesters: SeenBlockAttesters;
|
|
140
140
|
|
|
@@ -192,7 +192,7 @@ export interface IBeaconChain {
|
|
|
192
192
|
): {state: BeaconStateAllForks; executionOptimistic: boolean; finalized: boolean} | null;
|
|
193
193
|
/** Return state bytes by checkpoint */
|
|
194
194
|
getStateOrBytesByCheckpoint(
|
|
195
|
-
checkpoint:
|
|
195
|
+
checkpoint: CheckpointWithPayloadStatus
|
|
196
196
|
): Promise<{state: CachedBeaconStateAllForks | Uint8Array; executionOptimistic: boolean; finalized: boolean} | null>;
|
|
197
197
|
|
|
198
198
|
/**
|
|
@@ -242,6 +242,9 @@ export interface IBeaconChain {
|
|
|
242
242
|
/** Process a chain of blocks until complete */
|
|
243
243
|
processChainSegment(blocks: IBlockInput[], opts?: ImportBlockOpts): Promise<void>;
|
|
244
244
|
|
|
245
|
+
/** Process execution payload envelope: verify, import to fork choice, and persist to DB */
|
|
246
|
+
processExecutionPayload(payloadInput: PayloadEnvelopeInput, opts?: ImportPayloadOpts): Promise<void>;
|
|
247
|
+
|
|
245
248
|
getStatus(): Status;
|
|
246
249
|
|
|
247
250
|
recomputeForkChoiceHead(caller: ForkchoiceCaller): ProtoBlock;
|
|
@@ -41,7 +41,7 @@ export function isValidBlsToExecutionChangeForBlockInclusion(
|
|
|
41
41
|
state: CachedBeaconStateAllForks,
|
|
42
42
|
signedBLSToExecutionChange: capella.SignedBLSToExecutionChange
|
|
43
43
|
): boolean {
|
|
44
|
-
// For each condition from https://github.com/ethereum/consensus-specs/blob/
|
|
44
|
+
// For each condition from https://github.com/ethereum/consensus-specs/blob/v1.6.1/specs/capella/beacon-chain.md#new-process_bls_to_execution_change
|
|
45
45
|
//
|
|
46
46
|
// 1. assert address_change.validator_index < len(state.validators):
|
|
47
47
|
// If valid before will always be valid in the future, no need to check
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
2
|
import {ChainForkConfig} from "@lodestar/config";
|
|
3
|
-
import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
3
|
+
import {PayloadStatus, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
4
4
|
import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH, isForkPostBellatrix} from "@lodestar/params";
|
|
5
5
|
import {
|
|
6
6
|
CachedBeaconStateAllForks,
|
|
@@ -211,7 +211,11 @@ export class PrepareNextSlotScheduler {
|
|
|
211
211
|
// + if next slot is a skipped slot, it'd help getting target checkpoint state faster to validate attestations
|
|
212
212
|
if (isEpochTransition) {
|
|
213
213
|
this.metrics?.precomputeNextEpochTransition.count.inc({result: "success"}, 1);
|
|
214
|
-
|
|
214
|
+
// Determine payloadPresent from head block's payload status
|
|
215
|
+
// Pre-Gloas: payloadStatus is always FULL → payloadPresent = true
|
|
216
|
+
// Post-Gloas: FULL → true, EMPTY → false, PENDING → false (conservative, treat as block state)
|
|
217
|
+
const payloadPresent = headBlock.payloadStatus === PayloadStatus.FULL;
|
|
218
|
+
const previousHits = this.chain.regen.updatePreComputedCheckpoint(headRoot, nextEpoch, payloadPresent);
|
|
215
219
|
if (previousHits === 0) {
|
|
216
220
|
this.metrics?.precomputeNextEpochTransition.waste.inc();
|
|
217
221
|
}
|
|
@@ -73,7 +73,12 @@ export function computeEnvelopeStateRoot(
|
|
|
73
73
|
};
|
|
74
74
|
|
|
75
75
|
const processEnvelopeTimer = metrics?.blockPayload.executionPayloadEnvelopeProcessingTime.startTimer();
|
|
76
|
-
const postEnvelopeState = processExecutionPayloadEnvelope(postBlockState, signedEnvelope,
|
|
76
|
+
const postEnvelopeState = processExecutionPayloadEnvelope(postBlockState, signedEnvelope, {
|
|
77
|
+
// Signature is zero-ed (G2_POINT_AT_INFINITY), skip verification
|
|
78
|
+
verifySignature: false,
|
|
79
|
+
// State root is being computed here, the envelope doesn't have it yet
|
|
80
|
+
verifyStateRoot: false,
|
|
81
|
+
// Preserve cache in source state, since the resulting state is not added to the state cache
|
|
77
82
|
dontTransferCache: true,
|
|
78
83
|
});
|
|
79
84
|
processEnvelopeTimer?.();
|
|
@@ -441,7 +441,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
441
441
|
parentBlockRoot: toRootHex(parentBlockRoot),
|
|
442
442
|
feeRecipient,
|
|
443
443
|
});
|
|
444
|
-
// https://github.com/ethereum/consensus-specs/blob/
|
|
444
|
+
// https://github.com/ethereum/consensus-specs/blob/v1.6.1/specs/deneb/validator.md#constructing-the-beaconblockbody
|
|
445
445
|
const prepareRes = await prepareExecutionPayload(
|
|
446
446
|
this,
|
|
447
447
|
this.logger,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {PayloadStatus} from "@lodestar/fork-choice";
|
|
1
2
|
import {Root, RootHex, Slot} from "@lodestar/types";
|
|
2
3
|
|
|
3
4
|
export enum RegenErrorCode {
|
|
@@ -9,6 +10,8 @@ export enum RegenErrorCode {
|
|
|
9
10
|
BLOCK_NOT_IN_DB = "REGEN_ERROR_BLOCK_NOT_IN_DB",
|
|
10
11
|
STATE_TRANSITION_ERROR = "REGEN_ERROR_STATE_TRANSITION_ERROR",
|
|
11
12
|
INVALID_STATE_ROOT = "REGEN_ERROR_INVALID_STATE_ROOT",
|
|
13
|
+
UNEXPECTED_PAYLOAD_STATUS = "REGEN_ERROR_UNEXPECTED_PAYLOAD_STATUS",
|
|
14
|
+
INTERNAL_ERROR = "REGEN_ERROR_INTERNAL_ERROR",
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
export type RegenErrorType =
|
|
@@ -19,7 +22,9 @@ export type RegenErrorType =
|
|
|
19
22
|
| {code: RegenErrorCode.TOO_MANY_BLOCK_PROCESSED; stateRoot: RootHex | Root}
|
|
20
23
|
| {code: RegenErrorCode.BLOCK_NOT_IN_DB; blockRoot: RootHex | Root}
|
|
21
24
|
| {code: RegenErrorCode.STATE_TRANSITION_ERROR; error: Error}
|
|
22
|
-
| {code: RegenErrorCode.INVALID_STATE_ROOT; slot: Slot; expected: RootHex; actual: RootHex}
|
|
25
|
+
| {code: RegenErrorCode.INVALID_STATE_ROOT; slot: Slot; expected: RootHex; actual: RootHex}
|
|
26
|
+
| {code: RegenErrorCode.UNEXPECTED_PAYLOAD_STATUS; blockRoot: RootHex | Root; payloadStatus: PayloadStatus}
|
|
27
|
+
| {code: RegenErrorCode.INTERNAL_ERROR; message: string};
|
|
23
28
|
|
|
24
29
|
export class RegenError extends Error {
|
|
25
30
|
type: RegenErrorType;
|
|
@@ -2,15 +2,17 @@ import {routes} from "@lodestar/api";
|
|
|
2
2
|
import {ProtoBlock} from "@lodestar/fork-choice";
|
|
3
3
|
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
|
|
4
4
|
import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
|
|
5
|
-
import {
|
|
5
|
+
import {CheckpointHexPayload} from "../stateCache/types.js";
|
|
6
6
|
|
|
7
7
|
export enum RegenCaller {
|
|
8
8
|
getDuties = "getDuties",
|
|
9
9
|
processBlock = "processBlock",
|
|
10
10
|
produceBlock = "produceBlock",
|
|
11
11
|
validateGossipBlock = "validateGossipBlock",
|
|
12
|
+
validateGossipPayloadEnvelope = "validateGossipPayloadEnvelope",
|
|
12
13
|
validateGossipBlob = "validateGossipBlob",
|
|
13
14
|
validateGossipDataColumn = "validateGossipDataColumn",
|
|
15
|
+
validateGossipExecutionPayloadEnvelope = "validateGossipExecutionPayloadEnvelope",
|
|
14
16
|
precomputeEpoch = "precomputeEpoch",
|
|
15
17
|
predictProposerHead = "predictProposerHead",
|
|
16
18
|
produceAttestationData = "produceAttestationData",
|
|
@@ -38,15 +40,21 @@ export interface IStateRegenerator extends IStateRegeneratorInternal {
|
|
|
38
40
|
dumpCacheSummary(): routes.lodestar.StateCacheItem[];
|
|
39
41
|
getStateSync(stateRoot: RootHex): CachedBeaconStateAllForks | null;
|
|
40
42
|
getPreStateSync(block: BeaconBlock): CachedBeaconStateAllForks | null;
|
|
41
|
-
getCheckpointStateOrBytes(cp:
|
|
42
|
-
getCheckpointStateSync(cp:
|
|
43
|
+
getCheckpointStateOrBytes(cp: CheckpointHexPayload): Promise<CachedBeaconStateAllForks | Uint8Array | null>;
|
|
44
|
+
getCheckpointStateSync(cp: CheckpointHexPayload): CachedBeaconStateAllForks | null;
|
|
43
45
|
getClosestHeadState(head: ProtoBlock): CachedBeaconStateAllForks | null;
|
|
44
46
|
pruneOnCheckpoint(finalizedEpoch: Epoch, justifiedEpoch: Epoch, headStateRoot: RootHex): void;
|
|
45
47
|
pruneOnFinalized(finalizedEpoch: Epoch): void;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
processBlockState(blockRootHex: RootHex, postState: CachedBeaconStateAllForks): void;
|
|
49
|
+
processPayloadState(payloadState: CachedBeaconStateAllForks): void;
|
|
50
|
+
/**
|
|
51
|
+
* payloadPresent is true if this is payload state, false if block state.
|
|
52
|
+
* payloadPresent is always true for pre-gloas.
|
|
53
|
+
*/
|
|
54
|
+
addCheckpointState(cp: phase0.Checkpoint, item: CachedBeaconStateAllForks, payloadPresent: boolean): void;
|
|
48
55
|
updateHeadState(newHead: ProtoBlock, maybeHeadState: CachedBeaconStateAllForks): void;
|
|
49
|
-
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
|
|
56
|
+
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, payloadPresent: boolean): number | null;
|
|
57
|
+
upgradeForGloas(epoch: Epoch): void;
|
|
50
58
|
}
|
|
51
59
|
|
|
52
60
|
/**
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
|
-
import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
2
|
+
import {IForkChoice, PayloadStatus, ProtoBlock} from "@lodestar/fork-choice";
|
|
3
3
|
import {CachedBeaconStateAllForks, computeEpochAtSlot} from "@lodestar/state-transition";
|
|
4
4
|
import {BeaconBlock, Epoch, RootHex, Slot, isGloasBeaconBlock, phase0} from "@lodestar/types";
|
|
5
|
-
import {Logger, toRootHex} from "@lodestar/utils";
|
|
5
|
+
import {Logger, fromHex, toRootHex} from "@lodestar/utils";
|
|
6
6
|
import {Metrics} from "../../metrics/index.js";
|
|
7
7
|
import {JobItemQueue} from "../../util/queue/index.js";
|
|
8
|
-
import {BlockStateCache,
|
|
8
|
+
import {BlockStateCache, CheckpointHexPayload, CheckpointStateCache} from "../stateCache/types.js";
|
|
9
9
|
import {RegenError, RegenErrorCode} from "./errors.js";
|
|
10
10
|
import {
|
|
11
11
|
IStateRegenerator,
|
|
@@ -104,9 +104,19 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
104
104
|
const parentEpoch = computeEpochAtSlot(parentBlock.slot);
|
|
105
105
|
const blockEpoch = computeEpochAtSlot(block.slot);
|
|
106
106
|
|
|
107
|
+
// Convert PayloadStatus to payloadPresent boolean
|
|
108
|
+
if (parentBlock.payloadStatus === PayloadStatus.PENDING) {
|
|
109
|
+
throw new RegenError({
|
|
110
|
+
code: RegenErrorCode.UNEXPECTED_PAYLOAD_STATUS,
|
|
111
|
+
blockRoot: block.parentRoot,
|
|
112
|
+
payloadStatus: parentBlock.payloadStatus,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const payloadPresent = parentBlock.payloadStatus === PayloadStatus.FULL;
|
|
116
|
+
|
|
107
117
|
// Check the checkpoint cache (if the pre-state is a checkpoint state)
|
|
108
118
|
if (parentEpoch < blockEpoch) {
|
|
109
|
-
const checkpointState = this.checkpointStateCache.getLatest(parentRoot, blockEpoch);
|
|
119
|
+
const checkpointState = this.checkpointStateCache.getLatest(parentRoot, blockEpoch, payloadPresent);
|
|
110
120
|
if (checkpointState && computeEpochAtSlot(checkpointState.slot) === blockEpoch) {
|
|
111
121
|
return checkpointState;
|
|
112
122
|
}
|
|
@@ -125,14 +135,14 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
125
135
|
return null;
|
|
126
136
|
}
|
|
127
137
|
|
|
128
|
-
async getCheckpointStateOrBytes(cp:
|
|
138
|
+
async getCheckpointStateOrBytes(cp: CheckpointHexPayload): Promise<CachedBeaconStateAllForks | Uint8Array | null> {
|
|
129
139
|
return this.checkpointStateCache.getStateOrBytes(cp);
|
|
130
140
|
}
|
|
131
141
|
|
|
132
142
|
/**
|
|
133
143
|
* Get checkpoint state from cache
|
|
134
144
|
*/
|
|
135
|
-
getCheckpointStateSync(cp:
|
|
145
|
+
getCheckpointStateSync(cp: CheckpointHexPayload): CachedBeaconStateAllForks | null {
|
|
136
146
|
return this.checkpointStateCache.get(cp);
|
|
137
147
|
}
|
|
138
148
|
|
|
@@ -140,7 +150,19 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
140
150
|
* Get state closest to head
|
|
141
151
|
*/
|
|
142
152
|
getClosestHeadState(head: ProtoBlock): CachedBeaconStateAllForks | null {
|
|
143
|
-
|
|
153
|
+
// Convert PayloadStatus to payloadPresent boolean
|
|
154
|
+
if (head.payloadStatus === PayloadStatus.PENDING) {
|
|
155
|
+
throw new RegenError({
|
|
156
|
+
code: RegenErrorCode.UNEXPECTED_PAYLOAD_STATUS,
|
|
157
|
+
blockRoot: fromHex(head.blockRoot),
|
|
158
|
+
payloadStatus: head.payloadStatus,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const payloadPresent = head.payloadStatus === PayloadStatus.FULL;
|
|
162
|
+
return (
|
|
163
|
+
this.checkpointStateCache.getLatest(head.blockRoot, Infinity, payloadPresent) ||
|
|
164
|
+
this.blockStateCache.get(head.stateRoot)
|
|
165
|
+
);
|
|
144
166
|
}
|
|
145
167
|
|
|
146
168
|
pruneOnCheckpoint(finalizedEpoch: Epoch, justifiedEpoch: Epoch, headStateRoot: RootHex): void {
|
|
@@ -153,15 +175,24 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
153
175
|
this.blockStateCache.deleteAllBeforeEpoch(finalizedEpoch);
|
|
154
176
|
}
|
|
155
177
|
|
|
156
|
-
|
|
178
|
+
processBlockState(blockRootHex: RootHex, postState: CachedBeaconStateAllForks): void {
|
|
157
179
|
this.blockStateCache.add(postState);
|
|
158
180
|
this.checkpointStateCache.processState(blockRootHex, postState).catch((e) => {
|
|
159
181
|
this.logger.debug("Error processing block state", {blockRootHex, slot: postState.slot}, e);
|
|
160
182
|
});
|
|
161
183
|
}
|
|
162
184
|
|
|
163
|
-
|
|
164
|
-
|
|
185
|
+
/**
|
|
186
|
+
* Process payload state for caching after importing execution payload.
|
|
187
|
+
*/
|
|
188
|
+
processPayloadState(payloadState: CachedBeaconStateAllForks): void {
|
|
189
|
+
// Add payload state to block state cache (keyed by payload state root)
|
|
190
|
+
this.blockStateCache.add(payloadState);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// TODO GLOAS: This should also be called when importing execution payload after we implement it
|
|
194
|
+
addCheckpointState(cp: phase0.Checkpoint, item: CachedBeaconStateAllForks, payloadPresent: boolean): void {
|
|
195
|
+
this.checkpointStateCache.add(cp, item, payloadPresent);
|
|
165
196
|
}
|
|
166
197
|
|
|
167
198
|
updateHeadState(newHead: ProtoBlock, maybeHeadState: CachedBeaconStateAllForks): void {
|
|
@@ -197,8 +228,13 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
197
228
|
}
|
|
198
229
|
}
|
|
199
230
|
|
|
200
|
-
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null {
|
|
201
|
-
return this.checkpointStateCache.updatePreComputedCheckpoint(rootHex, epoch);
|
|
231
|
+
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch, payloadPresent: boolean): number | null {
|
|
232
|
+
return this.checkpointStateCache.updatePreComputedCheckpoint(rootHex, epoch, payloadPresent);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
upgradeForGloas(epoch: Epoch): void {
|
|
236
|
+
this.logger.verbose("Upgrading block state cache for Gloas fork", {epoch});
|
|
237
|
+
this.blockStateCache.upgradeToGloas();
|
|
202
238
|
}
|
|
203
239
|
|
|
204
240
|
/**
|