From 0e9cc20cfe34a9dc10eaa2831b5603fd4c49a3d4 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Fri, 15 Feb 2019 10:33:32 -0600 Subject: [PATCH] beacon node simplifications (#116) * remove previous randao scheme code * fix some epoch logging * move genesis time selection to state generation --- beacon_chain/beacon_node.nim | 13 ++++++++++--- beacon_chain/conf.nim | 7 +++++-- beacon_chain/spec/beaconstate.nim | 5 ----- beacon_chain/spec/datatypes.nim | 3 +++ beacon_chain/spec/helpers.nim | 5 +++++ beacon_chain/spec/validator.nim | 11 +++++++++-- beacon_chain/time.nim | 13 +++++++------ beacon_chain/trusted_state_snapshots.nim | 10 ++++++---- beacon_chain/validator_keygen.nim | 3 +-- tests/simulation/start.sh | 6 +++--- 10 files changed, 49 insertions(+), 27 deletions(-) diff --git a/beacon_chain/beacon_node.nim b/beacon_chain/beacon_node.nim index e313f46c5..25a01c9ca 100644 --- a/beacon_chain/beacon_node.nim +++ b/beacon_chain/beacon_node.nim @@ -102,6 +102,11 @@ proc sync*(node: BeaconNode): Future[bool] {.async.} = if t < node.beaconState.genesisTime * 1000: await sleepAsync int(node.beaconState.genesisTime * 1000 - t) + # TODO: change this to a full sync / block download + info "Syncing state from remote peers", + finalized_epoch = humaneEpochNum(node.beaconState.finalized_epoch), + target_slot_epoch = humaneEpochNum(targetSlot.slot_to_epoch) + while node.beaconState.finalized_epoch < targetSlot.slot_to_epoch: var (peer, changeLog) = await node.network.getValidatorChangeLog( node.beaconState.validator_registry_delta_chain_tip) @@ -284,7 +289,7 @@ proc scheduleEpochActions(node: BeaconNode, epoch: uint64) = ## attestations from our attached validators. doAssert node != nil - debug "Scheduling epoch actions", epoch + debug "Scheduling epoch actions", epoch = humaneEpochNum(epoch) # TODO: this copy of the state shouldn't be necessary, but please # see the comments in `get_beacon_proposer_index` @@ -320,7 +325,7 @@ proc scheduleEpochActions(node: BeaconNode, epoch: uint64) = node.lastScheduledEpoch = epoch let - nextEpoch = epoch + 1 + nextEpoch = humaneEpochNum(epoch + 1) at = node.beaconState.slotMiddle(nextEpoch * EPOCH_LENGTH) info "Scheduling next epoch update", @@ -416,7 +421,9 @@ when isMainModule: case config.cmd of createChain: - createStateSnapshot(config.chainStartupData, config.outputStateFile.string) + createStateSnapshot( + config.chainStartupData, config.genesisOffset, + config.outputStateFile.string) quit 0 of noCommand: diff --git a/beacon_chain/conf.nim b/beacon_chain/conf.nim index e42d56282..5fad6e1ab 100644 --- a/beacon_chain/conf.nim +++ b/beacon_chain/conf.nim @@ -16,7 +16,6 @@ type ChainStartupData* = object validatorDeposits*: seq[Deposit] - genesisTime*: Timestamp PrivateValidatorData* = object privKey*: ValidatorPrivKey @@ -69,6 +68,11 @@ type desc: "" shortform: "c".}: ChainStartupData + genesisOffset* {. + desc: "Seconds from now to add to genesis time" + shortForm: "g" + defaultValue: 0 .}: int + outputStateFile* {. desc: "Output file where to write the initial state snapshot" longform: "out" @@ -96,4 +100,3 @@ template handledAsJsonFilename(T: untyped) {.dirty.} = handledAsJsonFilename BeaconState handledAsJsonFilename ChainStartupData handledAsJsonFilename PrivateValidatorData - diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 27a128eed..2017ad510 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -334,11 +334,6 @@ func update_validator_registry*(state: var BeaconState) = process_penalties_and_exits(state) -# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#get_epoch_start_slot -func get_epoch_start_slot*(epoch: EpochNumber): SlotNumber = - # Return the starting slot of the given ``epoch``. - epoch * EPOCH_LENGTH - ## https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#attestations-1 proc checkAttestation*( state: BeaconState, attestation: Attestation, flags: UpdateFlags): bool = diff --git a/beacon_chain/spec/datatypes.nim b/beacon_chain/spec/datatypes.nim index 7266e6148..a900cb513 100644 --- a/beacon_chain/spec/datatypes.nim +++ b/beacon_chain/spec/datatypes.nim @@ -487,6 +487,9 @@ func shortValidatorKey*(state: BeaconState, validatorIdx: int): string = func humaneSlotNum*(s: SlotNumber): SlotNumber = s - GENESIS_SLOT +func humaneEpochNum*(e: EpochNumber): EpochNumber = + e - GENESIS_EPOCH + export writeValue, readValue diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index 9bc4979fd..d820f1c6a 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -102,6 +102,11 @@ func merkle_root*(values: openArray[Eth2Digest]): Eth2Digest = func slot_to_epoch*(slot: SlotNumber): EpochNumber = slot div EPOCH_LENGTH +# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#get_epoch_start_slot +func get_epoch_start_slot*(epoch: EpochNumber): SlotNumber = + # Return the starting slot of the given ``epoch``. + epoch * EPOCH_LENGTH + # https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#is_double_vote func is_double_vote*(attestation_data_1: AttestationData, attestation_data_2: AttestationData): bool = diff --git a/beacon_chain/spec/validator.nim b/beacon_chain/spec/validator.nim index f461250cb..15399e7b9 100644 --- a/beacon_chain/spec/validator.nim +++ b/beacon_chain/spec/validator.nim @@ -144,8 +144,15 @@ func get_crosslink_committees_at_slot*(state: BeaconState, slot: uint64, previous_epoch = get_previous_epoch(state) next_epoch = current_epoch + 1 - assert previous_epoch <= epoch, "Previous epoch: " & $previous_epoch & ", epoch: " & $epoch & ", Next epoch: " & $next_epoch - assert epoch <= next_epoch, "Previous epoch: " & $previous_epoch & ", epoch: " & $epoch & ", Next epoch: " & $next_epoch + assert previous_epoch <= epoch, + "Previous epoch: " & $humaneEpochNum(previous_epoch) & + ", epoch: " & $humaneEpochNum(epoch) & + ", Next epoch: " & $humaneEpochNum(next_epoch) + + assert epoch <= next_epoch, + "Previous epoch: " & $humaneEpochNum(previous_epoch) & + ", epoch: " & $humaneEpochNum(epoch) & + ", Next epoch: " & $humaneEpochNum(next_epoch) # TODO - Hack: used to be "epoch < next_epoch" (exlusive interval) # until https://github.com/status-im/nim-beacon-chain/issues/97 diff --git a/beacon_chain/time.nim b/beacon_chain/time.nim index d2e3fd34a..972ae7733 100644 --- a/beacon_chain/time.nim +++ b/beacon_chain/time.nim @@ -1,7 +1,7 @@ import random, chronos, - spec/datatypes + spec/[datatypes, helpers] type Timestamp* = uint64 # Unix epoch timestamp in millisecond resolution @@ -20,17 +20,18 @@ proc getSlotFromTime*(s: BeaconState, t = now()): SlotNumber = GENESIS_SLOT + uint64((int64(t - s.genesis_time * 1000) - detectedClockDrift) div int64(SLOT_DURATION * 1000)) -template slotStart*(s: BeaconState, slot: uint64): Timestamp = +func slotStart*(s: BeaconState, slot: SlotNumber): Timestamp = (s.genesis_time + (slot * SLOT_DURATION)) * 1000 -template slotMiddle*(s: BeaconState, slot: uint64): Timestamp = +func slotMiddle*(s: BeaconState, slot: SlotNumber): Timestamp = s.slotStart(slot) + SLOT_DURATION * 500 -template slotEnd*(s: BeaconState, slot: uint64): Timestamp = +func slotEnd*(s: BeaconState, slot: SlotNumber): Timestamp = + # TODO this is actually past the end, by nim inclusive semantics (sigh) s.slotStart(slot + 1) proc randomTimeInSlot*(s: BeaconState, - slot: uint64, + slot: SlotNumber, interval: HSlice[float, float]): Timestamp = ## Returns a random moment within the slot. ## The interval must be a sub-interval of [0..1]. @@ -39,7 +40,7 @@ proc randomTimeInSlot*(s: BeaconState, proc slotDistanceFromNow*(s: BeaconState): int64 = ## Returns how many slots have passed since a particular BeaconState was finalized - int64(s.timeSinceGenesis() div (SLOT_DURATION * EPOCH_LENGTH * 1000)) - int64(s.finalized_epoch) + int64(s.getSlotFromTime() - s.finalized_epoch.get_epoch_start_slot) proc synchronizeClock*() {.async.} = ## This should determine the offset of the local clock against a global diff --git a/beacon_chain/trusted_state_snapshots.nim b/beacon_chain/trusted_state_snapshots.nim index 772da77bc..da1abe62f 100644 --- a/beacon_chain/trusted_state_snapshots.nim +++ b/beacon_chain/trusted_state_snapshots.nim @@ -29,10 +29,12 @@ proc obtainTrustedStateSnapshot*(db: BeaconChainDB): Future[BeaconState] {.async assert(false, "Not implemented") -proc createStateSnapshot*(startup: ChainStartupData, outFile: string) = - let initialState = get_initial_beacon_state(startup.validatorDeposits, - startup.genesisTime, - Eth1Data(), {}) +proc createStateSnapshot*( + startup: ChainStartupData, genesisOffset: int, outFile: string) = + let initialState = get_initial_beacon_state( + startup.validatorDeposits, + uint64(int(fastEpochTime() div 1000) + genesisOffset), + Eth1Data(), {}) var vr: Validator Json.saveFile(outFile, initialState, pretty = true) diff --git a/beacon_chain/validator_keygen.nim b/beacon_chain/validator_keygen.nim index b6e2029f4..012f8cdeb 100644 --- a/beacon_chain/validator_keygen.nim +++ b/beacon_chain/validator_keygen.nim @@ -12,6 +12,7 @@ proc genSingleValidator(path: string): (ValidatorPubKey, ValidatorPrivKey) = var v: PrivateValidatorData v.privKey = newPrivKey() + writeFile(path, v) assert v.privKey != ValidatorPrivKey(), "Private key shouldn't be zero" @@ -61,7 +62,5 @@ cli do (validators: int, proof_of_possession: proofOfPossession, withdrawal_credentials: withdrawalCredentials))) - startupData.genesisTime = uint64(int(now() div 1000) + startupDelay) - writeFile(outputDir / "startup.json", startupData) diff --git a/tests/simulation/start.sh b/tests/simulation/start.sh index e030965ff..d5695e455 100755 --- a/tests/simulation/start.sh +++ b/tests/simulation/start.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -eu +set -eux # Kill children on ctrl-c trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT @@ -37,13 +37,13 @@ if [[ -z "$SKIP_BUILDS" ]]; then fi if [ ! -f $STARTUP_FILE ]; then - $VALIDATOR_KEYGEN_BIN --validators=$NUMBER_OF_VALIDATORS --outputDir="$SIMULATION_DIR" # --startupDelay=2 + $VALIDATOR_KEYGEN_BIN --validators=$NUMBER_OF_VALIDATORS --outputDir="$SIMULATION_DIR" fi if [ ! -f $SNAPSHOT_FILE ]; then $BEACON_NODE_BIN createChain \ --chainStartupData:$STARTUP_FILE \ - --out:$SNAPSHOT_FILE + --out:$SNAPSHOT_FILE # --genesisOffset=2 fi MASTER_NODE_ADDRESS_FILE="$SIMULATION_DIR/node-0/beacon_node.address"