remove get_epoch_start_slot(...) kludge and update to work exactly as 0.7.1 specifies; remove unused get_attestation_participants_cached(...); update AttestationData to 0.7.1 (being the last data structure, I believe, remaining for such; remove potentially spurious/certainly not-in-spec assertion from compute_committee(...); fix state sim to work with new get_epoch_start_slot/AttestationData/etc setup where it can't stuff all shards' attestations from same slot in the same MIN_ATTESTATION_INCLUSION_DELAY rotating/circular buffer of seq[Attestation]s without more involved shuffling of shard/slot calculation order; fix attestation pool testing to be consistent with get_epoch_start_slot(...) (#302)

This commit is contained in:
Dustin Brody 2019-06-29 09:17:24 +00:00 committed by GitHub
parent 214860cb88
commit 7356905f95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 36 deletions

View File

@ -264,8 +264,6 @@ func get_genesis_beacon_state*(
state state
# TODO candidate for spec?
# https://github.com/ethereum/eth2.0-specs/blob/0.5.1/specs/core/0_beacon-chain.md#on-genesis
func get_initial_beacon_block*(state: BeaconState): BeaconBlock = func get_initial_beacon_block*(state: BeaconState): BeaconBlock =
BeaconBlock( BeaconBlock(
slot: GENESIS_SLOT, slot: GENESIS_SLOT,
@ -281,9 +279,8 @@ func get_attestation_data_slot*(state: BeaconState,
offset = (data.crosslink.shard + SHARD_COUNT - offset = (data.crosslink.shard + SHARD_COUNT -
get_epoch_start_shard(state, data.target_epoch)) mod SHARD_COUNT get_epoch_start_shard(state, data.target_epoch)) mod SHARD_COUNT
# TODO re-instate once double-check correct conditions in attestation pool get_epoch_start_slot(data.target_epoch) + offset div
#get_epoch_start_slot(data.target_epoch) + offset div (committee_count div SLOTS_PER_EPOCH) (committee_count div SLOTS_PER_EPOCH)
data.slot
# This is the slower (O(n)), spec-compatible signature. # This is the slower (O(n)), spec-compatible signature.
func get_attestation_data_slot*(state: BeaconState, func get_attestation_data_slot*(state: BeaconState,
@ -433,14 +430,6 @@ func get_attesting_indices_seq*(
toSeq(items(get_attesting_indices( toSeq(items(get_attesting_indices(
state, attestation_data, bitfield, cache))) state, attestation_data, bitfield, cache)))
# TODO legacy function name; rename, reimplement caching if useful, blob/v0.6.2
iterator get_attestation_participants_cached*(
state: BeaconState, attestation_data: AttestationData, bitfield: BitField,
cache: var StateCache): ValidatorIndex =
for participant in get_attesting_indices(
state, attestation_data, bitfield, cache):
yield participant
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#convert_to_indexed # https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#convert_to_indexed
func convert_to_indexed(state: BeaconState, attestation: Attestation, func convert_to_indexed(state: BeaconState, attestation: Attestation,
stateCache: var StateCache): IndexedAttestation = stateCache: var StateCache): IndexedAttestation =
@ -473,8 +462,7 @@ func convert_to_indexed(state: BeaconState, attestation: Attestation,
## the conversion here otherwise needs sorting is due to the ## the conversion here otherwise needs sorting is due to the
## usage of HashSet -- order only matters in one place (that ## usage of HashSet -- order only matters in one place (that
## 0.6.3 highlights and explicates) except in that the spec, ## 0.6.3 highlights and explicates) except in that the spec,
## for no obvious reason, verifies it. So, here goes, sort a ## for no obvious reason, verifies it.
## list just so a called function can verify it's sorted.
IndexedAttestation( IndexedAttestation(
custody_bit_0_indices: sorted( custody_bit_0_indices: sorted(
mapIt(custody_bit_0_indices, it.uint64), system.cmp), mapIt(custody_bit_0_indices, it.uint64), system.cmp),
@ -595,7 +583,6 @@ proc makeAttestationData*(
else: get_block_root_at_slot(state, epoch_start_slot) else: get_block_root_at_slot(state, epoch_start_slot)
AttestationData( AttestationData(
slot: state.slot,
beacon_block_root: beacon_block_root, beacon_block_root: beacon_block_root,
target_root: target_root, target_root: target_root,
source_epoch: state.current_justified_epoch, source_epoch: state.current_justified_epoch,

View File

@ -117,9 +117,8 @@ type
signature*: ValidatorSig ##\ signature*: ValidatorSig ##\
## BLS aggregate signature ## BLS aggregate signature
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.2/specs/core/0_beacon-chain.md#attestationdata # https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#attestationdata
AttestationData* = object AttestationData* = object
slot*: Slot # TODO remove this, once figure out attestation pool issues
# LMD GHOST vote # LMD GHOST vote
beacon_block_root*: Eth2Digest beacon_block_root*: Eth2Digest

View File

@ -118,7 +118,6 @@ func compute_committee(indices: seq[ValidatorIndex], seed: Eth2Digest,
start = (len(indices).uint64 * index) div count start = (len(indices).uint64 * index) div count
endIdx = (len(indices).uint64 * (index + 1)) div count endIdx = (len(indices).uint64 * (index + 1)) div count
key = (indices.len, seed) key = (indices.len, seed)
doAssert endIdx.int - start.int > 0
if key notin stateCache.crosslink_committee_cache: if key notin stateCache.crosslink_committee_cache:
stateCache.crosslink_committee_cache[key] = stateCache.crosslink_committee_cache[key] =

View File

@ -1,7 +1,7 @@
import import
confutils, stats, times, confutils, stats, times,
json, strformat, json, strformat,
options, sequtils, random, options, sequtils, random, tables,
../tests/[testutil], ../tests/[testutil],
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest, helpers, validator], ../beacon_chain/spec/[beaconstate, crypto, datatypes, digest, helpers, validator],
../beacon_chain/[attestation_pool, extras, ssz, state_transition, fork_choice] ../beacon_chain/[attestation_pool, extras, ssz, state_transition, fork_choice]
@ -45,8 +45,8 @@ proc writeJson*(prefix, slot, v: auto) =
discard open(f, fmt"{prefix:04}-{humaneSlotNum(slot):08}.json", fmWrite) discard open(f, fmt"{prefix:04}-{humaneSlotNum(slot):08}.json", fmWrite)
write(f, pretty(%*(v))) write(f, pretty(%*(v)))
cli do(slots = 1945, cli do(slots = 448,
validators = SLOTS_PER_EPOCH * 8, # One per shard is minimum validators = SLOTS_PER_EPOCH * 9, # One per shard is minimum
json_interval = SLOTS_PER_EPOCH, json_interval = SLOTS_PER_EPOCH,
prefix = 0, prefix = 0,
attesterRatio {.desc: "ratio of validators that attest in each round"} = 0.9, attesterRatio {.desc: "ratio of validators that attest in each round"} = 0.9,
@ -58,7 +58,7 @@ cli do(slots = 1945,
genesisBlock = get_initial_beacon_block(genesisState) genesisBlock = get_initial_beacon_block(genesisState)
var var
attestations: array[MIN_ATTESTATION_INCLUSION_DELAY, seq[Attestation]] attestations = initTable[Slot, seq[Attestation]]()
state = genesisState state = genesisState
latest_block_root = signing_root(genesisBlock) latest_block_root = signing_root(genesisBlock)
timers: array[Timers, RunningStat] timers: array[Timers, RunningStat]
@ -78,10 +78,13 @@ cli do(slots = 1945,
maybeWrite() maybeWrite()
let let
attestations_idx = state.slot mod MIN_ATTESTATION_INCLUSION_DELAY attestations_idx = state.slot
body = BeaconBlockBody(attestations: attestations[attestations_idx]) body = BeaconBlockBody(
attestations: attestations.getOrDefault(attestations_idx))
attestations[attestations_idx] = @[] attestations.del attestations_idx
doAssert len(attestations) <=
(SLOTS_PER_EPOCH.int + MIN_ATTESTATION_INCLUSION_DELAY.int)
let t = let t =
if (state.slot > GENESIS_SLOT and if (state.slot > GENESIS_SLOT and
@ -127,9 +130,19 @@ cli do(slots = 1945,
# add the attestation if any of the validators attested, as given # add the attestation if any of the validators attested, as given
# by the randomness. We have to delay when the attestation is # by the randomness. We have to delay when the attestation is
# actually added to the block per the attestation delay rule! # actually added to the block per the attestation delay rule!
attestations[ let target_slot =
(state.slot + MIN_ATTESTATION_INCLUSION_DELAY - 1) mod get_attestation_data_slot(state, attestation.data) +
MIN_ATTESTATION_INCLUSION_DELAY].add attestation MIN_ATTESTATION_INCLUSION_DELAY - 1
## In principle, should enumerate possible shard/slot combinations by
## inverting get_attestation_data_slot(...), but this works. Could be
## filtering earlier if we know that this attestation's being created
## too late to be useful, as well.
if target_slot > attestations_idx:
var target_slot_attestations =
getOrDefault(attestations, target_slot)
target_slot_attestations.add attestation
attestations[target_slot] = target_slot_attestations
flushFile(stdout) flushFile(stdout)

View File

@ -40,7 +40,7 @@ suite "Attestation pool processing" & preset():
let let
# Create an attestation for slot 1! # Create an attestation for slot 1!
crosslink_committee = get_crosslink_committee(state.data.data, crosslink_committee = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 0, cache) slot_to_epoch(state.data.data.slot), 1, cache)
attestation = makeAttestation( attestation = makeAttestation(
state.data.data, state.blck.root, crosslink_committee[0]) state.data.data, state.blck.root, crosslink_committee[0])
@ -61,7 +61,7 @@ suite "Attestation pool processing" & preset():
let let
# Create an attestation for slot 1! # Create an attestation for slot 1!
cc0 = get_crosslink_committee(state.data.data, cc0 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 0, cache) slot_to_epoch(state.data.data.slot), 1, cache)
attestation0 = makeAttestation( attestation0 = makeAttestation(
state.data.data, state.blck.root, cc0[0]) state.data.data, state.blck.root, cc0[0])
@ -69,7 +69,7 @@ suite "Attestation pool processing" & preset():
let let
cc1 = get_crosslink_committee(state.data.data, cc1 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 0, cache) slot_to_epoch(state.data.data.slot), 2, cache)
attestation1 = makeAttestation( attestation1 = makeAttestation(
state.data.data, state.blck.root, cc1[0]) state.data.data, state.blck.root, cc1[0])
@ -77,7 +77,8 @@ suite "Attestation pool processing" & preset():
pool.add(state.data.data, attestation1) pool.add(state.data.data, attestation1)
pool.add(state.data.data, attestation0) pool.add(state.data.data, attestation0)
for i in 0..<MIN_ATTESTATION_INCLUSION_DELAY.int - 1: advanceState(state.data) for i in 0..<MIN_ATTESTATION_INCLUSION_DELAY.int - 1:
advanceState(state.data)
let attestations = pool.getAttestationsForBlock( let attestations = pool.getAttestationsForBlock(
state.data.data, state.data.data.slot + 1) state.data.data, state.data.data.slot + 1)
@ -91,7 +92,7 @@ suite "Attestation pool processing" & preset():
let let
# Create an attestation for slot 1! # Create an attestation for slot 1!
cc0 = get_crosslink_committee(state.data.data, cc0 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 0, cache) slot_to_epoch(state.data.data.slot), 1, cache)
attestation0 = makeAttestation( attestation0 = makeAttestation(
state.data.data, state.blck.root, cc0[0]) state.data.data, state.blck.root, cc0[0])
attestation1 = makeAttestation( attestation1 = makeAttestation(
@ -115,7 +116,7 @@ suite "Attestation pool processing" & preset():
var var
# Create an attestation for slot 1! # Create an attestation for slot 1!
cc0 = get_crosslink_committee(state.data.data, cc0 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 0, cache) slot_to_epoch(state.data.data.slot), 1, cache)
attestation0 = makeAttestation( attestation0 = makeAttestation(
state.data.data, state.blck.root, cc0[0]) state.data.data, state.blck.root, cc0[0])
attestation1 = makeAttestation( attestation1 = makeAttestation(
@ -140,7 +141,7 @@ suite "Attestation pool processing" & preset():
var var
# Create an attestation for slot 1! # Create an attestation for slot 1!
cc0 = get_crosslink_committee(state.data.data, cc0 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 0, cache) slot_to_epoch(state.data.data.slot), 1, cache)
attestation0 = makeAttestation( attestation0 = makeAttestation(
state.data.data, state.blck.root, cc0[0]) state.data.data, state.blck.root, cc0[0])
attestation1 = makeAttestation( attestation1 = makeAttestation(