mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-02-18 01:16:46 +00:00
verify that state_sim is justifying and finalizing; fix 3 more warnings; rename crosslink_committee_cache to beacon_committee_cache; fix O(n^2) usage of get_base_reward(...)
This commit is contained in:
parent
3744ba3a66
commit
6f87c8fd89
@ -60,8 +60,8 @@ task test, "Run all tests":
|
|||||||
buildBinary "all_fixtures_require_ssz", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=minimal"
|
buildBinary "all_fixtures_require_ssz", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=minimal"
|
||||||
buildBinary "all_fixtures_require_ssz", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=mainnet"
|
buildBinary "all_fixtures_require_ssz", "tests/official/", "-r -d:release -d:chronicles_log_level=DEBUG -d:const_preset=mainnet"
|
||||||
|
|
||||||
# State sim; getting into 3rd epoch useful
|
# State sim; getting into 4th epoch useful to trigger consensus checks
|
||||||
buildBinary "state_sim", "research/", "-r -d:release", "--validators=128 --slots=24"
|
buildBinary "state_sim", "research/", "-r -d:release", "--validators=128 --slots=40"
|
||||||
|
|
||||||
task sync_lfs_tests, "Sync LFS json tests":
|
task sync_lfs_tests, "Sync LFS json tests":
|
||||||
# Syncs the json test files (but not the EF yaml tests)
|
# Syncs the json test files (but not the EF yaml tests)
|
||||||
|
@ -174,7 +174,7 @@ type
|
|||||||
slots*: uint64 # number of slots that are suspected missing
|
slots*: uint64 # number of slots that are suspected missing
|
||||||
tries*: int
|
tries*: int
|
||||||
|
|
||||||
BlockRef* = ref object {.acyclic.}
|
BlockRef* {.acyclic.} = ref object
|
||||||
## Node in object graph guaranteed to lead back to tail block, and to have
|
## Node in object graph guaranteed to lead back to tail block, and to have
|
||||||
## a corresponding entry in database.
|
## a corresponding entry in database.
|
||||||
## Block graph should form a tree - in particular, there are no cycles.
|
## Block graph should form a tree - in particular, there are no cycles.
|
||||||
|
@ -197,7 +197,7 @@ else:
|
|||||||
proc createEth2Node*(conf: BeaconNodeConf,
|
proc createEth2Node*(conf: BeaconNodeConf,
|
||||||
bootstrapNodes: seq[BootstrapAddr]): Future[Eth2Node] {.async.} =
|
bootstrapNodes: seq[BootstrapAddr]): Future[Eth2Node] {.async.} =
|
||||||
var
|
var
|
||||||
(extIp, extTcpPort, extUdpPort) = setupNat(conf)
|
(extIp, extTcpPort, _) = setupNat(conf)
|
||||||
hostAddress = tcpEndPoint(globalListeningAddr, Port conf.tcpPort)
|
hostAddress = tcpEndPoint(globalListeningAddr, Port conf.tcpPort)
|
||||||
announcedAddresses = if extIp == globalListeningAddr: @[]
|
announcedAddresses = if extIp == globalListeningAddr: @[]
|
||||||
else: @[tcpEndPoint(extIp, extTcpPort)]
|
else: @[tcpEndPoint(extIp, extTcpPort)]
|
||||||
|
@ -303,7 +303,7 @@ type
|
|||||||
root*: Eth2Digest # hash_tree_root (not signing_root!)
|
root*: Eth2Digest # hash_tree_root (not signing_root!)
|
||||||
|
|
||||||
StateCache* = object
|
StateCache* = object
|
||||||
crosslink_committee_cache*:
|
beacon_committee_cache*:
|
||||||
Table[tuple[a: int, b: Eth2Digest], seq[ValidatorIndex]]
|
Table[tuple[a: int, b: Eth2Digest], seq[ValidatorIndex]]
|
||||||
active_validator_indices_cache*:
|
active_validator_indices_cache*:
|
||||||
Table[Epoch, seq[ValidatorIndex]]
|
Table[Epoch, seq[ValidatorIndex]]
|
||||||
|
@ -232,10 +232,11 @@ proc process_justification_and_finalization*(
|
|||||||
cat = "finalization"
|
cat = "finalization"
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.9.1/specs/core/0_beacon-chain.md#rewards-and-penalties-1
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.9.1/specs/core/0_beacon-chain.md#rewards-and-penalties-1
|
||||||
func get_base_reward(state: BeaconState, index: ValidatorIndex): Gwei =
|
func get_base_reward(state: BeaconState, index: ValidatorIndex,
|
||||||
let
|
total_balance: auto): Gwei =
|
||||||
total_balance = get_total_active_balance(state)
|
# Spec function recalculates total_balance every time, which creates an
|
||||||
effective_balance = state.validators[index].effective_balance
|
# O(n^2) situation.
|
||||||
|
let effective_balance = state.validators[index].effective_balance
|
||||||
effective_balance * BASE_REWARD_FACTOR div
|
effective_balance * BASE_REWARD_FACTOR div
|
||||||
integer_squareroot(total_balance) div BASE_REWARDS_PER_EPOCH
|
integer_squareroot(total_balance) div BASE_REWARDS_PER_EPOCH
|
||||||
|
|
||||||
@ -274,9 +275,10 @@ func get_attestation_deltas(state: BeaconState, stateCache: var StateCache):
|
|||||||
for index in eligible_validator_indices:
|
for index in eligible_validator_indices:
|
||||||
if index in unslashed_attesting_indices:
|
if index in unslashed_attesting_indices:
|
||||||
rewards[index] +=
|
rewards[index] +=
|
||||||
get_base_reward(state, index) * attesting_balance div total_balance
|
get_base_reward(state, index, total_balance) * attesting_balance div
|
||||||
|
total_balance
|
||||||
else:
|
else:
|
||||||
penalties[index] += get_base_reward(state, index)
|
penalties[index] += get_base_reward(state, index, total_balance)
|
||||||
|
|
||||||
# Proposer and inclusion delay micro-rewards
|
# Proposer and inclusion delay micro-rewards
|
||||||
## This depends on matching_source_attestations being an indexable seq, not a
|
## This depends on matching_source_attestations being an indexable seq, not a
|
||||||
@ -309,11 +311,12 @@ func get_attestation_deltas(state: BeaconState, stateCache: var StateCache):
|
|||||||
if a.inclusion_delay < attestation.inclusion_delay:
|
if a.inclusion_delay < attestation.inclusion_delay:
|
||||||
attestation = a
|
attestation = a
|
||||||
|
|
||||||
let proposer_reward =
|
let
|
||||||
(get_base_reward(state, index) div PROPOSER_REWARD_QUOTIENT).Gwei
|
base_reward = get_base_reward(state, index, total_balance)
|
||||||
|
proposer_reward = (base_reward div PROPOSER_REWARD_QUOTIENT).Gwei
|
||||||
|
|
||||||
rewards[attestation.proposer_index.int] += proposer_reward
|
rewards[attestation.proposer_index.int] += proposer_reward
|
||||||
let max_attester_reward = get_base_reward(state, index) - proposer_reward
|
let max_attester_reward = base_reward - proposer_reward
|
||||||
|
|
||||||
rewards[index] += max_attester_reward div attestation.inclusion_delay
|
rewards[index] += max_attester_reward div attestation.inclusion_delay
|
||||||
|
|
||||||
@ -325,7 +328,7 @@ func get_attestation_deltas(state: BeaconState, stateCache: var StateCache):
|
|||||||
state, matching_target_attestations, stateCache)
|
state, matching_target_attestations, stateCache)
|
||||||
for index in eligible_validator_indices:
|
for index in eligible_validator_indices:
|
||||||
penalties[index] +=
|
penalties[index] +=
|
||||||
BASE_REWARDS_PER_EPOCH.uint64 * get_base_reward(state, index)
|
BASE_REWARDS_PER_EPOCH.uint64 * get_base_reward(state, index, total_balance)
|
||||||
if index notin matching_target_attesting_indices:
|
if index notin matching_target_attesting_indices:
|
||||||
penalties[index] +=
|
penalties[index] +=
|
||||||
state.validators[index].effective_balance *
|
state.validators[index].effective_balance *
|
||||||
@ -426,9 +429,7 @@ proc process_epoch*(state: var BeaconState) =
|
|||||||
|
|
||||||
## Caching here for get_beacon_committee(...) can break otherwise, since
|
## Caching here for get_beacon_committee(...) can break otherwise, since
|
||||||
## get_active_validator_indices(...) usually changes.
|
## get_active_validator_indices(...) usually changes.
|
||||||
# TODO is this cache still necessary/useful? presumably not, but can't remove
|
clear(per_epoch_cache.beacon_committee_cache)
|
||||||
# quite yet
|
|
||||||
clear(per_epoch_cache.crosslink_committee_cache)
|
|
||||||
|
|
||||||
# @process_reveal_deadlines
|
# @process_reveal_deadlines
|
||||||
# @process_challenge_deadlines
|
# @process_challenge_deadlines
|
||||||
|
@ -98,8 +98,8 @@ func compute_committee(indices: seq[ValidatorIndex], seed: Eth2Digest,
|
|||||||
endIdx = (len(indices).uint64 * (index + 1)) div count
|
endIdx = (len(indices).uint64 * (index + 1)) div count
|
||||||
key = (indices.len, seed)
|
key = (indices.len, seed)
|
||||||
|
|
||||||
if key notin stateCache.crosslink_committee_cache:
|
if key notin stateCache.beacon_committee_cache:
|
||||||
stateCache.crosslink_committee_cache[key] =
|
stateCache.beacon_committee_cache[key] =
|
||||||
get_shuffled_seq(seed, len(indices).uint64)
|
get_shuffled_seq(seed, len(indices).uint64)
|
||||||
|
|
||||||
# These assertions from compute_shuffled_index(...)
|
# These assertions from compute_shuffled_index(...)
|
||||||
@ -110,15 +110,13 @@ func compute_committee(indices: seq[ValidatorIndex], seed: Eth2Digest,
|
|||||||
# In spec, this calls get_shuffled_index() every time, but that's wasteful
|
# In spec, this calls get_shuffled_index() every time, but that's wasteful
|
||||||
mapIt(
|
mapIt(
|
||||||
start.int .. (endIdx.int-1),
|
start.int .. (endIdx.int-1),
|
||||||
indices[stateCache.crosslink_committee_cache[key][it]])
|
indices[stateCache.beacon_committee_cache[key][it]])
|
||||||
|
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.9.1/specs/core/0_beacon-chain.md#get_beacon_committee
|
# https://github.com/ethereum/eth2.0-specs/blob/v0.9.1/specs/core/0_beacon-chain.md#get_beacon_committee
|
||||||
func get_beacon_committee*(state: BeaconState, slot: Slot, index: uint64, cache: var StateCache): seq[ValidatorIndex] =
|
func get_beacon_committee*(state: BeaconState, slot: Slot, index: uint64, cache: var StateCache): seq[ValidatorIndex] =
|
||||||
# Return the beacon committee at ``slot`` for ``index``.
|
# Return the beacon committee at ``slot`` for ``index``.
|
||||||
let
|
let
|
||||||
epoch = compute_epoch_at_slot(slot)
|
epoch = compute_epoch_at_slot(slot)
|
||||||
# TODO use state caching for this or not?
|
|
||||||
committees_per_slot = get_committee_count_at_slot(state, slot)
|
|
||||||
|
|
||||||
## This is a somewhat more fragile, but high-ROI, caching setup --
|
## This is a somewhat more fragile, but high-ROI, caching setup --
|
||||||
## get_active_validator_indices() is slow to run in a loop and only
|
## get_active_validator_indices() is slow to run in a loop and only
|
||||||
@ -127,22 +125,22 @@ func get_beacon_committee*(state: BeaconState, slot: Slot, index: uint64, cache:
|
|||||||
cache.active_validator_indices_cache[epoch] =
|
cache.active_validator_indices_cache[epoch] =
|
||||||
get_active_validator_indices(state, epoch)
|
get_active_validator_indices(state, epoch)
|
||||||
|
|
||||||
# TODO remove or replace this...
|
# Constant throughout an epoch
|
||||||
#if epoch notin cache.committee_count_cache:
|
if epoch notin cache.committee_count_cache:
|
||||||
# cache.committee_count_cache[epoch] = get_committee_count(state, epoch)
|
cache.committee_count_cache[epoch] =
|
||||||
|
get_committee_count_at_slot(state, slot)
|
||||||
|
|
||||||
# TODO profiling & make sure caches populated
|
|
||||||
compute_committee(
|
compute_committee(
|
||||||
cache.active_validator_indices_cache[epoch],
|
cache.active_validator_indices_cache[epoch],
|
||||||
get_seed(state, epoch, DOMAIN_BEACON_ATTESTER),
|
get_seed(state, epoch, DOMAIN_BEACON_ATTESTER),
|
||||||
(slot mod SLOTS_PER_EPOCH) * committees_per_slot + index,
|
(slot mod SLOTS_PER_EPOCH) * cache.committee_count_cache[epoch] + index,
|
||||||
committees_per_slot * SLOTS_PER_EPOCH,
|
cache.committee_count_cache[epoch] * SLOTS_PER_EPOCH,
|
||||||
cache
|
cache
|
||||||
)
|
)
|
||||||
|
|
||||||
# Not from spec
|
# Not from spec
|
||||||
func get_empty_per_epoch_cache*(): StateCache =
|
func get_empty_per_epoch_cache*(): StateCache =
|
||||||
result.crosslink_committee_cache =
|
result.beacon_committee_cache =
|
||||||
initTable[tuple[a: int, b: Eth2Digest], seq[ValidatorIndex]]()
|
initTable[tuple[a: int, b: Eth2Digest], seq[ValidatorIndex]]()
|
||||||
result.active_validator_indices_cache =
|
result.active_validator_indices_cache =
|
||||||
initTable[Epoch, seq[ValidatorIndex]]()
|
initTable[Epoch, seq[ValidatorIndex]]()
|
||||||
|
@ -52,7 +52,7 @@ func toSlot*(t: BeaconTime): tuple[afterGenesis: bool, slot: Slot] =
|
|||||||
(false, Slot(uint64(-ti) div SECONDS_PER_SLOT))
|
(false, Slot(uint64(-ti) div SECONDS_PER_SLOT))
|
||||||
|
|
||||||
func toBeaconTime*(c: BeaconClock, t: Time): BeaconTime =
|
func toBeaconTime*(c: BeaconClock, t: Time): BeaconTime =
|
||||||
BeaconTime(times.seconds(t - c.genesis))
|
BeaconTime(times.inSeconds(t - c.genesis))
|
||||||
|
|
||||||
func toSlot*(c: BeaconClock, t: Time): tuple[afterGenesis: bool, slot: Slot] =
|
func toSlot*(c: BeaconClock, t: Time): tuple[afterGenesis: bool, slot: Slot] =
|
||||||
c.toBeaconTime(t).toSlot()
|
c.toBeaconTime(t).toSlot()
|
||||||
|
@ -37,8 +37,24 @@ proc writeJson*(prefix, slot, v: auto) =
|
|||||||
let fileName = fmt"{prefix:04}-{shortLog(slot):08}.json"
|
let fileName = fmt"{prefix:04}-{shortLog(slot):08}.json"
|
||||||
Json.saveFile(fileName, v, pretty = true)
|
Json.saveFile(fileName, v, pretty = true)
|
||||||
|
|
||||||
cli do(slots = 448'u,
|
func verifyConsensus(state: BeaconState, attesterRatio: auto) =
|
||||||
validators = SLOTS_PER_EPOCH * 9, # One per shard is minimum
|
if attesterRatio < 0.63:
|
||||||
|
doAssert state.current_justified_checkpoint.epoch == 0
|
||||||
|
doAssert state.finalized_checkpoint.epoch == 0
|
||||||
|
|
||||||
|
# Quorum is 2/3 of validators, and at low numbers, quantization effects
|
||||||
|
# can dominate, so allow for play above/below attesterRatio of 2/3.
|
||||||
|
if attesterRatio < 0.72:
|
||||||
|
return
|
||||||
|
|
||||||
|
let current_epoch = get_current_epoch(state)
|
||||||
|
if current_epoch >= 3:
|
||||||
|
doAssert state.current_justified_checkpoint.epoch + 1 >= current_epoch
|
||||||
|
if current_epoch >= 4:
|
||||||
|
doAssert state.finalized_checkpoint.epoch + 2 >= current_epoch
|
||||||
|
|
||||||
|
cli do(slots = SLOTS_PER_EPOCH * 6,
|
||||||
|
validators = SLOTS_PER_EPOCH * 11, # One per shard is minimum
|
||||||
json_interval = SLOTS_PER_EPOCH,
|
json_interval = SLOTS_PER_EPOCH,
|
||||||
prefix = 0,
|
prefix = 0,
|
||||||
attesterRatio {.desc: "ratio of validators that attest in each round"} = 0.75,
|
attesterRatio {.desc: "ratio of validators that attest in each round"} = 0.75,
|
||||||
@ -69,6 +85,7 @@ cli do(slots = 448'u,
|
|||||||
|
|
||||||
for i in 0..<slots:
|
for i in 0..<slots:
|
||||||
maybeWrite()
|
maybeWrite()
|
||||||
|
verifyConsensus(state, attesterRatio)
|
||||||
|
|
||||||
let
|
let
|
||||||
attestations_idx = state.slot
|
attestations_idx = state.slot
|
||||||
@ -113,11 +130,13 @@ cli do(slots = 448'u,
|
|||||||
for v in scas:
|
for v in scas:
|
||||||
if (rand(r, high(int)).float * attesterRatio).int <= high(int):
|
if (rand(r, high(int)).float * attesterRatio).int <= high(int):
|
||||||
if first:
|
if first:
|
||||||
attestation = makeAttestation(state, latest_block_root, v, flags)
|
attestation =
|
||||||
|
makeAttestation(state, latest_block_root, v, cache, flags)
|
||||||
first = false
|
first = false
|
||||||
else:
|
else:
|
||||||
attestation.combine(
|
attestation.combine(
|
||||||
makeAttestation(state, latest_block_root, v, flags), flags)
|
makeAttestation(state, latest_block_root, v, cache, flags),
|
||||||
|
flags)
|
||||||
|
|
||||||
if not first:
|
if not first:
|
||||||
# add the attestation if any of the validators attested, as given
|
# add the attestation if any of the validators attested, as given
|
||||||
|
@ -45,7 +45,7 @@ suite "Attestation pool processing" & preset():
|
|||||||
beacon_committee = get_beacon_committee(state.data.data,
|
beacon_committee = get_beacon_committee(state.data.data,
|
||||||
state.data.data.slot, 0, cache)
|
state.data.data.slot, 0, cache)
|
||||||
attestation = makeAttestation(
|
attestation = makeAttestation(
|
||||||
state.data.data, state.blck.root, beacon_committee[0])
|
state.data.data, state.blck.root, beacon_committee[0], cache)
|
||||||
|
|
||||||
pool.add(state.data.data, state.blck, attestation)
|
pool.add(state.data.data, state.blck, attestation)
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ suite "Attestation pool processing" & preset():
|
|||||||
bc0 = get_beacon_committee(state.data.data,
|
bc0 = get_beacon_committee(state.data.data,
|
||||||
state.data.data.slot, 0, cache)
|
state.data.data.slot, 0, cache)
|
||||||
attestation0 = makeAttestation(
|
attestation0 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[0])
|
state.data.data, state.blck.root, bc0[0], cache)
|
||||||
|
|
||||||
process_slots(state.data, state.data.data.slot + 1)
|
process_slots(state.data, state.data.data.slot + 1)
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ suite "Attestation pool processing" & preset():
|
|||||||
bc1 = get_beacon_committee(state.data.data,
|
bc1 = get_beacon_committee(state.data.data,
|
||||||
state.data.data.slot, 0, cache)
|
state.data.data.slot, 0, cache)
|
||||||
attestation1 = makeAttestation(
|
attestation1 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc1[0])
|
state.data.data, state.blck.root, bc1[0], cache)
|
||||||
|
|
||||||
# test reverse order
|
# test reverse order
|
||||||
pool.add(state.data.data, state.blck, attestation1)
|
pool.add(state.data.data, state.blck, attestation1)
|
||||||
@ -95,9 +95,9 @@ suite "Attestation pool processing" & preset():
|
|||||||
bc0 = get_beacon_committee(state.data.data,
|
bc0 = get_beacon_committee(state.data.data,
|
||||||
state.data.data.slot, 0, cache)
|
state.data.data.slot, 0, cache)
|
||||||
attestation0 = makeAttestation(
|
attestation0 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[0])
|
state.data.data, state.blck.root, bc0[0], cache)
|
||||||
attestation1 = makeAttestation(
|
attestation1 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[1])
|
state.data.data, state.blck.root, bc0[1], cache)
|
||||||
|
|
||||||
pool.add(state.data.data, state.blck, attestation0)
|
pool.add(state.data.data, state.blck, attestation0)
|
||||||
pool.add(state.data.data, state.blck, attestation1)
|
pool.add(state.data.data, state.blck, attestation1)
|
||||||
@ -119,9 +119,9 @@ suite "Attestation pool processing" & preset():
|
|||||||
bc0 = get_beacon_committee(state.data.data,
|
bc0 = get_beacon_committee(state.data.data,
|
||||||
state.data.data.slot, 0, cache)
|
state.data.data.slot, 0, cache)
|
||||||
attestation0 = makeAttestation(
|
attestation0 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[0])
|
state.data.data, state.blck.root, bc0[0], cache)
|
||||||
attestation1 = makeAttestation(
|
attestation1 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[1])
|
state.data.data, state.blck.root, bc0[1], cache)
|
||||||
|
|
||||||
attestation0.combine(attestation1, {skipValidation})
|
attestation0.combine(attestation1, {skipValidation})
|
||||||
|
|
||||||
@ -144,9 +144,9 @@ suite "Attestation pool processing" & preset():
|
|||||||
bc0 = get_beacon_committee(state.data.data,
|
bc0 = get_beacon_committee(state.data.data,
|
||||||
state.data.data.slot, 0, cache)
|
state.data.data.slot, 0, cache)
|
||||||
attestation0 = makeAttestation(
|
attestation0 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[0])
|
state.data.data, state.blck.root, bc0[0], cache)
|
||||||
attestation1 = makeAttestation(
|
attestation1 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[1])
|
state.data.data, state.blck.root, bc0[1], cache)
|
||||||
|
|
||||||
attestation0.combine(attestation1, {skipValidation})
|
attestation0.combine(attestation1, {skipValidation})
|
||||||
|
|
||||||
|
@ -85,10 +85,10 @@ suite "Block processing" & preset():
|
|||||||
|
|
||||||
let
|
let
|
||||||
# Create an attestation for slot 1 signed by the only attester we have!
|
# Create an attestation for slot 1 signed by the only attester we have!
|
||||||
crosslink_committee =
|
beacon_committee =
|
||||||
get_beacon_committee(state, state.slot, 0, cache)
|
get_beacon_committee(state, state.slot, 0, cache)
|
||||||
attestation = makeAttestation(
|
attestation = makeAttestation(
|
||||||
state, previous_block_root, crosslink_committee[0])
|
state, previous_block_root, beacon_committee[0], cache)
|
||||||
|
|
||||||
# Some time needs to pass before attestations are included - this is
|
# Some time needs to pass before attestations are included - this is
|
||||||
# to let the attestation propagate properly to interested participants
|
# to let the attestation propagate properly to interested participants
|
||||||
|
@ -158,9 +158,9 @@ proc makeBlock*(
|
|||||||
addBlock(next_state, previous_block_root, body)
|
addBlock(next_state, previous_block_root, body)
|
||||||
|
|
||||||
proc find_beacon_committee(
|
proc find_beacon_committee(
|
||||||
state: BeaconState, validator_index: ValidatorIndex): auto =
|
state: BeaconState, validator_index: ValidatorIndex,
|
||||||
|
cache: var StateCache): auto =
|
||||||
let epoch = compute_epoch_at_slot(state.slot)
|
let epoch = compute_epoch_at_slot(state.slot)
|
||||||
var cache = get_empty_per_epoch_cache()
|
|
||||||
for epoch_committee_index in 0'u64 ..< get_committee_count_at_slot(
|
for epoch_committee_index in 0'u64 ..< get_committee_count_at_slot(
|
||||||
state, epoch.compute_start_slot_at_epoch) * SLOTS_PER_EPOCH:
|
state, epoch.compute_start_slot_at_epoch) * SLOTS_PER_EPOCH:
|
||||||
let
|
let
|
||||||
@ -174,14 +174,16 @@ proc find_beacon_committee(
|
|||||||
|
|
||||||
proc makeAttestation*(
|
proc makeAttestation*(
|
||||||
state: BeaconState, beacon_block_root: Eth2Digest,
|
state: BeaconState, beacon_block_root: Eth2Digest,
|
||||||
validator_index: ValidatorIndex, flags: UpdateFlags = {}): Attestation =
|
validator_index: ValidatorIndex, cache: var StateCache,
|
||||||
|
flags: UpdateFlags = {}): Attestation =
|
||||||
let
|
let
|
||||||
(committee, slot, index) = find_beacon_committee(state, validator_index)
|
(committee, slot, index) =
|
||||||
|
find_beacon_committee(state, validator_index, cache)
|
||||||
validator = state.validators[validator_index]
|
validator = state.validators[validator_index]
|
||||||
sac_index = committee.find(validator_index)
|
sac_index = committee.find(validator_index)
|
||||||
data = makeAttestationData(state, slot, index, beacon_block_root)
|
data = makeAttestationData(state, slot, index, beacon_block_root)
|
||||||
|
|
||||||
doAssert sac_index != -1, "find_shard_committee should guarantee this"
|
doAssert sac_index != -1, "find_beacon_committee should guarantee this"
|
||||||
|
|
||||||
var aggregation_bits = CommitteeValidatorsBits.init(committee.len)
|
var aggregation_bits = CommitteeValidatorsBits.init(committee.len)
|
||||||
aggregation_bits.raiseBit sac_index
|
aggregation_bits.raiseBit sac_index
|
||||||
|
Loading…
x
Reference in New Issue
Block a user