libp2p light client gossip validation (#3486)

When `--serve-light-client-data` is specified, provides stability on the
`optimistic_light_client_update` GossipSub topic.
This commit is contained in:
Etan Kissling 2022-03-14 14:05:38 +01:00 committed by GitHub
parent f550eb2f17
commit a08114e996
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 0 deletions

View File

@ -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,
@ -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]
@ -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

View File

@ -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,
@ -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()

View File

@ -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)
@ -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
@ -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"

View File

@ -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
@ -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_v0/ssz_snappy"
func getENRForkID*(cfg: RuntimeConfig,
epoch: Epoch,
genesis_validators_root: Eth2Digest): ENRForkID =