Add REST endpoint to retrieve historical_summaries
This commit is contained in:
parent
e06af18f4d
commit
816276dfb8
|
@ -269,3 +269,5 @@ const
|
|||
"Unable to load state for parent block, database corrupt?"
|
||||
RewardOverflowError* =
|
||||
"Reward value overflow"
|
||||
HistoricalSummariesUnavailable* =
|
||||
"Historical summaries unavailable"
|
||||
|
|
|
@ -138,3 +138,52 @@ proc installDebugApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
bestDescendant: item.bestDescendant))
|
||||
|
||||
RestApiResponse.jsonResponsePlain(response)
|
||||
|
||||
router.metricsApi2(
|
||||
MethodGet,
|
||||
"/eth/v1/debug/beacon/states/{state_id}/historical_summaries",
|
||||
{RestServerMetricsType.Status, Response},
|
||||
) do(state_id: StateIdent) -> RestApiResponse:
|
||||
let
|
||||
sid = state_id.valueOr:
|
||||
return RestApiResponse.jsonError(Http400, InvalidStateIdValueError, $error)
|
||||
bslot = node.getBlockSlotId(sid).valueOr:
|
||||
return RestApiResponse.jsonError(Http404, StateNotFoundError, $error)
|
||||
contentType = preferredContentType(jsonMediaType, sszMediaType).valueOr:
|
||||
return RestApiResponse.jsonError(Http406, ContentNotAcceptableError)
|
||||
|
||||
node.withStateForBlockSlotId(bslot):
|
||||
return withState(state):
|
||||
when consensusFork >= ConsensusFork.Capella:
|
||||
# Build the proof for historical_summaries field (28th field in BeaconState)
|
||||
let gIndex = GeneralizedIndex(59) # 31 + 28 = 59
|
||||
var proof: array[5, Digest]
|
||||
if forkyState.data.build_proof(gIndex, proof).isErr:
|
||||
return RestApiResponse.jsonError(Http500, InvalidMerkleProofIndexError)
|
||||
|
||||
if contentType == jsonMediaType:
|
||||
let response = RestHistoricalSummaries(
|
||||
historical_summaries: forkyState.data.historical_summaries.asSeq(),
|
||||
proof: proof,
|
||||
slot: bslot.slot,
|
||||
)
|
||||
|
||||
RestApiResponse.jsonResponseFinalized(
|
||||
response, node.getStateOptimistic(state), node.dag.isFinalized(bslot.bid)
|
||||
)
|
||||
elif contentType == sszMediaType:
|
||||
let
|
||||
headers = [("eth-consensus-version", consensusFork.toString())]
|
||||
response = GetHistoricalSummariesV1Response(
|
||||
historical_summaries: forkyState.data.historical_summaries,
|
||||
proof: proof,
|
||||
slot: bslot.slot,
|
||||
)
|
||||
|
||||
RestApiResponse.sszResponse(response, headers)
|
||||
else:
|
||||
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
||||
else:
|
||||
RestApiResponse.jsonError(Http404, HistoricalSummariesUnavailable)
|
||||
|
||||
RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
|
|
@ -83,6 +83,7 @@ RestJson.useDefaultSerializationFor(
|
|||
GetGenesisResponse,
|
||||
GetHeaderResponseDeneb,
|
||||
GetHeaderResponseElectra,
|
||||
GetHistoricalSummariesV1Response,
|
||||
GetKeystoresResponse,
|
||||
GetNextWithdrawalsResponse,
|
||||
GetPoolAttesterSlashingsResponse,
|
||||
|
@ -131,6 +132,7 @@ RestJson.useDefaultSerializationFor(
|
|||
RestEpochSyncCommittee,
|
||||
RestExtraData,
|
||||
RestGenesis,
|
||||
RestHistoricalSummaries,
|
||||
RestIndexedErrorMessage,
|
||||
RestIndexedErrorMessageItem,
|
||||
RestMetadata,
|
||||
|
@ -384,6 +386,7 @@ type
|
|||
DataOptimisticAndFinalizedObject |
|
||||
GetBlockV2Response |
|
||||
GetDistributedKeystoresResponse |
|
||||
GetHistoricalSummariesV1Response |
|
||||
GetKeystoresResponse |
|
||||
GetRemoteKeystoresResponse |
|
||||
GetStateForkResponse |
|
||||
|
|
|
@ -73,3 +73,56 @@ proc getStateV2*(client: RestClientRef, state_id: StateIdent,
|
|||
msg: msg, status: error.code, message: error.message)
|
||||
else:
|
||||
raiseRestResponseError(resp)
|
||||
|
||||
proc getHistoricalSummariesV1Plain*(
|
||||
state_id: StateIdent
|
||||
): RestPlainResponse {.
|
||||
rest,
|
||||
endpoint: "/eth/v1/debug/beacon/states/{state_id}/historical_summaries",
|
||||
accept: preferSSZ,
|
||||
meth: MethodGet
|
||||
.}
|
||||
|
||||
proc getHistoricalSummariesV1*(
|
||||
client: RestClientRef, state_id: StateIdent, cfg: RuntimeConfig, restAccept = ""
|
||||
): Future[Option[GetHistoricalSummariesV1Response]] {.async.} =
|
||||
let resp =
|
||||
if len(restAccept) > 0:
|
||||
await client.getHistoricalSummariesV1Plain(state_id, restAcceptType = restAccept)
|
||||
else:
|
||||
await client.getHistoricalSummariesV1Plain(state_id)
|
||||
|
||||
return
|
||||
case resp.status
|
||||
of 200:
|
||||
if resp.contentType.isNone() or isWildCard(resp.contentType.get().mediaType):
|
||||
raise newException(RestError, "Missing or incorrect Content-Type")
|
||||
else:
|
||||
let mediaType = resp.contentType.get().mediaType
|
||||
if mediaType == ApplicationJsonMediaType:
|
||||
let summaries = decodeBytes(
|
||||
GetHistoricalSummariesV1Response, resp.data, resp.contentType
|
||||
).valueOr:
|
||||
raise newException(RestError, $error)
|
||||
some(summaries)
|
||||
elif mediaType == OctetStreamMediaType:
|
||||
let summaries =
|
||||
try:
|
||||
SSZ.decode(resp.data, GetHistoricalSummariesV1Response)
|
||||
except SerializationError as exc:
|
||||
raise newException(RestError, exc.msg)
|
||||
some(summaries)
|
||||
else:
|
||||
raise newException(RestError, "Unsupported Content-Type")
|
||||
of 404:
|
||||
none(GetHistoricalSummariesV1Response)
|
||||
of 400, 500:
|
||||
let error = decodeBytes(RestErrorMessage, resp.data, resp.contentType).valueOr:
|
||||
let msg =
|
||||
"Incorrect response error format (" & $resp.status & ") [" & $error & "]"
|
||||
raise (ref RestResponseError)(msg: msg, status: resp.status)
|
||||
let msg = "Error response (" & $resp.status & ") [" & error.message & "]"
|
||||
raise
|
||||
(ref RestResponseError)(msg: msg, status: error.code, message: error.message)
|
||||
else:
|
||||
raiseRestResponseError(resp)
|
||||
|
|
|
@ -337,6 +337,11 @@ type
|
|||
RestEpochRandao* = object
|
||||
randao*: Eth2Digest
|
||||
|
||||
RestHistoricalSummaries* = object
|
||||
historical_summaries*: seq[HistoricalSummary]
|
||||
proof*: array[5, Eth2Digest]
|
||||
slot*: Slot
|
||||
|
||||
DataEnclosedObject*[T] = object
|
||||
data*: T
|
||||
|
||||
|
@ -469,6 +474,11 @@ type
|
|||
GetStateV2Response* = ref ForkedHashedBeaconState
|
||||
GetAggregatedAttestationV2Response* = ForkedAttestation
|
||||
|
||||
GetHistoricalSummariesV1Response* = object
|
||||
historical_summaries*: HashList[HistoricalSummary, Limit HISTORICAL_ROOTS_LIMIT]
|
||||
proof*: array[5, Eth2Digest]
|
||||
slot*: Slot
|
||||
|
||||
RestRoot* = object
|
||||
root*: Eth2Digest
|
||||
|
||||
|
|
Loading…
Reference in New Issue