Skip to content

Commit

Permalink
Updates for finalizing chain!
Browse files Browse the repository at this point in the history
* set epoch_boundary_root - chain finalizes!
* fix slotStart to offset GENESIS_SLOT
* work around bug that will be fixed by
ethereum/consensus-specs#732
* compile with debug info (there was a GC-related crash in C land)
  • Loading branch information
arnetheduck committed Mar 8, 2019
1 parent 0b47aca commit c1727cf
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 40 deletions.
26 changes: 9 additions & 17 deletions beacon_chain/beacon_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -265,31 +265,23 @@ proc makeAttestation(node: BeaconNode,
var state = node.state.data
skipSlots(state, node.state.blck.root, 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)
# 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
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
Expand Down
11 changes: 10 additions & 1 deletion beacon_chain/block_pool.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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*(
Expand Down
33 changes: 31 additions & 2 deletions beacon_chain/spec/beaconstate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
)
2 changes: 1 addition & 1 deletion beacon_chain/spec/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func get_current_epoch_committee_count*(state: BeaconState): uint64 =
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_current_epoch
func get_current_epoch*(state: BeaconState): Epoch =
# Return the current epoch of the given ``state``.
doAssert state.slot >= GENESIS_SLOT, $state.slot
doAssert state.slot >= GENESIS_SLOT, $state.slot
slot_to_epoch(state.slot)

# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_randao_mix
Expand Down
11 changes: 7 additions & 4 deletions beacon_chain/spec/validator.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/time.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion tests/simulation/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 4 additions & 13 deletions tests/testutil.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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(
Expand All @@ -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 =
Expand Down

0 comments on commit c1727cf

Please sign in to comment.