Updates for finalizing chain! (#162)

* set epoch_boundary_root - chain finalizes!
* fix slotStart to offset GENESIS_SLOT
* work around bug that will be fixed by
https://github.com/ethereum/eth2.0-specs/pull/732
* compile with debug info (there was a GC-related crash in C land)
This commit is contained in:
Jacek Sieka 2019-03-08 22:23:14 -06:00 committed by Dustin Brody
parent 0b47acae37
commit aec31b1126
8 changed files with 64 additions and 40 deletions

View File

@ -265,31 +265,23 @@ proc makeAttestation(node: BeaconNode,
var state = node.state.data
skipSlots(state, node.state.blck.root, slot)
# If we call makeAttestation too late, we must advance head only to `slot`
doAssert state.slot == slot,
"Corner case: head advanced beyond sheduled attestation slot"
let
justifiedBlockRoot =
get_block_root(state, get_epoch_start_slot(state.justified_epoch))
attestationData = AttestationData(
slot: slot,
shard: shard,
beacon_block_root: node.state.blck.root,
epoch_boundary_root: Eth2Digest(), # TODO
crosslink_data_root: Eth2Digest(), # TODO
latest_crosslink: state.latest_crosslinks[shard],
justified_epoch: state.justified_epoch,
justified_block_root: justifiedBlockRoot)
attestationData = makeAttestationData(state, shard, node.state.blck.root)
validatorSignature = await validator.signAttestation(attestationData)
var participationBitfield = repeat(0'u8, ceil_div8(committeeLen))
bitSet(participationBitfield, indexInCommittee)
var aggregationBitfield = repeat(0'u8, ceil_div8(committeeLen))
bitSet(aggregationBitfield, indexInCommittee)
var attestation = Attestation(
data: attestationData,
aggregate_signature: validatorSignature,
aggregation_bitfield: participationBitfield,
aggregation_bitfield: aggregationBitfield,
# Stub in phase0
custody_bitfield: newSeq[byte](participationBitfield.len)
custody_bitfield: newSeq[byte](aggregationBitfield.len)
)
# TODO what are we waiting for here? broadcast should never block, and never

View File

@ -247,6 +247,15 @@ proc add*(
return true
# This is an unresolved block - put it on the unresolved list for now...
# TODO if we receive spam blocks, one heurestic to implement might be to wait
# for a couple of attestations to appear before fetching parents - this
# would help prevent using up network resources for spam - this serves
# two purposes: one is that attestations are likely to appear for the
# block only if it's valid / not spam - the other is that malicious
# validators that are not proposers can sign invalid blocks and send
# them out without penalty - but signing invalid attestations carries
# a risk of being slashed, making attestations a more valuable spam
# filter.
debug "Unresolved block",
slot = humaneSlotNum(blck.slot),
stateRoot = shortLog(blck.state_root),
@ -322,7 +331,7 @@ proc maybePutState(pool: BlockPool, state: BeaconState) =
if state.slot mod SLOTS_PER_EPOCH == 0:
info "Storing state",
stateSlot = humaneSlotNum(state.slot),
stateRoot = hash_tree_root_final(state) # TODO cache?
stateRoot = shortLog(hash_tree_root_final(state)) # TODO cache?
pool.db.putState(state)
proc updateState*(

View File

@ -279,14 +279,15 @@ func get_attestation_participants*(state: BeaconState,
## ``bitfield``.
let crosslink_committees = get_crosslink_committees_at_slot(
state, attestation_data.slot)
assert anyIt(
doAssert anyIt(
crosslink_committees,
it[1] == attestation_data.shard)
let crosslink_committee = mapIt(
filterIt(crosslink_committees, it.shard == attestation_data.shard),
it.committee)[0]
# TODO this and other attestation-based fields need validation so we don't
# crash on a malicious attestation!
doAssert verify_bitfield(bitfield, len(crosslink_committee))
# Find the participating attesters in the committee
@ -493,3 +494,31 @@ func prepare_validator_for_withdrawal*(state: var BeaconState, index: ValidatorI
# Bug in 0.3.0 spec; constant got renamed. Use 0.3.0 name.
validator.withdrawable_epoch = get_current_epoch(state) +
MIN_VALIDATOR_WITHDRAWABILITY_DELAY
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/validator/0_beacon-chain-validator.md#attestations-1
proc makeAttestationData*(
state: BeaconState, shard: uint64,
beacon_block_root: Eth2Digest): AttestationData =
## Fine points:
## Head must be the head state during the slot that validator is
## part of committee - notably, it can't be a newer or older state (!)
# TODO update when https://github.com/ethereum/eth2.0-specs/issues/742
let
epoch_start_slot = get_epoch_start_slot(slot_to_epoch(state.slot))
epoch_boundary_root =
if epoch_start_slot == state.slot: beacon_block_root
else: get_block_root(state, epoch_start_slot)
justified_slot = get_epoch_start_slot(state.justified_epoch)
justified_block_root = get_block_root(state, justified_slot)
AttestationData(
slot: state.slot,
shard: shard,
beacon_block_root: beacon_block_root,
epoch_boundary_root: epoch_boundary_root,
crosslink_data_root: Eth2Digest(), # Stub in phase0
latest_crosslink: state.latest_crosslinks[shard],
justified_epoch: state.justified_epoch,
justified_block_root: justified_block_root,
)

View File

@ -134,17 +134,20 @@ func get_crosslink_committees_at_slot*(state: BeaconState, slot: Slot,
## ``slot`` in the next epoch -- with and without a `registry_change`
let
epoch = slot_to_epoch(slot)
# TODO: the + 1 here works around a bug, remove when upgrading to
# some more recent version:
# https://github.com/ethereum/eth2.0-specs/pull/732
epoch = slot_to_epoch(slot + 1)
current_epoch = get_current_epoch(state)
previous_epoch = get_previous_epoch(state)
next_epoch = current_epoch + 1
assert previous_epoch <= epoch,
doAssert previous_epoch <= epoch,
"Previous epoch: " & $humaneEpochNum(previous_epoch) &
", epoch: " & $humaneEpochNum(epoch) &
", Next epoch: " & $humaneEpochNum(next_epoch)
assert epoch <= next_epoch,
doAssert epoch <= next_epoch,
"Previous epoch: " & $humaneEpochNum(previous_epoch) &
", epoch: " & $humaneEpochNum(epoch) &
", Next epoch: " & $humaneEpochNum(next_epoch)
@ -170,7 +173,7 @@ func get_crosslink_committees_at_slot*(state: BeaconState, slot: Slot,
shuffling_start_shard = state.current_shuffling_start_shard
(committees_per_epoch, seed, shuffling_epoch, shuffling_start_shard)
else:
assert epoch == next_epoch
doAssert epoch == next_epoch
let
current_committees_per_epoch = get_current_epoch_committee_count(state)

View File

@ -21,7 +21,7 @@ proc getSlotFromTime*(s: BeaconState, t = now()): Slot =
int64(SECONDS_PER_SLOT * 1000))
func slotStart*(s: BeaconState, slot: Slot): Timestamp =
(s.genesis_time + (slot * SECONDS_PER_SLOT)) * 1000
(s.genesis_time + ((slot - GENESIS_SLOT) * SECONDS_PER_SLOT)) * 1000
func slotMiddle*(s: BeaconState, slot: Slot): Timestamp =
s.slotStart(slot) + SECONDS_PER_SLOT * 500

View File

@ -37,7 +37,7 @@ if [ ! -f $LAST_VALIDATOR ]; then
fi
if [[ -z "$SKIP_BUILDS" ]]; then
nim c -o:"$BEACON_NODE_BIN" $DEFS --opt:speed beacon_chain/beacon_node
nim c -o:"$BEACON_NODE_BIN" $DEFS --opt:speed --debuginfo beacon_chain/beacon_node
fi
if [ ! -f $SNAPSHOT_FILE ]; then

View File

@ -168,17 +168,7 @@ proc makeAttestation*(
get_crosslink_committees_at_slot(state, state.slot), validator_index)
validator = state.validator_registry[validator_index]
sac_index = sac.committee.find(validator_index)
data = AttestationData(
slot: state.slot,
shard: sac.shard,
beacon_block_root: beacon_block_root,
epoch_boundary_root: Eth2Digest(), # TODO
latest_crosslink: state.latest_crosslinks[sac.shard],
crosslink_data_root: Eth2Digest(), # TODO
justified_epoch: state.justified_epoch,
justified_block_root: get_block_root(state, get_epoch_start_slot(state.justified_epoch)),
)
data = makeAttestationData(state, sac.shard, beacon_block_root)
assert sac_index != -1, "find_shard_committe should guarantee this"
@ -187,7 +177,8 @@ proc makeAttestation*(
bitSet(aggregation_bitfield, sac_index)
let
msg = hash_tree_root_final(AttestationDataAndCustodyBit(data: data, custody_bit: false))
msg = hash_tree_root_final(
AttestationDataAndCustodyBit(data: data, custody_bit: false))
sig =
if skipValidation notin flags:
bls_sign(
@ -203,7 +194,7 @@ proc makeAttestation*(
data: data,
aggregation_bitfield: aggregation_bitfield,
aggregate_signature: sig,
custody_bitfield: repeat(0'u8, ceil_div8(sac.committee.len))
custody_bitfield: repeat(0'u8, aggregation_bitfield.len)
)
proc makeTestDB*(tailState: BeaconState, tailBlock: BeaconBlock): BeaconChainDB =