remove some unused imports, add tests for pubsub topics, and subscribe to interop attestations

This commit is contained in:
Dustin Brody 2020-05-14 13:19:10 +02:00 committed by zah
parent 6c9e2d98a8
commit 57519bebac
8 changed files with 128 additions and 62 deletions

View File

@ -67,9 +67,10 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
OK: 4/4 Fail: 0/4 Skip: 0/4 OK: 4/4 Fail: 0/4 Skip: 0/4
## Honest validator ## Honest validator
```diff ```diff
+ Attestation topics OK + General pubsub topics: OK
+ Mainnet attestation topics OK
``` ```
OK: 1/1 Fail: 0/1 Skip: 0/1 OK: 2/2 Fail: 0/2 Skip: 0/2
## Interop ## Interop
```diff ```diff
+ Interop genesis OK + Interop genesis OK
@ -241,4 +242,4 @@ OK: 4/4 Fail: 0/4 Skip: 0/4
OK: 8/8 Fail: 0/8 Skip: 0/8 OK: 8/8 Fail: 0/8 Skip: 0/8
---TOTAL--- ---TOTAL---
OK: 148/151 Fail: 3/151 Skip: 0/151 OK: 149/152 Fail: 3/152 Skip: 0/152

View File

@ -84,9 +84,10 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
OK: 4/4 Fail: 0/4 Skip: 0/4 OK: 4/4 Fail: 0/4 Skip: 0/4
## Honest validator ## Honest validator
```diff ```diff
+ Attestation topics OK + General pubsub topics: OK
+ Mainnet attestation topics OK
``` ```
OK: 1/1 Fail: 0/1 Skip: 0/1 OK: 2/2 Fail: 0/2 Skip: 0/2
## Interop ## Interop
```diff ```diff
+ Interop genesis OK + Interop genesis OK
@ -258,4 +259,4 @@ OK: 4/4 Fail: 0/4 Skip: 0/4
OK: 8/8 Fail: 0/8 Skip: 0/8 OK: 8/8 Fail: 0/8 Skip: 0/8
---TOTAL--- ---TOTAL---
OK: 157/160 Fail: 3/160 Skip: 0/160 OK: 158/161 Fail: 3/161 Skip: 0/161

View File

@ -666,6 +666,48 @@ proc installRpcHandlers(rpcServer: RpcServer, node: BeaconNode) =
rpcServer.installBeaconApiHandlers(node) rpcServer.installBeaconApiHandlers(node)
rpcServer.installDebugApiHandlers(node) rpcServer.installDebugApiHandlers(node)
proc installAttestationHandlers(node: BeaconNode) =
proc attestationHandler(attestation: Attestation) =
# Avoid double-counting attestation-topic attestations on shared codepath
# when they're reflected through beacon blocks
beacon_attestations_received.inc()
beacon_attestation_received_seconds_from_slot_start.observe(
node.beaconClock.now.int64 -
(attestation.data.slot.int64 * SECONDS_PER_SLOT.int64))
node.onAttestation(attestation)
var attestationSubscriptions: seq[Future[void]] = @[]
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#mainnet-3
for it in 0'u64 ..< ATTESTATION_SUBNET_COUNT.uint64:
closureScope:
let ci = it
attestationSubscriptions.add(node.network.subscribe(
getMainnetAttestationTopic(node.forkDigest, ci), attestationHandler,
# This proc needs to be within closureScope; don't lift out of loop.
proc(attestation: Attestation): bool =
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#attestation-subnets
let (afterGenesis, slot) = node.beaconClock.now().toSlot()
if not afterGenesis:
return false
node.attestationPool.isValidAttestation(attestation, slot, ci, {})))
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#interop-3
attestationSubscriptions.add(node.network.subscribe(
getInteropAttestationTopic(node.forkDigest), attestationHandler,
proc(attestation: Attestation): bool =
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#attestation-subnets
let (afterGenesis, slot) = node.beaconClock.now().toSlot()
if not afterGenesis:
return false
# isValidAttestation checks attestation.data.index == topicCommitteeIndex
# which doesn't make sense here, so rig that check to vacuously pass.
node.attestationPool.isValidAttestation(
attestation, slot, attestation.data.index, {})))
waitFor allFutures(attestationSubscriptions)
proc run*(node: BeaconNode) = proc run*(node: BeaconNode) =
if node.rpcServer != nil: if node.rpcServer != nil:
node.rpcServer.installRpcHandlers(node) node.rpcServer.installRpcHandlers(node)
@ -679,27 +721,7 @@ proc run*(node: BeaconNode) =
return false return false
node.blockPool.isValidBeaconBlock(signedBlock, slot, {}) node.blockPool.isValidBeaconBlock(signedBlock, slot, {})
proc attestationHandler(attestation: Attestation) = installAttestationHandlers(node)
# Avoid double-counting attestation-topic attestations on shared codepath
# when they're reflected through beacon blocks
beacon_attestations_received.inc()
beacon_attestation_received_seconds_from_slot_start.observe(node.beaconClock.now.int64 - (attestation.data.slot.int64 * SECONDS_PER_SLOT.int64))
node.onAttestation(attestation)
var attestationSubscriptions: seq[Future[void]] = @[]
for it in 0'u64 ..< ATTESTATION_SUBNET_COUNT.uint64:
closureScope:
let ci = it
attestationSubscriptions.add(node.network.subscribe(
getAttestationTopic(node.forkDigest, ci), attestationHandler,
proc(attestation: Attestation): bool =
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#attestation-subnets
let (afterGenesis, slot) = node.beaconClock.now().toSlot()
if not afterGenesis:
return false
node.attestationPool.isValidAttestation(attestation, slot, ci, {})))
waitFor allFutures(attestationSubscriptions)
let let
t = node.beaconClock.now().toSlot() t = node.beaconClock.now().toSlot()

View File

@ -204,8 +204,8 @@ func getTopics(forkDigest: ForkDigest,
var topics = newSeq[string](ATTESTATION_SUBNET_COUNT * 2) var topics = newSeq[string](ATTESTATION_SUBNET_COUNT * 2)
var offset = 0 var offset = 0
for i in 0'u64 ..< ATTESTATION_SUBNET_COUNT.uint64: for i in 0'u64 ..< ATTESTATION_SUBNET_COUNT.uint64:
topics[offset] = getAttestationTopic(forkDigest, i) topics[offset] = getMainnetAttestationTopic(forkDigest, i)
topics[offset + 1] = getAttestationTopic(forkDigest, i) & "_snappy" topics[offset + 1] = getMainnetAttestationTopic(forkDigest, i) & "_snappy"
offset += 2 offset += 2
topics topics
@ -514,8 +514,8 @@ proc pubsubLogger(conf: InspectorConf, switch: Switch,
if topic.endsWith(topicBeaconBlocksSuffix) or if topic.endsWith(topicBeaconBlocksSuffix) or
topic.endsWith(topicBeaconBlocksSuffix & "_snappy"): topic.endsWith(topicBeaconBlocksSuffix & "_snappy"):
info "SignedBeaconBlock", msg = SSZ.decode(buffer, SignedBeaconBlock) info "SignedBeaconBlock", msg = SSZ.decode(buffer, SignedBeaconBlock)
elif topic.endsWith(topicAttestationsSuffix) or elif topic.endsWith(topicMainnetAttestationsSuffix) or
topic.endsWith(topicAttestationsSuffix & "_snappy"): topic.endsWith(topicMainnetAttestationsSuffix & "_snappy"):
info "Attestation", msg = SSZ.decode(buffer, Attestation) info "Attestation", msg = SSZ.decode(buffer, Attestation)
elif topic.endsWith(topicVoluntaryExitsSuffix) or elif topic.endsWith(topicVoluntaryExitsSuffix) or
topic.endsWith(topicVoluntaryExitsSuffix & "_snappy"): topic.endsWith(topicVoluntaryExitsSuffix & "_snappy"):

View File

@ -13,10 +13,11 @@ import
const const
topicBeaconBlocksSuffix* = "beacon_block/ssz" topicBeaconBlocksSuffix* = "beacon_block/ssz"
topicAttestationsSuffix* = "_beacon_attestation/ssz" topicMainnetAttestationsSuffix* = "_beacon_attestation/ssz"
topicVoluntaryExitsSuffix* = "voluntary_exit/ssz" topicVoluntaryExitsSuffix* = "voluntary_exit/ssz"
topicProposerSlashingsSuffix* = "proposer_slashing/ssz" topicProposerSlashingsSuffix* = "proposer_slashing/ssz"
topicAttesterSlashingsSuffix* = "attester_slashing/ssz" topicAttesterSlashingsSuffix* = "attester_slashing/ssz"
topicInteropAttestationSuffix* = "beacon_attestation/ssz"
topicAggregateAndProofsSuffix* = "beacon_aggregate_and_proof/ssz" topicAggregateAndProofsSuffix* = "beacon_aggregate_and_proof/ssz"
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#configuration # https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#configuration
@ -27,40 +28,52 @@ const
# This is not part of the spec yet! # This is not part of the spec yet!
defaultEth2RpcPort* = 9090 defaultEth2RpcPort* = 9090
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#topics-and-messages
func getBeaconBlocksTopic*(forkDigest: ForkDigest): string = func getBeaconBlocksTopic*(forkDigest: ForkDigest): string =
try: try:
&"/eth2/{$forkDigest}/{topicBeaconBlocksSuffix}" &"/eth2/{$forkDigest}/{topicBeaconBlocksSuffix}"
except ValueError as e: except ValueError as e:
raiseAssert e.msg raiseAssert e.msg
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#topics-and-messages
func getVoluntaryExitsTopic*(forkDigest: ForkDigest): string = func getVoluntaryExitsTopic*(forkDigest: ForkDigest): string =
try: try:
&"/eth2/{$forkDigest}/{topicVoluntaryExitsSuffix}" &"/eth2/{$forkDigest}/{topicVoluntaryExitsSuffix}"
except ValueError as e: except ValueError as e:
raiseAssert e.msg raiseAssert e.msg
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#topics-and-messages
func getProposerSlashingsTopic*(forkDigest: ForkDigest): string = func getProposerSlashingsTopic*(forkDigest: ForkDigest): string =
try: try:
&"/eth2/{$forkDigest}/{topicProposerSlashingsSuffix}" &"/eth2/{$forkDigest}/{topicProposerSlashingsSuffix}"
except ValueError as e: except ValueError as e:
raiseAssert e.msg raiseAssert e.msg
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#topics-and-messages
func getAttesterSlashingsTopic*(forkDigest: ForkDigest): string = func getAttesterSlashingsTopic*(forkDigest: ForkDigest): string =
try: try:
&"/eth2/{$forkDigest}/{topicAttesterSlashingsSuffix}" &"/eth2/{$forkDigest}/{topicAttesterSlashingsSuffix}"
except ValueError as e: except ValueError as e:
raiseAssert e.msg raiseAssert e.msg
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#interop-3
func getInteropAttestationTopic*(forkDigest: ForkDigest): string =
try:
&"/eth2/{$forkDigest}/{topicInteropAttestationSuffix}"
except ValueError as e:
raiseAssert e.msg
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#topics-and-messages
func getAggregateAndProofsTopic*(forkDigest: ForkDigest): string = func getAggregateAndProofsTopic*(forkDigest: ForkDigest): string =
try: try:
&"/eth2/{$forkDigest}/{topicAggregateAndProofsSuffix}" &"/eth2/{$forkDigest}/{topicAggregateAndProofsSuffix}"
except ValueError as e: except ValueError as e:
raiseAssert e.msg raiseAssert e.msg
func getAttestationTopic*(forkDigest: ForkDigest, committeeIndex: uint64): string = # https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#mainnet-3
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#broadcast-attestation func getMainnetAttestationTopic*(forkDigest: ForkDigest, committeeIndex: uint64): string =
try: try:
let topicIndex = committeeIndex mod ATTESTATION_SUBNET_COUNT let topicIndex = committeeIndex mod ATTESTATION_SUBNET_COUNT
&"/eth2/{$forkDigest}/committee_index{topicIndex}{topicAttestationsSuffix}" &"/eth2/{$forkDigest}/committee_index{topicIndex}{topicMainnetAttestationsSuffix}"
except ValueError as e: except ValueError as e:
raiseAssert e.msg raiseAssert e.msg

View File

@ -14,17 +14,16 @@ import
chronos, metrics, json_rpc/[rpcserver, jsonmarshal], chronos, metrics, json_rpc/[rpcserver, jsonmarshal],
chronicles, chronicles,
json_serialization/std/[options, sets, net], serialization/errors, json_serialization/std/[options, sets, net], serialization/errors,
eth/db/kvstore, eth/db/kvstore_sqlite3, eth/db/kvstore,
eth/[keys, async_utils], eth/p2p/discoveryv5/[protocol, enr], eth/[keys, async_utils], eth/p2p/discoveryv5/[protocol, enr],
# Local modules # Local modules
spec/[datatypes, digest, crypto, beaconstate, helpers, validator, network, spec/[datatypes, digest, crypto, beaconstate, helpers, validator, network,
state_transition_block], state_transition_block],
conf, time, beacon_chain_db, validator_pool, conf, time, validator_pool,
attestation_pool, block_pool, eth2_network, attestation_pool, block_pool, eth2_network,
beacon_node_common, beacon_node_types, beacon_node_common, beacon_node_types,
mainchain_monitor, version, ssz, ssz/dynamic_navigator, mainchain_monitor, version, ssz, interop,
request_manager, interop, statusbar,
attestation_aggregation, sync_manager, sszdump attestation_aggregation, sync_manager, sszdump
# Metrics for tracking attestation and beacon block loss # Metrics for tracking attestation and beacon block loss
@ -124,7 +123,8 @@ proc sendAttestation(node: BeaconNode,
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#broadcast-attestation # https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/validator.md#broadcast-attestation
node.network.broadcast( node.network.broadcast(
getAttestationTopic(node.forkDigest, attestationData.index), attestation) getMainnetAttestationTopic(node.forkDigest, attestationData.index),
attestation)
if node.config.dumpEnabled: if node.config.dumpEnabled:
dump(node.config.dumpDir, attestationData, validator.pubKey) dump(node.config.dumpDir, attestationData, validator.pubKey)

View File

@ -1,5 +1,5 @@
import import
confutils, os, strutils, chronicles, json_serialization, confutils, os, strutils, json_serialization,
stew/byteutils, stew/byteutils,
../beacon_chain/spec/[crypto, datatypes, digest], ../beacon_chain/spec/[crypto, datatypes, digest],
../beacon_chain/ssz ../beacon_chain/ssz

View File

@ -7,25 +7,54 @@ import
suiteReport "Honest validator": suiteReport "Honest validator":
var forkDigest: ForkDigest var forkDigest: ForkDigest
timedTest "Attestation topics": timedTest "General pubsub topics:":
check: check:
getAttestationTopic(forkDigest, 0) == "/eth2/00000000/committee_index0_beacon_attestation/ssz" getBeaconBlocksTopic(forkDigest) == "/eth2/00000000/beacon_block/ssz"
getAttestationTopic(forkDigest, 9) == "/eth2/00000000/committee_index9_beacon_attestation/ssz" getVoluntaryExitsTopic(forkDigest) == "/eth2/00000000/voluntary_exit/ssz"
getAttestationTopic(forkDigest, 10) == "/eth2/00000000/committee_index10_beacon_attestation/ssz" getProposerSlashingsTopic(forkDigest) == "/eth2/00000000/proposer_slashing/ssz"
getAttestationTopic(forkDigest, 11) == "/eth2/00000000/committee_index11_beacon_attestation/ssz" getAttesterSlashingsTopic(forkDigest) == "/eth2/00000000/attester_slashing/ssz"
getAttestationTopic(forkDigest, 14) == "/eth2/00000000/committee_index14_beacon_attestation/ssz" getInteropAttestationTopic(forkDigest) == "/eth2/00000000/beacon_attestation/ssz"
getAttestationTopic(forkDigest, 22) == "/eth2/00000000/committee_index22_beacon_attestation/ssz" getAggregateAndProofsTopic(forkDigest) == "/eth2/00000000/beacon_aggregate_and_proof/ssz"
getAttestationTopic(forkDigest, 34) == "/eth2/00000000/committee_index34_beacon_attestation/ssz"
getAttestationTopic(forkDigest, 46) == "/eth2/00000000/committee_index46_beacon_attestation/ssz" timedTest "Mainnet attestation topics":
getAttestationTopic(forkDigest, 60) == "/eth2/00000000/committee_index60_beacon_attestation/ssz" check:
getAttestationTopic(forkDigest, 63) == "/eth2/00000000/committee_index63_beacon_attestation/ssz" getMainnetAttestationTopic(forkDigest, 0) ==
getAttestationTopic(forkDigest, 200) == "/eth2/00000000/committee_index8_beacon_attestation/ssz" "/eth2/00000000/committee_index0_beacon_attestation/ssz"
getAttestationTopic(forkDigest, 400) == "/eth2/00000000/committee_index16_beacon_attestation/ssz" getMainnetAttestationTopic(forkDigest, 9) ==
getAttestationTopic(forkDigest, 469) == "/eth2/00000000/committee_index21_beacon_attestation/ssz" "/eth2/00000000/committee_index9_beacon_attestation/ssz"
getAttestationTopic(forkDigest, 550) == "/eth2/00000000/committee_index38_beacon_attestation/ssz" getMainnetAttestationTopic(forkDigest, 10) ==
getAttestationTopic(forkDigest, 600) == "/eth2/00000000/committee_index24_beacon_attestation/ssz" "/eth2/00000000/committee_index10_beacon_attestation/ssz"
getAttestationTopic(forkDigest, 613) == "/eth2/00000000/committee_index37_beacon_attestation/ssz" getMainnetAttestationTopic(forkDigest, 11) ==
getAttestationTopic(forkDigest, 733) == "/eth2/00000000/committee_index29_beacon_attestation/ssz" "/eth2/00000000/committee_index11_beacon_attestation/ssz"
getAttestationTopic(forkDigest, 775) == "/eth2/00000000/committee_index7_beacon_attestation/ssz" getMainnetAttestationTopic(forkDigest, 14) ==
getAttestationTopic(forkDigest, 888) == "/eth2/00000000/committee_index56_beacon_attestation/ssz" "/eth2/00000000/committee_index14_beacon_attestation/ssz"
getAttestationTopic(forkDigest, 995) == "/eth2/00000000/committee_index35_beacon_attestation/ssz" getMainnetAttestationTopic(forkDigest, 22) ==
"/eth2/00000000/committee_index22_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 34) ==
"/eth2/00000000/committee_index34_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 46) ==
"/eth2/00000000/committee_index46_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 60) ==
"/eth2/00000000/committee_index60_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 63) ==
"/eth2/00000000/committee_index63_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 200) ==
"/eth2/00000000/committee_index8_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 400) ==
"/eth2/00000000/committee_index16_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 469) ==
"/eth2/00000000/committee_index21_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 550) ==
"/eth2/00000000/committee_index38_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 600) ==
"/eth2/00000000/committee_index24_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 613) ==
"/eth2/00000000/committee_index37_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 733) ==
"/eth2/00000000/committee_index29_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 775) ==
"/eth2/00000000/committee_index7_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 888) ==
"/eth2/00000000/committee_index56_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 995) ==
"/eth2/00000000/committee_index35_beacon_attestation/ssz"