From d35d408fa76ed02b0a288b5b1574594df1725422 Mon Sep 17 00:00:00 2001 From: tersec Date: Tue, 24 May 2022 07:23:48 +0000 Subject: [PATCH] remove deprecated JSON-RPC server (#3656) * remove deprecated JSON-RPC server * keep the command-line options around as no-ops, temporarily * service -> server; JSON-RPC is still used elsewhere --- beacon_chain/beacon_node.nim | 1 - beacon_chain/conf.nim | 11 +- beacon_chain/nimbus_beacon_node.nim | 23 +- beacon_chain/rpc/rpc_api.nim | 24 -- beacon_chain/rpc/rpc_beacon_api.nim | 513 ------------------------- beacon_chain/rpc/rpc_config_api.nim | 109 ------ beacon_chain/rpc/rpc_debug_api.nim | 35 -- beacon_chain/rpc/rpc_event_api.nim | 26 -- beacon_chain/rpc/rpc_nimbus_api.nim | 230 ----------- beacon_chain/rpc/rpc_node_api.nim | 256 ------------ beacon_chain/rpc/rpc_utils.nim | 111 ------ beacon_chain/rpc/rpc_validator_api.nim | 170 -------- beacon_chain/spec/network.nim | 3 - 13 files changed, 10 insertions(+), 1502 deletions(-) delete mode 100644 beacon_chain/rpc/rpc_api.nim delete mode 100644 beacon_chain/rpc/rpc_beacon_api.nim delete mode 100644 beacon_chain/rpc/rpc_config_api.nim delete mode 100644 beacon_chain/rpc/rpc_debug_api.nim delete mode 100644 beacon_chain/rpc/rpc_event_api.nim delete mode 100644 beacon_chain/rpc/rpc_nimbus_api.nim delete mode 100644 beacon_chain/rpc/rpc_node_api.nim delete mode 100644 beacon_chain/rpc/rpc_utils.nim delete mode 100644 beacon_chain/rpc/rpc_validator_api.nim diff --git a/beacon_chain/beacon_node.nim b/beacon_chain/beacon_node.nim index f1de5c2d1..fb65b7f83 100644 --- a/beacon_chain/beacon_node.nim +++ b/beacon_chain/beacon_node.nim @@ -53,7 +53,6 @@ type lightClientPool*: ref LightClientPool exitPool*: ref ExitPool eth1Monitor*: Eth1Monitor - rpcServer*: RpcServer restServer*: RestServerRef keymanagerServer*: RestServerRef keymanagerToken*: Option[string] diff --git a/beacon_chain/conf.nim b/beacon_chain/conf.nim index e6a9a4bb6..31fd4e486 100644 --- a/beacon_chain/conf.nim +++ b/beacon_chain/conf.nim @@ -338,18 +338,21 @@ type name: "status-bar-contents" }: string rpcEnabled* {. - desc: "Enable the JSON-RPC server (deprecated)" + hidden + desc: "Enable the JSON-RPC server (deprecated for removal)" defaultValue: false name: "rpc" }: bool rpcPort* {. - desc: "HTTP port for the JSON-RPC service" - defaultValue: defaultEth2RpcPort + hidden + desc: "HTTP port for the JSON-RPC service (deprecated for removal)" + defaultValue: 9190 defaultValueDesc: "9190" name: "rpc-port" }: Port rpcAddress* {. - desc: "Listening address of the RPC server" + hidden + desc: "Listening address of the RPC server (deprecated for removal)" defaultValue: defaultAdminListenAddress defaultValueDesc: "127.0.0.1" name: "rpc-address" }: ValidIpAddress diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index de4aa5aad..bf6914f7e 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -14,7 +14,7 @@ import stew/[byteutils, io2], eth/p2p/discoveryv5/[enr, random2], eth/keys, - ./rpc/[rest_api, rpc_api, state_ttl_cache], + ./rpc/[rest_api, state_ttl_cache], ./spec/datatypes/[altair, bellatrix, phase0], ./spec/[engine_authentication, weak_subjectivity], ./validators/[keystore_management, validator_duties], @@ -577,10 +577,8 @@ proc init*(T: type BeaconNode, config.web3ForcePolling, optJwtSecret) - let rpcServer = if config.rpcEnabled: - RpcServer.init(config.rpcAddress, config.rpcPort) - else: - nil + if config.rpcEnabled: + warn "Nimbus's JSON-RPC server has been removed. This includes the --rpc, --rpc-port, and --rpc-address configuration options. https://nimbus.guide/rest-api.html shows how to enable and configure the REST Beacon API server which replaces it." let restServer = if config.restEnabled: RestServerRef.init( @@ -676,7 +674,6 @@ proc init*(T: type BeaconNode, config: config, attachedValidators: validatorPool, eth1Monitor: eth1Monitor, - rpcServer: rpcServer, restServer: restServer, keymanagerServer: keymanagerServer, keymanagerToken: keymanagerToken, @@ -1293,16 +1290,6 @@ proc runOnSecondLoop(node: BeaconNode) {.async.} = func connectedPeersCount(node: BeaconNode): int = len(node.network.peerPool) -proc installRpcHandlers(rpcServer: RpcServer, node: BeaconNode) {. - raises: [Defect, CatchableError].} = - rpcServer.installBeaconApiHandlers(node) - rpcServer.installConfigApiHandlers(node) - rpcServer.installDebugApiHandlers(node) - rpcServer.installEventApiHandlers(node) - rpcServer.installNimbusApiHandlers(node) - rpcServer.installNodeApiHandlers(node) - rpcServer.installValidatorApiHandlers(node) - proc installRestHandlers(restServer: RestServerRef, node: BeaconNode) = restServer.router.installBeaconApiHandlers(node) restServer.router.installConfigApiHandlers(node) @@ -1465,10 +1452,6 @@ proc startBackfillTask(node: BeaconNode) {.async.} = proc run(node: BeaconNode) {.raises: [Defect, CatchableError].} = bnStatus = BeaconNodeStatus.Running - if not(isNil(node.rpcServer)): - node.rpcServer.installRpcHandlers(node) - node.rpcServer.start() - if not(isNil(node.restServer)): node.restServer.installRestHandlers(node) node.restServer.start() diff --git a/beacon_chain/rpc/rpc_api.nim b/beacon_chain/rpc/rpc_api.nim deleted file mode 100644 index d0e3507c3..000000000 --- a/beacon_chain/rpc/rpc_api.nim +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (c) 2018-2021 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -## The `rpc_api` module is a server implementation of a JSON-RPC-based API -## for Nimbus - it is based on the common REST API for Ethereum 2 found at -## https://ethereum.github.io/eth2.0-APIs/# but uses JSON-RPC as transport -## instead. There are also minor historical differences in encoding and data - -## these differences will likely remain so as to not break old tooling. -## -## The JSON-RPC is used by community utilities and tools and is kept for -## backwards compatibility mainly. -## A corresponding client can be found in the -## `spec/eth2_apis/rpc_beacon_client` module. -import - "."/[ - rpc_beacon_api, rpc_config_api, rpc_debug_api, rpc_event_api, - rpc_nimbus_api, rpc_node_api, rpc_validator_api] - -export - rpc_beacon_api, rpc_config_api, rpc_debug_api, rpc_event_api, - rpc_nimbus_api, rpc_node_api, rpc_validator_api diff --git a/beacon_chain/rpc/rpc_beacon_api.nim b/beacon_chain/rpc/rpc_beacon_api.nim deleted file mode 100644 index 0cab8d7be..000000000 --- a/beacon_chain/rpc/rpc_beacon_api.nim +++ /dev/null @@ -1,513 +0,0 @@ -# beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -{.push raises: [Defect].} - -import - std/[parseutils, sequtils, strutils, sets], - stew/[byteutils, results], - json_rpc/servers/httpserver, - chronicles, - ../beacon_node, - ../networking/eth2_network, - ../validators/validator_duties, - ../consensus_object_pools/blockchain_dag, - ../spec/[eth2_merkleization, forks, network, validator], - ../spec/datatypes/[phase0], - ./rpc_utils - -logScope: topics = "beaconapi" - -type - RpcServer = RpcHttpServer - - ValidatorQuery = object - # Security note / threat model: - # - The validator pubkey are stored in their raw bytes representation - # in the `keyset`. - # - While the input is from unknown source (as far as the beacon node is concerned), - # users are asked to not expose their - # RPC endpoints to untrusted network or use a reverse proxy in front. - # - At usage time, keys in the keyset are compared to keys registered - # in the Ethereum BeaconState which are valid - keyset: HashSet[ValidatorPubKey] - ids: seq[uint64] - - StatusQuery = object - statset: HashSet[string] - -template unimplemented() = - raise (ref CatchableError)(msg: "Unimplemented") - -proc createIdQuery(ids: openArray[string]): Result[ValidatorQuery, cstring] = - # validatorIds array should have maximum 30 items, and all items should be - # unique. - if len(ids) > 30: - return err("The number of ids exceeds the limit") - - # All ids in validatorIds must be unique. - if len(ids) != len(toHashSet(ids)): - return err("ids array must have unique item") - - var res = ValidatorQuery( - keyset: initHashSet[ValidatorPubKey](), - ids: newSeq[uint64]() - ) - - for item in ids: - if item.startsWith("0x"): - let pubkey = ? ValidatorPubKey.fromHex(item) - res.keyset.incl(pubkey) - else: - var tmp: uint64 - try: - if parseBiggestUInt(item, tmp) != len(item): - return err("Incorrect index value") - except ValueError: - return err("Cannot parse index value") - res.ids.add(tmp) - ok(res) - -proc createStatusQuery(status: openArray[string]): Result[StatusQuery, string] = - const AllowedStatuses = [ - "pending", "pending_initialized", "pending_queued", - "active", "active_ongoing", "active_exiting", "active_slashed", - "exited", "exited_unslashed", "exited_slashed", - "withdrawal", "withdrawal_possible", "withdrawal_done" - ] - - if len(status) > len(AllowedStatuses): - return err("The number of statuses exceeds the limit") - - var res = StatusQuery(statset: initHashSet[string]()) - - # All ids in validatorIds must be unique. - if len(status) != len(toHashSet(status)): - return err("Status array must have unique items") - - for item in status: - if item notin AllowedStatuses: - return err("Invalid status requested") - case item - of "pending": - res.statset.incl("pending_initialized") - res.statset.incl("pending_queued") - of "active": - res.statset.incl("active_ongoing") - res.statset.incl("active_exiting") - res.statset.incl("active_slashed") - of "exited": - res.statset.incl("exited_unslashed") - res.statset.incl("exited_slashed") - of "withdrawal": - res.statset.incl("withdrawal_possible") - res.statset.incl("withdrawal_done") - else: - res.statset.incl(item) - -proc getStatus(validator: Validator, - current_epoch: Epoch): Result[string, string] = - if validator.activation_epoch > current_epoch: - # pending - if validator.activation_eligibility_epoch == FAR_FUTURE_EPOCH: - ok("pending_initialized") - else: - # validator.activation_eligibility_epoch < FAR_FUTURE_EPOCH: - ok("pending_queued") - elif (validator.activation_epoch <= current_epoch) and - (current_epoch < validator.exit_epoch): - # active - if validator.exit_epoch == FAR_FUTURE_EPOCH: - ok("active_ongoing") - elif not validator.slashed: - # validator.exit_epoch < FAR_FUTURE_EPOCH - ok("active_exiting") - else: - # validator.exit_epoch < FAR_FUTURE_EPOCH and validator.slashed: - ok("active_slashed") - elif (validator.exit_epoch <= current_epoch) and - (current_epoch < validator.withdrawable_epoch): - # exited - if not validator.slashed: - ok("exited_unslashed") - else: - # validator.slashed - ok("exited_slashed") - elif validator.withdrawable_epoch <= current_epoch: - # withdrawal - if validator.effective_balance != 0: - ok("withdrawal_possible") - else: - # validator.effective_balance == 0 - ok("withdrawal_done") - else: - err("Invalid validator status") - -proc getForkedBlockFromBlockId( - node: BeaconNode, blockId: string): ForkedTrustedSignedBeaconBlock {. - raises: [Defect, CatchableError].} = - case blockId: - of "head": - node.dag.getForkedBlock(node.dag.head.bid).valueOr: - raise newException(CatchableError, "Block not found") - of "genesis": - node.dag.getForkedBlock(node.dag.genesis).valueOr: - raise newException(CatchableError, "Block not found") - of "finalized": - node.dag.getForkedBlock(node.dag.finalizedHead.blck.bid).valueOr: - raise newException(CatchableError, "Block not found") - else: - if blockId.startsWith("0x"): - let - blckRoot = parseRoot(blockId) - node.dag.getForkedBlock(blckRoot).valueOr: - raise newException(CatchableError, "Block not found") - else: - let bid = node.getBlockIdFromString(blockId) - node.dag.getForkedBlock(bid).valueOr: - raise newException(CatchableError, "Block not found") - -proc installBeaconApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. - raises: [Defect, CatchableError].} = - rpcServer.rpc("get_v1_beacon_genesis") do () -> RpcBeaconGenesis: - return ( - genesis_time: getStateField(node.dag.headState, genesis_time), - genesis_validators_root: - getStateField(node.dag.headState, genesis_validators_root), - genesis_fork_version: node.dag.cfg.GENESIS_FORK_VERSION - ) - - rpcServer.rpc("get_v1_beacon_states_root") do (stateId: string) -> Eth2Digest: - withStateForStateId(stateId): - return stateRoot - - rpcServer.rpc("get_v1_beacon_states_fork") do (stateId: string) -> Fork: - withStateForStateId(stateId): - return getStateField(state, fork) - - rpcServer.rpc("get_v1_beacon_states_finality_checkpoints") do ( - stateId: string) -> RpcBeaconStatesFinalityCheckpoints: - withStateForStateId(stateId): - return (previous_justified: - getStateField(state, previous_justified_checkpoint), - current_justified: - getStateField(state, current_justified_checkpoint), - finalized: getStateField(state, finalized_checkpoint)) - - rpcServer.rpc("get_v1_beacon_states_stateId_validators") do ( - stateId: string, validatorIds: Option[seq[string]], - status: Option[seq[string]]) -> seq[RpcBeaconStatesValidators]: - var vquery: ValidatorQuery - var squery: StatusQuery - let current_epoch = getStateField(node.dag.headState, slot).epoch - - template statusCheck(status, statusQuery, vstatus, current_epoch): bool = - if status.isNone(): - true - else: - if vstatus in squery.statset: - true - else: - false - - var res: seq[RpcBeaconStatesValidators] - - withStateForStateId(stateId): - if status.isSome: - let sqres = createStatusQuery(status.get()) - if sqres.isErr: - raise newException(CatchableError, sqres.error) - squery = sqres.get() - - if validatorIds.isSome: - let vqres = createIdQuery(validatorIds.get()) - if vqres.isErr: - raise newException(CatchableError, $vqres.error) - vquery = vqres.get() - - if validatorIds.isNone(): - for index, validator in getStateField(state, validators): - let sres = validator.getStatus(current_epoch) - if sres.isOk: - let vstatus = sres.get() - let includeFlag = statusCheck(status, squery, vstatus, - current_epoch) - if includeFlag: - res.add((validator: validator, - index: uint64(index), - status: vstatus, - balance: getStateField(state, balances).asSeq()[index])) - else: - for index in vquery.ids: - if index < lenu64(getStateField(state, validators)): - let validator = getStateField(state, validators).asSeq()[index] - let sres = validator.getStatus(current_epoch) - if sres.isOk: - let vstatus = sres.get() - let includeFlag = statusCheck(status, squery, vstatus, - current_epoch) - if includeFlag: - vquery.keyset.excl(validator.pubkey) - res.add((validator: validator, - index: uint64(index), - status: vstatus, - balance: getStateField(state, balances).asSeq()[index])) - - for index, validator in getStateField(state, validators): - if validator.pubkey in vquery.keyset: - let sres = validator.getStatus(current_epoch) - if sres.isOk: - let vstatus = sres.get() - let includeFlag = statusCheck(status, squery, vstatus, - current_epoch) - if includeFlag: - res.add((validator: validator, - index: uint64(index), - status: vstatus, - balance: getStateField(state, balances).asSeq()[index])) - return res - - rpcServer.rpc("get_v1_beacon_states_stateId_validators_validatorId") do ( - stateId: string, validatorId: string) -> RpcBeaconStatesValidators: - let current_epoch = getStateField(node.dag.headState, slot).epoch - let vqres = createIdQuery([validatorId]) - if vqres.isErr: - raise newException(CatchableError, $vqres.error) - let vquery = vqres.get() - - withStateForStateId(stateId): - if len(vquery.ids) > 0: - let index = vquery.ids[0] - if index < lenu64(getStateField(state, validators)): - let validator = getStateField(state, validators).asSeq()[index] - let sres = validator.getStatus(current_epoch) - if sres.isOk: - return (validator: validator, index: uint64(index), - status: sres.get(), - balance: getStateField(state, balances).asSeq()[index]) - else: - raise newException(CatchableError, "Incorrect validator's state") - else: - for index, validator in getStateField(state, validators): - if validator.pubkey in vquery.keyset: - let sres = validator.getStatus(current_epoch) - if sres.isOk: - return (validator: validator, index: uint64(index), - status: sres.get(), - balance: getStateField(state, balances).asSeq()[index]) - else: - raise newException(CatchableError, "Incorrect validator's state") - - rpcServer.rpc("get_v1_beacon_states_stateId_validator_balances") do ( - stateId: string, validatorsId: Option[seq[string]]) -> seq[RpcBalance]: - - var res: seq[RpcBalance] - withStateForStateId(stateId): - if validatorsId.isNone(): - for index, value in getStateField(state, balances): - let balance = (index: uint64(index), balance: value) - res.add(balance) - else: - let vqres = createIdQuery(validatorsId.get()) - if vqres.isErr: - raise newException(CatchableError, $vqres.error) - - var vquery = vqres.get() - for index in vquery.ids: - if index < lenu64(getStateField(state, validators)): - let validator = getStateField(state, validators).asSeq()[index] - vquery.keyset.excl(validator.pubkey) - let balance = (index: uint64(index), - balance: getStateField(state, balances).asSeq()[index]) - res.add(balance) - - for index, validator in getStateField(state, validators): - if validator.pubkey in vquery.keyset: - let balance = (index: uint64(index), - balance: getStateField(state, balances).asSeq()[index]) - res.add(balance) - return res - - rpcServer.rpc("get_v1_beacon_states_stateId_committees_epoch") do ( - stateId: string, epoch: Option[uint64], index: Option[uint64], - slot: Option[uint64]) -> seq[RpcBeaconStatesCommittees]: - withStateForStateId(stateId): - proc getCommittee(slot: Slot, - index: CommitteeIndex): RpcBeaconStatesCommittees = - let vals = get_beacon_committee( - state, slot, index, cache).mapIt(it.uint64) - return (index: index.uint64, slot: slot.uint64, validators: vals) - - proc forSlot(slot: Slot, res: var seq[RpcBeaconStatesCommittees]) = - let committees_per_slot = - get_committee_count_per_slot(state, slot.epoch, cache) - - if index.isNone: - for committee_index in get_committee_indices(committees_per_slot): - res.add(getCommittee(slot, committee_index)) - else: - if index.get() < committees_per_slot: - let cindex = CommitteeIndex.init(index.get()).expect( - "valid because verified against committees_per_slot") - res.add(getCommittee(slot, cindex)) - - var res: seq[RpcBeaconStatesCommittees] - - let qepoch = - if epoch.isNone: - epoch(getStateField(state, slot)) - else: - Epoch(epoch.get()) - - if slot.isNone: - for slot in qepoch.slots(): - forSlot(slot, res) - else: - forSlot(Slot(slot.get()), res) - - return res - - rpcServer.rpc("get_v1_beacon_headers") do ( - slot: Option[uint64], parent_root: Option[string]) -> - seq[RpcBeaconHeaders]: - unimplemented() - - rpcServer.rpc("get_v1_beacon_headers_blockId") do ( - blockId: string) -> - tuple[canonical: bool, header: SignedBeaconBlockHeader]: - let bd = node.getForkedBlockFromBlockId(blockId) - return withBlck(bd): - static: doAssert blck.signature is TrustedSig and - sizeof(ValidatorSig) == sizeof(blck.signature) - ( - canonical: node.dag.isCanonical( - BlockId(root: blck.root, slot: blck.message.slot)), - header: SignedBeaconBlockHeader( - message: blck.toBeaconBlockHeader - ) - ) - - rpcServer.rpc("post_v1_beacon_blocks") do (blck: phase0.SignedBeaconBlock) -> int: - let res = await sendBeaconBlock(node, ForkedSignedBeaconBlock.init(blck)) - if res.isErr(): - raise (ref CatchableError)(msg: $res.error()) - - if res.get(): - # The block was validated successfully and has been broadcast. - # It has also been integrated into the beacon node's database. - return 200 - else: - # The block failed validation, but was successfully broadcast anyway. - # It was not integrated into the beacon node''s database. - return 202 - - rpcServer.rpc("get_v1_beacon_blocks_blockId") do ( - blockId: string) -> phase0.TrustedSignedBeaconBlock: - let blck = node.getForkedBlockFromBlockId(blockId) - if blck.kind == BeaconBlockFork.Phase0: - return blck.phase0Data - else: - raiseNoAltairSupport() - - rpcServer.rpc("get_v1_beacon_blocks_blockId_root") do ( - blockId: string) -> Eth2Digest: - return withBlck(node.getForkedBlockFromBlockId(blockId)): - blck.root - - rpcServer.rpc("get_v1_beacon_blocks_blockId_attestations") do ( - blockId: string) -> seq[TrustedAttestation]: - return withBlck(node.getForkedBlockFromBlockId(blockId)): - blck.message.body.attestations.asSeq - - rpcServer.rpc("get_v1_beacon_pool_attestations") do ( - slot: Option[uint64], committee_index: Option[uint64]) -> - seq[RpcAttestation]: - - var res: seq[RpcAttestation] - - let qslot = - if slot.isSome(): - some(Slot(slot.get())) - else: - none[Slot]() - - let qindex = - if committee_index.isSome(): - some(CommitteeIndex(committee_index.get())) - else: - none[CommitteeIndex]() - - for item in node.attestationPool[].attestations(qslot, qindex): - let atuple = ( - aggregation_bits: to0xHex(item.aggregation_bits.bytes), - data: item.data, - signature: item.signature - ) - res.add(atuple) - - return res - - rpcServer.rpc("post_v1_beacon_pool_attestations") do ( - attestation: Attestation) -> bool: - let res = await node.sendAttestation(attestation) - if not res.isOk(): - raise (ref CatchableError)(msg: $res.error()) - return true - - rpcServer.rpc("get_v1_beacon_pool_attester_slashings") do ( - ) -> seq[AttesterSlashing]: - var res: seq[AttesterSlashing] - if isNil(node.exitPool): - return res - let length = len(node.exitPool.attester_slashings) - res = newSeqOfCap[AttesterSlashing](length) - for item in node.exitPool.attester_slashings.items(): - res.add(item) - return res - - rpcServer.rpc("post_v1_beacon_pool_attester_slashings") do ( - slashing: AttesterSlashing) -> bool: - let res = node.sendAttesterSlashing(slashing) - if not res.isOk(): - raise (ref CatchableError)(msg: $res.error()) - return true - - rpcServer.rpc("get_v1_beacon_pool_proposer_slashings") do ( - ) -> seq[ProposerSlashing]: - var res: seq[ProposerSlashing] - if isNil(node.exitPool): - return res - let length = len(node.exitPool.proposer_slashings) - res = newSeqOfCap[ProposerSlashing](length) - for item in node.exitPool.proposer_slashings.items(): - res.add(item) - return res - - rpcServer.rpc("post_v1_beacon_pool_proposer_slashings") do ( - slashing: ProposerSlashing) -> bool: - let res = node.sendProposerSlashing(slashing) - if not res.isOk(): - raise (ref CatchableError)(msg: $res.error()) - return true - - rpcServer.rpc("get_v1_beacon_pool_voluntary_exits") do ( - ) -> seq[SignedVoluntaryExit]: - var res: seq[SignedVoluntaryExit] - if isNil(node.exitPool): - return res - let length = len(node.exitPool.voluntary_exits) - res = newSeqOfCap[SignedVoluntaryExit](length) - for item in node.exitPool.voluntary_exits.items(): - res.add(item) - return res - - rpcServer.rpc("post_v1_beacon_pool_voluntary_exits") do ( - exit: SignedVoluntaryExit) -> bool: - let res = node.sendVoluntaryExit(exit) - if not res.isOk(): - raise (ref CatchableError)(msg: $res.error()) - return true diff --git a/beacon_chain/rpc/rpc_config_api.nim b/beacon_chain/rpc/rpc_config_api.nim deleted file mode 100644 index 9be12cd84..000000000 --- a/beacon_chain/rpc/rpc_config_api.nim +++ /dev/null @@ -1,109 +0,0 @@ -# beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -{.push raises: [Defect].} - -import - stew/[byteutils], - json_rpc/servers/httpserver, - chronicles, - ../beacon_node, - ../eth1/eth1_monitor, - ../spec/forks - -logScope: topics = "configapi" - -type - RpcServer = RpcHttpServer - -proc installConfigApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. - raises: [Defect, CatchableError].} = - rpcServer.rpc("get_v1_config_fork_schedule") do () -> seq[Fork]: - return @[getStateField(node.dag.headState, fork)] - - rpcServer.rpc("get_v1_config_spec") do () -> JsonNode: - return %*{ - # Note: This is intentionally only returning v1.0 config values. - # Please use the REST API /eth/v1/config/spec to retrieve the full config. - # https://github.com/ethereum/consensus-specs/blob/v1.0.1/configs/mainnet/phase0.yaml - "MAX_COMMITTEES_PER_SLOT": $MAX_COMMITTEES_PER_SLOT, - "TARGET_COMMITTEE_SIZE": $TARGET_COMMITTEE_SIZE, - "MAX_VALIDATORS_PER_COMMITTEE": $MAX_VALIDATORS_PER_COMMITTEE, - "MIN_PER_EPOCH_CHURN_LIMIT": $node.dag.cfg.MIN_PER_EPOCH_CHURN_LIMIT, - "CHURN_LIMIT_QUOTIENT": $node.dag.cfg.CHURN_LIMIT_QUOTIENT, - "SHUFFLE_ROUND_COUNT": $SHUFFLE_ROUND_COUNT, - "MIN_GENESIS_ACTIVE_VALIDATOR_COUNT": - $node.dag.cfg.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT, - "MIN_GENESIS_TIME": $node.dag.cfg.MIN_GENESIS_TIME, - "HYSTERESIS_QUOTIENT": $HYSTERESIS_QUOTIENT, - "HYSTERESIS_DOWNWARD_MULTIPLIER": $HYSTERESIS_DOWNWARD_MULTIPLIER, - "HYSTERESIS_UPWARD_MULTIPLIER": $HYSTERESIS_UPWARD_MULTIPLIER, - "SAFE_SLOTS_TO_UPDATE_JUSTIFIED": $SAFE_SLOTS_TO_UPDATE_JUSTIFIED, - "ETH1_FOLLOW_DISTANCE": $node.dag.cfg.ETH1_FOLLOW_DISTANCE, - "TARGET_AGGREGATORS_PER_COMMITTEE": $TARGET_AGGREGATORS_PER_COMMITTEE, - "RANDOM_SUBNETS_PER_VALIDATOR": $RANDOM_SUBNETS_PER_VALIDATOR, - "EPOCHS_PER_RANDOM_SUBNET_SUBSCRIPTION": - $EPOCHS_PER_RANDOM_SUBNET_SUBSCRIPTION, - "SECONDS_PER_ETH1_BLOCK": $node.dag.cfg.SECONDS_PER_ETH1_BLOCK, - "DEPOSIT_CHAIN_ID": $node.dag.cfg.DEPOSIT_CHAIN_ID, - "DEPOSIT_NETWORK_ID": $node.dag.cfg.DEPOSIT_NETWORK_ID, - "DEPOSIT_CONTRACT_ADDRESS": $node.dag.cfg.DEPOSIT_CONTRACT_ADDRESS, - "MIN_DEPOSIT_AMOUNT": $MIN_DEPOSIT_AMOUNT, - "MAX_EFFECTIVE_BALANCE": $MAX_EFFECTIVE_BALANCE, - "EJECTION_BALANCE": $node.dag.cfg.EJECTION_BALANCE, - "EFFECTIVE_BALANCE_INCREMENT": $EFFECTIVE_BALANCE_INCREMENT, - "GENESIS_FORK_VERSION": - "0x" & $node.dag.cfg.GENESIS_FORK_VERSION, - "BLS_WITHDRAWAL_PREFIX": to0xHex([BLS_WITHDRAWAL_PREFIX]), - "GENESIS_DELAY": $node.dag.cfg.GENESIS_DELAY, - "SECONDS_PER_SLOT": $SECONDS_PER_SLOT, - "MIN_ATTESTATION_INCLUSION_DELAY": $MIN_ATTESTATION_INCLUSION_DELAY, - "SLOTS_PER_EPOCH": $SLOTS_PER_EPOCH, - "MIN_SEED_LOOKAHEAD": $MIN_SEED_LOOKAHEAD, - "MAX_SEED_LOOKAHEAD": $MAX_SEED_LOOKAHEAD, - "EPOCHS_PER_ETH1_VOTING_PERIOD": $EPOCHS_PER_ETH1_VOTING_PERIOD, - "SLOTS_PER_HISTORICAL_ROOT": $SLOTS_PER_HISTORICAL_ROOT, - "MIN_VALIDATOR_WITHDRAWABILITY_DELAY": - $node.dag.cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY, - "SHARD_COMMITTEE_PERIOD": $node.dag.cfg.SHARD_COMMITTEE_PERIOD, - "MIN_EPOCHS_TO_INACTIVITY_PENALTY": $MIN_EPOCHS_TO_INACTIVITY_PENALTY, - "EPOCHS_PER_HISTORICAL_VECTOR": $EPOCHS_PER_HISTORICAL_VECTOR, - "EPOCHS_PER_SLASHINGS_VECTOR": $EPOCHS_PER_SLASHINGS_VECTOR, - "HISTORICAL_ROOTS_LIMIT": $HISTORICAL_ROOTS_LIMIT, - "VALIDATOR_REGISTRY_LIMIT": $VALIDATOR_REGISTRY_LIMIT, - "BASE_REWARD_FACTOR": $BASE_REWARD_FACTOR, - "WHISTLEBLOWER_REWARD_QUOTIENT": $WHISTLEBLOWER_REWARD_QUOTIENT, - "PROPOSER_REWARD_QUOTIENT": $PROPOSER_REWARD_QUOTIENT, - "INACTIVITY_PENALTY_QUOTIENT": $INACTIVITY_PENALTY_QUOTIENT, - "MIN_SLASHING_PENALTY_QUOTIENT": $MIN_SLASHING_PENALTY_QUOTIENT, - "PROPORTIONAL_SLASHING_MULTIPLIER": $PROPORTIONAL_SLASHING_MULTIPLIER, - "MAX_PROPOSER_SLASHINGS": $MAX_PROPOSER_SLASHINGS, - "MAX_ATTESTER_SLASHINGS": $MAX_ATTESTER_SLASHINGS, - "MAX_ATTESTATIONS": $MAX_ATTESTATIONS, - "MAX_DEPOSITS": $MAX_DEPOSITS, - "MAX_VOLUNTARY_EXITS": $MAX_VOLUNTARY_EXITS, - "DOMAIN_BEACON_PROPOSER": - to0xHex(DOMAIN_BEACON_PROPOSER.data), - "DOMAIN_BEACON_ATTESTER": - to0xHex(DOMAIN_BEACON_ATTESTER.data), - "DOMAIN_RANDAO": - to0xHex(DOMAIN_RANDAO.data), - "DOMAIN_DEPOSIT": - to0xHex(DOMAIN_DEPOSIT.data), - "DOMAIN_VOLUNTARY_EXIT": - to0xHex(DOMAIN_VOLUNTARY_EXIT.data), - "DOMAIN_SELECTION_PROOF": - to0xHex(DOMAIN_SELECTION_PROOF.data), - "DOMAIN_AGGREGATE_AND_PROOF": - to0xHex(DOMAIN_AGGREGATE_AND_PROOF.data) - } - - rpcServer.rpc("get_v1_config_deposit_contract") do () -> JsonNode: - return %*{ - "chain_id": $node.dag.cfg.DEPOSIT_CHAIN_ID, - "address": node.dag.cfg.DEPOSIT_CONTRACT_ADDRESS - } diff --git a/beacon_chain/rpc/rpc_debug_api.nim b/beacon_chain/rpc/rpc_debug_api.nim deleted file mode 100644 index 22d8bced8..000000000 --- a/beacon_chain/rpc/rpc_debug_api.nim +++ /dev/null @@ -1,35 +0,0 @@ -# beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -{.push raises: [Defect].} - -import - std/sequtils, - json_rpc/servers/httpserver, - chronicles, - ../version, ../beacon_node, - ../networking/[eth2_network, peer_pool], - ../spec/datatypes/phase0, - ./rpc_utils - -logScope: topics = "debugapi" - -type - RpcServer = RpcHttpServer - -proc installDebugApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. - raises: [Defect, CatchableError].} = - rpcServer.rpc("get_v1_debug_beacon_states_stateId") do ( - stateId: string) -> phase0.BeaconState: - withStateForStateId(stateId): - if state.kind == BeaconStateFork.Phase0: - return state.phase0Data.data - else: - raiseNoAltairSupport() - - rpcServer.rpc("get_v1_debug_beacon_heads") do () -> seq[tuple[root: Eth2Digest, slot: Slot]]: - return node.dag.heads.mapIt((it.root, it.slot)) diff --git a/beacon_chain/rpc/rpc_event_api.nim b/beacon_chain/rpc/rpc_event_api.nim deleted file mode 100644 index e18a7d6c3..000000000 --- a/beacon_chain/rpc/rpc_event_api.nim +++ /dev/null @@ -1,26 +0,0 @@ -# beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -{.push raises: [Defect].} - -import - json_rpc/servers/httpserver, - chronicles, - ../beacon_node - -logScope: topics = "eventapi" - -type - RpcServer = RpcHttpServer - -template unimplemented() = - raise (ref CatchableError)(msg: "Unimplemented") - -proc installEventApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. - raises: [Defect, CatchableError].} = - rpcServer.rpc("get_v1_events") do () -> JsonNode: - unimplemented() diff --git a/beacon_chain/rpc/rpc_nimbus_api.nim b/beacon_chain/rpc/rpc_nimbus_api.nim deleted file mode 100644 index d83ad5ff6..000000000 --- a/beacon_chain/rpc/rpc_nimbus_api.nim +++ /dev/null @@ -1,230 +0,0 @@ -# beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -{.push raises: [Defect].} - -import - std/[deques, sequtils, sets], - chronos, - stew/byteutils, - json_rpc/servers/httpserver, - libp2p/protocols/pubsub/pubsubpeer, - - ".."/[ - beacon_node, nimbus_binary_common, networking/eth2_network, - eth1/eth1_monitor, validators/validator_duties], - ../spec/datatypes/base, - ../spec/[forks], - ./rpc_utils - -when defined(chronosFutureTracking): - import stew/base10 - -logScope: topics = "nimbusapi" - -type - RpcServer = RpcHttpServer - - FutureInfo* = object - id*: string - child_id*: string - procname*: string - filename*: string - line*: int - state*: string - -proc installNimbusApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. - raises: [Defect, CatchableError].} = - ## Install non-standard api handlers - some of these are used by 3rd-parties - ## such as eth2stats, pending a full REST api - rpcServer.rpc("getBeaconHead") do () -> Slot: - return node.dag.head.slot - - rpcServer.rpc("getChainHead") do () -> JsonNode: - let - head = node.dag.head - finalized = getStateField(node.dag.headState, finalized_checkpoint) - justified = - getStateField(node.dag.headState, current_justified_checkpoint) - return %* { - "head_slot": head.slot, - "head_block_root": head.root.data.toHex(), - "finalized_slot": finalized.epoch * SLOTS_PER_EPOCH, - "finalized_block_root": finalized.root.data.toHex(), - "justified_slot": justified.epoch * SLOTS_PER_EPOCH, - "justified_block_root": justified.root.data.toHex(), - } - - rpcServer.rpc("getSyncing") do () -> bool: - return node.syncManager.inProgress - - rpcServer.rpc("getNetworkPeerId") do () -> string: - return $node.network.peerId() - - rpcServer.rpc("getNetworkPeers") do () -> seq[string]: - for peerId, peer in node.network.peerPool: - result.add $peerId - - rpcServer.rpc("getNodeVersion") do () -> string: - return "Nimbus/" & fullVersionStr - - rpcServer.rpc("peers") do () -> JsonNode: - var res = newJObject() - var peers = newJArray() - for id, peer in node.network.peerPool: - peers.add( - %( - id: shortLog(peer.peerId), - connectionState: $peer.connectionState, - score: peer.score, - ) - ) - res.add("peers", peers) - - return res - - rpcServer.rpc("setLogLevel") do (level: string) -> bool: - {.gcsafe.}: # It's probably not, actually. Hopefully we don't log from threads... - updateLogLevel(level) - return true - - rpcServer.rpc("setGraffiti") do (graffiti: string) -> bool: - node.graffitiBytes = GraffitiBytes.init(graffiti) - return true - - rpcServer.rpc("getEth1Chain") do () -> seq[Eth1Block]: - result = if node.eth1Monitor != nil: - mapIt(node.eth1Monitor.depositChainBlocks, it) - else: - @[] - - rpcServer.rpc("getEth1ProposalData") do () -> BlockProposalEth1Data: - let - wallSlot = node.beaconClock.now.slotOrZero - head = node.doChecksAndGetCurrentHead(wallSlot) - - let proposalState = assignClone(node.dag.headState) - node.dag.withUpdatedState( - proposalState[], - head.atSlot(wallSlot).toBlockSlotId().expect("not nil")): - return node.getBlockProposalEth1Data(state) - do: - raise (ref CatchableError)(msg: "Trying to access pruned state") - - rpcServer.rpc("debug_getChronosFutures") do () -> seq[FutureInfo]: - when defined(chronosFutureTracking): - var res: seq[FutureInfo] - - for item in pendingFutures(): - let loc = item.location[LocCreateIndex][] - let futureId = Base10.toString(item.id) - let childId = - if isNil(item.child): "" - else: Base10.toString(item.child.id) - res.add FutureInfo( - id: futureId, - child_id: childId, - procname: $loc.procedure, - filename: $loc.file, - line: loc.line, - state: $item.state - ) - - return res - else: - raise (ref CatchableError)( - msg: "Compile with '-d:chronosFutureTracking' to enable this request") - - rpcServer.rpc("debug_getGossipSubPeers") do () -> JsonNode: - var res = newJObject() - var gossipsub = newJObject() - - proc toNode(v: PubSubPeer, backoff: Moment): JsonNode = - %( - peerId: $v.peerId, - score: v.score, - iWantBudget: v.iWantBudget, - iHaveBudget: v.iHaveBudget, - outbound: v.outbound, - appScore: v.appScore, - behaviourPenalty: v.behaviourPenalty, - sendConnAvail: v.sendConn != nil, - closed: v.sendConn != nil and v.sendConn.closed, - atEof: v.sendConn != nil and v.sendConn.atEof, - address: if v.address.isSome(): - $v.address.get() - else: - "", - backoff: $(backoff - Moment.now()), - agent: when defined(libp2p_agents_metrics): - v.shortAgent - else: - "unknown", - ) - - for topic, v in node.network.pubsub.gossipsub: - var peers = newJArray() - let backoff = node.network.pubsub.backingOff.getOrDefault(topic) - for peer in v: - peers.add(peer.toNode(backoff.getOrDefault(peer.peerId))) - - gossipsub.add(topic, peers) - - res.add("gossipsub", gossipsub) - - var mesh = newJObject() - for topic, v in node.network.pubsub.mesh: - var peers = newJArray() - let backoff = node.network.pubsub.backingOff.getOrDefault(topic) - for peer in v: - peers.add(peer.toNode(backoff.getOrDefault(peer.peerId))) - - mesh.add(topic, peers) - - res.add("mesh", mesh) - - var coloc = newJArray() - for k, v in node.network.pubsub.peersInIP: - var a = newJObject() - var peers = newJArray() - for p in v: - peers.add(%($p)) - a.add($k, peers) - coloc.add(a) - - res.add("colocationPeers", coloc) - - var stats = newJArray() - for peerId, pstats in node.network.pubsub.peerStats: - let - peer = node.network.pubsub.peers.getOrDefault(peerId) - null = isNil(peer) - connected = if null: - false - else : - peer.connected() - - stats.add(%( - peerId: $peerId, - null: null, - connected: connected, - expire: $(pstats.expire - Moment.now()), - score: pstats.score - )) - - res.add("peerStats", stats) - - var peers = newJArray() - for peerId, peer in node.network.pubsub.peers: - peers.add(%( - connected: peer.connected, - peerId: $peerId - )) - - res.add("allPeers", peers) - - return res diff --git a/beacon_chain/rpc/rpc_node_api.nim b/beacon_chain/rpc/rpc_node_api.nim deleted file mode 100644 index 5f6cd16ae..000000000 --- a/beacon_chain/rpc/rpc_node_api.nim +++ /dev/null @@ -1,256 +0,0 @@ -# beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -{.push raises: [Defect].} - -import - std/[options, sequtils], - stew/byteutils, - chronicles, - json_rpc/servers/httpserver, - eth/p2p/discoveryv5/enr, - libp2p/[multiaddress, multicodec, peerstore], - ../beacon_node, ../version, - ../networking/[eth2_network, peer_pool], - ../sync/sync_manager, - ../spec/datatypes/base, - ./rpc_utils - -logScope: topics = "nodeapi" - -type - RpcServer = RpcHttpServer - -proc validateState(state: Option[seq[string]]): Option[set[ConnectionState]] = - var res: set[ConnectionState] - if state.isSome(): - let states = state.get() - for item in states: - case item - of "disconnected": - if ConnectionState.Disconnected notin res: - res.incl(ConnectionState.Disconnected) - else: - # `state` values should be unique - return none(set[ConnectionState]) - of "connecting": - if ConnectionState.Disconnected notin res: - res.incl(ConnectionState.Connecting) - else: - # `state` values should be unique - return none(set[ConnectionState]) - of "connected": - if ConnectionState.Connected notin res: - res.incl(ConnectionState.Connected) - else: - # `state` values should be unique - return none(set[ConnectionState]) - of "disconnecting": - if ConnectionState.Disconnecting notin res: - res.incl(ConnectionState.Disconnecting) - else: - # `state` values should be unique - return none(set[ConnectionState]) - else: - # Found incorrect `state` string value - return none(set[ConnectionState]) - - if res == {}: - res = {ConnectionState.Connecting, ConnectionState.Connected, - ConnectionState.Disconnecting, ConnectionState.Disconnected} - some(res) - -proc validateDirection(direction: Option[seq[string]]): Option[set[PeerType]] = - var res: set[PeerType] - if direction.isSome(): - let directions = direction.get() - for item in directions: - case item - of "inbound": - if PeerType.Incoming notin res: - res.incl(PeerType.Incoming) - else: - # `direction` values should be unique - return none(set[PeerType]) - of "outbound": - if PeerType.Outgoing notin res: - res.incl(PeerType.Outgoing) - else: - # `direction` values should be unique - return none(set[PeerType]) - else: - # Found incorrect `direction` string value - return none(set[PeerType]) - - if res == {}: - res = {PeerType.Incoming, PeerType.Outgoing} - some(res) - -proc toString(state: ConnectionState): string = - case state - of ConnectionState.Disconnected: - "disconnected" - of ConnectionState.Connecting: - "connecting" - of ConnectionState.Connected: - "connected" - of ConnectionState.Disconnecting: - "disconnecting" - else: - "" - -proc toString(direction: PeerType): string = - case direction: - of PeerType.Incoming: - "inbound" - of PeerType.Outgoing: - "outbound" - -proc getLastSeenAddress(node: BeaconNode, id: PeerId): string = - # TODO (cheatfate): We need to provide filter here, which will be able to - # filter such multiaddresses like `/ip4/0.0.0.0` or local addresses or - # addresses with peer ids. - let addrs = node.network.switch.peerStore.addressBook.get(id).toSeq() - if len(addrs) > 0: - $addrs[len(addrs) - 1] - else: - "" - -proc getDiscoveryAddresses(node: BeaconNode): Option[seq[string]] = - let restr = node.network.enrRecord().toTypedRecord() - if restr.isErr(): - return none[seq[string]]() - let respa = restr.get().toPeerAddr(udpProtocol) - if respa.isErr(): - return none[seq[string]]() - let pa = respa.get() - let mpa = MultiAddress.init(multiCodec("p2p"), pa.peerId) - if mpa.isErr(): - return none[seq[string]]() - var addresses = newSeqOfCap[string](len(pa.addrs)) - for item in pa.addrs: - let resa = concat(item, mpa.get()) - if resa.isOk(): - addresses.add($(resa.get())) - return some(addresses) - -proc getP2PAddresses(node: BeaconNode): Option[seq[string]] = - let pinfo = node.network.switch.peerInfo - let mpa = MultiAddress.init(multiCodec("p2p"), pinfo.peerId) - if mpa.isErr(): - return none[seq[string]]() - var addresses = newSeqOfCap[string](len(pinfo.addrs)) - for item in pinfo.addrs: - let resa = concat(item, mpa.get()) - if resa.isOk(): - addresses.add($(resa.get())) - return some(addresses) - -proc installNodeApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. - raises: [Defect, CatchableError].} = - rpcServer.rpc("get_v1_node_identity") do () -> RpcNodeIdentity: - let discoveryAddresses = - block: - let res = node.getDiscoveryAddresses() - if res.isSome(): - res.get() - else: - newSeq[string](0) - - let p2pAddresses = - block: - let res = node.getP2PAddresses() - if res.isSome(): - res.get() - else: - newSeq[string]() - - return ( - peer_id: $node.network.peerId(), - enr: node.network.enrRecord().toURI(), - p2p_addresses: p2pAddresses, - discovery_addresses: discoveryAddresses, - metadata: (node.network.metadata.seq_number, - to0xHex(node.network.metadata.attnets.bytes)) - ) - - rpcServer.rpc("get_v1_node_peers") do (state: Option[seq[string]], - direction: Option[seq[string]]) -> seq[RpcNodePeer]: - var res = newSeq[RpcNodePeer]() - let rstates = validateState(state) - if rstates.isNone(): - raise newException(CatchableError, "Incorrect state parameter") - let rdirs = validateDirection(direction) - if rdirs.isNone(): - raise newException(CatchableError, "Incorrect direction parameter") - let states = rstates.get() - let dirs = rdirs.get() - for peer in node.network.peers.values(): - if (peer.connectionState in states) and (peer.direction in dirs): - let resPeer = ( - peer_id: $peer.peerId, - enr: if peer.enr.isSome(): peer.enr.get().toURI() else: "", - last_seen_p2p_address: getLastSeenAddress(node, peer.peerId), - state: peer.connectionState.toString(), - direction: peer.direction.toString(), - agent: node.network.switch.peerStore.agentBook.get(peer.peerId), # Fields `agent` and `proto` are not - proto: node.network.switch.peerStore.protoVersionBook.get(peer.peerId) # part of specification - ) - res.add(resPeer) - return res - - rpcServer.rpc("get_v1_node_peer_count") do () -> RpcNodePeerCount: - var res: RpcNodePeerCount - for item in node.network.peers.values(): - case item.connectionState - of ConnectionState.Connecting: - inc(res.connecting) - of ConnectionState.Connected: - inc(res.connected) - of ConnectionState.Disconnecting: - inc(res.disconnecting) - of ConnectionState.Disconnected: - inc(res.disconnected) - of ConnectionState.None: - discard - return res - - rpcServer.rpc("get_v1_node_peers_peerId") do ( - peer_id: string) -> RpcNodePeer: - let pres = PeerId.init(peer_id) - if pres.isErr(): - raise newException(CatchableError, - "The peer ID supplied could not be parsed") - let pid = pres.get() - let peer = node.network.peers.getOrDefault(pid) - if isNil(peer): - raise newException(CatchableError, "Peer not found") - - return ( - peer_id: $peer.peerId, - enr: if peer.enr.isSome(): peer.enr.get().toURI() else: "", - last_seen_p2p_address: getLastSeenAddress(node, peer.peerId), - state: peer.connectionState.toString(), - direction: peer.direction.toString(), - agent: node.network.switch.peerStore.agentBook.get(peer.peerId), # Fields `agent` and `proto` are not - proto: node.network.switch.peerStore.protoVersionBook.get(peer.peerId) # part of specification - ) - - rpcServer.rpc("get_v1_node_version") do () -> JsonNode: - return %*{"version": "Nimbus/" & fullVersionStr} - - rpcServer.rpc("get_v1_node_syncing") do () -> RpcSyncInfo: - return node.syncManager.getInfo() - - rpcServer.rpc("get_v1_node_health") do () -> JsonNode: - # TODO: There currently no way to situation when we node has issues, so - # its impossible to return HTTP ERROR 503 according to specification. - if node.syncManager.inProgress: - # We need to return HTTP ERROR 206 according to specification - return %*{"health": 206} - else: - return %*{"health": 200} diff --git a/beacon_chain/rpc/rpc_utils.nim b/beacon_chain/rpc/rpc_utils.nim deleted file mode 100644 index 9fad73db7..000000000 --- a/beacon_chain/rpc/rpc_utils.nim +++ /dev/null @@ -1,111 +0,0 @@ -# beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -{.push raises: [Defect].} - -import - std/[strutils, parseutils], - stew/byteutils, - ../beacon_node, ../validators/validator_duties, - ../consensus_object_pools/[block_pools_types, blockchain_dag], - ../spec/datatypes/base, - ../spec/[forks, helpers], - ../spec/eth2_apis/[rpc_types, eth2_json_rpc_serialization] - -export forks, rpc_types, eth2_json_rpc_serialization, blockchain_dag - -template raiseNoAltairSupport*() = - raise (ref ValueError)(msg: - "The JSON-RPC interface does not support certain Altair operations due to changes in block structure - see https://nimbus.guide/rest-api.html for full altair support") - -template withStateForStateId*(stateId: string, body: untyped): untyped = - let - bsi = node.stateIdToBlockSlotId(stateId) - - template isState(state: ForkedHashedBeaconState): bool = - state.matches_block_slot(bsi.bid.root, bsi.slot) - - if isState(node.dag.headState): - withStateVars(node.dag.headState): - var cache {.inject, used.}: StateCache - body - else: - let rpcState = assignClone(node.dag.headState) - node.dag.withUpdatedState(rpcState[], bsi) do: - body - do: - raise (ref CatchableError)(msg: "Trying to access pruned state") - -proc parseRoot*(str: string): Eth2Digest {.raises: [Defect, ValueError].} = - Eth2Digest(data: hexToByteArray[32](str)) - -func checkEpochToSlotOverflow*(epoch: Epoch) {.raises: [Defect, ValueError].} = - const maxEpoch = epoch(FAR_FUTURE_SLOT) - if epoch >= maxEpoch: - raise newException( - ValueError, "Requesting epoch for which slot would overflow") - -proc doChecksAndGetCurrentHead*(node: BeaconNode, slot: Slot): BlockRef {.raises: [Defect, CatchableError].} = - result = node.dag.head - if not node.isSynced(result): - raise newException(CatchableError, "Cannot fulfill request until node is synced") - # TODO for now we limit the requests arbitrarily by up to 2 epochs into the future - if result.slot + uint64(2 * SLOTS_PER_EPOCH) < slot: - raise newException(CatchableError, "Requesting way ahead of the current head") - -proc doChecksAndGetCurrentHead*(node: BeaconNode, epoch: Epoch): BlockRef {.raises: [Defect, CatchableError].} = - checkEpochToSlotOverflow(epoch) - node.doChecksAndGetCurrentHead(epoch.start_slot()) - -proc parseSlot(slot: string): Slot {.raises: [Defect, CatchableError].} = - if slot.len == 0: - raise newException(ValueError, "Empty slot number not allowed") - var parsed: BiggestUInt - if parseBiggestUInt(slot, parsed) != slot.len: - raise newException(ValueError, "Not a valid slot number") - Slot parsed - -proc getBlockSlotIdFromString*(node: BeaconNode, slot: string): BlockSlotId {.raises: [Defect, CatchableError].} = - let parsed = parseSlot(slot) - discard node.doChecksAndGetCurrentHead(parsed) - node.dag.getBlockIdAtSlot(parsed).valueOr: - raise newException(ValueError, "Block not found") - -proc getBlockIdFromString*(node: BeaconNode, slot: string): BlockId {.raises: [Defect, CatchableError].} = - let parsed = parseSlot(slot) - discard node.doChecksAndGetCurrentHead(parsed) - let bsid = node.dag.getBlockIdAtSlot(parsed) - if bsid.isSome and bsid.get.isProposed(): - bsid.get().bid - else: - raise (ref ValueError)(msg: "Block not found") - -proc stateIdToBlockSlotId*(node: BeaconNode, stateId: string): BlockSlotId {.raises: [Defect, CatchableError].} = - case stateId: - of "head": - node.dag.head.bid.atSlot() - of "genesis": - node.dag.genesis.atSlot() - of "finalized": - node.dag.finalizedHead.toBlockSlotId().expect("not nil") - of "justified": - node.dag.head.atEpochStart( - getStateField( - node.dag.headState, current_justified_checkpoint).epoch). - toBlockSlotId().valueOr: - raise (ref ValueError)(msg: "State not found") - else: - if stateId.startsWith("0x"): - let stateRoot = parseRoot(stateId) - if stateRoot == getStateRoot(node.dag.headState): - node.dag.head.bid.atSlot() - else: - # We don't have a state root -> BlockSlot mapping - raise (ref ValueError)(msg: "State not found") - - else: # Parse as slot number - node.getBlockSlotIdFromString(stateId) diff --git a/beacon_chain/rpc/rpc_validator_api.nim b/beacon_chain/rpc/rpc_validator_api.nim deleted file mode 100644 index 5ced9944f..000000000 --- a/beacon_chain/rpc/rpc_validator_api.nim +++ /dev/null @@ -1,170 +0,0 @@ -# beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -{.push raises: [Defect].} - -import - # Standard library - std/tables, - - # Nimble packages - stew/objects, - json_rpc/servers/httpserver, - chronicles, - - # Local modules - ../spec/[forks, helpers, network, signatures], - ../spec/datatypes/phase0, - ../spec/eth2_apis/rpc_types, - ../consensus_object_pools/[blockchain_dag, spec_cache, attestation_pool], - ../beacon_node, - ../validators/validator_duties, - ../networking/eth2_network, - ./rpc_utils - -logScope: topics = "valapi" - -type - RpcServer* = RpcHttpServer - -proc installValidatorApiHandlers*(rpcServer: RpcServer, node: BeaconNode) {. - raises: [Defect, CatchableError].} = - rpcServer.rpc("get_v1_validator_block") do ( - slot: Slot, graffiti: GraffitiBytes, randao_reveal: ValidatorSig) -> phase0.BeaconBlock: - debug "get_v1_validator_block", slot = slot - let head = node.doChecksAndGetCurrentHead(slot) - let proposer = node.dag.getProposer(head, slot) - if proposer.isNone(): - raise newException(CatchableError, - "could not retrieve block for slot: " & $slot) - let res = await makeBeaconBlockForHeadAndSlot( - node, randao_reveal, proposer.get(), graffiti, head, slot) - if res.isErr(): - raise newException(CatchableError, res.error()) - let blck = res.get() - case blck.kind - of BeaconBlockFork.Phase0: - return blck.phase0Data - else: - raiseNoAltairSupport() - - rpcServer.rpc("get_v1_validator_attestation_data") do ( - slot: Slot, committee_index: CommitteeIndex) -> AttestationData: - debug "get_v1_validator_attestation_data", slot = slot - let - head = node.doChecksAndGetCurrentHead(slot) - epochRef = block: - let tmp = node.dag.getEpochRef(head, slot.epoch, true) - if isErr(tmp): - raise (ref CatchableError)(msg: "Trying to access pruned state") - tmp.get() - - return makeAttestationData(epochRef, head.atSlot(slot), committee_index) - - rpcServer.rpc("get_v1_validator_aggregate_attestation") do ( - slot: Slot, attestation_data_root: Eth2Digest)-> Attestation: - debug "get_v1_validator_aggregate_attestation" - let res = node.attestationPool[].getAggregatedAttestation(slot, attestation_data_root) - if res.isSome: - return res.get - raise newException(CatchableError, "Could not retrieve an aggregated attestation") - - rpcServer.rpc("post_v1_validator_aggregate_and_proofs") do ( - payload: SignedAggregateAndProof) -> bool: - debug "post_v1_validator_aggregate_and_proofs" - return (await node.sendAggregateAndProof(payload)).isOk() - - rpcServer.rpc("get_v1_validator_duties_attester") do ( - epoch: Epoch, public_keys: seq[ValidatorPubKey]) -> seq[RpcAttesterDuties]: - debug "get_v1_validator_duties_attester", epoch = epoch - let - head = node.doChecksAndGetCurrentHead(epoch) - epochRef = block: - let tmp = node.dag.getEpochRef(head, epoch, true) - if isErr(tmp): - raise (ref CatchableError)(msg: "Trying to access pruned state") - tmp.get() - - let - committees_per_slot = get_committee_count_per_slot(epochRef) - for slot in epoch.slots(): - for committee_index in get_committee_indices(committees_per_slot): - let committee = get_beacon_committee(epochRef, slot, committee_index) - for index_in_committee, validator_index in committee: - let curr_val_pubkey = epochRef.validatorKey(validator_index) - if curr_val_pubkey.isSome(): - if public_keys.findIt(it == curr_val_pubkey.get().toPubKey()) != -1: - result.add((public_key: curr_val_pubkey.get().toPubKey(), - validator_index: validator_index, - committee_index: committee_index, - committee_length: committee.lenu64, - validator_committee_index: index_in_committee.uint64, - slot: slot)) - - rpcServer.rpc("get_v1_validator_duties_proposer") do ( - epoch: Epoch) -> seq[RpcValidatorDuties]: - debug "get_v1_validator_duties_proposer", epoch = epoch - let - head = node.doChecksAndGetCurrentHead(epoch) - epochRef = block: - let tmp = node.dag.getEpochRef(head, epoch, true) - if isErr(tmp): - raise (ref CatchableError)(msg: "Trying to access pruned state") - tmp.get() - - for i, bp in epochRef.beacon_proposers: - if bp.isSome(): - result.add((public_key: epochRef.validatorKey(bp.get).get().toPubKey, - validator_index: bp.get(), - slot: epoch.start_slot() + i)) - - rpcServer.rpc("post_v1_validator_beacon_committee_subscriptions") do ( - committee_index: CommitteeIndex, slot: Slot, aggregator: bool, - validator_pubkey: ValidatorPubKey, slot_signature: ValidatorSig) -> bool: - debug "post_v1_validator_beacon_committee_subscriptions", - committee_index, slot - if committee_index.uint64 >= MAX_COMMITTEES_PER_SLOT.uint64: - raise newException(CatchableError, - "Invalid committee index") - - if node.syncManager.inProgress: - raise newException(CatchableError, - "Beacon node is currently syncing and not serving request on that endpoint") - - let wallSlot = node.beaconClock.now.slotOrZero - if wallSlot > slot + 1: - raise newException(CatchableError, - "Past slot requested") - - let epoch = slot.epoch - if epoch >= wallSlot.epoch and epoch - wallSlot.epoch > 1: - raise newException(CatchableError, - "Slot requested not in current or next wall-slot epoch") - - if not verify_slot_signature( - getStateField(node.dag.headState, fork), - getStateField(node.dag.headState, genesis_validators_root), - slot, validator_pubkey, slot_signature): - raise newException(CatchableError, - "Invalid slot signature") - - let - head = node.doChecksAndGetCurrentHead(epoch) - epochRef = block: - let tmp = node.dag.getEpochRef(head, epoch, true) - if isErr(tmp): - raise (ref CatchableError)(msg: "Trying to access pruned state") - tmp.get() - let - subnet_id = compute_subnet_for_attestation( - get_committee_count_per_slot(epochRef), slot, committee_index) - - # The validator index here is invalid, but since JSON-RPC is on its way - # to deprecation, this is fine - node.registerDuty( - slot, subnet_id, 0.ValidatorIndex, - is_aggregator(epochRef, slot, committee_index, slot_signature)) diff --git a/beacon_chain/spec/network.nim b/beacon_chain/spec/network.nim index 62a589f1f..e63e810ae 100644 --- a/beacon_chain/spec/network.nim +++ b/beacon_chain/spec/network.nim @@ -37,9 +37,6 @@ const defaultEth2TcpPort* = 9000 - # This is not part of the spec yet! Keep in sync with BASE_RPC_PORT - defaultEth2RpcPort* = 9190 - # This is not part of the spec! But its port which uses Lighthouse DefaultEth2RestPort* = 5052