2021-10-06 17:05:06 +00:00
|
|
|
# beacon_chain
|
2022-01-04 09:45:38 +00:00
|
|
|
# Copyright (c) 2021-2022 Status Research & Development GmbH
|
2021-10-06 17:05:06 +00:00
|
|
|
# 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).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
2021-08-23 10:41:48 +00:00
|
|
|
import std/sequtils
|
2021-08-27 09:00:06 +00:00
|
|
|
import chronicles
|
2021-10-19 14:09:26 +00:00
|
|
|
import ".."/[version, beacon_node],
|
2021-08-23 10:41:48 +00:00
|
|
|
".."/spec/forks,
|
2022-01-05 14:49:10 +00:00
|
|
|
"."/[rest_utils, state_ttl_cache]
|
2021-03-17 18:46:45 +00:00
|
|
|
|
2021-10-27 12:01:11 +00:00
|
|
|
export rest_utils
|
|
|
|
|
2021-03-17 18:46:45 +00:00
|
|
|
logScope: topics = "rest_debug"
|
|
|
|
|
|
|
|
proc installDebugApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
2021-08-23 10:41:48 +00:00
|
|
|
# https://ethereum.github.io/beacon-APIs/#/Debug/getState
|
2021-03-17 18:46:45 +00:00
|
|
|
router.api(MethodGet,
|
2022-01-06 07:38:40 +00:00
|
|
|
"/eth/v1/debug/beacon/states/{state_id}") do (
|
2021-03-17 18:46:45 +00:00
|
|
|
state_id: StateIdent) -> RestApiResponse:
|
2021-03-23 22:50:18 +00:00
|
|
|
let bslot =
|
|
|
|
block:
|
|
|
|
if state_id.isErr():
|
2021-04-08 10:49:28 +00:00
|
|
|
return RestApiResponse.jsonError(Http400, InvalidStateIdValueError,
|
2021-03-23 22:50:18 +00:00
|
|
|
$state_id.error())
|
|
|
|
let bres = node.getBlockSlot(state_id.get())
|
|
|
|
if bres.isErr():
|
2021-04-08 10:49:28 +00:00
|
|
|
return RestApiResponse.jsonError(Http404, StateNotFoundError,
|
2021-03-23 22:50:18 +00:00
|
|
|
$bres.error())
|
|
|
|
bres.get()
|
2021-09-16 13:32:32 +00:00
|
|
|
let contentType =
|
|
|
|
block:
|
2022-01-21 16:52:34 +00:00
|
|
|
let res = preferredContentType(jsonMediaType,
|
|
|
|
sszMediaType)
|
2021-09-16 13:32:32 +00:00
|
|
|
if res.isErr():
|
|
|
|
return RestApiResponse.jsonError(Http406, ContentNotAcceptableError)
|
|
|
|
res.get()
|
2021-03-23 22:50:18 +00:00
|
|
|
node.withStateForBlockSlot(bslot):
|
2021-09-16 13:32:32 +00:00
|
|
|
return
|
2021-10-18 16:37:27 +00:00
|
|
|
case stateData.data.kind
|
|
|
|
of BeaconStateFork.Phase0:
|
2022-01-21 16:52:34 +00:00
|
|
|
if contentType == sszMediaType:
|
|
|
|
RestApiResponse.sszResponse(stateData.data.phase0Data.data)
|
|
|
|
elif contentType == jsonMediaType:
|
|
|
|
RestApiResponse.jsonResponse(stateData.data.phase0Data.data)
|
|
|
|
else:
|
|
|
|
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
2022-01-04 09:45:38 +00:00
|
|
|
of BeaconStateFork.Altair, BeaconStateFork.Bellatrix:
|
2021-09-16 13:32:32 +00:00
|
|
|
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
|
|
|
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
2021-03-17 18:46:45 +00:00
|
|
|
|
2021-08-23 10:41:48 +00:00
|
|
|
# https://ethereum.github.io/beacon-APIs/#/Debug/getStateV2
|
|
|
|
router.api(MethodGet,
|
2022-01-06 07:38:40 +00:00
|
|
|
"/eth/v2/debug/beacon/states/{state_id}") do (
|
2021-08-23 10:41:48 +00:00
|
|
|
state_id: StateIdent) -> RestApiResponse:
|
|
|
|
let bslot =
|
|
|
|
block:
|
|
|
|
if state_id.isErr():
|
|
|
|
return RestApiResponse.jsonError(Http400, InvalidStateIdValueError,
|
|
|
|
$state_id.error())
|
|
|
|
let bres = node.getBlockSlot(state_id.get())
|
|
|
|
if bres.isErr():
|
|
|
|
return RestApiResponse.jsonError(Http404, StateNotFoundError,
|
|
|
|
$bres.error())
|
|
|
|
bres.get()
|
2021-09-16 13:32:32 +00:00
|
|
|
let contentType =
|
|
|
|
block:
|
2022-01-21 16:52:34 +00:00
|
|
|
let res = preferredContentType(jsonMediaType,
|
|
|
|
sszMediaType)
|
2021-09-16 13:32:32 +00:00
|
|
|
if res.isErr():
|
|
|
|
return RestApiResponse.jsonError(Http406, ContentNotAcceptableError)
|
|
|
|
res.get()
|
2021-08-23 10:41:48 +00:00
|
|
|
node.withStateForBlockSlot(bslot):
|
2021-09-16 13:32:32 +00:00
|
|
|
return
|
2022-01-21 16:52:34 +00:00
|
|
|
if contentType == jsonMediaType:
|
2021-11-05 07:34:34 +00:00
|
|
|
RestApiResponse.jsonResponsePlain(stateData.data)
|
2022-01-21 16:52:34 +00:00
|
|
|
elif contentType == sszMediaType:
|
2021-10-06 17:05:06 +00:00
|
|
|
withState(stateData.data):
|
|
|
|
RestApiResponse.sszResponse(state.data)
|
2021-09-16 13:32:32 +00:00
|
|
|
else:
|
|
|
|
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
|
|
|
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
2021-08-23 10:41:48 +00:00
|
|
|
|
|
|
|
# https://ethereum.github.io/beacon-APIs/#/Debug/getDebugChainHeads
|
2021-03-17 18:46:45 +00:00
|
|
|
router.api(MethodGet,
|
2022-01-06 07:38:40 +00:00
|
|
|
"/eth/v1/debug/beacon/heads") do () -> RestApiResponse:
|
2021-03-17 18:46:45 +00:00
|
|
|
return RestApiResponse.jsonResponse(
|
2021-06-01 11:13:40 +00:00
|
|
|
node.dag.heads.mapIt((root: it.root, slot: it.slot))
|
2021-03-17 18:46:45 +00:00
|
|
|
)
|
2021-04-13 10:19:31 +00:00
|
|
|
|
2022-01-06 07:38:40 +00:00
|
|
|
# Legacy URLS - Nimbus <= 1.5.5 used to expose the REST API with an additional
|
|
|
|
# `/api` path component
|
2021-04-13 10:19:31 +00:00
|
|
|
router.redirect(
|
|
|
|
MethodGet,
|
2022-01-06 07:38:40 +00:00
|
|
|
"/api/eth/v1/debug/beacon/states/{state_id}",
|
|
|
|
"/eth/v1/debug/beacon/states/{state_id}"
|
2021-04-13 10:19:31 +00:00
|
|
|
)
|
|
|
|
router.redirect(
|
|
|
|
MethodGet,
|
2022-01-06 07:38:40 +00:00
|
|
|
"/api/eth/v2/debug/beacon/states/{state_id}",
|
|
|
|
"/eth/v2/debug/beacon/states/{state_id}"
|
2021-04-13 10:19:31 +00:00
|
|
|
)
|
2021-08-23 10:41:48 +00:00
|
|
|
router.redirect(
|
|
|
|
MethodGet,
|
2022-01-06 07:38:40 +00:00
|
|
|
"/api/eth/v1/debug/beacon/heads",
|
|
|
|
"/eth/v1/debug/beacon/heads"
|
2021-08-23 10:41:48 +00:00
|
|
|
)
|