@lodestar/beacon-node 1.44.0-dev.6ef8199cfa → 1.44.0-dev.762dd5f186
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/impl/beacon/blocks/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/blocks/index.js +66 -33
- package/lib/api/impl/beacon/blocks/index.js.map +1 -1
- package/lib/api/impl/beacon/pool/index.d.ts.map +1 -1
- package/lib/api/impl/beacon/pool/index.js +1 -26
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/config/constants.d.ts +5 -0
- package/lib/api/impl/config/constants.d.ts.map +1 -1
- package/lib/api/impl/config/constants.js +6 -1
- package/lib/api/impl/config/constants.js.map +1 -1
- package/lib/api/impl/debug/index.d.ts.map +1 -1
- package/lib/api/impl/debug/index.js +69 -12
- package/lib/api/impl/debug/index.js.map +1 -1
- package/lib/api/impl/lodestar/index.d.ts.map +1 -1
- package/lib/api/impl/lodestar/index.js +28 -0
- 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 +117 -72
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.d.ts +0 -1
- package/lib/chain/archiveStore/archiveStore.d.ts.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +0 -4
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/blocks/importBlock.d.ts.map +1 -1
- package/lib/chain/blocks/importBlock.js +19 -4
- package/lib/chain/blocks/importBlock.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +5 -3
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +3 -3
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
- package/lib/chain/chain.d.ts +3 -3
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +11 -3
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/emitter.d.ts +2 -1
- package/lib/chain/emitter.d.ts.map +1 -1
- package/lib/chain/emitter.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +0 -7
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +0 -3
- package/lib/chain/errors/blockError.js.map +1 -1
- package/lib/chain/errors/executionPayloadBid.d.ts +23 -1
- package/lib/chain/errors/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/errors/executionPayloadBid.js +4 -0
- package/lib/chain/errors/executionPayloadBid.js.map +1 -1
- package/lib/chain/errors/payloadAttestation.d.ts +6 -0
- package/lib/chain/errors/payloadAttestation.d.ts.map +1 -1
- package/lib/chain/errors/payloadAttestation.js +1 -0
- package/lib/chain/errors/payloadAttestation.js.map +1 -1
- package/lib/chain/forkChoice/index.d.ts +4 -4
- package/lib/chain/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +24 -11
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +2 -2
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/executionPayloadBidPool.d.ts +4 -4
- package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
- package/lib/chain/opPools/executionPayloadBidPool.js +6 -4
- package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
- package/lib/chain/options.d.ts.map +1 -1
- package/lib/chain/options.js +1 -0
- package/lib/chain/options.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +2 -10
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.d.ts +4 -2
- package/lib/chain/produceBlock/produceBlockBody.d.ts.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +81 -27
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +2 -1
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +2 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +0 -1
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +0 -4
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +8 -2
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +0 -5
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +0 -5
- package/lib/chain/stateCache/fifoBlockStateCache.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 +5 -2
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +0 -2
- 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 +5 -1
- package/lib/chain/validation/block.d.ts.map +1 -1
- package/lib/chain/validation/block.js +4 -14
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts +7 -3
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +81 -16
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +1 -3
- 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 +24 -4
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validatorMonitor.d.ts +1 -0
- package/lib/chain/validatorMonitor.d.ts.map +1 -1
- package/lib/chain/validatorMonitor.js +16 -0
- package/lib/chain/validatorMonitor.js.map +1 -1
- package/lib/execution/builder/index.d.ts +1 -2
- package/lib/execution/builder/index.d.ts.map +1 -1
- package/lib/execution/builder/index.js +0 -1
- package/lib/execution/builder/index.js.map +1 -1
- package/lib/execution/engine/http.js +1 -1
- package/lib/execution/engine/http.js.map +1 -1
- package/lib/execution/engine/interface.d.ts +2 -2
- package/lib/execution/engine/interface.d.ts.map +1 -1
- package/lib/execution/engine/interface.js +6 -2
- 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 +3 -5
- package/lib/execution/engine/mock.js.map +1 -1
- package/lib/execution/engine/types.d.ts +15 -7
- package/lib/execution/engine/types.d.ts.map +1 -1
- package/lib/execution/engine/types.js +47 -9
- package/lib/execution/engine/types.js.map +1 -1
- package/lib/metrics/metrics/lodestar.d.ts +5 -1
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +14 -3
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +770 -3
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/interface.d.ts +1 -0
- package/lib/network/interface.d.ts.map +1 -1
- package/lib/network/network.d.ts +1 -0
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +5 -0
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +21 -6
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/index.d.ts +2 -2
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +25 -23
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js +9 -5
- package/lib/network/reqresp/handlers/beaconBlocksByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js +13 -3
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js +1 -1
- package/lib/network/reqresp/handlers/dataColumnSidecarsByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts +2 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js +16 -6
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRange.js.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts +2 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.d.ts.map +1 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js +15 -1
- package/lib/network/reqresp/handlers/executionPayloadEnvelopesByRoot.js.map +1 -1
- package/lib/network/reqresp/handlers/index.js +4 -4
- package/lib/network/reqresp/handlers/index.js.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.d.ts.map +1 -1
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js +23 -5
- package/lib/network/reqresp/utils/dataColumnResponseValidation.js.map +1 -1
- package/lib/sync/types.d.ts +9 -1
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +9 -2
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +64 -30
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/util/dataColumns.d.ts.map +1 -1
- package/lib/util/dataColumns.js +16 -11
- package/lib/util/dataColumns.js.map +1 -1
- package/lib/util/sszBytes.js +1 -1
- package/package.json +15 -17
- package/src/api/impl/beacon/blocks/index.ts +76 -42
- package/src/api/impl/beacon/pool/index.ts +4 -42
- package/src/api/impl/config/constants.ts +10 -0
- package/src/api/impl/debug/index.ts +73 -12
- package/src/api/impl/lodestar/index.ts +30 -0
- package/src/api/impl/validator/index.ts +137 -86
- package/src/chain/archiveStore/archiveStore.ts +0 -5
- package/src/chain/blocks/importBlock.ts +29 -7
- package/src/chain/blocks/importExecutionPayload.ts +8 -2
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +3 -5
- package/src/chain/chain.ts +14 -4
- package/src/chain/emitter.ts +3 -2
- package/src/chain/errors/blockError.ts +0 -4
- package/src/chain/errors/executionPayloadBid.ts +20 -1
- package/src/chain/errors/payloadAttestation.ts +2 -0
- package/src/chain/forkChoice/index.ts +27 -4
- package/src/chain/interface.ts +1 -2
- package/src/chain/opPools/executionPayloadBidPool.ts +10 -9
- package/src/chain/options.ts +1 -0
- package/src/chain/prepareNextSlot.ts +2 -11
- package/src/chain/produceBlock/produceBlockBody.ts +114 -40
- package/src/chain/regen/interface.ts +2 -1
- package/src/chain/regen/queued.ts +0 -5
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +8 -3
- package/src/chain/stateCache/fifoBlockStateCache.ts +0 -6
- package/src/chain/stateCache/persistentCheckpointsCache.ts +6 -2
- package/src/chain/stateCache/types.ts +0 -2
- package/src/chain/validation/block.ts +12 -16
- package/src/chain/validation/executionPayloadBid.ts +90 -19
- package/src/chain/validation/executionPayloadEnvelope.ts +1 -3
- package/src/chain/validation/payloadAttestationMessage.ts +26 -4
- package/src/chain/validatorMonitor.ts +18 -0
- package/src/execution/builder/index.ts +1 -4
- package/src/execution/engine/http.ts +1 -1
- package/src/execution/engine/interface.ts +12 -2
- package/src/execution/engine/mock.ts +6 -5
- package/src/execution/engine/types.ts +75 -14
- package/src/metrics/metrics/lodestar.ts +15 -3
- package/src/network/interface.ts +1 -0
- package/src/network/network.ts +11 -0
- package/src/network/processor/gossipHandlers.ts +26 -6
- package/src/network/processor/index.ts +27 -27
- package/src/network/reqresp/handlers/beaconBlocksByRange.ts +12 -5
- package/src/network/reqresp/handlers/dataColumnSidecarsByRange.ts +17 -3
- package/src/network/reqresp/handlers/dataColumnSidecarsByRoot.ts +1 -1
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRange.ts +22 -6
- package/src/network/reqresp/handlers/executionPayloadEnvelopesByRoot.ts +20 -1
- package/src/network/reqresp/handlers/index.ts +4 -4
- package/src/network/reqresp/utils/dataColumnResponseValidation.ts +22 -5
- package/src/sync/types.ts +11 -2
- package/src/sync/unknownBlock.ts +70 -31
- package/src/util/dataColumns.ts +17 -12
- package/src/util/sszBytes.ts +1 -1
- package/lib/execution/builder/utils.d.ts +0 -5
- package/lib/execution/builder/utils.d.ts.map +0 -1
- package/lib/execution/builder/utils.js +0 -17
- package/lib/execution/builder/utils.js.map +0 -1
- package/src/execution/builder/utils.ts +0 -19
|
@@ -914,20 +914,38 @@ export function getValidatorApi(
|
|
|
914
914
|
notWhileSyncing();
|
|
915
915
|
await waitForSlot(slot);
|
|
916
916
|
|
|
917
|
-
// TODO GLOAS: support producing blocks from builder bids
|
|
918
|
-
const source = ProducedBlockSource.engine;
|
|
919
|
-
|
|
920
|
-
// TODO GLOAS: needs to be updated after fork choice changes are merged
|
|
921
917
|
const parentBlock = chain.getProposerHead(slot);
|
|
922
918
|
const {blockRoot: parentBlockRootHex, slot: parentSlot} = parentBlock;
|
|
923
919
|
const parentBlockRoot = fromHex(parentBlockRootHex);
|
|
924
920
|
notOnOutOfRangeData(parentBlockRoot);
|
|
925
921
|
metrics?.blockProductionSlotDelta.set(slot - parentSlot);
|
|
926
|
-
metrics?.blockProductionRequests.inc({source});
|
|
927
922
|
|
|
928
923
|
const graffitiBytes = toGraffitiBytes(
|
|
929
924
|
graffiti ?? getDefaultGraffiti(getLodestarClientVersion(opts), chain.executionEngine.clientVersion, opts)
|
|
930
925
|
);
|
|
926
|
+
|
|
927
|
+
// TODO GLOAS: respect builderSelection (MaxProfit, BuilderAlways, ExecutionAlways, etc.) to let
|
|
928
|
+
// the user control bid source preferences and value comparison. Also add external builder api
|
|
929
|
+
// support when it is implemented.
|
|
930
|
+
const isBuildingOnFull = chain.forkChoice.shouldBuildOnFull(parentBlock, slot);
|
|
931
|
+
const bidParentBlockHash = isBuildingOnFull ? parentBlock.executionPayloadBlockHash : parentBlock.parentBlockHash;
|
|
932
|
+
const builderBid = chain.executionPayloadBidPool.getBestBid(slot, bidParentBlockHash, parentBlockRootHex);
|
|
933
|
+
|
|
934
|
+
const logCtx = {
|
|
935
|
+
slot,
|
|
936
|
+
parentSlot,
|
|
937
|
+
parentBlockRoot: parentBlockRootHex,
|
|
938
|
+
parentBlockHash: parentBlock.executionPayloadBlockHash,
|
|
939
|
+
fork,
|
|
940
|
+
...(builderBid !== null
|
|
941
|
+
? {
|
|
942
|
+
bidValue: builderBid.message.value,
|
|
943
|
+
builderIndex: builderBid.message.builderIndex,
|
|
944
|
+
bidBlockHash: toRootHex(builderBid.message.blockHash),
|
|
945
|
+
}
|
|
946
|
+
: {}),
|
|
947
|
+
};
|
|
948
|
+
|
|
931
949
|
const commonBlockBodyPromise = chain.produceCommonBlockBody({
|
|
932
950
|
slot,
|
|
933
951
|
parentBlock,
|
|
@@ -935,44 +953,76 @@ export function getValidatorApi(
|
|
|
935
953
|
graffiti: graffitiBytes,
|
|
936
954
|
});
|
|
937
955
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
feeRecipient,
|
|
947
|
-
commonBlockBodyPromise,
|
|
948
|
-
});
|
|
956
|
+
const baseAttrs = {
|
|
957
|
+
slot,
|
|
958
|
+
parentBlock,
|
|
959
|
+
randaoReveal,
|
|
960
|
+
graffiti: graffitiBytes,
|
|
961
|
+
feeRecipient,
|
|
962
|
+
commonBlockBodyPromise,
|
|
963
|
+
};
|
|
949
964
|
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
metrics?.
|
|
953
|
-
|
|
965
|
+
metrics?.blockProductionRequests.inc({source: ProducedBlockSource.engine});
|
|
966
|
+
if (builderBid !== null) {
|
|
967
|
+
metrics?.blockProductionRequests.inc({source: ProducedBlockSource.builder});
|
|
968
|
+
}
|
|
954
969
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
970
|
+
const timed = <T>(source: ProducedBlockSource, fn: () => Promise<T>): Promise<T> => {
|
|
971
|
+
const t = metrics?.blockProductionTime.startTimer();
|
|
972
|
+
return fn().finally(() => t?.({source}));
|
|
973
|
+
};
|
|
974
|
+
|
|
975
|
+
// Always build local block. If builder bid available, also build with it in parallel and prefer it.
|
|
976
|
+
const [engineResult, bidResult] = await Promise.allSettled([
|
|
977
|
+
timed(ProducedBlockSource.engine, () => chain.produceBlock(baseAttrs)),
|
|
978
|
+
builderBid !== null
|
|
979
|
+
? timed(ProducedBlockSource.builder, () => chain.produceBlock({...baseAttrs, builderBid}))
|
|
980
|
+
: Promise.reject(),
|
|
981
|
+
]);
|
|
982
|
+
|
|
983
|
+
let bestResult: typeof engineResult | null = null;
|
|
984
|
+
let source: ProducedBlockSource = ProducedBlockSource.engine;
|
|
985
|
+
if (builderBid !== null && bidResult.status === "fulfilled") {
|
|
986
|
+
source = ProducedBlockSource.builder;
|
|
987
|
+
bestResult = bidResult;
|
|
988
|
+
logger.info("Selected builder bid block", logCtx);
|
|
989
|
+
} else if (engineResult.status === "fulfilled") {
|
|
990
|
+
source = ProducedBlockSource.engine;
|
|
991
|
+
bestResult = engineResult;
|
|
992
|
+
if (builderBid !== null) {
|
|
993
|
+
logger.warn("Builder bid block production failed, using local block", logCtx);
|
|
964
994
|
}
|
|
995
|
+
}
|
|
965
996
|
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
}
|
|
974
|
-
|
|
997
|
+
if (bestResult === null || bestResult.status !== "fulfilled") {
|
|
998
|
+
const engineReason = engineResult.status === "rejected" ? engineResult.reason : undefined;
|
|
999
|
+
const bidReason = builderBid !== null && bidResult.status === "rejected" ? bidResult.reason : undefined;
|
|
1000
|
+
logger.error("Block production failed", {...logCtx, engineReason, bidReason});
|
|
1001
|
+
throw Error(`Block production failed: engine=${engineReason ?? "n/a"} builder=${bidReason ?? "n/a"}`);
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
const {block, executionPayloadValue, consensusBlockValue} = bestResult.value;
|
|
1005
|
+
|
|
1006
|
+
metrics?.blockProductionSuccess.inc({source});
|
|
1007
|
+
metrics?.blockProductionNumAggregated.observe({source}, block.body.attestations.length);
|
|
1008
|
+
metrics?.blockProductionConsensusBlockValue.observe({source}, Number(formatWeiToEth(consensusBlockValue)));
|
|
1009
|
+
metrics?.blockProductionExecutionPayloadValue.observe({source}, Number(formatWeiToEth(executionPayloadValue)));
|
|
1010
|
+
|
|
1011
|
+
const blockRoot = toRootHex(config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block));
|
|
1012
|
+
logger.verbose("Produced block", {
|
|
1013
|
+
...logCtx,
|
|
1014
|
+
executionPayloadValue,
|
|
1015
|
+
consensusBlockValue,
|
|
1016
|
+
root: blockRoot,
|
|
1017
|
+
});
|
|
1018
|
+
if (chain.opts.persistProducedBlocks) {
|
|
1019
|
+
void chain.persistBlock(block, "produced_engine_block");
|
|
975
1020
|
}
|
|
1021
|
+
|
|
1022
|
+
return {
|
|
1023
|
+
data: block as gloas.BeaconBlock,
|
|
1024
|
+
meta: {version: fork, consensusBlockValue},
|
|
1025
|
+
};
|
|
976
1026
|
},
|
|
977
1027
|
|
|
978
1028
|
async produceAttestationData({committeeIndex, slot}) {
|
|
@@ -1060,23 +1110,34 @@ export function getValidatorApi(
|
|
|
1060
1110
|
notWhileSyncing();
|
|
1061
1111
|
await waitForSlot(slot);
|
|
1062
1112
|
|
|
1063
|
-
const block = chain.forkChoice.
|
|
1113
|
+
const block = chain.forkChoice.getCanonicalBlockAtSlot(slot);
|
|
1064
1114
|
if (!block) {
|
|
1065
|
-
|
|
1115
|
+
// No block is seen at slot. Return 404 so vc can skip casting payload attestation.
|
|
1116
|
+
throw new ApiError(404, `No canonical block found at slot=${slot}`);
|
|
1066
1117
|
}
|
|
1067
1118
|
|
|
1068
|
-
const blockIsForSlot = block.slot === slot;
|
|
1069
1119
|
const payloadInput = chain.seenPayloadEnvelopeInputCache.get(block.blockRoot);
|
|
1070
1120
|
// Spec: set payload_present only if the envelope was seen before get_payload_due_ms()
|
|
1071
1121
|
// into the slot. Use the envelope's own arrival time (getPayloadEnvelopeSource), not
|
|
1072
1122
|
// the input's creation time.
|
|
1073
1123
|
const payloadDueSec = config.getPayloadDueMs() / 1000;
|
|
1074
|
-
const
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
const blobDataAvailable =
|
|
1124
|
+
const payloadSeenSec =
|
|
1125
|
+
payloadInput?.hasPayloadEnvelope() === true
|
|
1126
|
+
? chain.clock.secFromSlot(slot, payloadInput.getPayloadEnvelopeSource().seenTimestampSec)
|
|
1127
|
+
: null;
|
|
1128
|
+
const payloadPresent = payloadSeenSec !== null && payloadSeenSec < payloadDueSec;
|
|
1129
|
+
const blobDataAvailable = payloadInput?.hasAllData() === true;
|
|
1130
|
+
|
|
1131
|
+
logger.debug("Produced payload attestation data", {
|
|
1132
|
+
slot,
|
|
1133
|
+
blockRoot: block.blockRoot,
|
|
1134
|
+
blockSlot: block.slot,
|
|
1135
|
+
payloadPresent,
|
|
1136
|
+
blobDataAvailable,
|
|
1137
|
+
hasPayloadInput: payloadInput !== undefined,
|
|
1138
|
+
payloadSeenSec,
|
|
1139
|
+
payloadDueSec,
|
|
1140
|
+
});
|
|
1080
1141
|
|
|
1081
1142
|
return {
|
|
1082
1143
|
data: {
|
|
@@ -1146,7 +1207,10 @@ export function getValidatorApi(
|
|
|
1146
1207
|
const isPostFulu = isForkPostFulu(config.getForkName(startSlot));
|
|
1147
1208
|
const maxFutureEpoch = isPostFulu && nearNextEpoch && opts?.v2 ? nextEpoch + 1 : nextEpoch;
|
|
1148
1209
|
if (currentEpoch >= 0 && epoch > maxFutureEpoch) {
|
|
1149
|
-
throw new ApiError(
|
|
1210
|
+
throw new ApiError(
|
|
1211
|
+
400,
|
|
1212
|
+
`Requested epoch ${epoch} must not be more than ${maxFutureEpoch}, currentEpoch=${currentEpoch}, v2=${opts?.v2 ?? false}`
|
|
1213
|
+
);
|
|
1150
1214
|
}
|
|
1151
1215
|
|
|
1152
1216
|
const head = chain.forkChoice.getHead();
|
|
@@ -1230,17 +1294,35 @@ export function getValidatorApi(
|
|
|
1230
1294
|
duties.push({slot: startSlot + i, validatorIndex: indexes[i], pubkey: pubkeys[i]});
|
|
1231
1295
|
}
|
|
1232
1296
|
|
|
1233
|
-
//
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1297
|
+
// In v2 the dependent root is different after fulu due to deterministic proposer lookahead
|
|
1298
|
+
let dependentRoot = proposerShufflingDecisionRoot(
|
|
1299
|
+
opts?.v2 ? config.getForkName(startSlot) : ForkName.phase0,
|
|
1300
|
+
state,
|
|
1301
|
+
epoch
|
|
1302
|
+
);
|
|
1303
|
+
const logCtx = {
|
|
1304
|
+
epoch,
|
|
1305
|
+
stateSlot: state.slot,
|
|
1306
|
+
stateEpoch: state.epoch,
|
|
1307
|
+
v2: opts?.v2 ?? false,
|
|
1308
|
+
};
|
|
1309
|
+
if (dependentRoot === null) {
|
|
1310
|
+
// fallback to get_proposer_duties() v1, also in lodestar v1.43
|
|
1311
|
+
logger.verbose("Proposer duties decision root not in state, falling back to state epoch", logCtx);
|
|
1312
|
+
dependentRoot = proposerShufflingDecisionRoot(ForkName.phase0, state, state.epoch);
|
|
1313
|
+
}
|
|
1314
|
+
if (dependentRoot === null) {
|
|
1315
|
+
logger.verbose("Proposer duties decision root not in state, falling back to genesis block root", logCtx);
|
|
1316
|
+
dependentRoot = await getGenesisBlockRoot(state);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
const dependentRootHex = toRootHex(dependentRoot);
|
|
1320
|
+
logger.verbose("Computed proposer duties decision root", {...logCtx, dependentRoot: dependentRootHex});
|
|
1239
1321
|
|
|
1240
1322
|
return {
|
|
1241
1323
|
data: duties,
|
|
1242
1324
|
meta: {
|
|
1243
|
-
dependentRoot:
|
|
1325
|
+
dependentRoot: dependentRootHex,
|
|
1244
1326
|
executionOptimistic: isOptimisticBlock(head),
|
|
1245
1327
|
},
|
|
1246
1328
|
};
|
|
@@ -1419,33 +1501,6 @@ export function getValidatorApi(
|
|
|
1419
1501
|
};
|
|
1420
1502
|
},
|
|
1421
1503
|
|
|
1422
|
-
async getAggregatedAttestation({attestationDataRoot, slot}) {
|
|
1423
|
-
notWhileSyncing();
|
|
1424
|
-
|
|
1425
|
-
await waitForSlot(slot); // Must never request for a future slot > currentSlot
|
|
1426
|
-
|
|
1427
|
-
const dataRootHex = toRootHex(attestationDataRoot);
|
|
1428
|
-
const aggregate = chain.attestationPool.getAggregate(slot, dataRootHex, null);
|
|
1429
|
-
const fork = chain.config.getForkName(slot);
|
|
1430
|
-
|
|
1431
|
-
if (isForkPostElectra(fork)) {
|
|
1432
|
-
throw new ApiError(
|
|
1433
|
-
400,
|
|
1434
|
-
`Use getAggregatedAttestationV2 to retrieve aggregated attestations for post-electra fork=${fork}`
|
|
1435
|
-
);
|
|
1436
|
-
}
|
|
1437
|
-
|
|
1438
|
-
if (!aggregate) {
|
|
1439
|
-
throw new ApiError(404, `No aggregated attestation for slot=${slot}, dataRoot=${dataRootHex}`);
|
|
1440
|
-
}
|
|
1441
|
-
|
|
1442
|
-
metrics?.production.producedAggregateParticipants.observe(aggregate.aggregationBits.getTrueBitIndexes().length);
|
|
1443
|
-
|
|
1444
|
-
return {
|
|
1445
|
-
data: aggregate,
|
|
1446
|
-
};
|
|
1447
|
-
},
|
|
1448
|
-
|
|
1449
1504
|
async getAggregatedAttestationV2({attestationDataRoot, slot, committeeIndex}) {
|
|
1450
1505
|
notWhileSyncing();
|
|
1451
1506
|
|
|
@@ -1469,10 +1524,6 @@ export function getValidatorApi(
|
|
|
1469
1524
|
};
|
|
1470
1525
|
},
|
|
1471
1526
|
|
|
1472
|
-
async publishAggregateAndProofs({signedAggregateAndProofs}) {
|
|
1473
|
-
await this.publishAggregateAndProofsV2({signedAggregateAndProofs});
|
|
1474
|
-
},
|
|
1475
|
-
|
|
1476
1527
|
async publishAggregateAndProofsV2({signedAggregateAndProofs}) {
|
|
1477
1528
|
notWhileSyncing();
|
|
1478
1529
|
|
|
@@ -30,7 +30,6 @@ export enum ArchiveStoreTask {
|
|
|
30
30
|
PruneHistory = "prune_history",
|
|
31
31
|
OnFinalizedCheckpoint = "on_finalized_checkpoint",
|
|
32
32
|
MaybeArchiveState = "maybe_archive_state",
|
|
33
|
-
RegenPruneOnFinalized = "regen_prune_on_finalized",
|
|
34
33
|
ForkchoicePrune = "forkchoice_prune",
|
|
35
34
|
UpdateBackfillRange = "update_backfill_range",
|
|
36
35
|
}
|
|
@@ -229,10 +228,6 @@ export class ArchiveStore {
|
|
|
229
228
|
await this.statesArchiverStrategy.maybeArchiveState(finalized, this.metrics);
|
|
230
229
|
timer?.({source: ArchiveStoreTask.MaybeArchiveState});
|
|
231
230
|
|
|
232
|
-
timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
|
|
233
|
-
this.chain.regen.pruneOnFinalized(finalizedEpoch);
|
|
234
|
-
timer?.({source: ArchiveStoreTask.RegenPruneOnFinalized});
|
|
235
|
-
|
|
236
231
|
// tasks rely on extended fork choice
|
|
237
232
|
timer = this.metrics?.processFinalizedCheckpoint.durationByTask.startTimer();
|
|
238
233
|
const prunedBlocks = this.chain.forkChoice.prune(finalized.rootHex);
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
} from "@lodestar/state-transition";
|
|
23
23
|
import {Attestation, BeaconBlock, altair, capella, electra, isGloasBeaconBlock, phase0, ssz} from "@lodestar/types";
|
|
24
24
|
import {isErrorAborted, toRootHex} from "@lodestar/utils";
|
|
25
|
-
import {ZERO_HASH_HEX} from "../../constants/index.js";
|
|
25
|
+
import {GENESIS_SLOT, ZERO_HASH_HEX} from "../../constants/index.js";
|
|
26
26
|
import {callInNextEventLoop} from "../../util/eventLoop.js";
|
|
27
27
|
import {isOptimisticBlock} from "../../util/forkChoice.js";
|
|
28
28
|
import {isQueueErrorAborted} from "../../util/queue/index.js";
|
|
@@ -116,13 +116,19 @@ export async function importBlock(
|
|
|
116
116
|
}
|
|
117
117
|
executionStatus = parentBlock.executionStatus;
|
|
118
118
|
}
|
|
119
|
+
|
|
120
|
+
// getBeaconProposerOrNull will return null if head state is more than one epoch away
|
|
121
|
+
// from block slot. We skip proposer boost canonical check as we cannot determine the canonical proposer
|
|
122
|
+
const expectedProposerIndex: number | null = this.getHeadState().getBeaconProposerOrNull(blockSlot);
|
|
123
|
+
|
|
119
124
|
const blockSummary = this.forkChoice.onBlock(
|
|
120
125
|
block.message,
|
|
121
126
|
postState,
|
|
122
127
|
blockDelaySec,
|
|
123
128
|
currentSlot,
|
|
124
129
|
executionStatus,
|
|
125
|
-
dataAvailabilityStatus
|
|
130
|
+
dataAvailabilityStatus,
|
|
131
|
+
expectedProposerIndex
|
|
126
132
|
);
|
|
127
133
|
|
|
128
134
|
// This adds the state necessary to process the next block
|
|
@@ -183,10 +189,12 @@ export async function importBlock(
|
|
|
183
189
|
this.seenBlockAttesters.addIndices(blockEpoch, indexedAttestation.attestingIndices);
|
|
184
190
|
|
|
185
191
|
const correctHead = ssz.Root.equals(rootCache.getBlockRootAtSlot(attestation.data.slot), beaconBlockRoot);
|
|
186
|
-
const missedSlotVote =
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
const missedSlotVote =
|
|
193
|
+
attestation.data.slot > GENESIS_SLOT &&
|
|
194
|
+
ssz.Root.equals(
|
|
195
|
+
rootCache.getBlockRootAtSlot(attestation.data.slot - 1),
|
|
196
|
+
rootCache.getBlockRootAtSlot(attestation.data.slot)
|
|
197
|
+
);
|
|
190
198
|
this.validatorMonitor?.registerAttestationInBlock(
|
|
191
199
|
indexedAttestation,
|
|
192
200
|
parentBlockSlot,
|
|
@@ -257,8 +265,10 @@ export async function importBlock(
|
|
|
257
265
|
if (ptcIndices.length > 0) {
|
|
258
266
|
this.forkChoice.notifyPtcMessages(
|
|
259
267
|
toRootHex(payloadAttestation.data.beaconBlockRoot),
|
|
268
|
+
payloadAttestation.data.slot,
|
|
260
269
|
ptcIndices,
|
|
261
|
-
payloadAttestation.data.payloadPresent
|
|
270
|
+
payloadAttestation.data.payloadPresent,
|
|
271
|
+
payloadAttestation.data.blobDataAvailable
|
|
262
272
|
);
|
|
263
273
|
}
|
|
264
274
|
} catch (e) {
|
|
@@ -273,6 +283,18 @@ export async function importBlock(
|
|
|
273
283
|
const newHead = this.recomputeForkChoiceHead(ForkchoiceCaller.importBlock);
|
|
274
284
|
const currFinalizedEpoch = this.forkChoice.getFinalizedCheckpoint().epoch;
|
|
275
285
|
|
|
286
|
+
// Prune the gloas payload-envelope cache below the new head's parent so it stays bounded during
|
|
287
|
+
// syncing. On a synced node, cache holds just 2 entries — head (parent for
|
|
288
|
+
// next-slot production) and head.parent (proposer-boost-reorg fallback)
|
|
289
|
+
if (fork >= ForkSeq.gloas) {
|
|
290
|
+
callInNextEventLoop(() => {
|
|
291
|
+
const newHeadParent = this.forkChoice.getBlockHexDefaultStatus(newHead.parentRoot);
|
|
292
|
+
if (newHeadParent) {
|
|
293
|
+
this.seenPayloadEnvelopeInputCache.pruneBelowParent(newHeadParent);
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
276
298
|
if (newHead.blockRoot !== oldHead.blockRoot) {
|
|
277
299
|
// Set head state as strong reference
|
|
278
300
|
this.regen.updateHeadState(newHead, postState);
|
|
@@ -129,7 +129,7 @@ export async function importExecutionPayload(
|
|
|
129
129
|
|
|
130
130
|
// 3. Regenerate state for envelope verification
|
|
131
131
|
const blockState = await this.regen
|
|
132
|
-
.getBlockSlotState(protoBlock, protoBlock.slot, {dontTransferCache: true}, RegenCaller.
|
|
132
|
+
.getBlockSlotState(protoBlock, protoBlock.slot, {dontTransferCache: true}, RegenCaller.importExecutionPayload)
|
|
133
133
|
.catch(() =>
|
|
134
134
|
// only happen at the 1st batch of skipped slot checkpoint sync
|
|
135
135
|
this.regen.getClosestHeadState(protoBlock)
|
|
@@ -237,6 +237,7 @@ export async function importExecutionPayload(
|
|
|
237
237
|
blockRootHex,
|
|
238
238
|
blockHashHex,
|
|
239
239
|
envelope.payload.blockNumber,
|
|
240
|
+
envelope.payload.gasLimit,
|
|
240
241
|
execStatus,
|
|
241
242
|
dataAvailabilityStatus
|
|
242
243
|
);
|
|
@@ -254,7 +255,11 @@ export async function importExecutionPayload(
|
|
|
254
255
|
}
|
|
255
256
|
|
|
256
257
|
// 8. Record metrics for payload envelope and column sources
|
|
257
|
-
this.
|
|
258
|
+
const delaySec = this.clock.secFromSlot(slot);
|
|
259
|
+
this.metrics?.importPayload.elapsedTimeTillImported.observe(
|
|
260
|
+
{source: payloadInput.getPayloadEnvelopeSource().source},
|
|
261
|
+
delaySec
|
|
262
|
+
);
|
|
258
263
|
for (const {source} of payloadInput.getSampledColumnsWithSource()) {
|
|
259
264
|
this.metrics?.importPayload.columnsBySource.inc({source});
|
|
260
265
|
}
|
|
@@ -275,6 +280,7 @@ export async function importExecutionPayload(
|
|
|
275
280
|
builderIndex: envelope.builderIndex,
|
|
276
281
|
blockRoot: blockRootHex,
|
|
277
282
|
blockHash: blockHashHex,
|
|
283
|
+
delaySec,
|
|
278
284
|
});
|
|
279
285
|
}
|
|
280
286
|
|
|
@@ -61,10 +61,8 @@ export function verifyExecutionPayloadEnvelope(
|
|
|
61
61
|
`Prev randao mismatch between bid and payload bid=${toHex(bid.prevRandao)} payload=${toHex(payload.prevRandao)}`
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
|
-
if (
|
|
65
|
-
throw new Error(
|
|
66
|
-
`Gas limit mismatch between payload and bid payload=${payload.gasLimit} bid=${Number(bid.gasLimit)}`
|
|
67
|
-
);
|
|
64
|
+
if (bid.gasLimit !== payload.gasLimit) {
|
|
65
|
+
throw new Error(`Gas limit mismatch between payload and bid payload=${payload.gasLimit} bid=${bid.gasLimit}`);
|
|
68
66
|
}
|
|
69
67
|
if (!byteArrayEquals(bid.blockHash, payload.blockHash)) {
|
|
70
68
|
throw new Error(
|
|
@@ -74,7 +72,7 @@ export function verifyExecutionPayloadEnvelope(
|
|
|
74
72
|
// Verify execution_requests_root matches bid commitment.
|
|
75
73
|
// Can be skipped if already verified during gossip validation.
|
|
76
74
|
if (verifyExecutionRequestsRoot) {
|
|
77
|
-
const requestsRoot = ssz.
|
|
75
|
+
const requestsRoot = ssz.gloas.ExecutionRequests.hashTreeRoot(envelope.executionRequests);
|
|
78
76
|
if (!byteArrayEquals(requestsRoot, bid.executionRequestsRoot)) {
|
|
79
77
|
throw new Error(
|
|
80
78
|
`Execution requests root mismatch envelope=${toRootHex(requestsRoot)} bid=${toRootHex(bid.executionRequestsRoot)}`
|
package/src/chain/chain.ts
CHANGED
|
@@ -2,7 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
import {PrivateKey} from "@libp2p/interface";
|
|
3
3
|
import {Type} from "@chainsafe/ssz";
|
|
4
4
|
import {BeaconConfig} from "@lodestar/config";
|
|
5
|
-
import {CheckpointWithHex, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
|
|
5
|
+
import {CheckpointWithHex, ForkChoiceStateGetter, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
|
|
6
6
|
import {LoggerNode} from "@lodestar/logger/node";
|
|
7
7
|
import {
|
|
8
8
|
EFFECTIVE_BALANCE_INCREMENT,
|
|
@@ -40,7 +40,6 @@ import {
|
|
|
40
40
|
ValidatorIndex,
|
|
41
41
|
Wei,
|
|
42
42
|
deneb,
|
|
43
|
-
electra,
|
|
44
43
|
gloas,
|
|
45
44
|
isBlindedBeaconBlock,
|
|
46
45
|
phase0,
|
|
@@ -382,6 +381,14 @@ export class BeaconChain implements IBeaconChain {
|
|
|
382
381
|
blockStateCache.setHeadState(anchorState);
|
|
383
382
|
checkpointStateCache.add(checkpoint, anchorState);
|
|
384
383
|
|
|
384
|
+
const forkChoiceStateGetter: ForkChoiceStateGetter = ({stateRoot, checkpoint}) => {
|
|
385
|
+
if (stateRoot) return blockStateCache.get(stateRoot);
|
|
386
|
+
|
|
387
|
+
if (checkpoint) return checkpointStateCache.get({epoch: checkpoint.epoch, rootHex: checkpoint.rootHex});
|
|
388
|
+
|
|
389
|
+
return null;
|
|
390
|
+
};
|
|
391
|
+
|
|
385
392
|
const forkChoice = initializeForkChoice(
|
|
386
393
|
config,
|
|
387
394
|
emitter,
|
|
@@ -390,6 +397,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
390
397
|
isAnchorStateFinalized,
|
|
391
398
|
opts,
|
|
392
399
|
this.justifiedBalancesGetter.bind(this),
|
|
400
|
+
forkChoiceStateGetter,
|
|
393
401
|
metrics,
|
|
394
402
|
logger
|
|
395
403
|
);
|
|
@@ -916,10 +924,10 @@ export class BeaconChain implements IBeaconChain {
|
|
|
916
924
|
async getParentExecutionRequests(
|
|
917
925
|
parentBlockSlot: Slot,
|
|
918
926
|
parentBlockRootHex: RootHex
|
|
919
|
-
): Promise<
|
|
927
|
+
): Promise<gloas.ExecutionRequests> {
|
|
920
928
|
// at the fork boundary, parent is pre-gloas
|
|
921
929
|
if (!isForkPostGloas(this.config.getForkName(parentBlockSlot))) {
|
|
922
|
-
return ssz.
|
|
930
|
+
return ssz.gloas.ExecutionRequests.defaultValue();
|
|
923
931
|
}
|
|
924
932
|
const envelope = await this.getExecutionPayloadEnvelope(parentBlockSlot, parentBlockRootHex);
|
|
925
933
|
if (envelope === null) {
|
|
@@ -1049,6 +1057,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1049
1057
|
feeRecipient,
|
|
1050
1058
|
commonBlockBodyPromise,
|
|
1051
1059
|
parentBlock,
|
|
1060
|
+
builderBid,
|
|
1052
1061
|
}: BlockAttributes & {commonBlockBodyPromise: Promise<CommonBlockBody>}
|
|
1053
1062
|
): Promise<{
|
|
1054
1063
|
block: AssembledBlockType<T>;
|
|
@@ -1078,6 +1087,7 @@ export class BeaconChain implements IBeaconChain {
|
|
|
1078
1087
|
proposerIndex,
|
|
1079
1088
|
proposerPubKey,
|
|
1080
1089
|
commonBlockBodyPromise,
|
|
1090
|
+
builderBid,
|
|
1081
1091
|
}
|
|
1082
1092
|
);
|
|
1083
1093
|
|
package/src/chain/emitter.ts
CHANGED
|
@@ -3,7 +3,7 @@ import {StrictEventEmitter} from "strict-event-emitter-types";
|
|
|
3
3
|
import {routes} from "@lodestar/api";
|
|
4
4
|
import {CheckpointWithHex} from "@lodestar/fork-choice";
|
|
5
5
|
import {IBeaconStateView} from "@lodestar/state-transition";
|
|
6
|
-
import {DataColumnSidecar, RootHex, deneb, phase0} from "@lodestar/types";
|
|
6
|
+
import {DataColumnSidecar, RootHex, Slot, deneb, phase0} from "@lodestar/types";
|
|
7
7
|
import {PeerIdStr} from "../util/peerId.js";
|
|
8
8
|
import {BlockInputSource, IBlockInput} from "./blocks/blockInput/types.js";
|
|
9
9
|
import {PayloadEnvelopeInput} from "./blocks/payloadEnvelopeInput/payloadEnvelopeInput.js";
|
|
@@ -94,7 +94,8 @@ export type ChainEventData = {
|
|
|
94
94
|
peer: PeerIdStr;
|
|
95
95
|
source: BlockInputSource;
|
|
96
96
|
};
|
|
97
|
-
|
|
97
|
+
// slot is the message slot, not necessarily the envelope's slot, but useful as a logging/prune hint
|
|
98
|
+
[ChainEvent.unknownEnvelopeBlockRoot]: {rootHex: RootHex; slot: Slot; peer?: PeerIdStr; source: BlockInputSource};
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
export type IChainEvents = ApiEvents & {
|
|
@@ -61,9 +61,6 @@ export enum BlockErrorCode {
|
|
|
61
61
|
TRANSACTIONS_TOO_BIG = "BLOCK_ERROR_TRANSACTIONS_TOO_BIG",
|
|
62
62
|
/** Execution engine is unavailable, syncing, or api call errored. Peers must not be downscored on this code */
|
|
63
63
|
EXECUTION_ENGINE_ERROR = "BLOCK_ERROR_EXECUTION_ERROR",
|
|
64
|
-
/** The attestation head block is too far behind the attestation slot, causing many skip slots.
|
|
65
|
-
This is deemed a DoS risk */
|
|
66
|
-
TOO_MANY_SKIPPED_SLOTS = "TOO_MANY_SKIPPED_SLOTS",
|
|
67
64
|
/** The blobs are unavailable */
|
|
68
65
|
DATA_UNAVAILABLE = "BLOCK_ERROR_DATA_UNAVAILABLE",
|
|
69
66
|
/** Block contains too many kzg commitments */
|
|
@@ -89,7 +86,6 @@ export type BlockErrorType =
|
|
|
89
86
|
| {code: BlockErrorCode.FUTURE_SLOT; blockSlot: Slot; currentSlot: Slot}
|
|
90
87
|
| {code: BlockErrorCode.STATE_ROOT_MISMATCH}
|
|
91
88
|
| {code: BlockErrorCode.GENESIS_BLOCK}
|
|
92
|
-
| {code: BlockErrorCode.TOO_MANY_SKIPPED_SLOTS; parentSlot: Slot; blockSlot: Slot}
|
|
93
89
|
| {code: BlockErrorCode.WOULD_REVERT_FINALIZED_SLOT; blockSlot: Slot; finalizedSlot: Slot}
|
|
94
90
|
| {code: BlockErrorCode.ALREADY_KNOWN; root: RootHex}
|
|
95
91
|
| {code: BlockErrorCode.REPEAT_PROPOSAL; proposerIndex: ValidatorIndex}
|
|
@@ -3,13 +3,17 @@ import {GossipActionError} from "./gossipValidation.js";
|
|
|
3
3
|
|
|
4
4
|
export enum ExecutionPayloadBidErrorCode {
|
|
5
5
|
BUILDER_NOT_ELIGIBLE = "EXECUTION_PAYLOAD_BID_ERROR_BUILDER_NOT_ELIGIBLE",
|
|
6
|
+
INVALID_BUILDER_VERSION = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_BUILDER_VERSION",
|
|
6
7
|
NON_ZERO_EXECUTION_PAYMENT = "EXECUTION_PAYLOAD_BID_ERROR_NON_ZERO_EXECUTION_PAYMENT",
|
|
7
8
|
BID_ALREADY_KNOWN = "EXECUTION_PAYLOAD_BID_ERROR_BID_ALREADY_KNOWN",
|
|
8
9
|
BID_TOO_LOW = "EXECUTION_PAYLOAD_BID_ERROR_BID_TOO_LOW",
|
|
9
10
|
BID_TOO_HIGH = "EXECUTION_PAYLOAD_BID_ERROR_BID_TOO_HIGH",
|
|
10
11
|
TOO_MANY_KZG_COMMITMENTS = "EXECUTION_PAYLOAD_BID_ERROR_TOO_MANY_KZG_COMMITMENTS",
|
|
11
12
|
UNKNOWN_BLOCK_ROOT = "EXECUTION_PAYLOAD_BID_ERROR_UNKNOWN_BLOCK_ROOT",
|
|
13
|
+
UNKNOWN_PARENT_BLOCK_HASH = "EXECUTION_PAYLOAD_BID_ERROR_UNKNOWN_PARENT_BLOCK_HASH",
|
|
12
14
|
INVALID_SLOT = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_SLOT",
|
|
15
|
+
NOT_LATER_THAN_PARENT = "EXECUTION_PAYLOAD_BID_ERROR_NOT_LATER_THAN_PARENT",
|
|
16
|
+
INVALID_PREV_RANDAO = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_PREV_RANDAO",
|
|
13
17
|
INVALID_SIGNATURE = "EXECUTION_PAYLOAD_BID_ERROR_INVALID_SIGNATURE",
|
|
14
18
|
NO_MATCHING_PROPOSER_PREFERENCES = "EXECUTION_PAYLOAD_BID_ERROR_NO_MATCHING_PROPOSER_PREFERENCES",
|
|
15
19
|
PROPOSER_PREFERENCES_FEE_RECIPIENT_MISMATCH = "EXECUTION_PAYLOAD_BID_ERROR_PROPOSER_PREFERENCES_FEE_RECIPIENT_MISMATCH",
|
|
@@ -18,6 +22,12 @@ export enum ExecutionPayloadBidErrorCode {
|
|
|
18
22
|
|
|
19
23
|
export type ExecutionPayloadBidErrorType =
|
|
20
24
|
| {code: ExecutionPayloadBidErrorCode.BUILDER_NOT_ELIGIBLE; builderIndex: BuilderIndex}
|
|
25
|
+
| {
|
|
26
|
+
code: ExecutionPayloadBidErrorCode.INVALID_BUILDER_VERSION;
|
|
27
|
+
builderIndex: BuilderIndex;
|
|
28
|
+
version: number;
|
|
29
|
+
expectedVersion: number;
|
|
30
|
+
}
|
|
21
31
|
| {
|
|
22
32
|
code: ExecutionPayloadBidErrorCode.NON_ZERO_EXECUTION_PAYMENT;
|
|
23
33
|
builderIndex: BuilderIndex;
|
|
@@ -38,7 +48,15 @@ export type ExecutionPayloadBidErrorType =
|
|
|
38
48
|
commitmentLimit: number;
|
|
39
49
|
}
|
|
40
50
|
| {code: ExecutionPayloadBidErrorCode.UNKNOWN_BLOCK_ROOT; parentBlockRoot: RootHex}
|
|
51
|
+
| {code: ExecutionPayloadBidErrorCode.UNKNOWN_PARENT_BLOCK_HASH; parentBlockHash: RootHex}
|
|
41
52
|
| {code: ExecutionPayloadBidErrorCode.INVALID_SLOT; builderIndex: BuilderIndex; slot: Slot}
|
|
53
|
+
| {code: ExecutionPayloadBidErrorCode.NOT_LATER_THAN_PARENT; parentSlot: Slot; slot: Slot}
|
|
54
|
+
| {
|
|
55
|
+
code: ExecutionPayloadBidErrorCode.INVALID_PREV_RANDAO;
|
|
56
|
+
builderIndex: BuilderIndex;
|
|
57
|
+
bidPrevRandao: string;
|
|
58
|
+
expectedPrevRandao: string;
|
|
59
|
+
}
|
|
42
60
|
| {code: ExecutionPayloadBidErrorCode.INVALID_SIGNATURE; builderIndex: BuilderIndex; slot: Slot}
|
|
43
61
|
| {
|
|
44
62
|
code: ExecutionPayloadBidErrorCode.NO_MATCHING_PROPOSER_PREFERENCES;
|
|
@@ -56,7 +74,8 @@ export type ExecutionPayloadBidErrorType =
|
|
|
56
74
|
code: ExecutionPayloadBidErrorCode.PROPOSER_PREFERENCES_GAS_LIMIT_MISMATCH;
|
|
57
75
|
builderIndex: BuilderIndex;
|
|
58
76
|
bidGasLimit: number;
|
|
59
|
-
|
|
77
|
+
parentGasLimit: number;
|
|
78
|
+
targetGasLimit: number;
|
|
60
79
|
};
|
|
61
80
|
|
|
62
81
|
export class ExecutionPayloadBidError extends GossipActionError<ExecutionPayloadBidErrorType> {}
|
|
@@ -5,6 +5,7 @@ export enum PayloadAttestationErrorCode {
|
|
|
5
5
|
NOT_CURRENT_SLOT = "PAYLOAD_ATTESTATION_ERROR_NOT_CURRENT_SLOT",
|
|
6
6
|
PAYLOAD_ATTESTATION_ALREADY_KNOWN = "PAYLOAD_ATTESTATION_ERROR_PAYLOAD_ATTESTATION_ALREADY_KNOWN",
|
|
7
7
|
UNKNOWN_BLOCK_ROOT = "PAYLOAD_ATTESTATION_ERROR_UNKNOWN_BLOCK_ROOT",
|
|
8
|
+
INVALID_BLOCK_SLOT = "PAYLOAD_ATTESTATION_ERROR_INVALID_BLOCK_SLOT",
|
|
8
9
|
INVALID_BLOCK = "PAYLOAD_ATTESTATION_ERROR_INVALID_BLOCK",
|
|
9
10
|
INVALID_ATTESTER = "PAYLOAD_ATTESTATION_ERROR_INVALID_ATTESTER",
|
|
10
11
|
INVALID_SIGNATURE = "PAYLOAD_ATTESTATION_ERROR_INVALID_SIGNATURE",
|
|
@@ -18,6 +19,7 @@ export type PayloadAttestationErrorType =
|
|
|
18
19
|
blockRoot: RootHex;
|
|
19
20
|
}
|
|
20
21
|
| {code: PayloadAttestationErrorCode.UNKNOWN_BLOCK_ROOT; blockRoot: RootHex}
|
|
22
|
+
| {code: PayloadAttestationErrorCode.INVALID_BLOCK_SLOT; blockRoot: RootHex; blockSlot: Slot; slot: Slot}
|
|
21
23
|
| {code: PayloadAttestationErrorCode.INVALID_BLOCK; blockRoot: RootHex}
|
|
22
24
|
| {code: PayloadAttestationErrorCode.INVALID_ATTESTER; attesterIndex: ValidatorIndex}
|
|
23
25
|
| {code: PayloadAttestationErrorCode.INVALID_SIGNATURE};
|