@lodestar/beacon-node 1.41.0-dev.eb7efb2b90 → 1.41.0-dev.ef310100c0
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/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/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/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/execution/engine/http.d.ts +1 -0
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +3 -0
- package/lib/execution/engine/http.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 +8 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +14 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/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 +113 -63
- 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/peers/peerManager.d.ts +2 -0
- package/lib/network/peers/peerManager.d.ts.map +1 -1
- package/lib/network/peers/peerManager.js +54 -26
- package/lib/network/peers/peerManager.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/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 +11 -3
- package/lib/util/dataColumns.d.ts.map +1 -1
- package/lib/util/dataColumns.js +27 -0
- 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/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/dataColumnSidecar.ts +2 -5
- package/src/chain/validation/payloadAttestationMessage.ts +9 -1
- 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/execution/engine/http.ts +3 -0
- package/src/metrics/metrics/beacon.ts +5 -0
- package/src/metrics/metrics/lodestar.ts +14 -0
- 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/peers/peerManager.ts +65 -27
- 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/util/blobs.ts +3 -3
- package/src/util/dataColumns.ts +37 -1
- package/src/util/multifork.ts +45 -0
- package/src/util/serializedCache.ts +5 -0
package/src/chain/chain.ts
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
|
-
import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
|
|
4
3
|
import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
|
|
5
4
|
import {BeaconConfig} from "@lodestar/config";
|
|
6
5
|
import {CheckpointWithHex, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
|
|
7
6
|
import {LoggerNode} from "@lodestar/logger/node";
|
|
8
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
BUILDER_INDEX_SELF_BUILD,
|
|
9
|
+
EFFECTIVE_BALANCE_INCREMENT,
|
|
10
|
+
ForkPostFulu,
|
|
11
|
+
GENESIS_SLOT,
|
|
12
|
+
SLOTS_PER_EPOCH,
|
|
13
|
+
isForkPostElectra,
|
|
14
|
+
isForkPostGloas,
|
|
15
|
+
} from "@lodestar/params";
|
|
9
16
|
import {
|
|
10
17
|
BeaconStateAllForks,
|
|
11
18
|
BeaconStateElectra,
|
|
12
19
|
CachedBeaconStateAllForks,
|
|
20
|
+
CachedBeaconStateGloas,
|
|
13
21
|
EffectiveBalanceIncrements,
|
|
14
22
|
EpochShuffling,
|
|
15
|
-
|
|
23
|
+
PubkeyCache,
|
|
16
24
|
computeAnchorCheckpoint,
|
|
17
25
|
computeAttestationsRewards,
|
|
18
26
|
computeBlockRewards,
|
|
@@ -28,6 +36,7 @@ import {
|
|
|
28
36
|
BeaconBlock,
|
|
29
37
|
BlindedBeaconBlock,
|
|
30
38
|
BlindedBeaconBlockBody,
|
|
39
|
+
DataColumnSidecars,
|
|
31
40
|
Epoch,
|
|
32
41
|
Root,
|
|
33
42
|
RootHex,
|
|
@@ -38,7 +47,7 @@ import {
|
|
|
38
47
|
ValidatorIndex,
|
|
39
48
|
Wei,
|
|
40
49
|
deneb,
|
|
41
|
-
|
|
50
|
+
gloas,
|
|
42
51
|
isBlindedBeaconBlock,
|
|
43
52
|
phase0,
|
|
44
53
|
rewards,
|
|
@@ -87,8 +96,8 @@ import {
|
|
|
87
96
|
} from "./opPools/index.js";
|
|
88
97
|
import {IChainOptions} from "./options.js";
|
|
89
98
|
import {PrepareNextSlotScheduler} from "./prepareNextSlot.js";
|
|
90
|
-
import {computeNewStateRoot} from "./produceBlock/computeNewStateRoot.js";
|
|
91
|
-
import {AssembledBlockType, BlockType, ProduceResult} from "./produceBlock/index.js";
|
|
99
|
+
import {computeEnvelopeStateRoot, computeNewStateRoot} from "./produceBlock/computeNewStateRoot.js";
|
|
100
|
+
import {AssembledBlockType, BlockType, ProduceFullGloas, ProduceResult} from "./produceBlock/index.js";
|
|
92
101
|
import {BlockAttributes, produceBlockBody, produceCommonBlockBody} from "./produceBlock/produceBlockBody.js";
|
|
93
102
|
import {QueuedStateRegenerator, RegenCaller} from "./regen/index.js";
|
|
94
103
|
import {ReprocessController} from "./reprocess.js";
|
|
@@ -182,8 +191,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
182
191
|
readonly seenBlockAttesters = new SeenBlockAttesters();
|
|
183
192
|
|
|
184
193
|
// Global state caches
|
|
185
|
-
readonly
|
|
186
|
-
readonly index2pubkey: Index2PubkeyCache;
|
|
194
|
+
readonly pubkeyCache: PubkeyCache;
|
|
187
195
|
|
|
188
196
|
readonly beaconProposerCache: BeaconProposerCache;
|
|
189
197
|
readonly checkpointBalancesCache: CheckpointBalancesCache;
|
|
@@ -229,8 +237,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
229
237
|
{
|
|
230
238
|
privateKey,
|
|
231
239
|
config,
|
|
232
|
-
|
|
233
|
-
index2pubkey,
|
|
240
|
+
pubkeyCache,
|
|
234
241
|
db,
|
|
235
242
|
dbName,
|
|
236
243
|
dataDir,
|
|
@@ -246,8 +253,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
246
253
|
}: {
|
|
247
254
|
privateKey: PrivateKey;
|
|
248
255
|
config: BeaconConfig;
|
|
249
|
-
|
|
250
|
-
index2pubkey: Index2PubkeyCache;
|
|
256
|
+
pubkeyCache: PubkeyCache;
|
|
251
257
|
db: IBeaconDb;
|
|
252
258
|
dbName: string;
|
|
253
259
|
dataDir: string;
|
|
@@ -279,8 +285,8 @@ export class BeaconChain implements IBeaconChain {
|
|
|
279
285
|
const emitter = new ChainEventEmitter();
|
|
280
286
|
// by default, verify signatures on both main threads and worker threads
|
|
281
287
|
const bls = opts.blsVerifyAllMainThread
|
|
282
|
-
? new BlsSingleThreadVerifier({metrics,
|
|
283
|
-
: new BlsMultiThreadWorkerPool(opts, {logger, metrics,
|
|
288
|
+
? new BlsSingleThreadVerifier({metrics, pubkeyCache})
|
|
289
|
+
: new BlsMultiThreadWorkerPool(opts, {logger, metrics, pubkeyCache});
|
|
284
290
|
|
|
285
291
|
if (!clock) clock = new Clock({config, genesisTime: this.genesisTime, signal});
|
|
286
292
|
|
|
@@ -336,8 +342,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
336
342
|
]);
|
|
337
343
|
|
|
338
344
|
// Global cache of validators pubkey/index mapping
|
|
339
|
-
this.
|
|
340
|
-
this.index2pubkey = index2pubkey;
|
|
345
|
+
this.pubkeyCache = pubkeyCache;
|
|
341
346
|
|
|
342
347
|
const fileDataStore = opts.nHistoricalStatesFileDataStore ?? true;
|
|
343
348
|
const blockStateCache = new FIFOBlockStateCache(this.opts, {metrics});
|
|
@@ -808,7 +813,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
808
813
|
return null;
|
|
809
814
|
}
|
|
810
815
|
|
|
811
|
-
async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<
|
|
816
|
+
async getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecars> {
|
|
812
817
|
const blockInput = this.seenBlockInputCache.get(blockRootHex);
|
|
813
818
|
if (blockInput) {
|
|
814
819
|
if (!isBlockInputColumns(blockInput)) {
|
|
@@ -818,10 +823,10 @@ export class BeaconChain implements IBeaconChain {
|
|
|
818
823
|
}
|
|
819
824
|
const sidecarsUnfinalized = await this.db.dataColumnSidecar.values(fromHex(blockRootHex));
|
|
820
825
|
if (sidecarsUnfinalized.length > 0) {
|
|
821
|
-
return sidecarsUnfinalized;
|
|
826
|
+
return sidecarsUnfinalized as DataColumnSidecars;
|
|
822
827
|
}
|
|
823
828
|
const sidecarsFinalized = await this.db.dataColumnSidecarArchive.values(blockSlot);
|
|
824
|
-
return sidecarsFinalized;
|
|
829
|
+
return sidecarsFinalized as DataColumnSidecars;
|
|
825
830
|
}
|
|
826
831
|
|
|
827
832
|
async getSerializedDataColumnSidecars(
|
|
@@ -843,7 +848,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
843
848
|
if (serialized) {
|
|
844
849
|
return serialized;
|
|
845
850
|
}
|
|
846
|
-
return
|
|
851
|
+
return sszTypesFor(blockInput.forkName as ForkPostFulu).DataColumnSidecar.serialize(sidecar);
|
|
847
852
|
});
|
|
848
853
|
}
|
|
849
854
|
const sidecarsUnfinalized = await this.db.dataColumnSidecar.getManyBinary(fromHex(blockRootHex), indices);
|
|
@@ -902,6 +907,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
902
907
|
consensusBlockValue: Wei;
|
|
903
908
|
shouldOverrideBuilder?: boolean;
|
|
904
909
|
}> {
|
|
910
|
+
const fork = this.config.getForkName(slot);
|
|
905
911
|
const state = await this.regen.getBlockSlotState(
|
|
906
912
|
parentBlock,
|
|
907
913
|
slot,
|
|
@@ -909,7 +915,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
909
915
|
RegenCaller.produceBlock
|
|
910
916
|
);
|
|
911
917
|
const proposerIndex = state.epochCtx.getBeaconProposer(slot);
|
|
912
|
-
const proposerPubKey = this.
|
|
918
|
+
const proposerPubKey = this.pubkeyCache.getOrThrow(proposerIndex).toBytes();
|
|
913
919
|
|
|
914
920
|
const {body, produceResult, executionPayloadValue, shouldOverrideBuilder} = await produceBlockBody.call(
|
|
915
921
|
this,
|
|
@@ -930,7 +936,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
930
936
|
// The hashtree root computed here for debug log will get cached and hence won't introduce additional delays
|
|
931
937
|
const bodyRoot =
|
|
932
938
|
produceResult.type === BlockType.Full
|
|
933
|
-
?
|
|
939
|
+
? sszTypesFor(fork).BeaconBlockBody.hashTreeRoot(body)
|
|
934
940
|
: this.config
|
|
935
941
|
.getPostBellatrixForkTypes(slot)
|
|
936
942
|
.BlindedBeaconBlockBody.hashTreeRoot(body as BlindedBeaconBlockBody);
|
|
@@ -948,14 +954,33 @@ export class BeaconChain implements IBeaconChain {
|
|
|
948
954
|
body,
|
|
949
955
|
} as AssembledBlockType<T>;
|
|
950
956
|
|
|
951
|
-
const {newStateRoot, proposerReward} = computeNewStateRoot(this.metrics, state, block);
|
|
957
|
+
const {newStateRoot, proposerReward, postState} = computeNewStateRoot(this.metrics, state, block);
|
|
952
958
|
block.stateRoot = newStateRoot;
|
|
953
959
|
const blockRoot =
|
|
954
960
|
produceResult.type === BlockType.Full
|
|
955
|
-
?
|
|
961
|
+
? sszTypesFor(fork).BeaconBlock.hashTreeRoot(block)
|
|
956
962
|
: this.config.getPostBellatrixForkTypes(slot).BlindedBeaconBlock.hashTreeRoot(block as BlindedBeaconBlock);
|
|
957
963
|
const blockRootHex = toRootHex(blockRoot);
|
|
958
964
|
|
|
965
|
+
if (isForkPostGloas(fork)) {
|
|
966
|
+
// TODO GLOAS: we should retire BlockType post-gloas, may need a new enum for self vs non-self built
|
|
967
|
+
if (produceResult.type !== BlockType.Full) {
|
|
968
|
+
throw Error(`Unexpected block type=${produceResult.type} for post-gloas fork=${fork}`);
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
const gloasResult = produceResult as ProduceFullGloas;
|
|
972
|
+
const envelope: gloas.ExecutionPayloadEnvelope = {
|
|
973
|
+
payload: gloasResult.executionPayload,
|
|
974
|
+
executionRequests: gloasResult.executionRequests,
|
|
975
|
+
builderIndex: BUILDER_INDEX_SELF_BUILD,
|
|
976
|
+
beaconBlockRoot: blockRoot,
|
|
977
|
+
slot,
|
|
978
|
+
stateRoot: ZERO_HASH,
|
|
979
|
+
};
|
|
980
|
+
const envelopeStateRoot = computeEnvelopeStateRoot(this.metrics, postState as CachedBeaconStateGloas, envelope);
|
|
981
|
+
gloasResult.envelopeStateRoot = envelopeStateRoot;
|
|
982
|
+
}
|
|
983
|
+
|
|
959
984
|
// Track the produced block for consensus broadcast validations, later validation, etc.
|
|
960
985
|
this.blockProductionCache.set(blockRootHex, produceResult);
|
|
961
986
|
this.metrics?.blockProductionCacheSize.set(this.blockProductionCache.size);
|
|
@@ -1506,7 +1531,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1506
1531
|
throw Error(`State is not in cache for slot ${slot}`);
|
|
1507
1532
|
}
|
|
1508
1533
|
|
|
1509
|
-
const rewards = await computeAttestationsRewards(this.config, this.
|
|
1534
|
+
const rewards = await computeAttestationsRewards(this.config, this.pubkeyCache, cachedState, validatorIds);
|
|
1510
1535
|
|
|
1511
1536
|
return {rewards, executionOptimistic, finalized};
|
|
1512
1537
|
}
|
|
@@ -1523,6 +1548,6 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1523
1548
|
|
|
1524
1549
|
preState = processSlots(preState, block.slot); // Dial preState's slot to block.slot
|
|
1525
1550
|
|
|
1526
|
-
return computeSyncCommitteeRewards(this.config, this.
|
|
1551
|
+
return computeSyncCommitteeRewards(this.config, this.pubkeyCache, block, preState, validatorIds);
|
|
1527
1552
|
}
|
|
1528
1553
|
}
|
package/src/chain/emitter.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {StrictEventEmitter} from "strict-event-emitter-types";
|
|
|
3
3
|
import {routes} from "@lodestar/api";
|
|
4
4
|
import {CheckpointWithHex} from "@lodestar/fork-choice";
|
|
5
5
|
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
|
|
6
|
-
import {RootHex, deneb,
|
|
6
|
+
import {DataColumnSidecars, RootHex, deneb, phase0} from "@lodestar/types";
|
|
7
7
|
import {PeerIdStr} from "../util/peerId.js";
|
|
8
8
|
import {BlockInputSource, IBlockInput} from "./blocks/blockInput/types.js";
|
|
9
9
|
|
|
@@ -88,7 +88,7 @@ export type IChainEvents = ApiEvents & {
|
|
|
88
88
|
|
|
89
89
|
[ChainEvent.updateTargetCustodyGroupCount]: (targetGroupCount: number) => void;
|
|
90
90
|
|
|
91
|
-
[ChainEvent.publishDataColumns]: (sidecars:
|
|
91
|
+
[ChainEvent.publishDataColumns]: (sidecars: DataColumnSidecars) => void;
|
|
92
92
|
|
|
93
93
|
[ChainEvent.publishBlobSidecars]: (sidecars: deneb.BlobSidecar[]) => void;
|
|
94
94
|
|
package/src/chain/interface.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
import {PubkeyIndexMap} from "@chainsafe/pubkey-index-map";
|
|
2
1
|
import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
|
|
3
2
|
import {BeaconConfig} from "@lodestar/config";
|
|
4
3
|
import {CheckpointWithHex, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
|
|
5
|
-
import {
|
|
6
|
-
BeaconStateAllForks,
|
|
7
|
-
CachedBeaconStateAllForks,
|
|
8
|
-
EpochShuffling,
|
|
9
|
-
Index2PubkeyCache,
|
|
10
|
-
} from "@lodestar/state-transition";
|
|
4
|
+
import {BeaconStateAllForks, CachedBeaconStateAllForks, EpochShuffling, PubkeyCache} from "@lodestar/state-transition";
|
|
11
5
|
import {
|
|
12
6
|
BeaconBlock,
|
|
13
7
|
BlindedBeaconBlock,
|
|
8
|
+
DataColumnSidecars,
|
|
14
9
|
Epoch,
|
|
15
10
|
Root,
|
|
16
11
|
RootHex,
|
|
@@ -23,7 +18,6 @@ import {
|
|
|
23
18
|
altair,
|
|
24
19
|
capella,
|
|
25
20
|
deneb,
|
|
26
|
-
fulu,
|
|
27
21
|
phase0,
|
|
28
22
|
rewards,
|
|
29
23
|
} from "@lodestar/types";
|
|
@@ -117,8 +111,7 @@ export interface IBeaconChain {
|
|
|
117
111
|
readonly regen: IStateRegenerator;
|
|
118
112
|
readonly lightClientServer?: LightClientServer;
|
|
119
113
|
readonly reprocessController: ReprocessController;
|
|
120
|
-
readonly
|
|
121
|
-
readonly index2pubkey: Index2PubkeyCache;
|
|
114
|
+
readonly pubkeyCache: PubkeyCache;
|
|
122
115
|
readonly archiveStore: IArchiveStore;
|
|
123
116
|
|
|
124
117
|
// Ops pool
|
|
@@ -224,7 +217,7 @@ export interface IBeaconChain {
|
|
|
224
217
|
): Promise<{block: SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null>;
|
|
225
218
|
getBlobSidecars(blockSlot: Slot, blockRootHex: string): Promise<deneb.BlobSidecars | null>;
|
|
226
219
|
getSerializedBlobSidecars(blockSlot: Slot, blockRootHex: string): Promise<Uint8Array | null>;
|
|
227
|
-
getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<
|
|
220
|
+
getDataColumnSidecars(blockSlot: Slot, blockRootHex: string): Promise<DataColumnSidecars>;
|
|
228
221
|
getSerializedDataColumnSidecars(
|
|
229
222
|
blockSlot: Slot,
|
|
230
223
|
blockRootHex: string,
|
|
@@ -355,7 +355,10 @@ export class LightClientServer {
|
|
|
355
355
|
// Signature data
|
|
356
356
|
const update = await this.db.bestLightClientUpdate.get(period);
|
|
357
357
|
if (!update) {
|
|
358
|
-
throw
|
|
358
|
+
throw new LightClientServerError(
|
|
359
|
+
{code: LightClientServerErrorCode.RESOURCE_UNAVAILABLE},
|
|
360
|
+
`No partialUpdate available for period ${period}`
|
|
361
|
+
);
|
|
359
362
|
}
|
|
360
363
|
return update;
|
|
361
364
|
}
|
package/src/chain/options.ts
CHANGED
|
@@ -27,6 +27,7 @@ export type IChainOptions = BlockProcessOpts &
|
|
|
27
27
|
blsVerifyAllMainThread?: boolean;
|
|
28
28
|
blsVerifyAllMultiThread?: boolean;
|
|
29
29
|
blacklistedBlocks?: string[];
|
|
30
|
+
// TODO GLOAS: add similar option for execution payload envelopes?
|
|
30
31
|
persistProducedBlocks?: boolean;
|
|
31
32
|
persistInvalidSszObjects?: boolean;
|
|
32
33
|
persistInvalidSszObjectsDir?: string;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {routes} from "@lodestar/api";
|
|
2
2
|
import {ChainForkConfig} from "@lodestar/config";
|
|
3
3
|
import {getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
4
|
-
import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH} from "@lodestar/params";
|
|
4
|
+
import {ForkPostBellatrix, ForkSeq, SLOTS_PER_EPOCH, isForkPostBellatrix} from "@lodestar/params";
|
|
5
5
|
import {
|
|
6
6
|
CachedBeaconStateAllForks,
|
|
7
7
|
CachedBeaconStateExecutions,
|
|
8
|
+
CachedBeaconStateGloas,
|
|
8
9
|
StateHashTreeRootSource,
|
|
9
10
|
computeEpochAtSlot,
|
|
10
11
|
computeTimeAtSlot,
|
|
11
|
-
isExecutionStateType,
|
|
12
12
|
} from "@lodestar/state-transition";
|
|
13
13
|
import {Slot} from "@lodestar/types";
|
|
14
14
|
import {Logger, fromHex, isErrorAborted, sleep} from "@lodestar/utils";
|
|
@@ -120,10 +120,10 @@ export class PrepareNextSlotScheduler {
|
|
|
120
120
|
RegenCaller.precomputeEpoch
|
|
121
121
|
);
|
|
122
122
|
|
|
123
|
-
if (
|
|
123
|
+
if (isForkPostBellatrix(fork)) {
|
|
124
124
|
const proposerIndex = prepareState.epochCtx.getBeaconProposer(prepareSlot);
|
|
125
125
|
const feeRecipient = this.chain.beaconProposerCache.get(proposerIndex);
|
|
126
|
-
let updatedPrepareState = prepareState;
|
|
126
|
+
let updatedPrepareState = prepareState as CachedBeaconStateExecutions | CachedBeaconStateGloas;
|
|
127
127
|
let updatedHeadRoot = headRoot;
|
|
128
128
|
|
|
129
129
|
if (feeRecipient) {
|
|
@@ -146,7 +146,7 @@ export class PrepareNextSlotScheduler {
|
|
|
146
146
|
// only transfer cache if epoch transition because that's the state we will use to stateTransition() the 1st block of epoch
|
|
147
147
|
{dontTransferCache: !isEpochTransition},
|
|
148
148
|
RegenCaller.predictProposerHead
|
|
149
|
-
)) as CachedBeaconStateExecutions;
|
|
149
|
+
)) as CachedBeaconStateExecutions | CachedBeaconStateGloas;
|
|
150
150
|
updatedHeadRoot = proposerHeadRoot;
|
|
151
151
|
}
|
|
152
152
|
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CachedBeaconStateAllForks,
|
|
3
|
+
CachedBeaconStateGloas,
|
|
3
4
|
DataAvailabilityStatus,
|
|
4
5
|
ExecutionPayloadStatus,
|
|
6
|
+
G2_POINT_AT_INFINITY,
|
|
5
7
|
StateHashTreeRootSource,
|
|
6
8
|
stateTransition,
|
|
7
9
|
} from "@lodestar/state-transition";
|
|
8
|
-
import {
|
|
10
|
+
import {processExecutionPayloadEnvelope} from "@lodestar/state-transition/block";
|
|
11
|
+
import {BeaconBlock, BlindedBeaconBlock, Gwei, Root, gloas} from "@lodestar/types";
|
|
9
12
|
import {ZERO_HASH} from "../../constants/index.js";
|
|
10
13
|
import {Metrics} from "../../metrics/index.js";
|
|
11
14
|
|
|
@@ -18,7 +21,7 @@ export function computeNewStateRoot(
|
|
|
18
21
|
metrics: Metrics | null,
|
|
19
22
|
state: CachedBeaconStateAllForks,
|
|
20
23
|
block: BeaconBlock | BlindedBeaconBlock
|
|
21
|
-
): {newStateRoot: Root; proposerReward: Gwei} {
|
|
24
|
+
): {newStateRoot: Root; proposerReward: Gwei; postState: CachedBeaconStateAllForks} {
|
|
22
25
|
// Set signature to zero to re-use stateTransition() function which requires the SignedBeaconBlock type
|
|
23
26
|
const blockEmptySig = {message: block, signature: ZERO_HASH};
|
|
24
27
|
|
|
@@ -51,5 +54,34 @@ export function computeNewStateRoot(
|
|
|
51
54
|
const newStateRoot = postState.hashTreeRoot();
|
|
52
55
|
hashTreeRootTimer?.();
|
|
53
56
|
|
|
54
|
-
return {newStateRoot, proposerReward};
|
|
57
|
+
return {newStateRoot, proposerReward, postState};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Compute the state root after processing an execution payload envelope.
|
|
62
|
+
* Similar to `computeNewStateRoot` but for payload envelope processing.
|
|
63
|
+
*
|
|
64
|
+
* The `postBlockState` is mutated in place, callers must ensure it is not needed afterward.
|
|
65
|
+
*/
|
|
66
|
+
export function computeEnvelopeStateRoot(
|
|
67
|
+
metrics: Metrics | null,
|
|
68
|
+
postBlockState: CachedBeaconStateGloas,
|
|
69
|
+
envelope: gloas.ExecutionPayloadEnvelope
|
|
70
|
+
): Root {
|
|
71
|
+
const signedEnvelope: gloas.SignedExecutionPayloadEnvelope = {
|
|
72
|
+
message: envelope,
|
|
73
|
+
signature: G2_POINT_AT_INFINITY,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const processEnvelopeTimer = metrics?.blockPayload.executionPayloadEnvelopeProcessingTime.startTimer();
|
|
77
|
+
processExecutionPayloadEnvelope(postBlockState, signedEnvelope, false);
|
|
78
|
+
processEnvelopeTimer?.();
|
|
79
|
+
|
|
80
|
+
const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
|
|
81
|
+
source: StateHashTreeRootSource.computeEnvelopeStateRoot,
|
|
82
|
+
});
|
|
83
|
+
const stateRoot = postBlockState.hashTreeRoot();
|
|
84
|
+
hashTreeRootTimer?.();
|
|
85
|
+
|
|
86
|
+
return stateRoot;
|
|
55
87
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
|
-
import {ProtoBlock, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
2
|
+
import {IForkChoice, ProtoBlock, getSafeExecutionBlockHash} from "@lodestar/fork-choice";
|
|
3
3
|
import {
|
|
4
|
+
BUILDER_INDEX_SELF_BUILD,
|
|
4
5
|
ForkName,
|
|
5
6
|
ForkPostBellatrix,
|
|
7
|
+
ForkPostCapella,
|
|
6
8
|
ForkPostDeneb,
|
|
7
9
|
ForkPostFulu,
|
|
10
|
+
ForkPostGloas,
|
|
8
11
|
ForkPreGloas,
|
|
9
12
|
ForkSeq,
|
|
10
13
|
isForkPostAltair,
|
|
@@ -16,6 +19,8 @@ import {
|
|
|
16
19
|
CachedBeaconStateBellatrix,
|
|
17
20
|
CachedBeaconStateCapella,
|
|
18
21
|
CachedBeaconStateExecutions,
|
|
22
|
+
CachedBeaconStateGloas,
|
|
23
|
+
G2_POINT_AT_INFINITY,
|
|
19
24
|
computeTimeAtSlot,
|
|
20
25
|
getExpectedWithdrawals,
|
|
21
26
|
getRandaoMix,
|
|
@@ -42,6 +47,7 @@ import {
|
|
|
42
47
|
deneb,
|
|
43
48
|
electra,
|
|
44
49
|
fulu,
|
|
50
|
+
gloas,
|
|
45
51
|
} from "@lodestar/types";
|
|
46
52
|
import {Logger, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
47
53
|
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
@@ -99,6 +105,20 @@ export type AssembledBodyType<T extends BlockType> = T extends BlockType.Full
|
|
|
99
105
|
: BlindedBeaconBlockBody;
|
|
100
106
|
export type AssembledBlockType<T extends BlockType> = T extends BlockType.Full ? BeaconBlock : BlindedBeaconBlock;
|
|
101
107
|
|
|
108
|
+
export type ProduceFullGloas = {
|
|
109
|
+
type: BlockType.Full;
|
|
110
|
+
fork: ForkPostGloas;
|
|
111
|
+
executionPayload: ExecutionPayload<ForkPostGloas>;
|
|
112
|
+
executionRequests: electra.ExecutionRequests;
|
|
113
|
+
blobsBundle: BlobsBundle<ForkPostGloas>;
|
|
114
|
+
cells: fulu.Cell[][];
|
|
115
|
+
/**
|
|
116
|
+
* Cached envelope state root computed during block production.
|
|
117
|
+
* This is the state root after running `processExecutionPayloadEnvelope` on the
|
|
118
|
+
* post-block state, and later used to construct the `ExecutionPayloadEnvelope`.
|
|
119
|
+
*/
|
|
120
|
+
envelopeStateRoot: Root;
|
|
121
|
+
};
|
|
102
122
|
export type ProduceFullFulu = {
|
|
103
123
|
type: BlockType.Full;
|
|
104
124
|
fork: ForkPostFulu;
|
|
@@ -131,6 +151,7 @@ export type ProduceBlinded = {
|
|
|
131
151
|
|
|
132
152
|
/** The result of local block production, everything that's not the block itself */
|
|
133
153
|
export type ProduceResult =
|
|
154
|
+
| ProduceFullGloas
|
|
134
155
|
| ProduceFullFulu
|
|
135
156
|
| ProduceFullDeneb
|
|
136
157
|
| ProduceFullBellatrix
|
|
@@ -180,12 +201,112 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
180
201
|
this.logger.verbose("Producing beacon block body", logMeta);
|
|
181
202
|
|
|
182
203
|
if (isForkPostGloas(fork)) {
|
|
183
|
-
// TODO GLOAS:
|
|
204
|
+
// TODO GLOAS: support non self-building here, the block type differentiation between
|
|
205
|
+
// full and blinded no longer makes sense in gloas, it might be a good idea to move
|
|
206
|
+
// this into a completely separate function and have pre/post gloas more separated
|
|
207
|
+
const gloasState = currentState as CachedBeaconStateGloas;
|
|
208
|
+
const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice);
|
|
209
|
+
const finalizedBlockHash = this.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
|
|
210
|
+
const feeRecipient = requestedFeeRecipient ?? this.beaconProposerCache.getOrDefault(proposerIndex);
|
|
211
|
+
|
|
212
|
+
const endExecutionPayload = this.metrics?.executionBlockProductionTimeSteps.startTimer();
|
|
213
|
+
|
|
214
|
+
this.logger.verbose("Preparing execution payload from engine", {
|
|
215
|
+
slot: blockSlot,
|
|
216
|
+
parentBlockRoot: toRootHex(parentBlockRoot),
|
|
217
|
+
feeRecipient,
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Get execution payload from EL
|
|
221
|
+
const prepareRes = await prepareExecutionPayload(
|
|
222
|
+
this,
|
|
223
|
+
this.logger,
|
|
224
|
+
fork,
|
|
225
|
+
parentBlockRoot,
|
|
226
|
+
safeBlockHash,
|
|
227
|
+
finalizedBlockHash ?? ZERO_HASH_HEX,
|
|
228
|
+
gloasState,
|
|
229
|
+
feeRecipient
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const {prepType, payloadId} = prepareRes;
|
|
233
|
+
Object.assign(logMeta, {executionPayloadPrepType: prepType});
|
|
234
|
+
|
|
235
|
+
if (prepType !== PayloadPreparationType.Cached) {
|
|
236
|
+
await sleep(PAYLOAD_GENERATION_TIME_MS);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
this.logger.verbose("Fetching execution payload from engine", {slot: blockSlot, payloadId});
|
|
240
|
+
const payloadRes = await this.executionEngine.getPayload(fork, payloadId);
|
|
241
|
+
|
|
242
|
+
endExecutionPayload?.({step: BlockProductionStep.executionPayload});
|
|
243
|
+
|
|
244
|
+
const {executionPayload, blobsBundle, executionRequests} = payloadRes;
|
|
245
|
+
executionPayloadValue = payloadRes.executionPayloadValue;
|
|
246
|
+
shouldOverrideBuilder = payloadRes.shouldOverrideBuilder;
|
|
247
|
+
|
|
248
|
+
if (blobsBundle === undefined) {
|
|
249
|
+
throw Error(`Missing blobsBundle response from getPayload at fork=${fork}`);
|
|
250
|
+
}
|
|
251
|
+
if (executionRequests === undefined) {
|
|
252
|
+
throw Error(`Missing executionRequests response from getPayload at fork=${fork}`);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const cells = blobsBundle.blobs.map((blob) => kzg.computeCells(blob));
|
|
256
|
+
if (this.opts.sanityCheckExecutionEngineBlobs) {
|
|
257
|
+
await validateCellsAndKzgCommitments(blobsBundle.commitments, blobsBundle.proofs, cells);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Create self-build execution payload bid
|
|
261
|
+
const bid: gloas.ExecutionPayloadBid = {
|
|
262
|
+
parentBlockHash: gloasState.latestBlockHash,
|
|
263
|
+
parentBlockRoot: parentBlockRoot,
|
|
264
|
+
blockHash: executionPayload.blockHash,
|
|
265
|
+
prevRandao: getRandaoMix(gloasState, gloasState.epochCtx.epoch),
|
|
266
|
+
feeRecipient: executionPayload.feeRecipient,
|
|
267
|
+
gasLimit: BigInt(executionPayload.gasLimit),
|
|
268
|
+
builderIndex: BUILDER_INDEX_SELF_BUILD,
|
|
269
|
+
slot: blockSlot,
|
|
270
|
+
value: 0,
|
|
271
|
+
executionPayment: 0,
|
|
272
|
+
blobKzgCommitments: blobsBundle.commitments,
|
|
273
|
+
};
|
|
274
|
+
const signedBid: gloas.SignedExecutionPayloadBid = {
|
|
275
|
+
message: bid,
|
|
276
|
+
signature: G2_POINT_AT_INFINITY,
|
|
277
|
+
};
|
|
278
|
+
|
|
184
279
|
const commonBlockBody = await commonBlockBodyPromise;
|
|
185
|
-
|
|
186
|
-
|
|
280
|
+
const gloasBody = Object.assign({}, commonBlockBody) as gloas.BeaconBlockBody;
|
|
281
|
+
gloasBody.signedExecutionPayloadBid = signedBid;
|
|
282
|
+
// TODO GLOAS: Get payload attestations from pool for previous slot
|
|
283
|
+
gloasBody.payloadAttestations = [];
|
|
284
|
+
blockBody = gloasBody as AssembledBodyType<T>;
|
|
285
|
+
|
|
286
|
+
// Store execution payload data required to construct execution payload envelope later
|
|
287
|
+
const gloasResult = produceResult as ProduceFullGloas;
|
|
288
|
+
gloasResult.executionPayload = executionPayload as ExecutionPayload<ForkPostGloas>;
|
|
289
|
+
gloasResult.executionRequests = executionRequests;
|
|
290
|
+
gloasResult.blobsBundle = blobsBundle;
|
|
291
|
+
gloasResult.cells = cells;
|
|
292
|
+
|
|
293
|
+
const fetchedTime = Date.now() / 1000 - computeTimeAtSlot(this.config, blockSlot, this.genesisTime);
|
|
294
|
+
this.metrics?.blockPayload.payloadFetchedTime.observe({prepType}, fetchedTime);
|
|
295
|
+
this.logger.verbose("Produced block with self-build bid", {
|
|
296
|
+
slot: blockSlot,
|
|
297
|
+
executionPayloadValue,
|
|
298
|
+
prepType,
|
|
299
|
+
payloadId,
|
|
300
|
+
fetchedTime,
|
|
301
|
+
executionBlockHash: toRootHex(executionPayload.blockHash),
|
|
302
|
+
blobs: blobsBundle.commitments.length,
|
|
303
|
+
});
|
|
187
304
|
|
|
188
|
-
|
|
305
|
+
Object.assign(logMeta, {
|
|
306
|
+
transactions: executionPayload.transactions.length,
|
|
307
|
+
blobs: blobsBundle.commitments.length,
|
|
308
|
+
shouldOverrideBuilder,
|
|
309
|
+
});
|
|
189
310
|
} else if (isForkPostBellatrix(fork)) {
|
|
190
311
|
const safeBlockHash = getSafeExecutionBlockHash(this.forkChoice);
|
|
191
312
|
const finalizedBlockHash = this.forkChoice.getFinalizedBlock().executionPayloadBlockHash ?? ZERO_HASH_HEX;
|
|
@@ -447,8 +568,14 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
447
568
|
});
|
|
448
569
|
}
|
|
449
570
|
|
|
450
|
-
if (ForkSeq[fork] >= ForkSeq.
|
|
451
|
-
const {blsToExecutionChanges,
|
|
571
|
+
if (ForkSeq[fork] >= ForkSeq.gloas) {
|
|
572
|
+
const {blsToExecutionChanges, payloadAttestations} = blockBody as BeaconBlockBody<ForkPostGloas>;
|
|
573
|
+
Object.assign(logMeta, {
|
|
574
|
+
blsToExecutionChanges: blsToExecutionChanges.length,
|
|
575
|
+
payloadAttestations: payloadAttestations.length,
|
|
576
|
+
});
|
|
577
|
+
} else if (ForkSeq[fork] >= ForkSeq.capella) {
|
|
578
|
+
const {blsToExecutionChanges, executionPayload} = blockBody as BeaconBlockBody<ForkPostCapella & ForkPreGloas>;
|
|
452
579
|
Object.assign(logMeta, {
|
|
453
580
|
blsToExecutionChanges: blsToExecutionChanges.length,
|
|
454
581
|
});
|
|
@@ -480,10 +607,12 @@ export async function prepareExecutionPayload(
|
|
|
480
607
|
parentBlockRoot: Root,
|
|
481
608
|
safeBlockHash: RootHex,
|
|
482
609
|
finalizedBlockHash: RootHex,
|
|
483
|
-
state: CachedBeaconStateExecutions,
|
|
610
|
+
state: CachedBeaconStateExecutions | CachedBeaconStateGloas,
|
|
484
611
|
suggestedFeeRecipient: string
|
|
485
612
|
): Promise<{prepType: PayloadPreparationType; payloadId: PayloadId}> {
|
|
486
|
-
const parentHash =
|
|
613
|
+
const parentHash = isForkPostGloas(fork)
|
|
614
|
+
? (state as CachedBeaconStateGloas).latestBlockHash
|
|
615
|
+
: (state as CachedBeaconStateExecutions).latestExecutionPayloadHeader.blockHash;
|
|
487
616
|
const timestamp = computeTimeAtSlot(chain.config, state.slot, state.genesisTime);
|
|
488
617
|
const prevRandao = getRandaoMix(state, state.epochCtx.epoch);
|
|
489
618
|
|
|
@@ -568,25 +697,46 @@ export function getPayloadAttributesForSSE(
|
|
|
568
697
|
fork: ForkPostBellatrix,
|
|
569
698
|
chain: {
|
|
570
699
|
config: ChainForkConfig;
|
|
700
|
+
forkChoice: IForkChoice;
|
|
571
701
|
},
|
|
572
702
|
{
|
|
573
703
|
prepareState,
|
|
574
704
|
prepareSlot,
|
|
575
705
|
parentBlockRoot,
|
|
576
706
|
feeRecipient,
|
|
577
|
-
}: {
|
|
707
|
+
}: {
|
|
708
|
+
prepareState: CachedBeaconStateExecutions | CachedBeaconStateGloas;
|
|
709
|
+
prepareSlot: Slot;
|
|
710
|
+
parentBlockRoot: Root;
|
|
711
|
+
feeRecipient: string;
|
|
712
|
+
}
|
|
578
713
|
): SSEPayloadAttributes {
|
|
579
|
-
const parentHash =
|
|
714
|
+
const parentHash = isForkPostGloas(fork)
|
|
715
|
+
? (prepareState as CachedBeaconStateGloas).latestBlockHash
|
|
716
|
+
: (prepareState as CachedBeaconStateExecutions).latestExecutionPayloadHeader.blockHash;
|
|
580
717
|
const payloadAttributes = preparePayloadAttributes(fork, chain, {
|
|
581
718
|
prepareState,
|
|
582
719
|
prepareSlot,
|
|
583
720
|
parentBlockRoot,
|
|
584
721
|
feeRecipient,
|
|
585
722
|
});
|
|
723
|
+
|
|
724
|
+
let parentBlockNumber: number;
|
|
725
|
+
if (isForkPostGloas(fork)) {
|
|
726
|
+
// TODO GLOAS: revisit this after fork choice changes are merged
|
|
727
|
+
const parentBlock = chain.forkChoice.getBlock(parentBlockRoot);
|
|
728
|
+
if (parentBlock?.executionPayloadBlockHash == null) {
|
|
729
|
+
throw Error(`Parent block not found in fork choice root=${toRootHex(parentBlockRoot)}`);
|
|
730
|
+
}
|
|
731
|
+
parentBlockNumber = parentBlock.executionPayloadNumber;
|
|
732
|
+
} else {
|
|
733
|
+
parentBlockNumber = (prepareState as CachedBeaconStateExecutions).latestExecutionPayloadHeader.blockNumber;
|
|
734
|
+
}
|
|
735
|
+
|
|
586
736
|
const ssePayloadAttributes: SSEPayloadAttributes = {
|
|
587
737
|
proposerIndex: prepareState.epochCtx.getBeaconProposer(prepareSlot),
|
|
588
738
|
proposalSlot: prepareSlot,
|
|
589
|
-
parentBlockNumber
|
|
739
|
+
parentBlockNumber,
|
|
590
740
|
parentBlockRoot,
|
|
591
741
|
parentBlockHash: parentHash,
|
|
592
742
|
payloadAttributes,
|
|
@@ -605,7 +755,7 @@ function preparePayloadAttributes(
|
|
|
605
755
|
parentBlockRoot,
|
|
606
756
|
feeRecipient,
|
|
607
757
|
}: {
|
|
608
|
-
prepareState: CachedBeaconStateExecutions;
|
|
758
|
+
prepareState: CachedBeaconStateExecutions | CachedBeaconStateGloas;
|
|
609
759
|
prepareSlot: Slot;
|
|
610
760
|
parentBlockRoot: Root;
|
|
611
761
|
feeRecipient: string;
|
|
@@ -143,7 +143,10 @@ export async function validateGossipAttestationsSameAttData(
|
|
|
143
143
|
if (batchableBls) {
|
|
144
144
|
// all signature sets should have same signing root since we filtered in network processor
|
|
145
145
|
signatureValids = await chain.bls.verifySignatureSetsSameMessage(
|
|
146
|
-
signatureSets.map((set) =>
|
|
146
|
+
signatureSets.map((set) => {
|
|
147
|
+
const publicKey = chain.pubkeyCache.getOrThrow(set.index);
|
|
148
|
+
return {publicKey, signature: set.signature};
|
|
149
|
+
}),
|
|
147
150
|
signatureSets[0].signingRoot
|
|
148
151
|
);
|
|
149
152
|
} else {
|