diff --git a/beacon_chain/spec/beaconstate.nim b/beacon_chain/spec/beaconstate.nim index 54e01573c..77a90c92d 100644 --- a/beacon_chain/spec/beaconstate.nim +++ b/beacon_chain/spec/beaconstate.nim @@ -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``. - foldl(validators, a + state.validator_registry[b].effective_balance, 0'u64) + ## 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) = diff --git a/beacon_chain/spec/datatypes.nim b/beacon_chain/spec/datatypes.nim index 205f4db82..e41fa9df1 100644 --- a/beacon_chain/spec/datatypes.nim +++ b/beacon_chain/spec/datatypes.nim @@ -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 diff --git a/beacon_chain/spec/helpers.nim b/beacon_chain/spec/helpers.nim index 32a085f6c..bb0d180c7 100644 --- a/beacon_chain/spec/helpers.nim +++ b/beacon_chain/spec/helpers.nim @@ -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)) diff --git a/beacon_chain/spec/presets/mainnet.nim b/beacon_chain/spec/presets/mainnet.nim index 2e6eab56a..8968ea7eb 100644 --- a/beacon_chain/spec/presets/mainnet.nim +++ b/beacon_chain/spec/presets/mainnet.nim @@ -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 # --------------------------------------------------------------- diff --git a/beacon_chain/spec/presets/minimal.nim b/beacon_chain/spec/presets/minimal.nim index c97b3720f..880b0a894 100644 --- a/beacon_chain/spec/presets/minimal.nim +++ b/beacon_chain/spec/presets/minimal.nim @@ -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 # --------------------------------------------------------------- diff --git a/beacon_chain/state_transition.nim b/beacon_chain/state_transition.nim index 161e71efe..1bb393e55 100644 --- a/beacon_chain/state_transition.nim +++ b/beacon_chain/state_transition.nim @@ -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) diff --git a/beacon_chain/sync_protocol.nim b/beacon_chain/sync_protocol.nim index 400801df2..1beea1da7 100644 --- a/beacon_chain/sync_protocol.nim +++ b/beacon_chain/sync_protocol.nim @@ -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 diff --git a/beacon_chain/validator_keygen.nim b/beacon_chain/validator_keygen.nim index 5e33ca8fd..f5ee131db 100644 --- a/beacon_chain/validator_keygen.nim +++ b/beacon_chain/validator_keygen.nim @@ -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, diff --git a/tests/official/fixtures_utils.nim b/tests/official/fixtures_utils.nim index ae7091bf2..5f2f242af 100644 --- a/tests/official/fixtures_utils.nim +++ b/tests/official/fixtures_utils.nim @@ -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 diff --git a/tests/testutil.nim b/tests/testutil.nim index 465008fce..2afe75640 100644 --- a/tests/testutil.nim +++ b/tests/testutil.nim @@ -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,