diff --git a/beacon_chain/beacon_chain_db_immutable.nim b/beacon_chain/beacon_chain_db_immutable.nim index 6d5d5ade2..2e3ea753e 100644 --- a/beacon_chain/beacon_chain_db_immutable.nim +++ b/beacon_chain/beacon_chain_db_immutable.nim @@ -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 diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index 2e4a79e52..f80821a0c 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -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 diff --git a/beacon_chain/rpc/rest_beacon_api.nim b/beacon_chain/rpc/rest_beacon_api.nim index 3c9c042ef..3a4eeb5c6 100644 --- a/beacon_chain/rpc/rest_beacon_api.nim +++ b/beacon_chain/rpc/rest_beacon_api.nim @@ -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" ) diff --git a/beacon_chain/rpc/rest_config_api.nim b/beacon_chain/rpc/rest_config_api.nim index 12b22f556..019d986d0 100644 --- a/beacon_chain/rpc/rest_config_api.nim +++ b/beacon_chain/rpc/rest_config_api.nim @@ -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" ) diff --git a/beacon_chain/rpc/rest_debug_api.nim b/beacon_chain/rpc/rest_debug_api.nim index c2def2dfc..80f2efaa7 100644 --- a/beacon_chain/rpc/rest_debug_api.nim +++ b/beacon_chain/rpc/rest_debug_api.nim @@ -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" ) diff --git a/beacon_chain/rpc/rest_event_api.nim b/beacon_chain/rpc/rest_event_api.nim index 9304121b3..b52228392 100644 --- a/beacon_chain/rpc/rest_event_api.nim +++ b/beacon_chain/rpc/rest_event_api.nim @@ -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" ) diff --git a/beacon_chain/rpc/rest_nimbus_api.nim b/beacon_chain/rpc/rest_nimbus_api.nim index 4c92f9ed1..56786d87f 100644 --- a/beacon_chain/rpc/rest_nimbus_api.nim +++ b/beacon_chain/rpc/rest_nimbus_api.nim @@ -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") diff --git a/beacon_chain/rpc/rest_node_api.nim b/beacon_chain/rpc/rest_node_api.nim index 9e6170cb5..3088e7dcd 100644 --- a/beacon_chain/rpc/rest_node_api.nim +++ b/beacon_chain/rpc/rest_node_api.nim @@ -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" ) diff --git a/beacon_chain/rpc/rest_validator_api.nim b/beacon_chain/rpc/rest_validator_api.nim index 25894594b..671ebe73d 100644 --- a/beacon_chain/rpc/rest_validator_api.nim +++ b/beacon_chain/rpc/rest_validator_api.nim @@ -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" ) diff --git a/beacon_chain/spec/datatypes/altair.nim b/beacon_chain/spec/datatypes/altair.nim index dbdaea901..3b4e650b4 100644 --- a/beacon_chain/spec/datatypes/altair.nim +++ b/beacon_chain/spec/datatypes/altair.nim @@ -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), diff --git a/beacon_chain/spec/datatypes/base.nim b/beacon_chain/spec/datatypes/base.nim index d6ae28595..4a849653b 100644 --- a/beacon_chain/spec/datatypes/base.nim +++ b/beacon_chain/spec/datatypes/base.nim @@ -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) diff --git a/beacon_chain/spec/datatypes/merge.nim b/beacon_chain/spec/datatypes/merge.nim index 85a6f4c42..c06743f30 100644 --- a/beacon_chain/spec/datatypes/merge.nim +++ b/beacon_chain/spec/datatypes/merge.nim @@ -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 diff --git a/beacon_chain/spec/datatypes/phase0.nim b/beacon_chain/spec/datatypes/phase0.nim index 5987b503d..cf59ca0a6 100644 --- a/beacon_chain/spec/datatypes/phase0.nim +++ b/beacon_chain/spec/datatypes/phase0.nim @@ -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), diff --git a/beacon_chain/spec/eth2_apis/eth2_json_rpc_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_json_rpc_serialization.nim index 2cef99ccd..1c14cb284 100644 --- a/beacon_chain/spec/eth2_apis/eth2_json_rpc_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_json_rpc_serialization.nim @@ -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)])) diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim index e60fd50d6..e5823f080 100644 --- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim @@ -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 diff --git a/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim b/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim index d5383cbc0..70c489486 100644 --- a/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim +++ b/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim @@ -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", diff --git a/beacon_chain/spec/eth2_apis/rest_debug_calls.nim b/beacon_chain/spec/eth2_apis/rest_debug_calls.nim index b9ea4bafe..77eda368c 100644 --- a/beacon_chain/spec/eth2_apis/rest_debug_calls.nim +++ b/beacon_chain/spec/eth2_apis/rest_debug_calls.nim @@ -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) diff --git a/beacon_chain/spec/eth2_apis/rest_types.nim b/beacon_chain/spec/eth2_apis/rest_types.nim index 5d7b4cad0..2bc75311c 100644 --- a/beacon_chain/spec/eth2_apis/rest_types.nim +++ b/beacon_chain/spec/eth2_apis/rest_types.nim @@ -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 diff --git a/beacon_chain/spec/forks.nim b/beacon_chain/spec/forks.nim index a06efc494..45c70230f 100644 --- a/beacon_chain/spec/forks.nim +++ b/beacon_chain/spec/forks.nim @@ -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): diff --git a/beacon_chain/spec/ssz_codec.nim b/beacon_chain/spec/ssz_codec.nim index 223291032..d014dbe2d 100644 --- a/beacon_chain/spec/ssz_codec.nim +++ b/beacon_chain/spec/ssz_codec.nim @@ -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)) diff --git a/beacon_chain/spec/state_transition_epoch.nim b/beacon_chain/spec/state_transition_epoch.nim index 346eb4668..3d7c1ad2d 100644 --- a/beacon_chain/spec/state_transition_epoch.nim +++ b/beacon_chain/spec/state_transition_epoch.nim @@ -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 diff --git a/ncli/ncli_db.nim b/ncli/ncli_db.nim index dc249c0aa..5ae30749e 100644 --- a/ncli/ncli_db.nim +++ b/ncli/ncli_db.nim @@ -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) diff --git a/tests/spec_epoch_processing/test_process_justification_and_finalization.nim b/tests/spec_epoch_processing/test_process_justification_and_finalization.nim index 3923e8ed0..712ef1674 100644 --- a/tests/spec_epoch_processing/test_process_justification_and_finalization.nim +++ b/tests/spec_epoch_processing/test_process_justification_and_finalization.nim @@ -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, diff --git a/tests/test_forks.nim b/tests/test_forks.nim index a14d18877..c28b5c8d0 100644 --- a/tests/test_forks.nim +++ b/tests/test_forks.nim @@ -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))