latest_crosslink_root -> latest_crosslink; adjust checkAttestation; add SHUFFLE_ROUND_COUNT and FORK_CHOICE_BALANCE_INCREMENT constants; some additional casts because a few places where ValidatorIndex was used are now uint64; remove some old commented-out lines of code from shardcommittee transition

This commit is contained in:
Dustin Brody 2019-02-11 15:32:27 +01:00
parent 4747477160
commit d44999abc5
6 changed files with 99 additions and 55 deletions

View File

@ -171,7 +171,7 @@ proc makeAttestation(node: BeaconNode,
beacon_block_root: node.headBlockRoot,
epoch_boundary_root: Eth2Digest(), # TODO
shard_block_root: Eth2Digest(), # TODO
latest_crosslink_root: Eth2Digest(), # TODO
latest_crosslink: Crosslink(), # TODO
justified_epoch: node.beaconState.justified_epoch,
justified_block_root: justifiedBlockRoot)

View File

@ -320,20 +320,21 @@ func get_epoch_start_slot*(epoch: EpochNumber): SlotNumber =
# Return the starting slot of the given ``epoch``.
epoch * EPOCH_LENGTH
## https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#attestations-1
proc checkAttestation*(
state: BeaconState, attestation: Attestation, flags: UpdateFlags): bool =
## Check that an attestation follows the rules of being included in the state
## at the current slot. When acting as a proposer, the same rules need to
## be followed!
##
## https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#attestations-1
if not (attestation.data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot):
# Can't underflow, because GENESIS_SLOT > MIN_ATTESTATION_INCLUSION_DELAY
if not (attestation.data.slot <= state.slot - MIN_ATTESTATION_INCLUSION_DELAY):
warn("Attestation too new",
attestation_slot = attestation.data.slot, state_slot = state.slot)
return
if not (attestation.data.slot + EPOCH_LENGTH >= state.slot):
if not (state.slot - MIN_ATTESTATION_INCLUSION_DELAY <
attestation.data.slot + EPOCH_LENGTH):
warn("Attestation too old",
attestation_slot = attestation.data.slot, state_slot = state.slot)
return
@ -358,28 +359,62 @@ proc checkAttestation*(
expected_justified_block_root)
return
if not (state.latest_crosslinks[attestation.data.shard].shard_block_root in [
attestation.data.latest_crosslink_root,
attestation.data.shard_block_root]):
warn("Unexpected crosslink shard_block_root")
if not (state.latest_crosslinks[attestation.data.shard] in [
attestation.data.latest_crosslink,
Crosslink(
shard_block_root: attestation.data.shard_block_root,
epoch: slot_to_epoch(attestation.data.slot))]):
warn("Unexpected crosslink shard")
return
assert allIt(attestation.custody_bitfield, it == 0) #TO BE REMOVED IN PHASE 1
assert anyIt(attestation.aggregation_bitfield, it != 0)
let crosslink_committee = mapIt(
filterIt(get_crosslink_committees_at_slot(state, attestation.data.slot),
it.shard == attestation.data.shard),
it.committee)[0]
assert allIt(0 ..< len(crosslink_committee),
if get_bitfield_bit(
attestation.aggregation_bitfield, it) == 0b0:
get_bitfield_bit(attestation.custody_bitfield, it) == 0b0
else:
true)
let
participants = get_attestation_participants(
state, attestation.data, attestation.aggregation_bitfield)
## TODO when the custody_bitfield assertion-to-emptiness disappears do this
## and fix the custody_bit_0_participants check to depend on it.
# custody_bit_1_participants = {nothing, always, because assertion above}
custody_bit_1_participants: seq[ValidatorIndex] = @[]
custody_bit_0_participants = participants
group_public_key = bls_aggregate_pubkeys(
participants.mapIt(state.validator_registry[it].pubkey))
## the rest; turns into expensive NOP until then.
if skipValidation notin flags:
# Verify that aggregate_signature verifies using the group pubkey.
let msg = hash_tree_root_final(attestation.data)
if not bls_verify(
group_public_key, @(msg.data) & @[0'u8], attestation.aggregate_signature,
0, # TODO: get_domain(state.fork, attestation.data.slot, DOMAIN_ATTESTATION)
):
warn("Invalid attestation group signature")
return
assert bls_verify_multiple(
@[
bls_aggregate_pubkeys(mapIt(custody_bit_0_participants,
state.validator_registry[it].pubkey)),
bls_aggregate_pubkeys(mapIt(custody_bit_1_participants,
state.validator_registry[it].pubkey)),
],
@[
hash_tree_root(AttestationDataAndCustodyBit(
data: attestation.data, custody_bit: false)),
hash_tree_root(AttestationDataAndCustodyBit(
data: attestation.data, custody_bit: true)),
],
attestation.aggregate_signature,
get_domain(state.fork, slot_to_epoch(attestation.data.slot),
DOMAIN_ATTESTATION),
)
# To be removed in Phase1:
if attestation.data.shard_block_root != ZERO_HASH:

View File

@ -41,6 +41,7 @@ import
# to run.. well.. a chain with different constants!
const
# Misc
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#misc
SHARD_COUNT* = 1024 ##\
## Number of shards supported by the network - validators will jump around
## between these shards and provide attestations to their state.
@ -56,10 +57,6 @@ const
## with a Verifiable Delay Function (VDF) will improve committee robustness
## and lower the safe minimum committee size.)
EJECTION_BALANCE* = 2'u64^4 * 10'u64^9 ##\
## Once the balance of a validator drops below this, it will be ejected from
## the validator pool
MAX_BALANCE_CHURN_QUOTIENT* = 2^5 ##\
## At most `1/MAX_BALANCE_CHURN_QUOTIENT` of the validators can change during
## each validator registry change.
@ -71,16 +68,26 @@ const
MAX_WITHDRAWALS_PER_EPOCH* = 4 # withdrawals
SHUFFLE_ROUND_COUNT* = 90
# Deposit contract
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#deposit-contract
DEPOSIT_CONTRACT_TREE_DEPTH* = 2^5
# Gwei values
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#gwei-values
MIN_DEPOSIT_AMOUNT* = 2'u64^0 * 10'u64^9 ##\
## Minimum amounth of ETH that can be deposited in one call - deposits can
## be used either to top up an existing validator or commit to a new one
MAX_DEPOSIT_AMOUNT* = 2'u64^5 * 10'u64^9 ##\
## Maximum amounth of ETH that can be deposited in one call
FORK_CHOICE_BALANCE_INCREMENT* = 2'u64^0 * 10'u64^9
EJECTION_BALANCE* = 2'u64^4 * 10'u64^9 ##\
## Once the balance of a validator drops below this, it will be ejected from
## the validator pool
# Time parameter, here so that GENESIS_EPOCH can access it
EPOCH_LENGTH* = 64 ##\
## (~6.4 minutes)
@ -88,7 +95,7 @@ const
## processing is done
# Initial values
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#initial-values
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#initial-values
GENESIS_FORK_VERSION* = 0'u64
GENESIS_SLOT* = 2'u64^63
GENESIS_EPOCH* = GENESIS_SLOT div EPOCH_LENGTH # slot_to_epoch(GENESIS_SLOT)
@ -99,7 +106,7 @@ const
BLS_WITHDRAWAL_PREFIX_BYTE* = 0'u8
# Time parameters
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#time-parameters
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#time-parameters
SLOT_DURATION* = 6'u64 ## \
## TODO consistent time unit across projects, similar to C++ chrono?
@ -128,14 +135,14 @@ const
## epochs (~27 hours)
# State list lengths
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#state-list-lengths
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#state-list-lengths
LATEST_BLOCK_ROOTS_LENGTH* = 2'u64^13
LATEST_RANDAO_MIXES_LENGTH* = 2'u64^13
LATEST_INDEX_ROOTS_LENGTH* = 2'u64^13
LATEST_PENALIZED_EXIT_LENGTH* = 8192 # epochs
# Reward and penalty quotients
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#reward-and-penalty-quotients
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#reward-and-penalty-quotients
BASE_REWARD_QUOTIENT* = 2'u64^5 ##\
## The `BASE_REWARD_QUOTIENT` parameter dictates the per-epoch reward. It
## corresponds to ~2.54% annual interest assuming 10 million participating
@ -145,13 +152,12 @@ const
INACTIVITY_PENALTY_QUOTIENT* = 2'u64^24
# Status flags
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#status-flags
# Could model this with enum, but following spec closely here
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#status-flags
INITIATED_EXIT* = 1'u64
WITHDRAWABLE* = 2'u64
# Max operations per block
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#max-operations-per-block
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#max-operations-per-block
MAX_PROPOSER_SLASHINGS* = 2^4
MAX_ATTESTER_SLASHINGS* = 2^0
MAX_ATTESTATIONS* = 2^7
@ -165,20 +171,20 @@ type
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#proposerslashing
ProposerSlashing* = object
proposer_index*: ValidatorIndex
proposer_index*: uint64
proposal_data_1*: ProposalSignedData
proposal_signature_1*: ValidatorSig
proposal_data_2*: ProposalSignedData
proposal_signature_2*: ValidatorSig
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#attesterslashing
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#attesterslashing
AttesterSlashing* = object
slashable_attestation_1*: SlashableAttestation ## \
## First batch of votes
slashable_attestation_2*: SlashableAttestation ## \
## Second batch of votes
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#slashableattestation
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#slashableattestation
SlashableAttestation* = object
validator_indices*: seq[uint64] ##\
## Validator indices
@ -204,34 +210,38 @@ type
aggregate_signature*: ValidatorSig ##\
## Aggregate signature of the validators in `custody_bitfield`
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#attestationdata
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#attestation
AttestationData* = object
slot*: uint64
shard*: uint64
slot*: uint64 ##\
## Slot number
shard*: uint64 ##\
## Shard number
beacon_block_root*: Eth2Digest ##\
## Hash of the block we're signing
## Hash of root of the signed beacon block
epoch_boundary_root*: Eth2Digest ##\
## Hash of the ancestor at the cycle boundary
## Hash of root of the ancestor at the epoch boundary
shard_block_root*: Eth2Digest ##\
## Shard block hash being attested to
## Shard block's hash of root
latest_crosslink_root*: Eth2Digest ##\
## Last crosslink hash
latest_crosslink*: Crosslink ##\
## Last crosslink
justified_epoch*: uint64 ##\
## Epoch of last justified beacon block
## Last justified epoch in the beacon state
justified_block_root*: Eth2Digest ##\
## Hash of last justified beacon block
## Hash of the last justified beacon block
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#attestationdata
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#attestationdataandcustodybit
AttestationDataAndCustodyBit* = object
data*: AttestationData
custody_bit*: bool
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#deposit
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#deposit
Deposit* = object
branch*: seq[Eth2Digest] ##\
## Branch in the deposit tree
@ -242,25 +252,25 @@ type
deposit_data*: DepositData ##\
## Data
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#depositdata
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#depositdata
DepositData* = object
amount*: uint64 ## Value in Gwei
timestamp*: uint64 # Timestamp from deposit contract
deposit_input*: DepositInput
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#depositinput
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#depositinput
DepositInput* = object
pubkey*: ValidatorPubKey
withdrawal_credentials*: Eth2Digest
proof_of_possession*: ValidatorSig ##\
## BLS proof of possession (a BLS signature)
# https://github.com/ethereum/eth2.0-specs/blob/v0.1/specs/core/0_beacon-chain.md#exit
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#exit
Exit* = object
# Minimum epoch for processing exit
epoch*: uint64
# Index of the exiting validator
validator_index*: ValidatorIndex
validator_index*: uint64
# Validator signature
signature*: ValidatorSig
@ -421,7 +431,7 @@ type
Activation = 0
Exit = 1
# https://github.com/ethereum/eth2.0-specs/blob/dev/specs/core/0_beacon-chain.md#signature-domains
# https://github.com/ethereum/eth2.0-specs/blob/v0.2.0/specs/core/0_beacon-chain.md#signature-domains
SignatureDomain* {.pure.} = enum
DOMAIN_DEPOSIT = 0
DOMAIN_ATTESTATION = 1

View File

@ -140,7 +140,7 @@ proc processProposerSlashings(
return false
for proposer_slashing in blck.body.proposer_slashings:
let proposer = state.validator_registry[proposer_slashing.proposer_index]
let proposer = state.validator_registry[proposer_slashing.proposer_index.int]
if skipValidation notin flags:
if not bls_verify(
proposer.pubkey,
@ -180,7 +180,7 @@ proc processProposerSlashings(
notice "PropSlash: penalized slot"
return false
penalizeValidator(state, proposer_slashing.proposer_index)
penalizeValidator(state, proposer_slashing.proposer_index.ValidatorIndex)
return true
@ -324,7 +324,7 @@ proc processExits(
return false
for exit in blck.body.exits:
let validator = state.validator_registry[exit.validator_index]
let validator = state.validator_registry[exit.validator_index.int]
if skipValidation notin flags:
if not bls_verify(
@ -341,7 +341,7 @@ proc processExits(
notice "Exit: bad epoch"
return false
initiate_validator_exit(state, exit.validator_index)
initiate_validator_exit(state, exit.validator_index.int)
return true

View File

@ -96,7 +96,6 @@ suite "Block processing":
crosslink_committees = get_crosslink_committees_at_slot(state, state.slot)
attestation = makeAttestation(
state, previous_block_root,
#state.shard_committees_at_slots[state.slot][0].committee[0])
crosslink_committees[0].committee[0])
# Some time needs to pass before attestations are included - this is

View File

@ -174,8 +174,8 @@ proc makeAttestation*(
shard: sac.shard,
beacon_block_root: beacon_block_root,
epoch_boundary_root: Eth2Digest(), # TODO
latest_crosslink: Crosslink(), # TODO
shard_block_root: Eth2Digest(), # TODO
latest_crosslink_root: Eth2Digest(), # TODO
justified_epoch: state.justified_epoch,
justified_block_root: get_block_root(state, get_epoch_start_slot(state.justified_epoch)),
)