add sync committee types and some helpers (#2829)
This commit is contained in:
parent
6d47d96c84
commit
eeba2869fc
|
@ -98,9 +98,10 @@ OK: 3/3 Fail: 0/3 Skip: 0/3
|
|||
OK: 4/4 Fail: 0/4 Skip: 0/4
|
||||
## Gossip validation [Preset: mainnet]
|
||||
```diff
|
||||
+ Any committee index is valid OK
|
||||
+ Validation sanity OK
|
||||
```
|
||||
OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||
OK: 2/2 Fail: 0/2 Skip: 0/2
|
||||
## Honest validator
|
||||
```diff
|
||||
+ General pubsub topics OK
|
||||
|
@ -339,4 +340,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
|
|||
OK: 36/48 Fail: 0/48 Skip: 12/48
|
||||
|
||||
---TOTAL---
|
||||
OK: 185/197 Fail: 0/197 Skip: 12/197
|
||||
OK: 186/198 Fail: 0/198 Skip: 12/198
|
||||
|
|
|
@ -75,6 +75,33 @@ type
|
|||
nextAttestationEpoch*: seq[tuple[subnet: Epoch, aggregate: Epoch]] ## \
|
||||
## sequence based on validator indices
|
||||
|
||||
SyncCommitteeMsgKey* = object
|
||||
originator*: ValidatorIndex
|
||||
slot*: Slot
|
||||
committeeIdx*: SyncCommitteeIndex
|
||||
|
||||
TrustedSyncCommitteeMsg* = object
|
||||
slot*: Slot
|
||||
committeeIdx*: SyncCommitteeIndex
|
||||
positionInCommittee*: uint64
|
||||
signature*: CookedSig
|
||||
|
||||
BestSyncSubcommitteeContribution* = object
|
||||
totalParticipants*: int
|
||||
participationBits*: SyncCommitteeAggregationBits
|
||||
signature*: CookedSig
|
||||
|
||||
BestSyncSubcommitteeContributions* = array[SYNC_COMMITTEE_SUBNET_COUNT,
|
||||
BestSyncSubcommitteeContribution]
|
||||
|
||||
SyncCommitteeMsgPool* = object
|
||||
seenByAuthor*: HashSet[SyncCommitteeMsgKey]
|
||||
seenAggregateByAuthor*: HashSet[SyncCommitteeMsgKey]
|
||||
blockVotes*: Table[Eth2Digest, seq[TrustedSyncCommitteeMsg]]
|
||||
bestAggregates*: Table[Eth2Digest, BestSyncSubcommitteeContributions]
|
||||
|
||||
SyncCommitteeMsgPoolRef* = ref SyncCommitteeMsgPool
|
||||
|
||||
ExitPool* = object
|
||||
## The exit pool tracks attester slashings, proposer slashings, and
|
||||
## voluntary exits that could be added to a proposed block.
|
||||
|
@ -153,3 +180,6 @@ type
|
|||
lastCalculatedEpoch*: Epoch
|
||||
|
||||
func shortLog*(v: AttachedValidator): string = shortLog(v.pubKey)
|
||||
|
||||
func hash*(x: SyncCommitteeMsgKey): Hash =
|
||||
hashData(unsafeAddr x, sizeof(x))
|
||||
|
|
|
@ -2096,3 +2096,13 @@ proc broadcastBeaconBlock*(node: Eth2Node, forked: ForkedSignedBeaconBlock) =
|
|||
of BeaconBlockFork.Altair:
|
||||
let topic = getBeaconBlocksTopic(node.forkDigests.altair)
|
||||
node.broadcast(topic, forked.altairBlock)
|
||||
|
||||
proc broadcastSyncCommitteeMessage*(
|
||||
node: Eth2Node, msg: SyncCommitteeMessage, committeeIdx: SyncCommitteeIndex) =
|
||||
let topic = getSyncCommitteeTopic(node.forkDigests.altair, committeeIdx)
|
||||
node.broadcast(topic, msg)
|
||||
|
||||
proc broadcastSignedContributionAndProof*(
|
||||
node: Eth2Node, msg: SignedContributionAndProof) =
|
||||
let topic = getSyncCommitteeContributionAndProofTopic(node.forkDigests.altair)
|
||||
node.broadcast(topic, msg)
|
||||
|
|
|
@ -464,5 +464,8 @@ func init*(T: typedesc[ValidatorSig], data: array[RawSigSize, byte]): T {.noInit
|
|||
raise (ref ValueError)(msg: $v.error)
|
||||
v[]
|
||||
|
||||
func infinity*(T: type ValidatorSig): T =
|
||||
result.blob[0] = byte 0xC0
|
||||
|
||||
proc burnMem*(key: var ValidatorPrivKey) =
|
||||
ncrutils.burnMem(addr key, sizeof(ValidatorPrivKey))
|
||||
|
|
|
@ -442,6 +442,24 @@ when false:
|
|||
chronicles.formatIt BeaconBlock: it.shortLog
|
||||
chronicles.formatIt SyncCommitteeIndex: uint8(it)
|
||||
|
||||
template asInt*(x: SyncCommitteeIndex): int = int(x)
|
||||
template asUInt8*(x: SyncCommitteeIndex): uint8 = uint8(x)
|
||||
template asUInt64*(x: SyncCommitteeIndex): uint64 = uint64(x)
|
||||
|
||||
template `==`*(x, y: SyncCommitteeIndex): bool =
|
||||
distinctBase(x) == distinctBase(y)
|
||||
|
||||
iterator allSyncCommittees*: SyncCommitteeIndex =
|
||||
for committeeIdx in 0 ..< SYNC_COMMITTEE_SUBNET_COUNT:
|
||||
yield SyncCommitteeIndex(committeeIdx)
|
||||
|
||||
template validateSyncCommitteeIndexOr*(networkValParam: uint64, elseBody: untyped) =
|
||||
let networkVal = networkValParam
|
||||
if networkVal < SYNC_COMMITTEE_SUBNET_COUNT:
|
||||
SyncCommitteeIndex(networkVal)
|
||||
else:
|
||||
elseBody
|
||||
|
||||
template asUInt8*(x: SyncCommitteeIndex): uint8 = uint8(x)
|
||||
|
||||
Json.useCustomSerialization(BeaconState.justification_bits):
|
||||
|
|
|
@ -47,12 +47,18 @@ template epoch*(slot: Slot): Epoch =
|
|||
template isEpoch*(slot: Slot): bool =
|
||||
(slot mod SLOTS_PER_EPOCH) == 0
|
||||
|
||||
const SLOTS_PER_SYNC_COMMITTEE_PERIOD* =
|
||||
EPOCHS_PER_SYNC_COMMITTEE_PERIOD * SLOTS_PER_EPOCH
|
||||
|
||||
template syncCommitteePeriod*(epoch: Epoch): uint64 =
|
||||
epoch div EPOCHS_PER_SYNC_COMMITTEE_PERIOD
|
||||
|
||||
template syncCommitteePeriod*(slot: Slot): uint64 =
|
||||
epoch(slot) div EPOCHS_PER_SYNC_COMMITTEE_PERIOD
|
||||
|
||||
func syncCommitteePeriodStartSlot*(period: uint64): Slot =
|
||||
Slot(period * EPOCHS_PER_SYNC_COMMITTEE_PERIOD * SLOTS_PER_EPOCH)
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#compute_start_slot_at_epoch
|
||||
func compute_start_slot_at_epoch*(epoch: Epoch): Slot =
|
||||
## Return the start slot of ``epoch``.
|
||||
|
|
|
@ -171,6 +171,12 @@ func get_committee_count_per_slot*(state: SomeBeaconState,
|
|||
# Otherwise, get_beacon_committee(...) cannot access some committees.
|
||||
doAssert (SLOTS_PER_EPOCH * MAX_COMMITTEES_PER_SLOT) >= uint64(result)
|
||||
|
||||
iterator committee_indices_per_slot*(state: SomeBeaconState,
|
||||
epoch: Epoch,
|
||||
cache: var StateCache): CommitteeIndex =
|
||||
for idx in 0'u64 ..< get_committee_count_per_slot(state, epoch, cache):
|
||||
yield CommitteeIndex.verifiedValue(idx)
|
||||
|
||||
func get_committee_count_per_slot*(state: SomeBeaconState,
|
||||
slot: Slot,
|
||||
cache: var StateCache): uint64 =
|
||||
|
@ -194,11 +200,14 @@ func compute_committee_slice*(
|
|||
active_validators, index, count: uint64): Slice[int] =
|
||||
doAssert active_validators <= ValidatorIndex.high.uint64
|
||||
|
||||
let
|
||||
start = (active_validators * index) div count
|
||||
endIdx = (active_validators * (index + 1)) div count
|
||||
if index < count:
|
||||
let
|
||||
start = (active_validators * index) div count
|
||||
endIdx = (active_validators * (index + 1)) div count
|
||||
|
||||
start.int..(endIdx.int - 1)
|
||||
start.int..(endIdx.int - 1)
|
||||
else:
|
||||
0 .. -1
|
||||
|
||||
iterator compute_committee*(shuffled_indices: seq[ValidatorIndex],
|
||||
index: uint64, count: uint64): ValidatorIndex =
|
||||
|
|
|
@ -45,6 +45,25 @@ suite "Gossip validation " & preset():
|
|||
defaultRuntimeConfig, state.data, getStateField(state.data, slot) + 1,
|
||||
cache, rewards, {})
|
||||
|
||||
test "Any committee index is valid":
|
||||
template committee(idx: uint64): untyped =
|
||||
get_beacon_committee(
|
||||
dag.headState.data, dag.head.slot, idx.CommitteeIndex, cache)
|
||||
|
||||
template committeeLen(idx: uint64): untyped =
|
||||
get_beacon_committee_len(
|
||||
dag.headState.data, dag.head.slot, idx.CommitteeIndex, cache)
|
||||
|
||||
check:
|
||||
committee(0).len > 0
|
||||
committee(10000).len == 0
|
||||
committee(uint64.high).len == 0
|
||||
|
||||
check:
|
||||
committeeLen(2) > 0
|
||||
committeeLen(10000) == 0
|
||||
committeeLen(uint64.high) == 0
|
||||
|
||||
test "Validation sanity":
|
||||
# TODO: refactor tests to avoid skipping BLS validation
|
||||
dag.updateFlags.incl {skipBLSValidation}
|
||||
|
|
Loading…
Reference in New Issue