@lodestar/beacon-node 1.47.0-dev.f591cb177e → 1.48.0-dev.67344272c0
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 +44 -12
- 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 +21 -2
- package/lib/api/impl/beacon/pool/index.js.map +1 -1
- package/lib/api/impl/beacon/state/utils.d.ts +2 -1
- 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/events/index.d.ts.map +1 -1
- package/lib/api/impl/events/index.js +2 -0
- package/lib/api/impl/events/index.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 +237 -49
- package/lib/api/impl/validator/index.js.map +1 -1
- package/lib/api/impl/validator/utils.js +1 -1
- package/lib/api/impl/validator/utils.js.map +1 -1
- package/lib/api/rest/base.d.ts.map +1 -1
- package/lib/api/rest/base.js +7 -0
- package/lib/api/rest/base.js.map +1 -1
- package/lib/chain/archiveStore/archiveStore.js +1 -1
- package/lib/chain/archiveStore/archiveStore.js.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.d.ts +3 -2
- package/lib/chain/blocks/importExecutionPayload.d.ts.map +1 -1
- package/lib/chain/blocks/importExecutionPayload.js +11 -9
- package/lib/chain/blocks/importExecutionPayload.js.map +1 -1
- package/lib/chain/blocks/index.d.ts.map +1 -1
- package/lib/chain/blocks/index.js +21 -13
- package/lib/chain/blocks/index.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts +2 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js +6 -2
- package/lib/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.js.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts +14 -5
- package/lib/chain/blocks/payloadEnvelopeInput/types.d.ts.map +1 -1
- package/lib/chain/blocks/payloadEnvelopeInput/types.js +5 -0
- package/lib/chain/blocks/payloadEnvelopeInput/types.js.map +1 -1
- package/lib/chain/blocks/verifyBlock.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlock.js +5 -2
- package/lib/chain/blocks/verifyBlock.js.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.d.ts.map +1 -1
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js +22 -12
- package/lib/chain/blocks/verifyBlocksStateTransitionOnly.js.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.d.ts.map +1 -1
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js +2 -2
- package/lib/chain/blocks/verifyExecutionPayloadEnvelope.js.map +1 -1
- package/lib/chain/bls/index.d.ts +1 -1
- package/lib/chain/bls/index.d.ts.map +1 -1
- package/lib/chain/bls/interface.d.ts +5 -5
- package/lib/chain/bls/interface.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.d.ts +5 -11
- package/lib/chain/bls/multithread/index.d.ts.map +1 -1
- package/lib/chain/bls/multithread/index.js +116 -101
- package/lib/chain/bls/multithread/index.js.map +1 -1
- package/lib/chain/bls/multithread/jobItem.d.ts +5 -19
- package/lib/chain/bls/multithread/jobItem.d.ts.map +1 -1
- package/lib/chain/bls/multithread/jobItem.js +10 -65
- package/lib/chain/bls/multithread/jobItem.js.map +1 -1
- package/lib/chain/bls/multithread/types.d.ts +29 -8
- package/lib/chain/bls/multithread/types.d.ts.map +1 -1
- package/lib/chain/bls/multithread/types.js +12 -0
- package/lib/chain/bls/multithread/types.js.map +1 -1
- package/lib/chain/bls/multithread/utils.d.ts +4 -0
- package/lib/chain/bls/multithread/utils.d.ts.map +1 -1
- package/lib/chain/bls/multithread/utils.js +10 -0
- package/lib/chain/bls/multithread/utils.js.map +1 -1
- package/lib/chain/bls/multithread/worker.js +49 -23
- package/lib/chain/bls/multithread/worker.js.map +1 -1
- package/lib/chain/bls/singleThread.d.ts +4 -10
- package/lib/chain/bls/singleThread.d.ts.map +1 -1
- package/lib/chain/bls/singleThread.js +8 -45
- package/lib/chain/bls/singleThread.js.map +1 -1
- package/lib/chain/bls/utils.d.ts +4 -4
- package/lib/chain/bls/utils.d.ts.map +1 -1
- package/lib/chain/bls/utils.js +18 -19
- package/lib/chain/bls/utils.js.map +1 -1
- package/lib/chain/chain.d.ts +9 -4
- package/lib/chain/chain.d.ts.map +1 -1
- package/lib/chain/chain.js +22 -8
- package/lib/chain/chain.js.map +1 -1
- package/lib/chain/errors/blockError.d.ts +1 -0
- package/lib/chain/errors/blockError.d.ts.map +1 -1
- package/lib/chain/errors/blockError.js +6 -1
- 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/forkChoice/index.d.ts.map +1 -1
- package/lib/chain/forkChoice/index.js +4 -0
- package/lib/chain/forkChoice/index.js.map +1 -1
- package/lib/chain/interface.d.ts +8 -4
- package/lib/chain/interface.d.ts.map +1 -1
- package/lib/chain/interface.js.map +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js +1 -1
- package/lib/chain/opPools/aggregatedAttestationPool.js.map +1 -1
- package/lib/chain/opPools/attestationPool.d.ts +1 -1
- package/lib/chain/opPools/attestationPool.d.ts.map +1 -1
- package/lib/chain/opPools/attestationPool.js +1 -1
- package/lib/chain/opPools/attestationPool.js.map +1 -1
- package/lib/chain/opPools/deferredVoluntaryExitPool.d.ts +16 -0
- package/lib/chain/opPools/deferredVoluntaryExitPool.d.ts.map +1 -0
- package/lib/chain/opPools/deferredVoluntaryExitPool.js +57 -0
- package/lib/chain/opPools/deferredVoluntaryExitPool.js.map +1 -0
- package/lib/chain/opPools/executionPayloadBidPool.d.ts +7 -2
- package/lib/chain/opPools/executionPayloadBidPool.d.ts.map +1 -1
- package/lib/chain/opPools/executionPayloadBidPool.js +4 -4
- package/lib/chain/opPools/executionPayloadBidPool.js.map +1 -1
- package/lib/chain/opPools/index.d.ts +2 -1
- package/lib/chain/opPools/index.d.ts.map +1 -1
- package/lib/chain/opPools/index.js +1 -0
- package/lib/chain/opPools/index.js.map +1 -1
- package/lib/chain/opPools/payloadAttestationPool.js +3 -3
- package/lib/chain/opPools/payloadAttestationPool.js.map +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js +1 -1
- package/lib/chain/opPools/syncCommitteeMessagePool.js.map +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js +1 -1
- package/lib/chain/opPools/syncContributionAndProofPool.js.map +1 -1
- package/lib/chain/opPools/utils.d.ts +1 -1
- package/lib/chain/opPools/utils.d.ts.map +1 -1
- package/lib/chain/opPools/utils.js +1 -1
- package/lib/chain/opPools/utils.js.map +1 -1
- package/lib/chain/prepareNextSlot.d.ts +5 -0
- package/lib/chain/prepareNextSlot.d.ts.map +1 -1
- package/lib/chain/prepareNextSlot.js +47 -6
- package/lib/chain/prepareNextSlot.js.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.d.ts.map +1 -1
- package/lib/chain/produceBlock/computeNewStateRoot.js +3 -25
- package/lib/chain/produceBlock/computeNewStateRoot.js.map +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js +1 -1
- package/lib/chain/produceBlock/produceBlockBody.js.map +1 -1
- package/lib/chain/regen/interface.d.ts +5 -2
- package/lib/chain/regen/interface.d.ts.map +1 -1
- package/lib/chain/regen/interface.js +3 -0
- package/lib/chain/regen/interface.js.map +1 -1
- package/lib/chain/regen/queued.d.ts +2 -2
- package/lib/chain/regen/queued.d.ts.map +1 -1
- package/lib/chain/regen/queued.js +5 -5
- package/lib/chain/regen/queued.js.map +1 -1
- package/lib/chain/seenCache/seenAttesters.d.ts +9 -5
- package/lib/chain/seenCache/seenAttesters.d.ts.map +1 -1
- package/lib/chain/seenCache/seenAttesters.js +25 -4
- package/lib/chain/seenCache/seenAttesters.js.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts +28 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.d.ts.map +1 -1
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js +121 -13
- package/lib/chain/seenCache/seenPayloadEnvelopeInput.js.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts +5 -1
- package/lib/chain/stateCache/fifoBlockStateCache.d.ts.map +1 -1
- package/lib/chain/stateCache/fifoBlockStateCache.js +6 -0
- package/lib/chain/stateCache/fifoBlockStateCache.js.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts +47 -5
- package/lib/chain/stateCache/persistentCheckpointsCache.d.ts.map +1 -1
- package/lib/chain/stateCache/persistentCheckpointsCache.js +117 -7
- package/lib/chain/stateCache/persistentCheckpointsCache.js.map +1 -1
- package/lib/chain/stateCache/types.d.ts +3 -3
- package/lib/chain/stateCache/types.d.ts.map +1 -1
- package/lib/chain/validation/attestation.d.ts.map +1 -1
- package/lib/chain/validation/attestation.js +1 -4
- package/lib/chain/validation/attestation.js.map +1 -1
- package/lib/chain/validation/attesterSlashing.d.ts.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.d.ts.map +1 -1
- package/lib/chain/validation/block.js +40 -10
- package/lib/chain/validation/block.js.map +1 -1
- package/lib/chain/validation/executionPayloadBid.d.ts +15 -3
- package/lib/chain/validation/executionPayloadBid.d.ts.map +1 -1
- package/lib/chain/validation/executionPayloadBid.js +166 -12
- package/lib/chain/validation/executionPayloadBid.js.map +1 -1
- package/lib/chain/validation/executionPayloadEnvelope.js +1 -1
- 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 +5 -14
- package/lib/chain/validation/payloadAttestationMessage.js.map +1 -1
- package/lib/chain/validation/proposerPreferences.js +2 -2
- package/lib/chain/validation/proposerPreferences.js.map +1 -1
- package/lib/chain/validation/proposerSlashing.js +1 -1
- package/lib/chain/validation/proposerSlashing.js.map +1 -1
- package/lib/chain/validation/voluntaryExit.d.ts +9 -1
- package/lib/chain/validation/voluntaryExit.d.ts.map +1 -1
- package/lib/chain/validation/voluntaryExit.js +46 -1
- package/lib/chain/validation/voluntaryExit.js.map +1 -1
- package/lib/execution/builder/apiClient.d.ts +70 -0
- package/lib/execution/builder/apiClient.d.ts.map +1 -0
- package/lib/execution/builder/apiClient.js +202 -0
- package/lib/execution/builder/apiClient.js.map +1 -0
- package/lib/execution/builder/validateBid.d.ts +23 -0
- package/lib/execution/builder/validateBid.d.ts.map +1 -0
- package/lib/execution/builder/validateBid.js +119 -0
- package/lib/execution/builder/validateBid.js.map +1 -0
- package/lib/metrics/metrics/lodestar.d.ts +84 -23
- package/lib/metrics/metrics/lodestar.d.ts.map +1 -1
- package/lib/metrics/metrics/lodestar.js +161 -55
- package/lib/metrics/metrics/lodestar.js.map +1 -1
- package/lib/network/gossip/topic.d.ts +13 -0
- package/lib/network/gossip/topic.d.ts.map +1 -1
- package/lib/network/gossip/topic.js +37 -0
- package/lib/network/gossip/topic.js.map +1 -1
- package/lib/network/network.d.ts.map +1 -1
- package/lib/network/network.js +23 -43
- package/lib/network/network.js.map +1 -1
- package/lib/network/processor/constants.d.ts +7 -0
- package/lib/network/processor/constants.d.ts.map +1 -0
- package/lib/network/processor/constants.js +7 -0
- package/lib/network/processor/constants.js.map +1 -0
- package/lib/network/processor/gossipHandlers.d.ts.map +1 -1
- package/lib/network/processor/gossipHandlers.js +6 -2
- package/lib/network/processor/gossipHandlers.js.map +1 -1
- package/lib/network/processor/gossipQueues/indexed.d.ts.map +1 -1
- package/lib/network/processor/gossipQueues/indexed.js +0 -1
- package/lib/network/processor/gossipQueues/indexed.js.map +1 -1
- package/lib/network/processor/index.d.ts +3 -0
- package/lib/network/processor/index.d.ts.map +1 -1
- package/lib/network/processor/index.js +52 -23
- package/lib/network/processor/index.js.map +1 -1
- package/lib/network/reqresp/score.d.ts.map +1 -1
- package/lib/network/reqresp/score.js +5 -11
- package/lib/network/reqresp/score.js.map +1 -1
- package/lib/network/util.d.ts +0 -1
- package/lib/network/util.d.ts.map +1 -1
- package/lib/network/util.js +0 -4
- package/lib/network/util.js.map +1 -1
- package/lib/node/deferredVoluntaryExitPublisher.d.ts +15 -0
- package/lib/node/deferredVoluntaryExitPublisher.d.ts.map +1 -0
- package/lib/node/deferredVoluntaryExitPublisher.js +38 -0
- package/lib/node/deferredVoluntaryExitPublisher.js.map +1 -0
- package/lib/node/nodejs.d.ts +2 -1
- package/lib/node/nodejs.d.ts.map +1 -1
- package/lib/node/nodejs.js +7 -0
- package/lib/node/nodejs.js.map +1 -1
- package/lib/sync/range/batch.d.ts +23 -5
- package/lib/sync/range/batch.d.ts.map +1 -1
- package/lib/sync/range/batch.js +61 -22
- package/lib/sync/range/batch.js.map +1 -1
- package/lib/sync/range/chain.d.ts +2 -1
- package/lib/sync/range/chain.d.ts.map +1 -1
- package/lib/sync/range/chain.js +32 -12
- package/lib/sync/range/chain.js.map +1 -1
- package/lib/sync/range/range.js +1 -1
- package/lib/sync/range/range.js.map +1 -1
- package/lib/sync/types.d.ts +32 -0
- package/lib/sync/types.d.ts.map +1 -1
- package/lib/sync/types.js +33 -0
- package/lib/sync/types.js.map +1 -1
- package/lib/sync/unknownBlock.d.ts +6 -2
- package/lib/sync/unknownBlock.d.ts.map +1 -1
- package/lib/sync/unknownBlock.js +143 -68
- package/lib/sync/unknownBlock.js.map +1 -1
- package/lib/sync/utils/downloadByRange.d.ts.map +1 -1
- package/lib/sync/utils/downloadByRange.js +16 -11
- 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 +3 -1
- package/lib/sync/utils/downloadByRoot.js.map +1 -1
- package/package.json +35 -35
- package/src/api/impl/beacon/blocks/index.ts +51 -15
- package/src/api/impl/beacon/pool/index.ts +22 -2
- package/src/api/impl/beacon/state/utils.ts +2 -1
- package/src/api/impl/events/index.ts +3 -1
- package/src/api/impl/lodestar/index.ts +1 -1
- package/src/api/impl/validator/index.ts +290 -49
- package/src/api/impl/validator/utils.ts +1 -1
- package/src/api/rest/base.ts +7 -0
- package/src/chain/archiveStore/archiveStore.ts +1 -1
- package/src/chain/blocks/importExecutionPayload.ts +12 -11
- package/src/chain/blocks/index.ts +25 -13
- package/src/chain/blocks/payloadEnvelopeInput/payloadEnvelopeInput.ts +8 -2
- package/src/chain/blocks/payloadEnvelopeInput/types.ts +17 -4
- package/src/chain/blocks/verifyBlock.ts +5 -2
- package/src/chain/blocks/verifyBlocksStateTransitionOnly.ts +25 -16
- package/src/chain/blocks/verifyExecutionPayloadEnvelope.ts +1 -9
- package/src/chain/bls/index.ts +1 -1
- package/src/chain/bls/interface.ts +7 -3
- package/src/chain/bls/multithread/index.ts +148 -120
- package/src/chain/bls/multithread/jobItem.ts +12 -82
- package/src/chain/bls/multithread/types.ts +33 -8
- package/src/chain/bls/multithread/utils.ts +11 -0
- package/src/chain/bls/multithread/worker.ts +85 -27
- package/src/chain/bls/singleThread.ts +11 -55
- package/src/chain/bls/utils.ts +23 -24
- package/src/chain/chain.ts +25 -7
- package/src/chain/errors/blockError.ts +8 -2
- package/src/chain/errors/executionPayloadBid.ts +6 -0
- package/src/chain/forkChoice/index.ts +4 -0
- package/src/chain/interface.ts +8 -3
- package/src/chain/opPools/aggregatedAttestationPool.ts +1 -1
- package/src/chain/opPools/attestationPool.ts +1 -1
- package/src/chain/opPools/deferredVoluntaryExitPool.ts +65 -0
- package/src/chain/opPools/executionPayloadBidPool.ts +13 -7
- package/src/chain/opPools/index.ts +2 -1
- package/src/chain/opPools/payloadAttestationPool.ts +3 -3
- package/src/chain/opPools/syncCommitteeMessagePool.ts +1 -1
- package/src/chain/opPools/syncContributionAndProofPool.ts +1 -1
- package/src/chain/opPools/utils.ts +1 -1
- package/src/chain/prepareNextSlot.ts +49 -6
- package/src/chain/produceBlock/computeNewStateRoot.ts +3 -38
- package/src/chain/produceBlock/produceBlockBody.ts +1 -1
- package/src/chain/regen/interface.ts +5 -2
- package/src/chain/regen/queued.ts +5 -5
- package/src/chain/seenCache/seenAttesters.ts +31 -5
- package/src/chain/seenCache/seenPayloadEnvelopeInput.ts +143 -14
- package/src/chain/stateCache/fifoBlockStateCache.ts +8 -1
- package/src/chain/stateCache/persistentCheckpointsCache.ts +133 -8
- package/src/chain/stateCache/types.ts +3 -3
- package/src/chain/validation/attestation.ts +1 -7
- package/src/chain/validation/attesterSlashing.ts +1 -8
- package/src/chain/validation/block.ts +43 -10
- package/src/chain/validation/executionPayloadBid.ts +193 -14
- package/src/chain/validation/executionPayloadEnvelope.ts +0 -1
- package/src/chain/validation/payloadAttestationMessage.ts +6 -17
- package/src/chain/validation/proposerPreferences.ts +3 -3
- package/src/chain/validation/proposerSlashing.ts +1 -1
- package/src/chain/validation/voluntaryExit.ts +59 -2
- package/src/execution/builder/apiClient.ts +264 -0
- package/src/execution/builder/validateBid.ts +181 -0
- package/src/metrics/metrics/lodestar.ts +176 -61
- package/src/network/gossip/topic.ts +38 -0
- package/src/network/network.ts +29 -54
- package/src/network/processor/constants.ts +6 -0
- package/src/network/processor/gossipHandlers.ts +6 -2
- package/src/network/processor/gossipQueues/indexed.ts +0 -1
- package/src/network/processor/index.ts +67 -30
- package/src/network/reqresp/score.ts +5 -11
- package/src/network/util.ts +0 -5
- package/src/node/deferredVoluntaryExitPublisher.ts +54 -0
- package/src/node/nodejs.ts +10 -1
- package/src/sync/range/batch.ts +83 -28
- package/src/sync/range/chain.ts +35 -13
- package/src/sync/range/range.ts +1 -1
- package/src/sync/types.ts +33 -0
- package/src/sync/unknownBlock.ts +167 -73
- package/src/sync/utils/downloadByRange.ts +21 -12
- package/src/sync/utils/downloadByRoot.ts +3 -1
- package/lib/chain/bls/maybeBatch.d.ts +0 -12
- package/lib/chain/bls/maybeBatch.d.ts.map +0 -1
- package/lib/chain/bls/maybeBatch.js +0 -35
- package/lib/chain/bls/maybeBatch.js.map +0 -1
- package/src/chain/bls/maybeBatch.ts +0 -45
|
@@ -3,7 +3,7 @@ import { ExecutionStatus, PayloadStatus } from "@lodestar/fork-choice";
|
|
|
3
3
|
import { BUILDER_INDEX_SELF_BUILD, ForkName, ForkSeq, GENESIS_SLOT, SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT, SYNC_COMMITTEE_SUBNET_SIZE, isForkPostBellatrix, isForkPostDeneb, isForkPostElectra, isForkPostFulu, isForkPostGloas, } from "@lodestar/params";
|
|
4
4
|
import { DataAvailabilityStatus, beaconBlockToBlinded, calculateCommitteeAssignments, computeEpochAtSlot, computeStartSlotAtEpoch, computeTimeAtSlot, getCurrentSlot, isStatePostAltair, isStatePostGloas, proposerShufflingDecisionRoot, } from "@lodestar/state-transition";
|
|
5
5
|
import { ProducedBlockSource, getValidatorStatus, ssz, } from "@lodestar/types";
|
|
6
|
-
import { GWEI_TO_WEI, TimeoutError, defer, formatWeiToEth, fromHex, prettyWeiToEth, resolveOrRacePromises, toHex, toRootHex, } from "@lodestar/utils";
|
|
6
|
+
import { GWEI_TO_WEI, TimeoutError, byteArrayEquals, defer, formatWeiToEth, fromHex, prettyGweiToEth, prettyWeiToEth, resolveOrRacePromises, sleep, toHex, toPrintableUrl, toRootHex, } from "@lodestar/utils";
|
|
7
7
|
import { MAX_BUILDER_BOOST_FACTOR } from "@lodestar/validator";
|
|
8
8
|
import { BlockInputSource } from "../../../chain/blocks/blockInput/types.js";
|
|
9
9
|
import { AttestationError, AttestationErrorCode, GossipAction, ProposerPreferencesError, ProposerPreferencesErrorCode, SyncCommitteeError, SyncCommitteeErrorCode, } from "../../../chain/errors/index.js";
|
|
@@ -15,7 +15,9 @@ import { validateApiAggregateAndProof } from "../../../chain/validation/index.js
|
|
|
15
15
|
import { validateGossipProposerPreferences } from "../../../chain/validation/proposerPreferences.js";
|
|
16
16
|
import { validateSyncCommitteeGossipContributionAndProof } from "../../../chain/validation/syncCommitteeContributionAndProof.js";
|
|
17
17
|
import { ZERO_HASH } from "../../../constants/index.js";
|
|
18
|
+
import { BUILDER_BID_DEADLINE_MS, decodeBuilderUrl } from "../../../execution/builder/apiClient.js";
|
|
18
19
|
import { BuilderStatus, NoBidReceived } from "../../../execution/builder/http.js";
|
|
20
|
+
import { getBuilderBidTotalGwei, validateBuilderApiExecutionPayloadBid } from "../../../execution/builder/validateBid.js";
|
|
19
21
|
import { validateGossipFnRetryUnknownRoot } from "../../../network/processor/gossipHandlers.js";
|
|
20
22
|
import { callInNextEventLoop } from "../../../util/eventLoop.js";
|
|
21
23
|
import { isOptimisticBlock } from "../../../util/forkChoice.js";
|
|
@@ -38,6 +40,43 @@ import { computeSubnetForCommitteesAtSlot, getPubkeysForIndices, selectBlockProd
|
|
|
38
40
|
const BLOCK_PRODUCTION_RACE_CUTOFF_MS = 2_000;
|
|
39
41
|
/** Overall timeout for execution and block production apis */
|
|
40
42
|
const BLOCK_PRODUCTION_RACE_TIMEOUT_MS = 12_000;
|
|
43
|
+
/** Rejection message of the bid block branch when there is no viable bid to commit to */
|
|
44
|
+
const NO_BID_AVAILABLE = "No builder bid available";
|
|
45
|
+
/**
|
|
46
|
+
* Return the best bid by boosted total payment. A candidate with the max boost factor is
|
|
47
|
+
* preferred over any other regardless of value, ties prefer a builder api bid over the
|
|
48
|
+
* p2p bid, and the earlier received bid between builder api bids.
|
|
49
|
+
*/
|
|
50
|
+
function selectBestBid(candidates) {
|
|
51
|
+
const boostedValue = ({ totalGwei, boostFactor }) => boostFactor * totalGwei;
|
|
52
|
+
let best = null;
|
|
53
|
+
for (const candidate of candidates) {
|
|
54
|
+
if (best === null) {
|
|
55
|
+
best = candidate;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Preserve max boost preference before comparing bid values
|
|
59
|
+
const candidateIsMaxBoost = candidate.boostFactor === MAX_BUILDER_BOOST_FACTOR;
|
|
60
|
+
const bestIsMaxBoost = best.boostFactor === MAX_BUILDER_BOOST_FACTOR;
|
|
61
|
+
if (candidateIsMaxBoost !== bestIsMaxBoost) {
|
|
62
|
+
if (candidateIsMaxBoost) {
|
|
63
|
+
best = candidate;
|
|
64
|
+
}
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const candidateValue = boostedValue(candidate);
|
|
68
|
+
const bestValue = boostedValue(best);
|
|
69
|
+
if (candidateValue > bestValue) {
|
|
70
|
+
best = candidate;
|
|
71
|
+
}
|
|
72
|
+
else if (candidateValue === bestValue &&
|
|
73
|
+
// A tie prefers a builder api bid over the p2p bid, and the earlier received bid otherwise
|
|
74
|
+
(best.url === undefined || (candidate.url !== undefined && candidate.receivedMs < best.receivedMs))) {
|
|
75
|
+
best = candidate;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return best;
|
|
79
|
+
}
|
|
41
80
|
/**
|
|
42
81
|
* Engine block selection reasons tracked in metrics / logs
|
|
43
82
|
*/
|
|
@@ -613,12 +652,12 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
613
652
|
}
|
|
614
653
|
return { data, meta };
|
|
615
654
|
},
|
|
616
|
-
async produceBlockV4({ slot, randaoReveal, graffiti, feeRecipient, strictFeeRecipientCheck, includePayload,
|
|
655
|
+
async produceBlockV4({ slot, randaoReveal, graffiti, feeRecipient, strictFeeRecipientCheck, includePayload, builderConfig, }) {
|
|
617
656
|
const fork = config.getForkName(slot);
|
|
618
657
|
if (!isForkPostGloas(fork)) {
|
|
619
658
|
throw new ApiError(400, `produceBlockV4 not supported for pre-gloas fork=${fork}`);
|
|
620
659
|
}
|
|
621
|
-
builderBoostFactor = builderBoostFactor
|
|
660
|
+
const builderBoostFactor = builderConfig.builderBoostFactor;
|
|
622
661
|
if (builderBoostFactor > MAX_BUILDER_BOOST_FACTOR) {
|
|
623
662
|
throw new ApiError(400, `Invalid builderBoostFactor=${builderBoostFactor} > MAX_BUILDER_BOOST_FACTOR`);
|
|
624
663
|
}
|
|
@@ -637,31 +676,103 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
637
676
|
private: opts.private,
|
|
638
677
|
graffitiAppend: chain.opts.graffitiAppend,
|
|
639
678
|
}));
|
|
640
|
-
// TODO GLOAS: add external builder api support when it is implemented
|
|
641
679
|
const isBuildingOnFull = chain.forkChoice.shouldBuildOnFull(parentBlock, slot);
|
|
642
680
|
const bidParentBlockHash = isBuildingOnFull ? parentBlock.executionPayloadBlockHash : parentBlock.parentBlockHash;
|
|
681
|
+
// Post-gloas every proposal parent has an execution payload hash
|
|
682
|
+
if (bidParentBlockHash === null) {
|
|
683
|
+
throw new ApiError(500, `Unknown parent block hash for proposal parent ${parentBlockRootHex}`);
|
|
684
|
+
}
|
|
643
685
|
const circuitBreakerActive = chain.builderCircuitBreaker.isActive(slot, parentBlock);
|
|
644
|
-
//
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
686
|
+
// Fire builder API bid requests while the local payload is built, one request per entry.
|
|
687
|
+
// Any entry failure yields no bid and never fails block production.
|
|
688
|
+
let builderApiBidsPromise = Promise.resolve([]);
|
|
689
|
+
if (builderConfig.builders.length > 0 && !circuitBreakerActive) {
|
|
690
|
+
try {
|
|
691
|
+
const proposerIndex = chain.getHeadState().getBeaconProposer(slot);
|
|
692
|
+
const proposerPubkey = chain.pubkeyCache.getOrThrow(proposerIndex).toBytes();
|
|
693
|
+
builderApiBidsPromise = chain.builderApiClient.getExecutionPayloadBids(builderConfig.builders, slot, fromHex(bidParentBlockHash), parentBlockRoot, proposerPubkey);
|
|
694
|
+
}
|
|
695
|
+
catch (e) {
|
|
696
|
+
logger.warn("Unable to request builder API bids", { slot }, e);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// A builder bid is expected if builders are configured or a p2p bid was already received.
|
|
700
|
+
// Used by the censorship override which may run before the bid deadline
|
|
701
|
+
const builderBidExpected = builderConfig.builders.length > 0 ||
|
|
702
|
+
(!circuitBreakerActive &&
|
|
703
|
+
chain.executionPayloadBidPool.getBestBid(slot, bidParentBlockHash, parentBlockRootHex) !== null);
|
|
704
|
+
// Select the p2p bid once builders had time to bid up, matching the deadline advertised
|
|
705
|
+
// on builder API bid requests, unless the circuit breaker is active
|
|
706
|
+
const p2pBidPromise = circuitBreakerActive
|
|
707
|
+
? Promise.resolve(null)
|
|
708
|
+
: sleep(Math.max(0, BUILDER_BID_DEADLINE_MS - chain.clock.msFromSlot(slot))).then(() => {
|
|
709
|
+
const p2pBid = chain.executionPayloadBidPool.getBestBid(slot, bidParentBlockHash, parentBlockRootHex);
|
|
710
|
+
// Discard p2p bids below the proposer's configured floor on the total payment.
|
|
711
|
+
// A p2p bid's total is just its value since gossip validation enforces executionPayment=0.
|
|
712
|
+
if (p2pBid !== null && BigInt(p2pBid.signedBid.message.value) < builderConfig.minBid) {
|
|
713
|
+
logger.info("Best p2p bid below configured minimum", {
|
|
714
|
+
slot,
|
|
715
|
+
bidValue: prettyGweiToEth(p2pBid.signedBid.message.value),
|
|
716
|
+
minBid: prettyGweiToEth(builderConfig.minBid),
|
|
717
|
+
});
|
|
718
|
+
return null;
|
|
662
719
|
}
|
|
663
|
-
|
|
664
|
-
|
|
720
|
+
return p2pBid;
|
|
721
|
+
});
|
|
722
|
+
// Candidates are ranked by their boosted counted total payment, the p2p bid is governed
|
|
723
|
+
// by the top-level factors and each builder API bid by its own entry. Ties prefer the
|
|
724
|
+
// earliest received builder API bid, so the signed block can be routed back to its
|
|
725
|
+
// builder directly.
|
|
726
|
+
const bestBidPromise = (async () => {
|
|
727
|
+
const [builderApiBids, p2pBid] = await Promise.all([builderApiBidsPromise, p2pBidPromise]);
|
|
728
|
+
let parentExecutionRequestsPromise = null;
|
|
729
|
+
const candidates = (await Promise.all(builderApiBids.map(async ({ url, entry, signedBid, receivedMs }) => {
|
|
730
|
+
try {
|
|
731
|
+
await validateBuilderApiExecutionPayloadBid(chain, signedBid, {
|
|
732
|
+
slot,
|
|
733
|
+
parentBlock,
|
|
734
|
+
parentBlockHash: bidParentBlockHash,
|
|
735
|
+
parentBlockRoot: parentBlockRootHex,
|
|
736
|
+
entry,
|
|
737
|
+
getParentExecutionRequests: () => {
|
|
738
|
+
parentExecutionRequestsPromise ??= chain.getParentExecutionRequests(parentSlot, parentBlockRootHex);
|
|
739
|
+
return parentExecutionRequestsPromise;
|
|
740
|
+
},
|
|
741
|
+
});
|
|
742
|
+
return {
|
|
743
|
+
signedBid,
|
|
744
|
+
totalGwei: getBuilderBidTotalGwei(signedBid.message, entry.maxExecutionPayment),
|
|
745
|
+
boostFactor: entry.builderBoostFactor,
|
|
746
|
+
url,
|
|
747
|
+
receivedMs,
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
catch (e) {
|
|
751
|
+
metrics?.builderApi.bidsDiscarded.inc();
|
|
752
|
+
logger.warn("Ignoring invalid builder API bid", { slot, builder: toPrintableUrl(url) }, e);
|
|
753
|
+
return null;
|
|
754
|
+
}
|
|
755
|
+
}))).filter((candidate) => candidate !== null);
|
|
756
|
+
if (p2pBid !== null) {
|
|
757
|
+
candidates.push({
|
|
758
|
+
signedBid: p2pBid.signedBid,
|
|
759
|
+
totalGwei: BigInt(p2pBid.signedBid.message.value),
|
|
760
|
+
boostFactor: builderConfig.builderBoostFactor,
|
|
761
|
+
receivedMs: p2pBid.receivedMs,
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
const best = selectBestBid(candidates);
|
|
765
|
+
if (candidates.length > 0) {
|
|
766
|
+
logger.debug("Ranked builder bid candidates", {
|
|
767
|
+
slot,
|
|
768
|
+
candidates: candidates
|
|
769
|
+
.map((candidate) => `${candidate.url ?? "p2p"}:total=${prettyGweiToEth(candidate.totalGwei)}:boost=${candidate.boostFactor}:received=${candidate.receivedMs}ms`)
|
|
770
|
+
.join(","),
|
|
771
|
+
bidSource: best?.url ?? "p2p",
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
return best;
|
|
775
|
+
})();
|
|
665
776
|
const commonBlockBodyPromise = chain.produceCommonBlockBody({
|
|
666
777
|
slot,
|
|
667
778
|
parentBlock,
|
|
@@ -678,9 +789,6 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
678
789
|
commonBlockBodyPromise,
|
|
679
790
|
};
|
|
680
791
|
metrics?.blockProductionRequests.inc({ source: ProducedBlockSource.engine });
|
|
681
|
-
if (builderBid !== null) {
|
|
682
|
-
metrics?.blockProductionRequests.inc({ source: ProducedBlockSource.builder });
|
|
683
|
-
}
|
|
684
792
|
const timed = (source, fn) => {
|
|
685
793
|
const t = metrics?.blockProductionTime.startTimer();
|
|
686
794
|
return fn().finally(() => t?.({ source }));
|
|
@@ -691,48 +799,92 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
691
799
|
// use abort controller to stop waiting for the bid block if the engine block will be selected
|
|
692
800
|
const controller = new AbortController();
|
|
693
801
|
const enginePromise = timed(ProducedBlockSource.engine, () => chain.produceBlock(baseAttrs)).then((engineBlock) => {
|
|
694
|
-
// No need to wait for the bid block if the engine block will always be selected
|
|
695
|
-
// suspected builder censorship or
|
|
696
|
-
|
|
802
|
+
// No need to wait for the bid block if the engine block will always be selected, either
|
|
803
|
+
// due to suspected builder censorship, or because no builders are configured and the
|
|
804
|
+
// boost factor of 0 always prefers the local block over p2p bids
|
|
805
|
+
if (engineBlock.shouldOverrideBuilder || (builderConfig.builders.length === 0 && builderBoostFactor === 0n)) {
|
|
697
806
|
controller.abort();
|
|
698
807
|
}
|
|
699
808
|
return engineBlock;
|
|
700
809
|
});
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
810
|
+
const bidBlockPromise = bestBidPromise.then((candidate) => {
|
|
811
|
+
if (candidate === null) {
|
|
812
|
+
throw new Error(NO_BID_AVAILABLE);
|
|
813
|
+
}
|
|
814
|
+
metrics?.blockProductionRequests.inc({ source: ProducedBlockSource.builder });
|
|
815
|
+
return timed(ProducedBlockSource.builder, () => chain.produceBlock({ ...baseAttrs, builderBid: candidate.signedBid }));
|
|
816
|
+
});
|
|
817
|
+
const [engineResult, bidBlockResult] = await resolveOrRacePromises([enginePromise, bidBlockPromise], {
|
|
705
818
|
resolveTimeoutMs: cutoffMs,
|
|
706
819
|
raceTimeoutMs: BLOCK_PRODUCTION_RACE_TIMEOUT_MS,
|
|
707
820
|
signal: controller.signal,
|
|
708
821
|
});
|
|
709
822
|
let bestResult = null;
|
|
710
823
|
let source = ProducedBlockSource.engine;
|
|
824
|
+
// Resolved instantly whenever the bid branch produced a block
|
|
825
|
+
const bestBid = bidBlockResult.status === "fulfilled" ? await bestBidPromise : null;
|
|
826
|
+
const logCtx = {
|
|
827
|
+
slot,
|
|
828
|
+
parentSlot,
|
|
829
|
+
parentBlockRoot: parentBlockRootHex,
|
|
830
|
+
parentBlockHash: parentBlock.executionPayloadBlockHash,
|
|
831
|
+
fork,
|
|
832
|
+
builderBoostFactor,
|
|
833
|
+
strictFeeRecipientCheck,
|
|
834
|
+
circuitBreakerActive,
|
|
835
|
+
builderEntries: builderConfig.builders.length,
|
|
836
|
+
...(bestBid !== null
|
|
837
|
+
? {
|
|
838
|
+
bidSource: bestBid.url !== undefined ? toPrintableUrl(bestBid.url) : "p2p",
|
|
839
|
+
bidValue: prettyGweiToEth(bestBid.signedBid.message.value),
|
|
840
|
+
bidExecutionPayment: prettyGweiToEth(bestBid.signedBid.message.executionPayment),
|
|
841
|
+
// The full bid total and the counted total used during bid selection
|
|
842
|
+
bidTotal: prettyGweiToEth(BigInt(bestBid.signedBid.message.value) + bestBid.signedBid.message.executionPayment),
|
|
843
|
+
bidCountedTotal: prettyGweiToEth(bestBid.totalGwei),
|
|
844
|
+
bidBoostFactor: bestBid.boostFactor,
|
|
845
|
+
builderIndex: bestBid.signedBid.message.builderIndex,
|
|
846
|
+
bidBlockHash: toRootHex(bestBid.signedBid.message.blockHash),
|
|
847
|
+
bidReceivedMs: bestBid.receivedMs,
|
|
848
|
+
}
|
|
849
|
+
: {}),
|
|
850
|
+
};
|
|
711
851
|
// handle shouldOverrideBuilder separately
|
|
712
|
-
if (engineResult.status === "fulfilled" &&
|
|
852
|
+
if (engineResult.status === "fulfilled" &&
|
|
853
|
+
engineResult.value.shouldOverrideBuilder &&
|
|
854
|
+
(builderBidExpected || bidBlockResult.status === "fulfilled")) {
|
|
713
855
|
source = ProducedBlockSource.engine;
|
|
714
856
|
bestResult = engineResult;
|
|
715
857
|
metrics?.blockProductionSelectionResults.inc({
|
|
716
858
|
source: ProducedBlockSource.engine,
|
|
717
859
|
reason: EngineBlockSelectionReason.BuilderCensorship,
|
|
718
860
|
});
|
|
719
|
-
logger.warn("Selected local block: censorship suspected in builder bid",
|
|
861
|
+
logger.warn("Selected local block: censorship suspected in builder bid", {
|
|
862
|
+
...logCtx,
|
|
863
|
+
durationMs: engineResult.durationMs,
|
|
864
|
+
...getBlockValueLogInfo(engineResult.value),
|
|
865
|
+
});
|
|
720
866
|
}
|
|
721
|
-
else if (engineResult.status === "fulfilled" &&
|
|
867
|
+
else if (engineResult.status === "fulfilled" && bidBlockResult.status === "fulfilled") {
|
|
722
868
|
const result = selectBlockProductionSourceByBoostFactor({
|
|
723
|
-
builderBoostFactor,
|
|
869
|
+
builderBoostFactor: bestBid?.boostFactor ?? builderBoostFactor,
|
|
724
870
|
engineExecutionPayloadValue: engineResult.value.executionPayloadValue,
|
|
725
|
-
// The bid
|
|
726
|
-
builderExecutionPayloadValue:
|
|
871
|
+
// The bid total payment is its value plus its counted executionPayment, in Gwei
|
|
872
|
+
builderExecutionPayloadValue: (bestBid?.totalGwei ?? 0n) * GWEI_TO_WEI,
|
|
727
873
|
});
|
|
728
874
|
source = result.source;
|
|
729
875
|
metrics?.blockProductionSelectionResults.inc(result);
|
|
730
|
-
logger.info(`Selected ${source} block`, {
|
|
731
|
-
|
|
876
|
+
logger.info(`Selected ${source} block`, {
|
|
877
|
+
reason: result.reason,
|
|
878
|
+
...logCtx,
|
|
879
|
+
engineDurationMs: engineResult.durationMs,
|
|
880
|
+
...getBlockValueLogInfo(engineResult.value, ProducedBlockSource.engine),
|
|
881
|
+
builderDurationMs: bidBlockResult.durationMs,
|
|
882
|
+
});
|
|
883
|
+
bestResult = source === ProducedBlockSource.builder ? bidBlockResult : engineResult;
|
|
732
884
|
}
|
|
733
|
-
else if (
|
|
885
|
+
else if (bidBlockResult.status === "fulfilled") {
|
|
734
886
|
source = ProducedBlockSource.builder;
|
|
735
|
-
bestResult =
|
|
887
|
+
bestResult = bidBlockResult;
|
|
736
888
|
const reason = engineResult.status === "pending"
|
|
737
889
|
? BuilderBlockSelectionReason.EnginePending
|
|
738
890
|
: BuilderBlockSelectionReason.EngineError;
|
|
@@ -740,27 +892,31 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
740
892
|
logger.info("Selected builder bid block: no local block produced", {
|
|
741
893
|
reason,
|
|
742
894
|
...logCtx,
|
|
895
|
+
durationMs: bidBlockResult.durationMs,
|
|
896
|
+
...getBlockValueLogInfo(bidBlockResult.value),
|
|
743
897
|
error: engineResult.status === "rejected" ? engineResult.reason.message : undefined,
|
|
744
898
|
});
|
|
745
899
|
}
|
|
746
900
|
else if (engineResult.status === "fulfilled") {
|
|
747
901
|
source = ProducedBlockSource.engine;
|
|
748
902
|
bestResult = engineResult;
|
|
749
|
-
const reason =
|
|
903
|
+
const reason = bidBlockResult.status === "rejected" && bidBlockResult.reason.message === NO_BID_AVAILABLE
|
|
750
904
|
? EngineBlockSelectionReason.BuilderNoBid
|
|
751
|
-
:
|
|
905
|
+
: bidBlockResult.status === "pending"
|
|
752
906
|
? EngineBlockSelectionReason.BuilderPending
|
|
753
907
|
: EngineBlockSelectionReason.BuilderError;
|
|
754
908
|
metrics?.blockProductionSelectionResults.inc({ source: ProducedBlockSource.engine, reason });
|
|
755
909
|
logger.info("Selected local block: no builder bid block produced", {
|
|
756
910
|
reason,
|
|
757
911
|
...logCtx,
|
|
758
|
-
|
|
912
|
+
durationMs: engineResult.durationMs,
|
|
913
|
+
...getBlockValueLogInfo(engineResult.value),
|
|
914
|
+
error: bidBlockResult.status === "rejected" ? bidBlockResult.reason.message : undefined,
|
|
759
915
|
});
|
|
760
916
|
}
|
|
761
917
|
if (bestResult === null || bestResult.status !== "fulfilled") {
|
|
762
918
|
const engineReason = engineResult.status === "rejected" ? engineResult.reason : engineResult.status;
|
|
763
|
-
const bidReason =
|
|
919
|
+
const bidReason = bidBlockResult.status === "rejected" ? bidBlockResult.reason : bidBlockResult.status;
|
|
764
920
|
logger.error("Block production failed", {
|
|
765
921
|
...logCtx,
|
|
766
922
|
engineReason: String(engineReason),
|
|
@@ -812,7 +968,13 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
812
968
|
}
|
|
813
969
|
return {
|
|
814
970
|
data: block,
|
|
815
|
-
meta: {
|
|
971
|
+
meta: {
|
|
972
|
+
version: fork,
|
|
973
|
+
consensusBlockValue,
|
|
974
|
+
executionPayloadValue,
|
|
975
|
+
executionPayloadIncluded: false,
|
|
976
|
+
builderUrl: source === ProducedBlockSource.builder ? bestBid?.url : undefined,
|
|
977
|
+
},
|
|
816
978
|
};
|
|
817
979
|
},
|
|
818
980
|
async produceAttestationData({ committeeIndex, slot }) {
|
|
@@ -1443,6 +1605,32 @@ export function getValidatorApi(opts, { chain, config, logger, metrics, network,
|
|
|
1443
1605
|
throw new IndexedError("Error processing signed proposer preferences", failures);
|
|
1444
1606
|
}
|
|
1445
1607
|
},
|
|
1608
|
+
async submitBuilderPreferences({ builderPreferences }) {
|
|
1609
|
+
const failures = [];
|
|
1610
|
+
await Promise.all(builderPreferences.map(async (entry, i) => {
|
|
1611
|
+
let builder = Buffer.from(entry.url).toString("utf8");
|
|
1612
|
+
try {
|
|
1613
|
+
const url = decodeBuilderUrl(entry.url);
|
|
1614
|
+
builder = toPrintableUrl(url);
|
|
1615
|
+
const proposerIndex = chain.getHeadState().getBeaconProposer(entry.auth.message.slot);
|
|
1616
|
+
const expectedProposerPubkey = chain.pubkeyCache.getOrThrow(proposerIndex).toBytes();
|
|
1617
|
+
if (!byteArrayEquals(entry.proposerPubkey, expectedProposerPubkey)) {
|
|
1618
|
+
throw new ApiError(400, `Invalid proposer pubkey for builder preferences slot=${entry.auth.message.slot}`);
|
|
1619
|
+
}
|
|
1620
|
+
await chain.builderApiClient.submitBuilderPreferences(url, entry.proposerPubkey, {
|
|
1621
|
+
preferences: { maxExecutionPayment: entry.maxExecutionPayment },
|
|
1622
|
+
auth: entry.auth,
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
catch (e) {
|
|
1626
|
+
failures.push({ index: i, message: e.message });
|
|
1627
|
+
logger.verbose(`Error on submitBuilderPreferences [${i}]`, { slot: entry.auth.message.slot, builder }, e);
|
|
1628
|
+
}
|
|
1629
|
+
}));
|
|
1630
|
+
if (failures.length > 0) {
|
|
1631
|
+
throw new IndexedError("Error submitting builder preferences", failures);
|
|
1632
|
+
}
|
|
1633
|
+
},
|
|
1446
1634
|
async getExecutionPayloadEnvelope({ slot, beaconBlockRoot }) {
|
|
1447
1635
|
const fork = config.getForkName(slot);
|
|
1448
1636
|
if (!isForkPostGloas(fork)) {
|