From 6c87af9aab6d4adc33d24d1b3a5beb9805911ee3 Mon Sep 17 00:00:00 2001 From: Dustin Brody Date: Fri, 21 Feb 2020 13:16:58 +0100 Subject: [PATCH] split attestation beacon topic per honest validator spec --- beacon_chain/beacon_node.nim | 15 +++++++++------ beacon_chain/block_pool.nim | 1 + beacon_chain/inspector.nim | 4 ++-- beacon_chain/spec/network.nim | 14 ++++++++++++-- tests/all_tests.nim | 3 ++- tests/test_honest_validator.nim | 19 +++++++++++++++++++ 6 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 tests/test_honest_validator.nim diff --git a/beacon_chain/beacon_node.nim b/beacon_chain/beacon_node.nim index 0c51475ad..574f23c88 100644 --- a/beacon_chain/beacon_node.nim +++ b/beacon_chain/beacon_node.nim @@ -347,7 +347,9 @@ proc sendAttestation(node: BeaconNode, aggregation_bits: aggregationBits ) - node.network.broadcast(topicAttestations, attestation) + node.network.broadcast( + getAttestationTopic(attestationData.index mod ATTESTATION_SUBNET_COUNT), + attestation) if node.config.dump: SSZ.saveFile( @@ -856,12 +858,13 @@ proc run*(node: BeaconNode) = waitFor node.network.subscribe(topicBeaconBlocks) do (signedBlock: SignedBeaconBlock): onBeaconBlock(node, signedBlock) - waitFor node.network.subscribe(topicAttestations) do (attestation: Attestation): - # Avoid double-counting attestation-topic attestations on shared codepath - # when they're reflected through beacon blocks - beacon_attestations_received.inc() + for i in 0'u64 ..< ATTESTATION_SUBNET_COUNT: + waitFor node.network.subscribe(getAttestationTopic(i)) do (attestation: Attestation): + # Avoid double-counting attestation-topic attestations on shared codepath + # when they're reflected through beacon blocks + beacon_attestations_received.inc() - node.onAttestation(attestation) + node.onAttestation(attestation) let t = node.beaconClock.now().toSlot() diff --git a/beacon_chain/block_pool.nim b/beacon_chain/block_pool.nim index 38c5c6f8b..c1a67b646 100644 --- a/beacon_chain/block_pool.nim +++ b/beacon_chain/block_pool.nim @@ -932,6 +932,7 @@ proc getProposer*(pool: BlockPool, head: BlockRef, slot: Slot): Option[Validator pool.withState(pool.tmpState, head.atSlot(slot)): var cache = get_empty_per_epoch_cache() + # https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/validator.md#validator-assignments let proposerIdx = get_beacon_proposer_index(state, cache) if proposerIdx.isNone: warn "Missing proposer index", diff --git a/beacon_chain/inspector.nim b/beacon_chain/inspector.nim index e711afb8a..3f2979ae4 100644 --- a/beacon_chain/inspector.nim +++ b/beacon_chain/inspector.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018 Status Research & Development GmbH +# Copyright (c) 2018-2020 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). @@ -186,7 +186,7 @@ proc run(conf: InspectorConf) {.async.} = try: if ticket.topic.startsWith(topicBeaconBlocks): info "SignedBeaconBlock", msg = SSZ.decode(message.data, SignedBeaconBlock) - elif ticket.topic.startsWith(topicAttestations): + elif ticket.topic.endsWith(topicAttestationSuffix): info "Attestation", msg = SSZ.decode(message.data, Attestation) elif ticket.topic.startsWith(topicVoluntaryExits): info "SignedVoluntaryExit", msg = SSZ.decode(message.data, SignedVoluntaryExit) diff --git a/beacon_chain/spec/network.nim b/beacon_chain/spec/network.nim index 60491be5f..dbf86d050 100644 --- a/beacon_chain/spec/network.nim +++ b/beacon_chain/spec/network.nim @@ -1,13 +1,23 @@ # beacon_chain -# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2018-2020 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. +import strformat + const topicBeaconBlocks* = "/eth2/beacon_block/ssz" - topicAttestations* = "/eth2/beacon_attestation/ssz" + topicAttestationSuffix* = "_beacon_attestation/ssz" topicVoluntaryExits* = "/eth2/voluntary_exit/ssz" topicProposerSlashings* = "/eth2/proposer_slashing/ssz" topicAttesterSlashings* = "/eth2/attester_slashing/ssz" + + # https://github.com/ethereum/eth2.0-specs/blob/dev/specs/phase0/p2p-interface.md#configuration + ATTESTATION_SUBNET_COUNT* = 64 + +func getAttestationTopic*(committeeIndex: uint64): string = + doAssert committeeIndex < ATTESTATION_SUBNET_COUNT + # https://github.com/ethereum/eth2.0-specs/blob/v0.10.1/specs/phase0/validator.md#broadcast-attestation + &"/eth2/index{committeeIndex}{topicAttestationSuffix}" diff --git a/tests/all_tests.nim b/tests/all_tests.nim index bc0833bfa..6df21ff00 100644 --- a/tests/all_tests.nim +++ b/tests/all_tests.nim @@ -28,7 +28,8 @@ import # Unit test # ./test_validator # Empty! ./test_zero_signature, ./test_peer_pool, - ./test_sync_manager + ./test_sync_manager, + ./test_honest_validator import # Refactor state transition unit tests # TODO re-enable when useful diff --git a/tests/test_honest_validator.nim b/tests/test_honest_validator.nim new file mode 100644 index 000000000..dc4167c05 --- /dev/null +++ b/tests/test_honest_validator.nim @@ -0,0 +1,19 @@ +{.used.} + +import + unittest, stint, ./testutil, + ../beacon_chain/spec/network + +suite "Honest validator": + timedTest "Attestation topics": + check: + getAttestationTopic(0) == "/eth2/index0_beacon_attestation/ssz" + getAttestationTopic(9) == "/eth2/index9_beacon_attestation/ssz" + getAttestationTopic(10) == "/eth2/index10_beacon_attestation/ssz" + getAttestationTopic(11) == "/eth2/index11_beacon_attestation/ssz" + getAttestationTopic(14) == "/eth2/index14_beacon_attestation/ssz" + getAttestationTopic(22) == "/eth2/index22_beacon_attestation/ssz" + getAttestationTopic(34) == "/eth2/index34_beacon_attestation/ssz" + getAttestationTopic(46) == "/eth2/index46_beacon_attestation/ssz" + getAttestationTopic(60) == "/eth2/index60_beacon_attestation/ssz" + getAttestationTopic(63) == "/eth2/index63_beacon_attestation/ssz"