Adopt asyncraises guarantees to most of the REST API handlers. (#5803)
* Adopt asyncraises guarantees to most of the REST API handlers. Bump presto. * Fix copyright year. --------- Co-authored-by: Etan Kissling <etan@status.im>
This commit is contained in:
parent
9acb7b99fe
commit
525b994e7d
|
@ -129,14 +129,17 @@ proc toString*(kind: ValidatorFilterKind): string =
|
|||
|
||||
proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4881.md
|
||||
router.api(MethodGet, "/eth/v1/beacon/deposit_snapshot") do () -> RestApiResponse:
|
||||
router.api2(MethodGet, "/eth/v1/beacon/deposit_snapshot") do (
|
||||
) -> RestApiResponse:
|
||||
let snapshot = node.db.getDepositTreeSnapshot().valueOr:
|
||||
# This can happen in a very short window after the client is started, but the
|
||||
# snapshot record still haven't been upgraded in the database. Returning 404
|
||||
# should be easy to handle for the clients - they just need to retry.
|
||||
return RestApiResponse.jsonError(Http404, NoFinalizedSnapshotAvailableError)
|
||||
# This can happen in a very short window after the client is started,
|
||||
# but the snapshot record still haven't been upgraded in the database.
|
||||
# Returning 404 should be easy to handle for the clients - they just need
|
||||
# to retry.
|
||||
return RestApiResponse.jsonError(Http404,
|
||||
NoFinalizedSnapshotAvailableError)
|
||||
|
||||
return RestApiResponse.jsonResponse(
|
||||
RestApiResponse.jsonResponse(
|
||||
RestDepositSnapshot(
|
||||
finalized: snapshot.depositContractState.branch,
|
||||
deposit_root: snapshot.getDepositRoot(),
|
||||
|
@ -145,8 +148,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
execution_block_height: snapshot.blockHeight))
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getGenesis
|
||||
router.api(MethodGet, "/eth/v1/beacon/genesis") do () -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(
|
||||
router.api2(MethodGet, "/eth/v1/beacon/genesis") do () -> RestApiResponse:
|
||||
RestApiResponse.jsonResponse(
|
||||
(
|
||||
genesis_time: getStateField(node.dag.headState, genesis_time),
|
||||
genesis_validators_root:
|
||||
|
@ -156,7 +159,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateRoot
|
||||
router.api(MethodGet, "/eth/v1/beacon/states/{state_id}/root") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/states/{state_id}/root") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let
|
||||
sid = state_id.valueOr:
|
||||
|
@ -177,10 +180,10 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.dag.isFinalized(bslot.bid)
|
||||
)
|
||||
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateFork
|
||||
router.api(MethodGet, "/eth/v1/beacon/states/{state_id}/fork") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/states/{state_id}/fork") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let
|
||||
sid = state_id.valueOr:
|
||||
|
@ -207,11 +210,12 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.getStateOptimistic(state),
|
||||
node.dag.isFinalized(bslot.bid)
|
||||
)
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateFinalityCheckpoints
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/finality_checkpoints") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/finality_checkpoints") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let
|
||||
sid = state_id.valueOr:
|
||||
|
@ -238,7 +242,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.getStateOptimistic(state),
|
||||
node.dag.isFinalized(bslot.bid)
|
||||
)
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
proc getIndices(
|
||||
node: BeaconNode,
|
||||
|
@ -369,7 +374,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateValidators
|
||||
router.api(MethodGet, "/eth/v1/beacon/states/{state_id}/validators") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/states/{state_id}/validators") do (
|
||||
state_id: StateIdent, id: seq[ValidatorIdent],
|
||||
status: seq[ValidatorFilter]) -> RestApiResponse:
|
||||
let
|
||||
|
@ -404,7 +409,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
getValidators(node, bslot, validatorsMask, validatorIds)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/postStateValidators
|
||||
router.api(MethodPost, "/eth/v1/beacon/states/{state_id}/validators") do (
|
||||
router.api2(MethodPost, "/eth/v1/beacon/states/{state_id}/validators") do (
|
||||
state_id: StateIdent, contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let
|
||||
(validatorIds, validatorsMask) =
|
||||
|
@ -431,8 +436,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
getValidators(node, bslot, validatorsMask, validatorIds)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateValidator
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/validators/{validator_id}") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/validators/{validator_id}") do (
|
||||
state_id: StateIdent, validator_id: ValidatorIdent) -> RestApiResponse:
|
||||
let
|
||||
sid = state_id.valueOr:
|
||||
|
@ -465,7 +470,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
of ValidatorQueryKind.Index:
|
||||
let vres = vid.index.toValidatorIndex()
|
||||
if vres.isErr():
|
||||
case vres.error()
|
||||
case vres.error
|
||||
of ValidatorIndexError.TooHighValue:
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
TooHighValidatorIndexValueError)
|
||||
|
@ -493,11 +498,12 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.getStateOptimistic(state),
|
||||
node.dag.isFinalized(bslot.bid)
|
||||
)
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateValidatorBalances
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/validator_balances") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/validator_balances") do (
|
||||
state_id: StateIdent, id: seq[ValidatorIdent]) -> RestApiResponse:
|
||||
let
|
||||
sid = state_id.valueOr:
|
||||
|
@ -522,8 +528,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
getBalances(node, bslot, validatorIds)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/postStateValidatorBalances
|
||||
router.api(MethodPost,
|
||||
"/eth/v1/beacon/states/{state_id}/validator_balances") do (
|
||||
router.api2(MethodPost,
|
||||
"/eth/v1/beacon/states/{state_id}/validator_balances") do (
|
||||
state_id: StateIdent, contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let
|
||||
validatorIds =
|
||||
|
@ -546,8 +552,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
getBalances(node, bslot, validatorIds)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getEpochCommittees
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/committees") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/committees") do (
|
||||
state_id: StateIdent, epoch: Option[Epoch], index: Option[CommitteeIndex],
|
||||
slot: Option[Slot]) -> RestApiResponse:
|
||||
let
|
||||
|
@ -567,7 +573,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let repoch = epoch.get()
|
||||
if repoch.isErr():
|
||||
return RestApiResponse.jsonError(Http400, InvalidEpochValueError,
|
||||
$repoch.error())
|
||||
$repoch.error)
|
||||
let res = repoch.get()
|
||||
|
||||
if res > bslot.slot.epoch + MIN_SEED_LOOKAHEAD:
|
||||
|
@ -590,7 +596,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if rindex.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
InvalidCommitteeIndexValueError,
|
||||
$rindex.error())
|
||||
$rindex.error)
|
||||
some(rindex.get())
|
||||
else:
|
||||
none[CommitteeIndex]()
|
||||
|
@ -599,12 +605,13 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let rslot = slot.get()
|
||||
if rslot.isErr():
|
||||
return RestApiResponse.jsonError(Http400, InvalidSlotValueError,
|
||||
$rslot.error())
|
||||
$rslot.error)
|
||||
let res = rslot.get()
|
||||
if vepoch.isSome():
|
||||
if res.epoch != vepoch.get():
|
||||
return RestApiResponse.jsonError(Http400, InvalidSlotValueError,
|
||||
"Slot does not match requested epoch")
|
||||
return RestApiResponse.jsonError(
|
||||
Http400, InvalidSlotValueError,
|
||||
"Slot does not match requested epoch")
|
||||
else:
|
||||
if res.epoch > bslot.slot.epoch + 1:
|
||||
return RestApiResponse.jsonError(
|
||||
|
@ -620,6 +627,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
some(res)
|
||||
else:
|
||||
none[Slot]()
|
||||
|
||||
node.withStateForBlockSlotId(bslot):
|
||||
proc getCommittee(slot: Slot,
|
||||
index: CommitteeIndex): RestBeaconStatesCommittees =
|
||||
|
@ -660,11 +668,11 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.dag.isFinalized(bslot.bid)
|
||||
)
|
||||
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getEpochSyncCommittees
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/sync_committees") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/sync_committees") do (
|
||||
state_id: StateIdent, epoch: Option[Epoch]) -> RestApiResponse:
|
||||
let
|
||||
sid = state_id.valueOr:
|
||||
|
@ -683,7 +691,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let repoch = epoch.get()
|
||||
if repoch.isErr():
|
||||
return RestApiResponse.jsonError(Http400, InvalidEpochValueError,
|
||||
$repoch.error())
|
||||
$repoch.error)
|
||||
let res = repoch.get()
|
||||
if res > MaxEpoch:
|
||||
return RestApiResponse.jsonError(Http400, EpochOverflowValueError)
|
||||
|
@ -702,7 +710,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let res = syncCommitteeParticipants(state, qepoch)
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
$res.error())
|
||||
$res.error)
|
||||
let kres = res.get()
|
||||
if len(kres) == 0:
|
||||
return RestApiResponse.jsonError(Http500, InternalServerError,
|
||||
|
@ -742,12 +750,12 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.dag.isFinalized(bslot.bid)
|
||||
)
|
||||
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getStateRandao
|
||||
# https://github.com/ethereum/beacon-APIs/blob/b3c4defa238aaa74bf22aa602aa1b24b68a4c78e/apis/beacon/states/randao.yaml
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/randao") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/randao") do (
|
||||
state_id: StateIdent, epoch: Option[Epoch]) -> RestApiResponse:
|
||||
let
|
||||
sid = state_id.valueOr:
|
||||
|
@ -766,7 +774,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let repoch = epoch.get()
|
||||
if repoch.isErr():
|
||||
return RestApiResponse.jsonError(Http400, InvalidEpochValueError,
|
||||
$repoch.error())
|
||||
$repoch.error)
|
||||
let res = repoch.get()
|
||||
if res > MaxEpoch:
|
||||
return RestApiResponse.jsonError(Http400, EpochOverflowValueError)
|
||||
|
@ -801,10 +809,10 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.dag.isFinalized(bslot.bid)
|
||||
)
|
||||
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeaders
|
||||
router.api(MethodGet, "/eth/v1/beacon/headers") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/headers") do (
|
||||
slot: Option[Slot], parent_root: Option[Eth2Digest]) -> RestApiResponse:
|
||||
# TODO (cheatfate): This call is incomplete, because structure
|
||||
# of database do not allow to query blocks by `parent_root`.
|
||||
|
@ -813,7 +821,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let rslot = slot.get()
|
||||
if rslot.isErr():
|
||||
return RestApiResponse.jsonError(Http400, InvalidSlotValueError,
|
||||
$rslot.error())
|
||||
$rslot.error)
|
||||
rslot.get()
|
||||
else:
|
||||
node.dag.head.slot
|
||||
|
@ -822,32 +830,31 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let rroot = parent_root.get()
|
||||
if rroot.isErr():
|
||||
return RestApiResponse.jsonError(Http400, InvalidParentRootValueError,
|
||||
$rroot.error())
|
||||
$rroot.error)
|
||||
return RestApiResponse.jsonError(Http500, NoImplementationError)
|
||||
|
||||
let bdata = node.getForkedBlock(BlockIdent.init(qslot)).valueOr:
|
||||
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
|
||||
|
||||
return
|
||||
withBlck(bdata):
|
||||
let bid = BlockId(root: forkyBlck.root, slot: forkyBlck.message.slot)
|
||||
RestApiResponse.jsonResponseFinalized(
|
||||
[
|
||||
(
|
||||
root: forkyBlck.root,
|
||||
canonical: node.dag.isCanonical(bid),
|
||||
header: (
|
||||
message: forkyBlck.toBeaconBlockHeader,
|
||||
signature: forkyBlck.signature
|
||||
)
|
||||
withBlck(bdata):
|
||||
let bid = BlockId(root: forkyBlck.root, slot: forkyBlck.message.slot)
|
||||
RestApiResponse.jsonResponseFinalized(
|
||||
[
|
||||
(
|
||||
root: forkyBlck.root,
|
||||
canonical: node.dag.isCanonical(bid),
|
||||
header: (
|
||||
message: forkyBlck.toBeaconBlockHeader,
|
||||
signature: forkyBlck.signature
|
||||
)
|
||||
],
|
||||
node.getBlockOptimistic(bdata),
|
||||
node.dag.isFinalized(bid)
|
||||
)
|
||||
)
|
||||
],
|
||||
node.getBlockOptimistic(bdata),
|
||||
node.dag.isFinalized(bid)
|
||||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeader
|
||||
router.api(MethodGet, "/eth/v1/beacon/headers/{block_id}") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/headers/{block_id}") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
let
|
||||
bid = block_id.valueOr:
|
||||
|
@ -857,21 +864,20 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
bdata = node.getForkedBlock(bid).valueOr:
|
||||
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
|
||||
|
||||
return
|
||||
withBlck(bdata):
|
||||
let bid = BlockId(root: forkyBlck.root, slot: forkyBlck.message.slot)
|
||||
RestApiResponse.jsonResponseFinalized(
|
||||
(
|
||||
root: forkyBlck.root,
|
||||
canonical: node.dag.isCanonical(bid),
|
||||
header: (
|
||||
message: forkyBlck.toBeaconBlockHeader,
|
||||
signature: forkyBlck.signature
|
||||
)
|
||||
),
|
||||
node.getBlockOptimistic(bdata),
|
||||
node.dag.isFinalized(bid)
|
||||
)
|
||||
withBlck(bdata):
|
||||
let bid = BlockId(root: forkyBlck.root, slot: forkyBlck.message.slot)
|
||||
RestApiResponse.jsonResponseFinalized(
|
||||
(
|
||||
root: forkyBlck.root,
|
||||
canonical: node.dag.isCanonical(bid),
|
||||
header: (
|
||||
message: forkyBlck.toBeaconBlockHeader,
|
||||
signature: forkyBlck.signature
|
||||
)
|
||||
),
|
||||
node.getBlockOptimistic(bdata),
|
||||
node.dag.isFinalized(bid)
|
||||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlock
|
||||
router.api(MethodPost, "/eth/v1/beacon/blocks") do (
|
||||
|
@ -924,11 +930,11 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
Http503, BeaconNodeInSyncError, $res.error())
|
||||
Http503, BeaconNodeInSyncError, $res.error)
|
||||
if res.get().isNone():
|
||||
return RestApiResponse.jsonError(Http202, BlockValidationError)
|
||||
|
||||
return RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
|
||||
RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlockV2
|
||||
router.api(MethodPost, "/eth/v2/beacon/blocks") do (
|
||||
|
@ -1000,11 +1006,11 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
Http503, BeaconNodeInSyncError, $res.error())
|
||||
Http503, BeaconNodeInSyncError, $res.error)
|
||||
if res.get().isNone():
|
||||
return RestApiResponse.jsonError(Http202, BlockValidationError)
|
||||
|
||||
return RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
|
||||
RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlock
|
||||
# https://github.com/ethereum/beacon-APIs/blob/v2.4.0/apis/beacon/blocks/blinded_blocks.yaml
|
||||
|
@ -1046,7 +1052,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
Http500, InternalServerError, $res.error())
|
||||
Http500, InternalServerError, $res.error)
|
||||
if res.get().isNone():
|
||||
return RestApiResponse.jsonError(Http202, BlockValidationError)
|
||||
|
||||
|
@ -1076,20 +1082,20 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
Http503, BeaconNodeInSyncError, $res.error())
|
||||
Http503, BeaconNodeInSyncError, $res.error)
|
||||
elif res.get().isNone():
|
||||
return RestApiResponse.jsonError(Http202, BlockValidationError)
|
||||
|
||||
return RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
|
||||
RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlock
|
||||
router.api(MethodGet, "/eth/v1/beacon/blocks/{block_id}") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/blocks/{block_id}") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
return RestApiResponse.jsonError(
|
||||
RestApiResponse.jsonError(
|
||||
Http410, DeprecatedRemovalBeaconBlocksDebugStateV1)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockV2
|
||||
router.api(MethodGet, "/eth/v2/beacon/blocks/{block_id}") do (
|
||||
router.api2(MethodGet, "/eth/v2/beacon/blocks/{block_id}") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
let
|
||||
blockIdent = block_id.valueOr:
|
||||
|
@ -1105,31 +1111,31 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http406, ContentNotAcceptableError)
|
||||
res.get()
|
||||
return
|
||||
if contentType == sszMediaType:
|
||||
var data: seq[byte]
|
||||
if not node.dag.getBlockSSZ(bid, data):
|
||||
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
|
||||
|
||||
let
|
||||
fork = node.dag.cfg.consensusForkAtEpoch(bid.slot.epoch)
|
||||
headers = [("eth-consensus-version", fork.toString())]
|
||||
if contentType == sszMediaType:
|
||||
var data: seq[byte]
|
||||
if not node.dag.getBlockSSZ(bid, data):
|
||||
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
|
||||
|
||||
RestApiResponse.sszResponsePlain(data, headers)
|
||||
elif contentType == jsonMediaType:
|
||||
let bdata = node.dag.getForkedBlock(bid).valueOr:
|
||||
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
|
||||
let
|
||||
fork = node.dag.cfg.consensusForkAtEpoch(bid.slot.epoch)
|
||||
headers = [("eth-consensus-version", fork.toString())]
|
||||
|
||||
RestApiResponse.jsonResponseBlock(
|
||||
bdata.asSigned(),
|
||||
node.getBlockOptimistic(bdata),
|
||||
node.dag.isFinalized(bid)
|
||||
)
|
||||
else:
|
||||
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
||||
RestApiResponse.sszResponsePlain(data, headers)
|
||||
elif contentType == jsonMediaType:
|
||||
let bdata = node.dag.getForkedBlock(bid).valueOr:
|
||||
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
|
||||
|
||||
RestApiResponse.jsonResponseBlock(
|
||||
bdata.asSigned(),
|
||||
node.getBlockOptimistic(bdata),
|
||||
node.dag.isFinalized(bid)
|
||||
)
|
||||
else:
|
||||
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockRoot
|
||||
router.api(MethodGet, "/eth/v1/beacon/blocks/{block_id}/root") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/blocks/{block_id}/root") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
let
|
||||
blockIdent = block_id.valueOr:
|
||||
|
@ -1142,14 +1148,14 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
bdata = node.dag.getForkedBlock(bid).valueOr:
|
||||
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
|
||||
|
||||
return RestApiResponse.jsonResponseFinalized(
|
||||
RestApiResponse.jsonResponseFinalized(
|
||||
(root: bid.root),
|
||||
node.getBlockOptimistic(bdata),
|
||||
node.dag.isFinalized(bid)
|
||||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockAttestations
|
||||
router.api(MethodGet,
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/blocks/{block_id}/attestations") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
let
|
||||
|
@ -1159,17 +1165,16 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
bdata = node.getForkedBlock(blockIdent).valueOr:
|
||||
return RestApiResponse.jsonError(Http404, BlockNotFoundError)
|
||||
|
||||
return
|
||||
withBlck(bdata):
|
||||
let bid = BlockId(root: forkyBlck.root, slot: forkyBlck.message.slot)
|
||||
RestApiResponse.jsonResponseFinalized(
|
||||
forkyBlck.message.body.attestations.asSeq(),
|
||||
node.getBlockOptimistic(bdata),
|
||||
node.dag.isFinalized(bid)
|
||||
)
|
||||
withBlck(bdata):
|
||||
let bid = BlockId(root: forkyBlck.root, slot: forkyBlck.message.slot)
|
||||
RestApiResponse.jsonResponseFinalized(
|
||||
forkyBlck.message.body.attestations.asSeq(),
|
||||
node.getBlockOptimistic(bdata),
|
||||
node.dag.isFinalized(bid)
|
||||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolAttestations
|
||||
router.api(MethodGet, "/eth/v1/beacon/pool/attestations") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/pool/attestations") do (
|
||||
slot: Option[Slot],
|
||||
committee_index: Option[CommitteeIndex]) -> RestApiResponse:
|
||||
let vindex =
|
||||
|
@ -1178,7 +1183,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if rindex.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
InvalidCommitteeIndexValueError,
|
||||
$rindex.error())
|
||||
$rindex.error)
|
||||
Opt.some(rindex.get())
|
||||
else:
|
||||
Opt.none(CommitteeIndex)
|
||||
|
@ -1187,17 +1192,17 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let rslot = slot.get()
|
||||
if rslot.isErr():
|
||||
return RestApiResponse.jsonError(Http400, InvalidSlotValueError,
|
||||
$rslot.error())
|
||||
$rslot.error)
|
||||
Opt.some(rslot.get())
|
||||
else:
|
||||
Opt.none(Slot)
|
||||
var res: seq[Attestation]
|
||||
for item in node.attestationPool[].attestations(vslot, vindex):
|
||||
res.add(item)
|
||||
return RestApiResponse.jsonResponse(res)
|
||||
RestApiResponse.jsonResponse(res)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolAttestations
|
||||
router.api(MethodPost, "/eth/v1/beacon/pool/attestations") do (
|
||||
router.api2(MethodPost, "/eth/v1/beacon/pool/attestations") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let attestations =
|
||||
block:
|
||||
|
@ -1207,7 +1212,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if dres.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
InvalidAttestationObjectError,
|
||||
$dres.error())
|
||||
$dres.error)
|
||||
dres.get()
|
||||
|
||||
# Since our validation logic supports batch processing, we will submit all
|
||||
|
@ -1224,29 +1229,29 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
await allFutures(pending)
|
||||
for index, future in pending:
|
||||
if future.completed():
|
||||
let fres = future.read()
|
||||
let fres = future.value()
|
||||
if fres.isErr():
|
||||
let failure = RestIndexedErrorMessageItem(index: index,
|
||||
message: $fres.error())
|
||||
message: $fres.error)
|
||||
res.add(failure)
|
||||
elif future.failed() or future.cancelled():
|
||||
# This is unexpected failure, so we log the error message.
|
||||
let exc = future.readError()
|
||||
let exc = future.error()
|
||||
let failure = RestIndexedErrorMessageItem(index: index,
|
||||
message: $exc.msg)
|
||||
res.add(failure)
|
||||
res
|
||||
|
||||
if len(failures) > 0:
|
||||
return RestApiResponse.jsonErrorList(Http400, AttestationValidationError,
|
||||
failures)
|
||||
RestApiResponse.jsonErrorList(Http400, AttestationValidationError,
|
||||
failures)
|
||||
else:
|
||||
return RestApiResponse.jsonMsgResponse(AttestationValidationSuccess)
|
||||
RestApiResponse.jsonMsgResponse(AttestationValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolAttesterSlashings
|
||||
router.api(MethodGet, "/eth/v1/beacon/pool/attester_slashings") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/pool/attester_slashings") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(
|
||||
RestApiResponse.jsonResponse(
|
||||
toSeq(node.validatorChangePool.attester_slashings))
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolAttesterSlashings
|
||||
|
@ -1260,19 +1265,19 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if dres.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
InvalidAttesterSlashingObjectError,
|
||||
$dres.error())
|
||||
$dres.error)
|
||||
dres.get()
|
||||
let res = await node.router.routeAttesterSlashing(slashing)
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
AttesterSlashingValidationError,
|
||||
$res.error())
|
||||
return RestApiResponse.jsonMsgResponse(AttesterSlashingValidationSuccess)
|
||||
$res.error)
|
||||
RestApiResponse.jsonMsgResponse(AttesterSlashingValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolProposerSlashings
|
||||
router.api(MethodGet, "/eth/v1/beacon/pool/proposer_slashings") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/pool/proposer_slashings") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(
|
||||
RestApiResponse.jsonResponse(
|
||||
toSeq(node.validatorChangePool.proposer_slashings))
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolProposerSlashings
|
||||
|
@ -1286,55 +1291,58 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if dres.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
InvalidProposerSlashingObjectError,
|
||||
$dres.error())
|
||||
$dres.error)
|
||||
dres.get()
|
||||
let res = await node.router.routeProposerSlashing(slashing)
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
ProposerSlashingValidationError,
|
||||
$res.error())
|
||||
return RestApiResponse.jsonMsgResponse(ProposerSlashingValidationSuccess)
|
||||
$res.error)
|
||||
RestApiResponse.jsonMsgResponse(ProposerSlashingValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getPoolBLSToExecutionChanges
|
||||
# https://github.com/ethereum/beacon-APIs/blob/86850001845df9163da5ae9605dbf15cd318d5d0/apis/beacon/pool/bls_to_execution_changes.yaml
|
||||
router.api(MethodGet, "/eth/v1/beacon/pool/bls_to_execution_changes") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/pool/bls_to_execution_changes") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(
|
||||
RestApiResponse.jsonResponse(
|
||||
toSeq(node.validatorChangePool.bls_to_execution_changes_gossip) &
|
||||
toSeq(node.validatorChangePool.bls_to_execution_changes_api))
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/submitPoolBLSToExecutionChange
|
||||
# https://github.com/ethereum/beacon-APIs/blob/86850001845df9163da5ae9605dbf15cd318d5d0/apis/beacon/pool/bls_to_execution_changes.yaml
|
||||
router.api(MethodPost, "/eth/v1/beacon/pool/bls_to_execution_changes") do (
|
||||
router.api2(MethodPost, "/eth/v1/beacon/pool/bls_to_execution_changes") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
if node.currentSlot().epoch() < node.dag.cfg.CAPELLA_FORK_EPOCH:
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
InvalidBlsToExecutionChangeObjectError,
|
||||
"Attempt to add to BLS to execution change pool pre-Capella")
|
||||
let bls_to_execution_changes =
|
||||
block:
|
||||
if contentBody.isNone():
|
||||
return RestApiResponse.jsonError(Http400, EmptyRequestBodyError)
|
||||
let dres = decodeBody(seq[SignedBLSToExecutionChange], contentBody.get())
|
||||
if dres.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
InvalidBlsToExecutionChangeObjectError,
|
||||
$dres.error())
|
||||
dres.get()
|
||||
let res = await allFinished(mapIt(
|
||||
bls_to_execution_changes, node.router.routeBlsToExecutionChange(it)))
|
||||
for individual_res in res:
|
||||
doAssert individual_res.finished()
|
||||
if individual_res.failed():
|
||||
let
|
||||
bls_to_execution_changes =
|
||||
block:
|
||||
if contentBody.isNone():
|
||||
return RestApiResponse.jsonError(Http400, EmptyRequestBodyError)
|
||||
let dres =
|
||||
decodeBody(seq[SignedBLSToExecutionChange], contentBody.get())
|
||||
if dres.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
Http400, InvalidBlsToExecutionChangeObjectError, $dres.error)
|
||||
dres.get()
|
||||
pending = mapIt(bls_to_execution_changes,
|
||||
node.router.routeBlsToExecutionChange(it))
|
||||
|
||||
await allFutures(pending)
|
||||
|
||||
for future in pending:
|
||||
if future.failed() or future.cancelled():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
BlsToExecutionChangeValidationError,
|
||||
$individual_res.error[].msg)
|
||||
let fut_result = individual_res.read()
|
||||
if fut_result.isErr():
|
||||
$future.error().msg)
|
||||
let res = future.value()
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
BlsToExecutionChangeValidationError,
|
||||
$fut_result.error())
|
||||
return RestApiResponse.jsonMsgResponse(BlsToExecutionChangeValidationSuccess)
|
||||
$res.error)
|
||||
RestApiResponse.jsonMsgResponse(BlsToExecutionChangeValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolSyncCommitteeSignatures
|
||||
router.api(MethodPost, "/eth/v1/beacon/pool/sync_committees") do (
|
||||
|
@ -1357,18 +1365,17 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
for index, item in results:
|
||||
if item.isErr():
|
||||
res.add(RestIndexedErrorMessageItem(index: index,
|
||||
message: $item.error()))
|
||||
message: $item.error))
|
||||
res
|
||||
if len(failures) > 0:
|
||||
return RestApiResponse.jsonErrorList(Http400,
|
||||
SyncCommitteeMessageValidationError,
|
||||
failures)
|
||||
RestApiResponse.jsonErrorList(
|
||||
Http400, SyncCommitteeMessageValidationError, failures)
|
||||
else:
|
||||
return RestApiResponse.jsonMsgResponse(
|
||||
RestApiResponse.jsonMsgResponse(
|
||||
SyncCommitteeMessageValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolVoluntaryExits
|
||||
router.api(MethodGet, "/eth/v1/beacon/pool/voluntary_exits") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/pool/voluntary_exits") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(
|
||||
toSeq(node.validatorChangePool.voluntary_exits))
|
||||
|
@ -1384,18 +1391,17 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if dres.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
InvalidVoluntaryExitObjectError,
|
||||
$dres.error())
|
||||
$dres.error)
|
||||
dres.get()
|
||||
let res = await node.router.routeSignedVoluntaryExit(exit)
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
VoluntaryExitValidationError,
|
||||
$res.error())
|
||||
return RestApiResponse.jsonError(
|
||||
Http400, VoluntaryExitValidationError, $res.error)
|
||||
return RestApiResponse.jsonMsgResponse(VoluntaryExitValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.2#/Beacon/getBlobSidecars
|
||||
# https://github.com/ethereum/beacon-APIs/blob/v2.4.2/apis/beacon/blob_sidecars/blob_sidecars.yaml
|
||||
router.api(MethodGet, "/eth/v1/beacon/blob_sidecars/{block_id}") do (
|
||||
router.api2(MethodGet, "/eth/v1/beacon/blob_sidecars/{block_id}") do (
|
||||
block_id: BlockIdent, indices: seq[uint64]) -> RestApiResponse:
|
||||
let
|
||||
blockIdent = block_id.valueOr:
|
||||
|
@ -1429,12 +1435,11 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if node.dag.db.getBlobSidecar(bid.root, blobIndex, blobSidecar[]):
|
||||
discard data[].add blobSidecar[]
|
||||
|
||||
return
|
||||
if contentType == sszMediaType:
|
||||
RestApiResponse.sszResponse(
|
||||
data[], headers = [("eth-consensus-version",
|
||||
node.dag.cfg.consensusForkAtEpoch(bid.slot.epoch).toString())])
|
||||
elif contentType == jsonMediaType:
|
||||
RestApiResponse.jsonResponse(data)
|
||||
else:
|
||||
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
||||
if contentType == sszMediaType:
|
||||
RestApiResponse.sszResponse(
|
||||
data[], headers = [("eth-consensus-version",
|
||||
node.dag.cfg.consensusForkAtEpoch(bid.slot.epoch).toString())])
|
||||
elif contentType == jsonMediaType:
|
||||
RestApiResponse.jsonResponse(data)
|
||||
else:
|
||||
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||
|
@ -17,7 +17,8 @@ logScope: topics = "rest_builderapi"
|
|||
proc installBuilderApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=v2.4.0#/Builder/getNextWithdrawals
|
||||
# https://github.com/ethereum/beacon-APIs/blob/v2.4.0/apis/builder/states/expected_withdrawals.yaml
|
||||
router.api(MethodGet, "/eth/v1/builder/states/{state_id}/expected_withdrawals") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/builder/states/{state_id}/expected_withdrawals") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let
|
||||
sid = state_id.valueOr:
|
||||
|
@ -41,4 +42,4 @@ proc installBuilderApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(
|
||||
Http400, "The specified state is not a capella state")
|
||||
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
|
|
@ -326,19 +326,16 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Config/getForkSchedule
|
||||
router.api(MethodGet,
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/config/fork_schedule") do () -> RestApiResponse:
|
||||
return RestApiResponse.response(cachedForkSchedule, Http200,
|
||||
"application/json")
|
||||
RestApiResponse.response(cachedForkSchedule, Http200, "application/json")
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Config/getSpec
|
||||
router.api(MethodGet,
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/config/spec") do () -> RestApiResponse:
|
||||
return RestApiResponse.response(cachedConfigSpec, Http200,
|
||||
"application/json")
|
||||
RestApiResponse.response(cachedConfigSpec, Http200, "application/json")
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Config/getDepositContract
|
||||
router.api(MethodGet,
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/config/deposit_contract") do () -> RestApiResponse:
|
||||
return RestApiResponse.response(cachedDepositContract, Http200,
|
||||
"application/json")
|
||||
RestApiResponse.response(cachedDepositContract, Http200, "application/json")
|
||||
|
|
|
@ -19,15 +19,15 @@ logScope: topics = "rest_debug"
|
|||
|
||||
proc installDebugApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://ethereum.github.io/beacon-APIs/#/Debug/getState
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/debug/beacon/states/{state_id}") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/debug/beacon/states/{state_id}") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
return RestApiResponse.jsonError(
|
||||
RestApiResponse.jsonError(
|
||||
Http410, DeprecatedRemovalBeaconBlocksDebugStateV1)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Debug/getStateV2
|
||||
router.api(MethodGet,
|
||||
"/eth/v2/debug/beacon/states/{state_id}") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v2/debug/beacon/states/{state_id}") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let bslot =
|
||||
block:
|
||||
|
@ -46,43 +46,40 @@ proc installDebugApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http406, ContentNotAcceptableError)
|
||||
res.get()
|
||||
|
||||
node.withStateForBlockSlotId(bslot):
|
||||
return
|
||||
if contentType == jsonMediaType:
|
||||
RestApiResponse.jsonResponseState(
|
||||
state,
|
||||
node.getStateOptimistic(state)
|
||||
)
|
||||
state, node.getStateOptimistic(state))
|
||||
elif contentType == sszMediaType:
|
||||
let headers = [("eth-consensus-version", state.kind.toString())]
|
||||
withState(state):
|
||||
RestApiResponse.sszResponse(forkyState.data, headers)
|
||||
else:
|
||||
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Debug/getDebugChainHeads
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/debug/beacon/heads") do () -> RestApiResponse:
|
||||
return RestApiResponse.jsonError(
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/debug/beacon/heads") do () -> RestApiResponse:
|
||||
RestApiResponse.jsonError(
|
||||
Http410, DeprecatedRemovalGetDebugChainHeadsV1)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Debug/getDebugChainHeadsV2
|
||||
router.api(MethodGet,
|
||||
"/eth/v2/debug/beacon/heads") do () -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(
|
||||
router.api2(MethodGet,
|
||||
"/eth/v2/debug/beacon/heads") do () -> RestApiResponse:
|
||||
RestApiResponse.jsonResponse(
|
||||
node.dag.heads.mapIt(
|
||||
(
|
||||
root: it.root,
|
||||
slot: it.slot,
|
||||
execution_optimistic: not it.executionValid
|
||||
)
|
||||
(root: it.root, slot: it.slot,
|
||||
execution_optimistic: not it.executionValid)
|
||||
)
|
||||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Debug/getDebugForkChoice
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/debug/fork_choice") do () -> RestApiResponse:
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/debug/fork_choice") do () -> RestApiResponse:
|
||||
template forkChoice: auto = node.attestationPool[].forkChoice
|
||||
|
||||
var response = GetForkChoiceResponse(
|
||||
|
@ -135,4 +132,4 @@ proc installDebugApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
best_child: item.bestChild,
|
||||
bestDescendant: item.bestDescendant))
|
||||
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
|
|
@ -85,7 +85,7 @@ proc eventHandler*[T](response: HttpResponseRef,
|
|||
|
||||
proc installEventApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://ethereum.github.io/beacon-APIs/#/Events/eventstream
|
||||
router.api(MethodGet, "/eth/v1/events") do (
|
||||
router.api2(MethodGet, "/eth/v1/events") do (
|
||||
topics: seq[EventTopic]) -> RestApiResponse:
|
||||
let eventTopics =
|
||||
block:
|
||||
|
@ -174,7 +174,10 @@ proc installEventApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
res.add(handler)
|
||||
res
|
||||
|
||||
discard await one(handlers)
|
||||
try:
|
||||
discard await race(handlers)
|
||||
except ValueError:
|
||||
raiseAssert "There should be more than one event handler at this point!"
|
||||
# One of the handlers finished, it means that connection has been droped, so
|
||||
# we cancelling all other handlers.
|
||||
let pending =
|
||||
|
|
|
@ -142,17 +142,17 @@ proc handleAddRemoteValidatorReq(host: KeymanagerHost,
|
|||
|
||||
proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Keymanager/ListKeys
|
||||
router.api(MethodGet, "/eth/v1/keystores") do () -> RestApiResponse:
|
||||
router.api2(MethodGet, "/eth/v1/keystores") do () -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
return authErrorResponse authStatus.error
|
||||
let response = GetKeystoresResponse(
|
||||
data: listLocalValidators(host.validatorPool[]))
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Keymanager/ImportKeystores
|
||||
router.api(MethodPost, "/eth/v1/keystores") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
router.api2(MethodPost, "/eth/v1/keystores") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
return authErrorResponse authStatus.error
|
||||
|
@ -167,14 +167,30 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
|
||||
if request.slashing_protection.isSome():
|
||||
let slashing_protection = request.slashing_protection.get()
|
||||
let nodeSPDIR = toSPDIR(host.validatorPool[].slashingProtection)
|
||||
let nodeSPDIR =
|
||||
try:
|
||||
toSPDIR(host.validatorPool[].slashingProtection)
|
||||
except IOError as exc:
|
||||
return keymanagerApiError(
|
||||
Http500, "Internal server error; " & $exc.msg)
|
||||
if nodeSPDIR.metadata.genesis_validators_root.Eth2Digest !=
|
||||
slashing_protection.metadata.genesis_validators_root.Eth2Digest:
|
||||
return keymanagerApiError(Http400,
|
||||
"The slashing protection database and imported file refer to " &
|
||||
"different blockchains.")
|
||||
let res = inclSPDIR(host.validatorPool[].slashingProtection,
|
||||
slashing_protection)
|
||||
let res =
|
||||
try:
|
||||
inclSPDIR(host.validatorPool[].slashingProtection,
|
||||
slashing_protection)
|
||||
except SerializationError as exc:
|
||||
return keymanagerApiError(
|
||||
Http500, "Internal server error; Failed to import slashing " &
|
||||
"protection data, reason: " &
|
||||
exc.formatMsg("slashing_protection"))
|
||||
except IOError as exc:
|
||||
return keymanagerApiError(
|
||||
Http500, "Internal server error; Failed to import slashing " &
|
||||
"protection data, reason: " & $exc.msg)
|
||||
if res == siFailure:
|
||||
return keymanagerApiError(Http500,
|
||||
"Internal server error; Failed to import slashing protection data")
|
||||
|
@ -202,10 +218,10 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
response.data.add(
|
||||
RequestItemStatus(status: $KeystoreStatus.imported))
|
||||
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Keymanager/DeleteKeys
|
||||
router.api(MethodDelete, "/eth/v1/keystores") do (
|
||||
router.api2(MethodDelete, "/eth/v1/keystores") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
|
@ -221,7 +237,12 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
|
||||
var
|
||||
response: DeleteKeystoresResponse
|
||||
nodeSPDIR = toSPDIR(host.validatorPool[].slashingProtection)
|
||||
nodeSPDIR =
|
||||
try:
|
||||
toSPDIR(host.validatorPool[].slashingProtection)
|
||||
except IOError as exc:
|
||||
return keymanagerApiError(
|
||||
Http500, "Internal server error; " & $exc.msg)
|
||||
# Hash table to keep the removal status of all keys form request
|
||||
keysAndDeleteStatus = initTable[PubKeyBytes, RequestItemStatus]()
|
||||
responseSPDIR: SPDIR
|
||||
|
@ -263,23 +284,24 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
foundKeystore.status = $KeystoreStatus.notActive
|
||||
|
||||
for index, key in keys:
|
||||
response.data.add(keysAndDeleteStatus[key.blob.PubKey0x.PubKeyBytes])
|
||||
response.data.add(
|
||||
keysAndDeleteStatus.getOrDefault(key.blob.PubKey0x.PubKeyBytes))
|
||||
|
||||
response.slashing_protection = RestJson.encode(responseSPDIR)
|
||||
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Remote%20Key%20Manager/ListRemoteKeys
|
||||
router.api(MethodGet, "/eth/v1/remotekeys") do () -> RestApiResponse:
|
||||
router.api2(MethodGet, "/eth/v1/remotekeys") do () -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
return authErrorResponse authStatus.error
|
||||
let response = GetRemoteKeystoresResponse(
|
||||
data: listRemoteValidators(host.validatorPool[]))
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Remote%20Key%20Manager/ImportRemoteKeys
|
||||
router.api(MethodPost, "/eth/v1/remotekeys") do (
|
||||
router.api2(MethodPost, "/eth/v1/remotekeys") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
|
@ -307,10 +329,10 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
|
||||
response.data.add handleAddRemoteValidatorReq(host, keystore)
|
||||
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Remote%20Key%20Manager/DeleteRemoteKeys
|
||||
router.api(MethodDelete, "/eth/v1/remotekeys") do (
|
||||
router.api2(MethodDelete, "/eth/v1/remotekeys") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
|
@ -327,10 +349,10 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
var response: DeleteRemoteKeystoresResponse
|
||||
for index, key in keys:
|
||||
response.data.add handleRemoveValidatorReq(host, key)
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Fee%20Recipient/ListFeeRecipient
|
||||
router.api(MethodGet, "/eth/v1/validator/{pubkey}/feerecipient") do (
|
||||
router.api2(MethodGet, "/eth/v1/validator/{pubkey}/feerecipient") do (
|
||||
pubkey: ValidatorPubKey) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
|
@ -344,7 +366,7 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
ethaddress = host.getSuggestedFeeRecipient(
|
||||
pubkey, perValidatorDefaultFeeRecipient)
|
||||
|
||||
return if ethaddress.isOk:
|
||||
if ethaddress.isOk:
|
||||
RestApiResponse.jsonResponse(ListFeeRecipientResponse(
|
||||
pubkey: pubkey,
|
||||
ethaddress: ethaddress.get))
|
||||
|
@ -356,14 +378,14 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
keymanagerApiError(Http500, "Error reading fee recipient file")
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Fee%20Recipient/SetFeeRecipient
|
||||
router.api(MethodPost, "/eth/v1/validator/{pubkey}/feerecipient") do (
|
||||
pubkey: ValidatorPubKey,
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
router.api2(MethodPost, "/eth/v1/validator/{pubkey}/feerecipient") do (
|
||||
pubkey: ValidatorPubKey,
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
return authErrorResponse authStatus.error
|
||||
let
|
||||
pubkey= pubkey.valueOr:
|
||||
pubkey = pubkey.valueOr:
|
||||
return keymanagerApiError(Http400, InvalidValidatorPublicKey)
|
||||
feeRecipientReq =
|
||||
block:
|
||||
|
@ -376,14 +398,14 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
|
||||
status = host.setFeeRecipient(pubkey, feeRecipientReq.ethaddress)
|
||||
|
||||
return if status.isOk:
|
||||
if status.isOk:
|
||||
RestApiResponse.response("", Http202, "text/plain")
|
||||
else:
|
||||
keymanagerApiError(
|
||||
Http500, "Failed to set fee recipient: " & status.error)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Fee%20Recipient/DeleteFeeRecipient
|
||||
router.api(MethodDelete, "/eth/v1/validator/{pubkey}/feerecipient") do (
|
||||
router.api2(MethodDelete, "/eth/v1/validator/{pubkey}/feerecipient") do (
|
||||
pubkey: ValidatorPubKey) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
|
@ -393,15 +415,15 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
return keymanagerApiError(Http400, InvalidValidatorPublicKey)
|
||||
res = host.removeFeeRecipientFile(pubkey)
|
||||
|
||||
return if res.isOk:
|
||||
if res.isOk:
|
||||
RestApiResponse.response("", Http204, "text/plain")
|
||||
else:
|
||||
keymanagerApiError(
|
||||
Http500, "Failed to remove fee recipient file: " & res.error)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Gas%20Limit/getGasLimit
|
||||
router.api(MethodGet, "/eth/v1/validator/{pubkey}/gas_limit") do (
|
||||
pubkey: ValidatorPubKey) -> RestApiResponse:
|
||||
router.api2(MethodGet, "/eth/v1/validator/{pubkey}/gas_limit") do (
|
||||
pubkey: ValidatorPubKey) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
return authErrorResponse authStatus.error
|
||||
|
@ -411,7 +433,7 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
return keymanagerApiError(Http400, InvalidValidatorPublicKey)
|
||||
gasLimit = host.getSuggestedGasLimit(pubkey)
|
||||
|
||||
return if gasLimit.isOk:
|
||||
if gasLimit.isOk:
|
||||
RestApiResponse.jsonResponse(GetValidatorGasLimitResponse(
|
||||
pubkey: pubkey,
|
||||
gas_limit: gasLimit.get))
|
||||
|
@ -423,9 +445,9 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
keymanagerApiError(Http500, "Error reading gas limit file")
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Gas%20Limit/setGasLimit
|
||||
router.api(MethodPost, "/eth/v1/validator/{pubkey}/gas_limit") do (
|
||||
pubkey: ValidatorPubKey,
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
router.api2(MethodPost, "/eth/v1/validator/{pubkey}/gas_limit") do (
|
||||
pubkey: ValidatorPubKey,
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
return authErrorResponse authStatus.error
|
||||
|
@ -443,15 +465,15 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
|
||||
status = host.setGasLimit(pubkey, gasLimitReq.gas_limit)
|
||||
|
||||
return if status.isOk:
|
||||
if status.isOk:
|
||||
RestApiResponse.response("", Http202, "text/plain")
|
||||
else:
|
||||
keymanagerApiError(
|
||||
Http500, "Failed to set gas limit: " & status.error)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/#/Gas%20Limit/deleteGasLimit
|
||||
router.api(MethodDelete, "/eth/v1/validator/{pubkey}/gas_limit") do (
|
||||
pubkey: ValidatorPubKey) -> RestApiResponse:
|
||||
router.api2(MethodDelete, "/eth/v1/validator/{pubkey}/gas_limit") do (
|
||||
pubkey: ValidatorPubKey) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
return authErrorResponse authStatus.error
|
||||
|
@ -460,7 +482,7 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
return keymanagerApiError(Http400, InvalidValidatorPublicKey)
|
||||
res = host.removeGasLimitFile(pubkey)
|
||||
|
||||
return if res.isOk:
|
||||
if res.isOk:
|
||||
RestApiResponse.response("", Http204, "text/plain")
|
||||
else:
|
||||
keymanagerApiError(
|
||||
|
@ -468,17 +490,18 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
|
||||
# TODO: These URLs will be changed once we submit a proposal for
|
||||
# /eth/v2/remotekeys that supports distributed keys.
|
||||
router.api(MethodGet, "/eth/v1/remotekeys/distributed") do () -> RestApiResponse:
|
||||
router.api2(MethodGet, "/eth/v1/remotekeys/distributed") do (
|
||||
) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
return authErrorResponse authStatus.error
|
||||
let response = GetDistributedKeystoresResponse(
|
||||
data: listRemoteDistributedValidators(host.validatorPool[]))
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
# TODO: These URLs will be changed once we submit a proposal for
|
||||
# /eth/v2/remotekeys that supports distributed keys.
|
||||
router.api(MethodPost, "/eth/v1/remotekeys/distributed") do (
|
||||
router.api2(MethodPost, "/eth/v1/remotekeys/distributed") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
|
@ -504,9 +527,9 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
)
|
||||
response.data.add handleAddRemoteValidatorReq(host, keystore)
|
||||
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
router.api(MethodDelete, "/eth/v1/remotekeys/distributed") do (
|
||||
router.api2(MethodDelete, "/eth/v1/remotekeys/distributed") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let authStatus = checkAuthorization(request, host)
|
||||
if authStatus.isErr():
|
||||
|
@ -524,10 +547,10 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
for index, key in keys:
|
||||
response.data.add handleRemoveValidatorReq(host, key)
|
||||
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
# https://ethereum.github.io/keymanager-APIs/?urls.primaryName=dev#/Voluntary%20Exit/signVoluntaryExit
|
||||
router.api(MethodPost, "/eth/v1/validator/{pubkey}/voluntary_exit") do (
|
||||
router.api2(MethodPost, "/eth/v1/validator/{pubkey}/voluntary_exit") do (
|
||||
pubkey: ValidatorPubKey, epoch: Option[Epoch],
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
|
||||
|
@ -575,4 +598,4 @@ proc installKeymanagerHandlers*(router: var RestRouter, host: KeymanagerHost) =
|
|||
message: voluntaryExit,
|
||||
signature: signature
|
||||
)
|
||||
return RestApiResponse.jsonResponse(response)
|
||||
RestApiResponse.jsonResponse(response)
|
||||
|
|
|
@ -15,8 +15,8 @@ logScope: topics = "rest_light_client"
|
|||
|
||||
proc installLightClientApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getLightClientBootstrap
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/light_client/bootstrap/{block_root}") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/light_client/bootstrap/{block_root}") do (
|
||||
block_root: Eth2Digest) -> RestApiResponse:
|
||||
doAssert node.dag.lcDataStore.serve
|
||||
let contentType =
|
||||
|
@ -51,8 +51,8 @@ proc installLightClientApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http404, LCBootstrapUnavailable)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getLightClientUpdatesByRange
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/light_client/updates") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/light_client/updates") do (
|
||||
start_period: Option[SyncCommitteePeriod], count: Option[uint64]
|
||||
) -> RestApiResponse:
|
||||
doAssert node.dag.lcDataStore.serve
|
||||
|
@ -116,8 +116,8 @@ proc installLightClientApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getLightClientFinalityUpdate
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/light_client/finality_update") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/light_client/finality_update") do (
|
||||
) -> RestApiResponse:
|
||||
doAssert node.dag.lcDataStore.serve
|
||||
let contentType =
|
||||
|
@ -147,8 +147,8 @@ proc installLightClientApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http404, LCFinUpdateUnavailable)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getLightClientOptimisticUpdate
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/beacon/light_client/optimistic_update") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/beacon/light_client/optimistic_update") do (
|
||||
) -> RestApiResponse:
|
||||
doAssert node.dag.lcDataStore.serve
|
||||
let contentType =
|
||||
|
|
|
@ -152,16 +152,16 @@ proc toNode(v: PubSubPeer, backoff: Moment): RestPubSubPeer =
|
|||
)
|
||||
|
||||
proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
router.api(MethodGet, "/nimbus/v1/beacon/head") do () -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(node.dag.head.slot)
|
||||
router.api2(MethodGet, "/nimbus/v1/beacon/head") do () -> RestApiResponse:
|
||||
RestApiResponse.jsonResponse(node.dag.head.slot)
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/chain/head") do() -> RestApiResponse:
|
||||
router.api2(MethodGet, "/nimbus/v1/chain/head") do() -> RestApiResponse:
|
||||
let
|
||||
head = node.dag.head
|
||||
finalized = getStateField(node.dag.headState, finalized_checkpoint)
|
||||
justified =
|
||||
getStateField(node.dag.headState, current_justified_checkpoint)
|
||||
return RestApiResponse.jsonResponse(
|
||||
RestApiResponse.jsonResponse(
|
||||
(
|
||||
head_slot: head.slot,
|
||||
head_block_root: head.root.data.toHex(),
|
||||
|
@ -172,26 +172,26 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
)
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/syncmanager/status") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/syncmanager/status") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(node.syncManager.inProgress)
|
||||
RestApiResponse.jsonResponse(node.syncManager.inProgress)
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/node/peerid") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/node/peerid") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse((peerid: $node.network.peerId()))
|
||||
RestApiResponse.jsonResponse((peerid: $node.network.peerId()))
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/node/version") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/node/version") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse((version: "Nimbus/" & fullVersionStr))
|
||||
RestApiResponse.jsonResponse((version: "Nimbus/" & fullVersionStr))
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/network/ids") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/network/ids") do (
|
||||
) -> RestApiResponse:
|
||||
var res: seq[PeerId]
|
||||
for peerId, peer in node.network.peerPool:
|
||||
res.add(peerId)
|
||||
return RestApiResponse.jsonResponse((peerids: res))
|
||||
RestApiResponse.jsonResponse((peerids: res))
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/network/peers") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/network/peers") do (
|
||||
) -> RestApiResponse:
|
||||
var res: seq[RestSimplePeer]
|
||||
for id, peer in node.network.peerPool:
|
||||
|
@ -202,9 +202,9 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
score: peer.score
|
||||
)
|
||||
)
|
||||
return RestApiResponse.jsonResponse((peers: res))
|
||||
RestApiResponse.jsonResponse((peers: res))
|
||||
|
||||
router.api(MethodPost, "/nimbus/v1/graffiti") do (
|
||||
router.api2(MethodPost, "/nimbus/v1/graffiti") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
if contentBody.isNone:
|
||||
return RestApiResponse.jsonError(Http400, EmptyRequestBodyError)
|
||||
|
@ -225,20 +225,19 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http400, InvalidGraffitiBytesValue,
|
||||
$graffitiBytes.error())
|
||||
node.graffitiBytes = graffitiBytes.get()
|
||||
return RestApiResponse.jsonResponse((result: true))
|
||||
RestApiResponse.jsonResponse((result: true))
|
||||
elif body.contentType == TextPlainMediaType:
|
||||
return node.setGraffitiAux body.strData()
|
||||
node.setGraffitiAux body.strData()
|
||||
elif body.contentType == UrlEncodedMediaType:
|
||||
return node.setGraffitiAux decodeUrl(body.strData())
|
||||
node.setGraffitiAux decodeUrl(body.strData())
|
||||
else:
|
||||
return RestApiResponse.jsonError(Http400, "Unsupported content type: " &
|
||||
$body.contentType)
|
||||
RestApiResponse.jsonError(
|
||||
Http400, "Unsupported content type: " & $body.contentType)
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/graffiti") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(node.graffitiBytes)
|
||||
router.api2(MethodGet, "/nimbus/v1/graffiti") do () -> RestApiResponse:
|
||||
RestApiResponse.jsonResponse(node.graffitiBytes)
|
||||
|
||||
router.api(MethodPost, "/nimbus/v1/chronicles/settings") do (
|
||||
router.api2(MethodPost, "/nimbus/v1/chronicles/settings") do (
|
||||
log_level: Option[string]) -> RestApiResponse:
|
||||
if log_level.isSome():
|
||||
let level =
|
||||
|
@ -249,15 +248,17 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
$res.error())
|
||||
res.get()
|
||||
{.gcsafe.}:
|
||||
updateLogLevel(level)
|
||||
return RestApiResponse.jsonResponse((result: true))
|
||||
try:
|
||||
updateLogLevel(level)
|
||||
except ValueError:
|
||||
return RestApiResponse.jsonResponse((result: false))
|
||||
RestApiResponse.jsonResponse((result: true))
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/eth1/chain") do (
|
||||
) -> RestApiResponse:
|
||||
router.api2(MethodGet, "/nimbus/v1/eth1/chain") do () -> RestApiResponse:
|
||||
let res = mapIt(node.elManager.eth1ChainBlocks, it)
|
||||
return RestApiResponse.jsonResponse(res)
|
||||
RestApiResponse.jsonResponse(res)
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/eth1/proposal_data") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/eth1/proposal_data") do (
|
||||
) -> RestApiResponse:
|
||||
let wallSlot = node.beaconClock.now.slotOrZero
|
||||
let head =
|
||||
|
@ -279,7 +280,7 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
do:
|
||||
return RestApiResponse.jsonError(Http400, PrunedStateError)
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/debug/chronos/futures") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/debug/chronos/futures") do (
|
||||
) -> RestApiResponse:
|
||||
when defined(chronosFutureTracking):
|
||||
var res: seq[RestFutureInfo]
|
||||
|
@ -299,12 +300,12 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
state: $item.state
|
||||
)
|
||||
)
|
||||
return RestApiResponse.jsonResponse(res)
|
||||
RestApiResponse.jsonResponse(res)
|
||||
else:
|
||||
return RestApiResponse.jsonError(Http503,
|
||||
RestApiResponse.jsonError(Http503,
|
||||
"Compile with '-d:chronosFutureTracking' to get this request working")
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/debug/chronos/metrics") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/debug/chronos/metrics") do (
|
||||
) -> RestApiResponse:
|
||||
|
||||
template getCount(name: string): uint64 =
|
||||
|
@ -329,9 +330,9 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
http_body_readers: getCount(HttpBodyReaderTrackerName),
|
||||
http_body_writers: getCount(HttpBodyWriterTrackerName)
|
||||
)
|
||||
return RestApiResponse.jsonResponse(res)
|
||||
RestApiResponse.jsonResponse(res)
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/debug/chronos/restserver/connections") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/debug/chronos/restserver/connections") do (
|
||||
) -> RestApiResponse:
|
||||
var res: seq[RestConnectionInfo]
|
||||
for connection in node.restServer.server.getConnections():
|
||||
|
@ -378,9 +379,9 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
since_create: sinceCreate
|
||||
)
|
||||
)
|
||||
return RestApiResponse.jsonResponse(res)
|
||||
RestApiResponse.jsonResponse(res)
|
||||
|
||||
router.api(MethodPost, "/nimbus/v1/validator/activity/{epoch}") do (
|
||||
router.api2(MethodPost, "/nimbus/v1/validator/activity/{epoch}") do (
|
||||
epoch: Epoch, contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let indexList =
|
||||
block:
|
||||
|
@ -441,11 +442,10 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
active: node.attestationPool[].validatorSeenAtEpoch(qepoch, it)
|
||||
)
|
||||
)
|
||||
return RestApiResponse.jsonResponse(response)
|
||||
RestApiResponse.jsonResponse(response)
|
||||
|
||||
router.api(MethodGet, "/nimbus/v1/debug/gossip/peers") do (
|
||||
router.api2(MethodGet, "/nimbus/v1/debug/gossip/peers") do (
|
||||
) -> RestApiResponse:
|
||||
|
||||
let gossipPeers =
|
||||
block:
|
||||
var res: seq[tuple[topic: string, peers: seq[RestPubSubPeer]]]
|
||||
|
@ -496,7 +496,7 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
for peerId, peer in node.network.pubsub.peers:
|
||||
peers.add(RestPeerStatus(peerId: peerId, connected: peer.connected))
|
||||
peers
|
||||
return RestApiResponse.jsonResponse(
|
||||
RestApiResponse.jsonResponse(
|
||||
(
|
||||
gossip_peers: gossipPeers,
|
||||
mesh_peers: meshPeers,
|
||||
|
@ -506,7 +506,7 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
)
|
||||
|
||||
router.api(MethodPost, "/nimbus/v1/timesync") do (
|
||||
router.api2(MethodPost, "/nimbus/v1/timesync") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let
|
||||
timestamp2 = getTimestamp()
|
||||
|
@ -528,4 +528,4 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
timestamp3: getTimestamp(),
|
||||
delay: uint64(delay.nanoseconds)
|
||||
)
|
||||
return RestApiResponse.jsonResponsePlain(response)
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
|
|
@ -140,7 +140,7 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
RestApiResponse.prepareJsonResponse((version: "Nimbus/" & fullVersionStr))
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getNetworkIdentity
|
||||
router.api(MethodGet, "/eth/v1/node/identity") do () -> RestApiResponse:
|
||||
router.api2(MethodGet, "/eth/v1/node/identity") do () -> RestApiResponse:
|
||||
let discoveryAddresses =
|
||||
block:
|
||||
let res = node.getDiscoveryAddresses()
|
||||
|
@ -157,7 +157,7 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
else:
|
||||
newSeq[string]()
|
||||
|
||||
return RestApiResponse.jsonResponse(
|
||||
RestApiResponse.jsonResponse(
|
||||
(
|
||||
peer_id: $node.network.peerId(),
|
||||
enr: node.network.enrRecord().toURI(),
|
||||
|
@ -172,7 +172,7 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getPeers
|
||||
router.api(MethodGet, "/eth/v1/node/peers") do (
|
||||
router.api2(MethodGet, "/eth/v1/node/peers") do (
|
||||
state: seq[PeerStateKind],
|
||||
direction: seq[PeerDirectKind]) -> RestApiResponse:
|
||||
let connectionMask =
|
||||
|
@ -208,11 +208,10 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
proto: node.network.switch.peerStore[ProtoVersionBook][peer.peerId]
|
||||
)
|
||||
res.add(peer)
|
||||
return RestApiResponse.jsonResponseWMeta(res,
|
||||
(count: RestNumeric(len(res))))
|
||||
RestApiResponse.jsonResponseWMeta(res, (count: RestNumeric(len(res))))
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getPeerCount
|
||||
router.api(MethodGet, "/eth/v1/node/peer_count") do () -> RestApiResponse:
|
||||
router.api2(MethodGet, "/eth/v1/node/peer_count") do () -> RestApiResponse:
|
||||
var res: RestNodePeerCount
|
||||
for item in node.network.peers.values():
|
||||
case item.connectionState
|
||||
|
@ -226,10 +225,10 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
inc(res.disconnected)
|
||||
of ConnectionState.None:
|
||||
discard
|
||||
return RestApiResponse.jsonResponse(res)
|
||||
RestApiResponse.jsonResponse(res)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getPeer
|
||||
router.api(MethodGet, "/eth/v1/node/peers/{peer_id}") do (
|
||||
router.api2(MethodGet, "/eth/v1/node/peers/{peer_id}") do (
|
||||
peer_id: PeerId) -> RestApiResponse:
|
||||
let peer =
|
||||
block:
|
||||
|
@ -240,25 +239,26 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if isNil(res):
|
||||
return RestApiResponse.jsonError(Http404, PeerNotFoundError)
|
||||
res
|
||||
return RestApiResponse.jsonResponse(
|
||||
RestApiResponse.jsonResponse(
|
||||
(
|
||||
peer_id: $peer.peerId,
|
||||
enr: if peer.enr.isSome(): peer.enr.get().toURI() else: "",
|
||||
last_seen_p2p_address: getLastSeenAddress(node, peer.peerId),
|
||||
state: peer.connectionState.toString(),
|
||||
direction: peer.direction.toString(),
|
||||
agent: node.network.switch.peerStore[AgentBook][peer.peerId], # Fields `agent` and `proto` are not
|
||||
proto: node.network.switch.peerStore[ProtoVersionBook][peer.peerId] # part of specification
|
||||
agent: node.network.switch.peerStore[AgentBook][peer.peerId],
|
||||
# Fields `agent` and `proto` are not part of specification
|
||||
proto: node.network.switch.peerStore[ProtoVersionBook][peer.peerId]
|
||||
# Fields `agent` and `proto` are not part of specification
|
||||
)
|
||||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getNodeVersion
|
||||
router.api(MethodGet, "/eth/v1/node/version") do () -> RestApiResponse:
|
||||
return RestApiResponse.response(cachedVersion, Http200,
|
||||
"application/json")
|
||||
router.api2(MethodGet, "/eth/v1/node/version") do () -> RestApiResponse:
|
||||
RestApiResponse.response(cachedVersion, Http200, "application/json")
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getSyncingStatus
|
||||
router.api(MethodGet, "/eth/v1/node/syncing") do () -> RestApiResponse:
|
||||
router.api2(MethodGet, "/eth/v1/node/syncing") do () -> RestApiResponse:
|
||||
let
|
||||
wallSlot = node.beaconClock.now().slotOrZero()
|
||||
headSlot = node.dag.head.slot
|
||||
|
@ -284,10 +284,10 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
is_syncing: isSyncing, is_optimistic: isOptimistic,
|
||||
el_offline: elOffline
|
||||
)
|
||||
return RestApiResponse.jsonResponse(info)
|
||||
RestApiResponse.jsonResponse(info)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getHealth
|
||||
router.api(MethodGet, "/eth/v1/node/health") do () -> RestApiResponse:
|
||||
router.api2(MethodGet, "/eth/v1/node/health") do () -> RestApiResponse:
|
||||
# TODO: Add ability to detect node's issues and return 503 error according
|
||||
# to specification.
|
||||
let status =
|
||||
|
@ -295,4 +295,4 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
Http206
|
||||
else:
|
||||
Http200
|
||||
return RestApiResponse.response("", status, contentType = "")
|
||||
RestApiResponse.response("", status, contentType = "")
|
||||
|
|
|
@ -24,7 +24,7 @@ logScope: topics = "rest_validatorapi"
|
|||
|
||||
proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/getAttesterDuties
|
||||
router.api(MethodPost, "/eth/v1/validator/duties/attester/{epoch}") do (
|
||||
router.api2(MethodPost, "/eth/v1/validator/duties/attester/{epoch}") do (
|
||||
epoch: Epoch, contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let indexList =
|
||||
block:
|
||||
|
@ -107,11 +107,11 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
shufflingRef.attester_dependent_slot,
|
||||
shufflingRef.attester_dependent_root)
|
||||
|
||||
return RestApiResponse.jsonResponseWRoot(
|
||||
RestApiResponse.jsonResponseWRoot(
|
||||
duties, shufflingRef.attester_dependent_root, optimistic)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/getProposerDuties
|
||||
router.api(MethodGet, "/eth/v1/validator/duties/proposer/{epoch}") do (
|
||||
router.api2(MethodGet, "/eth/v1/validator/duties/proposer/{epoch}") do (
|
||||
epoch: Epoch) -> RestApiResponse:
|
||||
let qepoch =
|
||||
block:
|
||||
|
@ -159,11 +159,11 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
epochRef.proposer_dependent_slot,
|
||||
epochRef.proposer_dependent_root)
|
||||
|
||||
return RestApiResponse.jsonResponseWRoot(
|
||||
RestApiResponse.jsonResponseWRoot(
|
||||
duties, epochRef.proposer_dependent_root, optimistic)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/getSyncCommitteeDuties
|
||||
router.api(MethodPost, "/eth/v1/validator/duties/sync/{epoch}") do (
|
||||
router.api2(MethodPost, "/eth/v1/validator/duties/sync/{epoch}") do (
|
||||
epoch: Epoch, contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let indexList =
|
||||
block:
|
||||
|
@ -311,13 +311,13 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let res = emptyResponse()
|
||||
return RestApiResponse.jsonResponseWOpt(res, execOpt = Opt.some(false))
|
||||
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/produceBlock
|
||||
router.api(MethodGet, "/eth/v1/validator/blocks/{slot}") do (
|
||||
router.api2(MethodGet, "/eth/v1/validator/blocks/{slot}") do (
|
||||
slot: Slot, randao_reveal: Option[ValidatorSig],
|
||||
graffiti: Option[GraffitiBytes]) -> RestApiResponse:
|
||||
return RestApiResponse.jsonError(
|
||||
RestApiResponse.jsonError(
|
||||
Http410, DeprecatedRemovalValidatorBlocksV1)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/produceBlockV2
|
||||
|
@ -691,7 +691,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
raiseAssert "preferredContentType() returns invalid content type"
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/produceAttestationData
|
||||
router.api(MethodGet, "/eth/v1/validator/attestation_data") do (
|
||||
router.api2(MethodGet, "/eth/v1/validator/attestation_data") do (
|
||||
slot: Option[Slot],
|
||||
committee_index: Option[CommitteeIndex]) -> RestApiResponse:
|
||||
let adata =
|
||||
|
@ -751,10 +751,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
let epochRef = node.dag.getEpochRef(qhead, qslot.epoch, true).valueOr:
|
||||
return RestApiResponse.jsonError(Http400, PrunedStateError, $error)
|
||||
makeAttestationData(epochRef, qhead.atSlot(qslot), qindex)
|
||||
return RestApiResponse.jsonResponse(adata)
|
||||
RestApiResponse.jsonResponse(adata)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/getAggregatedAttestation
|
||||
router.api(MethodGet, "/eth/v1/validator/aggregate_attestation") do (
|
||||
router.api2(MethodGet, "/eth/v1/validator/aggregate_attestation") do (
|
||||
attestation_data_root: Option[Eth2Digest],
|
||||
slot: Option[Slot]) -> RestApiResponse:
|
||||
let attestation =
|
||||
|
@ -784,10 +784,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http400,
|
||||
UnableToGetAggregatedAttestationError)
|
||||
res.get()
|
||||
return RestApiResponse.jsonResponse(attestation)
|
||||
RestApiResponse.jsonResponse(attestation)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/publishAggregateAndProofs
|
||||
router.api(MethodPost, "/eth/v1/validator/aggregate_and_proofs") do (
|
||||
router.api2(MethodPost, "/eth/v1/validator/aggregate_and_proofs") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let proofs =
|
||||
block:
|
||||
|
@ -810,7 +810,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
await allFutures(pending)
|
||||
for future in pending:
|
||||
if future.completed():
|
||||
let res = future.read()
|
||||
let res = future.value()
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http400,
|
||||
AggregateAndProofValidationError,
|
||||
|
@ -818,11 +818,11 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
else:
|
||||
return RestApiResponse.jsonError(Http500,
|
||||
"Unexpected server failure, while sending aggregate and proof")
|
||||
return RestApiResponse.jsonMsgResponse(AggregateAndProofValidationSuccess)
|
||||
RestApiResponse.jsonMsgResponse(AggregateAndProofValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/prepareBeaconCommitteeSubnet
|
||||
router.api(MethodPost,
|
||||
"/eth/v1/validator/beacon_committee_subscriptions") do (
|
||||
router.api2(MethodPost,
|
||||
"/eth/v1/validator/beacon_committee_subscriptions") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let requests =
|
||||
block:
|
||||
|
@ -898,11 +898,11 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.validatorMonitor[].addAutoMonitor(
|
||||
validator_pubkey, ValidatorIndex(request.validator_index))
|
||||
|
||||
return RestApiResponse.jsonMsgResponse(BeaconCommitteeSubscriptionSuccess)
|
||||
RestApiResponse.jsonMsgResponse(BeaconCommitteeSubscriptionSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/prepareSyncCommitteeSubnets
|
||||
router.api(MethodPost,
|
||||
"/eth/v1/validator/sync_committee_subscriptions") do (
|
||||
router.api2(MethodPost,
|
||||
"/eth/v1/validator/sync_committee_subscriptions") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let subscriptions =
|
||||
block:
|
||||
|
@ -939,11 +939,11 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.validatorMonitor[].addAutoMonitor(
|
||||
validator_pubkey, ValidatorIndex(item.validator_index))
|
||||
|
||||
return RestApiResponse.jsonMsgResponse(SyncCommitteeSubscriptionSuccess)
|
||||
RestApiResponse.jsonMsgResponse(SyncCommitteeSubscriptionSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/produceSyncCommitteeContribution
|
||||
router.api(MethodGet,
|
||||
"/eth/v1/validator/sync_committee_contribution") do (
|
||||
router.api2(MethodGet,
|
||||
"/eth/v1/validator/sync_committee_contribution") do (
|
||||
slot: Option[Slot], subcommittee_index: Option[SyncSubCommitteeIndex],
|
||||
beacon_block_root: Option[Eth2Digest]) -> RestApiResponse:
|
||||
let qslot = block:
|
||||
|
@ -1003,11 +1003,11 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
qslot, blck.bid, qindex, contribution)
|
||||
if not(res):
|
||||
return RestApiResponse.jsonError(Http400, ProduceContributionError)
|
||||
return RestApiResponse.jsonResponse(contribution)
|
||||
RestApiResponse.jsonResponse(contribution)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/publishContributionAndProofs
|
||||
router.api(MethodPost,
|
||||
"/eth/v1/validator/contribution_and_proofs") do (
|
||||
router.api2(MethodPost,
|
||||
"/eth/v1/validator/contribution_and_proofs") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let proofs =
|
||||
block:
|
||||
|
@ -1033,31 +1033,28 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
await allFutures(pending)
|
||||
for index, future in pending:
|
||||
if future.completed():
|
||||
let fres = future.read()
|
||||
let fres = future.value()
|
||||
if fres.isErr():
|
||||
let failure = RestIndexedErrorMessageItem(index: index,
|
||||
message: $fres.error())
|
||||
res.add(failure)
|
||||
elif future.failed() or future.cancelled():
|
||||
# This is unexpected failure, so we log the error message.
|
||||
let exc = future.readError()
|
||||
let exc = future.error()
|
||||
let failure = RestIndexedErrorMessageItem(index: index,
|
||||
message: $exc.msg)
|
||||
res.add(failure)
|
||||
res
|
||||
|
||||
if len(failures) > 0:
|
||||
return RestApiResponse.jsonErrorList(Http400,
|
||||
ContributionAndProofValidationError,
|
||||
failures)
|
||||
RestApiResponse.jsonErrorList(
|
||||
Http400, ContributionAndProofValidationError, failures)
|
||||
else:
|
||||
return RestApiResponse.jsonMsgResponse(
|
||||
ContributionAndProofValidationSuccess
|
||||
)
|
||||
RestApiResponse.jsonMsgResponse(ContributionAndProofValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/ValidatorRequiredApi/prepareBeaconProposer
|
||||
router.api(MethodPost,
|
||||
"/eth/v1/validator/prepare_beacon_proposer") do (
|
||||
router.api2(MethodPost,
|
||||
"/eth/v1/validator/prepare_beacon_proposer") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let
|
||||
body =
|
||||
|
@ -1087,12 +1084,12 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
numUpdatedFeeRecipients = numUpdated,
|
||||
numRefreshedFeeRecipients = numRefreshed
|
||||
|
||||
return RestApiResponse.response("", Http200, "text/plain")
|
||||
RestApiResponse.response("", Http200, "text/plain")
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/registerValidator
|
||||
# https://github.com/ethereum/beacon-APIs/blob/v2.3.0/apis/validator/register_validator.yaml
|
||||
router.api(MethodPost,
|
||||
"/eth/v1/validator/register_validator") do (
|
||||
router.api2(MethodPost,
|
||||
"/eth/v1/validator/register_validator") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let
|
||||
body =
|
||||
|
@ -1114,10 +1111,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
node.externalBuilderRegistrations[signedValidatorRegistration.message.pubkey] =
|
||||
signedValidatorRegistration
|
||||
|
||||
return RestApiResponse.response("", Http200, "text/plain")
|
||||
RestApiResponse.response("", Http200, "text/plain")
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/getLiveness
|
||||
router.api(MethodPost, "/eth/v1/validator/liveness/{epoch}") do (
|
||||
router.api2(MethodPost, "/eth/v1/validator/liveness/{epoch}") do (
|
||||
epoch: Epoch, contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let
|
||||
qepoch =
|
||||
|
@ -1183,10 +1180,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
is_live: node.attestationPool[].validatorSeenAtEpoch(qepoch, it)
|
||||
)
|
||||
)
|
||||
return RestApiResponse.jsonResponse(response)
|
||||
RestApiResponse.jsonResponse(response)
|
||||
|
||||
# https://github.com/ethereum/beacon-APIs/blob/f087fbf2764e657578a6c29bdf0261b36ee8db1e/apis/validator/beacon_committee_selections.yaml
|
||||
router.api(MethodPost, "/eth/v1/validator/beacon_committee_selections") do (
|
||||
router.api2(MethodPost, "/eth/v1/validator/beacon_committee_selections") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
# "Consensus clients need not support this endpoint and may return a 501."
|
||||
# https://github.com/ethereum/beacon-APIs/pull/224: "This endpoint need not
|
||||
|
@ -1194,11 +1191,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
# able to use it when a feature flag is turned on, the intercepting
|
||||
# middleware can handle and swallow the request. I suggest a CL either
|
||||
# returns 501 Not Implemented [or] 400 Bad Request."
|
||||
return RestApiResponse.jsonError(
|
||||
Http501, AggregationSelectionNotImplemented)
|
||||
RestApiResponse.jsonError(Http501, AggregationSelectionNotImplemented)
|
||||
|
||||
# https://github.com/ethereum/beacon-APIs/blob/f087fbf2764e657578a6c29bdf0261b36ee8db1e/apis/validator/sync_committee_selections.yaml
|
||||
router.api(MethodPost, "/eth/v1/validator/sync_committee_selections") do (
|
||||
router.api2(MethodPost, "/eth/v1/validator/sync_committee_selections") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
# "Consensus clients need not support this endpoint and may return a 501."
|
||||
# https://github.com/ethereum/beacon-APIs/pull/224: "This endpoint need not
|
||||
|
@ -1206,5 +1202,4 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
# able to use it when a feature flag is turned on, the intercepting
|
||||
# middleware can handle and swallow the request. I suggest a CL either
|
||||
# returns 501 Not Implemented [or] 400 Bad Request."
|
||||
return RestApiResponse.jsonError(
|
||||
Http501, AggregationSelectionNotImplemented)
|
||||
RestApiResponse.jsonError(Http501, AggregationSelectionNotImplemented)
|
||||
|
|
Loading…
Reference in New Issue