Skip to content

Commit

Permalink
extend makeTestBlocks for sync aggregates
Browse files Browse the repository at this point in the history
This extends the `makeTestBlocks` function used in tests with a new
parameter `syncCommitteeRatio` to control whether the produced blocks
should be signed by the validators assigned to the sync committee.
A similar parameter already exists to configure whether attestations
for the test blocks should be produced.
  • Loading branch information
etan-status authored and zah committed Dec 1, 2021
1 parent 40a9da3 commit 5e9625c
Showing 1 changed file with 115 additions and 9 deletions.
124 changes: 115 additions & 9 deletions tests/testblockutil.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.

import
random,
chronicles,
options, stew/endians2,
../beacon_chain/consensus_object_pools/sync_committee_msg_pool,
../beacon_chain/validators/validator_pool,
../beacon_chain/spec/datatypes/merge,
../beacon_chain/spec/[
Expand Down Expand Up @@ -78,6 +80,7 @@ proc addTestBlock*(
eth1_data = Eth1Data(),
attestations = newSeq[Attestation](),
deposits = newSeq[Deposit](),
sync_aggregate = SyncAggregate.init(),
graffiti = default(GraffitiBytes),
flags: set[UpdateFlag] = {},
nextSlot = true,
Expand Down Expand Up @@ -116,7 +119,7 @@ proc addTestBlock*(
attestations,
deposits,
BeaconBlockExits(),
SyncAggregate.init(),
sync_aggregate,
default(ExecutionPayload),
noRollback,
cache)
Expand All @@ -137,6 +140,7 @@ proc makeTestBlock*(
eth1_data = Eth1Data(),
attestations = newSeq[Attestation](),
deposits = newSeq[Deposit](),
sync_aggregate = SyncAggregate.init(),
graffiti = default(GraffitiBytes),
cfg = defaultRuntimeConfig): ForkedSignedBeaconBlock =
# Create a block for `state.slot + 1` - like a block proposer would do!
Expand All @@ -145,7 +149,8 @@ proc makeTestBlock*(
# because the block includes the state root.
var tmpState = assignClone(state)
addTestBlock(
tmpState[], cache, eth1_data, attestations, deposits, graffiti, cfg = cfg)
tmpState[], cache, eth1_data,
attestations, deposits, sync_aggregate, graffiti, cfg = cfg)

func makeAttestationData*(
state: ForkyBeaconState, slot: Slot, committee_index: CommitteeIndex,
Expand Down Expand Up @@ -283,19 +288,120 @@ func makeFullAttestations*(
attestation.signature = agg.finish().toValidatorSig()
result.add attestation

proc makeSyncAggregate(
state: ForkedHashedBeaconState,
syncCommitteeRatio: float,
cfg: RuntimeConfig): SyncAggregate =
if syncCommitteeRatio <= 0.0:
return SyncAggregate.init()
let
syncCommittee =
withState(state):
when stateFork >= BeaconStateFork.Altair:
const SLOTS_PER_PERIOD =
EPOCHS_PER_SYNC_COMMITTEE_PERIOD * SLOTS_PER_EPOCH
if (state.data.slot + 1) mod SLOTS_PER_PERIOD == 0:
state.data.next_sync_committee
else:
state.data.current_sync_committee
else:
return SyncAggregate.init()
fork =
getStateField(state, fork)
genesis_validators_root =
getStateField(state, genesis_validators_root)
slot =
getStateField(state, slot)
latest_block_root =
withState(state): state.latest_block_root
syncCommitteePool = newClone(SyncCommitteeMsgPool.init())
type
Aggregator = object
subcommitteeIdx: SyncSubcommitteeIndex
validatorIdx: ValidatorIndex
selectionProof: ValidatorSig
var aggregators: seq[Aggregator]
for subcommitteeIdx in allSyncSubcommittees():
let
firstKeyIdx = subcommitteeIdx.int * SYNC_SUBCOMMITTEE_SIZE
lastKeyIdx = firstKeyIdx + SYNC_SUBCOMMITTEE_SIZE - 1
var processedKeys = initHashSet[ValidatorPubKey]()
for idx, validatorKey in syncCommittee.pubkeys[firstKeyIdx .. lastKeyIdx]:
if validatorKey in processedKeys: continue
processedKeys.incl validatorKey
if rand(1.0) > syncCommitteeRatio: continue
var positions: seq[uint64]
for pos, key in syncCommittee.pubkeys[firstKeyIdx + idx .. lastKeyIdx]:
if key == validatorKey:
positions.add (idx + pos).uint64
let
validatorIdx =
block:
var res = 0
for i, validator in getStateField(state, validators):
if validator.pubkey == validatorKey:
res = i
break
res.ValidatorIndex
signature = get_sync_committee_message_signature(
fork, genesis_validators_root,
slot, latest_block_root,
MockPrivKeys[validatorIdx])
selectionProofSig = get_sync_aggregator_selection_data_signature(
fork, genesis_validators_root,
slot, subcommitteeIdx.uint64,
MockPrivKeys[validatorIdx])
syncCommitteePool[].addSyncCommitteeMessage(
slot,
latest_block_root,
uint64 validatorIdx,
signature,
subcommitteeIdx,
positions)
if is_sync_committee_aggregator(selectionProofSig.toValidatorSig):
aggregators.add Aggregator(
subcommitteeIdx: subcommitteeIdx,
validatorIdx: validatorIdx,
selectionProof: selectionProofSig.toValidatorSig)
for aggregator in aggregators:
var contribution: SyncCommitteeContribution
if syncCommitteePool[].produceContribution(
slot, latest_block_root, aggregator.subcommitteeIdx, contribution):
let
contributionAndProof = ContributionAndProof(
aggregator_index: uint64 aggregator.validatorIdx,
contribution: contribution,
selection_proof: aggregator.selectionProof)
contributionSig = get_sync_committee_contribution_and_proof_signature(
fork, genesis_validators_root,
contributionAndProof,
MockPrivKeys[aggregator.validatorIdx])
signedContributionAndProof = SignedContributionAndProof(
message: contributionAndProof,
signature: contributionSig.toValidatorSig)
syncCommitteePool[].addContribution(
signedContributionAndProof, contribution.signature.load.get)
syncCommitteePool[].produceSyncAggregate(latest_block_root)

iterator makeTestBlocks*(
state: ForkedHashedBeaconState,
cache: var StateCache,
blocks: int,
attested: bool,
syncCommitteeRatio = 0.0,
cfg = defaultRuntimeConfig): ForkedSignedBeaconBlock =
var
state = assignClone(state)
for _ in 0..<blocks:
let parent_root = withState(state[]): state.latest_block_root()
let attestations = if attested:
makeFullAttestations(state[], parent_root, getStateField(state[], slot), cache)
else:
@[]

yield addTestBlock(state[], cache, attestations = attestations, cfg = cfg)
let
parent_root = withState(state[]): state.latest_block_root()
attestations =
if attested:
makeFullAttestations(
state[], parent_root, getStateField(state[], slot), cache)
else:
@[]
sync_aggregate = makeSyncAggregate(state[], syncCommitteeRatio, cfg)

yield addTestBlock(state[], cache,
attestations = attestations, sync_aggregate = sync_aggregate, cfg = cfg)

0 comments on commit 5e9625c

Please sign in to comment.