2018-11-26 13:33:06 +00:00
|
|
|
import
|
2019-02-19 23:35:02 +00:00
|
|
|
deques, options, sequtils, tables,
|
|
|
|
chronicles,
|
|
|
|
./spec/[beaconstate, datatypes, crypto, digest, helpers, validator], extras,
|
2019-03-13 22:59:20 +00:00
|
|
|
./attestation_pool, ./beacon_node_types, ./beacon_chain_db, ./ssz
|
2018-12-15 16:32:36 +00:00
|
|
|
|
2019-03-13 22:59:20 +00:00
|
|
|
proc get_ancestor(blck: BlockRef, slot: Slot): BlockRef =
|
|
|
|
if blck.slot == slot:
|
2019-01-14 12:19:44 +00:00
|
|
|
blck
|
2019-03-13 22:59:20 +00:00
|
|
|
elif blck.slot < slot:
|
|
|
|
nil
|
2019-01-08 17:28:21 +00:00
|
|
|
else:
|
2019-03-13 22:59:20 +00:00
|
|
|
get_ancestor(blck.parent, slot)
|
2019-01-08 17:28:21 +00:00
|
|
|
|
2019-03-13 22:59:20 +00:00
|
|
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.4.0/specs/core/0_beacon-chain.md#beacon-chain-fork-choice-rule
|
2019-01-14 12:19:44 +00:00
|
|
|
proc lmdGhost*(
|
2019-03-13 22:59:20 +00:00
|
|
|
pool: AttestationPool, start_state: BeaconState,
|
|
|
|
start_block: BlockRef): BlockRef =
|
2019-01-08 17:28:21 +00:00
|
|
|
# TODO: a Fenwick Tree datastructure to keep track of cumulated votes
|
|
|
|
# in O(log N) complexity
|
|
|
|
# https://en.wikipedia.org/wiki/Fenwick_tree
|
|
|
|
# Nim implementation for cumulative frequencies at
|
|
|
|
# https://github.com/numforge/laser/blob/990e59fffe50779cdef33aa0b8f22da19e1eb328/benchmarks/random_sampling/fenwicktree.nim
|
|
|
|
|
2019-03-13 22:59:20 +00:00
|
|
|
let
|
|
|
|
active_validator_indices =
|
|
|
|
get_active_validator_indices(
|
2019-07-01 07:53:42 +00:00
|
|
|
start_state, compute_epoch_of_slot(start_state.slot))
|
2019-03-13 22:59:20 +00:00
|
|
|
|
|
|
|
var attestation_targets: seq[tuple[validator: ValidatorIndex, blck: BlockRef]]
|
|
|
|
for i in active_validator_indices:
|
2019-07-01 09:13:14 +00:00
|
|
|
let pubKey = start_state.validators[i].pubkey
|
2019-03-13 22:59:20 +00:00
|
|
|
if (let vote = pool.latestAttestation(pubKey); not vote.isNil):
|
|
|
|
attestation_targets.add((i, vote))
|
|
|
|
|
|
|
|
template get_vote_count(blck: BlockRef): uint64 =
|
|
|
|
var res: uint64
|
|
|
|
for validator_index, target in attestation_targets.items():
|
|
|
|
if get_ancestor(target, blck.slot) == blck:
|
2019-03-14 13:33:56 +00:00
|
|
|
# The div on the balance is to chop off the insignification bits that
|
|
|
|
# fluctuate a lot epoch to epoch to have a more stable fork choice
|
0.6.2 updates (#275)
* update process_justification_and_finalization to 0.6.2; mark AttesterSlashing as 0.6.2
* replace get_effective_balance(...) with state.validator_registry[idx].effective_balance; rm get_effective_balance, process_ejections, should_update_validator_registry, update_validator_registry, and update_registry_and_shuffling_data; update get_total_balance to 0.6.2; implement process_registry_updates
* rm exit_validator; implement is_slashable_attestation_data; partly update processAttesterSlashings
* mark HistoricalBatch and Eth1Data as 0.6.2; implement get_shard_delta(...); replace 0.5 finish_epoch_update with 0.6 process_final_updates
* mark increase_balance, decrease_balance, get_delayed_activation_exit_epoch, bls_aggregate_pubkeys, bls_verify_multiple, Attestation, Transfer, slot_to_epoch, Crosslink, get_current_epoch, int_to_bytes*, various constants, processEth1Data, processTransfers, and verifyStateRoot as 0.6.2; rm is_double_vote and is_surround_vote
* mark get_bitfield_bit, verify_bitfield, ProposerSlashing, DepositData, VoluntaryExit, PendingAttestation, Fork, integer_squareroot, get_epoch_start_slot, is_active_validator, generate_seed, some constants to 0.6.2; rename MIN_PENALTY_QUOTIENT to MIN_SLASHING_PENALTY_QUOTIENT
* rm get_previous_total_balance, get_current_epoch_boundary_attestations, get_previous_epoch_boundary_attestations, and get_previous_epoch_matching_head_attestations
* update BeaconState to 0.6.2; simplify legacy get_crosslink_committees_at_slot infrastructure a bit by noting that registry_change is always false; reimplment 0.5 get_crosslink_committees_at_slot in terms of 0.6 get_crosslink_committee
* mark process_deposit(...), get_block_root_at_slot(...), get_block_root(...), Deposit, BeaconBlockHeader, BeaconBlockBody, hash(...), get_active_index_root(...), various constants, get_shard_delta(...), get_epoch_start_shard(...), get_crosslink_committee(...), processRandao(...), processVoluntaryExits(...), cacheState(...) as 0.6.2
* rm removed-since-0.5 split(...), is_power_of_2(...), get_shuffling(...); rm 0.5 versions of get_active_validator_indices and get_epoch_committee_count; add a few tests for integer_squareroot
* mark bytes_to_int(...) and advanceState(...) as 0.6.2
* rm 0.5 get_attesting_indices; update get_attesting_balance to 0.6.2
* another tiny commit to poke AppVeyor to maybe not timeout at connecting to GitHub partway through CI: mark get_churn_limit(...), initiate_validator_exit(...), and Validator as 0.6.2
* mark get_attestation_slot(...), AttestationDataAndCustodyBit, and BeaconBlock as 0.6.2
2019-06-03 10:31:04 +00:00
|
|
|
res +=
|
2019-07-01 09:13:14 +00:00
|
|
|
start_state.validators[validator_index].effective_balance div
|
2019-03-13 22:59:20 +00:00
|
|
|
FORK_CHOICE_BALANCE_INCREMENT
|
|
|
|
res
|
|
|
|
|
|
|
|
var head = start_block
|
|
|
|
while true:
|
|
|
|
if head.children.len() == 0:
|
|
|
|
return head
|
|
|
|
|
|
|
|
head = head.children[0]
|
|
|
|
var
|
|
|
|
headCount = get_vote_count(head)
|
|
|
|
|
|
|
|
for i in 1..<head.children.len:
|
|
|
|
if (let hc = get_vote_count(head.children[i]); hc > headCount):
|
|
|
|
head = head.children[i]
|
|
|
|
headCount = hc
|