more 0.7.0 updates (#287)

* update Deposit and BeaconBlockHeader to 0.7.0

* update get_total_balance(...) and get_base_reward(...) to 0.7.0

* rename initial value constant BLS_WITHDRAWAL_PREFIX_BYTE to BLS_WITHDRAWAL_PREFIX

* mark minimal presets as entirely migrated to 0.7.0; update process_rewards_and_penalties(...) to 0.7.0

* specify that targeting 0.7.0; adopt 0.7.0 refactoring of bls_domain/get_domain to update get_domain(...) to 0.7.0; mark that mainnet constant presets and block header processing are 0.7.0-consistent; update process_justification_and_finalization to 0.7.0 to fix potential underflow errors

* address mratsim's comment to copy whole spec comment
This commit is contained in:
Dustin Brody 2019-06-14 16:21:04 +00:00 committed by GitHub
parent 2a6e64d3f9
commit e9180c490e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 61 additions and 62 deletions

View File

@ -56,7 +56,7 @@ func process_deposit*(
hash_tree_root(deposit.data),
deposit.proof,
DEPOSIT_CONTRACT_TREE_DEPTH,
deposit.index,
state.deposit_index,
state.latest_eth1_data.deposit_root,
):
## TODO: a notice-like mechanism which works in a func
@ -68,12 +68,6 @@ func process_deposit*(
discard
# Deposits must be processed in order
if not (deposit.index == state.deposit_index):
## TODO see above, re errors
## it becomes even more important, as one might might sometimes want
## to flag such things as higher/lower priority. chronicles?
return false
state.deposit_index += 1
let
@ -183,9 +177,9 @@ func get_temporary_block_header(blck: BeaconBlock): BeaconBlockHeader =
## to ``ZERO_HASH``.
BeaconBlockHeader(
slot: blck.slot,
previous_block_root: blck.parent_root,
parent_root: blck.parent_root,
state_root: ZERO_HASH,
block_body_root: hash_tree_root(blck.body),
body_root: hash_tree_root(blck.body),
# signing_root(block) is used for block id purposes so signature is a stub
signature: ValidatorSig(),
)
@ -317,10 +311,13 @@ func get_block_root*(state: BeaconState, epoch: Epoch): Eth2Digest =
# Return the block root at a recent ``epoch``.
get_block_root_at_slot(state, get_epoch_start_slot(epoch))
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#get_total_balance
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#get_total_balance
func get_total_balance*(state: BeaconState, validators: auto): Gwei =
# Return the combined effective balance of an array of ``validators``.
## Return the combined effective balance of the ``indices``. (1 Gwei minimum
## to avoid divisions by zero.)
max(1'u64,
foldl(validators, a + state.validator_registry[b].effective_balance, 0'u64)
)
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#registry-updates
func process_registry_updates*(state: var BeaconState) =

View File

@ -53,11 +53,11 @@ else:
{.fatal: "Preset \"" & const_preset ".nim\" is not supported.".}
const
SPEC_VERSION* = "0.6.3" ## \
SPEC_VERSION* = "0.7.0" ## \
## Spec version we're aiming to be compatible with, right now
## TODO: improve this scheme once we can negotiate versions in protocol
# TODO remove erstwhile blob/v0.6.3
# TODO remove erstwhile blob/v0.7.0
FORK_CHOICE_BALANCE_INCREMENT* = 2'u64^0 * 10'u64^9
# Initial values
@ -139,14 +139,11 @@ type
data*: AttestationData
custody_bit*: bool
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#deposit
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#deposit
Deposit* = object
proof*: array[DEPOSIT_CONTRACT_TREE_DEPTH, Eth2Digest] ##\
## Branch in the deposit tree
index*: uint64 ##\
## Index in the deposit tree
data*: DepositData ##\
## Data
@ -219,12 +216,12 @@ type
signature*: ValidatorSig ##\
## Proposer signature
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#beaconblockheader
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#beaconblockheader
BeaconBlockHeader* = object
slot*: Slot
previous_block_root*: Eth2Digest
parent_root*: Eth2Digest
state_root*: Eth2Digest
block_body_root*: Eth2Digest
body_root*: Eth2Digest
signature*: ValidatorSig
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#beaconblockbody

View File

@ -151,21 +151,26 @@ 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.6.3/specs/core/0_beacon-chain.md#get_domain
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#bls_domain
func bls_domain(domain_type: SignatureDomain, fork_version: array[4, byte]):
uint64 =
var buf: array[8, byte]
buf[0..3] = fork_version
buf[4..7] = int_to_bytes4(domain_type.uint64)
bytes_to_int(buf)
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#get_domain
func get_domain*(
state: BeaconState, domain_type: SignatureDomain, message_epoch: Epoch): uint64 =
## Return the signature domain (fork version concatenated with domain type)
## of a message.
var buf: array[8, byte]
let
epoch = message_epoch
fork_version = if epoch < state.fork.epoch:
state.fork.previous_version
else:
state.fork.current_version
buf[0..3] = fork_version
buf[4..7] = int_to_bytes4(domain_type.uint64)
bytes_to_int(buf)
bls_domain(domain_type, fork_version)
func get_domain*(state: BeaconState, domain_type: SignatureDomain): uint64 =
get_domain(state, domain_type, get_current_epoch(state))

View File

@ -22,7 +22,7 @@ type
{.experimental: "codeReordering".} # SLOTS_PER_EPOCH is use before being defined in spec
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/configs/constant_presets/mainnet.yaml
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/configs/constant_presets/mainnet.yaml
const
# Misc
# ---------------------------------------------------------------
@ -83,12 +83,12 @@ const
# Initial values
# ---------------------------------------------------------------
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/configs/constant_presets/mainnet.yaml#L44
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/configs/constant_presets/mainnet.yaml#L44
GENESIS_FORK_VERSION* = [0'u8, 0'u8, 0'u8, 0'u8]
GENESIS_SLOT* = 0.Slot
FAR_FUTURE_EPOCH* = (not 0'u64).Epoch # 2^64 - 1 in spec
BLS_WITHDRAWAL_PREFIX_BYTE* = 0'u8
BLS_WITHDRAWAL_PREFIX* = 0'u8
# Time parameters
# ---------------------------------------------------------------

View File

@ -22,7 +22,7 @@ type
{.experimental: "codeReordering".} # SLOTS_PER_EPOCH is use before being defined in spec
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/configs/constant_presets/minimal.yaml
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/configs/constant_presets/minimal.yaml
const
# Misc
# ---------------------------------------------------------------
@ -66,7 +66,7 @@ const
GENESIS_FORK_VERSION* = [0'u8, 0'u8, 0'u8, 0'u8]
GENESIS_SLOT* = 0.Slot
FAR_FUTURE_EPOCH* = (not 0'u64).Epoch # 2^64 - 1 in spec
BLS_WITHDRAWAL_PREFIX_BYTE* = 0'u8
BLS_WITHDRAWAL_PREFIX* = 0'u8
# Time parameters
# ---------------------------------------------------------------

View File

@ -35,7 +35,7 @@ import
./extras, ./ssz, ./beacon_node_types,
./spec/[beaconstate, bitfield, crypto, datatypes, digest, helpers, validator]
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#block-header
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#block-header
proc processBlockHeader(
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
# Verify that the slots match
@ -57,8 +57,8 @@ proc processBlockHeader(
# Save current block as the new latest block
state.latest_block_header = BeaconBlockHeader(
slot: blck.slot,
previous_block_root: blck.parent_root,
block_body_root: hash_tree_root(blck.body),
parent_root: blck.parent_root,
body_root: hash_tree_root(blck.body),
)
# Verify proposer is not slashed
@ -369,7 +369,7 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
# Verify that the pubkey is valid
let wc = state.validator_registry[transfer.sender.int].
withdrawal_credentials
if not (wc.data[0] == BLS_WITHDRAWAL_PREFIX_BYTE and
if not (wc.data[0] == BLS_WITHDRAWAL_PREFIX and
wc.data[1..^1] == eth2hash(transfer.pubkey.getBytes).data[1..^1]):
notice "Transfer: incorrect withdrawal credentials"
return false
@ -614,7 +614,7 @@ func get_winning_crosslink_and_attesting_indices(
get_unslashed_attesting_indices(state,
get_attestations_for(winning_crosslink)))
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#justification-and-finalization
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#justification-and-finalization
func process_justification_and_finalization(state: var BeaconState) =
if get_current_epoch(state) <= GENESIS_EPOCH + 1:
return
@ -653,29 +653,29 @@ func process_justification_and_finalization(state: var BeaconState) =
## The 2nd/3rd/4th most recent epochs are justified, the 2nd using the 4th
## as source
if (bitfield shr 1) mod 8 == 0b111 and old_previous_justified_epoch ==
current_epoch - 3:
if (bitfield shr 1) mod 8 == 0b111 and old_previous_justified_epoch + 3 ==
current_epoch:
state.finalized_epoch = old_previous_justified_epoch
state.finalized_root = get_block_root(state, state.finalized_epoch)
## The 2nd/3rd most recent epochs are justified, the 2nd using the 3rd as
## source
if (bitfield shr 1) mod 4 == 0b11 and old_previous_justified_epoch ==
current_epoch - 2:
if (bitfield shr 1) mod 4 == 0b11 and old_previous_justified_epoch + 2 ==
current_epoch:
state.finalized_epoch = old_previous_justified_epoch
state.finalized_root = get_block_root(state, state.finalized_epoch)
## The 1st/2nd/3rd most recent epochs are justified, the 1st using the 3rd as
## source
if (bitfield shr 0) mod 8 == 0b111 and old_current_justified_epoch ==
current_epoch - 2:
if (bitfield shr 0) mod 8 == 0b111 and old_current_justified_epoch + 2 ==
current_epoch:
state.finalized_epoch = old_current_justified_epoch
state.finalized_root = get_block_root(state, state.finalized_epoch)
## The 1st/2nd most recent epochs are justified, the 1st using the 2nd as
## source
if (bitfield shr 0) mod 4 == 0b11 and old_current_justified_epoch ==
current_epoch - 1:
if (bitfield shr 0) mod 4 == 0b11 and old_current_justified_epoch + 1 ==
current_epoch:
state.finalized_epoch = old_current_justified_epoch
state.finalized_root = get_block_root(state, state.finalized_epoch)
@ -706,14 +706,13 @@ func process_crosslinks(state: var BeaconState, per_epoch_cache: var StateCache)
2'u64 * get_total_balance(state, crosslink_committee):
state.current_crosslinks[shard] = winning_crosslink
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#rewards-and-penalties
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#rewards-and-penalties-1
func get_base_reward(state: BeaconState, index: ValidatorIndex): Gwei =
let adjusted_quotient =
integer_squareroot(get_total_active_balance(state)) div BASE_REWARD_FACTOR
if adjusted_quotient == 0:
return 0
state.validator_registry[index].effective_balance div adjusted_quotient div
BASE_REWARDS_PER_EPOCH
let
total_balance = get_total_active_balance(state)
effective_balance = state.validator_registry[index].effective_balance
effective_balance * BASE_REWARD_FACTOR div
integer_squareroot(total_balance) div BASE_REWARDS_PER_EPOCH
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#rewards-and-penalties
func get_attestation_deltas(state: BeaconState):
@ -813,9 +812,12 @@ func get_crosslink_deltas(state: BeaconState, cache: var StateCache):
(rewards, penalties)
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#rewards-and-penalties
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.0/specs/core/0_beacon-chain.md#rewards-and-penalties-1
func process_rewards_and_penalties(
state: var BeaconState, cache: var StateCache) =
if get_current_epoch(state) == GENESIS_EPOCH:
return
let
(rewards1, penalties1) = get_attestation_deltas(state)
(rewards2, penalties2) = get_crosslink_deltas(state, cache)

View File

@ -31,16 +31,16 @@ const
func toHeader(b: BeaconBlock): BeaconBlockHeader =
BeaconBlockHeader(
slot: b.slot,
previous_block_root: b.parent_root,
parent_root: b.parent_root,
state_root: b.state_root,
block_body_root: hash_tree_root(b.body),
body_root: hash_tree_root(b.body),
signature: b.signature
)
proc fromHeaderAndBody(b: var BeaconBlock, h: BeaconBlockHeader, body: BeaconBlockBody) =
doAssert(hash_tree_root(body) == h.block_body_root)
doAssert(hash_tree_root(body) == h.body_root)
b.slot = h.slot
b.parent_root = h.previous_block_root
b.parent_root = h.parent_root
b.state_root = h.state_root
b.body = body
b.signature = h.signature
@ -58,7 +58,7 @@ proc mergeBlockHeadersAndBodies(headers: openarray[BeaconBlockHeader], bodies: o
var res: seq[BeaconBlock]
for i in 0 ..< headers.len:
if hash_tree_root(bodies[i]) != headers[i].block_body_root:
if hash_tree_root(bodies[i]) != headers[i].body_root:
info "Block body is wrong for header"
return

View File

@ -39,8 +39,7 @@ cli do (totalValidators: int = 125000,
data: DepositData(
amount: MAX_EFFECTIVE_BALANCE,
pubkey: pubKey,
withdrawal_credentials: withdrawalCredentials),
index: i.uint64)
withdrawal_credentials: withdrawalCredentials))
deposit.data.signature =
bls_sign(privkey, signing_root(deposit.data).data,

View File

@ -38,7 +38,7 @@ type
GENESIS_SLOT*: Slot
GENESIS_EPOCH*: Epoch
GENESIS_START_SHARD*: uint64
BLS_WITHDRAWAL_PREFIX_BYTE*: array[1, byte]
BLS_WITHDRAWAL_PREFIX*: array[1, byte]
SECONDS_PER_SLOT*: uint64
MIN_ATTESTATION_INCLUSION_DELAY*: uint64
SLOTS_PER_EPOCH*: int
@ -141,7 +141,7 @@ proc default*(T: typedesc): T = discard
proc readValue*[N: static int](r: var JsonReader, a: var array[N, byte]) {.inline.} =
# Needed for;
# - BLS_WITHDRAWAL_PREFIX_BYTE
# - BLS_WITHDRAWAL_PREFIX
# - Fork datatypes
# TODO: are all bytes and bytearray serialized as hex?
# if so export that to nim-eth

View File

@ -42,7 +42,6 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
domain = 3'u64
result = Deposit(
index: i.uint64,
data: DepositData(
pubkey: pubkey,
withdrawal_credentials: withdrawal_credentials,