raises for beacon validators & router (#5826)

Changes here are more significant because of some good old tech debt in
block production which has grown quite hairy - the reduction in
exception handling at least provides some steps in the right direction.
This commit is contained in:
Jacek Sieka 2024-02-07 12:26:04 +01:00 committed by GitHub
parent 94a65c2a9e
commit 47704bde14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 860 additions and 925 deletions

View File

@ -768,7 +768,7 @@ proc getPayload*(m: ELManager,
randomData: Eth2Digest, randomData: Eth2Digest,
suggestedFeeRecipient: Eth1Address, suggestedFeeRecipient: Eth1Address,
withdrawals: seq[capella.Withdrawal]): withdrawals: seq[capella.Withdrawal]):
Future[Opt[PayloadType]] {.async.} = Future[Opt[PayloadType]] {.async: (raises: [CancelledError]).} =
if m.elConnections.len == 0: if m.elConnections.len == 0:
return err() return err()
@ -790,6 +790,7 @@ proc getPayload*(m: ELManager,
)) ))
requestsCompleted = allFutures(requests) requestsCompleted = allFutures(requests)
# TODO cancel requests on cancellation
await requestsCompleted or deadline await requestsCompleted or deadline
var bestPayloadIdx = none int var bestPayloadIdx = none int
@ -807,40 +808,40 @@ proc getPayload*(m: ELManager,
# TODO: The engine_api module may offer an alternative API where it is guaranteed # TODO: The engine_api module may offer an alternative API where it is guaranteed
# to return the correct response type (i.e. the rule below will be enforced # to return the correct response type (i.e. the rule below will be enforced
# during deserialization). # during deserialization).
if req.read.executionPayload.withdrawals.isNone: if req.value().executionPayload.withdrawals.isNone:
warn "Execution client returned a block without a 'withdrawals' field for a post-Shanghai block", warn "Execution client returned a block without a 'withdrawals' field for a post-Shanghai block",
url = m.elConnections[idx].engineUrl.url url = m.elConnections[idx].engineUrl.url
continue continue
if engineApiWithdrawals != req.read.executionPayload.withdrawals.maybeDeref: if engineApiWithdrawals != req.value().executionPayload.withdrawals.maybeDeref:
# otherwise it formats as "@[(index: ..., validatorIndex: ..., # otherwise it formats as "@[(index: ..., validatorIndex: ...,
# address: ..., amount: ...), (index: ..., validatorIndex: ..., # address: ..., amount: ...), (index: ..., validatorIndex: ...,
# address: ..., amount: ...)]" # address: ..., amount: ...)]"
warn "Execution client did not return correct withdrawals", warn "Execution client did not return correct withdrawals",
withdrawals_from_cl_len = engineApiWithdrawals.len, withdrawals_from_cl_len = engineApiWithdrawals.len,
withdrawals_from_el_len = withdrawals_from_el_len =
req.read.executionPayload.withdrawals.maybeDeref.len, req.value().executionPayload.withdrawals.maybeDeref.len,
withdrawals_from_cl = withdrawals_from_cl =
mapIt(engineApiWithdrawals, it.asConsensusWithdrawal), mapIt(engineApiWithdrawals, it.asConsensusWithdrawal),
withdrawals_from_el = withdrawals_from_el =
mapIt( mapIt(
req.read.executionPayload.withdrawals.maybeDeref, req.value().executionPayload.withdrawals.maybeDeref,
it.asConsensusWithdrawal) it.asConsensusWithdrawal)
if req.read.executionPayload.extraData.len > MAX_EXTRA_DATA_BYTES: if req.value().executionPayload.extraData.len > MAX_EXTRA_DATA_BYTES:
warn "Execution client provided a block with invalid extraData (size exceeds limit)", warn "Execution client provided a block with invalid extraData (size exceeds limit)",
size = req.read.executionPayload.extraData.len, size = req.value().executionPayload.extraData.len,
limit = MAX_EXTRA_DATA_BYTES limit = MAX_EXTRA_DATA_BYTES
continue continue
if bestPayloadIdx.isNone: if bestPayloadIdx.isNone:
bestPayloadIdx = some idx bestPayloadIdx = some idx
else: else:
if cmpGetPayloadResponses(req.read, requests[bestPayloadIdx.get].read) > 0: if cmpGetPayloadResponses(req.value(), requests[bestPayloadIdx.get].value()) > 0:
bestPayloadIdx = some idx bestPayloadIdx = some idx
if bestPayloadIdx.isSome: if bestPayloadIdx.isSome:
return ok requests[bestPayloadIdx.get].read.asConsensusType return ok requests[bestPayloadIdx.get].value().asConsensusType
else: else:
return err() return err()

View File

@ -91,10 +91,10 @@ proc signDataPlain*(identifier: ValidatorPubKey,
proc init(t: typedesc[Web3SignerError], kind: Web3SignerErrorKind, proc init(t: typedesc[Web3SignerError], kind: Web3SignerErrorKind,
message: string): Web3SignerError = message: string): Web3SignerError =
Web3SignerError(kind: kind, message: message) Web3SignerError(kind: kind, message: message)
proc signData*(client: RestClientRef, identifier: ValidatorPubKey, proc signData*(client: RestClientRef, identifier: ValidatorPubKey,
body: Web3SignerRequest body: Web3SignerRequest
): Future[Web3SignerDataResponse] {.async.} = ): Future[Web3SignerDataResponse]
{.async: (raises: [CancelledError]).} =
inc(nbc_remote_signer_requests) inc(nbc_remote_signer_requests)
let let
@ -111,124 +111,118 @@ proc signData*(client: RestClientRef, identifier: ValidatorPubKey,
except RestError as exc: except RestError as exc:
return Web3SignerDataResponse.err( return Web3SignerDataResponse.err(
Web3SignerError.init(Web3SignerErrorKind.CommError, $exc.msg)) Web3SignerError.init(Web3SignerErrorKind.CommError, $exc.msg))
except CancelledError as exc:
raise exc
except CatchableError as exc:
return Web3SignerDataResponse.err(
Web3SignerError.init(Web3SignerErrorKind.UnexpectedError, $exc.msg))
return case response.status
case response.status of 200:
of 200: inc(nbc_remote_signer_200_responses)
inc(nbc_remote_signer_200_responses) let sig = block:
let sig = if response.contentType.isNone() or
if response.contentType.isNone() or isWildCard(response.contentType.get().mediaType):
isWildCard(response.contentType.get().mediaType):
inc(nbc_remote_signer_failures)
return Web3SignerDataResponse.err(
Web3SignerError.init(
Web3SignerErrorKind.InvalidContentType,
"Unable to decode signature from missing or incorrect content"
)
)
else:
let mediaType = response.contentType.get().mediaType
if mediaType == TextPlainMediaType:
let
asStr = fromBytes(string, response.data)
sigFromText = fromHex(ValidatorSig, asStr).valueOr:
inc(nbc_remote_signer_failures)
return Web3SignerDataResponse.err(
Web3SignerError.init(
Web3SignerErrorKind.InvalidPlain,
"Unable to decode signature from plain text"
)
)
sigFromText.load()
else:
let res = decodeBytes(Web3SignerSignatureResponse, response.data,
response.contentType).valueOr:
inc(nbc_remote_signer_failures)
return Web3SignerDataResponse.err(
Web3SignerError.init(
Web3SignerErrorKind.InvalidContent,
"Unable to decode remote signer response [" & $error & "]"
)
)
res.signature.load()
if sig.isNone():
inc(nbc_remote_signer_failures) inc(nbc_remote_signer_failures)
return Web3SignerDataResponse.err( return Web3SignerDataResponse.err(
Web3SignerError.init( Web3SignerError.init(
Web3SignerErrorKind.InvalidSignature, Web3SignerErrorKind.InvalidContentType,
"Remote signer returns invalid signature" "Unable to decode signature from missing or incorrect content"
) )
) )
inc(nbc_remote_signer_signatures) let mediaType = response.contentType.get().mediaType
Web3SignerDataResponse.ok(sig.get()) if mediaType == TextPlainMediaType:
of 400: let
inc(nbc_remote_signer_400_responses) asStr = fromBytes(string, response.data)
let message = sigFromText = fromHex(ValidatorSig, asStr).valueOr:
block: inc(nbc_remote_signer_failures)
let res = decodeBytes(Web3SignerErrorResponse, response.data, return Web3SignerDataResponse.err(
response.contentType) Web3SignerError.init(
if res.isErr(): Web3SignerErrorKind.InvalidPlain,
"Remote signer returns 400 Bad Request Format Error" "Unable to decode signature from plain text"
else: )
res.get().error )
Web3SignerDataResponse.err( sigFromText.load()
Web3SignerError.init(Web3SignerErrorKind.Error400, message)) else:
of 404: let res = decodeBytes(Web3SignerSignatureResponse, response.data,
inc(nbc_remote_signer_404_responses) response.contentType).valueOr:
let message = inc(nbc_remote_signer_failures)
block: return Web3SignerDataResponse.err(
let res = decodeBytes(Web3SignerErrorResponse, response.data, Web3SignerError.init(
response.contentType) Web3SignerErrorKind.InvalidContent,
if res.isErr(): "Unable to decode remote signer response [" & $error & "]"
"Remote signer returns 404 Validator's Key Not Found Error" )
else: )
res.get().error res.signature.load()
Web3SignerDataResponse.err(
Web3SignerError.init(Web3SignerErrorKind.Error404, message)) if sig.isNone():
of 412: inc(nbc_remote_signer_failures)
inc(nbc_remote_signer_412_responses) return Web3SignerDataResponse.err(
let message = Web3SignerError.init(
block: Web3SignerErrorKind.InvalidSignature,
let res = decodeBytes(Web3SignerErrorResponse, response.data, "Remote signer returns invalid signature"
response.contentType) )
if res.isErr(): )
"Remote signer returns 412 Slashing Protection Error"
else: inc(nbc_remote_signer_signatures)
res.get().error Web3SignerDataResponse.ok(sig.get())
Web3SignerDataResponse.err( of 400:
Web3SignerError.init(Web3SignerErrorKind.Error412, message)) inc(nbc_remote_signer_400_responses)
of 500: let message =
inc(nbc_remote_signer_500_responses) block:
let message = let res = decodeBytes(Web3SignerErrorResponse, response.data,
block: response.contentType)
let res = decodeBytes(Web3SignerErrorResponse, response.data, if res.isErr():
response.contentType) "Remote signer returns 400 Bad Request Format Error"
if res.isErr(): else:
"Remote signer returns 500 Internal Server Error" res.get().error
else: Web3SignerDataResponse.err(
res.get().error Web3SignerError.init(Web3SignerErrorKind.Error400, message))
Web3SignerDataResponse.err( of 404:
Web3SignerError.init(Web3SignerErrorKind.Error500, message)) inc(nbc_remote_signer_404_responses)
else: let message =
inc(nbc_remote_signer_unknown_responses) block:
let message = let res = decodeBytes(Web3SignerErrorResponse, response.data,
block: response.contentType)
let res = decodeBytes(Web3SignerErrorResponse, response.data, if res.isErr():
response.contentType) "Remote signer returns 404 Validator's Key Not Found Error"
if res.isErr(): else:
"Remote signer returns unexpected status code " & res.get().error
Base10.toString(uint64(response.status)) Web3SignerDataResponse.err(
else: Web3SignerError.init(Web3SignerErrorKind.Error404, message))
res.get().error of 412:
Web3SignerDataResponse.err( inc(nbc_remote_signer_412_responses)
Web3SignerError.init(Web3SignerErrorKind.UknownStatus, message)) let message =
block:
let res = decodeBytes(Web3SignerErrorResponse, response.data,
response.contentType)
if res.isErr():
"Remote signer returns 412 Slashing Protection Error"
else:
res.get().error
Web3SignerDataResponse.err(
Web3SignerError.init(Web3SignerErrorKind.Error412, message))
of 500:
inc(nbc_remote_signer_500_responses)
let message =
block:
let res = decodeBytes(Web3SignerErrorResponse, response.data,
response.contentType)
if res.isErr():
"Remote signer returns 500 Internal Server Error"
else:
res.get().error
Web3SignerDataResponse.err(
Web3SignerError.init(Web3SignerErrorKind.Error500, message))
else:
inc(nbc_remote_signer_unknown_responses)
let message =
block:
let res = decodeBytes(Web3SignerErrorResponse, response.data,
response.contentType)
if res.isErr():
"Remote signer returns unexpected status code " &
Base10.toString(uint64(response.status))
else:
res.get().error
Web3SignerDataResponse.err(
Web3SignerError.init(Web3SignerErrorKind.UknownStatus, message))
proc signData*( proc signData*(
client: RestClientRef, client: RestClientRef,
@ -236,7 +230,7 @@ proc signData*(
timerFut: Future[void], timerFut: Future[void],
attemptsCount: int, attemptsCount: int,
body: Web3SignerRequest body: Web3SignerRequest
): Future[Web3SignerDataResponse] {.async.} = ): Future[Web3SignerDataResponse] {.async: (raises: [CancelledError]).} =
doAssert(attemptsCount >= 1) doAssert(attemptsCount >= 1)
const BackoffTimeouts = [ const BackoffTimeouts = [
@ -249,14 +243,17 @@ proc signData*(
while true: while true:
var var
operationFut: Future[Web3SignerDataResponse] operationFut: Future[Web3SignerDataResponse].Raising([CancelledError])
lastError: Opt[Web3SignerError] lastError: Opt[Web3SignerError]
try: try:
operationFut = signData(client, identifier, body) operationFut = signData(client, identifier, body)
if isNil(timerFut): if isNil(timerFut):
await allFutures(operationFut) await allFutures(operationFut)
else: else:
discard await race(timerFut, operationFut) try:
discard await race(timerFut, operationFut)
except ValueError:
raiseAssert "race precondition satisfied"
except CancelledError as exc: except CancelledError as exc:
if not(operationFut.finished()): if not(operationFut.finished()):
await operationFut.cancelAndWait() await operationFut.cancelAndWait()
@ -275,7 +272,7 @@ proc signData*(
) )
) )
else: else:
let resp = operationFut.read() let resp = await operationFut
if resp.isOk(): if resp.isOk():
return resp return resp

File diff suppressed because it is too large Load Diff

View File

@ -632,7 +632,8 @@ proc existsKeystore(keystoreDir: string,
return true return true
false false
proc queryValidatorsSource*(web3signerUrl: Web3SignerUrl): Future[QueryResult] {.async.} = proc queryValidatorsSource*(web3signerUrl: Web3SignerUrl):
Future[QueryResult] {.async: (raises: [CancelledError]).} =
var keystores: seq[KeystoreData] var keystores: seq[KeystoreData]
logScope: logScope:
@ -671,13 +672,6 @@ proc queryValidatorsSource*(web3signerUrl: Web3SignerUrl): Future[QueryResult] {
except RestError as exc: except RestError as exc:
warn "Unable to poll validator's source", reason = $exc.msg warn "Unable to poll validator's source", reason = $exc.msg
return QueryResult.err($exc.msg) return QueryResult.err($exc.msg)
except CancelledError as exc:
debug "The polling of validator's source was interrupted"
raise exc
except CatchableError as exc:
warn "Unexpected error occured while polling validator's source",
error = $exc.name, reason = $exc.msg
return QueryResult.err($exc.msg)
remoteType = if web3signerUrl.provenBlockProperties.len == 0: remoteType = if web3signerUrl.provenBlockProperties.len == 0:
RemoteSignerType.Web3Signer RemoteSignerType.Web3Signer
@ -999,13 +993,7 @@ proc saveNetKeystore*(rng: var HmacDrbgContext, keystorePath: string,
let keyStore = createNetKeystore(kdfScrypt, rng, netKey, let keyStore = createNetKeystore(kdfScrypt, rng, netKey,
KeystorePass.init password) KeystorePass.init password)
var encodedStorage: string let encodedStorage = Json.encode(keyStore)
try:
encodedStorage = Json.encode(keyStore)
except SerializationError as exc:
error "Could not serialize network key storage", key_path = keystorePath
return err(KeystoreGenerationError(
kind: FailedToCreateKeystoreFile, error: exc.msg))
let res = secureWriteFile(keystorePath, encodedStorage) let res = secureWriteFile(keystorePath, encodedStorage)
if res.isOk(): if res.isOk():
@ -1182,14 +1170,7 @@ proc saveKeystore*(
let keyStore = createKeystore(kdfPbkdf2, rng, signingKey, let keyStore = createKeystore(kdfPbkdf2, rng, signingKey,
keypass, signingKeyPath, keypass, signingKeyPath,
mode = mode, salt = salt) mode = mode, salt = salt)
let encodedStorage = Json.encode(keyStore)
let encodedStorage =
try:
Json.encode(keyStore)
except SerializationError as e:
error "Could not serialize keystorage", key_path = keystoreFile
return err(KeystoreGenerationError(
kind: FailedToCreateKeystoreFile, error: e.msg))
? createLocalValidatorFiles(secretsDir, validatorsDir, ? createLocalValidatorFiles(secretsDir, validatorsDir,
keystoreDir, keystoreDir,
@ -1223,13 +1204,7 @@ proc saveLockedKeystore(
keypass, signingKeyPath, keypass, signingKeyPath,
mode = mode) mode = mode)
let encodedStorage = let encodedStorage = Json.encode(keyStore)
try:
Json.encode(keyStore)
except SerializationError as e:
error "Could not serialize keystorage", key_path = keystoreFile
return err(KeystoreGenerationError(
kind: FailedToCreateKeystoreFile, error: e.msg))
let lock = ? createLockedLocalValidatorFiles(secretsDir, validatorsDir, let lock = ? createLockedLocalValidatorFiles(secretsDir, validatorsDir,
keystoreDir, keystoreDir,
@ -1268,13 +1243,7 @@ proc saveKeystore(
return err(KeystoreGenerationError(kind: DuplicateKeystoreFile, return err(KeystoreGenerationError(kind: DuplicateKeystoreFile,
error: "Keystore file already exists")) error: "Keystore file already exists"))
let encodedStorage = let encodedStorage = Json.encode(keyStore)
try:
Json.encode(keyStore)
except SerializationError as exc:
error "Could not serialize keystorage", key_path = keystoreFile
return err(KeystoreGenerationError(
kind: FailedToCreateKeystoreFile, error: exc.msg))
? createRemoteValidatorFiles(validatorsDir, keystoreDir, keystoreFile, ? createRemoteValidatorFiles(validatorsDir, keystoreDir, keystoreFile,
encodedStorage) encodedStorage)
@ -1310,13 +1279,7 @@ proc saveLockedKeystore(
return err(KeystoreGenerationError(kind: DuplicateKeystoreFile, return err(KeystoreGenerationError(kind: DuplicateKeystoreFile,
error: "Keystore file already exists")) error: "Keystore file already exists"))
let encodedStorage = let encodedStorage = Json.encode(keyStore)
try:
Json.encode(keyStore)
except SerializationError as exc:
error "Could not serialize keystorage", key_path = keystoreFile
return err(KeystoreGenerationError(
kind: FailedToCreateKeystoreFile, error: exc.msg))
let lock = ? createLockedRemoteValidatorFiles(validatorsDir, keystoreDir, let lock = ? createLockedRemoteValidatorFiles(validatorsDir, keystoreDir,
keystoreFile, encodedStorage) keystoreFile, encodedStorage)
@ -1633,12 +1596,9 @@ proc generateDeposits*(cfg: RuntimeConfig,
ok deposits ok deposits
proc saveWallet(wallet: Wallet, outWalletPath: string): Result[void, string] = proc saveWallet(wallet: Wallet, outWalletPath: string): Result[void, string] =
let walletDir = splitFile(outWalletPath).dir let
var encodedWallet: string walletDir = splitFile(outWalletPath).dir
try:
encodedWallet = Json.encode(wallet, pretty = true) encodedWallet = Json.encode(wallet, pretty = true)
except SerializationError:
return err("Could not serialize wallet")
? secureCreatePath(walletDir).mapErr(proc(e: auto): string = ? secureCreatePath(walletDir).mapErr(proc(e: auto): string =
"Could not create wallet directory [" & walletDir & "]: " & $e) "Could not create wallet directory [" & walletDir & "]: " & $e)

View File

@ -85,7 +85,8 @@ template getCurrentBeaconTime(router: MessageRouter): BeaconTime =
type RouteBlockResult = Result[Opt[BlockRef], string] type RouteBlockResult = Result[Opt[BlockRef], string]
proc routeSignedBeaconBlock*( proc routeSignedBeaconBlock*(
router: ref MessageRouter, blck: ForkySignedBeaconBlock, router: ref MessageRouter, blck: ForkySignedBeaconBlock,
blobsOpt: Opt[seq[BlobSidecar]]): Future[RouteBlockResult] {.async.} = blobsOpt: Opt[seq[BlobSidecar]]):
Future[RouteBlockResult] {.async: (raises: [CancelledError]).} =
## Validate and broadcast beacon block, then add it to the block database ## Validate and broadcast beacon block, then add it to the block database
## Returns the new Head when block is added successfully to dag, none when ## Returns the new Head when block is added successfully to dag, none when
## block passes validation but is not added, and error otherwise ## block passes validation but is not added, and error otherwise
@ -191,7 +192,8 @@ proc routeSignedBeaconBlock*(
proc routeAttestation*( proc routeAttestation*(
router: ref MessageRouter, attestation: Attestation, router: ref MessageRouter, attestation: Attestation,
subnet_id: SubnetId, checkSignature: bool): Future[SendResult] {.async.} = subnet_id: SubnetId, checkSignature: bool):
Future[SendResult] {.async: (raises: [CancelledError]).} =
## Process and broadcast attestation - processing will register the it with ## Process and broadcast attestation - processing will register the it with
## the attestation pool ## the attestation pool
block: block:
@ -222,7 +224,7 @@ proc routeAttestation*(
proc routeAttestation*( proc routeAttestation*(
router: ref MessageRouter, attestation: Attestation): router: ref MessageRouter, attestation: Attestation):
Future[SendResult] {.async.} = Future[SendResult] {.async: (raises: [CancelledError]).} =
# Compute subnet, then route attestation # Compute subnet, then route attestation
let let
target = router[].dag.getBlockRef(attestation.data.target.root).valueOr: target = router[].dag.getBlockRef(attestation.data.target.root).valueOr:
@ -252,7 +254,7 @@ proc routeAttestation*(
proc routeSignedAggregateAndProof*( proc routeSignedAggregateAndProof*(
router: ref MessageRouter, proof: SignedAggregateAndProof, router: ref MessageRouter, proof: SignedAggregateAndProof,
checkSignature = true): checkSignature = true):
Future[SendResult] {.async.} = Future[SendResult] {.async: (raises: [CancelledError]).} =
## Validate and broadcast aggregate ## Validate and broadcast aggregate
block: block:
# Because the aggregate was (most likely) produced by this beacon node, # Because the aggregate was (most likely) produced by this beacon node,
@ -292,7 +294,8 @@ proc routeSignedAggregateAndProof*(
proc routeSyncCommitteeMessage*( proc routeSyncCommitteeMessage*(
router: ref MessageRouter, msg: SyncCommitteeMessage, router: ref MessageRouter, msg: SyncCommitteeMessage,
subcommitteeIdx: SyncSubcommitteeIndex, subcommitteeIdx: SyncSubcommitteeIndex,
checkSignature: bool): Future[SendResult] {.async.} = checkSignature: bool):
Future[SendResult] {.async: (raises: [CancelledError]).} =
block: block:
let res = await router[].processor.processSyncCommitteeMessage( let res = await router[].processor.processSyncCommitteeMessage(
MsgSource.api, msg, subcommitteeIdx, checkSignature) MsgSource.api, msg, subcommitteeIdx, checkSignature)
@ -325,7 +328,7 @@ proc routeSyncCommitteeMessage*(
proc routeSyncCommitteeMessages*( proc routeSyncCommitteeMessages*(
router: ref MessageRouter, msgs: seq[SyncCommitteeMessage]): router: ref MessageRouter, msgs: seq[SyncCommitteeMessage]):
Future[seq[SendResult]] {.async.} = Future[seq[SendResult]] {.async: (raises: [CancelledError]).} =
return withState(router[].dag.headState): return withState(router[].dag.headState):
when consensusFork >= ConsensusFork.Altair: when consensusFork >= ConsensusFork.Altair:
var statuses = newSeq[Opt[SendResult]](len(msgs)) var statuses = newSeq[Opt[SendResult]](len(msgs))
@ -382,13 +385,13 @@ proc routeSyncCommitteeMessages*(
for index, future in pending: for index, future in pending:
if future.completed(): if future.completed():
let fres = future.read() let fres = future.value()
if fres.isErr(): if fres.isErr():
statuses[indices[index]] = Opt.some(SendResult.err(fres.error())) statuses[indices[index]] = Opt.some(SendResult.err(fres.error()))
else: else:
statuses[indices[index]] = Opt.some(SendResult.ok()) statuses[indices[index]] = Opt.some(SendResult.ok())
elif future.failed() or future.cancelled(): elif future.failed() or future.cancelled():
let exc = future.readError() let exc = future.error()
debug "Unexpected failure while sending committee message", debug "Unexpected failure while sending committee message",
message = msgs[indices[index]], error = $exc.msg message = msgs[indices[index]], error = $exc.msg
statuses[indices[index]] = Opt.some(SendResult.err( statuses[indices[index]] = Opt.some(SendResult.err(
@ -410,7 +413,8 @@ proc routeSyncCommitteeMessages*(
proc routeSignedContributionAndProof*( proc routeSignedContributionAndProof*(
router: ref MessageRouter, router: ref MessageRouter,
msg: SignedContributionAndProof, msg: SignedContributionAndProof,
checkSignature: bool): Future[SendResult] {.async.} = checkSignature: bool):
Future[SendResult] {.async: (raises: [CancelledError]).} =
block: block:
let res = await router[].processor.processSignedContributionAndProof( let res = await router[].processor.processSignedContributionAndProof(
MsgSource.api, msg) MsgSource.api, msg)
@ -445,7 +449,7 @@ proc routeSignedContributionAndProof*(
proc routeSignedVoluntaryExit*( proc routeSignedVoluntaryExit*(
router: ref MessageRouter, exit: SignedVoluntaryExit): router: ref MessageRouter, exit: SignedVoluntaryExit):
Future[SendResult] {.async.} = Future[SendResult] {.async: (raises: [CancelledError]).} =
block: block:
let res = let res =
router[].processor[].processSignedVoluntaryExit(MsgSource.api, exit) router[].processor[].processSignedVoluntaryExit(MsgSource.api, exit)
@ -465,7 +469,7 @@ proc routeSignedVoluntaryExit*(
proc routeAttesterSlashing*( proc routeAttesterSlashing*(
router: ref MessageRouter, slashing: AttesterSlashing): router: ref MessageRouter, slashing: AttesterSlashing):
Future[SendResult] {.async.} = Future[SendResult] {.async: (raises: [CancelledError]).} =
block: block:
let res = let res =
router[].processor[].processAttesterSlashing(MsgSource.api, slashing) router[].processor[].processAttesterSlashing(MsgSource.api, slashing)
@ -486,7 +490,7 @@ proc routeAttesterSlashing*(
proc routeProposerSlashing*( proc routeProposerSlashing*(
router: ref MessageRouter, slashing: ProposerSlashing): router: ref MessageRouter, slashing: ProposerSlashing):
Future[SendResult] {.async.} = Future[SendResult] {.async: (raises: [CancelledError]).} =
block: block:
let res = let res =
router[].processor[].processProposerSlashing(MsgSource.api, slashing) router[].processor[].processProposerSlashing(MsgSource.api, slashing)
@ -508,7 +512,7 @@ proc routeProposerSlashing*(
proc routeBlsToExecutionChange*( proc routeBlsToExecutionChange*(
router: ref MessageRouter, router: ref MessageRouter,
bls_to_execution_change: SignedBLSToExecutionChange): bls_to_execution_change: SignedBLSToExecutionChange):
Future[SendResult] {.async.} = Future[SendResult] {.async: (raises: [CancelledError]).} =
block: block:
let res = await router.processor.processBlsToExecutionChange( let res = await router.processor.processBlsToExecutionChange(
MsgSource.api, bls_to_execution_change) MsgSource.api, bls_to_execution_change)

View File

@ -47,7 +47,7 @@ proc unblindAndRouteBlockMEV*(
blindedBlock: blindedBlock:
capella_mev.SignedBlindedBeaconBlock | capella_mev.SignedBlindedBeaconBlock |
deneb_mev.SignedBlindedBeaconBlock): deneb_mev.SignedBlindedBeaconBlock):
Future[Result[Opt[BlockRef], string]] {.async.} = Future[Result[Opt[BlockRef], string]] {.async: (raises: [CancelledError]).} =
const consensusFork = typeof(blindedBlock).kind const consensusFork = typeof(blindedBlock).kind
info "Proposing blinded Builder API block", info "Proposing blinded Builder API block",
@ -63,7 +63,9 @@ proc unblindAndRouteBlockMEV*(
return err("Submitting blinded block timed out") return err("Submitting blinded block timed out")
# From here on, including error paths, disallow local EL production by # From here on, including error paths, disallow local EL production by
# returning Opt.some, regardless of whether on head or newBlock. # returning Opt.some, regardless of whether on head or newBlock.
except CatchableError as exc: except RestDecodingError as exc:
return err("REST decoding error submitting blinded block: " & exc.msg)
except RestError as exc:
return err("exception in submitBlindedBlock: " & exc.msg) return err("exception in submitBlindedBlock: " & exc.msg)
const httpOk = 200 const httpOk = 200

View File

@ -36,7 +36,8 @@ proc toAttestation*(
registered.data, signature).expect("valid data") registered.data, signature).expect("valid data")
proc waitAfterBlockCutoff*(clock: BeaconClock, slot: Slot, proc waitAfterBlockCutoff*(clock: BeaconClock, slot: Slot,
head: Opt[BlockRef] = Opt.none(BlockRef)) {.async.} = head: Opt[BlockRef] = Opt.none(BlockRef))
{.async: (raises: [CancelledError]).} =
# The expected block arrived (or expectBlock was called again which # The expected block arrived (or expectBlock was called again which
# shouldn't happen as this is the only place we use it) - in our async # shouldn't happen as this is the only place we use it) - in our async
# loop however, we might have been doing other processing that caused delays # loop however, we might have been doing other processing that caused delays

View File

@ -436,7 +436,7 @@ proc updateDynamicValidators*(pool: ref ValidatorPool,
proc signWithDistributedKey(v: AttachedValidator, proc signWithDistributedKey(v: AttachedValidator,
request: Web3SignerRequest): Future[SignatureResult] request: Web3SignerRequest): Future[SignatureResult]
{.async.} = {.async: (raises: [CancelledError]).} =
doAssert v.data.threshold <= uint32(v.clients.len) doAssert v.data.threshold <= uint32(v.clients.len)
let let
@ -453,8 +453,8 @@ proc signWithDistributedKey(v: AttachedValidator,
for i, req in signatureReqs: for i, req in signatureReqs:
template shareInfo: untyped = v.clients[i][1] template shareInfo: untyped = v.clients[i][1]
if req.completed() and req.read.isOk: if req.completed() and req.value().isOk:
shares.add req.read.get.toSignatureShare(shareInfo.id) shares.add req.value.get.toSignatureShare(shareInfo.id)
neededShares = neededShares - 1 neededShares = neededShares - 1
else: else:
warn "Failed to obtain signature from remote signer", warn "Failed to obtain signature from remote signer",
@ -467,11 +467,11 @@ proc signWithDistributedKey(v: AttachedValidator,
let recovered = shares.recoverSignature() let recovered = shares.recoverSignature()
return SignatureResult.ok recovered.toValidatorSig return SignatureResult.ok recovered.toValidatorSig
return SignatureResult.err "Not enough shares to recover the signature" SignatureResult.err "Not enough shares to recover the signature"
proc signWithSingleKey(v: AttachedValidator, proc signWithSingleKey(v: AttachedValidator,
request: Web3SignerRequest): Future[SignatureResult] {. request: Web3SignerRequest): Future[SignatureResult]
async.} = {.async: (raises: [CancelledError]).} =
doAssert v.clients.len == 1 doAssert v.clients.len == 1
let let
deadline = sleepAsync(WEB3_SIGNER_DELAY_TOLERANCE) deadline = sleepAsync(WEB3_SIGNER_DELAY_TOLERANCE)
@ -480,12 +480,13 @@ proc signWithSingleKey(v: AttachedValidator,
if not(deadline.finished()): await cancelAndWait(deadline) if not(deadline.finished()): await cancelAndWait(deadline)
if res.isErr(): if res.isErr():
return SignatureResult.err(res.error.message) SignatureResult.err(res.error.message)
else: else:
return SignatureResult.ok(res.get().toValidatorSig()) SignatureResult.ok(res.get().toValidatorSig())
proc signData(v: AttachedValidator, proc signData(v: AttachedValidator,
request: Web3SignerRequest): Future[SignatureResult] = request: Web3SignerRequest): Future[SignatureResult]
{.async: (raises: [CancelledError], raw: true).} =
doAssert v.kind == ValidatorKind.Remote doAssert v.kind == ValidatorKind.Remote
debug "Signing request with remote signer", debug "Signing request with remote signer",
validator = shortLog(v), kind = request.kind validator = shortLog(v), kind = request.kind
@ -502,7 +503,8 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
ForkedMaybeBlindedBeaconBlock | ForkedMaybeBlindedBeaconBlock |
capella_mev.BlindedBeaconBlock | capella_mev.BlindedBeaconBlock |
deneb_mev.BlindedBeaconBlock deneb_mev.BlindedBeaconBlock
): Future[SignatureResult] {.async.} = ): Future[SignatureResult]
{.async: (raises: [CancelledError]).} =
type SomeBlockBody = type SomeBlockBody =
bellatrix.BeaconBlockBody | bellatrix.BeaconBlockBody |
capella.BeaconBlockBody | capella.BeaconBlockBody |
@ -525,226 +527,225 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
proof: proofRes.get) proof: proofRes.get)
proofs proofs
return case v.kind
case v.kind of ValidatorKind.Local:
of ValidatorKind.Local: SignatureResult.ok(
SignatureResult.ok( get_block_signature(
get_block_signature( fork, genesis_validators_root, slot, block_root,
fork, genesis_validators_root, slot, block_root, v.data.privateKey).toValidatorSig())
v.data.privateKey).toValidatorSig()) of ValidatorKind.Remote:
of ValidatorKind.Remote: let web3signerRequest =
let web3signerRequest = when blck is ForkedBlindedBeaconBlock:
when blck is ForkedBlindedBeaconBlock: case blck.kind
case blck.kind of ConsensusFork.Phase0, ConsensusFork.Altair, ConsensusFork.Bellatrix:
of ConsensusFork.Phase0, ConsensusFork.Altair, ConsensusFork.Bellatrix: return SignatureResult.err("Invalid beacon block fork version")
of ConsensusFork.Capella:
case v.data.remoteType
of RemoteSignerType.Web3Signer:
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
data: blck.capellaData.toBeaconBlockHeader))
of RemoteSignerType.VerifyingWeb3Signer:
let proofs = blockPropertiesProofs(
blck.capellaData.body, capellaIndex)
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
data: blck.capellaData.toBeaconBlockHeader),
proofs)
of ConsensusFork.Deneb:
case v.data.remoteType
of RemoteSignerType.Web3Signer:
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
data: blck.denebData.toBeaconBlockHeader))
of RemoteSignerType.VerifyingWeb3Signer:
let proofs = blockPropertiesProofs(
blck.denebData.body, denebIndex)
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
data: blck.denebData.toBeaconBlockHeader),
proofs)
elif blck is capella_mev.BlindedBeaconBlock:
case v.data.remoteType
of RemoteSignerType.Web3Signer:
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
data: blck.toBeaconBlockHeader))
of RemoteSignerType.VerifyingWeb3Signer:
let proofs = blockPropertiesProofs(
blck.body, capellaIndex)
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
data: blck.toBeaconBlockHeader),
proofs)
elif blck is deneb_mev.BlindedBeaconBlock:
case v.data.remoteType
of RemoteSignerType.Web3Signer:
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
data: blck.toBeaconBlockHeader))
of RemoteSignerType.VerifyingWeb3Signer:
let proofs = blockPropertiesProofs(
blck.body, denebIndex)
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
data: blck.toBeaconBlockHeader),
proofs)
elif blck is ForkedMaybeBlindedBeaconBlock:
withForkyMaybeBlindedBlck(blck):
when consensusFork < ConsensusFork.Bellatrix:
return SignatureResult.err("Invalid beacon block fork version") return SignatureResult.err("Invalid beacon block fork version")
of ConsensusFork.Capella: elif consensusFork == ConsensusFork.Bellatrix:
case v.data.remoteType when isBlinded:
of RemoteSignerType.Web3Signer:
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
data: blck.capellaData.toBeaconBlockHeader))
of RemoteSignerType.VerifyingWeb3Signer:
let proofs = blockPropertiesProofs(
blck.capellaData.body, capellaIndex)
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
data: blck.capellaData.toBeaconBlockHeader),
proofs)
of ConsensusFork.Deneb:
case v.data.remoteType
of RemoteSignerType.Web3Signer:
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
data: blck.denebData.toBeaconBlockHeader))
of RemoteSignerType.VerifyingWeb3Signer:
let proofs = blockPropertiesProofs(
blck.denebData.body, denebIndex)
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
data: blck.denebData.toBeaconBlockHeader),
proofs)
elif blck is capella_mev.BlindedBeaconBlock:
case v.data.remoteType
of RemoteSignerType.Web3Signer:
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
data: blck.toBeaconBlockHeader))
of RemoteSignerType.VerifyingWeb3Signer:
let proofs = blockPropertiesProofs(
blck.body, capellaIndex)
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
data: blck.toBeaconBlockHeader),
proofs)
elif blck is deneb_mev.BlindedBeaconBlock:
case v.data.remoteType
of RemoteSignerType.Web3Signer:
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
data: blck.toBeaconBlockHeader))
of RemoteSignerType.VerifyingWeb3Signer:
let proofs = blockPropertiesProofs(
blck.body, denebIndex)
Web3SignerRequest.init(fork, genesis_validators_root,
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
data: blck.toBeaconBlockHeader),
proofs)
elif blck is ForkedMaybeBlindedBeaconBlock:
withForkyMaybeBlindedBlck(blck):
when consensusFork < ConsensusFork.Bellatrix:
return SignatureResult.err("Invalid beacon block fork version") return SignatureResult.err("Invalid beacon block fork version")
elif consensusFork == ConsensusFork.Bellatrix: else:
when isBlinded: case v.data.remoteType
return SignatureResult.err("Invalid beacon block fork version") of RemoteSignerType.Web3Signer:
else: Web3SignerRequest.init(fork, genesis_validators_root,
case v.data.remoteType Web3SignerForkedBeaconBlock(kind: ConsensusFork.Bellatrix,
of RemoteSignerType.Web3Signer: data: forkyMaybeBlindedBlck.toBeaconBlockHeader))
Web3SignerRequest.init(fork, genesis_validators_root, of RemoteSignerType.VerifyingWeb3Signer:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Bellatrix, let proofs = blockPropertiesProofs(
data: forkyMaybeBlindedBlck.toBeaconBlockHeader)) blck.bellatrixData.body, bellatrixIndex)
of RemoteSignerType.VerifyingWeb3Signer: Web3SignerRequest.init(fork, genesis_validators_root,
let proofs = blockPropertiesProofs( Web3SignerForkedBeaconBlock(kind: ConsensusFork.Bellatrix,
blck.bellatrixData.body, bellatrixIndex) data: forkyMaybeBlindedBlck.toBeaconBlockHeader),
Web3SignerRequest.init(fork, genesis_validators_root, proofs)
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Bellatrix, elif consensusFork == ConsensusFork.Capella:
data: forkyMaybeBlindedBlck.toBeaconBlockHeader), when isBlinded:
proofs) case v.data.remoteType
elif consensusFork == ConsensusFork.Capella: of RemoteSignerType.Web3Signer:
when isBlinded: Web3SignerRequest.init(fork, genesis_validators_root,
case v.data.remoteType Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
of RemoteSignerType.Web3Signer: data: forkyMaybeBlindedBlck.toBeaconBlockHeader))
Web3SignerRequest.init(fork, genesis_validators_root, of RemoteSignerType.VerifyingWeb3Signer:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella, let proofs =
data: forkyMaybeBlindedBlck.toBeaconBlockHeader)) blockPropertiesProofs(forkyMaybeBlindedBlck.body,
of RemoteSignerType.VerifyingWeb3Signer: capellaIndex)
let proofs = Web3SignerRequest.init(fork, genesis_validators_root,
blockPropertiesProofs(forkyMaybeBlindedBlck.body, Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
capellaIndex) data: forkyMaybeBlindedBlck.toBeaconBlockHeader), proofs)
Web3SignerRequest.init(fork, genesis_validators_root, else:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella, case v.data.remoteType
data: forkyMaybeBlindedBlck.toBeaconBlockHeader), proofs) of RemoteSignerType.Web3Signer:
else: Web3SignerRequest.init(fork, genesis_validators_root,
case v.data.remoteType Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
of RemoteSignerType.Web3Signer: data: forkyMaybeBlindedBlck.toBeaconBlockHeader))
Web3SignerRequest.init(fork, genesis_validators_root, of RemoteSignerType.VerifyingWeb3Signer:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella, let proofs =
data: forkyMaybeBlindedBlck.toBeaconBlockHeader)) blockPropertiesProofs(forkyMaybeBlindedBlck.body,
of RemoteSignerType.VerifyingWeb3Signer: capellaIndex)
let proofs = Web3SignerRequest.init(fork, genesis_validators_root,
blockPropertiesProofs(forkyMaybeBlindedBlck.body, Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
capellaIndex) data: forkyMaybeBlindedBlck.toBeaconBlockHeader),
Web3SignerRequest.init(fork, genesis_validators_root, proofs)
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella, elif consensusFork == ConsensusFork.Deneb:
data: forkyMaybeBlindedBlck.toBeaconBlockHeader), when isBlinded:
proofs) case v.data.remoteType
elif consensusFork == ConsensusFork.Deneb: of RemoteSignerType.Web3Signer:
when isBlinded: Web3SignerRequest.init(fork, genesis_validators_root,
case v.data.remoteType Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
of RemoteSignerType.Web3Signer: data: forkyMaybeBlindedBlck.toBeaconBlockHeader))
Web3SignerRequest.init(fork, genesis_validators_root, of RemoteSignerType.VerifyingWeb3Signer:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb, let proofs =
data: forkyMaybeBlindedBlck.toBeaconBlockHeader)) blockPropertiesProofs(forkyMaybeBlindedBlck.body,
of RemoteSignerType.VerifyingWeb3Signer: denebIndex)
let proofs = Web3SignerRequest.init(fork, genesis_validators_root,
blockPropertiesProofs(forkyMaybeBlindedBlck.body, Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
denebIndex) data: forkyMaybeBlindedBlck.toBeaconBlockHeader), proofs)
Web3SignerRequest.init(fork, genesis_validators_root, else:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb, case v.data.remoteType
data: forkyMaybeBlindedBlck.toBeaconBlockHeader), proofs) of RemoteSignerType.Web3Signer:
else: Web3SignerRequest.init(fork, genesis_validators_root,
case v.data.remoteType Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
of RemoteSignerType.Web3Signer: data: forkyMaybeBlindedBlck.`block`.toBeaconBlockHeader))
Web3SignerRequest.init(fork, genesis_validators_root, of RemoteSignerType.VerifyingWeb3Signer:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb, let proofs =
data: forkyMaybeBlindedBlck.`block`.toBeaconBlockHeader)) blockPropertiesProofs(forkyMaybeBlindedBlck.`block`.body,
of RemoteSignerType.VerifyingWeb3Signer: denebIndex)
let proofs = Web3SignerRequest.init(fork, genesis_validators_root,
blockPropertiesProofs(forkyMaybeBlindedBlck.`block`.body, Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
denebIndex) data: forkyMaybeBlindedBlck.`block`.toBeaconBlockHeader),
Web3SignerRequest.init(fork, genesis_validators_root, proofs)
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb, else:
data: forkyMaybeBlindedBlck.`block`.toBeaconBlockHeader), case blck.kind
proofs) of ConsensusFork.Phase0, ConsensusFork.Altair:
else: return SignatureResult.err("Invalid beacon block fork version")
case blck.kind of ConsensusFork.Bellatrix:
of ConsensusFork.Phase0, ConsensusFork.Altair: case v.data.remoteType
return SignatureResult.err("Invalid beacon block fork version") of RemoteSignerType.Web3Signer:
of ConsensusFork.Bellatrix: Web3SignerRequest.init(fork, genesis_validators_root,
case v.data.remoteType Web3SignerForkedBeaconBlock(kind: ConsensusFork.Bellatrix,
of RemoteSignerType.Web3Signer: data: blck.bellatrixData.toBeaconBlockHeader))
Web3SignerRequest.init(fork, genesis_validators_root, of RemoteSignerType.VerifyingWeb3Signer:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Bellatrix, let proofs = blockPropertiesProofs(
data: blck.bellatrixData.toBeaconBlockHeader)) blck.bellatrixData.body, bellatrixIndex)
of RemoteSignerType.VerifyingWeb3Signer: Web3SignerRequest.init(fork, genesis_validators_root,
let proofs = blockPropertiesProofs( Web3SignerForkedBeaconBlock(kind: ConsensusFork.Bellatrix,
blck.bellatrixData.body, bellatrixIndex) data: blck.bellatrixData.toBeaconBlockHeader),
Web3SignerRequest.init(fork, genesis_validators_root, proofs)
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Bellatrix, of ConsensusFork.Capella:
data: blck.bellatrixData.toBeaconBlockHeader), case v.data.remoteType
proofs) of RemoteSignerType.Web3Signer:
of ConsensusFork.Capella: Web3SignerRequest.init(fork, genesis_validators_root,
case v.data.remoteType Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
of RemoteSignerType.Web3Signer: data: blck.capellaData.toBeaconBlockHeader))
Web3SignerRequest.init(fork, genesis_validators_root, of RemoteSignerType.VerifyingWeb3Signer:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella, let proofs = blockPropertiesProofs(
data: blck.capellaData.toBeaconBlockHeader)) blck.capellaData.body, capellaIndex)
of RemoteSignerType.VerifyingWeb3Signer: Web3SignerRequest.init(fork, genesis_validators_root,
let proofs = blockPropertiesProofs( Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
blck.capellaData.body, capellaIndex) data: blck.capellaData.toBeaconBlockHeader),
Web3SignerRequest.init(fork, genesis_validators_root, proofs)
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella, of ConsensusFork.Deneb:
data: blck.capellaData.toBeaconBlockHeader), case v.data.remoteType
proofs) of RemoteSignerType.Web3Signer:
of ConsensusFork.Deneb: Web3SignerRequest.init(fork, genesis_validators_root,
case v.data.remoteType Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
of RemoteSignerType.Web3Signer: data: blck.denebData.toBeaconBlockHeader))
Web3SignerRequest.init(fork, genesis_validators_root, of RemoteSignerType.VerifyingWeb3Signer:
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb, let proofs = blockPropertiesProofs(
data: blck.denebData.toBeaconBlockHeader)) blck.denebData.body, denebIndex)
of RemoteSignerType.VerifyingWeb3Signer: Web3SignerRequest.init(fork, genesis_validators_root,
let proofs = blockPropertiesProofs( Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
blck.denebData.body, denebIndex) data: blck.denebData.toBeaconBlockHeader),
Web3SignerRequest.init(fork, genesis_validators_root, proofs)
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb, await v.signData(web3signerRequest)
data: blck.denebData.toBeaconBlockHeader),
proofs)
await v.signData(web3signerRequest)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/validator.md#aggregate-signature # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/validator.md#aggregate-signature
proc getAttestationSignature*(v: AttachedValidator, fork: Fork, proc getAttestationSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, genesis_validators_root: Eth2Digest,
data: AttestationData data: AttestationData
): Future[SignatureResult] {.async.} = ): Future[SignatureResult]
return {.async: (raises: [CancelledError]).} =
case v.kind case v.kind
of ValidatorKind.Local: of ValidatorKind.Local:
SignatureResult.ok( SignatureResult.ok(
get_attestation_signature( get_attestation_signature(
fork, genesis_validators_root, data, fork, genesis_validators_root, data,
v.data.privateKey).toValidatorSig()) v.data.privateKey).toValidatorSig())
of ValidatorKind.Remote: of ValidatorKind.Remote:
let request = Web3SignerRequest.init(fork, genesis_validators_root, data) let request = Web3SignerRequest.init(fork, genesis_validators_root, data)
await v.signData(request) await v.signData(request)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/validator.md#broadcast-aggregate # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/validator.md#broadcast-aggregate
proc getAggregateAndProofSignature*(v: AttachedValidator, proc getAggregateAndProofSignature*(v: AttachedValidator,
fork: Fork, fork: Fork,
genesis_validators_root: Eth2Digest, genesis_validators_root: Eth2Digest,
aggregate_and_proof: AggregateAndProof aggregate_and_proof: AggregateAndProof
): Future[SignatureResult] {.async.} = ): Future[SignatureResult]
return {.async: (raises: [CancelledError]).} =
case v.kind case v.kind
of ValidatorKind.Local: of ValidatorKind.Local:
SignatureResult.ok( SignatureResult.ok(
get_aggregate_and_proof_signature( get_aggregate_and_proof_signature(
fork, genesis_validators_root, aggregate_and_proof, fork, genesis_validators_root, aggregate_and_proof,
v.data.privateKey).toValidatorSig() v.data.privateKey).toValidatorSig()
) )
of ValidatorKind.Remote: of ValidatorKind.Remote:
let request = Web3SignerRequest.init( let request = Web3SignerRequest.init(
fork, genesis_validators_root, aggregate_and_proof) fork, genesis_validators_root, aggregate_and_proof)
await v.signData(request) await v.signData(request)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/altair/validator.md#prepare-sync-committee-message # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/altair/validator.md#prepare-sync-committee-message
proc getSyncCommitteeMessage*(v: AttachedValidator, proc getSyncCommitteeMessage*(v: AttachedValidator,
@ -752,7 +753,8 @@ proc getSyncCommitteeMessage*(v: AttachedValidator,
genesis_validators_root: Eth2Digest, genesis_validators_root: Eth2Digest,
slot: Slot, slot: Slot,
beacon_block_root: Eth2Digest beacon_block_root: Eth2Digest
): Future[SyncCommitteeMessageResult] {.async.} = ): Future[SyncCommitteeMessageResult]
{.async: (raises: [CancelledError]).} =
let signature = let signature =
case v.kind case v.kind
of ValidatorKind.Local: of ValidatorKind.Local:
@ -765,58 +767,58 @@ proc getSyncCommitteeMessage*(v: AttachedValidator,
await v.signData(request) await v.signData(request)
if signature.isErr: if signature.isErr:
return SyncCommitteeMessageResult.err("Failed to obtain signature") return err("Failed to obtain signature")
return ok(
SyncCommitteeMessageResult.ok( SyncCommitteeMessage(
SyncCommitteeMessage( slot: slot,
slot: slot, beacon_block_root: beacon_block_root,
beacon_block_root: beacon_block_root, validator_index: uint64(v.index.get()),
validator_index: uint64(v.index.get()), signature: signature.get()
signature: signature.get()
)
) )
)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/altair/validator.md#aggregation-selection # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/altair/validator.md#aggregation-selection
proc getSyncCommitteeSelectionProof*(v: AttachedValidator, fork: Fork, proc getSyncCommitteeSelectionProof*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, genesis_validators_root: Eth2Digest,
slot: Slot, slot: Slot,
subcommittee_index: SyncSubcommitteeIndex subcommittee_index: SyncSubcommitteeIndex
): Future[SignatureResult] {.async.} = ): Future[SignatureResult]
return {.async: (raises: [CancelledError]).} =
case v.kind case v.kind
of ValidatorKind.Local: of ValidatorKind.Local:
SignatureResult.ok(get_sync_committee_selection_proof( SignatureResult.ok(get_sync_committee_selection_proof(
fork, genesis_validators_root, slot, subcommittee_index, fork, genesis_validators_root, slot, subcommittee_index,
v.data.privateKey).toValidatorSig()) v.data.privateKey).toValidatorSig())
of ValidatorKind.Remote: of ValidatorKind.Remote:
let request = Web3SignerRequest.init( let request = Web3SignerRequest.init(
fork, genesis_validators_root, fork, genesis_validators_root,
SyncAggregatorSelectionData( SyncAggregatorSelectionData(
slot: slot, subcommittee_index: uint64 subcommittee_index) slot: slot, subcommittee_index: uint64 subcommittee_index)
) )
await v.signData(request) await v.signData(request)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/altair/validator.md#broadcast-sync-committee-contribution # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/altair/validator.md#broadcast-sync-committee-contribution
proc getContributionAndProofSignature*(v: AttachedValidator, fork: Fork, proc getContributionAndProofSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, genesis_validators_root: Eth2Digest,
contribution_and_proof: ContributionAndProof contribution_and_proof: ContributionAndProof
): Future[SignatureResult] {.async.} = ): Future[SignatureResult]
return {.async: (raises: [CancelledError]).} =
case v.kind case v.kind
of ValidatorKind.Local: of ValidatorKind.Local:
SignatureResult.ok(get_contribution_and_proof_signature( SignatureResult.ok(get_contribution_and_proof_signature(
fork, genesis_validators_root, contribution_and_proof, fork, genesis_validators_root, contribution_and_proof,
v.data.privateKey).toValidatorSig()) v.data.privateKey).toValidatorSig())
of ValidatorKind.Remote: of ValidatorKind.Remote:
let request = Web3SignerRequest.init( let request = Web3SignerRequest.init(
fork, genesis_validators_root, contribution_and_proof) fork, genesis_validators_root, contribution_and_proof)
await v.signData(request) await v.signData(request)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/validator.md#randao-reveal # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/validator.md#randao-reveal
proc getEpochSignature*(v: AttachedValidator, fork: Fork, proc getEpochSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, epoch: Epoch genesis_validators_root: Eth2Digest, epoch: Epoch
): Future[SignatureResult] {.async.} = ): Future[SignatureResult]
{.async: (raises: [CancelledError]).} =
if v.epochSignature.isSome and v.epochSignature.get.epoch == epoch: if v.epochSignature.isSome and v.epochSignature.get.epoch == epoch:
return SignatureResult.ok(v.epochSignature.get.signature) return SignatureResult.ok(v.epochSignature.get.signature)
@ -840,7 +842,8 @@ proc getEpochSignature*(v: AttachedValidator, fork: Fork,
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/validator.md#aggregation-selection # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/validator.md#aggregation-selection
proc getSlotSignature*(v: AttachedValidator, fork: Fork, proc getSlotSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, slot: Slot genesis_validators_root: Eth2Digest, slot: Slot
): Future[SignatureResult] {.async.} = ): Future[SignatureResult]
{.async: (raises: [CancelledError]).} =
if v.slotSignature.isSome and v.slotSignature.get.slot == slot: if v.slotSignature.isSome and v.slotSignature.get.slot == slot:
return SignatureResult.ok(v.slotSignature.get.signature) return SignatureResult.ok(v.slotSignature.get.signature)
@ -863,41 +866,40 @@ proc getSlotSignature*(v: AttachedValidator, fork: Fork,
proc getValidatorExitSignature*(v: AttachedValidator, fork: Fork, proc getValidatorExitSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, genesis_validators_root: Eth2Digest,
voluntary_exit: VoluntaryExit voluntary_exit: VoluntaryExit
): Future[SignatureResult] {.async.} = ): Future[SignatureResult]
return {.async: (raises: [CancelledError]).} =
case v.kind case v.kind
of ValidatorKind.Local: of ValidatorKind.Local:
SignatureResult.ok(get_voluntary_exit_signature( SignatureResult.ok(get_voluntary_exit_signature(
fork, genesis_validators_root, voluntary_exit, fork, genesis_validators_root, voluntary_exit,
v.data.privateKey).toValidatorSig()) v.data.privateKey).toValidatorSig())
of ValidatorKind.Remote: of ValidatorKind.Remote:
let request = Web3SignerRequest.init(fork, genesis_validators_root, let request = Web3SignerRequest.init(fork, genesis_validators_root,
voluntary_exit) voluntary_exit)
await v.signData(request) await v.signData(request)
proc getDepositMessageSignature*(v: AttachedValidator, version: Version, proc getDepositMessageSignature*(v: AttachedValidator, version: Version,
deposit_message: DepositMessage deposit_message: DepositMessage
): Future[SignatureResult] {.async.} = ): Future[SignatureResult]
return {.async: (raises: [CancelledError]).} =
case v.kind case v.kind
of ValidatorKind.Local: of ValidatorKind.Local:
SignatureResult.ok(get_deposit_signature( SignatureResult.ok(get_deposit_signature(
deposit_message, version, deposit_message, version,
v.data.privateKey).toValidatorSig()) v.data.privateKey).toValidatorSig())
of ValidatorKind.Remote: of ValidatorKind.Remote:
let request = Web3SignerRequest.init(version, deposit_message) let request = Web3SignerRequest.init(version, deposit_message)
await v.signData(request) await v.signData(request)
# https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/builder.md#signing # https://github.com/ethereum/builder-specs/blob/v0.4.0/specs/bellatrix/builder.md#signing
proc getBuilderSignature*(v: AttachedValidator, fork: Fork, proc getBuilderSignature*(v: AttachedValidator, fork: Fork,
validatorRegistration: ValidatorRegistrationV1): validatorRegistration: ValidatorRegistrationV1):
Future[SignatureResult] {.async.} = Future[SignatureResult] {.async: (raises: [CancelledError]).} =
return case v.kind
case v.kind of ValidatorKind.Local:
of ValidatorKind.Local: SignatureResult.ok(get_builder_signature(
SignatureResult.ok(get_builder_signature( fork, validatorRegistration, v.data.privateKey).toValidatorSig())
fork, validatorRegistration, v.data.privateKey).toValidatorSig()) of ValidatorKind.Remote:
of ValidatorKind.Remote: let request = Web3SignerRequest.init(
let request = Web3SignerRequest.init( fork, ZERO_HASH, validatorRegistration)
fork, ZERO_HASH, validatorRegistration) await v.signData(request)
await v.signData(request)