mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-01-22 04:24:05 +00:00
Spec update to v0.1 (#88)
* update based on https://github.com/ethereum/eth2.0-specs/pull/483 * more spec updates
This commit is contained in:
parent
788b093284
commit
2d71b998c7
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user