@lodestar/beacon-node 1.43.0-dev.2870b59b6a → 1.43.0-dev.38479366cc
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.js +4 -6
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -2
- package/lib/api/impl/beacon/state/utils.d.ts.map +1 -1
- package/lib/api/impl/beacon/state/utils.js.map +1 -1
- package/lib/api/impl/lodestar/index.js +1 -1
- package/lib/api/impl/lodestar/index.js.map +1 -1
- package/lib/api/impl/validator/index.d.ts.map +1 -1
- package/lib/api/impl/validator/index.js +1 -4
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/GetBlobsTracker.d.ts +1 -1
- package/lib/chain/GetBlobsTracker.d.ts.map +1 -1
- package/lib/chain/GetBlobsTracker.js +1 -2
- package/lib/chain/GetBlobsTracker.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/archiveStore/interface.d.ts +4 -4
- package/lib/chain/archiveStore/interface.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts +4 -4
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.d.ts.map +1 -1
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js +2 -4
- package/lib/chain/archiveStore/strategies/frequencyStateArchiveStrategy.js.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts +2 -2
- package/lib/chain/archiveStore/utils/archiveBlocks.d.ts.map +1 -1
- package/lib/chain/archiveStore/utils/archiveBlocks.js +110 -58
- package/lib/chain/archiveStore/utils/archiveBlocks.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +28 -33
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +25 -13
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +73 -84
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts +5 -3
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +29 -11
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +3 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +20 -0
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts +5 -0
- package/lib/chain/blocks/payloadEnvelopeProcessor.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeProcessor.js +7 -5
- package/lib/chain/blocks/payloadEnvelopeProcessor.js.map +1 -1
- package/lib/chain/blocks/types.d.ts +15 -21
- package/lib/chain/blocks/types.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.d.ts +23 -2
- package/lib/chain/blocks/utils/chainSegment.d.ts.map +1 -1
- package/lib/chain/blocks/utils/chainSegment.js +81 -12
- package/lib/chain/blocks/utils/chainSegment.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts +3 -2
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +30 -5
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksSanityChecks.js +15 -4
- package/lib/chain/blocks/verifyBlocksSanityChecks.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +24 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +76 -0
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts +14 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.d.ts.map +1 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js +25 -0
- package/lib/chain/blocks/verifyPayloadsDataAvailability.js.map +1 -0
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.d.ts.map +1 -1
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js +2 -11
- package/lib/chain/blocks/writePayloadEnvelopeInputToDb.js.map +1 -1
- package/lib/chain/chain.d.ts +6 -5
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +30 -35
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +16 -4
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js +5 -0
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +8 -1
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +2 -0
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +5 -0
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +1 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.d.ts +5 -0
- package/lib/chain/errors/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadEnvelope.js +1 -0
- package/lib/chain/errors/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +11 -15
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +5 -4
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +48 -22
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts +3 -9
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +5 -32
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +4 -8
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +55 -24
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/errors.d.ts +1 -11
- package/lib/chain/regen/errors.d.ts.map +1 -1
- package/lib/chain/regen/errors.js +0 -2
- package/lib/chain/regen/errors.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +6 -11
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/queued.d.ts +6 -10
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +3 -10
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/regen/regen.d.ts +0 -5
- package/lib/chain/regen/regen.d.ts.map +1 -1
- package/lib/chain/regen/regen.js +0 -8
- package/lib/chain/regen/regen.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +11 -4
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +20 -18
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +1 -7
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +4 -9
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +0 -6
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/stateCache/types.js.map +1 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +1 -0
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +13 -1
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +20 -10
- package/lib/chain/validation/executionPayloadEnvelope.js.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.d.ts.map +1 -1
- package/lib/chain/validation/payloadAttestationMessage.js +4 -3
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js +1 -1
- package/lib/db/repositories/executionPayloadEnvelopeArchive.js.map +1 -1
- package/lib/execution/engine/http.d.ts.map +1 -1
- package/lib/execution/engine/http.js +21 -14
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +1 -0
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/mock.d.ts.map +1 -1
- package/lib/execution/engine/mock.js +6 -0
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/types.d.ts +20 -0
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +18 -0
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +1 -0
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +4 -0
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +3 -2
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/network.js +1 -1
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +24 -7
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +14 -6
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js +11 -5
- package/lib/network/reqresp/handlers/blobSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +17 -5
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +7 -4
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +4 -2
- package/lib/node/nodejs.js.map +1 -1
- package/lib/node/notifier.js +7 -1
- package/lib/node/notifier.js.map +1 -1
- package/lib/sync/range/batch.d.ts +12 -2
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +56 -30
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +6 -2
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +4 -3
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/range.d.ts.map +1 -1
- package/lib/sync/range/range.js +17 -6
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/types.d.ts +34 -0
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +34 -0
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +24 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +649 -53
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts +46 -10
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +147 -24
- package/lib/sync/utils/downloadByRange.js.map +1 -1
- package/lib/sync/utils/downloadByRoot.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRoot.js +6 -2
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts +0 -1
- package/lib/sync/utils/pendingBlocksTree.d.ts.map +1 -1
- package/lib/sync/utils/pendingBlocksTree.js +0 -9
- package/lib/sync/utils/pendingBlocksTree.js.map +1 -1
- package/lib/util/sszBytes.d.ts.map +1 -1
- package/lib/util/sszBytes.js +16 -3
- package/lib/util/sszBytes.js.map +1 -1
- package/package.json +17 -16
- package/src/api/impl/beacon/blocks/index.ts +6 -6
- package/src/api/impl/beacon/state/utils.ts +2 -2
- package/src/api/impl/lodestar/index.ts +1 -1
- package/src/api/impl/validator/index.ts +3 -6
- package/src/chain/GetBlobsTracker.ts +1 -2
- package/src/chain/archiveStore/archiveStore.ts +5 -5
- package/src/chain/archiveStore/interface.ts +4 -4
- package/src/chain/archiveStore/strategies/frequencyStateArchiveStrategy.ts +6 -8
- package/src/chain/archiveStore/utils/archiveBlocks.ts +153 -94
- package/src/chain/blocks/importBlock.ts +27 -38
- package/src/chain/blocks/importExecutionPayload.ts +93 -104
- package/src/chain/blocks/index.ts +45 -14
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +27 -0
- package/src/chain/blocks/payloadEnvelopeProcessor.ts +7 -6
- package/src/chain/blocks/types.ts +15 -26
- package/src/chain/blocks/utils/chainSegment.ts +106 -17
- package/src/chain/blocks/verifyBlock.ts +35 -6
- package/src/chain/blocks/verifyBlocksSanityChecks.ts +16 -7
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +129 -0
- package/src/chain/blocks/verifyPayloadsDataAvailability.ts +38 -0
- package/src/chain/blocks/writePayloadEnvelopeInputToDb.ts +9 -18
- package/src/chain/chain.ts +46 -51
- package/src/chain/emitter.ts +15 -3
- package/src/chain/errors/blockError.ts +4 -1
- package/src/chain/errors/executionPayloadBid.ts +6 -0
- package/src/chain/errors/executionPayloadEnvelope.ts +6 -0
- package/src/chain/forkChoice/index.ts +8 -20
- package/src/chain/interface.ts +9 -3
- package/src/chain/prepareNextSlot.ts +62 -23
- package/src/chain/produceBlock/computeNewStateRoot.ts +6 -43
- package/src/chain/produceBlock/produceBlockBody.ts +73 -27
- package/src/chain/regen/errors.ts +1 -6
- package/src/chain/regen/interface.ts +6 -11
- package/src/chain/regen/queued.ts +6 -14
- package/src/chain/regen/regen.ts +0 -8
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +22 -20
- package/src/chain/stateCache/persistentCheckpointsCache.ts +5 -15
- package/src/chain/stateCache/types.ts +0 -3
- package/src/chain/validation/block.ts +1 -0
- package/src/chain/validation/executionPayloadBid.ts +14 -0
- package/src/chain/validation/executionPayloadEnvelope.ts +21 -11
- package/src/chain/validation/payloadAttestationMessage.ts +5 -3
- package/src/db/repositories/executionPayloadEnvelopeArchive.ts +1 -1
- package/src/execution/engine/http.ts +21 -14
- package/src/execution/engine/interface.ts +1 -0
- package/src/execution/engine/mock.ts +8 -1
- package/src/execution/engine/types.ts +41 -0
- package/src/metrics/metrics/lodestar.ts +4 -0
- package/src/network/network.ts +1 -1
- package/src/network/processor/gossipHandlers.ts +30 -11
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +14 -6
- package/src/network/reqresp/handlers/blobSidecarsByRange.ts +11 -5
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -5
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +7 -4
- package/src/node/nodejs.ts +4 -2
- package/src/node/notifier.ts +8 -1
- package/src/sync/range/batch.ts +90 -35
- package/src/sync/range/chain.ts +13 -5
- package/src/sync/range/range.ts +18 -6
- package/src/sync/types.ts +72 -0
- package/src/sync/unknownBlock.ts +810 -57
- package/src/sync/utils/downloadByRange.ts +256 -39
- package/src/sync/utils/downloadByRoot.ts +12 -2
- package/src/sync/utils/pendingBlocksTree.ts +0 -15
- package/src/util/sszBytes.ts +21 -3
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DataAvailabilityStatus,
|
|
3
3
|
ExecutionPayloadStatus,
|
|
4
|
-
G2_POINT_AT_INFINITY,
|
|
5
4
|
IBeaconStateView,
|
|
6
|
-
IBeaconStateViewGloas,
|
|
7
5
|
StateHashTreeRootSource,
|
|
8
6
|
} from "@lodestar/state-transition";
|
|
9
|
-
import {BeaconBlock, BlindedBeaconBlock, Gwei, Root
|
|
7
|
+
import {BeaconBlock, BlindedBeaconBlock, Gwei, Root} from "@lodestar/types";
|
|
10
8
|
import {ZERO_HASH} from "../../constants/index.js";
|
|
11
9
|
import {Metrics} from "../../metrics/index.js";
|
|
12
10
|
|
|
@@ -19,11 +17,11 @@ export function computeNewStateRoot(
|
|
|
19
17
|
metrics: Metrics | null,
|
|
20
18
|
state: IBeaconStateView,
|
|
21
19
|
block: BeaconBlock | BlindedBeaconBlock
|
|
22
|
-
): {newStateRoot: Root; proposerReward: Gwei;
|
|
20
|
+
): {newStateRoot: Root; proposerReward: Gwei; postState: IBeaconStateView} {
|
|
23
21
|
// Set signature to zero to re-use stateTransition() function which requires the SignedBeaconBlock type
|
|
24
22
|
const blockEmptySig = {message: block, signature: ZERO_HASH};
|
|
25
23
|
|
|
26
|
-
const
|
|
24
|
+
const postState = state.stateTransition(
|
|
27
25
|
blockEmptySig,
|
|
28
26
|
{
|
|
29
27
|
// ExecutionPayloadStatus.valid: Assume payload valid, it has been produced by a trusted EL
|
|
@@ -42,49 +40,14 @@ export function computeNewStateRoot(
|
|
|
42
40
|
{metrics}
|
|
43
41
|
);
|
|
44
42
|
|
|
45
|
-
const {attestations, syncAggregate, slashing} =
|
|
43
|
+
const {attestations, syncAggregate, slashing} = postState.proposerRewards;
|
|
46
44
|
const proposerReward = BigInt(attestations + syncAggregate + slashing);
|
|
47
45
|
|
|
48
46
|
const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
|
|
49
47
|
source: StateHashTreeRootSource.computeNewStateRoot,
|
|
50
48
|
});
|
|
51
|
-
const newStateRoot =
|
|
49
|
+
const newStateRoot = postState.hashTreeRoot();
|
|
52
50
|
hashTreeRootTimer?.();
|
|
53
51
|
|
|
54
|
-
return {newStateRoot, proposerReward,
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Compute the state root after processing an execution payload envelope.
|
|
59
|
-
* Similar to `computeNewStateRoot` but for payload envelope processing.
|
|
60
|
-
*
|
|
61
|
-
*/
|
|
62
|
-
export function computePayloadEnvelopeStateRoot(
|
|
63
|
-
metrics: Metrics | null,
|
|
64
|
-
postBlockState: IBeaconStateViewGloas,
|
|
65
|
-
envelope: gloas.ExecutionPayloadEnvelope
|
|
66
|
-
): Root {
|
|
67
|
-
const signedEnvelope: gloas.SignedExecutionPayloadEnvelope = {
|
|
68
|
-
message: envelope,
|
|
69
|
-
signature: G2_POINT_AT_INFINITY,
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const processEnvelopeTimer = metrics?.blockPayload.executionPayloadEnvelopeProcessingTime.startTimer();
|
|
73
|
-
const postPayloadState = postBlockState.processExecutionPayloadEnvelope(signedEnvelope, {
|
|
74
|
-
// Signature is zero-ed (G2_POINT_AT_INFINITY), skip verification
|
|
75
|
-
verifySignature: false,
|
|
76
|
-
// State root is being computed here, the envelope doesn't have it yet
|
|
77
|
-
verifyStateRoot: false,
|
|
78
|
-
// Preserve cache in source state, since the resulting state is not added to the state cache
|
|
79
|
-
dontTransferCache: true,
|
|
80
|
-
});
|
|
81
|
-
processEnvelopeTimer?.();
|
|
82
|
-
|
|
83
|
-
const hashTreeRootTimer = metrics?.stateHashTreeRootTime.startTimer({
|
|
84
|
-
source: StateHashTreeRootSource.computePayloadEnvelopeStateRoot,
|
|
85
|
-
});
|
|
86
|
-
const stateRoot = postPayloadState.hashTreeRoot();
|
|
87
|
-
hashTreeRootTimer?.();
|
|
88
|
-
|
|
89
|
-
return stateRoot;
|
|
52
|
+
return {newStateRoot, proposerReward, postState};
|
|
90
53
|
}
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
IBeaconStateView,
|
|
20
20
|
type IBeaconStateViewBellatrix,
|
|
21
21
|
computeTimeAtSlot,
|
|
22
|
-
isParentBlockFull,
|
|
23
22
|
isStatePostBellatrix,
|
|
24
23
|
isStatePostCapella,
|
|
25
24
|
isStatePostGloas,
|
|
@@ -47,9 +46,10 @@ import {
|
|
|
47
46
|
electra,
|
|
48
47
|
fulu,
|
|
49
48
|
gloas,
|
|
49
|
+
ssz,
|
|
50
50
|
} from "@lodestar/types";
|
|
51
|
-
import {Logger, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
52
|
-
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
51
|
+
import {Logger, byteArrayEquals, fromHex, sleep, toHex, toPubkeyHex, toRootHex} from "@lodestar/utils";
|
|
52
|
+
import {ZERO_HASH, ZERO_HASH_HEX} from "../../constants/index.js";
|
|
53
53
|
import {numToQuantity} from "../../execution/engine/utils.js";
|
|
54
54
|
import {
|
|
55
55
|
IExecutionBuilder,
|
|
@@ -111,12 +111,6 @@ export type ProduceFullGloas = {
|
|
|
111
111
|
executionRequests: electra.ExecutionRequests;
|
|
112
112
|
blobsBundle: BlobsBundle<ForkPostGloas>;
|
|
113
113
|
cells: fulu.Cell[][];
|
|
114
|
-
/**
|
|
115
|
-
* Cached payload envelope state root computed during block production.
|
|
116
|
-
* This is the state root after running `processExecutionPayloadEnvelope` on the
|
|
117
|
-
* post-block state, and later used to construct the `ExecutionPayloadEnvelope`.
|
|
118
|
-
*/
|
|
119
|
-
payloadEnvelopeStateRoot: Root;
|
|
120
114
|
};
|
|
121
115
|
export type ProduceFullFulu = {
|
|
122
116
|
type: BlockType.Full;
|
|
@@ -220,15 +214,30 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
220
214
|
});
|
|
221
215
|
|
|
222
216
|
// Get execution payload from EL
|
|
217
|
+
const isExtendingPayload = this.forkChoice.shouldExtendPayload(toRootHex(parentBlockRoot));
|
|
218
|
+
let parentBlockHash = isExtendingPayload
|
|
219
|
+
? currentState.latestExecutionPayloadBid.blockHash
|
|
220
|
+
: currentState.latestExecutionPayloadBid.parentBlockHash;
|
|
221
|
+
// At gloas genesis the committed bid has no prior EL block to reference
|
|
222
|
+
// (`bid.parentBlockHash` is zero). Fall back to `bid.blockHash` (= eth1 genesis hash) so the
|
|
223
|
+
// FCU to the EL carries a valid head. Post-genesis bids always reference a non-zero parent.
|
|
224
|
+
if (isStatePostGloas(currentState) && byteArrayEquals(parentBlockHash, ZERO_HASH)) {
|
|
225
|
+
parentBlockHash = currentState.latestExecutionPayloadBid.blockHash;
|
|
226
|
+
}
|
|
227
|
+
const parentExecutionRequests = isExtendingPayload
|
|
228
|
+
? await this.getParentExecutionRequests(parentBlock.slot, parentBlock.blockRoot)
|
|
229
|
+
: ssz.electra.ExecutionRequests.defaultValue();
|
|
223
230
|
const prepareRes = await prepareExecutionPayload(
|
|
224
231
|
this,
|
|
225
232
|
this.logger,
|
|
226
233
|
fork,
|
|
227
234
|
parentBlockRoot,
|
|
235
|
+
parentBlockHash,
|
|
228
236
|
safeBlockHash,
|
|
229
237
|
finalizedBlockHash ?? ZERO_HASH_HEX,
|
|
230
238
|
currentState,
|
|
231
|
-
feeRecipient
|
|
239
|
+
feeRecipient,
|
|
240
|
+
parentExecutionRequests
|
|
232
241
|
);
|
|
233
242
|
|
|
234
243
|
const {prepType, payloadId} = prepareRes;
|
|
@@ -261,8 +270,8 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
261
270
|
|
|
262
271
|
// Create self-build execution payload bid
|
|
263
272
|
const bid: gloas.ExecutionPayloadBid = {
|
|
264
|
-
parentBlockHash
|
|
265
|
-
parentBlockRoot
|
|
273
|
+
parentBlockHash,
|
|
274
|
+
parentBlockRoot,
|
|
266
275
|
blockHash: executionPayload.blockHash,
|
|
267
276
|
prevRandao: currentState.getRandaoMix(currentState.epoch),
|
|
268
277
|
feeRecipient: executionPayload.feeRecipient,
|
|
@@ -272,6 +281,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
272
281
|
value: 0,
|
|
273
282
|
executionPayment: 0,
|
|
274
283
|
blobKzgCommitments: blobsBundle.commitments,
|
|
284
|
+
executionRequestsRoot: ssz.electra.ExecutionRequests.hashTreeRoot(executionRequests),
|
|
275
285
|
};
|
|
276
286
|
const signedBid: gloas.SignedExecutionPayloadBid = {
|
|
277
287
|
message: bid,
|
|
@@ -283,6 +293,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
283
293
|
gloasBody.signedExecutionPayloadBid = signedBid;
|
|
284
294
|
// TODO GLOAS: Get payload attestations from pool for previous slot
|
|
285
295
|
gloasBody.payloadAttestations = [];
|
|
296
|
+
gloasBody.parentExecutionRequests = parentExecutionRequests;
|
|
286
297
|
blockBody = gloasBody as AssembledBodyType<T>;
|
|
287
298
|
|
|
288
299
|
// Store execution payload data required to construct execution payload envelope later
|
|
@@ -340,6 +351,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
340
351
|
this.logger,
|
|
341
352
|
fork,
|
|
342
353
|
parentBlockRoot,
|
|
354
|
+
currentState.latestExecutionPayloadHeader.blockHash,
|
|
343
355
|
safeBlockHash,
|
|
344
356
|
finalizedBlockHash ?? ZERO_HASH_HEX,
|
|
345
357
|
currentState,
|
|
@@ -448,6 +460,7 @@ export async function produceBlockBody<T extends BlockType>(
|
|
|
448
460
|
this.logger,
|
|
449
461
|
fork,
|
|
450
462
|
parentBlockRoot,
|
|
463
|
+
currentState.latestExecutionPayloadHeader.blockHash,
|
|
451
464
|
safeBlockHash,
|
|
452
465
|
finalizedBlockHash ?? ZERO_HASH_HEX,
|
|
453
466
|
currentState,
|
|
@@ -613,17 +626,18 @@ export async function prepareExecutionPayload(
|
|
|
613
626
|
logger: Logger,
|
|
614
627
|
fork: ForkPostBellatrix,
|
|
615
628
|
parentBlockRoot: Root,
|
|
629
|
+
parentBlockHash: Bytes32,
|
|
616
630
|
safeBlockHash: RootHex,
|
|
617
631
|
finalizedBlockHash: RootHex,
|
|
618
632
|
state: IBeaconStateViewBellatrix,
|
|
619
|
-
suggestedFeeRecipient: string
|
|
633
|
+
suggestedFeeRecipient: string,
|
|
634
|
+
parentExecutionRequests?: electra.ExecutionRequests
|
|
620
635
|
): Promise<{prepType: PayloadPreparationType; payloadId: PayloadId}> {
|
|
621
|
-
const parentHash = state.latestBlockHash;
|
|
622
636
|
const timestamp = computeTimeAtSlot(chain.config, state.slot, state.genesisTime);
|
|
623
637
|
const prevRandao = state.getRandaoMix(state.epoch);
|
|
624
638
|
|
|
625
639
|
const payloadIdCached = chain.executionEngine.payloadIdCache.get({
|
|
626
|
-
headBlockHash: toRootHex(
|
|
640
|
+
headBlockHash: toRootHex(parentBlockHash),
|
|
627
641
|
finalizedBlockHash,
|
|
628
642
|
timestamp: numToQuantity(timestamp),
|
|
629
643
|
prevRandao: toHex(prevRandao),
|
|
@@ -652,12 +666,14 @@ export async function prepareExecutionPayload(
|
|
|
652
666
|
prepareState: state,
|
|
653
667
|
prepareSlot: state.slot,
|
|
654
668
|
parentBlockRoot,
|
|
669
|
+
parentBlockHash,
|
|
655
670
|
feeRecipient: suggestedFeeRecipient,
|
|
671
|
+
parentExecutionRequests,
|
|
656
672
|
});
|
|
657
673
|
|
|
658
674
|
payloadId = await chain.executionEngine.notifyForkchoiceUpdate(
|
|
659
675
|
fork,
|
|
660
|
-
toRootHex(
|
|
676
|
+
toRootHex(parentBlockHash),
|
|
661
677
|
safeBlockHash,
|
|
662
678
|
finalizedBlockHash,
|
|
663
679
|
attributes
|
|
@@ -709,20 +725,33 @@ export function getPayloadAttributesForSSE(
|
|
|
709
725
|
prepareState,
|
|
710
726
|
prepareSlot,
|
|
711
727
|
parentBlockRoot,
|
|
728
|
+
parentBlockHash,
|
|
712
729
|
feeRecipient,
|
|
713
|
-
|
|
730
|
+
parentExecutionRequests,
|
|
731
|
+
}: {
|
|
732
|
+
prepareState: IBeaconStateViewBellatrix;
|
|
733
|
+
prepareSlot: Slot;
|
|
734
|
+
parentBlockRoot: Root;
|
|
735
|
+
parentBlockHash: Bytes32;
|
|
736
|
+
feeRecipient: string;
|
|
737
|
+
parentExecutionRequests?: electra.ExecutionRequests;
|
|
738
|
+
}
|
|
714
739
|
): SSEPayloadAttributes {
|
|
715
|
-
const parentHash = prepareState.latestBlockHash;
|
|
716
740
|
const payloadAttributes = preparePayloadAttributes(fork, chain, {
|
|
717
741
|
prepareState,
|
|
718
742
|
prepareSlot,
|
|
719
743
|
parentBlockRoot,
|
|
744
|
+
parentBlockHash,
|
|
720
745
|
feeRecipient,
|
|
746
|
+
parentExecutionRequests,
|
|
721
747
|
});
|
|
722
748
|
|
|
723
749
|
let parentBlockNumber: number;
|
|
724
750
|
if (isForkPostGloas(fork)) {
|
|
725
|
-
const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(
|
|
751
|
+
const parentBlock = chain.forkChoice.getBlockHexAndBlockHash(
|
|
752
|
+
toRootHex(parentBlockRoot),
|
|
753
|
+
toRootHex(parentBlockHash)
|
|
754
|
+
);
|
|
726
755
|
if (parentBlock?.executionPayloadBlockHash == null) {
|
|
727
756
|
throw Error(`Parent block not found in fork choice root=${toRootHex(parentBlockRoot)}`);
|
|
728
757
|
}
|
|
@@ -736,7 +765,7 @@ export function getPayloadAttributesForSSE(
|
|
|
736
765
|
proposalSlot: prepareSlot,
|
|
737
766
|
parentBlockNumber,
|
|
738
767
|
parentBlockRoot,
|
|
739
|
-
parentBlockHash
|
|
768
|
+
parentBlockHash,
|
|
740
769
|
payloadAttributes,
|
|
741
770
|
};
|
|
742
771
|
return ssePayloadAttributes;
|
|
@@ -751,12 +780,16 @@ function preparePayloadAttributes(
|
|
|
751
780
|
prepareState,
|
|
752
781
|
prepareSlot,
|
|
753
782
|
parentBlockRoot,
|
|
783
|
+
parentBlockHash,
|
|
754
784
|
feeRecipient,
|
|
785
|
+
parentExecutionRequests,
|
|
755
786
|
}: {
|
|
756
787
|
prepareState: IBeaconStateViewBellatrix;
|
|
757
788
|
prepareSlot: Slot;
|
|
758
789
|
parentBlockRoot: Root;
|
|
790
|
+
parentBlockHash: Bytes32;
|
|
759
791
|
feeRecipient: string;
|
|
792
|
+
parentExecutionRequests?: electra.ExecutionRequests;
|
|
760
793
|
}
|
|
761
794
|
): SSEPayloadAttributes["payloadAttributes"] {
|
|
762
795
|
const timestamp = computeTimeAtSlot(chain.config, prepareSlot, prepareState.genesisTime);
|
|
@@ -772,13 +805,22 @@ function preparePayloadAttributes(
|
|
|
772
805
|
throw new Error("Expected Capella state for withdrawals");
|
|
773
806
|
}
|
|
774
807
|
|
|
775
|
-
if (isStatePostGloas(prepareState)
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
808
|
+
if (isStatePostGloas(prepareState)) {
|
|
809
|
+
const isExtendingPayload = byteArrayEquals(parentBlockHash, prepareState.latestExecutionPayloadBid.blockHash);
|
|
810
|
+
if (isExtendingPayload) {
|
|
811
|
+
if (parentExecutionRequests === undefined) {
|
|
812
|
+
throw new Error("parentExecutionRequests required when extending full parent");
|
|
813
|
+
}
|
|
814
|
+
(payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
|
|
815
|
+
prepareState.getExpectedWithdrawalsForFullParent(parentExecutionRequests);
|
|
816
|
+
} else {
|
|
817
|
+
// When the parent block is empty, state.payloadExpectedWithdrawals holds a batch
|
|
818
|
+
// already deducted from CL balances but never credited on the EL (the envelope
|
|
819
|
+
// was not delivered). The next payload must carry those same withdrawals to
|
|
820
|
+
// restore CL/EL consistency, otherwise validators permanently lose that balance.
|
|
821
|
+
(payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
|
|
822
|
+
prepareState.payloadExpectedWithdrawals;
|
|
823
|
+
}
|
|
782
824
|
} else {
|
|
783
825
|
// withdrawals logic is now fork aware as it changes on electra fork post capella
|
|
784
826
|
(payloadAttributes as capella.SSEPayloadAttributes["payloadAttributes"]).withdrawals =
|
|
@@ -790,6 +832,10 @@ function preparePayloadAttributes(
|
|
|
790
832
|
(payloadAttributes as deneb.SSEPayloadAttributes["payloadAttributes"]).parentBeaconBlockRoot = parentBlockRoot;
|
|
791
833
|
}
|
|
792
834
|
|
|
835
|
+
if (ForkSeq[fork] >= ForkSeq.gloas) {
|
|
836
|
+
(payloadAttributes as gloas.SSEPayloadAttributes["payloadAttributes"]).slotNumber = prepareSlot;
|
|
837
|
+
}
|
|
838
|
+
|
|
793
839
|
return payloadAttributes;
|
|
794
840
|
}
|
|
795
841
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {PayloadStatus} from "@lodestar/fork-choice";
|
|
2
1
|
import {Root, RootHex, Slot} from "@lodestar/types";
|
|
3
2
|
|
|
4
3
|
export enum RegenErrorCode {
|
|
@@ -10,8 +9,6 @@ export enum RegenErrorCode {
|
|
|
10
9
|
BLOCK_NOT_IN_DB = "REGEN_ERROR_BLOCK_NOT_IN_DB",
|
|
11
10
|
STATE_TRANSITION_ERROR = "REGEN_ERROR_STATE_TRANSITION_ERROR",
|
|
12
11
|
INVALID_STATE_ROOT = "REGEN_ERROR_INVALID_STATE_ROOT",
|
|
13
|
-
UNEXPECTED_PAYLOAD_STATUS = "REGEN_ERROR_UNEXPECTED_PAYLOAD_STATUS",
|
|
14
|
-
INTERNAL_ERROR = "REGEN_ERROR_INTERNAL_ERROR",
|
|
15
12
|
}
|
|
16
13
|
|
|
17
14
|
export type RegenErrorType =
|
|
@@ -22,9 +19,7 @@ export type RegenErrorType =
|
|
|
22
19
|
| {code: RegenErrorCode.TOO_MANY_BLOCK_PROCESSED; stateRoot: RootHex | Root}
|
|
23
20
|
| {code: RegenErrorCode.BLOCK_NOT_IN_DB; blockRoot: RootHex | Root}
|
|
24
21
|
| {code: RegenErrorCode.STATE_TRANSITION_ERROR; error: Error}
|
|
25
|
-
| {code: RegenErrorCode.INVALID_STATE_ROOT; slot: Slot; expected: RootHex; actual: RootHex}
|
|
26
|
-
| {code: RegenErrorCode.UNEXPECTED_PAYLOAD_STATUS; blockRoot: RootHex | Root; payloadStatus: PayloadStatus}
|
|
27
|
-
| {code: RegenErrorCode.INTERNAL_ERROR; message: string};
|
|
22
|
+
| {code: RegenErrorCode.INVALID_STATE_ROOT; slot: Slot; expected: RootHex; actual: RootHex};
|
|
28
23
|
|
|
29
24
|
export class RegenError extends Error {
|
|
30
25
|
type: RegenErrorType;
|
|
@@ -2,7 +2,7 @@ import {routes} from "@lodestar/api";
|
|
|
2
2
|
import {ProtoBlock} from "@lodestar/fork-choice";
|
|
3
3
|
import {IBeaconStateView} from "@lodestar/state-transition";
|
|
4
4
|
import {BeaconBlock, Epoch, RootHex, Slot, phase0} from "@lodestar/types";
|
|
5
|
-
import {
|
|
5
|
+
import {CheckpointHex} from "../stateCache/types.js";
|
|
6
6
|
|
|
7
7
|
export enum RegenCaller {
|
|
8
8
|
getDuties = "getDuties",
|
|
@@ -40,20 +40,15 @@ export interface IStateRegenerator extends IStateRegeneratorInternal {
|
|
|
40
40
|
dumpCacheSummary(): routes.lodestar.StateCacheItem[];
|
|
41
41
|
getStateSync(stateRoot: RootHex): IBeaconStateView | null;
|
|
42
42
|
getPreStateSync(block: BeaconBlock): IBeaconStateView | null;
|
|
43
|
-
getCheckpointStateOrBytes(cp:
|
|
44
|
-
getCheckpointStateSync(cp:
|
|
43
|
+
getCheckpointStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null>;
|
|
44
|
+
getCheckpointStateSync(cp: CheckpointHex): IBeaconStateView | null;
|
|
45
45
|
getClosestHeadState(head: ProtoBlock): IBeaconStateView | null;
|
|
46
46
|
pruneOnCheckpoint(finalizedEpoch: Epoch, justifiedEpoch: Epoch, headStateRoot: RootHex): void;
|
|
47
47
|
pruneOnFinalized(finalizedEpoch: Epoch): void;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* payloadPresent is true if this is payload state, false if block state.
|
|
52
|
-
* payloadPresent is always true for pre-gloas.
|
|
53
|
-
*/
|
|
54
|
-
addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView, payloadPresent: boolean): void;
|
|
48
|
+
processState(blockRootHex: RootHex, postState: IBeaconStateView): void;
|
|
49
|
+
addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView): void;
|
|
55
50
|
updateHeadState(newHead: ProtoBlock, maybeHeadState: IBeaconStateView): void;
|
|
56
|
-
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch
|
|
51
|
+
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null;
|
|
57
52
|
}
|
|
58
53
|
|
|
59
54
|
/**
|
|
@@ -5,7 +5,7 @@ import {BeaconBlock, Epoch, RootHex, Slot, isGloasBeaconBlock, phase0} from "@lo
|
|
|
5
5
|
import {Logger, toRootHex} from "@lodestar/utils";
|
|
6
6
|
import {Metrics} from "../../metrics/index.js";
|
|
7
7
|
import {JobItemQueue} from "../../util/queue/index.js";
|
|
8
|
-
import {BlockStateCache,
|
|
8
|
+
import {BlockStateCache, CheckpointHex, CheckpointStateCache} from "../stateCache/types.js";
|
|
9
9
|
import {RegenError, RegenErrorCode} from "./errors.js";
|
|
10
10
|
import {
|
|
11
11
|
IStateRegenerator,
|
|
@@ -125,14 +125,14 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
125
125
|
return null;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
async getCheckpointStateOrBytes(cp:
|
|
128
|
+
async getCheckpointStateOrBytes(cp: CheckpointHex): Promise<IBeaconStateView | Uint8Array | null> {
|
|
129
129
|
return this.checkpointStateCache.getStateOrBytes(cp);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
/**
|
|
133
133
|
* Get checkpoint state from cache
|
|
134
134
|
*/
|
|
135
|
-
getCheckpointStateSync(cp:
|
|
135
|
+
getCheckpointStateSync(cp: CheckpointHex): IBeaconStateView | null {
|
|
136
136
|
return this.checkpointStateCache.get(cp);
|
|
137
137
|
}
|
|
138
138
|
|
|
@@ -153,22 +153,14 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
153
153
|
this.blockStateCache.deleteAllBeforeEpoch(finalizedEpoch);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
processState(blockRootHex: RootHex, postState: IBeaconStateView): void {
|
|
157
157
|
this.blockStateCache.add(postState);
|
|
158
158
|
this.checkpointStateCache.processState(blockRootHex, postState).catch((e) => {
|
|
159
159
|
this.logger.debug("Error processing block state", {blockRootHex, slot: postState.slot}, e);
|
|
160
160
|
});
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
* Process payload state for caching after importing execution payload.
|
|
165
|
-
*/
|
|
166
|
-
processPayloadState(payloadState: IBeaconStateView): void {
|
|
167
|
-
// Add payload state to block state cache (keyed by payload state root)
|
|
168
|
-
this.blockStateCache.add(payloadState);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView, _payloadPresent: boolean): void {
|
|
163
|
+
addCheckpointState(cp: phase0.Checkpoint, item: IBeaconStateView): void {
|
|
172
164
|
this.checkpointStateCache.add(cp, item);
|
|
173
165
|
}
|
|
174
166
|
|
|
@@ -205,7 +197,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
|
|
|
205
197
|
}
|
|
206
198
|
}
|
|
207
199
|
|
|
208
|
-
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch
|
|
200
|
+
updatePreComputedCheckpoint(rootHex: RootHex, epoch: Epoch): number | null {
|
|
209
201
|
return this.checkpointStateCache.updatePreComputedCheckpoint(rootHex, epoch);
|
|
210
202
|
}
|
|
211
203
|
|
package/src/chain/regen/regen.ts
CHANGED
|
@@ -332,11 +332,6 @@ async function processSlotsByCheckpoint(
|
|
|
332
332
|
* emitting "checkpoint" events after every epoch processed.
|
|
333
333
|
*
|
|
334
334
|
* Stops processing after no more full epochs can be processed.
|
|
335
|
-
*
|
|
336
|
-
* Output state variant:
|
|
337
|
-
* - Post-Gloas: If slots are processed, returns block state (payloadPresent=false).
|
|
338
|
-
* If no slots processed, returns preState as-is (preserves variant).
|
|
339
|
-
* - Pre-Gloas: Always payloadPresent=true (no block/payload distinction).
|
|
340
335
|
*/
|
|
341
336
|
export async function processSlotsToNearestCheckpoint(
|
|
342
337
|
modules: {
|
|
@@ -380,9 +375,6 @@ export async function processSlotsToNearestCheckpoint(
|
|
|
380
375
|
// This may becomes the "official" checkpoint state if the 1st block of epoch is skipped
|
|
381
376
|
const checkpointState = postState;
|
|
382
377
|
const cp = getCheckpointFromState(checkpointState);
|
|
383
|
-
// processSlots() only does epoch transitions, never processes payloads
|
|
384
|
-
// Pre-Gloas: payloadPresent is always true (execution payload embedded in block)
|
|
385
|
-
// Post-Gloas: result is a block state (payloadPresent=false)
|
|
386
378
|
checkpointStateCache.add(cp, checkpointState);
|
|
387
379
|
// consumers should not mutate state ever
|
|
388
380
|
emitter?.emit(ChainEvent.checkpoint, cp, checkpointState);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {CheckpointWithHex} from "@lodestar/fork-choice";
|
|
2
2
|
import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
|
|
3
|
-
import {RootHex} from "@lodestar/types";
|
|
3
|
+
import {RootHex, Slot} from "@lodestar/types";
|
|
4
4
|
import {Logger} from "@lodestar/utils";
|
|
5
5
|
import {Metrics} from "../../metrics/metrics.js";
|
|
6
6
|
import {SerializedCache} from "../../util/serializedCache.js";
|
|
@@ -21,8 +21,15 @@ export type SeenPayloadEnvelopeInputModules = {
|
|
|
21
21
|
/**
|
|
22
22
|
* Cache for tracking PayloadEnvelopeInput instances, keyed by beacon block root.
|
|
23
23
|
*
|
|
24
|
-
* Created during block import when a block is processed.
|
|
25
|
-
*
|
|
24
|
+
* Created during block import when a block is processed. Two pruning paths:
|
|
25
|
+
* - `prepareNextSlot` calls `pruneBelow(headParentSlot)` every slot once the head we'll build
|
|
26
|
+
* on is known.
|
|
27
|
+
* - `onFinalized` calls `pruneBelow(finalizedSlot)` on every finalization for bulk cleanup.
|
|
28
|
+
*
|
|
29
|
+
* Steady state (linear chain, healthy progression): the cache holds ~2 entries — the head
|
|
30
|
+
* (parent for next-slot production) and its parent (proposer-boost-reorg fallback). It can
|
|
31
|
+
* transiently hold more during forks, range-sync bursts, or when `prepareNextSlot` skips
|
|
32
|
+
* ticks; subsequent ticks settle it back.
|
|
26
33
|
*/
|
|
27
34
|
export class SeenPayloadEnvelopeInput {
|
|
28
35
|
private readonly chainEvents: ChainEventEmitter;
|
|
@@ -58,16 +65,7 @@ export class SeenPayloadEnvelopeInput {
|
|
|
58
65
|
}
|
|
59
66
|
|
|
60
67
|
private onFinalized = (checkpoint: CheckpointWithHex): void => {
|
|
61
|
-
|
|
62
|
-
const finalizedSlot = computeStartSlotAtEpoch(checkpoint.epoch);
|
|
63
|
-
let deletedCount = 0;
|
|
64
|
-
for (const [, input] of this.payloadInputs) {
|
|
65
|
-
if (input.slot < finalizedSlot) {
|
|
66
|
-
this.evictPayloadInput(input);
|
|
67
|
-
deletedCount++;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
this.logger?.debug("SeenPayloadEnvelopeInput.onFinalized deleted cached entries", {deletedCount});
|
|
68
|
+
this.pruneBelow(computeStartSlotAtEpoch(checkpoint.epoch));
|
|
71
69
|
};
|
|
72
70
|
|
|
73
71
|
add(props: CreateFromBlockProps): PayloadEnvelopeInput {
|
|
@@ -88,17 +86,21 @@ export class SeenPayloadEnvelopeInput {
|
|
|
88
86
|
return this.payloadInputs.get(blockRootHex)?.hasPayloadEnvelope() ?? false;
|
|
89
87
|
}
|
|
90
88
|
|
|
91
|
-
prune(blockRootHex: RootHex): void {
|
|
92
|
-
const payloadInput = this.payloadInputs.get(blockRootHex);
|
|
93
|
-
if (payloadInput) {
|
|
94
|
-
this.evictPayloadInput(payloadInput);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
89
|
size(): number {
|
|
99
90
|
return this.payloadInputs.size;
|
|
100
91
|
}
|
|
101
92
|
|
|
93
|
+
pruneBelow(slot: Slot): void {
|
|
94
|
+
let deletedCount = 0;
|
|
95
|
+
for (const [, input] of this.payloadInputs) {
|
|
96
|
+
if (input.slot < slot) {
|
|
97
|
+
this.evictPayloadInput(input);
|
|
98
|
+
deletedCount++;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
this.logger?.debug("SeenPayloadEnvelopeInput.pruneBelow deleted entries", {slot, deletedCount});
|
|
102
|
+
}
|
|
103
|
+
|
|
102
104
|
private evictPayloadInput(payloadInput: PayloadEnvelopeInput): void {
|
|
103
105
|
this.serializedCache.delete(payloadInput.getSerializedCacheKeys());
|
|
104
106
|
this.payloadInputs.delete(payloadInput.blockRootHex);
|
|
@@ -9,7 +9,7 @@ import {IClock} from "../../util/clock.js";
|
|
|
9
9
|
import {serializeState} from "../serializeState.js";
|
|
10
10
|
import {CPStateDatastore, DatastoreKey} from "./datastore/index.js";
|
|
11
11
|
import {MapTracker} from "./mapMetrics.js";
|
|
12
|
-
import {BlockStateCache, CacheItemType, CheckpointHex,
|
|
12
|
+
import {BlockStateCache, CacheItemType, CheckpointHex, CheckpointStateCache} from "./types.js";
|
|
13
13
|
|
|
14
14
|
export type PersistentCheckpointStateCacheOpts = {
|
|
15
15
|
/** Keep max n state epochs in memory, persist the rest to disk */
|
|
@@ -226,7 +226,10 @@ export class PersistentCheckpointStateCache implements CheckpointStateCache {
|
|
|
226
226
|
}
|
|
227
227
|
sszTimer?.();
|
|
228
228
|
const timer = this.metrics?.cpStateCache.stateReloadDuration.startTimer();
|
|
229
|
-
|
|
229
|
+
// preload validators and balances for faster state transition
|
|
230
|
+
const newCachedState = seedState.loadOtherState(stateBytes, validatorsBytes, {
|
|
231
|
+
preloadValidatorsAndBalances: true,
|
|
232
|
+
});
|
|
230
233
|
// hashTreeRoot() calls the commit() inside
|
|
231
234
|
// there is no modification inside the state, it's just that we want to compute and cache all roots
|
|
232
235
|
const stateRoot = toRootHex(newCachedState.hashTreeRoot());
|
|
@@ -843,19 +846,6 @@ export function toCheckpointHex(checkpoint: phase0.Checkpoint): CheckpointHex {
|
|
|
843
846
|
};
|
|
844
847
|
}
|
|
845
848
|
|
|
846
|
-
/** TODO GLOAS: remove after rolling back regen dual-state changes */
|
|
847
|
-
export function fcCheckpointToHexPayload(checkpoint: {
|
|
848
|
-
epoch: Epoch;
|
|
849
|
-
rootHex: RootHex;
|
|
850
|
-
payloadStatus?: number;
|
|
851
|
-
}): CheckpointHexPayload {
|
|
852
|
-
return {
|
|
853
|
-
epoch: checkpoint.epoch,
|
|
854
|
-
rootHex: checkpoint.rootHex,
|
|
855
|
-
payloadPresent: true,
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
|
|
859
849
|
export function toCheckpointKey(cp: CheckpointHex): string {
|
|
860
850
|
return `${cp.rootHex}:${cp.epoch}`;
|
|
861
851
|
}
|
|
@@ -4,9 +4,6 @@ import {Epoch, RootHex, phase0} from "@lodestar/types";
|
|
|
4
4
|
|
|
5
5
|
export type CheckpointHex = {epoch: Epoch; rootHex: RootHex};
|
|
6
6
|
|
|
7
|
-
/** TODO GLOAS: payloadPresent is ignored — remove after rolling back regen dual-state changes */
|
|
8
|
-
export type CheckpointHexPayload = {epoch: Epoch; rootHex: RootHex; payloadPresent: boolean};
|
|
9
|
-
|
|
10
7
|
/**
|
|
11
8
|
* Lodestar currently keeps two state caches around.
|
|
12
9
|
*
|
|
@@ -103,6 +103,7 @@ export async function validateGossipBlock(
|
|
|
103
103
|
if (chain.forkChoice.getBlockHexAndBlockHash(parentRoot, parentBlockHashHex) === null) {
|
|
104
104
|
throw new BlockGossipError(GossipAction.IGNORE, {
|
|
105
105
|
code: BlockErrorCode.PARENT_PAYLOAD_UNKNOWN,
|
|
106
|
+
parentRoot,
|
|
106
107
|
parentBlockHash: parentBlockHashHex,
|
|
107
108
|
});
|
|
108
109
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {PublicKey} from "@chainsafe/blst";
|
|
2
2
|
import {
|
|
3
|
+
computeEpochAtSlot,
|
|
3
4
|
createSingleSignatureSetFromComponents,
|
|
4
5
|
getExecutionPayloadBidSigningRoot,
|
|
5
6
|
isActiveBuilder,
|
|
@@ -76,6 +77,19 @@ async function validateExecutionPayloadBid(
|
|
|
76
77
|
// `SignedProposerPreferences` associated with `bid.slot`.
|
|
77
78
|
// TODO GLOAS: Implement this along with proposer preference
|
|
78
79
|
|
|
80
|
+
// [REJECT] The length of KZG commitments is less than or equal to the limitation defined in the
|
|
81
|
+
// consensus layer -- i.e. validate that
|
|
82
|
+
// `len(bid.blob_kzg_commitments) <= get_blob_parameters(compute_epoch_at_slot(bid.slot)).max_blobs_per_block`.
|
|
83
|
+
const blobKzgCommitmentsLen = bid.blobKzgCommitments.length;
|
|
84
|
+
const maxBlobsPerBlock = chain.config.getMaxBlobsPerBlock(computeEpochAtSlot(bid.slot));
|
|
85
|
+
if (blobKzgCommitmentsLen > maxBlobsPerBlock) {
|
|
86
|
+
throw new ExecutionPayloadBidError(GossipAction.REJECT, {
|
|
87
|
+
code: ExecutionPayloadBidErrorCode.TOO_MANY_KZG_COMMITMENTS,
|
|
88
|
+
blobKzgCommitmentsLen,
|
|
89
|
+
commitmentLimit: maxBlobsPerBlock,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
79
93
|
// [IGNORE] this is the first signed bid seen with a valid signature from the given builder for this slot.
|
|
80
94
|
if (chain.seenExecutionPayloadBids.isKnown(bid.slot, bid.builderIndex)) {
|
|
81
95
|
throw new ExecutionPayloadBidError(GossipAction.IGNORE, {
|