From 34853ca15527752c48b2dba3d56da56f01364aa7 Mon Sep 17 00:00:00 2001 From: Eugene Kabanov Date: Wed, 22 May 2024 01:03:38 +0300 Subject: [PATCH] VC: Deprecate fallback path to produceBlockV2, use produceBlockV3 always. (#6300) * Remove fallback path to publishBlockV2(), use publishBlockV3(). * Update AllTests.md. --- AllTests-mainnet.md | 2 +- beacon_chain/validator_client/api.nim | 109 ----- .../validator_client/block_service.nim | 387 +----------------- beacon_chain/validator_client/common.nim | 1 - 4 files changed, 13 insertions(+), 486 deletions(-) diff --git a/AllTests-mainnet.md b/AllTests-mainnet.md index 534e465dd..ebdb530e5 100644 --- a/AllTests-mainnet.md +++ b/AllTests-mainnet.md @@ -1030,4 +1030,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2 OK: 9/9 Fail: 0/9 Skip: 0/9 ---TOTAL--- -OK: 686/691 Fail: 0/691 Skip: 5/691 +OK: 687/692 Fail: 0/692 Skip: 5/692 diff --git a/beacon_chain/validator_client/api.nim b/beacon_chain/validator_client/api.nim index 75d171ddc..5762bf088 100644 --- a/beacon_chain/validator_client/api.nim +++ b/beacon_chain/validator_client/api.nim @@ -2022,97 +2022,6 @@ proc publishContributionAndProofs*( raise (ref ValidatorApiError)( msg: "Failed to publish sync committee contribution", data: failures) -proc produceBlockV2*( - vc: ValidatorClientRef, - slot: Slot, - randao_reveal: ValidatorSig, - graffiti: GraffitiBytes, - strategy: ApiStrategyKind - ): Future[ProduceBlockResponseV2] {.async.} = - const - RequestName = "produceBlockV2" - - var failures: seq[ApiNodeFailure] - - case strategy - of ApiStrategyKind.First, ApiStrategyKind.Best: - let res = vc.firstSuccessParallel( - RestPlainResponse, - ProduceBlockResponseV2, - SlotDuration, - ViableNodeStatus, - {BeaconNodeRole.BlockProposalData}, - produceBlockV2Plain(it, slot, randao_reveal, graffiti)): - if apiResponse.isErr(): - handleCommunicationError() - ApiResponse[ProduceBlockResponseV2].err(apiResponse.error) - else: - let response = apiResponse.get() - case response.status: - of 200: - let - version = response.headers.getString("eth-consensus-version") - res = decodeBytes(ProduceBlockResponseV2, response.data, - response.contentType, version) - if res.isErr(): - handleUnexpectedData() - ApiResponse[ProduceBlockResponseV2].err($res.error) - else: - ApiResponse[ProduceBlockResponseV2].ok(res.get()) - of 400: - handle400() - ApiResponse[ProduceBlockResponseV2].err(ResponseInvalidError) - of 500: - handle500() - ApiResponse[ProduceBlockResponseV2].err(ResponseInternalError) - of 503: - handle503() - ApiResponse[ProduceBlockResponseV2].err(ResponseNoSyncError) - else: - handleUnexpectedCode() - ApiResponse[ProduceBlockResponseV2].err(ResponseUnexpectedError) - - if res.isErr(): - raise (ref ValidatorApiError)(msg: res.error, data: failures) - return res.get() - - of ApiStrategyKind.Priority: - vc.firstSuccessSequential( - RestPlainResponse, - SlotDuration, - ViableNodeStatus, - {BeaconNodeRole.BlockProposalData}, - produceBlockV2Plain(it, slot, randao_reveal, graffiti)): - if apiResponse.isErr(): - handleCommunicationError() - false - else: - let response = apiResponse.get() - case response.status: - of 200: - let - version = response.headers.getString("eth-consensus-version") - res = decodeBytes(ProduceBlockResponseV2, response.data, - response.contentType, version) - if res.isOk(): return res.get() - handleUnexpectedData() - false - of 400: - handle400() - false - of 500: - handle500() - false - of 503: - handle503() - false - else: - handleUnexpectedCode() - false - - raise (ref ValidatorApiError)( - msg: "Failed to produce block", data: failures) - proc produceBlockV3*( vc: ValidatorClientRef, slot: Slot, @@ -2161,24 +2070,15 @@ proc produceBlockV3*( ApiResponse[ProduceBlockResponseV3].ok(res.get()) of 400: handle400() - node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3) - ApiResponse[ProduceBlockResponseV3].err(ResponseInvalidError) - of 404: - # TODO (cheatfate): Remove this handler when produceBlockV2 support - # will be dropped. - handle400() - node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3) ApiResponse[ProduceBlockResponseV3].err(ResponseInvalidError) of 500: handle500() - node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3) ApiResponse[ProduceBlockResponseV3].err(ResponseInternalError) of 503: handle503() ApiResponse[ProduceBlockResponseV3].err(ResponseNoSyncError) else: handleUnexpectedCode() - node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3) ApiResponse[ProduceBlockResponseV3].err(ResponseUnexpectedError) if res.isErr(): @@ -2216,24 +2116,15 @@ proc produceBlockV3*( false of 400: handle400() - node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3) - false - of 404: - # TODO (cheatfate): Remove this handler when produceBlockV2 support - # will be dropped. - handle400() - node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3) false of 500: handle500() - node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3) false of 503: handle503() false else: handleUnexpectedCode() - node.features.incl(RestBeaconNodeFeature.NoProduceBlockV3) false raise (ref ValidatorApiError)( diff --git a/beacon_chain/validator_client/block_service.nim b/beacon_chain/validator_client/block_service.nim index 30198ac9e..1bd6514b7 100644 --- a/beacon_chain/validator_client/block_service.nim +++ b/beacon_chain/validator_client/block_service.nim @@ -49,114 +49,6 @@ func shortLog(v: ForkedMaybeBlindedBeaconBlock): auto = proc proposeBlock(vc: ValidatorClientRef, slot: Slot, proposerKey: ValidatorPubKey) {.async.} -proc produceBlock( - vc: ValidatorClientRef, - currentSlot, slot: Slot, - randao_reveal: ValidatorSig, - graffiti: GraffitiBytes, - validator: AttachedValidator - ): Future[Opt[PreparedBeaconBlock]] {.async.} = - logScope: - slot = slot - wall_slot = currentSlot - validator = validatorLog(validator) - let - produceBlockResponse = - try: - await vc.produceBlockV2(slot, randao_reveal, graffiti, - ApiStrategyKind.Best) - except ValidatorApiError as exc: - warn "Unable to retrieve block data", reason = exc.getFailureReason() - return Opt.none(PreparedBeaconBlock) - except CancelledError as exc: - debug "Block data production has been interrupted" - raise exc - except CatchableError as exc: - error "An unexpected error occurred while getting block data", - error_name = exc.name, error_msg = exc.msg - return Opt.none(PreparedBeaconBlock) - case produceBlockResponse.kind - of ConsensusFork.Phase0: - let blck = produceBlockResponse.phase0Data - return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck), - data: ForkedBeaconBlock.init(blck), - kzgProofsOpt: Opt.none(deneb.KzgProofs), - blobsOpt: Opt.none(deneb.Blobs))) - of ConsensusFork.Altair: - let blck = produceBlockResponse.altairData - return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck), - data: ForkedBeaconBlock.init(blck), - kzgProofsOpt: Opt.none(deneb.KzgProofs), - blobsOpt: Opt.none(deneb.Blobs))) - of ConsensusFork.Bellatrix: - let blck = produceBlockResponse.bellatrixData - return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck), - data: ForkedBeaconBlock.init(blck), - kzgProofsOpt: Opt.none(deneb.KzgProofs), - blobsOpt: Opt.none(deneb.Blobs))) - of ConsensusFork.Capella: - let blck = produceBlockResponse.capellaData - return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck), - data: ForkedBeaconBlock.init(blck), - kzgProofsOpt: Opt.none(deneb.KzgProofs), - blobsOpt: Opt.none(deneb.Blobs))) - of ConsensusFork.Deneb: - let - blck = produceBlockResponse.denebData.`block` - kzgProofs = produceBlockResponse.denebData.kzg_proofs - blobs = produceBlockResponse.denebData.blobs - return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck), - data: ForkedBeaconBlock.init(blck), - kzgProofsOpt: Opt.some(kzgProofs), - blobsOpt: Opt.some(blobs))) - of ConsensusFork.Electra: - let - blck = produceBlockResponse.electraData.`block` - kzgProofs = produceBlockResponse.electraData.kzg_proofs - blobs = produceBlockResponse.electraData.blobs - return Opt.some(PreparedBeaconBlock(blockRoot: hash_tree_root(blck), - data: ForkedBeaconBlock.init(blck), - kzgProofsOpt: Opt.some(kzgProofs), - blobsOpt: Opt.some(blobs))) - -proc produceBlindedBlock( - vc: ValidatorClientRef, - currentSlot, slot: Slot, - randao_reveal: ValidatorSig, - graffiti: GraffitiBytes, - validator: AttachedValidator - ): Future[Opt[PreparedBlindedBeaconBlock]] {.async.} = - logScope: - slot = slot - wall_slot = currentSlot - validator = validatorLog(validator) - let - beaconBlock = - try: - await vc.produceBlindedBlock(slot, randao_reveal, graffiti, - ApiStrategyKind.Best) - except ValidatorApiError as exc: - warn "Unable to retrieve blinded block data", error_msg = exc.msg, - reason = exc.getFailureReason() - return Opt.none(PreparedBlindedBeaconBlock) - except CancelledError as exc: - debug "Blinded block data production has been interrupted" - raise exc - except CatchableError as exc: - error "An unexpected error occurred while getting blinded block data", - error_name = exc.name, error_msg = exc.msg - return Opt.none(PreparedBlindedBeaconBlock) - blockRoot = withBlck(beaconBlock): hash_tree_root(forkyBlck) - - return Opt.some( - PreparedBlindedBeaconBlock(blockRoot: blockRoot, data: beaconBlock)) - -proc lazyWait[T](fut: Future[T]) {.async.} = - try: - discard await fut - except CatchableError: - discard - proc prepareRandao(vc: ValidatorClientRef, slot: Slot, proposerKey: ValidatorPubKey) {.async.} = if slot == GENESIS_SLOT: @@ -209,21 +101,9 @@ proc spawnProposalTask(vc: ValidatorClientRef, duty: duty ) -proc isProduceBlockV3Supported(vc: ValidatorClientRef): bool = - let - # Both `statuses` and `roles` should be set to values which are used in - # api.produceBlockV3() call. - statuses = ViableNodeStatus - roles = {BeaconNodeRole.BlockProposalData} - - for node in vc.filterNodes(statuses, roles): - if RestBeaconNodeFeature.NoProduceBlockV3 notin node.features: - return true - false - proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, fork: Fork, randaoReveal: ValidatorSig, - validator: AttachedValidator): Future[bool] {.async.} = + validator: AttachedValidator) {.async.} = let genesisRoot = vc.beaconGenesis.genesis_validators_root graffiti = @@ -247,14 +127,14 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, ApiStrategyKind.Best) except ValidatorApiError as exc: warn "Unable to retrieve block data", reason = exc.getFailureReason() - return false + return except CancelledError as exc: debug "Block data production has been interrupted" raise exc except CatchableError as exc: error "An unexpected error occurred while getting block data", error_name = exc.name, error_msg = exc.msg - return false + return withForkyMaybeBlindedBlck(maybeBlock): when isBlinded: @@ -282,7 +162,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, if notSlashable.isErr(): warn "Slashing protection activated for blinded block proposal" - return false + return let signature = try: @@ -292,7 +172,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, if res.isErr(): warn "Unable to sign blinded block proposal using remote signer", reason = res.error() - return false + return res.get() except CancelledError as exc: debug "Blinded block signature process has been interrupted" @@ -300,7 +180,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, except CatchableError as exc: error "An unexpected error occurred while signing blinded block", error_name = exc.name, error_msg = exc.msg - return false + return let signedBlock = @@ -313,7 +193,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, except ValidatorApiError as exc: warn "Unable to publish blinded block", reason = exc.getFailureReason() - return false + return except CancelledError as exc: debug "Blinded block publication has been interrupted" raise exc @@ -321,17 +201,15 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, error "An unexpected error occurred while publishing blinded " & "block", error_name = exc.name, error_msg = exc.msg - return false + return if res: let delay = vc.getDelay(slot.block_deadline()) beacon_blocks_sent.inc() beacon_blocks_sent_delay.observe(delay.toFloatSeconds()) notice "Blinded block published", delay = delay - true else: warn "Blinded block was not accepted by beacon node" - false else: let blockRoot = hash_tree_root( @@ -367,7 +245,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, if notSlashable.isErr(): warn "Slashing protection activated for block proposal" - return false + return let signature = @@ -377,7 +255,7 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, if res.isErr(): warn "Unable to sign block proposal using remote signer", reason = res.error() - return false + return res.get() except CancelledError as exc: debug "Block signature process has been interrupted" @@ -385,240 +263,12 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot, except CatchableError as exc: error "An unexpected error occurred while signing block", error_name = exc.name, error_msg = exc.msg - return false + return signedBlockContents = RestPublishedSignedBlockContents.init( forkyMaybeBlindedBlck, blockRoot, signature) - res = - try: - debug "Sending block" - await vc.publishBlock(signedBlockContents, ApiStrategyKind.First) - except ValidatorApiError as exc: - warn "Unable to publish block", reason = exc.getFailureReason() - return false - except CancelledError as exc: - debug "Block publication has been interrupted" - raise exc - except CatchableError as exc: - error "An unexpected error occurred while publishing block", - error_name = exc.name, error_msg = exc.msg - return false - - if res: - let delay = vc.getDelay(slot.block_deadline()) - beacon_blocks_sent.inc() - beacon_blocks_sent_delay.observe(delay.toFloatSeconds()) - notice "Block published", delay = delay - true - else: - warn "Block was not accepted by beacon node" - false - -proc publishBlockV2(vc: ValidatorClientRef, currentSlot, slot: Slot, - fork: Fork, randaoReveal: ValidatorSig, - validator: AttachedValidator) {.async.} = - let - genesisRoot = vc.beaconGenesis.genesis_validators_root - graffiti = vc.getGraffitiBytes(validator) - vindex = validator.index.get() - - logScope: - validator = validatorLog(validator) - validator_index = vindex - slot = slot - wall_slot = currentSlot - - var beaconBlocks = - block: - let blindedBlockFut = - if vc.config.payloadBuilderEnable: - vc.produceBlindedBlock(currentSlot, slot, randaoReveal, graffiti, - validator) - else: - nil - let normalBlockFut = vc.produceBlock(currentSlot, slot, randaoReveal, - graffiti, validator) - let blindedBlock = - if isNil(blindedBlockFut): - Opt.none(PreparedBlindedBeaconBlock) - else: - try: - await blindedBlockFut - except CancelledError as exc: - if not(normalBlockFut.finished()): - await normalBlockFut.cancelAndWait() - raise exc - except CatchableError: - # This should not happen, because all the exceptions are handled. - Opt.none(PreparedBlindedBeaconBlock) - - let normalBlock = - if blindedBlock.isNone(): - try: - await normalBlockFut - except CancelledError as exc: - raise exc - except CatchableError: - # This should not happen, because all the exceptions are handled. - Opt.none(PreparedBeaconBlock) - else: - if not(normalBlockFut.finished()): - asyncSpawn lazyWait(normalBlockFut) - Opt.none(PreparedBeaconBlock) - - if blindedBlock.isNone() and normalBlock.isNone(): - return - - (blindedBlock: blindedBlock, normalBlock: normalBlock) - - if beaconBlocks.blindedBlock.isSome(): - let - preparedBlock = beaconBlocks.blindedBlock.get() - signingRoot = compute_block_signing_root(fork, genesisRoot, slot, - preparedBlock.blockRoot) - notSlashable = vc.attachedValidators[] - .slashingProtection - .registerBlock(vindex, validator.pubkey, slot, signingRoot) - - logScope: - blck = shortLog(preparedBlock.data) - block_root = shortLog(preparedBlock.blockRoot) - signing_root = shortLog(signingRoot) - - if notSlashable.isOk(): - let - signature = - try: - let res = await validator.getBlockSignature(fork, genesisRoot, - slot, - preparedBlock.blockRoot, - preparedBlock.data) - if res.isErr(): - warn "Unable to sign blinded block proposal using remote signer", - reason = res.error() - return - res.get() - except CancelledError as exc: - debug "Blinded block signature process has been interrupted" - raise exc - except CatchableError as exc: - error "An unexpected error occurred while signing blinded block", - error_name = exc.name, error_msg = exc.msg - return - - logScope: - signature = shortLog(signature) - - let - signedBlock = ForkedSignedBlindedBeaconBlock.init(preparedBlock.data, - preparedBlock.blockRoot, signature) - res = - try: - debug "Sending blinded block" - await vc.publishBlindedBlock(signedBlock, ApiStrategyKind.First) - except ValidatorApiError as exc: - warn "Unable to publish blinded block", - reason = exc.getFailureReason() - return - except CancelledError as exc: - debug "Blinded block publication has been interrupted" - raise exc - except CatchableError as exc: - error "An unexpected error occurred while publishing blinded block", - error_name = exc.name, error_msg = exc.msg - return - - if res: - let delay = vc.getDelay(slot.block_deadline()) - beacon_blocks_sent.inc() - beacon_blocks_sent_delay.observe(delay.toFloatSeconds()) - notice "Blinded block published", delay = delay - else: - warn "Blinded block was not accepted by beacon node" - else: - warn "Slashing protection activated for blinded block proposal" - else: - let - preparedBlock = beaconBlocks.normalBlock.get() - signingRoot = compute_block_signing_root(fork, genesisRoot, slot, - preparedBlock.blockRoot) - notSlashable = vc.attachedValidators[] - .slashingProtection - .registerBlock(vindex, validator.pubkey, slot, signingRoot) - - logScope: - blck = shortLog(preparedBlock.data) - block_root = shortLog(preparedBlock.blockRoot) - signing_root = shortLog(signingRoot) - - if notSlashable.isOk(): - let - signature = - try: - let res = await validator.getBlockSignature(fork, - genesisRoot, slot, - preparedBlock.blockRoot, - preparedBlock.data) - if res.isErr(): - warn "Unable to sign block proposal using remote signer", - reason = res.error() - return - res.get() - except CancelledError as exc: - debug "Block signature process has been interrupted" - raise exc - except CatchableError as exc: - error "An unexpected error occurred while signing block", - error_name = exc.name, error_msg = exc.msg - return - - signedBlockContents = - case preparedBlock.data.kind - of ConsensusFork.Phase0: - RestPublishedSignedBlockContents(kind: ConsensusFork.Phase0, - phase0Data: phase0.SignedBeaconBlock( - message: preparedBlock.data.phase0Data, - root: preparedBlock.blockRoot, - signature: signature)) - of ConsensusFork.Altair: - RestPublishedSignedBlockContents(kind: ConsensusFork.Altair, - altairData: altair.SignedBeaconBlock( - message: preparedBlock.data.altairData, - root: preparedBlock.blockRoot, - signature: signature)) - of ConsensusFork.Bellatrix: - RestPublishedSignedBlockContents(kind: ConsensusFork.Bellatrix, - bellatrixData: bellatrix.SignedBeaconBlock( - message: preparedBlock.data.bellatrixData, - root: preparedBlock.blockRoot, - signature: signature)) - of ConsensusFork.Capella: - RestPublishedSignedBlockContents(kind: ConsensusFork.Capella, - capellaData: capella.SignedBeaconBlock( - message: preparedBlock.data.capellaData, - root: preparedBlock.blockRoot, - signature: signature)) - of ConsensusFork.Deneb: - RestPublishedSignedBlockContents(kind: ConsensusFork.Deneb, - denebData: DenebSignedBlockContents( - signed_block: deneb.SignedBeaconBlock( - message: preparedBlock.data.denebData, - root: preparedBlock.blockRoot, - signature: signature), - kzg_proofs: preparedBlock.kzgProofsOpt.get, - blobs: preparedBlock.blobsOpt.get)) - of ConsensusFork.Electra: - RestPublishedSignedBlockContents(kind: ConsensusFork.Electra, - electraData: ElectraSignedBlockContents( - signed_block: electra.SignedBeaconBlock( - message: preparedBlock.data.electraData, - root: preparedBlock.blockRoot, - signature: signature), - kzg_proofs: preparedBlock.kzgProofsOpt.get, - blobs: preparedBlock.blobsOpt.get)) - res = try: debug "Sending block" @@ -641,8 +291,6 @@ proc publishBlockV2(vc: ValidatorClientRef, currentSlot, slot: Slot, notice "Block published", delay = delay else: warn "Block was not accepted by beacon node" - else: - warn "Slashing protection activated for block proposal" proc publishBlock(vc: ValidatorClientRef, currentSlot, slot: Slot, validator: AttachedValidator) {.async.} = @@ -677,18 +325,7 @@ proc publishBlock(vc: ValidatorClientRef, currentSlot, slot: Slot, error_name = exc.name, error_msg = exc.msg return - # TODO (cheatfate): This branch should be removed as soon as `produceBlockV2` - # call will be fully deprecated. - if vc.isProduceBlockV3Supported(): - # We call `V3` first, if call fails and `isProduceBlockV3Supported()` - # did not find any nodes which support `V3` we try to call `V2`. - let res = - await vc.publishBlockV3(currentSlot, slot, fork, randaoReveal, validator) - if not(res) and not(vc.isProduceBlockV3Supported()): - notice "Block production using V3 failed, trying V2" - await vc.publishBlockV2(currentSlot, slot, fork, randaoReveal, validator) - else: - await vc.publishBlockV2(currentSlot, slot, fork, randaoReveal, validator) + await vc.publishBlockV3(currentSlot, slot, fork, randaoReveal, validator) proc proposeBlock(vc: ValidatorClientRef, slot: Slot, proposerKey: ValidatorPubKey) {.async.} = diff --git a/beacon_chain/validator_client/common.nim b/beacon_chain/validator_client/common.nim index 971302085..40cf6a637 100644 --- a/beacon_chain/validator_client/common.nim +++ b/beacon_chain/validator_client/common.nim @@ -117,7 +117,6 @@ type RestBeaconNodeFeature* {.pure.} = enum NoNimbusExtensions, ## BN does not support Nimbus Extensions - NoProduceBlockV3 ## BN does not support produceBlockV3 call TimeOffset* = object value: int64