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:
Dustin Brody 2019-03-17 15:17:40 -07:00
parent f36c2d86dc
commit 18f1d000a1
No known key found for this signature in database
GPG Key ID: 3D7A11A0156519DC
10 changed files with 153 additions and 90 deletions

View File

@ -239,7 +239,7 @@ proc add*(pool: var AttestationPool,
slot = humaneSlotNum(attestation.data.slot),
shard = attestation.data.shard,
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),
signature = shortLog(attestation.aggregate_signature),
validations = a.validations.len() # TODO popcount of union
@ -262,7 +262,7 @@ proc add*(pool: var AttestationPool,
slot = humaneSlotNum(attestation.data.slot),
shard = attestation.data.shard,
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),
signature = shortLog(attestation.aggregate_signature),
validations = 1
@ -350,4 +350,4 @@ proc resolve*(pool: var AttestationPool, state: BeaconState) =
proc latestAttestation*(
pool: AttestationPool, pubKey: ValidatorPubKey): BlockRef =
pool.latestAttestations.getOrDefault(pubKey)
pool.latestAttestations.getOrDefault(pubKey)

View File

@ -312,7 +312,7 @@ proc proposeBlock(node: BeaconNode,
let proposal = Proposal(
slot: slot.uint64,
shard: BEACON_CHAIN_SHARD_NUMBER,
block_root: Eth2Digest(data: signed_root(newBlock, "signature")),
block_root: Eth2Digest(data: signed_root(newBlock)),
signature: ValidatorSig(),
)
newBlock.signature =
@ -523,7 +523,7 @@ proc onAttestation(node: BeaconNode, attestation: Attestation) =
slot = humaneSlotNum(attestation.data.slot),
shard = attestation.data.shard,
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),
signature = shortLog(attestation.aggregate_signature)

View File

@ -16,6 +16,24 @@ func get_effective_balance*(state: BeaconState, index: ValidatorIndex): Gwei =
## validator with the given ``index``.
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
func process_deposit(state: var BeaconState, deposit: Deposit) =
## 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
## 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(
## state, pubkey, proof_of_possession, withdrawal_credentials):
## return
@ -89,19 +143,22 @@ 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/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,
index: ValidatorIndex) =
## Exit the validator with the given ``index``.
## 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
if validator.exit_epoch <= get_delayed_activation_exit_epoch(get_current_epoch(state)):
if validator.exit_epoch <= delayed_activation_exit_epoch:
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) =
# Not in spec, but useful to avoid underflow.
@ -228,7 +285,7 @@ func get_genesis_beacon_state*(
# Recent state
# 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()),
)
@ -386,6 +443,7 @@ func update_validator_registry*(state: var BeaconState) =
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
# TODO this is https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#attestations now
proc checkAttestation*(
state: BeaconState, attestation: Attestation, flags: UpdateFlags): bool =
## Check that an attestation follows the rules of being included in the state
@ -418,15 +476,15 @@ proc checkAttestation*(
else:
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",
attestation_justified_epoch =
humaneEpochNum(attestation.data.justified_epoch),
humaneEpochNum(attestation.data.source_epoch),
expected_justified_epoch = humaneEpochNum(expected_justified_epoch))
return
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):
warn("Unexpected justified block root",
attestation_justified_block_root = attestation.data.justified_block_root,
@ -434,14 +492,14 @@ proc checkAttestation*(
return
if not (state.latest_crosslinks[attestation.data.shard] in [
attestation.data.latest_crosslink,
attestation.data.previous_crosslink,
Crosslink(
crosslink_data_root: attestation.data.crosslink_data_root,
epoch: slot_to_epoch(attestation_data_slot))]):
warn("Unexpected crosslink 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)),
crosslink_data_root = attestation.data.crosslink_data_root)
return
@ -545,7 +603,7 @@ proc makeAttestationData*(
beacon_block_root: beacon_block_root,
epoch_boundary_root: epoch_boundary_root,
crosslink_data_root: Eth2Digest(), # Stub in phase0
latest_crosslink: state.latest_crosslinks[shard],
justified_epoch: state.current_justified_epoch,
previous_crosslink: state.latest_crosslinks[shard],
source_epoch: state.current_justified_epoch,
justified_block_root: justified_block_root,
)

View File

@ -83,7 +83,7 @@ const
# 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
# 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
# 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_EPOCH* = (GENESIS_SLOT.uint64 div SLOTS_PER_EPOCH).Epoch ##\
## slot_to_epoch(GENESIS_SLOT)
@ -118,7 +119,7 @@ const
BLS_WITHDRAWAL_PREFIX_BYTE* = 0'u8
# 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
## TODO consistent time unit across projects, similar to C++ chrono?
@ -151,6 +152,9 @@ const
MIN_VALIDATOR_WITHDRAWABILITY_DELAY* = 2'u64^8 ##\
## 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
LATEST_RANDAO_MIXES_LENGTH* = 8192
LATEST_ACTIVE_INDEX_ROOTS_LENGTH* = 8192 # 2'u64^13, epochs
@ -190,7 +194,7 @@ type
header_2*: BeaconBlockHeader ##\
# 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
slashable_attestation_1*: SlashableAttestation ## \
## First slashable attestation
@ -211,7 +215,7 @@ type
aggregate_signature*: ValidatorSig ## \
## 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
aggregation_bitfield*: seq[byte] ##\
## 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
AttestationData* = object
slot*: Slot ##\
## Slot number
# LMD GHOST vote
slot*: Slot
beacon_block_root*: Eth2Digest
shard*: uint64 ##\
## Shard number
# FFG vote
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 ##\
## Hash of root of the signed beacon block
epoch_boundary_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
# Crosslink vote
shard*: uint64
previous_crosslink*: Crosslink
crosslink_data_root*: Eth2Digest
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#attestationdataandcustodybit
AttestationDataAndCustodyBit* = object
data*: AttestationData
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
branch*: seq[Eth2Digest] ##\
proof*: array[DEPOSIT_CONTRACT_TREE_DEPTH, Eth2Digest] ##\
## Branch in the deposit tree
index*: uint64 ##\
@ -289,12 +286,12 @@ type
# Validator signature
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
from_field*: uint64 ##\
sender*: uint64 ##\
## Sender index
to*: uint64 ##\
recipient*: uint64 ##\
## Recipient index
amount*: uint64 ##\
@ -433,9 +430,8 @@ type
## `latest_block_header.state_root == ZERO_HASH` temporarily
historical_roots*: seq[Eth2Digest]
# TOOD remove these, gone in 0.5
# TOOD remove, gone in 0.5
latest_attestations*: seq[PendingAttestation]
batched_block_roots*: seq[Eth2Digest]
# Ethereum 1.0 chain data
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
Fork* = object
previous_version*: uint64 # Previous fork version
current_version*: uint64 # Current fork version
epoch*: Epoch # Fork epoch number
previous_version*: array[4, byte] ##\
## Previous fork version
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
Eth1Data* = object

View File

@ -69,24 +69,17 @@ func integer_squareroot*(n: SomeInteger): SomeInteger =
y = (x + n div x) div 2
x
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_fork_version
func get_fork_version*(fork: Fork, epoch: Epoch): uint64 =
# 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): array[4, byte] =
## Return the fork version of the given ``epoch``.
if epoch < fork.epoch:
fork.previous_version
else:
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
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 =
## Merkleize ``values`` (where ``len(values)`` is a power of two) and return
## the Merkle root.
@ -146,8 +139,8 @@ func is_surround_vote*(attestation_data_1: AttestationData,
attestation_data_2: AttestationData): bool =
## Check if ``attestation_data_1`` surrounds ``attestation_data_2``.
let
source_epoch_1 = attestation_data_1.justified_epoch
source_epoch_2 = attestation_data_2.justified_epoch
source_epoch_1 = attestation_data_1.source_epoch
source_epoch_2 = attestation_data_2.source_epoch
# RLP artifact
target_epoch_1 = slot_to_epoch(attestation_data_1.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
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] =
## Gets indices of active validators from 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]
# 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
# Little-endian data representation
@ -219,7 +212,7 @@ func bytes_to_int*(data: seq[byte]): uint64 =
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-
# 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] =
## Little-endian data representation
## 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_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] =
doAssert x >= 0
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[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
func generate_seed*(state: BeaconState, epoch: Epoch): Eth2Digest =
# Generate a seed for the given ``epoch``.

View File

@ -12,8 +12,8 @@ import
../ssz,
./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/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_shuffling
# 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,
list_size: uint64,
): seq[ValidatorIndex] =

View File

@ -315,12 +315,13 @@ func hash_tree_root*[T: object|tuple](x: T): array[32, byte] =
h.update hash_tree_root(field.toSSZType)
# 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)
var found_field_name = false
## TODO this isn't how 0.5 defines signed_root, but works well enough
## for now.
withHash:
for name, field in x.fieldPairs:
if name == "signature":

View File

@ -51,11 +51,11 @@ func verifyBlockSignature(state: BeaconState, blck: BeaconBlock): bool =
proposal = Proposal(
slot: blck.slot.uint64,
shard: BEACON_CHAIN_SHARD_NUMBER,
block_root: Eth2Digest(data: signed_root(blck, "signature")),
block_root: Eth2Digest(data: signed_root(blck)),
signature: blck.signature)
bls_verify(
proposer.pubkey,
signed_root(proposal, "signature"),
signed_root(proposal),
proposal.signature,
get_domain(state.fork, get_current_epoch(state), DOMAIN_BEACON_BLOCK))
@ -126,8 +126,8 @@ proc processRandao(
true
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#eth1-data
func processDepositRoot(state: var BeaconState, blck: BeaconBlock) =
# https://github.com/ethereum/eth2.0-specs/blob/v0.5.0/specs/core/0_beacon-chain.md#eth1-data-1
func processEth1Data(state: var BeaconState, blck: BeaconBlock) =
# TODO verify that there's at most one match
for x in state.eth1_data_votes.mitems():
if blck.body.eth1_data == x.eth1_data:
@ -344,7 +344,7 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
return false
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):
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) >=
state.validator_registry[
transfer.from_field.int].withdrawable_epoch or
state.validator_registry[transfer.from_field.int].activation_epoch ==
transfer.sender.int].withdrawable_epoch or
state.validator_registry[transfer.sender.int].activation_epoch ==
FAR_FUTURE_EPOCH):
notice "Transfer: epoch mismatch"
return false
let wc = state.validator_registry[transfer.from_field.int].
let wc = state.validator_registry[transfer.sender.int].
withdrawal_credentials
if not (wc.data[0] == BLS_WITHDRAWAL_PREFIX_BYTE and
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
reduce_balance(
state.validator_balances[transfer.from_field.int],
state.validator_balances[transfer.sender.int],
transfer.amount + transfer.fee)
state.validator_balances[transfer.to.int] += transfer.amount
state.validator_balances[transfer.recipient.int] += transfer.amount
state.validator_balances[
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
state.latest_block_roots[(state.slot - 1) mod SLOTS_PER_HISTORICAL_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(
state: var BeaconState, blck: BeaconBlock, flags: UpdateFlags): bool =
@ -478,7 +476,7 @@ proc processBlock(
if not processRandao(state, blck, flags):
return false
processDepositRoot(state, blck)
processEth1Data(state, blck)
if not processProposerSlashings(state, blck, flags):
return false
@ -534,7 +532,6 @@ func process_slashings(state: var BeaconState) =
current_epoch = get_current_epoch(state)
active_validator_indices = get_active_validator_indices(
state.validator_registry, current_epoch)
# 0.4.0 spec doesn't use this helper function?
total_balance = get_total_balance(state, active_validator_indices)
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:
return
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#helper-variables
let
current_epoch = get_current_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)
)
# 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 =
let state_root = hash_tree_root_final(state)
if state_root != blck.state_root:

View File

@ -30,7 +30,7 @@ proc signBlockProposal*(v: AttachedValidator, fork: Fork,
await sleepAsync(1)
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))
else:
# TODO:

View File

@ -47,6 +47,7 @@ func makeDeposit(i: int, flags: UpdateFlags): Deposit =
bls_sign(privkey, hash_tree_root_final(proof_of_possession_data).data, domain)
Deposit(
index: i.uint64,
deposit_data: DepositData(
deposit_input: DepositInput(
pubkey: pubkey,
@ -85,7 +86,7 @@ proc addBlock*(
# Ferret out remaining GENESIS_EPOCH == 0 assumptions in test code
doAssert allIt(
body.attestations,
it.data.latest_crosslink.epoch >= GENESIS_EPOCH)
it.data.previous_crosslink.epoch >= GENESIS_EPOCH)
let
# Index from the new state, but registry from the old state.. hmm...
@ -125,10 +126,10 @@ proc addBlock*(
signed_data = Proposal(
slot: new_block.slot.uint64,
shard: BEACON_CHAIN_SHARD_NUMBER,
block_root: Eth2Digest(data: signed_root(new_block, "signature")),
block_root: Eth2Digest(data: signed_root(new_block)),
signature: ValidatorSig(),
)
proposal_hash = signed_root(signed_data, "signature")
proposal_hash = signed_root(signed_data)
doAssert proposerPrivkey.pubKey() == proposer.pubkey,
"signature key should be derived from private key! - wrong privkey?"