remove JSON-RPC consensus layer API client (#3676)

* remove JSON-RPC consensus layer API client

* rm eth2_json_rpc_serialization
This commit is contained in:
tersec 2022-05-31 11:05:15 +00:00 committed by GitHub
parent 01efa93cf6
commit 48f9631ed1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 5 additions and 446 deletions

View File

@ -639,10 +639,6 @@ type
desc: "URL of the beacon node REST service"
name: "rest-url" }: Option[Uri]
rpcUrlForExit* {.
desc: "URL of the beacon node JSON-RPC service"
name: "rpc-url" }: Option[Uri]
of BNStartUpCmd.record:
case recordCmd* {.command.}: RecordCmd
of RecordCmd.create:

View File

@ -9,7 +9,7 @@
import
std/[os, sequtils, times],
bearssl, chronicles,
./spec/eth2_apis/[rpc_beacon_client, rest_beacon_client],
./spec/eth2_apis/rest_beacon_client,
./spec/signatures,
./validators/keystore_management,
"."/[conf, beacon_clock, filepath]
@ -108,85 +108,6 @@ proc askForExitConfirmation(): ClientExitAction =
else:
ClientExitAction.quiting
proc rpcValidatorExit(config: BeaconNodeConf) {.async.} =
warn "The JSON-PRC API is deprecated. Consider using the REST API"
let port = try:
let value = parseInt(config.rpcUrlForExit.get.port)
if value < Port.low.int or value > Port.high.int:
raise newException(ValueError,
"The port number must be between " & $Port.low & " and " & $Port.high)
Port value
except CatchableError as err:
fatal "Invalid port number", err = err.msg
quit 1
let rpcClient = newRpcHttpClient()
try:
await connect(rpcClient, config.rpcUrlForExit.get.hostname, port,
secure = config.rpcUrlForExit.get.scheme in ["https", "wss"])
except CatchableError as err:
fatal "Failed to connect to the beacon node RPC service", err = err.msg
quit 1
let (validator, validatorIdx, _, _) = try:
await rpcClient.get_v1_beacon_states_stateId_validators_validatorId(
"head", config.exitedValidator)
except CatchableError as err:
fatal "Failed to obtain information for validator", err = err.msg
quit 1
let exitAtEpoch = if config.exitAtEpoch.isSome:
Epoch config.exitAtEpoch.get
else:
let headSlot = try:
await rpcClient.getBeaconHead()
except CatchableError as err:
fatal "Failed to obtain the current head slot", err = err.msg
quit 1
headSlot.epoch
let fork = try:
await rpcClient.get_v1_beacon_states_fork("head")
except CatchableError as err:
fatal "Failed to obtain the fork id of the head state", err = err.msg
quit 1
let genesis_validators_root = try:
(await rpcClient.get_v1_beacon_genesis()).genesis_validators_root
except CatchableError as err:
fatal "Failed to obtain the genesis validators root of the network",
err = err.msg
quit 1
let
validatorKeyAsStr = "0x" & $validator.pubkey
signedExit = getSignedExitMessage(config,
validatorKeyAsStr,
exitAtEpoch,
validatorIdx,
fork,
genesis_validators_root)
try:
let choice = askForExitConfirmation()
if choice == ClientExitAction.quiting:
quit 0
elif choice == ClientExitAction.confirmation:
let success = await rpcClient.post_v1_beacon_pool_voluntary_exits(signedExit)
if success:
echo "Successfully published voluntary exit for validator " &
$validatorIdx & "(" & validatorKeyAsStr[0..9] & ")."
quit 0
else:
echo "The voluntary exit was not submitted successfully. Please try again."
quit 1
except CatchableError as err:
fatal "Failed to send the signed exit message to the beacon node RPC",
err = err.msg
quit 1
proc restValidatorExit(config: BeaconNodeConf) {.async.} =
let
address = if isNone(config.restUrlForExit):
@ -327,12 +248,7 @@ proc restValidatorExit(config: BeaconNodeConf) {.async.} =
quit 1
proc handleValidatorExitCommand(config: BeaconNodeConf) {.async.} =
if isSome(config.restUrlForExit):
await restValidatorExit(config)
elif isSome(config.rpcUrlForExit):
await rpcValidatorExit(config)
else:
await restValidatorExit(config)
await restValidatorExit(config)
proc doDeposits*(config: BeaconNodeConf, rng: var BrHmacDrbgContext) {.
raises: [Defect, CatchableError].} =

View File

@ -1,150 +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].}
# The serializations in this file are approximations of
# https://ethereum.github.io/eth2.0-APIs/#/ but where written before the standard
# had materialized - they've now made it out to releases which means the easiest
# thing to do is to maintain them as-is, even if there are mismatches. In
# particular, numbers are serialized as strings in the eth2 API - here, they
# use numbers instead.
#
# Using numbers creates problems - uint64 which often appears in eth2 can't
# portably be represented since many json parsers balk at anything >2^53 and
# start losing precision. The other issue is the json parser in nim - it can't
# handle numbers >2^63, either crashing or giving wrong results:
# https://github.com/status-im/nimbus-eth2/issues/2430
import
# Standard library
std/[typetraits],
# Nimble packages
stew/byteutils,
json_rpc/jsonmarshal,
ssz_serialization/types,
# Local modules
../datatypes/base
export jsonmarshal, base
proc toJsonHex(data: openArray[byte]): string =
# Per the eth2 API spec, hex arrays are printed with leading 0x
"0x" & toHex(data)
proc fromJson*(n: JsonNode, argName: string, result: var ValidatorPubKey) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
result = ValidatorPubKey.fromHex(n.getStr()).tryGet()
proc `%`*(pubkey: ValidatorPubKey): JsonNode =
newJString(toJsonHex(toRaw(pubkey)))
proc fromJson*(n: JsonNode, argName: string, result: var List) {.raises: [Defect, ValueError].} =
fromJson(n, argName, asSeq result)
proc `%`*(list: List): JsonNode = %(asSeq(list))
proc fromJson*(n: JsonNode, argName: string, result: var BitList) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
result = type(result)(hexToSeqByte(n.getStr()))
proc `%`*(bitlist: BitList): JsonNode =
newJString(toJsonHex(seq[byte](BitSeq(bitlist))))
proc fromJson*(n: JsonNode, argName: string, result: var ValidatorSig) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
result = ValidatorSig.fromHex(n.getStr()).tryGet()
proc `%`*(value: ValidatorSig): JsonNode =
newJString(toJsonHex(toRaw(value)))
proc fromJson*(n: JsonNode, argName: string, result: var TrustedSig) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
hexToByteArray(n.getStr(), result.data)
proc `%`*(value: TrustedSig): JsonNode =
newJString(toJsonHex(toRaw(value)))
proc fromJson*(n: JsonNode, argName: string, result: var Version) {.raises: [Defect, ValueError].} =
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)))
template genFromJsonForIntType(T: untyped) =
proc fromJson*(n: JsonNode, argName: string, result: var T) {.raises: [Defect, ValueError].} =
n.kind.expect(JInt, argName)
let asInt = n.getBiggestInt()
when T is Epoch:
if asInt == -1:
# TODO: This is a major hack here. Since the json library
# cannot handle properly 0xffffffff when serializing and
# deserializing uint64 values, we detect one known wrong
# result, appering in most `Validator` records. To fix
# this issue, we'll have to switch to nim-json-serialization
# in nim-json-rpc or work towards implementing a fix upstream.
result = FAR_FUTURE_EPOCH
return
if asInt < 0:
# signed -> unsigned conversions are unchecked
# https://github.com/nim-lang/RFCs/issues/175
raise newException(
ValueError, "JSON-RPC input is an unexpected negative value")
result = T(asInt)
genFromJsonForIntType(Epoch)
genFromJsonForIntType(Slot)
genFromJsonForIntType(CommitteeIndex)
genFromJsonForIntType(ValidatorIndex)
proc `%`*(value: Epoch): JsonNode =
# In nim <= 1.2.6, `uint64` was silently cast to int64 resulting in
# FAR_FUTURE_EPOCH showing as -1 - this is a hack to maintain that behaviour
# in a world where a Defect or an actual correct value is used - the eth2
# REST api instead prints all epochs and similar large numbers as strings!
# See also https://github.com/status-im/nimbus-eth2/issues/2430
newJInt(cast[int64](value))
proc `%`*(value: Slot): JsonNode =
newJInt(cast[int64](value))
proc `%`*(value: GraffitiBytes): JsonNode =
newJString(toJsonHex(distinctBase(value)))
proc fromJson*(n: JsonNode, argName: string, value: var GraffitiBytes) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
value = GraffitiBytes.init n.getStr()
proc `%`*(value: CommitteeIndex): JsonNode =
newJInt(value.BiggestInt)
proc `%`*(value: ValidatorIndex): JsonNode =
newJInt(value.BiggestInt)
proc `%`*(value: Eth2Digest): JsonNode =
newJString(toJsonHex(value.data))
proc fromJson*(n: JsonNode, argName: string, result: var Eth2Digest) {.raises: [Defect, ValueError].} =
n.kind.expect(JString, argName)
hexToByteArray(n.getStr(), result.data)
proc `%`*(value: BitSeq): JsonNode =
newJString(toJsonHex(value.bytes))
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)]))

View File

@ -1,59 +0,0 @@
import
options,
rpc_types,
../datatypes/phase0
proc get_v1_beacon_genesis(): RpcBeaconGenesis
# TODO stateId is part of the REST path
proc get_v1_beacon_states_root(stateId: string): Eth2Digest
# TODO stateId is part of the REST path
proc get_v1_beacon_states_fork(stateId: string): Fork
# TODO stateId is part of the REST path
proc get_v1_beacon_states_finality_checkpoints(
stateId: string): RpcBeaconStatesFinalityCheckpoints
# TODO stateId is part of the REST path
proc get_v1_beacon_states_stateId_validators(
stateId: string, validatorIds: seq[string],
status: string): seq[RpcBeaconStatesValidators]
# TODO stateId and validatorId are part of the REST path
proc get_v1_beacon_states_stateId_validators_validatorId(
stateId: string, validatorId: string): RpcBeaconStatesValidators
# TODO stateId and epoch are part of the REST path
proc get_v1_beacon_states_stateId_committees_epoch(stateId: string,
epoch: uint64, index: uint64, slot: uint64): seq[RpcBeaconStatesCommittees]
proc get_v1_beacon_headers(slot: uint64, parent_root: Eth2Digest): seq[RpcBeaconHeaders]
# TODO blockId is part of the REST path
proc get_v1_beacon_headers_blockId(blockId: string):
tuple[canonical: bool, header: SignedBeaconBlockHeader]
# TODO blockId is part of the REST path
proc get_v1_beacon_blocks_blockId(blockId: string): phase0.SignedBeaconBlock
# TODO blockId is part of the REST path
proc get_v1_beacon_blocks_blockId_root(blockId: string): Eth2Digest
# TODO blockId is part of the REST path
proc get_v1_beacon_blocks_blockId_attestations(blockId: string): seq[Attestation]
# TODO POST /v1/beacon/pool/attester_slashings
# TODO POST /v1/beacon/pool/proposer_slashings
# TODO POST /v1/beacon/pool/attestations
proc get_v1_beacon_pool_attestations(slot: Option[uint64], committee_index: Option[uint64]): seq[RpcAttestation]
proc post_v1_beacon_pool_attestations(attestation: Attestation): bool
proc get_v1_beacon_pool_attester_slashings(): seq[AttesterSlashing]
proc get_v1_beacon_pool_proposer_slashings(): seq[ProposerSlashing]
proc get_v1_beacon_pool_voluntary_exits(): seq[VoluntaryExit]
proc post_v1_beacon_pool_voluntary_exits(exit: SignedVoluntaryExit): bool
proc get_v1_config_fork_schedule(): seq[Fork]

View File

@ -1,16 +0,0 @@
import
std/os,
json_rpc/rpcclient,
"."/[rpc_types, eth2_json_rpc_serialization],
../datatypes/[phase0, altair]
export
rpcclient,
rpc_types,
eth2_json_rpc_serialization
createRpcSigs(RpcClient, currentSourcePath.parentDir / "rpc_beacon_calls.nim")
createRpcSigs(RpcClient, currentSourcePath.parentDir / "rpc_debug_calls.nim")
createRpcSigs(RpcClient, currentSourcePath.parentDir / "rpc_nimbus_calls.nim")
createRpcSigs(RpcClient, currentSourcePath.parentDir / "rpc_node_calls.nim")
createRpcSigs(RpcClient, currentSourcePath.parentDir / "rpc_validator_calls.nim")

View File

@ -1,8 +0,0 @@
import
rpc_types,
../datatypes/phase0
export rpc_types
proc get_v1_debug_beacon_states_stateId(stateId: string): phase0.BeaconState
proc get_v1_debug_beacon_heads(): seq[tuple[root: Eth2Digest, slot: Slot]]

View File

@ -1,17 +0,0 @@
import
rpc_types
export rpc_types
proc getBeaconHead(): Slot
proc getChainHead(): JsonNode
proc getSyncing(): bool
proc getNetworkPeerId(): string
proc getNetworkPeers(): seq[string]
proc getNodeVersion(): string
proc peers(): JsonNode
proc setLogLevel(level: string)
proc getEth1Chain(): JsonNode
proc getEth1ProposalData(): JsonNode
proc getChronosFutures(): JsonNode
proc getGossipSubPeers(): JsonNode

View File

@ -1,11 +0,0 @@
import
options,
rpc_types
proc get_v1_node_identity(): RpcNodeIdentity
proc get_v1_node_version(): JsonNode
proc get_v1_node_syncing(): RpcSyncInfo
proc get_v1_node_health(): JsonNode
proc get_v1_node_peers(state: Option[seq[string]],
direction: Option[seq[string]]): seq[RpcNodePeer]

View File

@ -1,67 +1,16 @@
# beacon_chain
# Copyright (c) 2018-2021 Status Research & Development GmbH
# Copyright (c) 2018-2022 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.
# Types used in the JSON-RPC (legacy) API - these are generally derived from
# the common REST API, https://ethereum.github.io/eth2.0-APIs/#/
{.push raises: [Defect].}
import
../datatypes/[phase0, altair]
export phase0, altair
import ../datatypes/base
export base
type
RpcAttesterDuties* = tuple
public_key: ValidatorPubKey
validator_index: ValidatorIndex
committee_index: CommitteeIndex
committee_length: uint64
validator_committee_index: uint64
slot: Slot
RpcValidatorDuties* = tuple
public_key: ValidatorPubKey
validator_index: ValidatorIndex
slot: Slot
RpcBeaconGenesis* = tuple
genesis_time: uint64
genesis_validators_root: Eth2Digest
genesis_fork_version: Version
RpcBeaconStatesFinalityCheckpoints* = tuple
previous_justified: Checkpoint
current_justified: Checkpoint
finalized: Checkpoint
RpcBeaconStatesValidators* = tuple
validator: Validator
index: uint64
status: string
balance: uint64
RpcBeaconStatesCommittees* = tuple
index: uint64
slot: uint64
validators: seq[uint64] # each object in the sequence should have an index field...
RpcBeaconHeaders* = tuple
root: Eth2Digest
canonical: bool
header: SignedBeaconBlockHeader
RpcNodeIdentity* = tuple
peer_id: string
enr: string
p2p_addresses: seq[string]
discovery_addresses: seq[string]
metadata: tuple[seq_number: uint64, attnets: string]
RpcNodePeer* = tuple
peer_id: string
enr: string
@ -71,21 +20,6 @@ type
agent: string # This is not part of specification
proto: string # This is not part of specification
RpcNodePeerCount* = tuple
disconnected: int
connecting: int
connected: int
disconnecting: int
RpcAttestation* = tuple
aggregation_bits: string
data: AttestationData
signature: ValidatorSig
RpcBalance* = tuple
index: uint64
balance: uint64
RpcSyncInfo* = tuple
head_slot: Slot
sync_distance: uint64

View File

@ -1,26 +0,0 @@
import
options,
rpc_types
# calls that return a bool are actually without a return type in the main REST API
# spec but nim-json-rpc requires that all RPC calls have a return type.
proc get_v1_validator_block(slot: Slot, graffiti: GraffitiBytes, randao_reveal: ValidatorSig): phase0.BeaconBlock
proc get_v1_validator_attestation_data(slot: Slot, committee_index: CommitteeIndex): AttestationData
proc get_v1_validator_aggregate_attestation(slot: Slot, attestation_data_root: Eth2Digest): Attestation
proc post_v1_validator_aggregate_and_proofs(payload: SignedAggregateAndProof): bool
# TODO epoch is part of the REST path
proc get_v1_validator_duties_attester(epoch: Epoch, public_keys: seq[ValidatorPubKey]): seq[RpcAttesterDuties]
# TODO epoch is part of the REST path
proc get_v1_validator_duties_proposer(epoch: Epoch): seq[RpcValidatorDuties]
proc post_v1_validator_beacon_committee_subscriptions(committee_index: CommitteeIndex,
slot: Slot,
aggregator: bool,
validator_pubkey: ValidatorPubKey,
slot_signature: ValidatorSig): bool