From 2d71b998c7abfc4b17d7ef49a13d378069efe8e9 Mon Sep 17 00:00:00 2001 From: Dustin Brody Date: Thu, 7 Feb 2019 10:43:21 +0000 Subject: [PATCH] Spec update to v0.1 (#88) * update based on https://github.com/ethereum/eth2.0-specs/pull/483 * more spec updates --- beacon_chain/beacon_node.nim | 6 +---- beacon_chain/spec/beaconstate.nim | 15 ++---------- beacon_chain/spec/datatypes.nim | 28 +++++++--------------- beacon_chain/spec/helpers.nim | 5 ++-- beacon_chain/state_transition.nim | 40 ++++++++++++++----------------- tests/testutil.nim | 11 +-------- 6 files changed, 33 insertions(+), 72 deletions(-) diff --git a/beacon_chain/beacon_node.nim b/beacon_chain/beacon_node.nim index dec7c843c..8edec0fe2 100644 --- a/beacon_chain/beacon_node.nim +++ b/beacon_chain/beacon_node.nim @@ -206,17 +206,13 @@ proc proposeBlock(node: BeaconNode, let ok = updateState(state, node.headBlockRoot, none[BeaconBlock](), {}) doAssert ok - let - randaoCommitment = node.beaconState.validator_registry[validator.idx].randao_commitment - randaoReveal = await validator.randaoReveal(randaoCommitment) - var blockBody = BeaconBlockBody( attestations: node.attestationPool.getAttestationsForBlock(node.beaconState, slot)) var newBlock = BeaconBlock( slot: slot, parent_root: node.headBlockRoot, - randao_reveal: randaoReveal, + randao_reveal: ValidatorSig(), # TODO probably wrong eth1_data: node.mainchainMonitor.getBeaconBlockRef(), signature: ValidatorSig(), # we need the rest of the block first! body: blockBody) diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 8db47ff33..43525d3b4 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -26,12 +26,10 @@ func sum_effective_balances*( func validate_proof_of_possession(state: BeaconState, pubkey: ValidatorPubKey, proof_of_possession: ValidatorSig, - withdrawal_credentials: Eth2Digest, - randao_commitment: Eth2Digest): bool = + withdrawal_credentials: Eth2Digest): bool = let proof_of_possession_data = DepositInput( pubkey: pubkey, withdrawal_credentials: withdrawal_credentials, - randao_commitment: randao_commitment ) bls_verify( @@ -57,8 +55,7 @@ func process_deposit(state: var BeaconState, # TODO return error; currently, just fails if ever called # but hadn't been set up to run at all doAssert validate_proof_of_possession( - state, pubkey, proof_of_possession, withdrawal_credentials, - randao_commitment) + state, pubkey, proof_of_possession, withdrawal_credentials) let validator_pubkeys = state.validator_registry.mapIt(it.pubkey) @@ -67,13 +64,10 @@ func process_deposit(state: var BeaconState, let validator = Validator( pubkey: pubkey, withdrawal_credentials: withdrawal_credentials, - randao_commitment: randao_commitment, - randao_layers: 0, activation_epoch: FAR_FUTURE_EPOCH, exit_epoch: FAR_FUTURE_EPOCH, withdrawal_epoch: FAR_FUTURE_EPOCH, penalized_epoch: FAR_FUTURE_EPOCH, - exit_count: 0, status_flags: 0, ) @@ -121,10 +115,6 @@ func exit_validator*(state: var BeaconState, validator.exit_epoch = get_entry_exit_effect_epoch(get_current_epoch(state)) - # The following updates only occur if not previous exited - state.validator_registry_exit_count += 1 - validator.exit_count = state.validator_registry_exit_count - func process_penalties_and_exits(state: var BeaconState) = let current_epoch = get_current_epoch(state) @@ -188,7 +178,6 @@ func get_initial_beacon_state*( ), validator_registry_update_epoch: GENESIS_EPOCH, - validator_registry_exit_count: 0, validator_registry_delta_chain_tip: ZERO_HASH, # Randomness and committees diff --git a/beacon_chain/spec/datatypes.nim b/beacon_chain/spec/datatypes.nim index 95118cec4..f0237aead 100644 --- a/beacon_chain/spec/datatypes.nim +++ b/beacon_chain/spec/datatypes.nim @@ -259,14 +259,16 @@ type proof_of_possession*: ValidatorSig ##\ ## BLS proof of possession (a BLS signature) + # https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#exit Exit* = object - # Minimum slot for processing exit - slot*: uint64 + # Minimum epoch for processing exit + epoch*: uint64 # Index of the exiting validator validator_index*: ValidatorIndex # Validator signature signature*: ValidatorSig + # https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#beaconblock BeaconBlock* = object ## For each slot, a proposer is chosen from the validator pool to propose ## a new block. Once the block as been proposed, it is transmitted to @@ -281,7 +283,7 @@ type state_root*: Eth2Digest ##\ ##\ The state root, _after_ this block has been processed - randao_reveal*: Eth2Digest ##\ + randao_reveal*: ValidatorSig ##\ ## Proposer RANDAO reveal eth1_data*: Eth1Data @@ -291,6 +293,7 @@ type body*: BeaconBlockBody + # https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#beaconblockbody BeaconBlockBody* = object proposer_slashings*: seq[ProposerSlashing] attester_slashings*: seq[AttesterSlashing] @@ -298,12 +301,14 @@ type deposits*: seq[Deposit] exits*: seq[Exit] + # https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#proposalsigneddata ProposalSignedData* = object slot*: uint64 shard*: uint64 ##\ ## Shard number (or `BEACON_CHAIN_SHARD_NUMBER` for beacon chain) block_root*: Eth2Digest + # https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#beaconstate BeaconState* = object slot*: uint64 genesis_time*: uint64 @@ -316,7 +321,6 @@ type ## Validator balances in Gwei! validator_registry_update_epoch*: uint64 - validator_registry_exit_count*: uint64 # TODO remove, not in spec anymore validator_registry_delta_chain_tip*: Eth2Digest ##\ @@ -356,19 +360,6 @@ type pubkey*: ValidatorPubKey withdrawal_credentials*: Eth2Digest - # TODO remove randao_commitment, randao_layers - randao_commitment*: Eth2Digest ##\ - ## RANDAO commitment created by repeatedly taking the hash of a secret value - ## so as to create "onion layers" around it. For every block that a - ## validator proposes, one level of the onion is peeled. See: - ## * https://ethresear.ch/t/rng-exploitability-analysis-assuming-pure-randao-based-main-chain/1825 - ## * repeat_hash - ## * processRandaoReveal - - randao_layers*: uint64 ##\ - ## Number of proposals the proposer missed, and thus the number of times to - ## apply hash function to randao reveal - activation_epoch*: EpochNumber ##\ ## Slot when validator activated @@ -381,9 +372,6 @@ type penalized_epoch*: EpochNumber ##\ ## Slot when validator penalized - exit_count*: uint64 ##\ - ## Exit counter when validator exited (or 0) - status_flags*: uint64 Crosslink* = object diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index 24e7c1977..e19d29481 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -140,9 +140,10 @@ func get_fork_version*(fork: Fork, epoch: EpochNumber): uint64 = fork.current_version func get_domain*( - fork: Fork, slot: uint64, domain_type: SignatureDomain): uint64 = + fork: Fork, epoch: EpochNumber, domain_type: SignatureDomain): uint64 = # TODO Slot overflow? Or is slot 32 bits for all intents and purposes? - (get_fork_version(fork, slot) shl 32) + domain_type.uint32 + # Get the domain number that represents the fork meta and signature domain. + (get_fork_version(fork, epoch) shl 32) + domain_type.uint32 func is_power_of_2*(v: uint64): bool = (v and (v-1)) == 0 diff --git a/beacon_chain/state_transition.nim b/beacon_chain/state_transition.nim index 5249edc8f..c18bf2a4f 100644 --- a/beacon_chain/state_transition.nim +++ b/beacon_chain/state_transition.nim @@ -85,21 +85,23 @@ proc processRandao( if skipValidation notin flags: # Check that proposer commit and reveal match - let expected = repeat_hash(blck.randao_reveal, proposer.randao_layers) - if expected != proposer.randao_commitment: - notice "Randao reveal mismatch", reveal = blck.randao_reveal, - layers = proposer.randao_layers, - commitment = proposer.randao_commitment, - expected - return false + # TODO re-enable if appropriate + #let expected = repeat_hash(blck.randao_reveal, proposer.randao_layers) + #if expected != proposer.randao_commitment: + # notice "Randao reveal mismatch", reveal = blck.randao_reveal, + # layers = proposer.randao_layers, + # commitment = proposer.randao_commitment, + # expected + # return false + discard # Update state and proposer now that we're alright - let mix = state.slot mod LATEST_RANDAO_MIXES_LENGTH - for i, b in state.latest_randao_mixes[mix].data: - state.latest_randao_mixes[mix].data[i] = b xor blck.randao_reveal.data[i] + let + mix = get_current_epoch(state) mod LATEST_RANDAO_MIXES_LENGTH + rr = hash_tree_root_final(blck.randao_reveal).data - proposer.randao_commitment = blck.randao_reveal - proposer.randao_layers = 0 + for i, b in state.latest_randao_mixes[mix].data: + state.latest_randao_mixes[mix].data[i] = b xor rr[i] return true @@ -303,7 +305,7 @@ proc processExits( if skipValidation notin flags: if not bls_verify( validator.pubkey, ZERO_HASH.data, exit.signature, - get_domain(state.fork, exit.slot, DOMAIN_EXIT)): + get_domain(state.fork, exit.epoch, DOMAIN_EXIT)): notice "Exit: invalid signature" return false @@ -311,8 +313,8 @@ proc processExits( notice "Exit: exit/entry too close" return false - if not (state.slot >= exit.slot): - notice "Exit: bad slot" + if not (get_current_epoch(state) >= exit.epoch): + notice "Exit: bad epoch" return false initiate_validator_exit(state, exit.validator_index) @@ -336,16 +338,10 @@ func processSlot(state: var BeaconState, previous_block_root: Eth2Digest) = ## chain at that time. In case the proposer is missing, it may happen that ## the no block is produced during the slot. ## - ## https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#per-slot-processing - + ## https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#per-slot-processing state.slot += 1 - state.validator_registry[ - get_beacon_proposer_index(state, state.slot)].randao_layers += 1 - state.latest_randao_mixes[state.slot mod LATEST_RANDAO_MIXES_LENGTH] = - state.latest_randao_mixes[(state.slot - 1) mod LATEST_RANDAO_MIXES_LENGTH] state.latest_block_roots[(state.slot - 1) mod LATEST_BLOCK_ROOTS_LENGTH] = previous_block_root - if state.slot mod LATEST_BLOCK_ROOTS_LENGTH == 0: state.batched_block_roots.add(merkle_root(state.latest_block_roots)) diff --git a/tests/testutil.nim b/tests/testutil.nim index 31446bd09..bc2771bd0 100644 --- a/tests/testutil.nim +++ b/tests/testutil.nim @@ -28,15 +28,6 @@ func hackPrivKey(v: Validator): ValidatorPrivKey = min(sizeof(v.withdrawal_credentials.data), sizeof(i))) makeValidatorPrivKey(i) -func hackReveal(v: Validator): Eth2Digest = - result = v.withdrawal_credentials - for i in 0..randaoRounds: - let tmp = repeat_hash(result, 1) - if tmp == v.randao_commitment: - return - result = tmp - raise newException(Exception, "can't find randao hack value") - func makeDeposit(i: int, flags: UpdateFlags): Deposit = ## Ugly hack for now: we stick the private key in withdrawal_credentials ## which means we can repro private key and randao reveal from this data, @@ -114,7 +105,7 @@ proc addBlock*( slot: state.slot + 1, parent_root: previous_block_root, state_root: Eth2Digest(), # we need the new state first - randao_reveal: hackReveal(proposer), + randao_reveal: ValidatorSig(), # TODO eth1_data: Eth1Data(), # TODO signature: ValidatorSig(), # we need the rest of the block first! body: body