AttestationData.justified epoch -> AttestationData.source_epoch and AttestationData.latest_crosslink -> AttestationData.previous_crosslink; implement verify_merkle_branch and update process_deposit to use it; rm BeaconState.batched_block_roots; Transfer.{from, to} -> Transfer.{sender, recipient}; update Fork data type and code to use bytes4; implement int_to_bytes8 (close to metaprogramming time); adjust signed_root and all callers to use 0.5.0 calling signature; processDepositRoot -> processEth1Data
This commit is contained in:
parent
f36c2d86dc
commit
18f1d000a1
|
@ -239,7 +239,7 @@ proc add*(pool: var AttestationPool,
|
||||||
slot = humaneSlotNum(attestation.data.slot),
|
slot = humaneSlotNum(attestation.data.slot),
|
||||||
shard = attestation.data.shard,
|
shard = attestation.data.shard,
|
||||||
beaconBlockRoot = shortLog(attestation.data.beacon_block_root),
|
beaconBlockRoot = shortLog(attestation.data.beacon_block_root),
|
||||||
justifiedEpoch = humaneEpochNum(attestation.data.justified_epoch),
|
sourceEpoch = humaneEpochNum(attestation.data.source_epoch),
|
||||||
justifiedBlockRoot = shortLog(attestation.data.justified_block_root),
|
justifiedBlockRoot = shortLog(attestation.data.justified_block_root),
|
||||||
signature = shortLog(attestation.aggregate_signature),
|
signature = shortLog(attestation.aggregate_signature),
|
||||||
validations = a.validations.len() # TODO popcount of union
|
validations = a.validations.len() # TODO popcount of union
|
||||||
|
@ -262,7 +262,7 @@ proc add*(pool: var AttestationPool,
|
||||||
slot = humaneSlotNum(attestation.data.slot),
|
slot = humaneSlotNum(attestation.data.slot),
|
||||||
shard = attestation.data.shard,
|
shard = attestation.data.shard,
|
||||||
beaconBlockRoot = shortLog(attestation.data.beacon_block_root),
|
beaconBlockRoot = shortLog(attestation.data.beacon_block_root),
|
||||||
justifiedEpoch = humaneEpochNum(attestation.data.justified_epoch),
|
sourceEpoch = humaneEpochNum(attestation.data.source_epoch),
|
||||||
justifiedBlockRoot = shortLog(attestation.data.justified_block_root),
|
justifiedBlockRoot = shortLog(attestation.data.justified_block_root),
|
||||||
signature = shortLog(attestation.aggregate_signature),
|
signature = shortLog(attestation.aggregate_signature),
|
||||||
validations = 1
|
validations = 1
|
||||||
|
@ -350,4 +350,4 @@ proc resolve*(pool: var AttestationPool, state: BeaconState) =
|
||||||
|
|
||||||
proc latestAttestation*(
|
proc latestAttestation*(
|
||||||
pool: AttestationPool, pubKey: ValidatorPubKey): BlockRef =
|
pool: AttestationPool, pubKey: ValidatorPubKey): BlockRef =
|
||||||
pool.latestAttestations.getOrDefault(pubKey)
|
pool.latestAttestations.getOrDefault(pubKey)
|
||||||
|
|
|
@ -312,7 +312,7 @@ proc proposeBlock(node: BeaconNode,
|
||||||
let proposal = Proposal(
|
let proposal = Proposal(
|
||||||
slot: slot.uint64,
|
slot: slot.uint64,
|
||||||
shard: BEACON_CHAIN_SHARD_NUMBER,
|
shard: BEACON_CHAIN_SHARD_NUMBER,
|
||||||
block_root: Eth2Digest(data: signed_root(newBlock, "signature")),
|
block_root: Eth2Digest(data: signed_root(newBlock)),
|
||||||
signature: ValidatorSig(),
|
signature: ValidatorSig(),
|
||||||
)
|
)
|
||||||
newBlock.signature =
|
newBlock.signature =
|
||||||
|
@ -523,7 +523,7 @@ proc onAttestation(node: BeaconNode, attestation: Attestation) =
|
||||||
slot = humaneSlotNum(attestation.data.slot),
|
slot = humaneSlotNum(attestation.data.slot),
|
||||||
shard = attestation.data.shard,
|
shard = attestation.data.shard,
|
||||||
beaconBlockRoot = shortLog(attestation.data.beacon_block_root),
|
beaconBlockRoot = shortLog(attestation.data.beacon_block_root),
|
||||||
justifiedEpoch = humaneEpochNum(attestation.data.justified_epoch),
|
sourceEpoch = humaneEpochNum(attestation.data.source_epoch),
|
||||||
justifiedBlockRoot = shortLog(attestation.data.justified_block_root),
|
justifiedBlockRoot = shortLog(attestation.data.justified_block_root),
|
||||||
signature = shortLog(attestation.aggregate_signature)
|
signature = shortLog(attestation.aggregate_signature)
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,24 @@ func get_effective_balance*(state: BeaconState, index: ValidatorIndex): Gwei =
|
||||||
## validator with the given ``index``.
|
## validator with the given ``index``.
|
||||||
min(state.validator_balances[index], MAX_DEPOSIT_AMOUNT)
|
min(state.validator_balances[index], MAX_DEPOSIT_AMOUNT)
|
||||||
|
|
||||||
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#verify_merkle_branch
|
||||||
|
func verify_merkle_branch(leaf: Eth2Digest, proof: openarray[Eth2Digest], depth: uint64, index: uint64, root: Eth2Digest): bool =
|
||||||
|
## Verify that the given ``leaf`` is on the merkle branch ``proof``
|
||||||
|
## starting with the given ``root``.
|
||||||
|
var
|
||||||
|
value = leaf
|
||||||
|
buf: array[64, byte]
|
||||||
|
|
||||||
|
for i in 0 ..< depth.int:
|
||||||
|
if (index div (1'u64 shl i)) mod 2 != 0:
|
||||||
|
buf[0..31] = proof[i.int].data
|
||||||
|
buf[32..63] = value.data
|
||||||
|
else:
|
||||||
|
buf[0..31] = value.data
|
||||||
|
buf[32..63] = proof[i.int].data
|
||||||
|
value = eth2hash(buf)
|
||||||
|
value == root
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#process_deposit
|
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#process_deposit
|
||||||
func process_deposit(state: var BeaconState, deposit: Deposit) =
|
func process_deposit(state: var BeaconState, deposit: Deposit) =
|
||||||
## Process a deposit from Ethereum 1.0.
|
## Process a deposit from Ethereum 1.0.
|
||||||
|
@ -23,6 +41,42 @@ func process_deposit(state: var BeaconState, deposit: Deposit) =
|
||||||
|
|
||||||
let deposit_input = deposit.deposit_data.deposit_input
|
let deposit_input = deposit.deposit_data.deposit_input
|
||||||
|
|
||||||
|
## Should equal 8 bytes for deposit_data.amount +
|
||||||
|
## 8 bytes for deposit_data.timestamp +
|
||||||
|
## 176 bytes for deposit_data.deposit_input
|
||||||
|
## It should match the deposit_data in the eth1.0 deposit contract
|
||||||
|
## TODO actual serialize func useful after all
|
||||||
|
var serialized_deposit_data: array[8 + 8 + 176, byte]
|
||||||
|
serialized_deposit_data[0..7] = deposit.deposit_data.amount.int_to_bytes8()
|
||||||
|
serialized_deposit_data[8..15] =
|
||||||
|
deposit.deposit_data.timestamp.int_to_bytes8()
|
||||||
|
serialized_deposit_data[16..63] = deposit_input.pubkey.getBytes()
|
||||||
|
serialized_deposit_data[64..95] = deposit_input.withdrawal_credentials.data
|
||||||
|
serialized_deposit_data[96..191] =
|
||||||
|
deposit_input.proof_of_possession.getBytes()
|
||||||
|
|
||||||
|
# Verify the Merkle branch
|
||||||
|
let merkle_branch_is_valid = verify_merkle_branch(
|
||||||
|
eth2hash(serialized_deposit_data),
|
||||||
|
deposit.proof,
|
||||||
|
DEPOSIT_CONTRACT_TREE_DEPTH,
|
||||||
|
deposit.index,
|
||||||
|
state.latest_eth1_data.deposit_root)
|
||||||
|
## TODO enable this check, after using merkle_root (not in spec anymore, but
|
||||||
|
## useful to construct proofs) to build proofs (i.e. the other child in each
|
||||||
|
## pair of children at each level of the merkle tree), and injecting a proof
|
||||||
|
## sequence corresponding to their hash values, into the `Deposits`, in that
|
||||||
|
## tests/testutil.nim area of code. Currently it's checking against garbage,
|
||||||
|
## either when creating genesis states or in the block processing of deposit
|
||||||
|
## lists from Eth1Data.
|
||||||
|
# doAssert merkle_branch_is_valid
|
||||||
|
|
||||||
|
## Increment the next deposit index we are expecting. Note that this
|
||||||
|
## needs to be done here because while the deposit contract will never
|
||||||
|
## create an invalid Merkle branch, it may admit an invalid deposit
|
||||||
|
## object, and we need to be able to skip over it
|
||||||
|
state.deposit_index += 1
|
||||||
|
|
||||||
## if not validate_proof_of_possession(
|
## if not validate_proof_of_possession(
|
||||||
## state, pubkey, proof_of_possession, withdrawal_credentials):
|
## state, pubkey, proof_of_possession, withdrawal_credentials):
|
||||||
## return
|
## return
|
||||||
|
@ -89,19 +143,22 @@ func initiate_validator_exit*(state: var BeaconState,
|
||||||
var validator = addr state.validator_registry[index]
|
var validator = addr state.validator_registry[index]
|
||||||
validator.initiated_exit = true
|
validator.initiated_exit = true
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#exit_validator
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#exit_validator
|
||||||
func exit_validator*(state: var BeaconState,
|
func exit_validator*(state: var BeaconState,
|
||||||
index: ValidatorIndex) =
|
index: ValidatorIndex) =
|
||||||
## Exit the validator with the given ``index``.
|
## Exit the validator with the given ``index``.
|
||||||
## Note that this function mutates ``state``.
|
## Note that this function mutates ``state``.
|
||||||
|
|
||||||
let validator = addr state.validator_registry[index]
|
let
|
||||||
|
validator = addr state.validator_registry[index]
|
||||||
|
delayed_activation_exit_epoch =
|
||||||
|
get_delayed_activation_exit_epoch(get_current_epoch(state))
|
||||||
|
|
||||||
# The following updates only occur if not previous exited
|
# The following updates only occur if not previous exited
|
||||||
if validator.exit_epoch <= get_delayed_activation_exit_epoch(get_current_epoch(state)):
|
if validator.exit_epoch <= delayed_activation_exit_epoch:
|
||||||
return
|
return
|
||||||
|
|
||||||
validator.exit_epoch = get_delayed_activation_exit_epoch(get_current_epoch(state))
|
validator.exit_epoch = delayed_activation_exit_epoch
|
||||||
|
|
||||||
func reduce_balance*(balance: var uint64, amount: uint64) =
|
func reduce_balance*(balance: var uint64, amount: uint64) =
|
||||||
# Not in spec, but useful to avoid underflow.
|
# Not in spec, but useful to avoid underflow.
|
||||||
|
@ -228,7 +285,7 @@ func get_genesis_beacon_state*(
|
||||||
|
|
||||||
# Recent state
|
# Recent state
|
||||||
# latest_block_roots, latest_active_index_roots, latest_slashed_balances,
|
# latest_block_roots, latest_active_index_roots, latest_slashed_balances,
|
||||||
# latest_attestations, and batched_block_roots automatically initialized.
|
# and latest_attestations automatically initialized.
|
||||||
latest_block_header: get_temporary_block_header(get_empty_block()),
|
latest_block_header: get_temporary_block_header(get_empty_block()),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -386,6 +443,7 @@ func update_validator_registry*(state: var BeaconState) =
|
||||||
state.validator_registry_update_epoch = current_epoch
|
state.validator_registry_update_epoch = current_epoch
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#attestations-1
|
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#attestations-1
|
||||||
|
# TODO this is https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#attestations now
|
||||||
proc checkAttestation*(
|
proc checkAttestation*(
|
||||||
state: BeaconState, attestation: Attestation, flags: UpdateFlags): bool =
|
state: BeaconState, attestation: Attestation, flags: UpdateFlags): bool =
|
||||||
## Check that an attestation follows the rules of being included in the state
|
## Check that an attestation follows the rules of being included in the state
|
||||||
|
@ -418,15 +476,15 @@ proc checkAttestation*(
|
||||||
else:
|
else:
|
||||||
state.previous_justified_epoch
|
state.previous_justified_epoch
|
||||||
|
|
||||||
if not (attestation.data.justified_epoch == expected_justified_epoch):
|
if not (attestation.data.source_epoch == expected_justified_epoch):
|
||||||
warn("Unexpected justified epoch",
|
warn("Unexpected justified epoch",
|
||||||
attestation_justified_epoch =
|
attestation_justified_epoch =
|
||||||
humaneEpochNum(attestation.data.justified_epoch),
|
humaneEpochNum(attestation.data.source_epoch),
|
||||||
expected_justified_epoch = humaneEpochNum(expected_justified_epoch))
|
expected_justified_epoch = humaneEpochNum(expected_justified_epoch))
|
||||||
return
|
return
|
||||||
|
|
||||||
let expected_justified_block_root =
|
let expected_justified_block_root =
|
||||||
get_block_root(state, get_epoch_start_slot(attestation.data.justified_epoch))
|
get_block_root(state, get_epoch_start_slot(attestation.data.source_epoch))
|
||||||
if not (attestation.data.justified_block_root == expected_justified_block_root):
|
if not (attestation.data.justified_block_root == expected_justified_block_root):
|
||||||
warn("Unexpected justified block root",
|
warn("Unexpected justified block root",
|
||||||
attestation_justified_block_root = attestation.data.justified_block_root,
|
attestation_justified_block_root = attestation.data.justified_block_root,
|
||||||
|
@ -434,14 +492,14 @@ proc checkAttestation*(
|
||||||
return
|
return
|
||||||
|
|
||||||
if not (state.latest_crosslinks[attestation.data.shard] in [
|
if not (state.latest_crosslinks[attestation.data.shard] in [
|
||||||
attestation.data.latest_crosslink,
|
attestation.data.previous_crosslink,
|
||||||
Crosslink(
|
Crosslink(
|
||||||
crosslink_data_root: attestation.data.crosslink_data_root,
|
crosslink_data_root: attestation.data.crosslink_data_root,
|
||||||
epoch: slot_to_epoch(attestation_data_slot))]):
|
epoch: slot_to_epoch(attestation_data_slot))]):
|
||||||
warn("Unexpected crosslink shard",
|
warn("Unexpected crosslink shard",
|
||||||
state_latest_crosslinks_attestation_data_shard =
|
state_latest_crosslinks_attestation_data_shard =
|
||||||
state.latest_crosslinks[attestation.data.shard],
|
state.latest_crosslinks[attestation.data.shard],
|
||||||
attestation_data_latest_crosslink = attestation.data.latest_crosslink,
|
attestation_data_previous_crosslink = attestation.data.previous_crosslink,
|
||||||
epoch = humaneEpochNum(slot_to_epoch(attestation_data_slot)),
|
epoch = humaneEpochNum(slot_to_epoch(attestation_data_slot)),
|
||||||
crosslink_data_root = attestation.data.crosslink_data_root)
|
crosslink_data_root = attestation.data.crosslink_data_root)
|
||||||
return
|
return
|
||||||
|
@ -545,7 +603,7 @@ proc makeAttestationData*(
|
||||||
beacon_block_root: beacon_block_root,
|
beacon_block_root: beacon_block_root,
|
||||||
epoch_boundary_root: epoch_boundary_root,
|
epoch_boundary_root: epoch_boundary_root,
|
||||||
crosslink_data_root: Eth2Digest(), # Stub in phase0
|
crosslink_data_root: Eth2Digest(), # Stub in phase0
|
||||||
latest_crosslink: state.latest_crosslinks[shard],
|
previous_crosslink: state.latest_crosslinks[shard],
|
||||||
justified_epoch: state.current_justified_epoch,
|
source_epoch: state.current_justified_epoch,
|
||||||
justified_block_root: justified_block_root,
|
justified_block_root: justified_block_root,
|
||||||
)
|
)
|
||||||
|
|
|
@ -83,7 +83,7 @@ const
|
||||||
|
|
||||||
# Deposit contract
|
# Deposit contract
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#deposit-contract
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#deposit-contract
|
||||||
DEPOSIT_CONTRACT_TREE_DEPTH* = 2^5
|
DEPOSIT_CONTRACT_TREE_DEPTH* = 32
|
||||||
|
|
||||||
# Gwei values
|
# Gwei values
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#gwei-values
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#gwei-values
|
||||||
|
@ -107,7 +107,8 @@ const
|
||||||
## Compile with -d:SLOTS_PER_EPOCH=4 for shorter epochs
|
## Compile with -d:SLOTS_PER_EPOCH=4 for shorter epochs
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#initial-values
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#initial-values
|
||||||
GENESIS_FORK_VERSION* = 0'u64
|
# TODO: in 0.5.0, GENESIS_FORK_VERSION defined as int, but used as [byte]
|
||||||
|
GENESIS_FORK_VERSION* = [0'u8, 0'u8, 0'u8, 0'u8]
|
||||||
GENESIS_SLOT* = (2'u64^32).Slot
|
GENESIS_SLOT* = (2'u64^32).Slot
|
||||||
GENESIS_EPOCH* = (GENESIS_SLOT.uint64 div SLOTS_PER_EPOCH).Epoch ##\
|
GENESIS_EPOCH* = (GENESIS_SLOT.uint64 div SLOTS_PER_EPOCH).Epoch ##\
|
||||||
## slot_to_epoch(GENESIS_SLOT)
|
## slot_to_epoch(GENESIS_SLOT)
|
||||||
|
@ -118,7 +119,7 @@ const
|
||||||
BLS_WITHDRAWAL_PREFIX_BYTE* = 0'u8
|
BLS_WITHDRAWAL_PREFIX_BYTE* = 0'u8
|
||||||
|
|
||||||
# Time parameters
|
# Time parameters
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#time-parameters
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#time-parameters
|
||||||
SECONDS_PER_SLOT*{.intdefine.} = 6'u64 # Compile with -d:SECONDS_PER_SLOT=1 for 6x faster slots
|
SECONDS_PER_SLOT*{.intdefine.} = 6'u64 # Compile with -d:SECONDS_PER_SLOT=1 for 6x faster slots
|
||||||
## TODO consistent time unit across projects, similar to C++ chrono?
|
## TODO consistent time unit across projects, similar to C++ chrono?
|
||||||
|
|
||||||
|
@ -151,6 +152,9 @@ const
|
||||||
MIN_VALIDATOR_WITHDRAWABILITY_DELAY* = 2'u64^8 ##\
|
MIN_VALIDATOR_WITHDRAWABILITY_DELAY* = 2'u64^8 ##\
|
||||||
## epochs (~27 hours)
|
## epochs (~27 hours)
|
||||||
|
|
||||||
|
PERSISTENT_COMMITTEE_PERIOD* = 2'u64^11 ##\
|
||||||
|
## epochs (9 days)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#state-list-lengths
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#state-list-lengths
|
||||||
LATEST_RANDAO_MIXES_LENGTH* = 8192
|
LATEST_RANDAO_MIXES_LENGTH* = 8192
|
||||||
LATEST_ACTIVE_INDEX_ROOTS_LENGTH* = 8192 # 2'u64^13, epochs
|
LATEST_ACTIVE_INDEX_ROOTS_LENGTH* = 8192 # 2'u64^13, epochs
|
||||||
|
@ -190,7 +194,7 @@ type
|
||||||
header_2*: BeaconBlockHeader ##\
|
header_2*: BeaconBlockHeader ##\
|
||||||
# Second block header
|
# Second block header
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#attesterslashing
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#attesterslashing
|
||||||
AttesterSlashing* = object
|
AttesterSlashing* = object
|
||||||
slashable_attestation_1*: SlashableAttestation ## \
|
slashable_attestation_1*: SlashableAttestation ## \
|
||||||
## First slashable attestation
|
## First slashable attestation
|
||||||
|
@ -211,7 +215,7 @@ type
|
||||||
aggregate_signature*: ValidatorSig ## \
|
aggregate_signature*: ValidatorSig ## \
|
||||||
## Aggregate signature
|
## Aggregate signature
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#attestation
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#attestation
|
||||||
Attestation* = object
|
Attestation* = object
|
||||||
aggregation_bitfield*: seq[byte] ##\
|
aggregation_bitfield*: seq[byte] ##\
|
||||||
## Attester aggregation bitfield
|
## Attester aggregation bitfield
|
||||||
|
@ -227,38 +231,31 @@ type
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#attestationdata
|
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#attestationdata
|
||||||
AttestationData* = object
|
AttestationData* = object
|
||||||
slot*: Slot ##\
|
# LMD GHOST vote
|
||||||
## Slot number
|
slot*: Slot
|
||||||
|
beacon_block_root*: Eth2Digest
|
||||||
|
|
||||||
shard*: uint64 ##\
|
# FFG vote
|
||||||
## Shard number
|
source_epoch*: Epoch
|
||||||
|
## TODO epoch_boundary_root and justified_block_root are creatures of new
|
||||||
|
## epoch processing and don't function quite as straightforwardly as just
|
||||||
|
## renamings, so do that as part of epoch processing change.
|
||||||
|
epoch_boundary_root*: Eth2Digest
|
||||||
|
justified_block_root*: Eth2Digest
|
||||||
|
|
||||||
beacon_block_root*: Eth2Digest ##\
|
# Crosslink vote
|
||||||
## Hash of root of the signed beacon block
|
shard*: uint64
|
||||||
|
previous_crosslink*: Crosslink
|
||||||
epoch_boundary_root*: Eth2Digest ##\
|
crosslink_data_root*: Eth2Digest
|
||||||
## Hash of root of the ancestor at the epoch boundary
|
|
||||||
|
|
||||||
crosslink_data_root*: Eth2Digest ##\
|
|
||||||
## Data from the shard since the last attestation
|
|
||||||
|
|
||||||
latest_crosslink*: Crosslink ##\
|
|
||||||
## Last crosslink
|
|
||||||
|
|
||||||
justified_epoch*: Epoch ##\
|
|
||||||
## Last justified epoch in the beacon state
|
|
||||||
|
|
||||||
justified_block_root*: Eth2Digest ##\
|
|
||||||
## Hash of the last justified beacon block
|
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#attestationdataandcustodybit
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#attestationdataandcustodybit
|
||||||
AttestationDataAndCustodyBit* = object
|
AttestationDataAndCustodyBit* = object
|
||||||
data*: AttestationData
|
data*: AttestationData
|
||||||
custody_bit*: bool
|
custody_bit*: bool
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#deposit
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#deposit
|
||||||
Deposit* = object
|
Deposit* = object
|
||||||
branch*: seq[Eth2Digest] ##\
|
proof*: array[DEPOSIT_CONTRACT_TREE_DEPTH, Eth2Digest] ##\
|
||||||
## Branch in the deposit tree
|
## Branch in the deposit tree
|
||||||
|
|
||||||
index*: uint64 ##\
|
index*: uint64 ##\
|
||||||
|
@ -289,12 +286,12 @@ type
|
||||||
# Validator signature
|
# Validator signature
|
||||||
signature*: ValidatorSig
|
signature*: ValidatorSig
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#transfer
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#transfer
|
||||||
Transfer* = object
|
Transfer* = object
|
||||||
from_field*: uint64 ##\
|
sender*: uint64 ##\
|
||||||
## Sender index
|
## Sender index
|
||||||
|
|
||||||
to*: uint64 ##\
|
recipient*: uint64 ##\
|
||||||
## Recipient index
|
## Recipient index
|
||||||
|
|
||||||
amount*: uint64 ##\
|
amount*: uint64 ##\
|
||||||
|
@ -433,9 +430,8 @@ type
|
||||||
## `latest_block_header.state_root == ZERO_HASH` temporarily
|
## `latest_block_header.state_root == ZERO_HASH` temporarily
|
||||||
historical_roots*: seq[Eth2Digest]
|
historical_roots*: seq[Eth2Digest]
|
||||||
|
|
||||||
# TOOD remove these, gone in 0.5
|
# TOOD remove, gone in 0.5
|
||||||
latest_attestations*: seq[PendingAttestation]
|
latest_attestations*: seq[PendingAttestation]
|
||||||
batched_block_roots*: seq[Eth2Digest]
|
|
||||||
|
|
||||||
# Ethereum 1.0 chain data
|
# Ethereum 1.0 chain data
|
||||||
latest_eth1_data*: Eth1Data
|
latest_eth1_data*: Eth1Data
|
||||||
|
@ -485,9 +481,14 @@ type
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#fork
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#fork
|
||||||
Fork* = object
|
Fork* = object
|
||||||
previous_version*: uint64 # Previous fork version
|
previous_version*: array[4, byte] ##\
|
||||||
current_version*: uint64 # Current fork version
|
## Previous fork version
|
||||||
epoch*: Epoch # Fork epoch number
|
|
||||||
|
current_version*: array[4, byte] ##\
|
||||||
|
## Current fork version
|
||||||
|
|
||||||
|
epoch*: Epoch ##\
|
||||||
|
## Fork epoch number
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#eth1data
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#eth1data
|
||||||
Eth1Data* = object
|
Eth1Data* = object
|
||||||
|
|
|
@ -69,24 +69,17 @@ func integer_squareroot*(n: SomeInteger): SomeInteger =
|
||||||
y = (x + n div x) div 2
|
y = (x + n div x) div 2
|
||||||
x
|
x
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_fork_version
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_fork_version
|
||||||
func get_fork_version*(fork: Fork, epoch: Epoch): uint64 =
|
func get_fork_version*(fork: Fork, epoch: Epoch): array[4, byte] =
|
||||||
## Return the fork version of the given ``epoch``.
|
## Return the fork version of the given ``epoch``.
|
||||||
if epoch < fork.epoch:
|
if epoch < fork.epoch:
|
||||||
fork.previous_version
|
fork.previous_version
|
||||||
else:
|
else:
|
||||||
fork.current_version
|
fork.current_version
|
||||||
|
|
||||||
# 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.5.0/specs/core/0_beacon-chain.md#is_power_of_two
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#is_power_of_two
|
||||||
func is_power_of_2*(v: uint64): bool = (v > 0'u64) and (v and (v-1)) == 0
|
func is_power_of_2*(v: uint64): bool = (v > 0'u64) and (v and (v-1)) == 0
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#merkle_root
|
|
||||||
func merkle_root*(values: openArray[Eth2Digest]): Eth2Digest =
|
func merkle_root*(values: openArray[Eth2Digest]): Eth2Digest =
|
||||||
## Merkleize ``values`` (where ``len(values)`` is a power of two) and return
|
## Merkleize ``values`` (where ``len(values)`` is a power of two) and return
|
||||||
## the Merkle root.
|
## the Merkle root.
|
||||||
|
@ -146,8 +139,8 @@ func is_surround_vote*(attestation_data_1: AttestationData,
|
||||||
attestation_data_2: AttestationData): bool =
|
attestation_data_2: AttestationData): bool =
|
||||||
## Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
## Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
|
||||||
let
|
let
|
||||||
source_epoch_1 = attestation_data_1.justified_epoch
|
source_epoch_1 = attestation_data_1.source_epoch
|
||||||
source_epoch_2 = attestation_data_2.justified_epoch
|
source_epoch_2 = attestation_data_2.source_epoch
|
||||||
# RLP artifact
|
# RLP artifact
|
||||||
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
||||||
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
||||||
|
@ -159,7 +152,7 @@ func is_active_validator*(validator: Validator, epoch: Epoch): bool =
|
||||||
### Check if ``validator`` is active
|
### Check if ``validator`` is active
|
||||||
validator.activation_epoch <= epoch and epoch < validator.exit_epoch
|
validator.activation_epoch <= epoch and epoch < validator.exit_epoch
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_active_validator_indices
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_active_validator_indices
|
||||||
func get_active_validator_indices*(validators: openArray[Validator], epoch: Epoch): seq[ValidatorIndex] =
|
func get_active_validator_indices*(validators: openArray[Validator], epoch: Epoch): seq[ValidatorIndex] =
|
||||||
## Gets indices of active validators from validators
|
## Gets indices of active validators from validators
|
||||||
for idx, val in validators:
|
for idx, val in validators:
|
||||||
|
@ -210,7 +203,7 @@ func get_active_index_root(state: BeaconState, epoch: Epoch): Eth2Digest =
|
||||||
state.latest_active_index_roots[epoch mod LATEST_ACTIVE_INDEX_ROOTS_LENGTH]
|
state.latest_active_index_roots[epoch mod LATEST_ACTIVE_INDEX_ROOTS_LENGTH]
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#bytes_to_int
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#bytes_to_int
|
||||||
func bytes_to_int*(data: seq[byte]): uint64 =
|
func bytes_to_int*(data: openarray[byte]): uint64 =
|
||||||
doAssert data.len == 8
|
doAssert data.len == 8
|
||||||
|
|
||||||
# Little-endian data representation
|
# Little-endian data representation
|
||||||
|
@ -219,7 +212,7 @@ func bytes_to_int*(data: seq[byte]): uint64 =
|
||||||
result = result * 256 + data[i]
|
result = result * 256 + data[i]
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#int_to_bytes1-int_to_bytes2-
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#int_to_bytes1-int_to_bytes2-
|
||||||
# Have 1, 4, and 32-byte versions. 2+ more and maybe worth metaprogramming.
|
# Have 1, 4, 8, and 32-byte versions. 1+ more and maybe worth metaprogramming.
|
||||||
func int_to_bytes32*(x: uint64): array[32, byte] =
|
func int_to_bytes32*(x: uint64): array[32, byte] =
|
||||||
## Little-endian data representation
|
## Little-endian data representation
|
||||||
## TODO remove uint64 when those callers fade away
|
## TODO remove uint64 when those callers fade away
|
||||||
|
@ -228,6 +221,10 @@ func int_to_bytes32*(x: uint64): array[32, byte] =
|
||||||
|
|
||||||
func int_to_bytes32*(x: Epoch): array[32, byte] {.borrow.}
|
func int_to_bytes32*(x: Epoch): array[32, byte] {.borrow.}
|
||||||
|
|
||||||
|
func int_to_bytes8*(x: uint64): array[8, byte] =
|
||||||
|
for i in 0 ..< 8:
|
||||||
|
result[i] = byte((x shr i*8) and 0xff)
|
||||||
|
|
||||||
func int_to_bytes1*(x: int): array[1, byte] =
|
func int_to_bytes1*(x: int): array[1, byte] =
|
||||||
doAssert x >= 0
|
doAssert x >= 0
|
||||||
doAssert x < 256
|
doAssert x < 256
|
||||||
|
@ -244,6 +241,15 @@ func int_to_bytes4*(x: uint64): array[4, byte] =
|
||||||
result[2] = ((x shr 16) and 0xff).byte
|
result[2] = ((x shr 16) and 0xff).byte
|
||||||
result[3] = ((x shr 24) and 0xff).byte
|
result[3] = ((x shr 24) and 0xff).byte
|
||||||
|
|
||||||
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.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.
|
||||||
|
var buf: array[8, byte]
|
||||||
|
buf[0..3] = get_fork_version(fork, epoch)
|
||||||
|
buf[4..7] = int_to_bytes4(domain_type.uint64)
|
||||||
|
bytes_to_int(buf)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#generate_seed
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#generate_seed
|
||||||
func generate_seed*(state: BeaconState, epoch: Epoch): Eth2Digest =
|
func generate_seed*(state: BeaconState, epoch: Epoch): Eth2Digest =
|
||||||
# Generate a seed for the given ``epoch``.
|
# Generate a seed for the given ``epoch``.
|
||||||
|
|
|
@ -12,8 +12,8 @@ import
|
||||||
../ssz,
|
../ssz,
|
||||||
./crypto, ./datatypes, ./digest, ./helpers
|
./crypto, ./datatypes, ./digest, ./helpers
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_shuffling
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_shuffling
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_permuted_index
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#get_permuted_index
|
||||||
func get_shuffled_seq*(seed: Eth2Digest,
|
func get_shuffled_seq*(seed: Eth2Digest,
|
||||||
list_size: uint64,
|
list_size: uint64,
|
||||||
): seq[ValidatorIndex] =
|
): seq[ValidatorIndex] =
|
||||||
|
|
|
@ -315,12 +315,13 @@ func hash_tree_root*[T: object|tuple](x: T): array[32, byte] =
|
||||||
h.update hash_tree_root(field.toSSZType)
|
h.update hash_tree_root(field.toSSZType)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/simple-serialize.md#signed-roots
|
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/simple-serialize.md#signed-roots
|
||||||
func signed_root*[T: object](x: T, ignored: string = "sig"): array[32, byte] =
|
func signed_root*[T: object](x: T): array[32, byte] =
|
||||||
# TODO write tests for this (check vs hash_tree_root)
|
# TODO write tests for this (check vs hash_tree_root)
|
||||||
|
|
||||||
var found_field_name = false
|
var found_field_name = false
|
||||||
|
|
||||||
## TODO this isn't how 0.5 defines signed_root, but works well enough
|
## TODO this isn't how 0.5 defines signed_root, but works well enough
|
||||||
|
## for now.
|
||||||
withHash:
|
withHash:
|
||||||
for name, field in x.fieldPairs:
|
for name, field in x.fieldPairs:
|
||||||
if name == "signature":
|
if name == "signature":
|
||||||
|
|
|
@ -51,11 +51,11 @@ func verifyBlockSignature(state: BeaconState, blck: BeaconBlock): bool =
|
||||||
proposal = Proposal(
|
proposal = Proposal(
|
||||||
slot: blck.slot.uint64,
|
slot: blck.slot.uint64,
|
||||||
shard: BEACON_CHAIN_SHARD_NUMBER,
|
shard: BEACON_CHAIN_SHARD_NUMBER,
|
||||||
block_root: Eth2Digest(data: signed_root(blck, "signature")),
|
block_root: Eth2Digest(data: signed_root(blck)),
|
||||||
signature: blck.signature)
|
signature: blck.signature)
|
||||||
bls_verify(
|
bls_verify(
|
||||||
proposer.pubkey,
|
proposer.pubkey,
|
||||||
signed_root(proposal, "signature"),
|
signed_root(proposal),
|
||||||
proposal.signature,
|
proposal.signature,
|
||||||
get_domain(state.fork, get_current_epoch(state), DOMAIN_BEACON_BLOCK))
|
get_domain(state.fork, get_current_epoch(state), DOMAIN_BEACON_BLOCK))
|
||||||
|
|
||||||
|
@ -126,8 +126,8 @@ proc processRandao(
|
||||||
|
|
||||||
true
|
true
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#eth1-data
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#eth1-data-1
|
||||||
func processDepositRoot(state: var BeaconState, blck: BeaconBlock) =
|
func processEth1Data(state: var BeaconState, blck: BeaconBlock) =
|
||||||
# TODO verify that there's at most one match
|
# TODO verify that there's at most one match
|
||||||
for x in state.eth1_data_votes.mitems():
|
for x in state.eth1_data_votes.mitems():
|
||||||
if blck.body.eth1_data == x.eth1_data:
|
if blck.body.eth1_data == x.eth1_data:
|
||||||
|
@ -344,7 +344,7 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
|
||||||
return false
|
return false
|
||||||
|
|
||||||
for transfer in blck.body.transfers:
|
for transfer in blck.body.transfers:
|
||||||
let from_balance = state.validator_balances[transfer.from_field.int]
|
let from_balance = state.validator_balances[transfer.sender.int]
|
||||||
|
|
||||||
if not (from_balance >= transfer.amount):
|
if not (from_balance >= transfer.amount):
|
||||||
notice "Transfer: source balance too low for amount"
|
notice "Transfer: source balance too low for amount"
|
||||||
|
@ -365,13 +365,13 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
|
||||||
|
|
||||||
if not (get_current_epoch(state) >=
|
if not (get_current_epoch(state) >=
|
||||||
state.validator_registry[
|
state.validator_registry[
|
||||||
transfer.from_field.int].withdrawable_epoch or
|
transfer.sender.int].withdrawable_epoch or
|
||||||
state.validator_registry[transfer.from_field.int].activation_epoch ==
|
state.validator_registry[transfer.sender.int].activation_epoch ==
|
||||||
FAR_FUTURE_EPOCH):
|
FAR_FUTURE_EPOCH):
|
||||||
notice "Transfer: epoch mismatch"
|
notice "Transfer: epoch mismatch"
|
||||||
return false
|
return false
|
||||||
|
|
||||||
let wc = state.validator_registry[transfer.from_field.int].
|
let wc = state.validator_registry[transfer.sender.int].
|
||||||
withdrawal_credentials
|
withdrawal_credentials
|
||||||
if not (wc.data[0] == BLS_WITHDRAWAL_PREFIX_BYTE and
|
if not (wc.data[0] == BLS_WITHDRAWAL_PREFIX_BYTE and
|
||||||
wc.data[1..^1] == eth2hash(transfer.pubkey.getBytes).data[1..^1]):
|
wc.data[1..^1] == eth2hash(transfer.pubkey.getBytes).data[1..^1]):
|
||||||
|
@ -389,9 +389,9 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
|
||||||
|
|
||||||
# TODO https://github.com/ethereum/eth2.0-specs/issues/727
|
# TODO https://github.com/ethereum/eth2.0-specs/issues/727
|
||||||
reduce_balance(
|
reduce_balance(
|
||||||
state.validator_balances[transfer.from_field.int],
|
state.validator_balances[transfer.sender.int],
|
||||||
transfer.amount + transfer.fee)
|
transfer.amount + transfer.fee)
|
||||||
state.validator_balances[transfer.to.int] += transfer.amount
|
state.validator_balances[transfer.recipient.int] += transfer.amount
|
||||||
state.validator_balances[
|
state.validator_balances[
|
||||||
get_beacon_proposer_index(state, state.slot)] += transfer.fee
|
get_beacon_proposer_index(state, state.slot)] += transfer.fee
|
||||||
|
|
||||||
|
@ -431,8 +431,6 @@ func processSlot(state: var BeaconState, previous_block_root: Eth2Digest) =
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#block-roots
|
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#block-roots
|
||||||
state.latest_block_roots[(state.slot - 1) mod SLOTS_PER_HISTORICAL_ROOT] =
|
state.latest_block_roots[(state.slot - 1) mod SLOTS_PER_HISTORICAL_ROOT] =
|
||||||
previous_block_root
|
previous_block_root
|
||||||
if state.slot mod SLOTS_PER_HISTORICAL_ROOT == 0:
|
|
||||||
state.batched_block_roots.add(merkle_root(state.latest_block_roots))
|
|
||||||
|
|
||||||
proc processBlock(
|
proc processBlock(
|
||||||
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
|
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
|
||||||
|
@ -478,7 +476,7 @@ proc processBlock(
|
||||||
if not processRandao(state, blck, flags):
|
if not processRandao(state, blck, flags):
|
||||||
return false
|
return false
|
||||||
|
|
||||||
processDepositRoot(state, blck)
|
processEth1Data(state, blck)
|
||||||
|
|
||||||
if not processProposerSlashings(state, blck, flags):
|
if not processProposerSlashings(state, blck, flags):
|
||||||
return false
|
return false
|
||||||
|
@ -534,7 +532,6 @@ func process_slashings(state: var BeaconState) =
|
||||||
current_epoch = get_current_epoch(state)
|
current_epoch = get_current_epoch(state)
|
||||||
active_validator_indices = get_active_validator_indices(
|
active_validator_indices = get_active_validator_indices(
|
||||||
state.validator_registry, current_epoch)
|
state.validator_registry, current_epoch)
|
||||||
# 0.4.0 spec doesn't use this helper function?
|
|
||||||
total_balance = get_total_balance(state, active_validator_indices)
|
total_balance = get_total_balance(state, active_validator_indices)
|
||||||
|
|
||||||
for index, validator in state.validator_registry:
|
for index, validator in state.validator_registry:
|
||||||
|
@ -591,7 +588,6 @@ func processEpoch(state: var BeaconState) =
|
||||||
if (state.slot + 1) mod SLOTS_PER_EPOCH != 0:
|
if (state.slot + 1) mod SLOTS_PER_EPOCH != 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#helper-variables
|
|
||||||
let
|
let
|
||||||
current_epoch = get_current_epoch(state)
|
current_epoch = get_current_epoch(state)
|
||||||
previous_epoch = get_previous_epoch(state)
|
previous_epoch = get_previous_epoch(state)
|
||||||
|
@ -998,7 +994,7 @@ func processEpoch(state: var BeaconState) =
|
||||||
not (slot_to_epoch(it.data.slot) < current_epoch)
|
not (slot_to_epoch(it.data.slot) < current_epoch)
|
||||||
)
|
)
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#state-root-verification
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#state-root-verification
|
||||||
proc verifyStateRoot(state: BeaconState, blck: BeaconBlock): bool =
|
proc verifyStateRoot(state: BeaconState, blck: BeaconBlock): bool =
|
||||||
let state_root = hash_tree_root_final(state)
|
let state_root = hash_tree_root_final(state)
|
||||||
if state_root != blck.state_root:
|
if state_root != blck.state_root:
|
||||||
|
|
|
@ -30,7 +30,7 @@ proc signBlockProposal*(v: AttachedValidator, fork: Fork,
|
||||||
await sleepAsync(1)
|
await sleepAsync(1)
|
||||||
let proposalRoot = hash_tree_root_final(proposal)
|
let proposalRoot = hash_tree_root_final(proposal)
|
||||||
|
|
||||||
result = bls_sign(v.privKey, signed_root(proposal, "signature"),
|
result = bls_sign(v.privKey, signed_root(proposal),
|
||||||
get_domain(fork, slot_to_epoch(proposal.slot), DOMAIN_BEACON_BLOCK))
|
get_domain(fork, slot_to_epoch(proposal.slot), DOMAIN_BEACON_BLOCK))
|
||||||
else:
|
else:
|
||||||
# TODO:
|
# TODO:
|
||||||
|
|
|
@ -47,6 +47,7 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
|
||||||
bls_sign(privkey, hash_tree_root_final(proof_of_possession_data).data, domain)
|
bls_sign(privkey, hash_tree_root_final(proof_of_possession_data).data, domain)
|
||||||
|
|
||||||
Deposit(
|
Deposit(
|
||||||
|
index: i.uint64,
|
||||||
deposit_data: DepositData(
|
deposit_data: DepositData(
|
||||||
deposit_input: DepositInput(
|
deposit_input: DepositInput(
|
||||||
pubkey: pubkey,
|
pubkey: pubkey,
|
||||||
|
@ -85,7 +86,7 @@ proc addBlock*(
|
||||||
# Ferret out remaining GENESIS_EPOCH == 0 assumptions in test code
|
# Ferret out remaining GENESIS_EPOCH == 0 assumptions in test code
|
||||||
doAssert allIt(
|
doAssert allIt(
|
||||||
body.attestations,
|
body.attestations,
|
||||||
it.data.latest_crosslink.epoch >= GENESIS_EPOCH)
|
it.data.previous_crosslink.epoch >= GENESIS_EPOCH)
|
||||||
|
|
||||||
let
|
let
|
||||||
# Index from the new state, but registry from the old state.. hmm...
|
# Index from the new state, but registry from the old state.. hmm...
|
||||||
|
@ -125,10 +126,10 @@ proc addBlock*(
|
||||||
signed_data = Proposal(
|
signed_data = Proposal(
|
||||||
slot: new_block.slot.uint64,
|
slot: new_block.slot.uint64,
|
||||||
shard: BEACON_CHAIN_SHARD_NUMBER,
|
shard: BEACON_CHAIN_SHARD_NUMBER,
|
||||||
block_root: Eth2Digest(data: signed_root(new_block, "signature")),
|
block_root: Eth2Digest(data: signed_root(new_block)),
|
||||||
signature: ValidatorSig(),
|
signature: ValidatorSig(),
|
||||||
)
|
)
|
||||||
proposal_hash = signed_root(signed_data, "signature")
|
proposal_hash = signed_root(signed_data)
|
||||||
|
|
||||||
doAssert proposerPrivkey.pubKey() == proposer.pubkey,
|
doAssert proposerPrivkey.pubKey() == proposer.pubkey,
|
||||||
"signature key should be derived from private key! - wrong privkey?"
|
"signature key should be derived from private key! - wrong privkey?"
|
||||||
|
|
Loading…
Reference in New Issue