support v0.12.1 attestation topics in beacon node/inspector subscribing (#1187)

* support v0.12.1 attestation topics in beacon node and inspector subscribing

* bump is_valid_merkle_branch() spec ref
This commit is contained in:
tersec 2020-06-18 13:10:25 +00:00 committed by GitHub
parent 4436c85ff7
commit dc1a565b3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 159 additions and 68 deletions

View File

@ -742,12 +742,20 @@ proc installAttestationHandlers(node: BeaconNode) =
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 =
attestationValidator(attestation, ci)
))
when ETH2_SPEC == "v0.12.1":
attestationSubscriptions.add(node.network.subscribe(
getAttestationTopic(node.forkDigest, ci), attestationHandler,
# This proc needs to be within closureScope; don't lift out of loop.
proc(attestation: Attestation): bool =
attestationValidator(attestation, ci)
))
else:
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 =
attestationValidator(attestation, ci)
))
when ETH2_SPEC == "v0.11.3":
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#interop-3

View File

@ -53,7 +53,7 @@ func parent*(bs: BlockSlot): BlockSlot =
slot: bs.slot - 1
)
func populateEpochCache*(state: BeaconState, epoch: Epoch): EpochRef =
func populateEpochCache(state: BeaconState, epoch: Epoch): EpochRef =
result = (EpochRef)(
epoch: state.slot.compute_epoch_at_slot,
shuffled_active_validator_indices:
@ -148,7 +148,7 @@ func getEpochInfo*(blck: BlockRef, state: BeaconState): EpochRef =
if matching_epochinfo.len == 0:
let cache = populateEpochCache(state, state_epoch)
blck.epochsInfo.add(cache)
trace "candidate_chains.skipAndUpdateState(): back-filling parent.epochInfo",
trace "candidate_chains.getEpochInfo: back-filling parent.epochInfo",
state_slot = state.slot
cache
elif matching_epochinfo.len == 1:

View File

@ -207,8 +207,12 @@ func getTopics(forkDigest: ForkDigest,
var topics = newSeq[string](ATTESTATION_SUBNET_COUNT * 2)
var offset = 0
for i in 0'u64 ..< ATTESTATION_SUBNET_COUNT.uint64:
topics[offset] = getMainnetAttestationTopic(forkDigest, i)
topics[offset + 1] = getMainnetAttestationTopic(forkDigest, i) & "_snappy"
when ETH2_SPEC == "v0.12.1":
topics[offset] = getAttestationTopic(forkDigest, i)
topics[offset + 1] = getAttestationTopic(forkDigest, i) & "_snappy"
else:
topics[offset] = getMainnetAttestationTopic(forkDigest, i)
topics[offset + 1] = getMainnetAttestationTopic(forkDigest, i) & "_snappy"
offset += 2
topics

View File

@ -14,7 +14,7 @@ import
./crypto, ./datatypes, ./digest, ./helpers, ./signatures, ./validator,
../../nbench/bench_lab
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.3/specs/phase0/beacon-chain.md#is_valid_merkle_branch
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#is_valid_merkle_branch
func is_valid_merkle_branch*(leaf: Eth2Digest, branch: openarray[Eth2Digest], depth: uint64, index: uint64, root: Eth2Digest): bool {.nbench.}=
## Check if ``leaf`` at ``index`` verifies against the Merkle ``root`` and
## ``branch``.

View File

@ -64,7 +64,13 @@ func get_active_validator_indices*(state: BeaconState, epoch: Epoch):
if is_active_validator(val, epoch):
result.add idx.ValidatorIndex
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.3/specs/phase0/beacon-chain.md#get_committee_count_at_slot
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/beacon-chain.md#get_committee_count_at_slot
func get_committee_count_at_slot*(num_active_validators: auto):
uint64 =
clamp(
num_active_validators div SLOTS_PER_EPOCH div TARGET_COMMITTEE_SIZE,
1, MAX_COMMITTEES_PER_SLOT).uint64
func get_committee_count_at_slot*(state: BeaconState, slot: Slot): uint64 =
# Return the number of committees at ``slot``.
@ -74,10 +80,7 @@ func get_committee_count_at_slot*(state: BeaconState, slot: Slot): uint64 =
# CommitteeIndex return type here.
let epoch = compute_epoch_at_slot(slot)
let active_validator_indices = get_active_validator_indices(state, epoch)
let committees_per_slot = clamp(
len(active_validator_indices) div SLOTS_PER_EPOCH div TARGET_COMMITTEE_SIZE,
1, MAX_COMMITTEES_PER_SLOT).uint64
result = committees_per_slot
result = get_committee_count_at_slot(len(active_validator_indices))
# Otherwise, get_beacon_committee(...) cannot access some committees.
doAssert (SLOTS_PER_EPOCH * MAX_COMMITTEES_PER_SLOT).uint64 >= result

View File

@ -12,14 +12,17 @@ import
datatypes
const
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/p2p-interface.md#topics-and-messages
topicBeaconBlocksSuffix* = "beacon_block/ssz"
topicMainnetAttestationsSuffix* = "_beacon_attestation/ssz"
topicVoluntaryExitsSuffix* = "voluntary_exit/ssz"
topicProposerSlashingsSuffix* = "proposer_slashing/ssz"
topicAttesterSlashingsSuffix* = "attester_slashing/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.3/specs/phase0/p2p-interface.md#topics-and-messages
topicMainnetAttestationsSuffix* = "_beacon_attestation/ssz"
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#misc
ATTESTATION_SUBNET_COUNT* = 64
defaultEth2TcpPort* = 9000
@ -30,35 +33,30 @@ const
when ETH2_SPEC == "v0.11.3":
const topicInteropAttestationSuffix* = "beacon_attestation/ssz"
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#topics-and-messages
func getBeaconBlocksTopic*(forkDigest: ForkDigest): string =
try:
&"/eth2/{$forkDigest}/{topicBeaconBlocksSuffix}"
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 getVoluntaryExitsTopic*(forkDigest: ForkDigest): string =
try:
&"/eth2/{$forkDigest}/{topicVoluntaryExitsSuffix}"
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 getProposerSlashingsTopic*(forkDigest: ForkDigest): string =
try:
&"/eth2/{$forkDigest}/{topicProposerSlashingsSuffix}"
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 getAttesterSlashingsTopic*(forkDigest: ForkDigest): string =
try:
&"/eth2/{$forkDigest}/{topicAttesterSlashingsSuffix}"
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 =
try:
&"/eth2/{$forkDigest}/{topicAggregateAndProofsSuffix}"
@ -72,10 +70,44 @@ when ETH2_SPEC == "v0.11.3":
except ValueError as e:
raiseAssert e.msg
# 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.3/specs/phase0/p2p-interface.md#mainnet-3
func getMainnetAttestationTopic*(forkDigest: ForkDigest, committeeIndex: uint64): string =
let topicIndex = committeeIndex mod ATTESTATION_SUBNET_COUNT
try:
let topicIndex = committeeIndex mod ATTESTATION_SUBNET_COUNT
&"/eth2/{$forkDigest}/committee_index{topicIndex}{topicMainnetAttestationsSuffix}"
except ValueError as e:
raiseAssert e.msg
when ETH2_SPEC == "v0.12.1":
import helpers
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#broadcast-attestation
func compute_subnet_for_attestation*(
num_active_validators: uint64, attestation: Attestation): uint64 =
# Compute the correct subnet for an attestation for Phase 0.
# Note, this mimics expected Phase 1 behavior where attestations will be
# mapped to their shard subnet.
#
# The spec version has params (state: BeaconState, attestation: Attestation),
# but it's only to call get_committee_count_at_slot(), which needs only epoch
# and the number of active validators.
let
slots_since_epoch_start = attestation.data.slot mod SLOTS_PER_EPOCH
committees_since_epoch_start =
get_committee_count_at_slot(num_active_validators) * slots_since_epoch_start
(committees_since_epoch_start + attestation.data.index) mod ATTESTATION_SUBNET_COUNT
# https://github.com/ethereum/eth2.0-specs/blob/v0.12.1/specs/phase0/validator.md#broadcast-attestation
func getAttestationTopic*(forkDigest: ForkDigest, subnetIndex: uint64):
string =
# This is for subscribing or broadcasting manually to a known index.
try:
&"/eth2/{$forkDigest}/beacon_attestation_{subnetIndex}/ssz"
except ValueError as e:
raiseAssert e.msg
func getAttestationTopic*(forkDigest: ForkDigest, attestation: Attestation, num_active_validators: uint64): string =
getAttestationTopic(
forkDigest,
compute_subnet_for_attestation(num_active_validators, attestation))

View File

@ -24,7 +24,7 @@ const
MAX_COMMITTEES_PER_SLOT* {.intdefine.} = 64
TARGET_COMMITTEE_SIZE* = 2^7 ##\
TARGET_COMMITTEE_SIZE* = 128 ##\
## Number of validators in the committee attesting to one shard
## Per spec:
## For the safety of crosslinks `TARGET_COMMITTEE_SIZE` exceeds

View File

@ -19,45 +19,89 @@ suiteReport "Honest validator":
true
getAggregateAndProofsTopic(forkDigest) == "/eth2/00000000/beacon_aggregate_and_proof/ssz"
timedTest "Mainnet attestation topics":
check:
getMainnetAttestationTopic(forkDigest, 0) ==
"/eth2/00000000/committee_index0_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 9) ==
"/eth2/00000000/committee_index9_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 10) ==
"/eth2/00000000/committee_index10_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 11) ==
"/eth2/00000000/committee_index11_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 14) ==
"/eth2/00000000/committee_index14_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"
when ETH2_SPEC == "v0.11.3":
timedTest "Mainnet attestation topics":
check:
getMainnetAttestationTopic(forkDigest, 0) ==
"/eth2/00000000/committee_index0_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 9) ==
"/eth2/00000000/committee_index9_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 10) ==
"/eth2/00000000/committee_index10_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 11) ==
"/eth2/00000000/committee_index11_beacon_attestation/ssz"
getMainnetAttestationTopic(forkDigest, 14) ==
"/eth2/00000000/committee_index14_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"
else:
timedTest "Mainnet attestation topics":
check:
getAttestationTopic(forkDigest, 0) ==
"/eth2/00000000/beacon_attestation_0/ssz"
getAttestationTopic(forkDigest, 5) ==
"/eth2/00000000/beacon_attestation_5/ssz"
getAttestationTopic(forkDigest, 7) ==
"/eth2/00000000/beacon_attestation_7/ssz"
getAttestationTopic(forkDigest, 9) ==
"/eth2/00000000/beacon_attestation_9/ssz"
getAttestationTopic(forkDigest, 13) ==
"/eth2/00000000/beacon_attestation_13/ssz"
getAttestationTopic(forkDigest, 19) ==
"/eth2/00000000/beacon_attestation_19/ssz"
getAttestationTopic(forkDigest, 20) ==
"/eth2/00000000/beacon_attestation_20/ssz"
getAttestationTopic(forkDigest, 22) ==
"/eth2/00000000/beacon_attestation_22/ssz"
getAttestationTopic(forkDigest, 25) ==
"/eth2/00000000/beacon_attestation_25/ssz"
getAttestationTopic(forkDigest, 27) ==
"/eth2/00000000/beacon_attestation_27/ssz"
getAttestationTopic(forkDigest, 31) ==
"/eth2/00000000/beacon_attestation_31/ssz"
getAttestationTopic(forkDigest, 39) ==
"/eth2/00000000/beacon_attestation_39/ssz"
getAttestationTopic(forkDigest, 45) ==
"/eth2/00000000/beacon_attestation_45/ssz"
getAttestationTopic(forkDigest, 47) ==
"/eth2/00000000/beacon_attestation_47/ssz"
getAttestationTopic(forkDigest, 48) ==
"/eth2/00000000/beacon_attestation_48/ssz"
getAttestationTopic(forkDigest, 50) ==
"/eth2/00000000/beacon_attestation_50/ssz"
getAttestationTopic(forkDigest, 53) ==
"/eth2/00000000/beacon_attestation_53/ssz"
getAttestationTopic(forkDigest, 54) ==
"/eth2/00000000/beacon_attestation_54/ssz"
getAttestationTopic(forkDigest, 62) ==
"/eth2/00000000/beacon_attestation_62/ssz"
getAttestationTopic(forkDigest, 63) ==
"/eth2/00000000/beacon_attestation_63/ssz"