Skip to content

Commit

Permalink
libp2p light client gossip validation
Browse files Browse the repository at this point in the history
When `--serve-light-client-data` is specified, provides stability on the
`optimistic_light_client_update` GossipSub topic.
  • Loading branch information
etan-status committed Mar 11, 2022
1 parent ae408c2 commit 0adc54b
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 0 deletions.
29 changes: 29 additions & 0 deletions beacon_chain/gossip_processing/eth2_processor.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

{.push raises: [Defect].}

# References to `vFuture` refer to the pre-release proposal of the libp2p based
# light client sync protocol. Conflicting release versions are not in use.
# https://github.com/ethereum/consensus-specs/pull/2802

import
std/tables,
stew/results, bearssl,
Expand Down Expand Up @@ -58,6 +62,10 @@ declareCounter beacon_sync_committee_contributions_received,
"Number of valid sync committee contributions processed by this node"
declareCounter beacon_sync_committee_contributions_dropped,
"Number of invalid sync committee contributions dropped by this node", labels = ["reason"]
declareCounter beacon_optimistic_light_client_updates_received,
"Number of valid optimistic light client updates processed by this node"
declareCounter beacon_optimistic_light_client_updates_dropped,
"Number of invalid optimistic light client updates dropped by this node", labels = ["reason"]

const delayBuckets = [2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, Inf]

Expand Down Expand Up @@ -529,3 +537,24 @@ proc contributionValidator*(
beacon_sync_committee_contributions_dropped.inc(1, [$v.error[0]])

err(v.error())

# https://github.com/ethereum/consensus-specs/blob/vFuture/specs/altair/sync-protocol.md#optimistic_light_client_update
proc optimisticLightClientUpdateValidator*(
self: var Eth2Processor, src: MsgSource,
optimistic_update: OptimisticLightClientUpdate
): Result[void, ValidationError] =
logScope:
optimistic_update

debug "Optimistic light client update received"

let v = self.dag.validateOptimisticLightClientUpdate(optimistic_update)
if v.isOk():
trace "Optimistic light client update validated"

beacon_optimistic_light_client_updates_received.inc()
else:
debug "Dropping optimistic light client update", error = v.error
beacon_optimistic_light_client_updates_dropped.inc(1, [$v.error[0]])

v
21 changes: 21 additions & 0 deletions beacon_chain/gossip_processing/gossip_validation.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

{.push raises: [Defect].}

# References to `vFuture` refer to the pre-release proposal of the libp2p based
# light client sync protocol. Conflicting release versions are not in use.
# https://github.com/ethereum/consensus-specs/pull/2802

import
# Status
chronicles, chronos, metrics,
Expand Down Expand Up @@ -1028,3 +1032,20 @@ proc validateContribution*(
sig.get()

return ok((sig, participants))

# https://github.com/ethereum/consensus-specs/blob/vFuture/specs/altair/sync-protocol.md#optimistic_light_client_update
proc validateOptimisticLightClientUpdate*(
dag: ChainDAGRef, optimistic_update: OptimisticLightClientUpdate):
Result[void, ValidationError] =
template local_update(): auto = dag.lightClientCache.optimisticUpdate

if optimistic_update != local_update:
# [IGNORE] The optimistic update is not attesting to the latest block's
# parent block.
if optimistic_update.attested_header != local_update.attested_header:
return errIgnore("OptimisticLightClientUpdate: not attesting to latest")

# [REJECT] The optimistic update does not match the expected value.
return errReject("OptimisticLightClientUpdate: not matching expected value")

ok()
22 changes: 22 additions & 0 deletions beacon_chain/nimbus_beacon_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,10 @@ proc addAltairMessageHandlers(node: BeaconNode, forkDigest: ForkDigest, slot: Sl

node.network.updateSyncnetsMetadata(currentSyncCommitteeSubnets)

if node.config.serveLightClientData:
node.network.subscribe(
getOptimisticLightClientUpdateTopic(forkDigest), basicParams)

proc removeAltairMessageHandlers(node: BeaconNode, forkDigest: ForkDigest) =
node.removePhase0MessageHandlers(forkDigest)

Expand All @@ -825,6 +829,9 @@ proc removeAltairMessageHandlers(node: BeaconNode, forkDigest: ForkDigest) =
node.network.unsubscribe(
getSyncCommitteeContributionAndProofTopic(forkDigest))

if node.config.serveLightClientData:
node.network.unsubscribe(getOptimisticLightClientUpdateTopic(forkDigest))

proc trackCurrentSyncCommitteeTopics(node: BeaconNode, slot: Slot) =
# Unlike trackNextSyncCommitteeTopics, just snap to the currently correct
# set of subscriptions, and use current_sync_committee. Furthermore, this
Expand Down Expand Up @@ -1323,6 +1330,21 @@ proc installMessageValidators(node: BeaconNode) =
installSyncCommitteeeValidators(node.dag.forkDigests.altair)
installSyncCommitteeeValidators(node.dag.forkDigests.bellatrix)

template installOptimisticLightClientUpdateValidator(digest: auto) =
node.network.addValidator(
getOptimisticLightClientUpdateTopic(digest),
proc(msg: OptimisticLightClientUpdate): ValidationResult =
if node.config.serveLightClientData:
toValidationResult(
node.processor[].optimisticLightClientUpdateValidator(
MsgSource.gossip, msg))
else:
debug "Ignoring optimistic light client update: Feature disabled"
ValidationResult.Ignore)

installOptimisticLightClientUpdateValidator(node.dag.forkDigests.altair)
installOptimisticLightClientUpdateValidator(node.dag.forkDigests.bellatrix)

proc stop(node: BeaconNode) =
bnStatus = BeaconNodeStatus.Stopping
notice "Graceful shutdown"
Expand Down
9 changes: 9 additions & 0 deletions beacon_chain/spec/network.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

{.push raises: [Defect].}

# References to `vFuture` refer to the pre-release proposal of the libp2p based
# light client sync protocol. Conflicting release versions are not in use.
# https://github.com/ethereum/consensus-specs/pull/2802

import
"."/[helpers, forks],
"."/datatypes/base
Expand Down Expand Up @@ -94,6 +98,11 @@ func getSyncCommitteeContributionAndProofTopic*(forkDigest: ForkDigest): string
## For subscribing and unsubscribing to/from a subnet.
eth2Prefix(forkDigest) & "sync_committee_contribution_and_proof/ssz_snappy"

# https://github.com/ethereum/consensus-specs/blob/vFuture/specs/altair/sync-protocol.md#optimistic_light_client_update
func getOptimisticLightClientUpdateTopic*(forkDigest: ForkDigest): string =
## For broadcasting or obtaining the latest `OptimisticLightClientUpdate`.
eth2Prefix(forkDigest) & "optimistic_light_client_update/ssz_snappy"

func getENRForkID*(cfg: RuntimeConfig,
epoch: Epoch,
genesis_validators_root: Eth2Digest): ENRForkID =
Expand Down

0 comments on commit 0adc54b

Please sign in to comment.