@lodestar/beacon-node 1.39.0-dev.882891d89c → 1.39.0-dev.b37f2bd1bd
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/utils.js +1 -1
- package/lib/api/impl/beacon/blocks/utils.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +1 -1
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts +1 -2
- package/lib/chain/blocks/verifyBlocksSignatures.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSignatures.js +2 -2
- package/lib/chain/blocks/verifyBlocksSignatures.js.map +1 -1
- package/lib/chain/chain.d.ts +4 -1
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +16 -8
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/genesis/genesis.d.ts +51 -0
- package/lib/chain/genesis/genesis.d.ts.map +1 -0
- package/lib/chain/genesis/genesis.js +123 -0
- package/lib/chain/genesis/genesis.js.map +1 -0
- package/lib/chain/genesis/interface.d.ts +13 -0
- package/lib/chain/genesis/interface.d.ts.map +1 -0
- package/lib/chain/genesis/interface.js +2 -0
- package/lib/chain/genesis/interface.js.map +1 -0
- package/lib/chain/initState.d.ts +14 -1
- package/lib/chain/initState.d.ts.map +1 -1
- package/lib/chain/initState.js +62 -1
- package/lib/chain/initState.js.map +1 -1
- package/lib/chain/interface.d.ts +2 -0
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts +4 -4
- package/lib/chain/opPools/aggregatedAttestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +4 -4
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/opPool.d.ts +0 -3
- package/lib/chain/opPools/opPool.d.ts.map +1 -1
- package/lib/chain/opPools/opPool.js +8 -9
- package/lib/chain/opPools/opPool.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts +4 -0
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +21 -1
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +1 -0
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +11 -8
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/rewards/attestationsRewards.d.ts +1 -2
- package/lib/chain/rewards/attestationsRewards.d.ts.map +1 -1
- package/lib/chain/rewards/attestationsRewards.js +8 -8
- package/lib/chain/rewards/attestationsRewards.js.map +1 -1
- package/lib/chain/rewards/blockRewards.d.ts +1 -2
- package/lib/chain/rewards/blockRewards.d.ts.map +1 -1
- package/lib/chain/rewards/blockRewards.js +5 -5
- package/lib/chain/rewards/blockRewards.js.map +1 -1
- package/lib/chain/rewards/syncCommitteeRewards.d.ts +1 -2
- package/lib/chain/rewards/syncCommitteeRewards.d.ts.map +1 -1
- package/lib/chain/rewards/syncCommitteeRewards.js +2 -2
- package/lib/chain/rewards/syncCommitteeRewards.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -4
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +2 -4
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.js +1 -1
- package/lib/chain/validation/attesterSlashing.js.map +1 -1
- package/lib/chain/validation/block.js +1 -1
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/blsToExecutionChange.js +1 -1
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.js +1 -1
- package/lib/chain/validation/signatureSets/aggregateAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts +1 -2
- package/lib/chain/validation/signatureSets/contributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/contributionAndProof.js +2 -2
- package/lib/chain/validation/signatureSets/contributionAndProof.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts +1 -2
- package/lib/chain/validation/signatureSets/syncCommittee.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommittee.js +2 -2
- package/lib/chain/validation/signatureSets/syncCommittee.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts +1 -2
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js +2 -2
- package/lib/chain/validation/signatureSets/syncCommitteeContribution.js.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts +1 -2
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.d.ts.map +1 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js +2 -1
- package/lib/chain/validation/signatureSets/syncCommitteeSelectionProof.js.map +1 -1
- package/lib/chain/validation/syncCommittee.js +1 -1
- package/lib/chain/validation/syncCommittee.js.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.d.ts.map +1 -1
- package/lib/chain/validation/syncCommitteeContributionAndProof.js +3 -3
- package/lib/chain/validation/syncCommitteeContributionAndProof.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +1 -1
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/db/beacon.d.ts +7 -3
- package/lib/db/beacon.d.ts.map +1 -1
- package/lib/db/beacon.js +12 -33
- package/lib/db/beacon.js.map +1 -1
- package/lib/db/buckets.d.ts +6 -12
- package/lib/db/buckets.d.ts.map +1 -1
- package/lib/db/buckets.js +1 -6
- package/lib/db/buckets.js.map +1 -1
- package/lib/db/interface.d.ts +7 -2
- package/lib/db/interface.d.ts.map +1 -1
- package/lib/db/repositories/depositDataRoot.d.ts +22 -0
- package/lib/db/repositories/depositDataRoot.d.ts.map +1 -0
- package/lib/db/repositories/depositDataRoot.js +62 -0
- package/lib/db/repositories/depositDataRoot.js.map +1 -0
- package/lib/db/repositories/depositEvent.d.ts +13 -0
- package/lib/db/repositories/depositEvent.d.ts.map +1 -0
- package/lib/db/repositories/depositEvent.js +27 -0
- package/lib/db/repositories/depositEvent.js.map +1 -0
- package/lib/db/repositories/eth1Data.d.ts +13 -0
- package/lib/db/repositories/eth1Data.d.ts.map +1 -0
- package/lib/db/repositories/eth1Data.js +26 -0
- package/lib/db/repositories/eth1Data.js.map +1 -0
- package/lib/db/repositories/index.d.ts +3 -0
- package/lib/db/repositories/index.d.ts.map +1 -1
- package/lib/db/repositories/index.js +3 -0
- package/lib/db/repositories/index.js.map +1 -1
- package/lib/db/single/index.d.ts +3 -0
- package/lib/db/single/index.d.ts.map +1 -0
- package/lib/db/single/index.js +3 -0
- package/lib/db/single/index.js.map +1 -0
- package/lib/db/single/preGenesisState.d.ts +16 -0
- package/lib/db/single/preGenesisState.d.ts.map +1 -0
- package/lib/db/single/preGenesisState.js +29 -0
- package/lib/db/single/preGenesisState.js.map +1 -0
- package/lib/db/single/preGenesisStateLastProcessedBlock.d.ts +14 -0
- package/lib/db/single/preGenesisStateLastProcessedBlock.d.ts.map +1 -0
- package/lib/db/single/preGenesisStateLastProcessedBlock.js +27 -0
- package/lib/db/single/preGenesisStateLastProcessedBlock.js.map +1 -0
- package/lib/eth1/errors.d.ts +66 -0
- package/lib/eth1/errors.d.ts.map +1 -0
- package/lib/eth1/errors.js +27 -0
- package/lib/eth1/errors.js.map +1 -0
- package/lib/eth1/eth1DataCache.d.ts +19 -0
- package/lib/eth1/eth1DataCache.d.ts.map +1 -0
- package/lib/eth1/eth1DataCache.js +19 -0
- package/lib/eth1/eth1DataCache.js.map +1 -0
- package/lib/eth1/eth1DepositDataTracker.d.ts +80 -0
- package/lib/eth1/eth1DepositDataTracker.d.ts.map +1 -0
- package/lib/eth1/eth1DepositDataTracker.js +317 -0
- package/lib/eth1/eth1DepositDataTracker.js.map +1 -0
- package/lib/eth1/eth1DepositsCache.d.ts +42 -0
- package/lib/eth1/eth1DepositsCache.d.ts.map +1 -0
- package/lib/eth1/eth1DepositsCache.js +119 -0
- package/lib/eth1/eth1DepositsCache.js.map +1 -0
- package/lib/eth1/index.d.ts +31 -0
- package/lib/eth1/index.d.ts.map +1 -0
- package/lib/eth1/index.js +71 -0
- package/lib/eth1/index.js.map +1 -0
- package/lib/eth1/interface.d.ts +74 -0
- package/lib/eth1/interface.d.ts.map +1 -0
- package/lib/eth1/interface.js +8 -0
- package/lib/eth1/interface.js.map +1 -0
- package/lib/eth1/options.d.ts +22 -0
- package/lib/eth1/options.d.ts.map +1 -0
- package/lib/eth1/options.js +8 -0
- package/lib/eth1/options.js.map +1 -0
- package/lib/eth1/provider/eth1Provider.d.ts +39 -0
- package/lib/eth1/provider/eth1Provider.d.ts.map +1 -0
- package/lib/eth1/provider/eth1Provider.js +147 -0
- package/lib/eth1/provider/eth1Provider.js.map +1 -0
- package/lib/{execution/engine → eth1/provider}/jsonRpcHttpClient.d.ts +1 -1
- package/lib/eth1/provider/jsonRpcHttpClient.d.ts.map +1 -0
- package/lib/eth1/provider/jsonRpcHttpClient.js.map +1 -0
- package/lib/eth1/provider/jwt.d.ts.map +1 -0
- package/lib/eth1/provider/jwt.js.map +1 -0
- package/lib/eth1/provider/utils.d.ts +65 -0
- package/lib/eth1/provider/utils.d.ts.map +1 -0
- package/lib/eth1/provider/utils.js +120 -0
- package/lib/eth1/provider/utils.js.map +1 -0
- package/lib/eth1/stream.d.ts +15 -0
- package/lib/eth1/stream.d.ts.map +1 -0
- package/lib/eth1/stream.js +54 -0
- package/lib/eth1/stream.js.map +1 -0
- package/lib/eth1/utils/depositContract.d.ts +14 -0
- package/lib/eth1/utils/depositContract.d.ts.map +1 -0
- package/lib/eth1/utils/depositContract.js +33 -0
- package/lib/eth1/utils/depositContract.js.map +1 -0
- package/lib/eth1/utils/deposits.d.ts +8 -0
- package/lib/eth1/utils/deposits.d.ts.map +1 -0
- package/lib/eth1/utils/deposits.js +47 -0
- package/lib/eth1/utils/deposits.js.map +1 -0
- package/lib/eth1/utils/eth1Data.d.ts +22 -0
- package/lib/eth1/utils/eth1Data.d.ts.map +1 -0
- package/lib/eth1/utils/eth1Data.js +77 -0
- package/lib/eth1/utils/eth1Data.js.map +1 -0
- package/lib/eth1/utils/eth1DepositEvent.d.ts +7 -0
- package/lib/eth1/utils/eth1DepositEvent.d.ts.map +1 -0
- package/lib/eth1/utils/eth1DepositEvent.js +13 -0
- package/lib/eth1/utils/eth1DepositEvent.js.map +1 -0
- package/lib/eth1/utils/eth1Vote.d.ts +17 -0
- package/lib/eth1/utils/eth1Vote.d.ts.map +1 -0
- package/lib/eth1/utils/eth1Vote.js +111 -0
- package/lib/eth1/utils/eth1Vote.js.map +1 -0
- package/lib/eth1/utils/groupDepositEventsByBlock.d.ts +9 -0
- package/lib/eth1/utils/groupDepositEventsByBlock.d.ts.map +1 -0
- package/lib/eth1/utils/groupDepositEventsByBlock.js +17 -0
- package/lib/eth1/utils/groupDepositEventsByBlock.js.map +1 -0
- package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.d.ts +10 -0
- package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.d.ts.map +1 -0
- package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.js +14 -0
- package/lib/eth1/utils/optimizeNextBlockDiffForGenesis.js.map +1 -0
- package/lib/execution/engine/http.d.ts +1 -1
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +3 -2
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/index.d.ts.map +1 -1
- package/lib/execution/engine/index.js +1 -1
- package/lib/execution/engine/index.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +1 -1
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/interface.js.map +1 -1
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +1 -1
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/payloadIdCache.d.ts +1 -1
- package/lib/execution/engine/payloadIdCache.d.ts.map +1 -1
- package/lib/execution/engine/types.d.ts +1 -1
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +1 -1
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/execution/engine/utils.d.ts +2 -64
- package/lib/execution/engine/utils.d.ts.map +1 -1
- package/lib/execution/engine/utils.js +2 -91
- package/lib/execution/engine/utils.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +35 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +90 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +9 -10
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/options.d.ts +2 -0
- package/lib/node/options.d.ts.map +1 -1
- package/lib/node/options.js +2 -0
- package/lib/node/options.js.map +1 -1
- package/lib/node/utils/interop/deposits.d.ts +1 -2
- package/lib/node/utils/interop/deposits.d.ts.map +1 -1
- package/lib/node/utils/interop/deposits.js.map +1 -1
- package/lib/node/utils/interop/state.d.ts +1 -1
- package/lib/node/utils/interop/state.d.ts.map +1 -1
- package/lib/node/utils/state.d.ts +7 -1
- package/lib/node/utils/state.d.ts.map +1 -1
- package/lib/node/utils/state.js +14 -1
- package/lib/node/utils/state.js.map +1 -1
- package/lib/sync/backfill/backfill.d.ts.map +1 -1
- package/lib/sync/backfill/backfill.js +4 -2
- package/lib/sync/backfill/backfill.js.map +1 -1
- package/lib/sync/backfill/verify.d.ts +1 -1
- package/lib/sync/backfill/verify.d.ts.map +1 -1
- package/lib/sync/backfill/verify.js +2 -2
- package/lib/sync/backfill/verify.js.map +1 -1
- package/package.json +20 -14
- package/src/api/impl/beacon/blocks/utils.ts +1 -1
- package/src/chain/blocks/verifyBlock.ts +0 -1
- package/src/chain/blocks/verifyBlocksSignatures.ts +1 -3
- package/src/chain/chain.ts +19 -7
- package/src/chain/genesis/genesis.ts +190 -0
- package/src/chain/genesis/interface.ts +14 -0
- package/src/chain/initState.ts +97 -1
- package/src/chain/interface.ts +2 -0
- package/src/chain/opPools/aggregatedAttestationPool.ts +7 -7
- package/src/chain/opPools/opPool.ts +8 -8
- package/src/chain/prepareNextSlot.ts +28 -1
- package/src/chain/produceBlock/produceBlockBody.ts +12 -8
- package/src/chain/rewards/attestationsRewards.ts +4 -13
- package/src/chain/rewards/blockRewards.ts +3 -6
- package/src/chain/rewards/syncCommitteeRewards.ts +1 -3
- package/src/chain/stateCache/persistentCheckpointsCache.ts +2 -15
- package/src/chain/validation/attesterSlashing.ts +1 -1
- package/src/chain/validation/block.ts +1 -1
- package/src/chain/validation/blsToExecutionChange.ts +1 -1
- package/src/chain/validation/proposerSlashing.ts +1 -1
- package/src/chain/validation/signatureSets/aggregateAndProof.ts +1 -1
- package/src/chain/validation/signatureSets/contributionAndProof.ts +1 -3
- package/src/chain/validation/signatureSets/syncCommittee.ts +1 -3
- package/src/chain/validation/signatureSets/syncCommitteeContribution.ts +1 -3
- package/src/chain/validation/signatureSets/syncCommitteeSelectionProof.ts +1 -2
- package/src/chain/validation/syncCommittee.ts +1 -1
- package/src/chain/validation/syncCommitteeContributionAndProof.ts +3 -8
- package/src/chain/validation/voluntaryExit.ts +1 -1
- package/src/db/beacon.ts +16 -38
- package/src/db/buckets.ts +7 -12
- package/src/db/interface.ts +13 -2
- package/src/db/repositories/depositDataRoot.ts +80 -0
- package/src/db/repositories/depositEvent.ts +32 -0
- package/src/db/repositories/eth1Data.ts +33 -0
- package/src/db/repositories/index.ts +3 -0
- package/src/db/single/index.ts +2 -0
- package/src/db/single/preGenesisState.ts +37 -0
- package/src/db/single/preGenesisStateLastProcessedBlock.ts +34 -0
- package/src/eth1/errors.ts +40 -0
- package/src/eth1/eth1DataCache.ts +26 -0
- package/src/eth1/eth1DepositDataTracker.ts +410 -0
- package/src/eth1/eth1DepositsCache.ts +141 -0
- package/src/eth1/index.ts +94 -0
- package/src/eth1/interface.ts +87 -0
- package/src/eth1/options.ts +28 -0
- package/src/eth1/provider/eth1Provider.ts +229 -0
- package/src/{execution/engine → eth1/provider}/jsonRpcHttpClient.ts +1 -1
- package/src/eth1/provider/utils.ts +136 -0
- package/src/eth1/stream.ts +75 -0
- package/src/eth1/utils/depositContract.ts +37 -0
- package/src/eth1/utils/deposits.ts +70 -0
- package/src/eth1/utils/eth1Data.ts +100 -0
- package/src/eth1/utils/eth1DepositEvent.ts +12 -0
- package/src/eth1/utils/eth1Vote.ts +142 -0
- package/src/eth1/utils/groupDepositEventsByBlock.ts +19 -0
- package/src/eth1/utils/optimizeNextBlockDiffForGenesis.ts +18 -0
- package/src/execution/engine/http.ts +9 -8
- package/src/execution/engine/index.ts +1 -1
- package/src/execution/engine/interface.ts +1 -1
- package/src/execution/engine/mock.ts +2 -1
- package/src/execution/engine/payloadIdCache.ts +1 -1
- package/src/execution/engine/types.ts +9 -9
- package/src/execution/engine/utils.ts +5 -111
- package/src/index.ts +2 -1
- package/src/metrics/metrics/lodestar.ts +92 -0
- package/src/node/nodejs.ts +9 -11
- package/src/node/options.ts +3 -0
- package/src/node/utils/interop/deposits.ts +1 -3
- package/src/node/utils/interop/state.ts +1 -1
- package/src/node/utils/state.ts +18 -3
- package/src/sync/backfill/backfill.ts +3 -8
- package/src/sync/backfill/verify.ts +1 -3
- package/lib/execution/engine/jsonRpcHttpClient.d.ts.map +0 -1
- package/lib/execution/engine/jsonRpcHttpClient.js.map +0 -1
- package/lib/execution/engine/jwt.d.ts.map +0 -1
- package/lib/execution/engine/jwt.js.map +0 -1
- /package/lib/{execution/engine → eth1/provider}/jsonRpcHttpClient.js +0 -0
- /package/lib/{execution/engine → eth1/provider}/jwt.d.ts +0 -0
- /package/lib/{execution/engine → eth1/provider}/jwt.js +0 -0
- /package/src/{execution/engine → eth1/provider}/jwt.ts +0 -0
package/src/chain/chain.ts
CHANGED
|
@@ -43,6 +43,7 @@ import {Logger, fromHex, gweiToWei, isErrorAborted, pruneSetToMax, sleep, toRoot
|
|
|
43
43
|
import {ProcessShutdownCallback} from "@lodestar/validator";
|
|
44
44
|
import {GENESIS_EPOCH, ZERO_HASH} from "../constants/index.js";
|
|
45
45
|
import {IBeaconDb} from "../db/index.js";
|
|
46
|
+
import {IEth1ForBlockProduction} from "../eth1/index.js";
|
|
46
47
|
import {BuilderStatus} from "../execution/builder/http.js";
|
|
47
48
|
import {IExecutionBuilder, IExecutionEngine} from "../execution/index.js";
|
|
48
49
|
import {Metrics} from "../metrics/index.js";
|
|
@@ -116,6 +117,7 @@ const DEFAULT_MAX_CACHED_PRODUCED_RESULTS = 4;
|
|
|
116
117
|
export class BeaconChain implements IBeaconChain {
|
|
117
118
|
readonly genesisTime: UintNum64;
|
|
118
119
|
readonly genesisValidatorsRoot: Root;
|
|
120
|
+
readonly eth1: IEth1ForBlockProduction;
|
|
119
121
|
readonly executionEngine: IExecutionEngine;
|
|
120
122
|
readonly executionBuilder?: IExecutionBuilder;
|
|
121
123
|
// Expose config for convenience in modularized functions
|
|
@@ -142,7 +144,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
142
144
|
readonly aggregatedAttestationPool: AggregatedAttestationPool;
|
|
143
145
|
readonly syncCommitteeMessagePool: SyncCommitteeMessagePool;
|
|
144
146
|
readonly syncContributionAndProofPool;
|
|
145
|
-
readonly opPool
|
|
147
|
+
readonly opPool = new OpPool();
|
|
146
148
|
|
|
147
149
|
// Gossip seen cache
|
|
148
150
|
readonly seenAttesters = new SeenAttesters();
|
|
@@ -214,6 +216,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
214
216
|
validatorMonitor,
|
|
215
217
|
anchorState,
|
|
216
218
|
isAnchorStateFinalized,
|
|
219
|
+
eth1,
|
|
217
220
|
executionEngine,
|
|
218
221
|
executionBuilder,
|
|
219
222
|
}: {
|
|
@@ -230,6 +233,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
230
233
|
validatorMonitor: ValidatorMonitor | null;
|
|
231
234
|
anchorState: BeaconStateAllForks;
|
|
232
235
|
isAnchorStateFinalized: boolean;
|
|
236
|
+
eth1: IEth1ForBlockProduction;
|
|
233
237
|
executionEngine: IExecutionEngine;
|
|
234
238
|
executionBuilder?: IExecutionBuilder;
|
|
235
239
|
}
|
|
@@ -244,6 +248,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
244
248
|
this.genesisTime = anchorState.genesisTime;
|
|
245
249
|
this.anchorStateLatestBlockSlot = anchorState.latestBlockHeader.slot;
|
|
246
250
|
this.genesisValidatorsRoot = anchorState.genesisValidatorsRoot;
|
|
251
|
+
this.eth1 = eth1;
|
|
247
252
|
this.executionEngine = executionEngine;
|
|
248
253
|
this.executionBuilder = executionBuilder;
|
|
249
254
|
const signal = this.abortController.signal;
|
|
@@ -260,7 +265,6 @@ export class BeaconChain implements IBeaconChain {
|
|
|
260
265
|
this.aggregatedAttestationPool = new AggregatedAttestationPool(this.config, metrics);
|
|
261
266
|
this.syncCommitteeMessagePool = new SyncCommitteeMessagePool(config, clock, this.opts?.preaggregateSlotDistance);
|
|
262
267
|
this.syncContributionAndProofPool = new SyncContributionAndProofPool(config, clock, metrics, logger);
|
|
263
|
-
this.opPool = new OpPool(config);
|
|
264
268
|
|
|
265
269
|
this.seenAggregatedAttestations = new SeenAggregatedAttestations(metrics);
|
|
266
270
|
this.seenContributionAndProof = new SeenContributionAndProof(metrics);
|
|
@@ -290,7 +294,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
290
294
|
// Restore state caches
|
|
291
295
|
// anchorState may already by a CachedBeaconState. If so, don't create the cache again, since deserializing all
|
|
292
296
|
// pubkeys takes ~30 seconds for 350k keys (mainnet 2022Q2).
|
|
293
|
-
// When the BeaconStateCache is created in
|
|
297
|
+
// When the BeaconStateCache is created in eth1 genesis builder it may be incorrect. Until we can ensure that
|
|
294
298
|
// it's safe to re-use _ANY_ BeaconStateCache, this option is disabled by default and only used in tests.
|
|
295
299
|
const cachedState =
|
|
296
300
|
isCachedBeaconState(anchorState) && opts.skipCreateStateCacheIfAvailable
|
|
@@ -335,7 +339,6 @@ export class BeaconChain implements IBeaconChain {
|
|
|
335
339
|
this.cpStateDatastore = fileDataStore ? new FileCPStateDatastore(dataDir) : new DbCPStateDatastore(this.db);
|
|
336
340
|
checkpointStateCache = new PersistentCheckpointStateCache(
|
|
337
341
|
{
|
|
338
|
-
config,
|
|
339
342
|
metrics,
|
|
340
343
|
logger,
|
|
341
344
|
clock,
|
|
@@ -414,6 +417,15 @@ export class BeaconChain implements IBeaconChain {
|
|
|
414
417
|
signal
|
|
415
418
|
);
|
|
416
419
|
|
|
420
|
+
// Stop polling eth1 data if anchor state is in Electra AND deposit_requests_start_index is reached
|
|
421
|
+
const anchorStateFork = this.config.getForkName(anchorState.slot);
|
|
422
|
+
if (isForkPostElectra(anchorStateFork)) {
|
|
423
|
+
const {eth1DepositIndex, depositRequestsStartIndex} = anchorState as BeaconStateElectra;
|
|
424
|
+
if (eth1DepositIndex === Number(depositRequestsStartIndex)) {
|
|
425
|
+
this.eth1.stopPollingEth1Data();
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
417
429
|
// always run PrepareNextSlotScheduler except for fork_choice spec tests
|
|
418
430
|
if (!opts?.disablePrepareNextSlot) {
|
|
419
431
|
new PrepareNextSlotScheduler(this, this.config, metrics, this.logger, signal);
|
|
@@ -1308,7 +1320,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1308
1320
|
|
|
1309
1321
|
const postState = this.regen.getStateSync(toRootHex(block.stateRoot)) ?? undefined;
|
|
1310
1322
|
|
|
1311
|
-
return computeBlockRewards(
|
|
1323
|
+
return computeBlockRewards(block, preState.clone(), postState?.clone());
|
|
1312
1324
|
}
|
|
1313
1325
|
|
|
1314
1326
|
async getAttestationsRewards(
|
|
@@ -1332,7 +1344,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1332
1344
|
throw Error(`State is not in cache for slot ${slot}`);
|
|
1333
1345
|
}
|
|
1334
1346
|
|
|
1335
|
-
const rewards = await computeAttestationsRewards(this.
|
|
1347
|
+
const rewards = await computeAttestationsRewards(this.pubkey2index, cachedState, validatorIds);
|
|
1336
1348
|
|
|
1337
1349
|
return {rewards, executionOptimistic, finalized};
|
|
1338
1350
|
}
|
|
@@ -1349,6 +1361,6 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1349
1361
|
|
|
1350
1362
|
preState = processSlots(preState, block.slot); // Dial preState's slot to block.slot
|
|
1351
1363
|
|
|
1352
|
-
return computeSyncCommitteeRewards(this.
|
|
1364
|
+
return computeSyncCommitteeRewards(this.index2pubkey, block, preState.clone(), validatorIds);
|
|
1353
1365
|
}
|
|
1354
1366
|
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {Tree, toGindex} from "@chainsafe/persistent-merkle-tree";
|
|
2
|
+
import {BeaconConfig, ChainForkConfig} from "@lodestar/config";
|
|
3
|
+
import {GENESIS_EPOCH, GENESIS_SLOT} from "@lodestar/params";
|
|
4
|
+
import {
|
|
5
|
+
BeaconStateAllForks,
|
|
6
|
+
CachedBeaconStateAllForks,
|
|
7
|
+
applyDeposits,
|
|
8
|
+
applyEth1BlockHash,
|
|
9
|
+
applyTimestamp,
|
|
10
|
+
createCachedBeaconState,
|
|
11
|
+
createEmptyEpochCacheImmutableData,
|
|
12
|
+
getActiveValidatorIndices,
|
|
13
|
+
getGenesisBeaconState,
|
|
14
|
+
getTemporaryBlockHeader,
|
|
15
|
+
} from "@lodestar/state-transition";
|
|
16
|
+
import {phase0, ssz} from "@lodestar/types";
|
|
17
|
+
import {Logger} from "@lodestar/utils";
|
|
18
|
+
import {DepositTree} from "../../db/repositories/depositDataRoot.js";
|
|
19
|
+
import {IEth1Provider} from "../../eth1/index.js";
|
|
20
|
+
import {IEth1StreamParams} from "../../eth1/interface.js";
|
|
21
|
+
import {getDepositsAndBlockStreamForGenesis, getDepositsStream} from "../../eth1/stream.js";
|
|
22
|
+
import {GenesisResult, IGenesisBuilder} from "./interface.js";
|
|
23
|
+
|
|
24
|
+
export type GenesisBuilderKwargs = {
|
|
25
|
+
config: ChainForkConfig;
|
|
26
|
+
eth1Provider: IEth1Provider;
|
|
27
|
+
logger: Logger;
|
|
28
|
+
|
|
29
|
+
/** Use to restore pending progress */
|
|
30
|
+
pendingStatus?: {
|
|
31
|
+
state: BeaconStateAllForks;
|
|
32
|
+
depositTree: DepositTree;
|
|
33
|
+
lastProcessedBlockNumber: number;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
maxBlocksPerPoll?: number;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export class GenesisBuilder implements IGenesisBuilder {
|
|
41
|
+
// Expose state to persist on error
|
|
42
|
+
readonly state: CachedBeaconStateAllForks;
|
|
43
|
+
readonly depositTree: DepositTree;
|
|
44
|
+
/** Is null if no block has been processed yet */
|
|
45
|
+
lastProcessedBlockNumber: number | null = null;
|
|
46
|
+
|
|
47
|
+
private readonly config: BeaconConfig;
|
|
48
|
+
private readonly eth1Provider: IEth1Provider;
|
|
49
|
+
private readonly logger: Logger;
|
|
50
|
+
private readonly signal?: AbortSignal;
|
|
51
|
+
private readonly eth1Params: IEth1StreamParams;
|
|
52
|
+
private readonly depositCache = new Set<number>();
|
|
53
|
+
private readonly fromBlock: number;
|
|
54
|
+
private readonly logEvery = 30 * 1000;
|
|
55
|
+
private lastLog = 0;
|
|
56
|
+
/** Current count of active validators in the state */
|
|
57
|
+
private activatedValidatorCount: number;
|
|
58
|
+
|
|
59
|
+
constructor({config, eth1Provider, logger, signal, pendingStatus, maxBlocksPerPoll}: GenesisBuilderKwargs) {
|
|
60
|
+
// at genesis builder, there is no genesis validator so we don't have a real BeaconConfig
|
|
61
|
+
// but we need BeaconConfig to temporarily create CachedBeaconState, the cast here is safe since we don't use any getDomain here
|
|
62
|
+
// the use of state as CachedBeaconState is just for convenient, GenesisResult returns TreeView anyway
|
|
63
|
+
this.eth1Provider = eth1Provider;
|
|
64
|
+
this.logger = logger;
|
|
65
|
+
this.signal = signal;
|
|
66
|
+
this.eth1Params = {
|
|
67
|
+
...config,
|
|
68
|
+
maxBlocksPerPoll: maxBlocksPerPoll ?? 10000,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
let stateView: BeaconStateAllForks;
|
|
72
|
+
|
|
73
|
+
if (pendingStatus) {
|
|
74
|
+
this.logger.info("Restoring pending genesis state", {block: pendingStatus.lastProcessedBlockNumber});
|
|
75
|
+
stateView = pendingStatus.state;
|
|
76
|
+
this.depositTree = pendingStatus.depositTree;
|
|
77
|
+
this.fromBlock = Math.max(pendingStatus.lastProcessedBlockNumber + 1, this.eth1Provider.deployBlock);
|
|
78
|
+
} else {
|
|
79
|
+
stateView = getGenesisBeaconState(
|
|
80
|
+
config,
|
|
81
|
+
ssz.phase0.Eth1Data.defaultValue(),
|
|
82
|
+
getTemporaryBlockHeader(config, config.getForkTypes(GENESIS_SLOT).BeaconBlock.defaultValue())
|
|
83
|
+
);
|
|
84
|
+
this.depositTree = ssz.phase0.DepositDataRootList.defaultViewDU();
|
|
85
|
+
this.fromBlock = this.eth1Provider.deployBlock;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// TODO - PENDING: Ensure EpochCacheImmutableData is created only once
|
|
89
|
+
this.state = createCachedBeaconState(stateView, createEmptyEpochCacheImmutableData(config, stateView));
|
|
90
|
+
this.config = this.state.config;
|
|
91
|
+
this.activatedValidatorCount = getActiveValidatorIndices(stateView, GENESIS_EPOCH).length;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get eth1 deposit events and blocks and apply to this.state until we found genesis.
|
|
96
|
+
*/
|
|
97
|
+
async waitForGenesis(): Promise<GenesisResult> {
|
|
98
|
+
await this.eth1Provider.validateContract();
|
|
99
|
+
|
|
100
|
+
// Load data from data from this.db.depositData, this.db.depositDataRoot
|
|
101
|
+
// And start from a more recent fromBlock
|
|
102
|
+
const blockNumberValidatorGenesis = await this.waitForGenesisValidators();
|
|
103
|
+
|
|
104
|
+
const depositsAndBlocksStream = getDepositsAndBlockStreamForGenesis(
|
|
105
|
+
blockNumberValidatorGenesis,
|
|
106
|
+
this.eth1Provider,
|
|
107
|
+
this.eth1Params,
|
|
108
|
+
this.signal
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
for await (const [depositEvents, block] of depositsAndBlocksStream) {
|
|
112
|
+
this.applyDeposits(depositEvents);
|
|
113
|
+
applyTimestamp(this.config, this.state, block.timestamp);
|
|
114
|
+
applyEth1BlockHash(this.state, block.blockHash);
|
|
115
|
+
this.lastProcessedBlockNumber = block.blockNumber;
|
|
116
|
+
|
|
117
|
+
if (
|
|
118
|
+
this.state.genesisTime >= this.config.MIN_GENESIS_TIME &&
|
|
119
|
+
this.activatedValidatorCount >= this.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
|
120
|
+
) {
|
|
121
|
+
this.logger.info("Found genesis state", {blockNumber: block.blockNumber});
|
|
122
|
+
return {
|
|
123
|
+
state: this.state,
|
|
124
|
+
depositTree: this.depositTree,
|
|
125
|
+
block,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this.throttledLog(`Waiting for min genesis time ${block.timestamp} / ${this.config.MIN_GENESIS_TIME}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
throw Error("depositsStream stopped without a valid genesis state");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* First phase of waiting for genesis.
|
|
137
|
+
* Stream deposits events in batches as big as possible without querying block data
|
|
138
|
+
* @returns Block number at which there are enough active validators is state for genesis
|
|
139
|
+
*/
|
|
140
|
+
private async waitForGenesisValidators(): Promise<number> {
|
|
141
|
+
const depositsStream = getDepositsStream(this.fromBlock, this.eth1Provider, this.eth1Params, this.signal);
|
|
142
|
+
|
|
143
|
+
for await (const {depositEvents, blockNumber} of depositsStream) {
|
|
144
|
+
this.applyDeposits(depositEvents);
|
|
145
|
+
this.lastProcessedBlockNumber = blockNumber;
|
|
146
|
+
|
|
147
|
+
if (this.activatedValidatorCount >= this.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT) {
|
|
148
|
+
this.logger.info("Found enough genesis validators", {blockNumber});
|
|
149
|
+
return blockNumber;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.throttledLog(
|
|
153
|
+
`Found ${this.state.validators.length} / ${this.config.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT} validators to genesis`
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
throw Error("depositsStream stopped without a valid genesis state");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private applyDeposits(depositEvents: phase0.DepositEvent[]): void {
|
|
161
|
+
const newDeposits = depositEvents
|
|
162
|
+
.filter((depositEvent) => !this.depositCache.has(depositEvent.index))
|
|
163
|
+
.map((depositEvent) => {
|
|
164
|
+
this.depositCache.add(depositEvent.index);
|
|
165
|
+
this.depositTree.push(ssz.phase0.DepositData.hashTreeRoot(depositEvent.depositData));
|
|
166
|
+
const gindex = toGindex(this.depositTree.type.depth, BigInt(depositEvent.index));
|
|
167
|
+
|
|
168
|
+
// Apply changes from the push above
|
|
169
|
+
this.depositTree.commit();
|
|
170
|
+
const depositTreeNode = this.depositTree.node;
|
|
171
|
+
return {
|
|
172
|
+
proof: new Tree(depositTreeNode).getSingleProof(gindex),
|
|
173
|
+
data: depositEvent.depositData,
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const {activatedValidatorCount} = applyDeposits(this.config, this.state, newDeposits, this.depositTree);
|
|
178
|
+
this.activatedValidatorCount += activatedValidatorCount;
|
|
179
|
+
|
|
180
|
+
// TODO: If necessary persist deposits here to this.db.depositData, this.db.depositDataRoot
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Throttle genesis generation status log to prevent spamming */
|
|
184
|
+
private throttledLog(message: string): void {
|
|
185
|
+
if (Date.now() - this.lastLog > this.logEvery) {
|
|
186
|
+
this.lastLog = Date.now();
|
|
187
|
+
this.logger.info(message);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {CompositeViewDU, VectorCompositeType} from "@chainsafe/ssz";
|
|
2
|
+
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
|
|
3
|
+
import {ssz} from "@lodestar/types";
|
|
4
|
+
import {Eth1Block} from "../../eth1/interface.js";
|
|
5
|
+
|
|
6
|
+
export type GenesisResult = {
|
|
7
|
+
state: CachedBeaconStateAllForks;
|
|
8
|
+
depositTree: CompositeViewDU<VectorCompositeType<typeof ssz.Root>>;
|
|
9
|
+
block: Eth1Block;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export interface IGenesisBuilder {
|
|
13
|
+
waitForGenesis: () => Promise<GenesisResult>;
|
|
14
|
+
}
|
package/src/chain/initState.ts
CHANGED
|
@@ -1,11 +1,37 @@
|
|
|
1
1
|
import {ChainForkConfig} from "@lodestar/config";
|
|
2
2
|
import {ZERO_HASH} from "@lodestar/params";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
BeaconStateAllForks,
|
|
5
|
+
CachedBeaconStateAllForks,
|
|
6
|
+
computeEpochAtSlot,
|
|
7
|
+
computeStartSlotAtEpoch,
|
|
8
|
+
} from "@lodestar/state-transition";
|
|
4
9
|
import {SignedBeaconBlock, ssz} from "@lodestar/types";
|
|
5
10
|
import {Logger, toHex, toRootHex} from "@lodestar/utils";
|
|
6
11
|
import {GENESIS_SLOT} from "../constants/index.js";
|
|
7
12
|
import {IBeaconDb} from "../db/index.js";
|
|
13
|
+
import {Eth1Provider} from "../eth1/index.js";
|
|
14
|
+
import {Eth1Options} from "../eth1/options.js";
|
|
8
15
|
import {Metrics} from "../metrics/index.js";
|
|
16
|
+
import {GenesisBuilder} from "./genesis/genesis.js";
|
|
17
|
+
import {GenesisResult} from "./genesis/interface.js";
|
|
18
|
+
|
|
19
|
+
export async function persistGenesisResult(
|
|
20
|
+
db: IBeaconDb,
|
|
21
|
+
genesisResult: GenesisResult,
|
|
22
|
+
genesisBlock: SignedBeaconBlock
|
|
23
|
+
): Promise<void> {
|
|
24
|
+
await Promise.all([
|
|
25
|
+
db.stateArchive.add(genesisResult.state),
|
|
26
|
+
db.blockArchive.add(genesisBlock),
|
|
27
|
+
db.depositDataRoot.putList(genesisResult.depositTree.getAllReadonlyValues()),
|
|
28
|
+
db.eth1Data.put(genesisResult.block.timestamp, {
|
|
29
|
+
...genesisResult.block,
|
|
30
|
+
depositCount: genesisResult.depositTree.length,
|
|
31
|
+
depositRoot: genesisResult.depositTree.hashTreeRoot(),
|
|
32
|
+
}),
|
|
33
|
+
]);
|
|
34
|
+
}
|
|
9
35
|
|
|
10
36
|
export async function persistAnchorState(
|
|
11
37
|
config: ChainForkConfig,
|
|
@@ -49,6 +75,76 @@ export function createGenesisBlock(config: ChainForkConfig, genesisState: Beacon
|
|
|
49
75
|
return genesisBlock;
|
|
50
76
|
}
|
|
51
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Initialize and persist a genesis state and related data
|
|
80
|
+
*/
|
|
81
|
+
export async function initStateFromEth1({
|
|
82
|
+
config,
|
|
83
|
+
db,
|
|
84
|
+
logger,
|
|
85
|
+
opts,
|
|
86
|
+
signal,
|
|
87
|
+
}: {
|
|
88
|
+
config: ChainForkConfig;
|
|
89
|
+
db: IBeaconDb;
|
|
90
|
+
logger: Logger;
|
|
91
|
+
opts: Eth1Options;
|
|
92
|
+
signal: AbortSignal;
|
|
93
|
+
}): Promise<CachedBeaconStateAllForks> {
|
|
94
|
+
logger.info("Listening to eth1 for genesis state");
|
|
95
|
+
|
|
96
|
+
const statePreGenesis = await db.preGenesisState.get();
|
|
97
|
+
const depositTree = await db.depositDataRoot.getDepositRootTree();
|
|
98
|
+
const lastProcessedBlockNumber = await db.preGenesisStateLastProcessedBlock.get();
|
|
99
|
+
|
|
100
|
+
const builder = new GenesisBuilder({
|
|
101
|
+
config,
|
|
102
|
+
eth1Provider: new Eth1Provider(config, {...opts, logger}, signal),
|
|
103
|
+
logger,
|
|
104
|
+
signal,
|
|
105
|
+
pendingStatus:
|
|
106
|
+
statePreGenesis && depositTree !== undefined && lastProcessedBlockNumber != null
|
|
107
|
+
? {state: statePreGenesis, depositTree, lastProcessedBlockNumber}
|
|
108
|
+
: undefined,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const genesisResult = await builder.waitForGenesis();
|
|
113
|
+
|
|
114
|
+
// Note: .hashTreeRoot() automatically commits()
|
|
115
|
+
const genesisBlock = createGenesisBlock(config, genesisResult.state);
|
|
116
|
+
const types = config.getForkTypes(GENESIS_SLOT);
|
|
117
|
+
const stateRoot = genesisResult.state.hashTreeRoot();
|
|
118
|
+
const blockRoot = types.BeaconBlock.hashTreeRoot(genesisBlock.message);
|
|
119
|
+
|
|
120
|
+
logger.info("Initializing genesis state", {
|
|
121
|
+
stateRoot: toRootHex(stateRoot),
|
|
122
|
+
blockRoot: toRootHex(blockRoot),
|
|
123
|
+
validatorCount: genesisResult.state.validators.length,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
await persistGenesisResult(db, genesisResult, genesisBlock);
|
|
127
|
+
|
|
128
|
+
logger.verbose("Clearing pending genesis state if any");
|
|
129
|
+
await db.preGenesisState.delete();
|
|
130
|
+
await db.preGenesisStateLastProcessedBlock.delete();
|
|
131
|
+
|
|
132
|
+
return genesisResult.state;
|
|
133
|
+
} catch (e) {
|
|
134
|
+
if (builder.lastProcessedBlockNumber != null) {
|
|
135
|
+
logger.info("Persisting genesis state", {block: builder.lastProcessedBlockNumber});
|
|
136
|
+
|
|
137
|
+
// Commit changed before serializing
|
|
138
|
+
builder.state.commit();
|
|
139
|
+
|
|
140
|
+
await db.preGenesisState.put(builder.state);
|
|
141
|
+
await db.depositDataRoot.putList(builder.depositTree.getAllReadonlyValues());
|
|
142
|
+
await db.preGenesisStateLastProcessedBlock.put(builder.lastProcessedBlockNumber);
|
|
143
|
+
}
|
|
144
|
+
throw e;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
52
148
|
/**
|
|
53
149
|
* Restore the latest beacon state from db
|
|
54
150
|
*/
|
package/src/chain/interface.ts
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
phase0,
|
|
26
26
|
} from "@lodestar/types";
|
|
27
27
|
import {Logger} from "@lodestar/utils";
|
|
28
|
+
import {IEth1ForBlockProduction} from "../eth1/index.js";
|
|
28
29
|
import {IExecutionBuilder, IExecutionEngine} from "../execution/index.js";
|
|
29
30
|
import {Metrics} from "../metrics/metrics.js";
|
|
30
31
|
import {BufferPool} from "../util/bufferPool.js";
|
|
@@ -87,6 +88,7 @@ export interface IBeaconChain {
|
|
|
87
88
|
readonly genesisTime: UintNum64;
|
|
88
89
|
readonly genesisValidatorsRoot: Root;
|
|
89
90
|
readonly earliestAvailableSlot: Slot;
|
|
91
|
+
readonly eth1: IEth1ForBlockProduction;
|
|
90
92
|
readonly executionEngine: IExecutionEngine;
|
|
91
93
|
readonly executionBuilder?: IExecutionBuilder;
|
|
92
94
|
// Expose config for convenience in modularized functions
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Signature, aggregateSignatures} from "@chainsafe/blst";
|
|
2
2
|
import {BitArray} from "@chainsafe/ssz";
|
|
3
|
-
import {
|
|
3
|
+
import {ChainForkConfig} from "@lodestar/config";
|
|
4
4
|
import {IForkChoice} from "@lodestar/fork-choice";
|
|
5
5
|
import {
|
|
6
6
|
ForkName,
|
|
@@ -162,7 +162,7 @@ export class AggregatedAttestationPool {
|
|
|
162
162
|
private lowestPermissibleSlot = 0;
|
|
163
163
|
|
|
164
164
|
constructor(
|
|
165
|
-
private readonly config:
|
|
165
|
+
private readonly config: ChainForkConfig,
|
|
166
166
|
private readonly metrics: Metrics | null = null
|
|
167
167
|
) {
|
|
168
168
|
metrics?.opPool.aggregatedAttestationPool.attDataPerSlot.addCollect(() => this.onScrapeMetrics(metrics));
|
|
@@ -249,7 +249,7 @@ export class AggregatedAttestationPool {
|
|
|
249
249
|
const stateEpoch = state.epochCtx.epoch;
|
|
250
250
|
const statePrevEpoch = stateEpoch - 1;
|
|
251
251
|
|
|
252
|
-
const notSeenValidatorsFn = getNotSeenValidatorsFn(
|
|
252
|
+
const notSeenValidatorsFn = getNotSeenValidatorsFn(state);
|
|
253
253
|
const validateAttestationDataFn = getValidateAttestationDataFn(forkChoice, state);
|
|
254
254
|
|
|
255
255
|
const attestationsByScore: AttestationWithScore[] = [];
|
|
@@ -362,7 +362,7 @@ export class AggregatedAttestationPool {
|
|
|
362
362
|
const statePrevEpoch = stateEpoch - 1;
|
|
363
363
|
const rootCache = new RootCache(state);
|
|
364
364
|
|
|
365
|
-
const notSeenValidatorsFn = getNotSeenValidatorsFn(
|
|
365
|
+
const notSeenValidatorsFn = getNotSeenValidatorsFn(state);
|
|
366
366
|
const validateAttestationDataFn = getValidateAttestationDataFn(forkChoice, state);
|
|
367
367
|
|
|
368
368
|
const slots = Array.from(this.attestationGroupByIndexByDataHexBySlot.keys()).sort((a, b) => b - a);
|
|
@@ -656,7 +656,7 @@ export class MatchingDataAttestationGroup {
|
|
|
656
656
|
private readonly attestations: AttestationWithIndex[] = [];
|
|
657
657
|
|
|
658
658
|
constructor(
|
|
659
|
-
private readonly config:
|
|
659
|
+
private readonly config: ChainForkConfig,
|
|
660
660
|
readonly committee: Uint32Array,
|
|
661
661
|
readonly data: phase0.AttestationData
|
|
662
662
|
) {}
|
|
@@ -864,9 +864,9 @@ export function aggregateConsolidation({byCommittee, attData}: AttestationsConso
|
|
|
864
864
|
* Pre-compute participation from a CachedBeaconStateAllForks, for use to check if an attestation's committee
|
|
865
865
|
* has already attested or not.
|
|
866
866
|
*/
|
|
867
|
-
export function getNotSeenValidatorsFn(
|
|
867
|
+
export function getNotSeenValidatorsFn(state: CachedBeaconStateAllForks): GetNotSeenValidatorsFn {
|
|
868
868
|
const stateSlot = state.slot;
|
|
869
|
-
if (config.getForkName(stateSlot) === ForkName.phase0) {
|
|
869
|
+
if (state.config.getForkName(stateSlot) === ForkName.phase0) {
|
|
870
870
|
// Get attestations to be included in a phase0 block.
|
|
871
871
|
// As we are close to altair, this is not really important, it's mainly for e2e.
|
|
872
872
|
// The performance is not great due to the different BeaconState data structure to altair.
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {BeaconConfig} from "@lodestar/config";
|
|
2
1
|
import {Id, Repository} from "@lodestar/db";
|
|
3
2
|
import {
|
|
4
3
|
BLS_WITHDRAWAL_PREFIX,
|
|
@@ -52,8 +51,6 @@ export class OpPool {
|
|
|
52
51
|
/** Map of validator index -> SignedBLSToExecutionChange */
|
|
53
52
|
private readonly blsToExecutionChanges = new Map<ValidatorIndex, SignedBLSToExecutionChangeVersioned>();
|
|
54
53
|
|
|
55
|
-
constructor(private readonly config: BeaconConfig) {}
|
|
56
|
-
|
|
57
54
|
// Getters for metrics
|
|
58
55
|
|
|
59
56
|
get attesterSlashingsSize(): number {
|
|
@@ -194,8 +191,9 @@ export class OpPool {
|
|
|
194
191
|
phase0.SignedVoluntaryExit[],
|
|
195
192
|
capella.SignedBLSToExecutionChange[],
|
|
196
193
|
] {
|
|
194
|
+
const {config} = state;
|
|
197
195
|
const stateEpoch = computeEpochAtSlot(state.slot);
|
|
198
|
-
const stateFork =
|
|
196
|
+
const stateFork = config.getForkSeq(state.slot);
|
|
199
197
|
const toBeSlashedIndices = new Set<ValidatorIndex>();
|
|
200
198
|
const proposerSlashings: phase0.ProposerSlashing[] = [];
|
|
201
199
|
|
|
@@ -267,7 +265,7 @@ export class OpPool {
|
|
|
267
265
|
// a future fork.
|
|
268
266
|
isVoluntaryExitSignatureIncludable(
|
|
269
267
|
stateFork,
|
|
270
|
-
|
|
268
|
+
config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch))
|
|
271
269
|
)
|
|
272
270
|
) {
|
|
273
271
|
voluntaryExits.push(voluntaryExit);
|
|
@@ -370,13 +368,14 @@ export class OpPool {
|
|
|
370
368
|
* Prune if validator has already exited at or before the finalized checkpoint of the head.
|
|
371
369
|
*/
|
|
372
370
|
private pruneVoluntaryExits(headState: CachedBeaconStateAllForks): void {
|
|
373
|
-
const
|
|
371
|
+
const {config} = headState;
|
|
372
|
+
const headStateFork = config.getForkSeq(headState.slot);
|
|
374
373
|
const finalizedEpoch = headState.finalizedCheckpoint.epoch;
|
|
375
374
|
|
|
376
375
|
for (const [key, voluntaryExit] of this.voluntaryExits.entries()) {
|
|
377
376
|
// VoluntaryExit messages signed in the previous fork become invalid and can never be included in any future
|
|
378
377
|
// block, so just drop as the head state advances into the next fork.
|
|
379
|
-
if (
|
|
378
|
+
if (config.getForkSeq(computeStartSlotAtEpoch(voluntaryExit.message.epoch)) < headStateFork) {
|
|
380
379
|
this.voluntaryExits.delete(key);
|
|
381
380
|
}
|
|
382
381
|
|
|
@@ -393,8 +392,9 @@ export class OpPool {
|
|
|
393
392
|
* to opPool once gossipsub seen cache TTL passes.
|
|
394
393
|
*/
|
|
395
394
|
private pruneBlsToExecutionChanges(headBlock: SignedBeaconBlock, headState: CachedBeaconStateAllForks): void {
|
|
395
|
+
const {config} = headState;
|
|
396
396
|
const recentBlsToExecutionChanges =
|
|
397
|
-
|
|
397
|
+
config.getForkSeq(headBlock.message.slot) >= ForkSeq.capella
|
|
398
398
|
? (headBlock as capella.SignedBeaconBlock).message.body.blsToExecutionChanges
|
|
399
399
|
: [];
|
|
400
400
|
|
|
@@ -1,8 +1,9 @@
|
|
|
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, isForkPostElectra} from "@lodestar/params";
|
|
5
5
|
import {
|
|
6
|
+
BeaconStateElectra,
|
|
6
7
|
CachedBeaconStateAllForks,
|
|
7
8
|
CachedBeaconStateExecutions,
|
|
8
9
|
StateHashTreeRootSource,
|
|
@@ -221,6 +222,9 @@ export class PrepareNextSlotScheduler {
|
|
|
221
222
|
}
|
|
222
223
|
this.metrics?.precomputeNextEpochTransition.hits.set(previousHits ?? 0);
|
|
223
224
|
|
|
225
|
+
// Check if we can stop polling eth1 data
|
|
226
|
+
this.stopEth1Polling();
|
|
227
|
+
|
|
224
228
|
this.logger.verbose("Completed PrepareNextSlotScheduler epoch transition", {
|
|
225
229
|
nextEpoch,
|
|
226
230
|
headSlot,
|
|
@@ -248,4 +252,27 @@ export class PrepareNextSlotScheduler {
|
|
|
248
252
|
state.hashTreeRoot();
|
|
249
253
|
hashTreeRootTimer?.();
|
|
250
254
|
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Stop eth1 data polling after eth1_deposit_index has reached deposit_requests_start_index in Electra as described in EIP-6110
|
|
258
|
+
*/
|
|
259
|
+
stopEth1Polling(): void {
|
|
260
|
+
// Only continue if eth1 is still polling and finalized checkpoint is in Electra. State regen is expensive
|
|
261
|
+
if (this.chain.eth1.isPollingEth1Data()) {
|
|
262
|
+
const finalizedCheckpoint = this.chain.forkChoice.getFinalizedCheckpoint();
|
|
263
|
+
const checkpointFork = this.config.getForkInfoAtEpoch(finalizedCheckpoint.epoch).name;
|
|
264
|
+
|
|
265
|
+
if (isForkPostElectra(checkpointFork)) {
|
|
266
|
+
const finalizedState = this.chain.getStateByCheckpoint(finalizedCheckpoint)?.state;
|
|
267
|
+
|
|
268
|
+
if (
|
|
269
|
+
finalizedState !== undefined &&
|
|
270
|
+
finalizedState.eth1DepositIndex === Number((finalizedState as BeaconStateElectra).depositRequestsStartIndex)
|
|
271
|
+
) {
|
|
272
|
+
// Signal eth1 to stop polling eth1Data
|
|
273
|
+
this.chain.eth1.stopPollingEth1Data();
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
251
278
|
}
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
} from "@lodestar/types";
|
|
46
46
|
import {Logger, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
47
47
|
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
48
|
-
import {numToQuantity} from "../../
|
|
48
|
+
import {numToQuantity} from "../../eth1/provider/utils.js";
|
|
49
49
|
import {
|
|
50
50
|
IExecutionBuilder,
|
|
51
51
|
IExecutionEngine,
|
|
@@ -78,6 +78,7 @@ export enum BlockProductionStep {
|
|
|
78
78
|
voluntaryExits = "voluntaryExits",
|
|
79
79
|
blsToExecutionChanges = "blsToExecutionChanges",
|
|
80
80
|
attestations = "attestations",
|
|
81
|
+
eth1DataAndDeposits = "eth1DataAndDeposits",
|
|
81
82
|
syncAggregate = "syncAggregate",
|
|
82
83
|
executionPayload = "executionPayload",
|
|
83
84
|
}
|
|
@@ -165,7 +166,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
165
166
|
// even though shouldOverrideBuilder is relevant for the engine response, for simplicity of typing
|
|
166
167
|
// we just return it undefined for the builder which anyway doesn't get consumed downstream
|
|
167
168
|
let shouldOverrideBuilder: boolean | undefined;
|
|
168
|
-
const fork =
|
|
169
|
+
const fork = currentState.config.getForkName(blockSlot);
|
|
169
170
|
const produceResult = {
|
|
170
171
|
type: blockType,
|
|
171
172
|
fork,
|
|
@@ -644,7 +645,7 @@ export async function produceCommonBlockBody<T extends BlockType>(
|
|
|
644
645
|
? this.metrics?.executionBlockProductionTimeSteps
|
|
645
646
|
: this.metrics?.builderBlockProductionTimeSteps;
|
|
646
647
|
|
|
647
|
-
const fork =
|
|
648
|
+
const fork = currentState.config.getForkName(slot);
|
|
648
649
|
|
|
649
650
|
// TODO:
|
|
650
651
|
// Iterate through the naive aggregation pool and ensure all the attestations from there
|
|
@@ -666,17 +667,20 @@ export async function produceCommonBlockBody<T extends BlockType>(
|
|
|
666
667
|
step: BlockProductionStep.attestations,
|
|
667
668
|
});
|
|
668
669
|
|
|
670
|
+
const endEth1DataAndDeposits = stepsMetrics?.startTimer();
|
|
671
|
+
const {eth1Data, deposits} = await this.eth1.getEth1DataAndDeposits(currentState);
|
|
672
|
+
endEth1DataAndDeposits?.({
|
|
673
|
+
step: BlockProductionStep.eth1DataAndDeposits,
|
|
674
|
+
});
|
|
675
|
+
|
|
669
676
|
const blockBody: Omit<CommonBlockBody, "blsToExecutionChanges" | "syncAggregate"> = {
|
|
670
677
|
randaoReveal,
|
|
671
678
|
graffiti,
|
|
672
|
-
|
|
673
|
-
eth1Data: currentState.eth1Data,
|
|
679
|
+
eth1Data,
|
|
674
680
|
proposerSlashings,
|
|
675
681
|
attesterSlashings,
|
|
676
682
|
attestations,
|
|
677
|
-
|
|
678
|
-
// we no longer support handling deposits from earlier forks.
|
|
679
|
-
deposits: [],
|
|
683
|
+
deposits,
|
|
680
684
|
voluntaryExits,
|
|
681
685
|
};
|
|
682
686
|
|