adopt LC REST API with v0 suffix (without proofs) (#3775)
* adopt LC REST API with v0 suffix (without proofs) Adopts the light client data REST API used by Lodestar as defined in https://github.com/ethereum/beacon-APIs/pull/181 with a v0 suffix. Requests: - `/eth/v0/beacon/light_client/bootstrap/{block_root}` - `/eth/v0/beacon/light_client/updates?start_period={start_period}&count={count}` - `/eth/v0/beacon/light_client/finality_update` - `/eth/v0/beacon/light_client/optimistic_update` HTTP Server-Sent Events (SSE): - `light_client_finality_update_v0` - `light_client_optimistic_update_v0` More work is needed to adopt the proofs endpoint, it is not included. * initialize event queues * register event topics
This commit is contained in:
parent
5439978a37
commit
61ee0611bb
|
@ -21,7 +21,7 @@ import
|
||||||
./consensus_object_pools/[
|
./consensus_object_pools/[
|
||||||
blockchain_dag, block_quarantine, exit_pool, attestation_pool,
|
blockchain_dag, block_quarantine, exit_pool, attestation_pool,
|
||||||
sync_committee_msg_pool],
|
sync_committee_msg_pool],
|
||||||
./spec/datatypes/base,
|
./spec/datatypes/[base, altair],
|
||||||
./sync/[optimistic_sync_light_client, sync_manager, request_manager],
|
./sync/[optimistic_sync_light_client, sync_manager, request_manager],
|
||||||
./validators/[action_tracker, validator_monitor, validator_pool],
|
./validators/[action_tracker, validator_monitor, validator_pool],
|
||||||
./rpc/state_ttl_cache
|
./rpc/state_ttl_cache
|
||||||
|
@ -41,6 +41,8 @@ type
|
||||||
blocksQueue*: AsyncEventQueue[ForkedTrustedSignedBeaconBlock]
|
blocksQueue*: AsyncEventQueue[ForkedTrustedSignedBeaconBlock]
|
||||||
headQueue*: AsyncEventQueue[HeadChangeInfoObject]
|
headQueue*: AsyncEventQueue[HeadChangeInfoObject]
|
||||||
reorgQueue*: AsyncEventQueue[ReorgInfoObject]
|
reorgQueue*: AsyncEventQueue[ReorgInfoObject]
|
||||||
|
finUpdateQueue*: AsyncEventQueue[altair.LightClientFinalityUpdate]
|
||||||
|
optUpdateQueue*: AsyncEventQueue[altair.LightClientOptimisticUpdate]
|
||||||
attestQueue*: AsyncEventQueue[Attestation]
|
attestQueue*: AsyncEventQueue[Attestation]
|
||||||
contribQueue*: AsyncEventQueue[SignedContributionAndProof]
|
contribQueue*: AsyncEventQueue[SignedContributionAndProof]
|
||||||
exitQueue*: AsyncEventQueue[SignedVoluntaryExit]
|
exitQueue*: AsyncEventQueue[SignedVoluntaryExit]
|
||||||
|
|
|
@ -161,9 +161,9 @@ proc loadChainDag(
|
||||||
proc onChainReorg(data: ReorgInfoObject) =
|
proc onChainReorg(data: ReorgInfoObject) =
|
||||||
eventBus.reorgQueue.emit(data)
|
eventBus.reorgQueue.emit(data)
|
||||||
proc onLightClientFinalityUpdate(data: altair.LightClientFinalityUpdate) =
|
proc onLightClientFinalityUpdate(data: altair.LightClientFinalityUpdate) =
|
||||||
discard
|
eventBus.finUpdateQueue.emit(data)
|
||||||
proc onLightClientOptimisticUpdate(data: altair.LightClientOptimisticUpdate) =
|
proc onLightClientOptimisticUpdate(data: altair.LightClientOptimisticUpdate) =
|
||||||
discard
|
eventBus.optUpdateQueue.emit(data)
|
||||||
|
|
||||||
let
|
let
|
||||||
chainDagFlags =
|
chainDagFlags =
|
||||||
|
@ -374,6 +374,8 @@ proc init*(T: type BeaconNode,
|
||||||
blocksQueue: newAsyncEventQueue[ForkedTrustedSignedBeaconBlock](),
|
blocksQueue: newAsyncEventQueue[ForkedTrustedSignedBeaconBlock](),
|
||||||
headQueue: newAsyncEventQueue[HeadChangeInfoObject](),
|
headQueue: newAsyncEventQueue[HeadChangeInfoObject](),
|
||||||
reorgQueue: newAsyncEventQueue[ReorgInfoObject](),
|
reorgQueue: newAsyncEventQueue[ReorgInfoObject](),
|
||||||
|
finUpdateQueue: newAsyncEventQueue[altair.LightClientFinalityUpdate](),
|
||||||
|
optUpdateQueue: newAsyncEventQueue[altair.LightClientOptimisticUpdate](),
|
||||||
attestQueue: newAsyncEventQueue[Attestation](),
|
attestQueue: newAsyncEventQueue[Attestation](),
|
||||||
contribQueue: newAsyncEventQueue[SignedContributionAndProof](),
|
contribQueue: newAsyncEventQueue[SignedContributionAndProof](),
|
||||||
exitQueue: newAsyncEventQueue[SignedVoluntaryExit](),
|
exitQueue: newAsyncEventQueue[SignedVoluntaryExit](),
|
||||||
|
@ -1315,6 +1317,8 @@ proc installRestHandlers(restServer: RestServerRef, node: BeaconNode) =
|
||||||
restServer.router.installNimbusApiHandlers(node)
|
restServer.router.installNimbusApiHandlers(node)
|
||||||
restServer.router.installNodeApiHandlers(node)
|
restServer.router.installNodeApiHandlers(node)
|
||||||
restServer.router.installValidatorApiHandlers(node)
|
restServer.router.installValidatorApiHandlers(node)
|
||||||
|
if node.dag.lightClientDataServe:
|
||||||
|
restServer.router.installLightClientApiHandlers(node)
|
||||||
|
|
||||||
proc installMessageValidators(node: BeaconNode) =
|
proc installMessageValidators(node: BeaconNode) =
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#attestations-and-aggregation
|
# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/p2p-interface.md#attestations-and-aggregation
|
||||||
|
|
|
@ -1,22 +1,28 @@
|
||||||
# Copyright (c) 2018-2021 Status Research & Development GmbH
|
# beacon_chain
|
||||||
|
# Copyright (c) 2018-2022 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * 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).
|
# * 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.
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
## The `rest_api` module is a server implementation for the common REST API for
|
## The `rest_api` module is a server implementation for the common REST API for
|
||||||
## Ethereum 2 found at https://ethereum.github.io/eth2.0-APIs/#
|
## Ethereum 2 found at https://ethereum.github.io/eth2.0-APIs/#
|
||||||
## along with several nimbus-specific extensions. It is used by the validator
|
## along with several nimbus-specific extensions. It is used by the validator
|
||||||
## client as well as many community utilities.
|
## client as well as many community utilities.
|
||||||
## A corresponding client can be found in the
|
## A corresponding client can be found in the
|
||||||
## `spec/eth2_apis/rest_beacon_client` module
|
## `spec/eth2_apis/rest_beacon_client` module
|
||||||
|
|
||||||
import
|
import
|
||||||
"."/[
|
"."/[
|
||||||
rest_utils,
|
rest_utils,
|
||||||
rest_beacon_api, rest_config_api, rest_debug_api, rest_event_api,
|
rest_beacon_api, rest_config_api, rest_debug_api, rest_event_api,
|
||||||
rest_nimbus_api, rest_node_api, rest_validator_api, rest_key_management_api]
|
rest_key_management_api, rest_light_client_api, rest_nimbus_api,
|
||||||
|
rest_node_api, rest_validator_api]
|
||||||
|
|
||||||
export
|
export
|
||||||
rest_utils,
|
rest_utils,
|
||||||
rest_beacon_api, rest_config_api, rest_debug_api, rest_event_api,
|
rest_beacon_api, rest_config_api, rest_debug_api, rest_event_api,
|
||||||
rest_nimbus_api, rest_node_api, rest_validator_api, rest_key_management_api
|
rest_key_management_api, rest_light_client_api, rest_nimbus_api,
|
||||||
|
rest_node_api, rest_validator_api
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
# beacon_chain
|
||||||
|
# Copyright (c) 2021-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.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
../spec/beacon_time
|
../spec/beacon_time
|
||||||
|
|
||||||
|
@ -190,3 +199,19 @@ const
|
||||||
"Invalid Authorization Header"
|
"Invalid Authorization Header"
|
||||||
PrunedStateError* =
|
PrunedStateError* =
|
||||||
"Trying to access a pruned historical state"
|
"Trying to access a pruned historical state"
|
||||||
|
InvalidBlockRootValueError* =
|
||||||
|
"Invalid block root value"
|
||||||
|
InvalidSyncPeriodError* =
|
||||||
|
"Invalid sync committee period requested"
|
||||||
|
InvalidCountError* =
|
||||||
|
"Invalid count requested"
|
||||||
|
MissingStartPeriodValueError* =
|
||||||
|
"Missing `start_period` value"
|
||||||
|
MissingCountValueError* =
|
||||||
|
"Missing `count` value"
|
||||||
|
LCBootstrapUnavailable* =
|
||||||
|
"LC bootstrap unavailable"
|
||||||
|
LCFinUpdateUnavailable* =
|
||||||
|
"LC finality update unavailable"
|
||||||
|
LCOptUpdateUnavailable* =
|
||||||
|
"LC optimistic update unavailable"
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
# Copyright (c) 2018-2020 Status Research & Development GmbH
|
# beacon_chain
|
||||||
|
# Copyright (c) 2018-2022 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * 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).
|
# * 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.
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
stew/results,
|
stew/results,
|
||||||
chronicles,
|
chronicles,
|
||||||
|
@ -14,40 +17,20 @@ export rest_utils
|
||||||
|
|
||||||
logScope: topics = "rest_eventapi"
|
logScope: topics = "rest_eventapi"
|
||||||
|
|
||||||
proc validateEventTopics(events: seq[EventTopic]): Result[EventTopics,
|
proc validateEventTopics(events: seq[EventTopic],
|
||||||
cstring] =
|
withLightClient: bool): Result[EventTopics, cstring] =
|
||||||
const NonUniqueError = cstring("Event topics must be unique")
|
const NonUniqueError = cstring("Event topics must be unique")
|
||||||
|
const UnsupportedError = cstring("Unsupported event topic value")
|
||||||
var res: set[EventTopic]
|
var res: set[EventTopic]
|
||||||
for item in events:
|
for item in events:
|
||||||
case item
|
if item in res:
|
||||||
of EventTopic.Head:
|
return err(NonUniqueError)
|
||||||
if EventTopic.Head in res:
|
if not withLightClient and item in [
|
||||||
return err(NonUniqueError)
|
EventTopic.LightClientFinalityUpdate,
|
||||||
res.incl(EventTopic.Head)
|
EventTopic.LightClientOptimisticUpdate]:
|
||||||
of EventTopic.Block:
|
return err(UnsupportedError)
|
||||||
if EventTopic.Block in res:
|
res.incl(item)
|
||||||
return err(NonUniqueError)
|
|
||||||
res.incl(EventTopic.Block)
|
|
||||||
of EventTopic.Attestation:
|
|
||||||
if EventTopic.Attestation in res:
|
|
||||||
return err(NonUniqueError)
|
|
||||||
res.incl(EventTopic.Attestation)
|
|
||||||
of EventTopic.VoluntaryExit:
|
|
||||||
if EventTopic.VoluntaryExit in res:
|
|
||||||
return err(NonUniqueError)
|
|
||||||
res.incl(EventTopic.VoluntaryExit)
|
|
||||||
of EventTopic.FinalizedCheckpoint:
|
|
||||||
if EventTopic.FinalizedCheckpoint in res:
|
|
||||||
return err(NonUniqueError)
|
|
||||||
res.incl(EventTopic.FinalizedCheckpoint)
|
|
||||||
of EventTopic.ChainReorg:
|
|
||||||
if EventTopic.ChainReorg in res:
|
|
||||||
return err(NonUniqueError)
|
|
||||||
res.incl(EventTopic.ChainReorg)
|
|
||||||
of EventTopic.ContributionAndProof:
|
|
||||||
if EventTopic.ContributionAndProof in res:
|
|
||||||
return err(NonUniqueError)
|
|
||||||
res.incl(EventTopic.ContributionAndProof)
|
|
||||||
if res == {}:
|
if res == {}:
|
||||||
err("Empty topics list")
|
err("Empty topics list")
|
||||||
else:
|
else:
|
||||||
|
@ -105,6 +88,7 @@ proc eventHandler*[T](response: HttpResponseRef,
|
||||||
|
|
||||||
proc installEventApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
proc installEventApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||||
# https://ethereum.github.io/beacon-APIs/#/Events/eventstream
|
# https://ethereum.github.io/beacon-APIs/#/Events/eventstream
|
||||||
|
# https://github.com/ethereum/beacon-APIs/pull/181
|
||||||
router.api(MethodGet, "/eth/v1/events") do (
|
router.api(MethodGet, "/eth/v1/events") do (
|
||||||
topics: seq[EventTopic]) -> RestApiResponse:
|
topics: seq[EventTopic]) -> RestApiResponse:
|
||||||
let eventTopics =
|
let eventTopics =
|
||||||
|
@ -112,7 +96,8 @@ proc installEventApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||||
if topics.isErr():
|
if topics.isErr():
|
||||||
return RestApiResponse.jsonError(Http400, "Invalid topics value",
|
return RestApiResponse.jsonError(Http400, "Invalid topics value",
|
||||||
$topics.error())
|
$topics.error())
|
||||||
let res = validateEventTopics(topics.get())
|
let res = validateEventTopics(topics.get(),
|
||||||
|
node.dag.lightClientDataServe)
|
||||||
if res.isErr():
|
if res.isErr():
|
||||||
return RestApiResponse.jsonError(Http400, "Invalid topics value",
|
return RestApiResponse.jsonError(Http400, "Invalid topics value",
|
||||||
$res.error())
|
$res.error())
|
||||||
|
@ -164,6 +149,16 @@ proc installEventApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||||
let handler = response.eventHandler(node.eventBus.contribQueue,
|
let handler = response.eventHandler(node.eventBus.contribQueue,
|
||||||
"contribution_and_proof")
|
"contribution_and_proof")
|
||||||
res.add(handler)
|
res.add(handler)
|
||||||
|
if EventTopic.LightClientFinalityUpdate in eventTopics:
|
||||||
|
doAssert node.dag.lightClientDataServe
|
||||||
|
let handler = response.eventHandler(node.eventBus.finUpdateQueue,
|
||||||
|
"light_client_finality_update_v0")
|
||||||
|
res.add(handler)
|
||||||
|
if EventTopic.LightClientOptimisticUpdate in eventTopics:
|
||||||
|
doAssert node.dag.lightClientDataServe
|
||||||
|
let handler = response.eventHandler(node.eventBus.optUpdateQueue,
|
||||||
|
"light_client_optimistic_update_v0")
|
||||||
|
res.add(handler)
|
||||||
res
|
res
|
||||||
|
|
||||||
discard await one(handlers)
|
discard await one(handlers)
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
# beacon_chain
|
||||||
|
# Copyright (c) 2021-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.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
|
import chronicles
|
||||||
|
import ../beacon_node,
|
||||||
|
./rest_utils
|
||||||
|
|
||||||
|
logScope: topics = "rest_light_client"
|
||||||
|
|
||||||
|
proc installLightClientApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||||
|
# https://github.com/ethereum/beacon-APIs/pull/181
|
||||||
|
router.api(MethodGet,
|
||||||
|
"/eth/v0/beacon/light_client/bootstrap/{block_root}") do (
|
||||||
|
block_root: Eth2Digest) -> RestApiResponse:
|
||||||
|
doAssert node.dag.lightClientDataServe
|
||||||
|
let vroot = block:
|
||||||
|
if block_root.isErr():
|
||||||
|
return RestApiResponse.jsonError(Http400, InvalidBlockRootValueError,
|
||||||
|
$block_root.error())
|
||||||
|
block_root.get()
|
||||||
|
|
||||||
|
let bootstrap = node.dag.getLightClientBootstrap(vroot)
|
||||||
|
if bootstrap.isOk:
|
||||||
|
return RestApiResponse.jsonResponse(bootstrap)
|
||||||
|
else:
|
||||||
|
return RestApiResponse.jsonError(Http404, LCBootstrapUnavailable)
|
||||||
|
|
||||||
|
# https://github.com/ethereum/beacon-APIs/pull/181
|
||||||
|
router.api(MethodGet,
|
||||||
|
"/eth/v0/beacon/light_client/updates") do (
|
||||||
|
start_period: Option[SyncCommitteePeriod], count: Option[uint64]
|
||||||
|
) -> RestApiResponse:
|
||||||
|
doAssert node.dag.lightClientDataServe
|
||||||
|
let vstart = block:
|
||||||
|
if start_period.isNone():
|
||||||
|
return RestApiResponse.jsonError(Http400, MissingStartPeriodValueError)
|
||||||
|
let rstart = start_period.get()
|
||||||
|
if rstart.isErr():
|
||||||
|
return RestApiResponse.jsonError(Http400, InvalidSyncPeriodError,
|
||||||
|
$rstart.error())
|
||||||
|
rstart.get()
|
||||||
|
let vcount = block:
|
||||||
|
if count.isNone():
|
||||||
|
return RestApiResponse.jsonError(Http400, MissingCountValueError)
|
||||||
|
let rcount = count.get()
|
||||||
|
if rcount.isErr():
|
||||||
|
return RestApiResponse.jsonError(Http400, InvalidCountError,
|
||||||
|
$rcount.error())
|
||||||
|
rcount.get()
|
||||||
|
let
|
||||||
|
headPeriod = node.dag.head.slot.sync_committee_period
|
||||||
|
# Limit number of updates in response
|
||||||
|
maxSupportedCount =
|
||||||
|
if vstart > headPeriod:
|
||||||
|
0'u64
|
||||||
|
else:
|
||||||
|
min(headPeriod + 1 - vstart, MAX_REQUEST_LIGHT_CLIENT_UPDATES)
|
||||||
|
numPeriods = min(vcount, maxSupportedCount)
|
||||||
|
onePastPeriod = vstart + numPeriods
|
||||||
|
|
||||||
|
var updates = newSeqOfCap[LightClientUpdate](numPeriods)
|
||||||
|
for period in vstart..<onePastPeriod:
|
||||||
|
let update = node.dag.getLightClientUpdateForPeriod(period)
|
||||||
|
if update.isSome:
|
||||||
|
updates.add update.get
|
||||||
|
return RestApiResponse.jsonResponse(updates)
|
||||||
|
|
||||||
|
# https://github.com/ethereum/beacon-APIs/pull/181
|
||||||
|
router.api(MethodGet,
|
||||||
|
"/eth/v0/beacon/light_client/finality_update") do (
|
||||||
|
) -> RestApiResponse:
|
||||||
|
doAssert node.dag.lightClientDataServe
|
||||||
|
let finality_update = node.dag.getLightClientFinalityUpdate()
|
||||||
|
if finality_update.isSome:
|
||||||
|
return RestApiResponse.jsonResponse(finality_update)
|
||||||
|
else:
|
||||||
|
return RestApiResponse.jsonError(Http404, LCFinUpdateUnavailable)
|
||||||
|
|
||||||
|
# https://github.com/ethereum/beacon-APIs/pull/181
|
||||||
|
router.api(MethodGet,
|
||||||
|
"/eth/v0/beacon/light_client/optimistic_update") do (
|
||||||
|
) -> RestApiResponse:
|
||||||
|
doAssert node.dag.lightClientDataServe
|
||||||
|
let optimistic_update = node.dag.getLightClientOptimisticUpdate()
|
||||||
|
if optimistic_update.isSome:
|
||||||
|
return RestApiResponse.jsonResponse(optimistic_update)
|
||||||
|
else:
|
||||||
|
return RestApiResponse.jsonError(Http404, LCOptUpdateUnavailable)
|
|
@ -1,3 +1,12 @@
|
||||||
|
# beacon_chain
|
||||||
|
# Copyright (c) 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.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import std/[options, macros],
|
import std/[options, macros],
|
||||||
stew/byteutils, presto,
|
stew/byteutils, presto,
|
||||||
../spec/[forks],
|
../spec/[forks],
|
||||||
|
@ -37,6 +46,8 @@ proc validate(key: string, value: string): int =
|
||||||
0
|
0
|
||||||
of "{validator_id}":
|
of "{validator_id}":
|
||||||
0
|
0
|
||||||
|
of "{block_root}":
|
||||||
|
0
|
||||||
else:
|
else:
|
||||||
1
|
1
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# beacon_chain
|
||||||
# Copyright (c) 2018-2022 Status Research & Development GmbH
|
# Copyright (c) 2018-2022 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||||
|
@ -2147,6 +2148,10 @@ proc decodeString*(t: typedesc[EventTopic],
|
||||||
ok(EventTopic.ChainReorg)
|
ok(EventTopic.ChainReorg)
|
||||||
of "contribution_and_proof":
|
of "contribution_and_proof":
|
||||||
ok(EventTopic.ContributionAndProof)
|
ok(EventTopic.ContributionAndProof)
|
||||||
|
of "light_client_finality_update_v0":
|
||||||
|
ok(EventTopic.LightClientFinalityUpdate)
|
||||||
|
of "light_client_optimistic_update_v0":
|
||||||
|
ok(EventTopic.LightClientOptimisticUpdate)
|
||||||
else:
|
else:
|
||||||
err("Incorrect event's topic value")
|
err("Incorrect event's topic value")
|
||||||
|
|
||||||
|
@ -2186,6 +2191,11 @@ proc decodeString*(t: typedesc[Epoch], value: string): Result[Epoch, cstring] =
|
||||||
let res = ? Base10.decode(uint64, value)
|
let res = ? Base10.decode(uint64, value)
|
||||||
ok(Epoch(res))
|
ok(Epoch(res))
|
||||||
|
|
||||||
|
proc decodeString*(t: typedesc[SyncCommitteePeriod],
|
||||||
|
value: string): Result[SyncCommitteePeriod, cstring] =
|
||||||
|
let res = ? Base10.decode(uint64, value)
|
||||||
|
ok(SyncCommitteePeriod(res))
|
||||||
|
|
||||||
proc decodeString*(t: typedesc[uint64],
|
proc decodeString*(t: typedesc[uint64],
|
||||||
value: string): Result[uint64, cstring] =
|
value: string): Result[uint64, cstring] =
|
||||||
Base10.decode(uint64, value)
|
Base10.decode(uint64, value)
|
||||||
|
|
|
@ -33,7 +33,7 @@ const
|
||||||
type
|
type
|
||||||
EventTopic* {.pure.} = enum
|
EventTopic* {.pure.} = enum
|
||||||
Head, Block, Attestation, VoluntaryExit, FinalizedCheckpoint, ChainReorg,
|
Head, Block, Attestation, VoluntaryExit, FinalizedCheckpoint, ChainReorg,
|
||||||
ContributionAndProof
|
ContributionAndProof, LightClientFinalityUpdate, LightClientOptimisticUpdate
|
||||||
|
|
||||||
EventTopics* = set[EventTopic]
|
EventTopics* = set[EventTopic]
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@ import
|
||||||
../spec/[helpers, forks, network],
|
../spec/[helpers, forks, network],
|
||||||
".."/[beacon_clock],
|
".."/[beacon_clock],
|
||||||
../networking/eth2_network,
|
../networking/eth2_network,
|
||||||
../consensus_object_pools/blockchain_dag
|
../consensus_object_pools/blockchain_dag,
|
||||||
|
../rpc/rest_constants
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "sync"
|
topics = "sync"
|
||||||
|
@ -548,8 +549,7 @@ p2pProtocol BeaconSync(version = 1,
|
||||||
await response.send(bootstrap.get, contextBytes)
|
await response.send(bootstrap.get, contextBytes)
|
||||||
else:
|
else:
|
||||||
peer.updateRequestQuota(lightClientEmptyResponseCost)
|
peer.updateRequestQuota(lightClientEmptyResponseCost)
|
||||||
raise newException(
|
raise newException(ResourceUnavailableError, LCBootstrapUnavailable)
|
||||||
ResourceUnavailableError, "LC bootstrap unavailable")
|
|
||||||
|
|
||||||
peer.updateRequestQuota(lightClientBootstrapResponseCost)
|
peer.updateRequestQuota(lightClientBootstrapResponseCost)
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ p2pProtocol BeaconSync(version = 1,
|
||||||
|
|
||||||
peer.awaitNonNegativeRequestQuota()
|
peer.awaitNonNegativeRequestQuota()
|
||||||
|
|
||||||
let finality_update = dag.getLightClientFinalityUpdate
|
let finality_update = dag.getLightClientFinalityUpdate()
|
||||||
if finality_update.isSome:
|
if finality_update.isSome:
|
||||||
let
|
let
|
||||||
contextEpoch = finality_update.get.attested_header.slot.epoch
|
contextEpoch = finality_update.get.attested_header.slot.epoch
|
||||||
|
@ -617,8 +617,7 @@ p2pProtocol BeaconSync(version = 1,
|
||||||
await response.send(finality_update.get, contextBytes)
|
await response.send(finality_update.get, contextBytes)
|
||||||
else:
|
else:
|
||||||
peer.updateRequestQuota(lightClientEmptyResponseCost)
|
peer.updateRequestQuota(lightClientEmptyResponseCost)
|
||||||
raise newException(ResourceUnavailableError,
|
raise newException(ResourceUnavailableError, LCFinUpdateUnavailable)
|
||||||
"LC finality update unavailable")
|
|
||||||
|
|
||||||
peer.updateRequestQuota(lightClientFinalityUpdateResponseCost)
|
peer.updateRequestQuota(lightClientFinalityUpdateResponseCost)
|
||||||
|
|
||||||
|
@ -636,7 +635,7 @@ p2pProtocol BeaconSync(version = 1,
|
||||||
|
|
||||||
peer.awaitNonNegativeRequestQuota()
|
peer.awaitNonNegativeRequestQuota()
|
||||||
|
|
||||||
let optimistic_update = dag.getLightClientOptimisticUpdate
|
let optimistic_update = dag.getLightClientOptimisticUpdate()
|
||||||
if optimistic_update.isSome:
|
if optimistic_update.isSome:
|
||||||
let
|
let
|
||||||
contextEpoch = optimistic_update.get.attested_header.slot.epoch
|
contextEpoch = optimistic_update.get.attested_header.slot.epoch
|
||||||
|
@ -644,8 +643,7 @@ p2pProtocol BeaconSync(version = 1,
|
||||||
await response.send(optimistic_update.get, contextBytes)
|
await response.send(optimistic_update.get, contextBytes)
|
||||||
else:
|
else:
|
||||||
peer.updateRequestQuota(lightClientEmptyResponseCost)
|
peer.updateRequestQuota(lightClientEmptyResponseCost)
|
||||||
raise newException(ResourceUnavailableError,
|
raise newException(ResourceUnavailableError, LCOptUpdateUnavailable)
|
||||||
"LC optimistic update unavailable")
|
|
||||||
|
|
||||||
peer.updateRequestQuota(lightClientOptimisticUpdateResponseCost)
|
peer.updateRequestQuota(lightClientOptimisticUpdateResponseCost)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue