REST JSON support improvements (#3232)
* support downloading blocks / states via JSON in addition to SSZ - slow, but needed for infura support - SSZ is still used when server supports it * use common forked block/state reader in REST API * fix stack overflows in REST JSON decoder * fix invalid serialization of `justification_bits` in `/eth/v1/debug/beacon/states` and `/eth/v2/debug/beacon/states` * fix REST client to use `/eth/...` instead of `/api/eth/...`, update "default" urls to expose REST api via `/eth` as well as this is what the standard says - `/api` was added early on based on an example "base url" in the spec that has been removed since * expose Nimbus REST extensions via `/nimbus` in addition to `/api/nimbus` to stay consistent with `/eth` * fix invalid state root when reading states via REST * fix recursive imports in `spec/ssz_codec` * remove usages of `serialization.useCustomSerialization` - fickle
This commit is contained in:
parent
0a4728a241
commit
0e2b4e39fa
|
@ -58,10 +58,7 @@ type
|
|||
HashList[PendingAttestation, Limit(MAX_ATTESTATIONS * SLOTS_PER_EPOCH)]
|
||||
|
||||
# Finality
|
||||
justification_bits*: uint8 ##\
|
||||
## Bit set for every recent justified epoch
|
||||
## Model a Bitvector[4] as a one-byte uint, which should remain consistent
|
||||
## with ssz/hashing.
|
||||
justification_bits*: JustificationBits
|
||||
|
||||
previous_justified_checkpoint*: Checkpoint ##\
|
||||
## Previous epoch snapshot
|
||||
|
@ -113,10 +110,7 @@ type
|
|||
HashList[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT]
|
||||
|
||||
# Finality
|
||||
justification_bits*: uint8 ##\
|
||||
## Bit set for every recent justified epoch
|
||||
## Model a Bitvector[4] as a one-byte uint, which should remain consistent
|
||||
## with ssz/hashing.
|
||||
justification_bits*: JustificationBits
|
||||
|
||||
previous_justified_checkpoint*: Checkpoint ##\
|
||||
## Previous epoch snapshot
|
||||
|
@ -175,10 +169,7 @@ type
|
|||
HashList[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT]
|
||||
|
||||
# Finality
|
||||
justification_bits*: uint8 ##\
|
||||
## Bit set for every recent justified epoch
|
||||
## Model a Bitvector[4] as a one-byte uint, which should remain consistent
|
||||
## with ssz/hashing.
|
||||
justification_bits*: JustificationBits
|
||||
|
||||
previous_justified_checkpoint*: Checkpoint ##\
|
||||
## Previous epoch snapshot
|
||||
|
|
|
@ -184,8 +184,9 @@ proc init*(T: type BeaconNode,
|
|||
try:
|
||||
# Checkpoint block might come from an earlier fork than the state with
|
||||
# the state having empty slots processed past the fork epoch.
|
||||
checkpointBlock = readSszForkedTrustedSignedBeaconBlock(
|
||||
let tmp = readSszForkedSignedBeaconBlock(
|
||||
cfg, readAllBytes(checkpointBlockPath).tryGet())
|
||||
checkpointBlock = tmp.asTrusted()
|
||||
except SszError as err:
|
||||
fatal "Invalid checkpoint block", err = err.formatMsg(checkpointBlockPath)
|
||||
quit 1
|
||||
|
|
|
@ -103,7 +103,7 @@ proc toString*(kind: ValidatorFilterKind): string =
|
|||
|
||||
proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getGenesis
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/genesis") do () -> RestApiResponse:
|
||||
router.api(MethodGet, "/eth/v1/beacon/genesis") do () -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(
|
||||
(
|
||||
genesis_time: getStateField(node.dag.headState.data, genesis_time),
|
||||
|
@ -114,7 +114,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateRoot
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/states/{state_id}/root") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/states/{state_id}/root") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let bslot =
|
||||
block:
|
||||
|
@ -137,7 +137,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateFork
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/states/{state_id}/fork") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/states/{state_id}/fork") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let bslot =
|
||||
block:
|
||||
|
@ -170,7 +170,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateFinalityCheckpoints
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/beacon/states/{state_id}/finality_checkpoints") do (
|
||||
"/eth/v1/beacon/states/{state_id}/finality_checkpoints") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let bslot =
|
||||
block:
|
||||
|
@ -201,7 +201,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateValidators
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/states/{state_id}/validators") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/states/{state_id}/validators") do (
|
||||
state_id: StateIdent, id: seq[ValidatorIdent],
|
||||
status: seq[ValidatorFilter]) -> RestApiResponse:
|
||||
let bslot =
|
||||
|
@ -331,7 +331,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateValidator
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/beacon/states/{state_id}/validators/{validator_id}") do (
|
||||
"/eth/v1/beacon/states/{state_id}/validators/{validator_id}") do (
|
||||
state_id: StateIdent, validator_id: ValidatorIdent) -> RestApiResponse:
|
||||
let bslot =
|
||||
block:
|
||||
|
@ -400,7 +400,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getStateValidatorBalances
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/beacon/states/{state_id}/validator_balances") do (
|
||||
"/eth/v1/beacon/states/{state_id}/validator_balances") do (
|
||||
state_id: StateIdent, id: seq[ValidatorIdent]) -> RestApiResponse:
|
||||
let bslot =
|
||||
block:
|
||||
|
@ -493,7 +493,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getEpochCommittees
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/beacon/states/{state_id}/committees") do (
|
||||
"/eth/v1/beacon/states/{state_id}/committees") do (
|
||||
state_id: StateIdent, epoch: Option[Epoch], index: Option[CommitteeIndex],
|
||||
slot: Option[Slot]) -> RestApiResponse:
|
||||
let bslot =
|
||||
|
@ -583,7 +583,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getEpochSyncCommittees
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/beacon/states/{state_id}/sync_committees") do (
|
||||
"/eth/v1/beacon/states/{state_id}/sync_committees") do (
|
||||
state_id: StateIdent, epoch: Option[Epoch]) -> RestApiResponse:
|
||||
let bslot =
|
||||
block:
|
||||
|
@ -664,7 +664,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeaders
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/headers") do (
|
||||
router.api(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`.
|
||||
|
@ -717,7 +717,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeader
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/headers/{block_id}") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/headers/{block_id}") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
let bdata =
|
||||
block:
|
||||
|
@ -749,7 +749,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlock
|
||||
router.api(MethodPost, "/api/eth/v1/beacon/blocks") do (
|
||||
router.api(MethodPost, "/eth/v1/beacon/blocks") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let forked =
|
||||
block:
|
||||
|
@ -798,7 +798,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonMsgResponse(BlockValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlock
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/blocks/{block_id}") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/blocks/{block_id}") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
let bdata =
|
||||
block:
|
||||
|
@ -830,7 +830,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
RestApiResponse.jsonError(Http404, BlockNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockV2
|
||||
router.api(MethodGet, "/api/eth/v2/beacon/blocks/{block_id}") do (
|
||||
router.api(MethodGet, "/eth/v2/beacon/blocks/{block_id}") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
let bdata =
|
||||
block:
|
||||
|
@ -864,7 +864,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockRoot
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/blocks/{block_id}/root") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/blocks/{block_id}/root") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
let blck =
|
||||
block:
|
||||
|
@ -879,7 +879,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockAttestations
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/beacon/blocks/{block_id}/attestations") do (
|
||||
"/eth/v1/beacon/blocks/{block_id}/attestations") do (
|
||||
block_id: BlockIdent) -> RestApiResponse:
|
||||
let bdata =
|
||||
block:
|
||||
|
@ -895,7 +895,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
RestApiResponse.jsonResponse(blck.message.body.attestations.asSeq())
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolAttestations
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/pool/attestations") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/pool/attestations") do (
|
||||
slot: Option[Slot],
|
||||
committee_index: Option[CommitteeIndex]) -> RestApiResponse:
|
||||
let vindex =
|
||||
|
@ -923,7 +923,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponse(res)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolAttestations
|
||||
router.api(MethodPost, "/api/eth/v1/beacon/pool/attestations") do (
|
||||
router.api(MethodPost, "/eth/v1/beacon/pool/attestations") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let attestations =
|
||||
block:
|
||||
|
@ -970,7 +970,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonMsgResponse(AttestationValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolAttesterSlashings
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/pool/attester_slashings") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/pool/attester_slashings") do (
|
||||
) -> RestApiResponse:
|
||||
var res: seq[AttesterSlashing]
|
||||
if isNil(node.exitPool):
|
||||
|
@ -982,7 +982,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponse(res)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolAttesterSlashings
|
||||
router.api(MethodPost, "/api/eth/v1/beacon/pool/attester_slashings") do (
|
||||
router.api(MethodPost, "/eth/v1/beacon/pool/attester_slashings") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let slashing =
|
||||
block:
|
||||
|
@ -1002,7 +1002,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonMsgResponse(AttesterSlashingValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolProposerSlashings
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/pool/proposer_slashings") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/pool/proposer_slashings") do (
|
||||
) -> RestApiResponse:
|
||||
var res: seq[ProposerSlashing]
|
||||
if isNil(node.exitPool):
|
||||
|
@ -1014,7 +1014,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponse(res)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolProposerSlashings
|
||||
router.api(MethodPost, "/api/eth/v1/beacon/pool/proposer_slashings") do (
|
||||
router.api(MethodPost, "/eth/v1/beacon/pool/proposer_slashings") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let slashing =
|
||||
block:
|
||||
|
@ -1034,7 +1034,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonMsgResponse(ProposerSlashingValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolSyncCommitteeSignatures
|
||||
router.api(MethodPost, "/api/eth/v1/beacon/pool/sync_committees") do (
|
||||
router.api(MethodPost, "/eth/v1/beacon/pool/sync_committees") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let messages =
|
||||
block:
|
||||
|
@ -1065,7 +1065,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
SyncCommitteeMessageValidationSuccess)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolVoluntaryExits
|
||||
router.api(MethodGet, "/api/eth/v1/beacon/pool/voluntary_exits") do (
|
||||
router.api(MethodGet, "/eth/v1/beacon/pool/voluntary_exits") do (
|
||||
) -> RestApiResponse:
|
||||
var res: seq[SignedVoluntaryExit]
|
||||
if isNil(node.exitPool):
|
||||
|
@ -1077,7 +1077,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponse(res)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolVoluntaryExit
|
||||
router.api(MethodPost, "/api/eth/v1/beacon/pool/voluntary_exits") do (
|
||||
router.api(MethodPost, "/eth/v1/beacon/pool/voluntary_exits") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let exit =
|
||||
block:
|
||||
|
@ -1096,128 +1096,130 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
$res.error())
|
||||
return RestApiResponse.jsonMsgResponse(VoluntaryExitValidationSuccess)
|
||||
|
||||
# Legacy URLS - Nimbus <= 1.5.5 used to expose the REST API with an additional
|
||||
# `/api` path component
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/eth/v1/beacon/genesis",
|
||||
"/eth/v1/beacon/genesis",
|
||||
"/api/eth/v1/beacon/genesis"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/eth/v1/beacon/states/{state_id}/root",
|
||||
"/eth/v1/beacon/states/{state_id}/root",
|
||||
"/api/eth/v1/beacon/states/{state_id}/root"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/eth/v1/beacon/states/{state_id}/fork",
|
||||
"/eth/v1/beacon/states/{state_id}/fork",
|
||||
"/api/eth/v1/beacon/states/{state_id}/fork"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/finality_checkpoints",
|
||||
"/api/eth/v1/beacon/states/{state_id}/finality_checkpoints"
|
||||
"/api/eth/v1/beacon/states/{state_id}/finality_checkpoints",
|
||||
"/eth/v1/beacon/states/{state_id}/finality_checkpoints"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/validators",
|
||||
"/api/eth/v1/beacon/states/{state_id}/validators"
|
||||
"/api/eth/v1/beacon/states/{state_id}/validators",
|
||||
"/eth/v1/beacon/states/{state_id}/validators"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/validators/{validator_id}",
|
||||
"/api/eth/v1/beacon/states/{state_id}/validators/{validator_id}"
|
||||
"/api/eth/v1/beacon/states/{state_id}/validators/{validator_id}",
|
||||
"/eth/v1/beacon/states/{state_id}/validators/{validator_id}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/validator_balances",
|
||||
"/api/eth/v1/beacon/states/{state_id}/validator_balances"
|
||||
"/api/eth/v1/beacon/states/{state_id}/validator_balances",
|
||||
"/eth/v1/beacon/states/{state_id}/validator_balances"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/committees",
|
||||
"/api/eth/v1/beacon/states/{state_id}/committees"
|
||||
"/api/eth/v1/beacon/states/{state_id}/committees",
|
||||
"/eth/v1/beacon/states/{state_id}/committees"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/states/{state_id}/sync_committees",
|
||||
"/api/eth/v1/beacon/states/{state_id}/sync_committees"
|
||||
"/api/eth/v1/beacon/states/{state_id}/sync_committees",
|
||||
"/eth/v1/beacon/states/{state_id}/sync_committees"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/headers",
|
||||
"/api/eth/v1/beacon/headers"
|
||||
"/api/eth/v1/beacon/headers",
|
||||
"/eth/v1/beacon/headers"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/headers/{block_id}",
|
||||
"/api/eth/v1/beacon/headers/{block_id}"
|
||||
"/api/eth/v1/beacon/headers/{block_id}",
|
||||
"/eth/v1/beacon/headers/{block_id}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/beacon/blocks",
|
||||
"/api/eth/v1/beacon/blocks"
|
||||
"/api/eth/v1/beacon/blocks",
|
||||
"/eth/v1/beacon/blocks"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/blocks/{block_id}",
|
||||
"/api/eth/v1/beacon/blocks/{block_id}"
|
||||
"/api/eth/v1/beacon/blocks/{block_id}",
|
||||
"/eth/v1/beacon/blocks/{block_id}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v2/beacon/blocks/{block_id}",
|
||||
"/api/eth/v2/beacon/blocks/{block_id}"
|
||||
"/api/eth/v2/beacon/blocks/{block_id}",
|
||||
"/eth/v2/beacon/blocks/{block_id}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/blocks/{block_id}/root",
|
||||
"/api/eth/v1/beacon/blocks/{block_id}/root"
|
||||
"/api/eth/v1/beacon/blocks/{block_id}/root",
|
||||
"/eth/v1/beacon/blocks/{block_id}/root"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/blocks/{block_id}/attestations",
|
||||
"/api/eth/v1/beacon/blocks/{block_id}/attestations"
|
||||
"/api/eth/v1/beacon/blocks/{block_id}/attestations",
|
||||
"/eth/v1/beacon/blocks/{block_id}/attestations"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/pool/attestations",
|
||||
"/api/eth/v1/beacon/pool/attestations"
|
||||
"/api/eth/v1/beacon/pool/attestations",
|
||||
"/eth/v1/beacon/pool/attestations"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/beacon/pool/attestations",
|
||||
"/api/eth/v1/beacon/pool/attestations"
|
||||
"/api/eth/v1/beacon/pool/attestations",
|
||||
"/eth/v1/beacon/pool/attestations"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/beacon/pool/attester_slashings",
|
||||
"/api/eth/v1/beacon/pool/attester_slashings"
|
||||
"/api/eth/v1/beacon/pool/attester_slashings",
|
||||
"/eth/v1/beacon/pool/attester_slashings"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/pool/attester_slashings",
|
||||
"/api/eth/v1/beacon/pool/attester_slashings"
|
||||
"/api/eth/v1/beacon/pool/attester_slashings",
|
||||
"/eth/v1/beacon/pool/attester_slashings"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/beacon/pool/proposer_slashings",
|
||||
"/api/eth/v1/beacon/pool/proposer_slashings"
|
||||
"/api/eth/v1/beacon/pool/proposer_slashings",
|
||||
"/eth/v1/beacon/pool/proposer_slashings"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/pool/proposer_slashings",
|
||||
"/api/eth/v1/beacon/pool/proposer_slashings"
|
||||
"/api/eth/v1/beacon/pool/proposer_slashings",
|
||||
"/eth/v1/beacon/pool/proposer_slashings"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/beacon/pool/sync_committees",
|
||||
"/api/eth/v1/beacon/pool/sync_committees"
|
||||
"/api/eth/v1/beacon/pool/sync_committees",
|
||||
"/eth/v1/beacon/pool/sync_committees"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/beacon/pool/voluntary_exits",
|
||||
"/api/eth/v1/beacon/pool/voluntary_exits"
|
||||
"/api/eth/v1/beacon/pool/voluntary_exits",
|
||||
"/eth/v1/beacon/pool/voluntary_exits"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/beacon/pool/voluntary_exits",
|
||||
"/api/eth/v1/beacon/pool/voluntary_exits"
|
||||
"/api/eth/v1/beacon/pool/voluntary_exits",
|
||||
"/eth/v1/beacon/pool/voluntary_exits"
|
||||
)
|
||||
|
|
|
@ -253,34 +253,36 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Config/getForkSchedule
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/config/fork_schedule") do () -> RestApiResponse:
|
||||
"/eth/v1/config/fork_schedule") do () -> RestApiResponse:
|
||||
return RestApiResponse.response(cachedForkSchedule, Http200,
|
||||
"application/json")
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Config/getSpec
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/config/spec") do () -> RestApiResponse:
|
||||
"/eth/v1/config/spec") do () -> RestApiResponse:
|
||||
return RestApiResponse.response(cachedConfigSpec, Http200,
|
||||
"application/json")
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Config/getDepositContract
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/config/deposit_contract") do () -> RestApiResponse:
|
||||
"/eth/v1/config/deposit_contract") do () -> RestApiResponse:
|
||||
return RestApiResponse.response(cachedDepositContract, Http200,
|
||||
"application/json")
|
||||
|
||||
# Legacy URLS - Nimbus <= 1.5.5 used to expose the REST API with an additional
|
||||
# `/api` path component
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/config/fork_schedule",
|
||||
"/api/eth/v1/config/fork_schedule"
|
||||
"/api/eth/v1/config/fork_schedule",
|
||||
"/eth/v1/config/fork_schedule"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/config/spec",
|
||||
"/api/eth/v1/config/spec"
|
||||
"/api/eth/v1/config/spec",
|
||||
"/eth/v1/config/spec"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/config/deposit_contract",
|
||||
"/api/eth/v1/config/deposit_contract"
|
||||
"/api/eth/v1/config/deposit_contract",
|
||||
"/eth/v1/config/deposit_contract"
|
||||
)
|
||||
|
|
|
@ -18,7 +18,7 @@ logScope: topics = "rest_debug"
|
|||
proc installDebugApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://ethereum.github.io/beacon-APIs/#/Debug/getState
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/debug/beacon/states/{state_id}") do (
|
||||
"/eth/v1/debug/beacon/states/{state_id}") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let bslot =
|
||||
block:
|
||||
|
@ -54,7 +54,7 @@ proc installDebugApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Debug/getStateV2
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v2/debug/beacon/states/{state_id}") do (
|
||||
"/eth/v2/debug/beacon/states/{state_id}") do (
|
||||
state_id: StateIdent) -> RestApiResponse:
|
||||
let bslot =
|
||||
block:
|
||||
|
@ -87,23 +87,25 @@ proc installDebugApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Debug/getDebugChainHeads
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/debug/beacon/heads") do () -> RestApiResponse:
|
||||
"/eth/v1/debug/beacon/heads") do () -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(
|
||||
node.dag.heads.mapIt((root: it.root, slot: it.slot))
|
||||
)
|
||||
|
||||
# Legacy URLS - Nimbus <= 1.5.5 used to expose the REST API with an additional
|
||||
# `/api` path component
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/debug/beacon/states/{state_id}",
|
||||
"/api/eth/v1/debug/beacon/states/{state_id}"
|
||||
"/api/eth/v1/debug/beacon/states/{state_id}",
|
||||
"/eth/v1/debug/beacon/states/{state_id}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v2/debug/beacon/states/{state_id}",
|
||||
"/api/eth/v2/debug/beacon/states/{state_id}"
|
||||
"/api/eth/v2/debug/beacon/states/{state_id}",
|
||||
"/eth/v2/debug/beacon/states/{state_id}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/debug/beacon/heads",
|
||||
"/api/eth/v1/debug/beacon/heads"
|
||||
"/api/eth/v1/debug/beacon/heads",
|
||||
"/eth/v1/debug/beacon/heads"
|
||||
)
|
||||
|
|
|
@ -95,7 +95,7 @@ proc eventHandler*(response: HttpResponseRef, node: BeaconNode,
|
|||
|
||||
proc installEventApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://ethereum.github.io/beacon-APIs/#/Events/eventstream
|
||||
router.api(MethodGet, "/api/eth/v1/events") do (
|
||||
router.api(MethodGet, "/eth/v1/events") do (
|
||||
topics: seq[EventTopic]) -> RestApiResponse:
|
||||
let eventTopics =
|
||||
block:
|
||||
|
@ -175,8 +175,10 @@ proc installEventApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
await allFutures(pending)
|
||||
return
|
||||
|
||||
# Legacy URLS - Nimbus <= 1.5.5 used to expose the REST API with an additional
|
||||
# `/api` path component
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/events",
|
||||
"/api/eth/v1/events"
|
||||
"/api/eth/v1/events",
|
||||
"/eth/v1/events"
|
||||
)
|
||||
|
|
|
@ -112,10 +112,10 @@ proc toNode(v: PubSubPeer, backoff: Moment): RestPubSubPeer =
|
|||
)
|
||||
|
||||
proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
router.api(MethodGet, "/api/nimbus/v1/beacon/head") do () -> RestApiResponse:
|
||||
router.api(MethodGet, "/nimbus/v1/beacon/head") do () -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(node.dag.head.slot)
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/chain/head") do() -> RestApiResponse:
|
||||
router.api(MethodGet, "/nimbus/v1/chain/head") do() -> RestApiResponse:
|
||||
let
|
||||
head = node.dag.head
|
||||
finalized = getStateField(node.dag.headState.data, finalized_checkpoint)
|
||||
|
@ -132,26 +132,26 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
)
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/syncmanager/status") do (
|
||||
router.api(MethodGet, "/nimbus/v1/syncmanager/status") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(node.syncManager.inProgress)
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/node/peerid") do (
|
||||
router.api(MethodGet, "/nimbus/v1/node/peerid") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse((peerid: $node.network.peerId()))
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/node/version") do (
|
||||
router.api(MethodGet, "/nimbus/v1/node/version") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse((version: "Nimbus/" & fullVersionStr))
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/network/ids") do (
|
||||
router.api(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))
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/network/peers") do (
|
||||
router.api(MethodGet, "/nimbus/v1/network/peers") do (
|
||||
) -> RestApiResponse:
|
||||
var res: seq[RestSimplePeer]
|
||||
for id, peer in node.network.peerPool:
|
||||
|
@ -164,7 +164,7 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
return RestApiResponse.jsonResponse((peers: res))
|
||||
|
||||
router.api(MethodPost, "/api/nimbus/v1/graffiti") do (
|
||||
router.api(MethodPost, "/nimbus/v1/graffiti") do (
|
||||
value: Option[GraffitiBytes]) -> RestApiResponse:
|
||||
if value.isSome() and value.get().isOk():
|
||||
node.graffitiBytes = value.get().get()
|
||||
|
@ -172,11 +172,11 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
else:
|
||||
return RestApiResponse.jsonError(Http400, InvalidGraffitiBytesValye)
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/graffiti") do (
|
||||
router.api(MethodGet, "/nimbus/v1/graffiti") do (
|
||||
) -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(node.graffitiBytes)
|
||||
|
||||
router.api(MethodPost, "/api/nimbus/v1/chronicles/settings") do (
|
||||
router.api(MethodPost, "/nimbus/v1/chronicles/settings") do (
|
||||
log_level: Option[string]) -> RestApiResponse:
|
||||
if log_level.isSome():
|
||||
let level =
|
||||
|
@ -190,7 +190,7 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
updateLogLevel(level)
|
||||
return RestApiResponse.jsonResponse((result: true))
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/eth1/chain") do (
|
||||
router.api(MethodGet, "/nimbus/v1/eth1/chain") do (
|
||||
) -> RestApiResponse:
|
||||
let res =
|
||||
if not(isNil(node.eth1Monitor)):
|
||||
|
@ -199,7 +199,7 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
@[]
|
||||
return RestApiResponse.jsonResponse(res)
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/eth1/proposal_data") do (
|
||||
router.api(MethodGet, "/nimbus/v1/eth1/proposal_data") do (
|
||||
) -> RestApiResponse:
|
||||
let wallSlot = node.beaconClock.now.slotOrZero
|
||||
let head =
|
||||
|
@ -215,7 +215,7 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
do:
|
||||
return RestApiResponse.jsonError(Http400, PrunedStateError)
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/debug/chronos/futures") do (
|
||||
router.api(MethodGet, "/nimbus/v1/debug/chronos/futures") do (
|
||||
) -> RestApiResponse:
|
||||
when defined(chronosFutureTracking):
|
||||
var res: seq[RestFutureInfo]
|
||||
|
@ -240,7 +240,7 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http503,
|
||||
"Compile with '-d:chronosFutureTracking' to get this request working")
|
||||
|
||||
router.api(MethodGet, "/api/nimbus/v1/debug/gossip/peers") do (
|
||||
router.api(MethodGet, "/nimbus/v1/debug/gossip/peers") do (
|
||||
) -> RestApiResponse:
|
||||
|
||||
let gossipPeers =
|
||||
|
@ -302,3 +302,62 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
all_peers: allPeers
|
||||
)
|
||||
)
|
||||
|
||||
# Legacy URLS - Nimbus <= 1.5.5 used to expose the REST API with an additional
|
||||
# `/api` path component
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/beacon/head",
|
||||
"/nimbus/v1/beacon/head")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/chain/head",
|
||||
"/nimbus/v1/chain/head")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/syncmanager/status",
|
||||
"/nimbus/v1/syncmanager/status")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/node/peerid",
|
||||
"/nimbus/v1/node/peerid")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/node/version",
|
||||
"/nimbus/v1/node/version")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/network/ids",
|
||||
"/nimbus/v1/network/ids")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/network/peers",
|
||||
"/nimbus/v1/network/peers")
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/api/nimbus/v1/graffiti",
|
||||
"/nimbus/v1/graffiti")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/graffiti",
|
||||
"/nimbus/v1/graffiti")
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/api/nimbus/v1/chronicles/settings",
|
||||
"/nimbus/v1/chronicles/settings")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/eth1/chain",
|
||||
"/nimbus/v1/eth1/chain")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/eth1/proposal_data",
|
||||
"/nimbus/v1/eth1/proposal_data")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/debug/chronos/futures",
|
||||
"/nimbus/v1/debug/chronos/futures")
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/api/nimbus/v1/debug/gossip/peers",
|
||||
"/nimbus/v1/debug/gossip/peers")
|
||||
|
|
|
@ -133,7 +133,7 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
RestApiResponse.prepareJsonResponse((version: "Nimbus/" & fullVersionStr))
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getNetworkIdentity
|
||||
router.api(MethodGet, "/api/eth/v1/node/identity") do () -> RestApiResponse:
|
||||
router.api(MethodGet, "/eth/v1/node/identity") do () -> RestApiResponse:
|
||||
let discoveryAddresses =
|
||||
block:
|
||||
let res = node.getDiscoveryAddresses()
|
||||
|
@ -165,7 +165,7 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getPeers
|
||||
router.api(MethodGet, "/api/eth/v1/node/peers") do (
|
||||
router.api(MethodGet, "/eth/v1/node/peers") do (
|
||||
state: seq[PeerStateKind],
|
||||
direction: seq[PeerDirectKind]) -> RestApiResponse:
|
||||
let connectionMask =
|
||||
|
@ -208,7 +208,7 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponseWMeta(res, (count: uint64(len(res))))
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getPeerCount
|
||||
router.api(MethodGet, "/api/eth/v1/node/peer_count") do () -> RestApiResponse:
|
||||
router.api(MethodGet, "/eth/v1/node/peer_count") do () -> RestApiResponse:
|
||||
var res: RestNodePeerCount
|
||||
for item in node.network.peers.values():
|
||||
case item.connectionState
|
||||
|
@ -225,7 +225,7 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponse(res)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getPeer
|
||||
router.api(MethodGet, "/api/eth/v1/node/peers/{peer_id}") do (
|
||||
router.api(MethodGet, "/eth/v1/node/peers/{peer_id}") do (
|
||||
peer_id: PeerID) -> RestApiResponse:
|
||||
let peer =
|
||||
block:
|
||||
|
@ -249,16 +249,16 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getNodeVersion
|
||||
router.api(MethodGet, "/api/eth/v1/node/version") do () -> RestApiResponse:
|
||||
router.api(MethodGet, "/eth/v1/node/version") do () -> RestApiResponse:
|
||||
return RestApiResponse.response(cachedVersion, Http200,
|
||||
"application/json")
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getSyncingStatus
|
||||
router.api(MethodGet, "/api/eth/v1/node/syncing") do () -> RestApiResponse:
|
||||
router.api(MethodGet, "/eth/v1/node/syncing") do () -> RestApiResponse:
|
||||
return RestApiResponse.jsonResponse(node.syncManager.getInfo())
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Node/getHealth
|
||||
router.api(MethodGet, "/api/eth/v1/node/health") do () -> RestApiResponse:
|
||||
router.api(MethodGet, "/eth/v1/node/health") do () -> RestApiResponse:
|
||||
# TODO: Add ability to detect node's issues and return 503 error according
|
||||
# to specification.
|
||||
let res =
|
||||
|
@ -268,38 +268,40 @@ proc installNodeApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
(health: 200)
|
||||
return RestApiResponse.jsonResponse(res)
|
||||
|
||||
# Legacy URLS - Nimbus <= 1.5.5 used to expose the REST API with an additional
|
||||
# `/api` path component
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/node/identity",
|
||||
"/api/eth/v1/node/identity"
|
||||
"/api/eth/v1/node/identity",
|
||||
"/eth/v1/node/identity"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/node/peers",
|
||||
"/api/eth/v1/node/peers"
|
||||
"/api/eth/v1/node/peers",
|
||||
"/eth/v1/node/peers"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/node/peer_count",
|
||||
"/api/eth/v1/node/peer_count"
|
||||
"/api/eth/v1/node/peer_count",
|
||||
"/eth/v1/node/peer_count"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/node/peers/{peer_id}",
|
||||
"/api/eth/v1/node/peers/{peer_id}"
|
||||
"/api/eth/v1/node/peers/{peer_id}",
|
||||
"/eth/v1/node/peers/{peer_id}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/node/version",
|
||||
"/api/eth/v1/node/version"
|
||||
"/api/eth/v1/node/version",
|
||||
"/eth/v1/node/version"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/node/syncing",
|
||||
"/api/eth/v1/node/syncing"
|
||||
"/api/eth/v1/node/syncing",
|
||||
"/eth/v1/node/syncing"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/node/health",
|
||||
"/api/eth/v1/node/health"
|
||||
"/api/eth/v1/node/health",
|
||||
"/eth/v1/node/health"
|
||||
)
|
||||
|
|
|
@ -21,7 +21,7 @@ logScope: topics = "rest_validatorapi"
|
|||
|
||||
proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/getAttesterDuties
|
||||
router.api(MethodPost, "/api/eth/v1/validator/duties/attester/{epoch}") do (
|
||||
router.api(MethodPost, "/eth/v1/validator/duties/attester/{epoch}") do (
|
||||
epoch: Epoch, contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let indexList =
|
||||
block:
|
||||
|
@ -105,7 +105,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponseWRoot(duties, droot)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/getProposerDuties
|
||||
router.api(MethodGet, "/api/eth/v1/validator/duties/proposer/{epoch}") do (
|
||||
router.api(MethodGet, "/eth/v1/validator/duties/proposer/{epoch}") do (
|
||||
epoch: Epoch) -> RestApiResponse:
|
||||
let qepoch =
|
||||
block:
|
||||
|
@ -152,7 +152,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
res
|
||||
return RestApiResponse.jsonResponseWRoot(duties, droot)
|
||||
|
||||
router.api(MethodPost, "/api/eth/v1/validator/duties/sync/{epoch}") do (
|
||||
router.api(MethodPost, "/eth/v1/validator/duties/sync/{epoch}") do (
|
||||
epoch: Epoch, contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let indexList =
|
||||
block:
|
||||
|
@ -285,7 +285,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http404, StateNotFoundError)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/produceBlock
|
||||
router.api(MethodGet, "/api/eth/v1/validator/blocks/{slot}") do (
|
||||
router.api(MethodGet, "/eth/v1/validator/blocks/{slot}") do (
|
||||
slot: Slot, randao_reveal: Option[ValidatorSig],
|
||||
graffiti: Option[GraffitiBytes]) -> RestApiResponse:
|
||||
let message =
|
||||
|
@ -343,7 +343,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
"Unable to produce block for altair fork")
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/produceBlockV2
|
||||
router.api(MethodGet, "/api/eth/v2/validator/blocks/{slot}") do (
|
||||
router.api(MethodGet, "/eth/v2/validator/blocks/{slot}") do (
|
||||
slot: Slot, randao_reveal: Option[ValidatorSig],
|
||||
graffiti: Option[GraffitiBytes]) -> RestApiResponse:
|
||||
let message =
|
||||
|
@ -395,7 +395,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponsePlain(message)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/produceAttestationData
|
||||
router.api(MethodGet, "/api/eth/v1/validator/attestation_data") do (
|
||||
router.api(MethodGet, "/eth/v1/validator/attestation_data") do (
|
||||
slot: Option[Slot],
|
||||
committee_index: Option[CommitteeIndex]) -> RestApiResponse:
|
||||
let adata =
|
||||
|
@ -435,7 +435,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponse(adata)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/getAggregatedAttestation
|
||||
router.api(MethodGet, "/api/eth/v1/validator/aggregate_attestation") do (
|
||||
router.api(MethodGet, "/eth/v1/validator/aggregate_attestation") do (
|
||||
attestation_data_root: Option[Eth2Digest],
|
||||
slot: Option[Slot]) -> RestApiResponse:
|
||||
let attestation =
|
||||
|
@ -467,7 +467,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonResponse(attestation)
|
||||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/publishAggregateAndProofs
|
||||
router.api(MethodPost, "/api/eth/v1/validator/aggregate_and_proofs") do (
|
||||
router.api(MethodPost, "/eth/v1/validator/aggregate_and_proofs") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let proofs =
|
||||
block:
|
||||
|
@ -502,7 +502,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/prepareBeaconCommitteeSubnet
|
||||
router.api(MethodPost,
|
||||
"/api/eth/v1/validator/beacon_committee_subscriptions") do (
|
||||
"/eth/v1/validator/beacon_committee_subscriptions") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
# TODO (cheatfate): This call could not be finished because more complex
|
||||
# peer manager implementation needed.
|
||||
|
@ -575,7 +575,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/prepareSyncCommitteeSubnets
|
||||
router.api(MethodPost,
|
||||
"/api/eth/v1/validator/sync_committee_subscriptions") do (
|
||||
"/eth/v1/validator/sync_committee_subscriptions") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let subscriptions =
|
||||
block:
|
||||
|
@ -610,7 +610,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/produceSyncCommitteeContribution
|
||||
router.api(MethodGet,
|
||||
"/api/eth/v1/validator/sync_committee_contribution") do (
|
||||
"/eth/v1/validator/sync_committee_contribution") do (
|
||||
slot: Option[Slot], subcommittee_index: Option[uint64],
|
||||
beacon_block_root: Option[Eth2Digest]) -> RestApiResponse:
|
||||
# We doing this check to avoid any confusion in future.
|
||||
|
@ -670,7 +670,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
# https://ethereum.github.io/beacon-APIs/#/Validator/publishContributionAndProofs
|
||||
router.api(MethodPost,
|
||||
"/api/eth/v1/validator/contribution_and_proofs") do (
|
||||
"/eth/v1/validator/contribution_and_proofs") do (
|
||||
contentBody: Option[ContentBody]) -> RestApiResponse:
|
||||
let proofs =
|
||||
block:
|
||||
|
@ -718,63 +718,65 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
ContributionAndProofValidationSuccess
|
||||
)
|
||||
|
||||
# Legacy URLS - Nimbus <= 1.5.5 used to expose the REST API with an additional
|
||||
# `/api` path component
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/validator/duties/attester/{epoch}",
|
||||
"/api/eth/v1/validator/duties/attester/{epoch}"
|
||||
"/api/eth/v1/validator/duties/attester/{epoch}",
|
||||
"/eth/v1/validator/duties/attester/{epoch}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/validator/duties/proposer/{epoch}",
|
||||
"/api/eth/v1/validator/duties/proposer/{epoch}"
|
||||
"/api/eth/v1/validator/duties/proposer/{epoch}",
|
||||
"/eth/v1/validator/duties/proposer/{epoch}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/validator/duties/sync/{epoch}",
|
||||
"/api/eth/v1/validator/duties/sync/{epoch}"
|
||||
"/api/eth/v1/validator/duties/sync/{epoch}",
|
||||
"/eth/v1/validator/duties/sync/{epoch}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/validator/blocks/{slot}",
|
||||
"/api/eth/v1/validator/blocks/{slot}"
|
||||
"/api/eth/v1/validator/blocks/{slot}",
|
||||
"/eth/v1/validator/blocks/{slot}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v2/validator/blocks/{slot}",
|
||||
"/api/eth/v2/validator/blocks/{slot}"
|
||||
"/api/eth/v2/validator/blocks/{slot}",
|
||||
"/eth/v2/validator/blocks/{slot}"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/validator/attestation_data",
|
||||
"/api/eth/v1/validator/attestation_data"
|
||||
"/api/eth/v1/validator/attestation_data",
|
||||
"/eth/v1/validator/attestation_data"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/validator/aggregate_attestation",
|
||||
"/api/eth/v1/validator/aggregate_attestation"
|
||||
"/api/eth/v1/validator/aggregate_attestation",
|
||||
"/eth/v1/validator/aggregate_attestation"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/validator/aggregate_and_proofs",
|
||||
"/api/eth/v1/validator/aggregate_and_proofs"
|
||||
"/api/eth/v1/validator/aggregate_and_proofs",
|
||||
"/eth/v1/validator/aggregate_and_proofs"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/validator/beacon_committee_subscriptions",
|
||||
"/api/eth/v1/validator/beacon_committee_subscriptions"
|
||||
"/api/eth/v1/validator/beacon_committee_subscriptions",
|
||||
"/eth/v1/validator/beacon_committee_subscriptions"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/validator/sync_committee_subscriptions",
|
||||
"/api/eth/v1/validator/sync_committee_subscriptions"
|
||||
"/api/eth/v1/validator/sync_committee_subscriptions",
|
||||
"/eth/v1/validator/sync_committee_subscriptions"
|
||||
)
|
||||
router.redirect(
|
||||
MethodGet,
|
||||
"/eth/v1/validator/sync_committee_contribution",
|
||||
"/api/eth/v1/validator/sync_committee_contribution"
|
||||
"/api/eth/v1/validator/sync_committee_contribution",
|
||||
"/eth/v1/validator/sync_committee_contribution"
|
||||
)
|
||||
router.redirect(
|
||||
MethodPost,
|
||||
"/eth/v1/validator/contribution_and_proofs",
|
||||
"/api/eth/v1/validator/contribution_and_proofs"
|
||||
"/api/eth/v1/validator/contribution_and_proofs",
|
||||
"/eth/v1/validator/contribution_and_proofs"
|
||||
)
|
||||
|
|
|
@ -25,13 +25,12 @@
|
|||
{.push raises: [Defect].}
|
||||
|
||||
import
|
||||
std/[macros, typetraits, sets, hashes],
|
||||
std/[typetraits, sets, hashes],
|
||||
chronicles,
|
||||
stew/[assign2, bitops2],
|
||||
json_serialization/types as jsonTypes
|
||||
"."/[base, phase0]
|
||||
|
||||
import ./base, ./phase0
|
||||
export base
|
||||
export base, sets
|
||||
|
||||
from ssz_serialization/merkleization import GeneralizedIndex
|
||||
export merkleization.GeneralizedIndex
|
||||
|
@ -232,10 +231,7 @@ type
|
|||
HashList[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT]
|
||||
|
||||
# Finality
|
||||
justification_bits*: uint8 ##\
|
||||
## Bit set for every recent justified epoch
|
||||
## Model a Bitvector[4] as a one-byte uint, which should remain consistent
|
||||
## with ssz/hashing.
|
||||
justification_bits*: JustificationBits
|
||||
|
||||
previous_justified_checkpoint*: Checkpoint ##\
|
||||
## Previous epoch snapshot
|
||||
|
@ -491,7 +487,7 @@ type
|
|||
current_epoch_participation*:
|
||||
List[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT]
|
||||
|
||||
justification_bits*: uint8
|
||||
justification_bits*: JustificationBits
|
||||
previous_justified_checkpoint*: Checkpoint
|
||||
current_justified_checkpoint*: Checkpoint
|
||||
finalized_checkpoint*: Checkpoint
|
||||
|
@ -536,21 +532,6 @@ template validateSyncCommitteeIndexOr*(
|
|||
|
||||
template asUInt8*(x: SyncSubcommitteeIndex): uint8 = uint8(x)
|
||||
|
||||
Json.useCustomSerialization(BeaconState.justification_bits):
|
||||
read:
|
||||
let s = reader.readValue(string)
|
||||
|
||||
if s.len != 4:
|
||||
raiseUnexpectedValue(reader, "A string with 4 characters expected")
|
||||
|
||||
try:
|
||||
s.parseHexInt.uint8
|
||||
except ValueError:
|
||||
raiseUnexpectedValue(reader, "The `justification_bits` value must be a hex string")
|
||||
|
||||
write:
|
||||
writer.writeValue "0x" & value.toHex
|
||||
|
||||
func shortLog*(v: SomeBeaconBlock): auto =
|
||||
(
|
||||
slot: shortLog(v.slot),
|
||||
|
|
|
@ -163,6 +163,10 @@ type
|
|||
|
||||
Gwei* = uint64
|
||||
|
||||
# BitVector[4] in the spec, ie 4 bits which end up encoded as a byte for
|
||||
# SSZ / hashing purposes
|
||||
JustificationBits* = distinct uint8
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.8/specs/phase0/beacon-chain.md#proposerslashing
|
||||
ProposerSlashing* = object
|
||||
signed_header_1*: SignedBeaconBlockHeader
|
||||
|
@ -622,6 +626,21 @@ proc readValue*(reader: var JsonReader, value: var ForkDigest)
|
|||
except ValueError:
|
||||
raiseUnexpectedValue(reader, "Hex string of 4 bytes expected")
|
||||
|
||||
proc `$`*(x: JustificationBits): string =
|
||||
"0x" & toHex(uint8(x))
|
||||
|
||||
proc readValue*(reader: var JsonReader, value: var JustificationBits)
|
||||
{.raises: [IOError, SerializationError, Defect].} =
|
||||
let hex = reader.readValue(string)
|
||||
try:
|
||||
value = JustificationBits(hexToByteArray(hex, 1)[0])
|
||||
except ValueError:
|
||||
raiseUnexpectedValue(reader, "Hex string of 1 byte expected")
|
||||
|
||||
proc writeValue*(writer: var JsonWriter, value: JustificationBits)
|
||||
{.raises: [IOError, Defect].} =
|
||||
writer.writeValue $value
|
||||
|
||||
# In general, ValidatorIndex is assumed to be convertible to/from an int. This
|
||||
# should be valid for a long time, because
|
||||
# https://github.com/ethereum/annotated-spec/blob/master/phase0/beacon-chain.md#configuration
|
||||
|
@ -675,6 +694,9 @@ template `$`*(x: CommitteeIndex): auto =
|
|||
template `==`*(x, y: SubnetId): bool =
|
||||
distinctBase(x) == distinctBase(y)
|
||||
|
||||
template `==`*(x, y: JustificationBits): bool =
|
||||
distinctBase(x) == distinctBase(y)
|
||||
|
||||
template `$`*(x: SubnetId): string =
|
||||
$ distinctBase(x)
|
||||
|
||||
|
|
|
@ -13,14 +13,13 @@
|
|||
{.push raises: [Defect].}
|
||||
|
||||
import
|
||||
std/macros,
|
||||
stew/assign2,
|
||||
stew/[assign2, byteutils],
|
||||
json_serialization,
|
||||
json_serialization/types as jsonTypes,
|
||||
ssz_serialization/types as sszTypes,
|
||||
../digest,
|
||||
./phase0, ./altair,
|
||||
nimcrypto/utils
|
||||
"."/[base, phase0, altair]
|
||||
|
||||
export json_serialization, base
|
||||
|
||||
type
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.8/specs/bellatrix/beacon-chain.md#custom-types
|
||||
|
@ -123,10 +122,7 @@ type
|
|||
HashList[ParticipationFlags, Limit VALIDATOR_REGISTRY_LIMIT]
|
||||
|
||||
# Finality
|
||||
justification_bits*: uint8 ##\
|
||||
## Bit set for every recent justified epoch
|
||||
## Model a Bitvector[4] as a one-byte uint, which should remain consistent
|
||||
## with ssz/hashing.
|
||||
justification_bits*: JustificationBits
|
||||
|
||||
previous_justified_checkpoint*: Checkpoint ##\
|
||||
## Previous epoch snapshot
|
||||
|
@ -345,11 +341,11 @@ type
|
|||
func encodeQuantityHex*(x: auto): string =
|
||||
"0x" & x.toHex
|
||||
|
||||
proc fromHex*(T: typedesc[BloomLogs], s: string): T =
|
||||
hexToBytes(s, result.data)
|
||||
proc fromHex*(T: typedesc[BloomLogs], s: string): T {.raises: [Defect, ValueError].} =
|
||||
hexToByteArray(s, result.data)
|
||||
|
||||
proc fromHex*(T: typedesc[ExecutionAddress], s: string): T =
|
||||
hexToBytes(s, result.data)
|
||||
proc fromHex*(T: typedesc[ExecutionAddress], s: string): T {.raises: [Defect, ValueError].} =
|
||||
hexToByteArray(s, result.data)
|
||||
|
||||
proc writeValue*(w: var JsonWriter, a: ExecutionAddress) {.raises: [Defect, IOError, SerializationError].} =
|
||||
w.writeValue $a
|
||||
|
|
|
@ -24,13 +24,12 @@
|
|||
|
||||
{.push raises: [Defect].}
|
||||
|
||||
import ./base
|
||||
export base
|
||||
|
||||
import
|
||||
std/[macros, json, strutils, tables],
|
||||
stew/[assign2, byteutils], chronicles,
|
||||
json_serialization/types as jsonTypes
|
||||
stew/[assign2],
|
||||
chronicles,
|
||||
./base
|
||||
|
||||
export base
|
||||
|
||||
type
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.8/specs/phase0/beacon-chain.md#beaconstate
|
||||
|
@ -75,10 +74,7 @@ type
|
|||
HashList[PendingAttestation, Limit(MAX_ATTESTATIONS * SLOTS_PER_EPOCH)]
|
||||
|
||||
# Finality
|
||||
justification_bits*: uint8 ##\
|
||||
## Bit set for every recent justified epoch
|
||||
## Model a Bitvector[4] as a one-byte uint, which should remain consistent
|
||||
## with ssz/hashing.
|
||||
justification_bits*: JustificationBits
|
||||
|
||||
previous_justified_checkpoint*: Checkpoint ##\
|
||||
## Previous epoch snapshot
|
||||
|
@ -253,21 +249,6 @@ func clear*(info: var EpochInfo) =
|
|||
info.validators.setLen(0)
|
||||
info.balances = TotalBalances()
|
||||
|
||||
Json.useCustomSerialization(BeaconState.justification_bits):
|
||||
read:
|
||||
let s = reader.readValue(string)
|
||||
|
||||
if s.len != 4:
|
||||
raiseUnexpectedValue(reader, "A string with 4 characters expected")
|
||||
|
||||
try:
|
||||
s.parseHexInt.uint8
|
||||
except ValueError:
|
||||
raiseUnexpectedValue(reader, "The `justification_bits` value must be a hex string")
|
||||
|
||||
write:
|
||||
writer.writeValue "0x" & value.toHex
|
||||
|
||||
func shortLog*(v: SomeBeaconBlock): auto =
|
||||
(
|
||||
slot: shortLog(v.slot),
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
import
|
||||
# Standard library
|
||||
std/[tables, typetraits],
|
||||
std/[typetraits],
|
||||
|
||||
# Nimble packages
|
||||
stew/byteutils,
|
||||
|
@ -75,6 +75,10 @@ proc fromJson*(n: JsonNode, argName: string, result: var Version) {.raises: [Def
|
|||
n.kind.expect(JString, argName)
|
||||
hexToByteArray(n.getStr(), array[4, byte](result))
|
||||
|
||||
proc fromJson*(n: JsonNode, argName: string, result: var JustificationBits) {.raises: [Defect, ValueError].} =
|
||||
n.kind.expect(JString, argName)
|
||||
result = JustificationBits(hexToByteArray(n.getStr(), 1)[0])
|
||||
|
||||
proc `%`*(value: Version): JsonNode =
|
||||
newJString(toJsonHex(distinctBase(value)))
|
||||
|
||||
|
@ -141,3 +145,6 @@ proc `%`*(value: BitSeq): JsonNode =
|
|||
proc fromJson*(n: JsonNode, argName: string, result: var BitSeq) {.raises: [Defect, ValueError].} =
|
||||
n.kind.expect(JString, argName)
|
||||
result = BitSeq(hexToSeqByte(n.getStr()))
|
||||
|
||||
proc `%`*(value: JustificationBits): JsonNode =
|
||||
newJString(toJsonHex([distinctBase(value)]))
|
||||
|
|
|
@ -89,11 +89,7 @@ type
|
|||
|
||||
SszDecodeTypes* =
|
||||
GetPhase0StateSszResponse |
|
||||
GetAltairStateSszResponse |
|
||||
GetPhase0BlockSszResponse |
|
||||
GetAltairBlockSszResponse |
|
||||
GetBlockV2Header |
|
||||
GetStateV2Header
|
||||
GetPhase0BlockSszResponse
|
||||
|
||||
{.push raises: [Defect].}
|
||||
|
||||
|
@ -346,7 +342,33 @@ proc readValue*(reader: var JsonReader[RestJson], value: var uint64) {.
|
|||
if res.isOk():
|
||||
value = res.get()
|
||||
else:
|
||||
reader.raiseUnexpectedValue($res.error())
|
||||
reader.raiseUnexpectedValue($res.error() & ": " & svalue)
|
||||
|
||||
proc writeValue*(w: var JsonWriter[RestJson], value: uint8) {.
|
||||
raises: [IOError, Defect].} =
|
||||
writeValue(w, Base10.toString(value))
|
||||
|
||||
proc readValue*(reader: var JsonReader[RestJson], value: var uint8) {.
|
||||
raises: [IOError, SerializationError, Defect].} =
|
||||
let svalue = reader.readValue(string)
|
||||
let res = Base10.decode(uint8, svalue)
|
||||
if res.isOk():
|
||||
value = res.get()
|
||||
else:
|
||||
reader.raiseUnexpectedValue($res.error() & ": " & svalue)
|
||||
|
||||
proc writeValue*(w: var JsonWriter[RestJson], value: JustificationBits) {.
|
||||
raises: [IOError, Defect].} =
|
||||
w.writeValue hexOriginal([uint8(value)])
|
||||
|
||||
proc readValue*(reader: var JsonReader[RestJson], value: var JustificationBits) {.
|
||||
raises: [IOError, SerializationError, Defect].} =
|
||||
let hex = reader.readValue(string)
|
||||
try:
|
||||
value = JustificationBits(hexToByteArray(hex, 1)[0])
|
||||
except ValueError:
|
||||
raiseUnexpectedValue(reader,
|
||||
"The `justification_bits` value must be a hex string")
|
||||
|
||||
## UInt256
|
||||
proc writeValue*(w: var JsonWriter[RestJson], value: UInt256) {.
|
||||
|
@ -362,23 +384,6 @@ proc readValue*(reader: var JsonReader[RestJson], value: var UInt256) {.
|
|||
raiseUnexpectedValue(reader,
|
||||
"UInt256 value should be a valid decimal string")
|
||||
|
||||
## byte
|
||||
proc writeValue*(w: var JsonWriter[RestJson], value: byte) {.
|
||||
raises: [IOError, Defect].} =
|
||||
var data: array[1, byte]
|
||||
data[0] = value
|
||||
writeValue(w, hexOriginal(data))
|
||||
|
||||
proc readValue*(reader: var JsonReader[RestJson], value: var byte) {.
|
||||
raises: [IOError, SerializationError, Defect].} =
|
||||
var data: array[1, byte]
|
||||
try:
|
||||
hexToByteArray(reader.readValue(string), data)
|
||||
value = data[0]
|
||||
except ValueError:
|
||||
raiseUnexpectedValue(reader,
|
||||
"byte value should be a valid hex string")
|
||||
|
||||
## DomainType
|
||||
proc writeValue*(w: var JsonWriter[RestJson], value: DomainType) {.
|
||||
raises: [IOError, Defect].} =
|
||||
|
@ -898,7 +903,7 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
assign(value.field, tmp[].field)
|
||||
else:
|
||||
value = tmp[] # slow, but rare (hopefully)
|
||||
value.field.root = hash_tree_root(value.field.data)
|
||||
value.field.root = hash_tree_root(value.field.data)
|
||||
|
||||
case version.get():
|
||||
of BeaconStateFork.Phase0:
|
||||
|
@ -1328,19 +1333,6 @@ proc decodeBody*[T](t: typedesc[T],
|
|||
return err("Unexpected deserialization error")
|
||||
ok(data)
|
||||
|
||||
RestJson.useCustomSerialization(phase0.BeaconState.justification_bits):
|
||||
read:
|
||||
let s = reader.readValue(string)
|
||||
if s.len != 4:
|
||||
raiseUnexpectedValue(reader, "A string with 4 characters expected")
|
||||
try:
|
||||
hexToByteArray(s, 1)[0]
|
||||
except ValueError:
|
||||
raiseUnexpectedValue(reader,
|
||||
"The `justification_bits` value must be a hex string")
|
||||
write:
|
||||
writer.writeValue "0x" & toHex([value])
|
||||
|
||||
proc encodeBytes*[T: EncodeTypes](value: T,
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
case contentType
|
||||
|
|
|
@ -36,7 +36,7 @@ proc getStateFork*(state_id: StateIdent): RestResponse[GetStateForkResponse] {.
|
|||
|
||||
proc getStateFinalityCheckpoints*(state_id: StateIdent
|
||||
): RestResponse[GetStateFinalityCheckpointsResponse] {.
|
||||
rest, endpoint: "/api/eth/v1/beacon/states/{state_id}/finality_checkpoints",
|
||||
rest, endpoint: "/eth/v1/beacon/states/{state_id}/finality_checkpoints",
|
||||
meth: MethodGet.}
|
||||
## https://ethereum.github.io/beacon-APIs/#/Beacon/getStateFinalityCheckpoints
|
||||
|
||||
|
@ -75,12 +75,12 @@ proc getEpochSyncCommittees*(state_id: StateIdent, epoch: Option[Epoch],
|
|||
|
||||
proc getBlockHeaders*(slot: Option[Slot], parent_root: Option[Eth2Digest]
|
||||
): RestResponse[GetBlockHeadersResponse] {.
|
||||
rest, endpoint: "/api/eth/v1/beacon/headers",
|
||||
rest, endpoint: "/eth/v1/beacon/headers",
|
||||
meth: MethodGet.}
|
||||
## https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeaders
|
||||
|
||||
proc getBlockHeader*(block_id: BlockIdent): RestResponse[GetBlockHeaderResponse] {.
|
||||
rest, endpoint: "/api/eth/v1/beacon/headers/{block_id}",
|
||||
rest, endpoint: "/eth/v1/beacon/headers/{block_id}",
|
||||
meth: MethodGet.}
|
||||
## https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockHeader
|
||||
|
||||
|
@ -95,7 +95,7 @@ proc publishBlock*(body: altair.SignedBeaconBlock): RestPlainResponse {.
|
|||
## https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlock
|
||||
|
||||
proc getBlockPlain*(block_id: BlockIdent): RestPlainResponse {.
|
||||
rest, endpoint: "/api/eth/v1/beacon/blocks/{block_id}",
|
||||
rest, endpoint: "/eth/v1/beacon/blocks/{block_id}",
|
||||
accept: "application/octet-stream,application-json;q=0.9",
|
||||
meth: MethodGet.}
|
||||
## https://ethereum.github.io/beacon-APIs/#/Beacon/getBlock
|
||||
|
@ -156,21 +156,24 @@ proc getBlock*(client: RestClientRef, block_id: BlockIdent,
|
|||
return data
|
||||
|
||||
proc getBlockV2Plain*(block_id: BlockIdent): RestPlainResponse {.
|
||||
rest, endpoint: "/api/eth/v2/beacon/blocks/{block_id}",
|
||||
rest, endpoint: "/eth/v2/beacon/blocks/{block_id}",
|
||||
accept: "application/octet-stream,application-json;q=0.9",
|
||||
meth: MethodGet.}
|
||||
## https://ethereum.github.io/beacon-APIs/#/Beacon/getBlockV2
|
||||
|
||||
proc getBlockV2*(client: RestClientRef, block_id: BlockIdent,
|
||||
forks: array[2, Fork],
|
||||
restAccept = ""): Future[ForkedSignedBeaconBlock] {.
|
||||
cfg: RuntimeConfig,
|
||||
restAccept = ""): Future[Option[ForkedSignedBeaconBlock]] {.
|
||||
async.} =
|
||||
# Return the asked-for block, or None in case 404 is returned from the server.
|
||||
# Raises on other errors
|
||||
let resp =
|
||||
if len(restAccept) > 0:
|
||||
await client.getBlockV2Plain(block_id, restAcceptType = restAccept)
|
||||
else:
|
||||
await client.getBlockV2Plain(block_id)
|
||||
let data =
|
||||
|
||||
return
|
||||
case resp.status
|
||||
of 200:
|
||||
case resp.contentType
|
||||
|
@ -182,35 +185,18 @@ proc getBlockV2*(client: RestClientRef, block_id: BlockIdent,
|
|||
if res.isErr():
|
||||
raise newException(RestError, $res.error())
|
||||
res.get()
|
||||
blck
|
||||
some blck
|
||||
of "application/octet-stream":
|
||||
let header =
|
||||
block:
|
||||
let res = decodeBytes(GetBlockV2Header, resp.data, resp.contentType)
|
||||
if res.isErr():
|
||||
raise newException(RestError, $res.error())
|
||||
res.get()
|
||||
if header.slot.epoch() < forks[1].epoch:
|
||||
let blck =
|
||||
block:
|
||||
let res = decodeBytes(GetPhase0BlockSszResponse, resp.data,
|
||||
resp.contentType)
|
||||
if res.isErr():
|
||||
raise newException(RestError, $res.error())
|
||||
res.get()
|
||||
ForkedSignedBeaconBlock.init(blck)
|
||||
else:
|
||||
let blck =
|
||||
block:
|
||||
let res = decodeBytes(GetAltairBlockSszResponse, resp.data,
|
||||
resp.contentType)
|
||||
if res.isErr():
|
||||
raise newException(RestError, $res.error())
|
||||
res.get()
|
||||
ForkedSignedBeaconBlock.init(blck)
|
||||
try:
|
||||
some readSszForkedSignedBeaconBlock(cfg, resp.data)
|
||||
except CatchableError as exc:
|
||||
raise newException(RestError, exc.msg)
|
||||
else:
|
||||
raise newException(RestError, "Unsupported content-type")
|
||||
of 400, 404, 500:
|
||||
of 404:
|
||||
none(ForkedSignedBeaconBlock)
|
||||
|
||||
of 400, 500:
|
||||
let error =
|
||||
block:
|
||||
let res = decodeBytes(RestGenericError, resp.data, resp.contentType)
|
||||
|
@ -224,7 +210,6 @@ proc getBlockV2*(client: RestClientRef, block_id: BlockIdent,
|
|||
else:
|
||||
let msg = "Unknown response status error (" & $resp.status & ")"
|
||||
raise newException(RestError, msg)
|
||||
return data
|
||||
|
||||
proc getBlockRoot*(block_id: BlockIdent): RestResponse[GetBlockRootResponse] {.
|
||||
rest, endpoint: "/eth/v1/beacon/blocks/{block_id}/root",
|
||||
|
|
|
@ -78,8 +78,10 @@ proc getStateV2Plain*(state_id: StateIdent): RestPlainResponse {.
|
|||
## https://ethereum.github.io/beacon-APIs/#/Debug/getStateV2
|
||||
|
||||
proc getStateV2*(client: RestClientRef, state_id: StateIdent,
|
||||
forks: array[2, Fork],
|
||||
restAccept = ""): Future[ForkedHashedBeaconState] {.async.} =
|
||||
cfg: RuntimeConfig,
|
||||
restAccept = ""): Future[ref ForkedHashedBeaconState] {.async.} =
|
||||
# nil is returned if the state is not found due to a 404 - `ref` is needed
|
||||
# to manage stack usage
|
||||
let resp =
|
||||
if len(restAccept) > 0:
|
||||
await client.getStateV2Plain(state_id, restAcceptType = restAccept)
|
||||
|
@ -92,42 +94,22 @@ proc getStateV2*(client: RestClientRef, state_id: StateIdent,
|
|||
of "application/json":
|
||||
let state =
|
||||
block:
|
||||
let res = decodeBytes(GetStateV2Response, resp.data,
|
||||
resp.contentType)
|
||||
if res.isErr():
|
||||
raise newException(RestError, $res.error())
|
||||
res.get()
|
||||
let res = newClone(decodeBytes(GetStateV2Response, resp.data,
|
||||
resp.contentType))
|
||||
if res[].isErr():
|
||||
raise newException(RestError, $res[].error())
|
||||
newClone(res[].get())
|
||||
state
|
||||
of "application/octet-stream":
|
||||
let header =
|
||||
block:
|
||||
let res = decodeBytes(GetStateV2Header, resp.data, resp.contentType)
|
||||
if res.isErr():
|
||||
raise newException(RestError, $res.error())
|
||||
res.get()
|
||||
if header.slot.epoch() < forks[1].epoch:
|
||||
let state = newClone(
|
||||
block:
|
||||
let res = newClone(decodeBytes(
|
||||
GetPhase0StateSszResponse, resp.data, resp.contentType))
|
||||
if res[].isErr():
|
||||
raise newException(RestError, $res[].error())
|
||||
res[].get())
|
||||
ForkedHashedBeaconState.init(phase0.HashedBeaconState(
|
||||
data: state[], root: hash_tree_root(state[])))
|
||||
else:
|
||||
let state = newClone(
|
||||
block:
|
||||
let res = newClone(decodeBytes(
|
||||
GetAltairStateSszResponse, resp.data, resp.contentType))
|
||||
if res[].isErr():
|
||||
raise newException(RestError, $res[].error())
|
||||
res[].get())
|
||||
ForkedHashedBeaconState.init(altair.HashedBeaconState(
|
||||
data: state[], root: hash_tree_root(state[])))
|
||||
try:
|
||||
newClone(readSszForkedHashedBeaconState(cfg, resp.data))
|
||||
except CatchableError as exc:
|
||||
raise newException(RestError, exc.msg)
|
||||
else:
|
||||
raise newException(RestError, "Unsupported content-type")
|
||||
of 400, 404, 500:
|
||||
of 404:
|
||||
nil
|
||||
of 400, 500:
|
||||
let error =
|
||||
block:
|
||||
let res = decodeBytes(RestGenericError, resp.data, resp.contentType)
|
||||
|
|
|
@ -408,11 +408,6 @@ type
|
|||
signature*: ValidatorSig
|
||||
slot*: Slot
|
||||
|
||||
ForkedBeaconStateHeader* = object
|
||||
genesis_time*: uint64
|
||||
genesis_validators_root*: Eth2Digest
|
||||
slot*: Slot
|
||||
|
||||
Web3SignerKeysResponse* = object
|
||||
keys*: seq[ValidatorPubKey]
|
||||
|
||||
|
@ -495,9 +490,7 @@ type
|
|||
GetBlockResponse* = DataEnclosedObject[phase0.SignedBeaconBlock]
|
||||
GetStateResponse* = DataEnclosedObject[phase0.BeaconState]
|
||||
GetBlockV2Response* = ForkedSignedBeaconBlock
|
||||
GetBlockV2Header* = ForkedSignedBlockHeader
|
||||
GetStateV2Response* = ForkedHashedBeaconState
|
||||
GetStateV2Header* = ForkedBeaconStateHeader
|
||||
GetStateV2Response* = ref ForkedHashedBeaconState
|
||||
GetPhase0StateSszResponse* = phase0.BeaconState
|
||||
GetAltairStateSszResponse* = altair.BeaconState
|
||||
GetPhase0BlockSszResponse* = phase0.SignedBeaconBlock
|
||||
|
|
|
@ -446,9 +446,9 @@ type
|
|||
signature*: ValidatorSig
|
||||
slot: Slot # start of BeaconBlock
|
||||
|
||||
func readSszForkedTrustedSignedBeaconBlock*(
|
||||
func readSszForkedSignedBeaconBlock*(
|
||||
cfg: RuntimeConfig, data: openArray[byte]):
|
||||
ForkedTrustedSignedBeaconBlock {.raises: [Defect, SszError].} =
|
||||
ForkedSignedBeaconBlock {.raises: [Defect, SszError].} =
|
||||
## Helper to read a header from bytes when it's not certain what kind of block
|
||||
## it is
|
||||
if data.len() < sizeof(ForkedBeaconBlockHeader):
|
||||
|
@ -459,7 +459,7 @@ func readSszForkedTrustedSignedBeaconBlock*(
|
|||
|
||||
# careful - `result` is used, RVO didn't seem to work without
|
||||
# TODO move time helpers somewhere to avoid circular imports
|
||||
result = ForkedTrustedSignedBeaconBlock(
|
||||
result = ForkedSignedBeaconBlock(
|
||||
kind: cfg.blockForkAtEpoch(Epoch(header.slot div SLOTS_PER_EPOCH)))
|
||||
|
||||
withBlck(result):
|
||||
|
|
|
@ -11,10 +11,9 @@
|
|||
import
|
||||
std/[typetraits],
|
||||
ssz_serialization/codec,
|
||||
../spec/datatypes/[phase0, altair],
|
||||
./eth2_merkleization
|
||||
./datatypes/base
|
||||
|
||||
export codec, phase0, altair, typetraits, eth2_merkleization
|
||||
export codec, base, typetraits
|
||||
|
||||
# Coding and decoding of SSZ to spec-specific types
|
||||
|
||||
|
@ -22,6 +21,7 @@ template toSszType*(v: Slot|Epoch): auto = uint64(v)
|
|||
template toSszType*(v: BlsCurveType): auto = toRaw(v)
|
||||
template toSszType*(v: ForkDigest|GraffitiBytes): auto = distinctBase(v)
|
||||
template toSszType*(v: Version): auto = distinctBase(v)
|
||||
template toSszType*(v: JustificationBits): auto = distinctBase(v)
|
||||
|
||||
func fromSszBytes*(T: type GraffitiBytes, data: openArray[byte]): T {.raisesssz.} =
|
||||
if data.len != sizeof(result):
|
||||
|
@ -43,3 +43,8 @@ func fromSszBytes*(T: type Version, bytes: openArray[byte]): T {.raisesssz.} =
|
|||
if bytes.len != sizeof(result):
|
||||
raiseIncorrectSize T
|
||||
copyMem(result.addr, unsafeAddr bytes[0], sizeof(result))
|
||||
|
||||
func fromSszBytes*(T: type JustificationBits, bytes: openArray[byte]): T {.raisesssz.} =
|
||||
if bytes.len != sizeof(result):
|
||||
raiseIncorrectSize T
|
||||
copyMem(result.addr, unsafeAddr bytes[0], sizeof(result))
|
||||
|
|
|
@ -259,8 +259,9 @@ proc process_justification_and_finalization*(state: var phase0.BeaconState,
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.1.8/specs/phase0/beacon-chain.md#misc
|
||||
const JUSTIFICATION_BITS_LENGTH = 4
|
||||
|
||||
state.justification_bits = (state.justification_bits shl 1) and
|
||||
cast[uint8]((2^JUSTIFICATION_BITS_LENGTH) - 1)
|
||||
state.justification_bits = JustificationBits(
|
||||
(uint8(state.justification_bits) shl 1) and
|
||||
uint8((2^JUSTIFICATION_BITS_LENGTH) - 1))
|
||||
|
||||
let total_active_balance = balances.current_epoch
|
||||
if balances.previous_epoch_target_attesters * 3 >=
|
||||
|
@ -268,7 +269,7 @@ proc process_justification_and_finalization*(state: var phase0.BeaconState,
|
|||
state.current_justified_checkpoint =
|
||||
Checkpoint(epoch: previous_epoch,
|
||||
root: get_block_root(state, previous_epoch))
|
||||
state.justification_bits.setBit 1
|
||||
uint8(state.justification_bits).setBit 1
|
||||
|
||||
trace "Justified with previous epoch",
|
||||
current_epoch = current_epoch,
|
||||
|
@ -282,14 +283,14 @@ proc process_justification_and_finalization*(state: var phase0.BeaconState,
|
|||
state.current_justified_checkpoint =
|
||||
Checkpoint(epoch: current_epoch,
|
||||
root: get_block_root(state, current_epoch))
|
||||
state.justification_bits.setBit 0
|
||||
uint8(state.justification_bits).setBit 0
|
||||
|
||||
trace "Justified with current epoch",
|
||||
current_epoch = current_epoch,
|
||||
checkpoint = shortLog(state.current_justified_checkpoint)
|
||||
|
||||
# Process finalizations
|
||||
let bitfield = state.justification_bits
|
||||
let bitfield = uint8(state.justification_bits)
|
||||
|
||||
## The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th
|
||||
## as source
|
||||
|
@ -355,14 +356,15 @@ proc weigh_justification_and_finalization(state: var (altair.BeaconState | merge
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.1.8/specs/phase0/beacon-chain.md#misc
|
||||
const JUSTIFICATION_BITS_LENGTH = 4
|
||||
|
||||
state.justification_bits = (state.justification_bits shl 1) and
|
||||
cast[uint8]((2^JUSTIFICATION_BITS_LENGTH) - 1)
|
||||
state.justification_bits = JustificationBits(
|
||||
(uint8(state.justification_bits) shl 1) and
|
||||
uint8((2^JUSTIFICATION_BITS_LENGTH) - 1))
|
||||
|
||||
if previous_epoch_target_balance * 3 >= total_active_balance * 2:
|
||||
state.current_justified_checkpoint =
|
||||
Checkpoint(epoch: previous_epoch,
|
||||
root: get_block_root(state, previous_epoch))
|
||||
state.justification_bits.setBit 1
|
||||
uint8(state.justification_bits).setBit 1
|
||||
|
||||
trace "Justified with previous epoch",
|
||||
current_epoch = current_epoch,
|
||||
|
@ -378,14 +380,14 @@ proc weigh_justification_and_finalization(state: var (altair.BeaconState | merge
|
|||
state.current_justified_checkpoint =
|
||||
Checkpoint(epoch: current_epoch,
|
||||
root: get_block_root(state, current_epoch))
|
||||
state.justification_bits.setBit 0
|
||||
uint8(state.justification_bits).setBit 0
|
||||
|
||||
trace "Justified with current epoch",
|
||||
current_epoch = current_epoch,
|
||||
checkpoint = shortLog(state.current_justified_checkpoint)
|
||||
|
||||
# Process finalizations
|
||||
let bitfield = state.justification_bits
|
||||
let bitfield = uint8(state.justification_bits)
|
||||
|
||||
## The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th
|
||||
## as source
|
||||
|
|
|
@ -359,10 +359,10 @@ proc cmdPutBlock(conf: DbConf, cfg: RuntimeConfig) =
|
|||
defer: db.close()
|
||||
|
||||
for file in conf.blckFile:
|
||||
let blck = readSszForkedTrustedSignedBeaconBlock(
|
||||
let blck = readSszForkedSignedBeaconBlock(
|
||||
cfg, readAllBytes(file).tryGet())
|
||||
|
||||
withBlck(blck):
|
||||
withBlck(blck.asTrusted()):
|
||||
db.putBlock(blck)
|
||||
if conf.setHead:
|
||||
db.putHeadBlock(blck.root)
|
||||
|
|
|
@ -44,11 +44,11 @@ proc finalizeOn234(
|
|||
# Mock the state
|
||||
getStateField(state, previous_justified_checkpoint) = c4
|
||||
getStateField(state, current_justified_checkpoint) = c3
|
||||
getStateField(state, justification_bits) = 0'u8 # Bitvector of length 4
|
||||
getStateField(state, justification_bits) = JustificationBits(0'u8) # Bitvector of length 4
|
||||
# mock 3rd and 4th latest epochs as justified
|
||||
# indices are pre-shift
|
||||
getStateField(state, justification_bits).setBit 1
|
||||
getStateField(state, justification_bits).setBit 2
|
||||
uint8(getStateField(state, justification_bits)).setBit 1
|
||||
uint8(getStateField(state, justification_bits)).setBit 2
|
||||
# mock the 2nd latest epoch as justifiable, with 4th as the source
|
||||
addMockAttestations(
|
||||
state.phase0Data.data,
|
||||
|
@ -90,10 +90,10 @@ proc finalizeOn23(state: var ForkedHashedBeaconState, epoch: Epoch, sufficient_s
|
|||
# Mock the state
|
||||
getStateField(state, previous_justified_checkpoint) = c3
|
||||
getStateField(state, current_justified_checkpoint) = c3
|
||||
getStateField(state, justification_bits) = 0'u8 # Bitvector of length 4
|
||||
getStateField(state, justification_bits) = JustificationBits(0'u8) # Bitvector of length 4
|
||||
# mock 3rd as justified
|
||||
# indices are pre-shift
|
||||
getStateField(state, justification_bits).setBit 1
|
||||
uint8(getStateField(state, justification_bits)).setBit 1
|
||||
# mock the 2nd latest epoch as justifiable, with 3rd as the source
|
||||
addMockAttestations(
|
||||
state.phase0Data.data,
|
||||
|
@ -135,10 +135,10 @@ proc finalizeOn123(state: var ForkedHashedBeaconState, epoch: Epoch, sufficient_
|
|||
# Mock the state
|
||||
getStateField(state, previous_justified_checkpoint) = c5
|
||||
getStateField(state, current_justified_checkpoint) = c3
|
||||
getStateField(state, justification_bits) = 0'u8 # Bitvector of length 4
|
||||
getStateField(state, justification_bits) = JustificationBits(0'u8) # Bitvector of length 4
|
||||
# mock 3rd as justified
|
||||
# indices are pre-shift
|
||||
getStateField(state, justification_bits).setBit 1
|
||||
uint8(getStateField(state, justification_bits)).setBit 1
|
||||
# mock the 2nd latest epoch as justifiable, with 5th as the source
|
||||
addMockAttestations(
|
||||
state.phase0Data.data,
|
||||
|
@ -188,10 +188,10 @@ proc finalizeOn12(state: var ForkedHashedBeaconState, epoch: Epoch, sufficient_s
|
|||
# Mock the state
|
||||
getStateField(state, previous_justified_checkpoint) = c2
|
||||
getStateField(state, current_justified_checkpoint) = c2
|
||||
getStateField(state, justification_bits) = 0'u8 # Bitvector of length 4
|
||||
getStateField(state, justification_bits) = JustificationBits(0'u8) # Bitvector of length 4
|
||||
# mock 3rd as justified
|
||||
# indices are pre-shift
|
||||
getStateField(state, justification_bits).setBit 0
|
||||
uint8(getStateField(state, justification_bits)).setBit 0
|
||||
# mock the 2nd latest epoch as justifiable, with 3rd as the source
|
||||
addMockAttestations(
|
||||
state.phase0Data.data,
|
||||
|
|
|
@ -27,9 +27,9 @@ template testTrustedSignedBeaconBlock(T: type, s: Slot) =
|
|||
|
||||
let
|
||||
bytes = SSZ.encode(blck[])
|
||||
forked = (ref ForkedTrustedSignedBeaconBlock)()
|
||||
forked = (ref ForkedSignedBeaconBlock)()
|
||||
|
||||
forked[] = readSszForkedTrustedSignedBeaconBlock(cfg, bytes)
|
||||
forked[] = readSszForkedSignedBeaconBlock(cfg, bytes)
|
||||
|
||||
check:
|
||||
forked.kind == T.toFork()
|
||||
|
@ -97,4 +97,4 @@ suite "Forked SSZ readers":
|
|||
let
|
||||
bytes = SSZ.encode(AttestationData())
|
||||
expect(SszError):
|
||||
discard newClone(readSszForkedTrustedSignedBeaconBlock(cfg, bytes))
|
||||
discard newClone(readSszForkedSignedBeaconBlock(cfg, bytes))
|
||||
|
|
Loading…
Reference in New Issue