more 0.4.0 spec updates: renamings, continue Proposal updates, and note several more functions which were verified not to have changed in 0.4.0 (#163)
This commit is contained in:
parent
89aa3ec53f
commit
13de015038
|
@ -324,8 +324,9 @@ proc proposeBlock(node: BeaconNode,
|
|||
parent_root: node.state.blck.root,
|
||||
randao_reveal: validator.genRandaoReveal(state, slot),
|
||||
eth1_data: node.mainchainMonitor.getBeaconBlockRef(),
|
||||
body: blockBody,
|
||||
signature: ValidatorSig(), # we need the rest of the block first!
|
||||
body: blockBody)
|
||||
)
|
||||
|
||||
let ok =
|
||||
updateState(state, node.state.blck.root, newBlock, {skipValidation})
|
||||
|
@ -333,12 +334,13 @@ proc proposeBlock(node: BeaconNode,
|
|||
|
||||
newBlock.state_root = Eth2Digest(data: hash_tree_root(state))
|
||||
|
||||
var signedData = ProposalSignedData(
|
||||
let proposal = Proposal(
|
||||
slot: slot,
|
||||
shard: BEACON_CHAIN_SHARD_NUMBER,
|
||||
blockRoot: hash_tree_root_final(newBlock))
|
||||
|
||||
newBlock.signature = await validator.signBlockProposal(state.fork, signedData)
|
||||
block_root: Eth2Digest(data: signed_root(newBlock, "signature")),
|
||||
signature: ValidatorSig(),
|
||||
)
|
||||
newBlock.signature = await validator.signBlockProposal(state.fork, proposal)
|
||||
|
||||
# TODO what are we waiting for here? broadcast should never block, and never
|
||||
# fail...
|
||||
|
|
|
@ -61,25 +61,25 @@ func process_deposit(state: var BeaconState, deposit: Deposit) =
|
|||
|
||||
state.validator_balances[index] += amount
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_entry_exit_effect_epoch
|
||||
func get_entry_exit_effect_epoch*(epoch: Epoch): Epoch =
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_delayed_activation_exit_epoch
|
||||
func get_delayed_activation_exit_epoch*(epoch: Epoch): Epoch =
|
||||
## An entry or exit triggered in the ``epoch`` given by the input takes effect at
|
||||
## the epoch given by the output.
|
||||
epoch + 1 + ACTIVATION_EXIT_DELAY
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#activate_validator
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#activate_validator
|
||||
func activate_validator(state: var BeaconState,
|
||||
index: ValidatorIndex,
|
||||
genesis: bool) =
|
||||
is_genesis: bool) =
|
||||
## Activate the validator with the given ``index``.
|
||||
## Note that this function mutates ``state``.
|
||||
let validator = addr state.validator_registry[index]
|
||||
|
||||
validator.activation_epoch =
|
||||
if genesis:
|
||||
if is_genesis:
|
||||
GENESIS_EPOCH
|
||||
else:
|
||||
get_entry_exit_effect_epoch(get_current_epoch(state))
|
||||
get_delayed_activation_exit_epoch(get_current_epoch(state))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#initiate_validator_exit
|
||||
func initiate_validator_exit*(state: var BeaconState,
|
||||
|
@ -89,7 +89,7 @@ func initiate_validator_exit*(state: var BeaconState,
|
|||
var validator = addr state.validator_registry[index]
|
||||
validator.initiated_exit = true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#exit_validator
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#exit_validator
|
||||
func exit_validator*(state: var BeaconState,
|
||||
index: ValidatorIndex) =
|
||||
## Exit the validator with the given ``index``.
|
||||
|
@ -98,10 +98,10 @@ func exit_validator*(state: var BeaconState,
|
|||
let validator = addr state.validator_registry[index]
|
||||
|
||||
# The following updates only occur if not previous exited
|
||||
if validator.exit_epoch <= get_entry_exit_effect_epoch(get_current_epoch(state)):
|
||||
if validator.exit_epoch <= get_delayed_activation_exit_epoch(get_current_epoch(state)):
|
||||
return
|
||||
|
||||
validator.exit_epoch = get_entry_exit_effect_epoch(get_current_epoch(state))
|
||||
validator.exit_epoch = get_delayed_activation_exit_epoch(get_current_epoch(state))
|
||||
|
||||
func reduce_balance*(balance: var uint64, amount: uint64) =
|
||||
# Not in spec, but useful to avoid underflow.
|
||||
|
@ -484,14 +484,12 @@ proc checkAttestation*(
|
|||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#prepare_validator_for_withdrawal
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#prepare_validator_for_withdrawal
|
||||
func prepare_validator_for_withdrawal*(state: var BeaconState, index: ValidatorIndex) =
|
||||
## Set the validator with the given ``index`` as withdrawable
|
||||
## ``MIN_VALIDATOR_WITHDRAWABILITY_DELAY`` after the current epoch.
|
||||
## Note that this function mutates ``state``.
|
||||
var validator = addr state.validator_registry[index]
|
||||
|
||||
# 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
|
||||
|
||||
|
|
|
@ -313,7 +313,7 @@ type
|
|||
signature*: ValidatorSig ##\
|
||||
## Sender signature
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#beaconblock
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/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
|
||||
|
@ -333,11 +333,11 @@ type
|
|||
|
||||
eth1_data*: Eth1Data
|
||||
|
||||
body*: BeaconBlockBody
|
||||
|
||||
signature*: ValidatorSig ##\
|
||||
## Proposer signature
|
||||
|
||||
body*: BeaconBlockBody
|
||||
|
||||
BeaconBlockHeader* = object
|
||||
## Same as BeaconBlock, except `body` is the `hash_tree_root` of the
|
||||
## associated BeaconBlockBody.
|
||||
|
@ -350,7 +350,7 @@ type
|
|||
signature*: ValidatorSig
|
||||
body*: Eth2Digest
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#beaconblockbody
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#beaconblockbody
|
||||
BeaconBlockBody* = object
|
||||
proposer_slashings*: seq[ProposerSlashing]
|
||||
attester_slashings*: seq[AttesterSlashing]
|
||||
|
@ -373,13 +373,6 @@ type
|
|||
signature*: ValidatorSig ##\
|
||||
## Signature
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/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.3.0/specs/core/0_beacon-chain.md#beaconstate
|
||||
BeaconState* = object
|
||||
slot*: uint64
|
||||
|
|
|
@ -75,13 +75,13 @@ func get_fork_version*(fork: Fork, epoch: Epoch): uint64 =
|
|||
else:
|
||||
fork.current_version
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_domain
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_domain
|
||||
func get_domain*(
|
||||
fork: Fork, epoch: Epoch, domain_type: SignatureDomain): uint64 =
|
||||
# Get the domain number that represents the fork meta and signature domain.
|
||||
(get_fork_version(fork, epoch) shl 32) + domain_type.uint32
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#is_power_of_two
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#is_power_of_two
|
||||
func is_power_of_2*(v: uint64): bool = (v and (v-1)) == 0
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#merkle_root
|
||||
|
@ -119,11 +119,11 @@ func merkle_root*(values: openArray[Eth2Digest]): Eth2Digest =
|
|||
|
||||
o[1]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#slot_to_epoch
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#slot_to_epoch
|
||||
func slot_to_epoch*(slot: Slot): Epoch =
|
||||
slot div SLOTS_PER_EPOCH
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_epoch_start_slot
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_epoch_start_slot
|
||||
func get_epoch_start_slot*(epoch: Epoch): Slot =
|
||||
# Return the starting slot of the given ``epoch``.
|
||||
epoch * SLOTS_PER_EPOCH
|
||||
|
@ -162,13 +162,13 @@ func get_active_validator_indices*(validators: openArray[Validator], epoch: Epoc
|
|||
if is_active_validator(val, epoch):
|
||||
result.add idx.ValidatorIndex
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_epoch_committee_count
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_epoch_committee_count
|
||||
func get_epoch_committee_count*(active_validator_count: int): uint64 =
|
||||
clamp(
|
||||
active_validator_count div SLOTS_PER_EPOCH div TARGET_COMMITTEE_SIZE,
|
||||
1, SHARD_COUNT div SLOTS_PER_EPOCH).uint64 * SLOTS_PER_EPOCH
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_current_epoch_committee_count
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_current_epoch_committee_count
|
||||
func get_current_epoch_committee_count*(state: BeaconState): uint64 =
|
||||
# Return the number of committees in the current epoch of the given ``state``.
|
||||
let current_active_validators = get_active_validator_indices(
|
||||
|
@ -177,13 +177,13 @@ func get_current_epoch_committee_count*(state: BeaconState): uint64 =
|
|||
)
|
||||
get_epoch_committee_count(len(current_active_validators))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_current_epoch
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.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
|
||||
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
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_randao_mix
|
||||
func get_randao_mix*(state: BeaconState,
|
||||
epoch: Epoch): Eth2Digest =
|
||||
## Returns the randao mix at a recent ``epoch``.
|
||||
|
@ -237,7 +237,7 @@ func int_to_bytes4*(x: uint64): array[4, byte] =
|
|||
result[2] = ((x shr 16) and 0xff).byte
|
||||
result[3] = ((x shr 24) and 0xff).byte
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#generate_seed
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#generate_seed
|
||||
func generate_seed*(state: BeaconState, epoch: Epoch): Eth2Digest =
|
||||
# Generate a seed for the given ``epoch``.
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ func get_previous_epoch_committee_count(state: BeaconState): uint64 =
|
|||
)
|
||||
get_epoch_committee_count(len(previous_active_validators))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#get_next_epoch_committee_count
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_next_epoch_committee_count
|
||||
func get_next_epoch_committee_count(state: BeaconState): uint64 =
|
||||
## Return the number of committees in the next epoch of the given ``state``.
|
||||
let next_active_validators = get_active_validator_indices(
|
||||
|
|
|
@ -39,27 +39,24 @@ func flatten[T](v: openArray[seq[T]]): seq[T] =
|
|||
# TODO not in nim - doh.
|
||||
for x in v: result.add x
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#proposer-signature
|
||||
func verifyProposerSignature(state: BeaconState, blck: BeaconBlock): bool =
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#block-signature
|
||||
func verifyBlockSignature(state: BeaconState, blck: BeaconBlock): bool =
|
||||
## When creating a block, the proposer will sign a version of the block that
|
||||
## doesn't contain the data (chicken and egg), then add the signature to that
|
||||
## block. Here, we check that the signature is correct by repeating the same
|
||||
## process.
|
||||
var blck_without_signature = blck
|
||||
blck_without_signature.signature = ValidatorSig()
|
||||
|
||||
let
|
||||
signed_data = ProposalSignedData(
|
||||
slot: state.slot,
|
||||
proposer =
|
||||
state.validator_registry[get_beacon_proposer_index(state, state.slot)]
|
||||
proposal = Proposal(
|
||||
slot: blck.slot,
|
||||
shard: BEACON_CHAIN_SHARD_NUMBER,
|
||||
block_root: hash_tree_root_final(blck_without_signature)
|
||||
)
|
||||
proposal_root = hash_tree_root_final(signed_data)
|
||||
proposer_index = get_beacon_proposer_index(state, state.slot)
|
||||
|
||||
block_root: Eth2Digest(data: signed_root(blck, "signature")),
|
||||
signature: blck.signature)
|
||||
bls_verify(
|
||||
state.validator_registry[proposer_index].pubkey,
|
||||
proposal_root.data, blck.signature,
|
||||
proposer.pubkey,
|
||||
signed_root(proposal, "signature"),
|
||||
proposal.signature,
|
||||
get_domain(state.fork, get_current_epoch(state), DOMAIN_PROPOSAL))
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.3.0/specs/core/0_beacon-chain.md#randao
|
||||
|
@ -296,7 +293,7 @@ proc processExits(
|
|||
for exit in blck.body.voluntary_exits:
|
||||
let validator = state.validator_registry[exit.validator_index.int]
|
||||
|
||||
if not (validator.exit_epoch > get_entry_exit_effect_epoch(get_current_epoch(state))):
|
||||
if not (validator.exit_epoch > get_delayed_activation_exit_epoch(get_current_epoch(state))):
|
||||
notice "Exit: exit/entry too close"
|
||||
return false
|
||||
|
||||
|
@ -350,7 +347,10 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
|
|||
return false
|
||||
|
||||
if not (get_current_epoch(state) >=
|
||||
state.validator_registry[transfer.from_field.int].withdrawable_epoch):
|
||||
state.validator_registry[
|
||||
transfer.from_field.int].withdrawable_epoch or
|
||||
state.validator_registry[transfer.from_field.int].activation_epoch ==
|
||||
FAR_FUTURE_EPOCH):
|
||||
notice "Transfer: epoch mismatch"
|
||||
return false
|
||||
|
||||
|
@ -362,11 +362,7 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
|
|||
return false
|
||||
|
||||
if skipValidation notin flags:
|
||||
let transfer_message = hash_tree_root(
|
||||
Transfer(
|
||||
from_field: transfer.from_field, to: transfer.to,
|
||||
amount: transfer.amount, fee: transfer.fee, slot: transfer.slot,
|
||||
signature: EMPTY_SIGNATURE))
|
||||
let transfer_message = signed_root(transfer, "signature")
|
||||
if not bls_verify(
|
||||
pubkey=transfer.pubkey, transfer_message, transfer.signature,
|
||||
get_domain(state.fork, slot_to_epoch(transfer.slot), DOMAIN_TRANSFER)):
|
||||
|
@ -430,8 +426,8 @@ proc processBlock(
|
|||
# of BeaconBlock - we would then have an intermediate `ProposedBlock`
|
||||
# type that omits some fields - this way, the compiler would guarantee
|
||||
# that we don't try to access fields that don't have a value yet
|
||||
if not verifyProposerSignature(state, blck):
|
||||
notice "Proposer signature not valid", slot = humaneSlotNum(state.slot)
|
||||
if not verifyBlockSignature(state, blck):
|
||||
notice "Block signature not valid", slot = humaneSlotNum(state.slot)
|
||||
return false
|
||||
|
||||
if not processRandao(state, blck, flags):
|
||||
|
|
|
@ -41,13 +41,12 @@ proc getValidator*(pool: ValidatorPool,
|
|||
pool.validators.getOrDefault(validatorKey)
|
||||
|
||||
proc signBlockProposal*(v: AttachedValidator, fork: Fork,
|
||||
proposal: ProposalSignedData): Future[ValidatorSig] {.async.} =
|
||||
proposal: Proposal): Future[ValidatorSig] {.async.} =
|
||||
if v.kind == inProcess:
|
||||
await sleepAsync(1)
|
||||
let proposalRoot = hash_tree_root_final(proposal)
|
||||
|
||||
# TODO: Should we use proposalRoot as data, or digest in regards to signature?
|
||||
result = bls_sign(v.privKey, proposalRoot.data,
|
||||
result = bls_sign(v.privKey, signed_root(proposal, "signature"),
|
||||
get_domain(fork, slot_to_epoch(proposal.slot), DOMAIN_PROPOSAL))
|
||||
else:
|
||||
# TODO:
|
||||
|
|
|
@ -90,7 +90,7 @@ cli do(slots = 1945,
|
|||
|
||||
if attesterRatio > 0.0:
|
||||
# attesterRatio is the fraction of attesters that actually do their
|
||||
# work for every slot - we'll randimize it deterministically to give
|
||||
# work for every slot - we'll randomize it deterministically to give
|
||||
# some variation
|
||||
let scass = withTimerRet(timers[tShuffle]):
|
||||
get_crosslink_committees_at_slot(state, state.slot)
|
||||
|
|
|
@ -119,19 +119,19 @@ proc addBlock*(
|
|||
|
||||
# Once we've collected all the state data, we sign the block data along with
|
||||
# some book-keeping values
|
||||
signed_data = ProposalSignedData(
|
||||
signed_data = Proposal(
|
||||
slot: new_block.slot,
|
||||
shard: BEACON_CHAIN_SHARD_NUMBER,
|
||||
block_root: Eth2Digest(data: hash_tree_root(new_block))
|
||||
block_root: Eth2Digest(data: signed_root(new_block, "signature")),
|
||||
signature: ValidatorSig(),
|
||||
)
|
||||
proposal_hash = hash_tree_root(signed_data)
|
||||
proposal_hash = signed_root(signed_data, "signature")
|
||||
|
||||
assert proposerPrivkey.pubKey() == proposer.pubkey,
|
||||
"signature key should be derived from private key! - wrong privkey?"
|
||||
|
||||
if skipValidation notin flags:
|
||||
# We have a signature - put it in the block and we should be done!
|
||||
# TODO domain present do something!
|
||||
new_block.signature =
|
||||
bls_sign(proposerPrivkey, proposal_hash,
|
||||
get_domain(state.fork, slot_to_epoch(state.slot), DOMAIN_PROPOSAL))
|
||||
|
|
Loading…
Reference in New Issue