refactor batch validation not to require genesis_validators_root each time (#4640)
This commit is contained in:
parent
0cc0c7e6b7
commit
629b005c27
|
@ -98,6 +98,10 @@ type
|
|||
# we accumulate here instead
|
||||
counts: tuple[signatures, batches, aggregates: int64]
|
||||
|
||||
# Most scheduled checks require this immutable value, so don't require it
|
||||
# to be provided separately each time
|
||||
genesis_validators_root: Eth2Digest
|
||||
|
||||
const
|
||||
# We cap waiting for an idle slot in case there's a lot of network traffic
|
||||
# taking up all CPU - we don't want to _completely_ stop processing
|
||||
|
@ -122,10 +126,12 @@ const
|
|||
|
||||
proc new*(
|
||||
T: type BatchCrypto, rng: ref HmacDrbgContext,
|
||||
eager: Eager, taskpool: TaskPoolPtr): ref BatchCrypto =
|
||||
eager: Eager, genesis_validators_root: Eth2Digest, taskpool: TaskPoolPtr):
|
||||
ref BatchCrypto =
|
||||
(ref BatchCrypto)(
|
||||
verifier: BatchVerifier(rng: rng, taskpool: taskpool),
|
||||
eager: eager,
|
||||
genesis_validators_root: genesis_validators_root,
|
||||
pruneTime: Moment.now())
|
||||
|
||||
func len(batch: Batch): int =
|
||||
|
@ -161,12 +167,12 @@ proc pruneBatchQueue(batchCrypto: ref BatchCrypto) =
|
|||
|
||||
batchCrypto.batches.popFirst()[].skip()
|
||||
|
||||
proc combine(a: var Signature, b: Signature) =
|
||||
func combine(a: var Signature, b: Signature) =
|
||||
var tmp = AggregateSignature.init(CookedSig(a))
|
||||
tmp.aggregate(b)
|
||||
a = Signature(tmp.finish())
|
||||
|
||||
proc combine(a: var PublicKey, b: PublicKey) =
|
||||
func combine(a: var PublicKey, b: PublicKey) =
|
||||
var tmp = AggregatePublicKey.init(CookedPubKey(a))
|
||||
tmp.aggregate(b)
|
||||
a = PublicKey(tmp.finish())
|
||||
|
@ -303,10 +309,9 @@ template withBatch(
|
|||
|
||||
# See also verify_attestation_signature
|
||||
proc scheduleAttestationCheck*(
|
||||
batchCrypto: ref BatchCrypto,
|
||||
fork: Fork, genesis_validators_root: Eth2Digest,
|
||||
attestationData: AttestationData,
|
||||
pubkey: CookedPubKey, signature: ValidatorSig
|
||||
batchCrypto: ref BatchCrypto, fork: Fork,
|
||||
attestationData: AttestationData, pubkey: CookedPubKey,
|
||||
signature: ValidatorSig
|
||||
): Result[tuple[fut: Future[BatchResult], sig: CookedSig], cstring] =
|
||||
## Schedule crypto verification of an attestation
|
||||
##
|
||||
|
@ -322,15 +327,14 @@ proc scheduleAttestationCheck*(
|
|||
return err("attestation: cannot load signature")
|
||||
fut = batchCrypto.withBatch("batch_validation.scheduleAttestationCheck"):
|
||||
attestation_signature_set(
|
||||
fork, genesis_validators_root, attestationData, pubkey, sig)
|
||||
fork, batchCrypto[].genesis_validators_root, attestationData, pubkey,
|
||||
sig)
|
||||
|
||||
ok((fut, sig))
|
||||
|
||||
proc scheduleAggregateChecks*(
|
||||
batchCrypto: ref BatchCrypto,
|
||||
fork: Fork, genesis_validators_root: Eth2Digest,
|
||||
signedAggregateAndProof: SignedAggregateAndProof,
|
||||
dag: ChainDAGRef,
|
||||
batchCrypto: ref BatchCrypto, fork: Fork,
|
||||
signedAggregateAndProof: SignedAggregateAndProof, dag: ChainDAGRef,
|
||||
attesting_indices: openArray[ValidatorIndex]
|
||||
): Result[tuple[
|
||||
aggregatorFut, slotFut, aggregateFut: Future[BatchResult],
|
||||
|
@ -368,24 +372,23 @@ proc scheduleAggregateChecks*(
|
|||
let
|
||||
aggregatorFut = batchCrypto.withBatch("scheduleAggregateChecks.aggregator"):
|
||||
aggregate_and_proof_signature_set(
|
||||
fork, genesis_validators_root, aggregate_and_proof, aggregatorKey,
|
||||
aggregatorSig)
|
||||
fork, batchCrypto[].genesis_validators_root, aggregate_and_proof,
|
||||
aggregatorKey, aggregatorSig)
|
||||
slotFut = batchCrypto.withBatch("scheduleAggregateChecks.selection_proof"):
|
||||
slot_signature_set(
|
||||
fork, genesis_validators_root, aggregate.data.slot, aggregatorKey,
|
||||
slotSig)
|
||||
fork, batchCrypto[].genesis_validators_root, aggregate.data.slot,
|
||||
aggregatorKey, slotSig)
|
||||
aggregateFut = batchCrypto.withBatch("scheduleAggregateChecks.aggregate"):
|
||||
attestation_signature_set(
|
||||
fork, genesis_validators_root, aggregate.data, aggregateKey,
|
||||
aggregateSig)
|
||||
fork, batchCrypto[].genesis_validators_root, aggregate.data,
|
||||
aggregateKey, aggregateSig)
|
||||
|
||||
ok((aggregatorFut, slotFut, aggregateFut, aggregateSig))
|
||||
|
||||
proc scheduleSyncCommitteeMessageCheck*(
|
||||
batchCrypto: ref BatchCrypto,
|
||||
fork: Fork, genesis_validators_root: Eth2Digest,
|
||||
slot: Slot, beacon_block_root: Eth2Digest,
|
||||
pubkey: CookedPubKey, signature: ValidatorSig
|
||||
batchCrypto: ref BatchCrypto, fork: Fork, slot: Slot,
|
||||
beacon_block_root: Eth2Digest, pubkey: CookedPubKey,
|
||||
signature: ValidatorSig
|
||||
): Result[tuple[fut: Future[BatchResult], sig: CookedSig], cstring] =
|
||||
## Schedule crypto verification of an attestation
|
||||
##
|
||||
|
@ -401,16 +404,15 @@ proc scheduleSyncCommitteeMessageCheck*(
|
|||
return err("SyncCommitteMessage: cannot load signature")
|
||||
fut = batchCrypto.withBatch("scheduleSyncCommitteeMessageCheck"):
|
||||
sync_committee_message_signature_set(
|
||||
fork, genesis_validators_root, slot, beacon_block_root, pubkey, sig)
|
||||
fork, batchCrypto[].genesis_validators_root, slot, beacon_block_root,
|
||||
pubkey, sig)
|
||||
|
||||
ok((fut, sig))
|
||||
|
||||
proc scheduleContributionChecks*(
|
||||
batchCrypto: ref BatchCrypto,
|
||||
fork: Fork, genesis_validators_root: Eth2Digest,
|
||||
signedContributionAndProof: SignedContributionAndProof,
|
||||
subcommitteeIdx: SyncSubcommitteeIndex,
|
||||
dag: ChainDAGRef): Result[tuple[
|
||||
fork: Fork, signedContributionAndProof: SignedContributionAndProof,
|
||||
subcommitteeIdx: SyncSubcommitteeIndex, dag: ChainDAGRef): Result[tuple[
|
||||
aggregatorFut, proofFut, contributionFut: Future[BatchResult],
|
||||
sig: CookedSig], cstring] =
|
||||
## Schedule crypto verification of all signatures in a
|
||||
|
@ -444,22 +446,22 @@ proc scheduleContributionChecks*(
|
|||
let
|
||||
aggregatorFut = batchCrypto.withBatch("scheduleContributionAndProofChecks.aggregator"):
|
||||
contribution_and_proof_signature_set(
|
||||
fork, genesis_validators_root, contribution_and_proof, aggregatorKey,
|
||||
aggregatorSig)
|
||||
fork, batchCrypto[].genesis_validators_root, contribution_and_proof,
|
||||
aggregatorKey, aggregatorSig)
|
||||
proofFut = batchCrypto.withBatch("scheduleContributionAndProofChecks.selection_proof"):
|
||||
sync_committee_selection_proof_set(
|
||||
fork, genesis_validators_root, contribution.slot,
|
||||
fork, batchCrypto[].genesis_validators_root, contribution.slot,
|
||||
subcommitteeIdx, aggregatorKey, proofSig)
|
||||
contributionFut = batchCrypto.withBatch("scheduleContributionAndProofChecks.contribution"):
|
||||
sync_committee_message_signature_set(
|
||||
fork, genesis_validators_root, contribution.slot,
|
||||
fork, batchCrypto[].genesis_validators_root, contribution.slot,
|
||||
contribution.beacon_block_root, contributionKey, contributionSig)
|
||||
|
||||
ok((aggregatorFut, proofFut, contributionFut, contributionSig))
|
||||
|
||||
proc scheduleBlsToExecutionChangeCheck*(
|
||||
batchCrypto: ref BatchCrypto,
|
||||
genesisFork: Fork, genesis_validators_root: Eth2Digest,
|
||||
genesisFork: Fork,
|
||||
signedBLSToExecutionChange: SignedBLSToExecutionChange): Result[tuple[
|
||||
blsToExecutionFut: Future[BatchResult],
|
||||
sig: CookedSig], cstring] =
|
||||
|
@ -487,7 +489,7 @@ proc scheduleBlsToExecutionChangeCheck*(
|
|||
return err("scheduleBlsToExecutionChangeCheck: invalid validator change signature")
|
||||
validatorChangeFut = batchCrypto.withBatch("scheduleContributionAndProofChecks.contribution"):
|
||||
bls_to_execution_change_signature_set(
|
||||
genesis_fork, genesis_validators_root,
|
||||
genesis_fork, batchCrypto[].genesis_validators_root,
|
||||
signedBLSToExecutionChange.message,
|
||||
validatorChangePubkey, validatorChangeSig)
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ proc new*(T: type Eth2Processor,
|
|||
# Only run eager attestation signature verification if we're not
|
||||
# processing blocks in order to give priority to block processing
|
||||
eager = proc(): bool = not blockProcessor[].hasBlocks(),
|
||||
taskpool)
|
||||
genesis_validators_root = dag.genesis_validators_root, taskpool)
|
||||
)
|
||||
|
||||
# Each validator logs, validates then passes valid data to its destination
|
||||
|
|
|
@ -550,8 +550,6 @@ proc validateAttestation*(
|
|||
|
||||
let
|
||||
fork = pool.dag.forkAtEpoch(attestation.data.slot.epoch)
|
||||
genesis_validators_root =
|
||||
getStateField(pool.dag.headState, genesis_validators_root)
|
||||
attesting_index = get_attesting_indices_one(
|
||||
shufflingRef, slot, committee_index, attestation.aggregation_bits)
|
||||
|
||||
|
@ -581,8 +579,8 @@ proc validateAttestation*(
|
|||
# Attestation signatures are batch-verified
|
||||
let deferredCrypto = batchCrypto
|
||||
.scheduleAttestationCheck(
|
||||
fork, genesis_validators_root, attestation.data,
|
||||
pubkey, attestation.signature)
|
||||
fork, attestation.data, pubkey,
|
||||
attestation.signature)
|
||||
if deferredCrypto.isErr():
|
||||
return checkedReject(deferredCrypto.error)
|
||||
|
||||
|
@ -736,8 +734,6 @@ proc validateAggregate*(
|
|||
|
||||
let
|
||||
fork = pool.dag.forkAtEpoch(aggregate.data.slot.epoch)
|
||||
genesis_validators_root =
|
||||
getStateField(pool.dag.headState, genesis_validators_root)
|
||||
attesting_indices = get_attesting_indices(
|
||||
shufflingRef, slot, committee_index, aggregate.aggregation_bits)
|
||||
|
||||
|
@ -745,8 +741,8 @@ proc validateAggregate*(
|
|||
sig = if checkSignature:
|
||||
let deferredCrypto = batchCrypto
|
||||
.scheduleAggregateChecks(
|
||||
fork, genesis_validators_root,
|
||||
signedAggregateAndProof, pool.dag, attesting_indices
|
||||
fork, signedAggregateAndProof, pool.dag,
|
||||
attesting_indices
|
||||
)
|
||||
if deferredCrypto.isErr():
|
||||
return checkedReject(deferredCrypto.error)
|
||||
|
@ -842,8 +838,7 @@ proc validateBlsToExecutionChange*(
|
|||
|
||||
# BLS to execution change signatures are batch-verified
|
||||
let deferredCrypto = batchCrypto.scheduleBlsToExecutionChangeCheck(
|
||||
pool.dag.cfg.genesisFork, pool.dag.genesis_validators_root,
|
||||
signed_address_change)
|
||||
pool.dag.cfg.genesisFork, signed_address_change)
|
||||
if deferredCrypto.isErr():
|
||||
return checkedReject(deferredCrypto.error)
|
||||
|
||||
|
@ -980,7 +975,6 @@ proc validateSyncCommitteeMessage*(
|
|||
let
|
||||
epoch = msg.slot.epoch
|
||||
fork = dag.forkAtEpoch(epoch)
|
||||
genesis_validators_root = dag.genesis_validators_root
|
||||
senderPubKey = dag.validatorKey(msg.validator_index).valueOr:
|
||||
return errReject("SyncCommitteeMessage: invalid validator index")
|
||||
|
||||
|
@ -989,8 +983,7 @@ proc validateSyncCommitteeMessage*(
|
|||
# Attestation signatures are batch-verified
|
||||
let deferredCrypto = batchCrypto
|
||||
.scheduleSyncCommitteeMessageCheck(
|
||||
fork, genesis_validators_root,
|
||||
msg.slot, msg.beacon_block_root,
|
||||
fork, msg.slot, msg.beacon_block_root,
|
||||
senderPubKey, msg.signature)
|
||||
if deferredCrypto.isErr():
|
||||
return errReject(deferredCrypto.error)
|
||||
|
@ -1060,7 +1053,6 @@ proc validateContribution*(
|
|||
let
|
||||
epoch = msg.message.contribution.slot.epoch
|
||||
fork = dag.forkAtEpoch(epoch)
|
||||
genesis_validators_root = dag.genesis_validators_root
|
||||
|
||||
if msg.message.contribution.aggregation_bits.countOnes() == 0:
|
||||
# [REJECT] The contribution has participants
|
||||
|
@ -1081,7 +1073,7 @@ proc validateContribution*(
|
|||
|
||||
let sig = if checkSignature:
|
||||
let deferredCrypto = batchCrypto.scheduleContributionChecks(
|
||||
fork, genesis_validators_root, msg, subcommitteeIdx, dag)
|
||||
fork, msg, subcommitteeIdx, dag)
|
||||
if deferredCrypto.isErr():
|
||||
return errReject(deferredCrypto.error)
|
||||
|
||||
|
|
|
@ -330,7 +330,8 @@ cli do(slots = SLOTS_PER_EPOCH * 6,
|
|||
quarantine = newClone(Quarantine.init())
|
||||
attPool = AttestationPool.init(dag, quarantine)
|
||||
batchCrypto = BatchCrypto.new(
|
||||
keys.newRng(), eager = func(): bool = true, taskpool)
|
||||
keys.newRng(), eager = func(): bool = true,
|
||||
genesis_validators_root = dag.genesis_validators_root, taskpool)
|
||||
syncCommitteePool = newClone SyncCommitteeMsgPool.init(keys.newRng())
|
||||
timers: array[Timers, RunningStat]
|
||||
attesters: RunningStat
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# beacon_chain
|
||||
# Copyright (c) 2018-2022 Status Research & Development GmbH
|
||||
# Copyright (c) 2018-2023 Status Research & Development GmbH
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||
|
@ -47,7 +47,9 @@ suite "Gossip validation " & preset():
|
|||
state = newClone(dag.headState)
|
||||
cache = StateCache()
|
||||
info = ForkedEpochInfo()
|
||||
batchCrypto = BatchCrypto.new(keys.newRng(), eager = proc(): bool = false, taskpool)
|
||||
batchCrypto = BatchCrypto.new(
|
||||
keys.newRng(), eager = proc(): bool = false,
|
||||
genesis_validators_root = dag.genesis_validators_root, taskpool)
|
||||
# Slot 0 is a finalized slot - won't be making attestations for it..
|
||||
check:
|
||||
process_slots(
|
||||
|
@ -185,7 +187,6 @@ suite "Gossip validation - Extra": # Not based on preset config
|
|||
cfg
|
||||
taskpool = Taskpool.new()
|
||||
quarantine = newClone(Quarantine.init())
|
||||
batchCrypto = BatchCrypto.new(keys.newRng(), eager = proc(): bool = false, taskpool)
|
||||
var
|
||||
verifier = BatchVerifier(rng: keys.newRng(), taskpool: Taskpool.new())
|
||||
dag = block:
|
||||
|
@ -216,6 +217,12 @@ suite "Gossip validation - Extra": # Not based on preset config
|
|||
check: added.isOk()
|
||||
dag.updateHead(added[], quarantine[])
|
||||
dag
|
||||
|
||||
let batchCrypto = BatchCrypto.new(
|
||||
keys.newRng(), eager = proc(): bool = false,
|
||||
genesis_validators_root = dag.genesis_validators_root, taskpool)
|
||||
|
||||
var
|
||||
state = assignClone(dag.headState.altairData)
|
||||
slot = state[].data.slot
|
||||
|
||||
|
|
Loading…
Reference in New Issue