@@ -120,7 +120,7 @@ func aggregateAttesters(
120120 if inited:
121121 attestersAgg.aggregate (key)
122122 else :
123- attestersAgg = AggregatePublicKey .init (key)
123+ attestersAgg.init (key)
124124 inited = true
125125
126126 if not inited:
@@ -287,135 +287,132 @@ proc collectSignatureSets*(
287287 # ----------------------------------------------------
288288 mixin load
289289
290+ const consensusFork = ForkySignedBeaconBlock .kind
291+ template forkyState (): untyped =
292+ state.forky (consensusFork)
293+
290294 let
291- fork = getStateField (state, fork)
292- genesis_validators_root = getStateField (state, genesis_validators_root)
295+ fork = forkyState.data. fork
296+ genesis_validators_root = forkyState.data. genesis_validators_root
293297 proposer_index = signed_block.message.proposer_index
294298 proposer_key = validatorKeys.load (proposer_index).valueOr:
295299 return err (" collectSignatureSets: invalid proposer index" )
296- epoch = signed_block.message.slot.epoch ()
297300
298301
299302 # 1. Block proposer
300303 # ----------------------------------------------------
301- sigs.add block_signature_set (
302- fork, genesis_validators_root,
303- signed_block.message.slot, signed_block.root,
304- proposer_key, signed_block.signature.load.valueOr do :
305- return err (" collectSignatureSets: cannot load signature" ))
304+ block :
305+ let sig = signed_block.signature.load.valueOr:
306+ return err (" collectSignatureSets: cannot load signature" )
307+
308+ sigs.add block_signature_set (
309+ fork, genesis_validators_root, signed_block.message.slot, signed_block.root,
310+ proposer_key, sig,
311+ )
306312
307313 # 2. Randao Reveal
308314 # ----------------------------------------------------
309- sigs.add epoch_signature_set (
310- fork, genesis_validators_root, epoch, proposer_key,
311- signed_block.message.body.randao_reveal.load ().valueOr do :
312- return err (" collectSignatureSets: cannot load randao" ))
315+ block :
316+ let
317+ epoch = signed_block.message.slot.epoch ()
318+ sig = signed_block.message.body.randao_reveal.load ().valueOr:
319+ return err (" collectSignatureSets: cannot load randao" )
320+ sigs.add epoch_signature_set (
321+ fork, genesis_validators_root, epoch, proposer_key, sig
322+ )
313323
314324 # 3. Proposer slashings
315325 # ----------------------------------------------------
316326 # Denial-of-service:
317327 # SSZ deserialization guarantees that blocks received from random sources
318328 # including peer or RPC
319329 # have at most MAX_PROPOSER_SLASHINGS proposer slashings.
320- for i in 0 ..< signed_block.message.body.proposer_slashings.len:
321- # don't use "items" for iterating over large type
322- # due to https://github.com/nim-lang/Nim/issues/14421
323- # fixed in 1.4.2
324-
325- # Alias
326- template slashing : untyped = signed_block.message.body.proposer_slashings[i]
327-
330+ for slashing in signed_block.message.body.proposer_slashings:
328331 # Proposed block 1
329332 block :
330333 let
331334 header = slashing.signed_header_1
332335 key = validatorKeys.load (header.message.proposer_index).valueOr:
333336 return err (" collectSignatureSets: invalid slashing proposer index 1" )
337+ sig = header.signature.load ().valueOr:
338+ return err (" collectSignatureSets: cannot load proposer slashing 1 signature" )
334339
335340 sigs.add block_signature_set (
336- fork, genesis_validators_root, header.message.slot, header.message,
337- key, header.signature.load ().valueOr do :
338- return err (
339- " collectSignatureSets: cannot load proposer slashing 1 signature" ))
341+ fork, genesis_validators_root, header.message.slot, header.message, key, sig
342+ )
340343
341344 # Conflicting block 2
342345 block :
343346 let
344347 header = slashing.signed_header_2
345348 key = validatorKeys.load (header.message.proposer_index).valueOr:
346349 return err (" collectSignatureSets: invalid slashing proposer index 2" )
350+ sig = header.signature.load ().valueOr:
351+ return err (" collectSignatureSets: cannot load proposer slashing 2 signature" )
347352
348353 sigs.add block_signature_set (
349- fork, genesis_validators_root, header.message.slot, header.message,
350- key, header.signature.load ().valueOr do :
351- return err (
352- " collectSignatureSets: cannot load proposer slashing 2 signature" ))
354+ fork, genesis_validators_root, header.message.slot, header.message, key, sig
355+ )
353356
354357 # 4. Attester slashings
355358 # ----------------------------------------------------
356359 # Denial-of-service:
357360 # SSZ deserialization guarantees that blocks received from random sources
358361 # including peer or RPC
359362 # have at most MAX_ATTESTER_SLASHINGS attester slashings.
360- for i in 0 ..< signed_block.message.body.attester_slashings.len:
361- # don't use "items" for iterating over large type
362- # due to https://github.com/nim-lang/Nim/issues/14421
363- # fixed in 1.4.2
364-
365- # Alias
366- template slashing : untyped = signed_block.message.body.attester_slashings[i]
367-
363+ for slashing in signed_block.message.body.attester_slashings:
368364 # Attestation 1
369365 block :
370366 let
371- key = ? aggregateAttesters (
372- slashing.attestation_1.attesting_indices.asSeq (), validatorKeys)
367+ key =
368+ ? aggregateAttesters (
369+ slashing.attestation_1.attesting_indices.asSeq (), validatorKeys
370+ )
373371 sig = slashing.attestation_1.signature.load ().valueOr:
374372 return err (" Invalid attestation slashing signature 1" )
375373 sigs.add attestation_signature_set (
376- fork, genesis_validators_root, slashing.attestation_1.data, key, sig)
374+ fork, genesis_validators_root, slashing.attestation_1.data, key, sig
375+ )
377376
378377 # Conflicting attestation 2
379378 block :
380379 let
381- key = ? aggregateAttesters (
382- slashing.attestation_2.attesting_indices.asSeq (), validatorKeys)
380+ key =
381+ ? aggregateAttesters (
382+ slashing.attestation_2.attesting_indices.asSeq (), validatorKeys
383+ )
383384 sig = slashing.attestation_2.signature.load ().valueOr:
384385 return err (" Invalid attestation slashing signature 2" )
385386 sigs.add attestation_signature_set (
386- fork, genesis_validators_root, slashing.attestation_2.data, key, sig)
387+ fork, genesis_validators_root, slashing.attestation_2.data, key, sig
388+ )
387389
388390 # 5. Attestations
389391 # ----------------------------------------------------
390392 # Denial-of-service:
391393 # SSZ deserialization guarantees that blocks received from random sources
392394 # including peer or RPC
393395 # have at most MAX_ATTESTATIONS attestations.
394- for i in 0 ..< signed_block.message.body.attestations.len:
395- # don't use "items" for iterating over large type
396- # due to https://github.com/nim-lang/Nim/issues/14421
397- # fixed in 1.4.2
398- template attestation : untyped = signed_block.message.body.attestations[i]
399-
400- when typeof (signed_block).kind < ConsensusFork .Electra :
401- let
402- key = ? aggregateAttesters (
396+ for attestation in signed_block.message.body.attestations:
397+ let
398+ attesting_indices =
399+ when consensusFork < ConsensusFork .Electra :
403400 get_attesting_indices (
404- state, attestation.data, attestation.aggregation_bits, cache),
405- validatorKeys)
406- else :
407- let
408- key = ? aggregateAttesters (
401+ forkyState.data, attestation.data, attestation.aggregation_bits, cache
402+ )
403+ else :
409404 get_attesting_indices (
410- state, attestation.data, attestation.aggregation_bits,
411- attestation.committee_bits, cache),
412- validatorKeys)
413- let
405+ forkyState.data, attestation.data, attestation.aggregation_bits,
406+ attestation.committee_bits, cache,
407+ )
408+
409+ key = ? aggregateAttesters (attesting_indices, validatorKeys)
414410 sig = attestation.signature.load ().valueOr:
415411 return err (" Invalid attestation signature" )
416412
417413 sigs.add attestation_signature_set (
418- fork, genesis_validators_root, attestation.data, key, sig)
414+ fork, genesis_validators_root, attestation.data, key, sig
415+ )
419416
420417 # 6. VoluntaryExits
421418 # ----------------------------------------------------
@@ -424,72 +421,67 @@ proc collectSignatureSets*(
424421 # including peer or RPC
425422 # have at most MAX_VOLUNTARY_EXITS voluntary exits.
426423 if signed_block.message.body.voluntary_exits.len > 0 :
427- let voluntary_exit_fork = withConsensusFork (state.kind):
424+ # https://eips.ethereum.org/EIPS/eip-7044
425+ # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#modified-process_voluntary_exit
426+ let voluntary_exit_fork =
428427 consensusFork.voluntary_exit_signature_fork (fork, capella_fork_version)
429- for i in 0 ..< signed_block.message.body.voluntary_exits.len:
430- # don't use "items" for iterating over large type
431- # due to https://github.com/nim-lang/Nim/issues/14421
432- # fixed in 1.4.2
433- template volex : untyped = signed_block.message.body.voluntary_exits[i]
434- let key = validatorKeys.load (volex.message.validator_index).valueOr:
435- return err (" collectSignatureSets: invalid voluntary exit" )
428+ for volex in signed_block.message.body.voluntary_exits:
429+ let
430+ key = validatorKeys.load (volex.message.validator_index).valueOr:
431+ return err (" collectSignatureSets: invalid voluntary exit" )
432+ sig = volex.signature.load.valueOr:
433+ return err (" collectSignatureSets: cannot load voluntary exit signature" )
436434
437435 sigs.add voluntary_exit_signature_set (
438- # https://eips.ethereum.org/EIPS/eip-7044
439- # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#modified-process_voluntary_exit
440- voluntary_exit_fork, genesis_validators_root, volex.message, key,
441- volex.signature.load.valueOr do :
442- return err (
443- " collectSignatureSets: cannot load voluntary exit signature" ))
436+ voluntary_exit_fork, genesis_validators_root, volex.message, key, sig
437+ )
444438
445- block :
446- when signed_block is phase0.SignedBeaconBlock :
447- discard
439+ # 7. SyncAggregate
440+ # ----------------------------------------------------
441+ when consensusFork >= ConsensusFork .Altair :
442+ if signed_block.message.body.sync_aggregate.sync_committee_bits.isZeros:
443+ if signed_block.message.body.sync_aggregate.sync_committee_signature !=
444+ ValidatorSig .infinity ():
445+ return err (
446+ " collectSignatureSets: empty sync aggregates need signature of point at infinity"
447+ )
448448 else :
449- # 7. SyncAggregate
450- # ----------------------------------------------------
451- withState (state):
452- when consensusFork >= ConsensusFork .Altair :
453- if signed_block.message.body.sync_aggregate.sync_committee_bits.isZeros:
454- if signed_block.message.body.sync_aggregate.sync_committee_signature != ValidatorSig .infinity ():
455- return err (" collectSignatureSets: empty sync aggregates need signature of point at infinity" )
456- else :
457- let
458- current_sync_committee =
459- forkyState.data.get_sync_committee_cache (cache).current_sync_committee
460- previous_slot = max (forkyState.data.slot, Slot (1 )) - 1
461- beacon_block_root = get_block_root_at_slot (forkyState.data, previous_slot)
462- pubkey = ? aggregateAttesters (
463- current_sync_committee,
464- signed_block.message.body.sync_aggregate.sync_committee_bits,
465- validatorKeys)
466-
467- sigs.add sync_committee_message_signature_set (
468- fork, genesis_validators_root, previous_slot, beacon_block_root,
469- pubkey,
470- signed_block.message.body.sync_aggregate.sync_committee_signature.load ().valueOr do :
471- return err (" collectSignatureSets: cannot load signature" ))
449+ let
450+ current_sync_committee =
451+ forkyState.data.get_sync_committee_cache (cache).current_sync_committee
452+ previous_slot = max (forkyState.data.slot, Slot (1 )) - 1
453+ beacon_block_root = get_block_root_at_slot (forkyState.data, previous_slot)
454+ pubkey =
455+ ? aggregateAttesters (
456+ current_sync_committee,
457+ signed_block.message.body.sync_aggregate.sync_committee_bits, validatorKeys,
458+ )
459+ sig = signed_block.message.body.sync_aggregate.sync_committee_signature.load ().valueOr:
460+ return err (" collectSignatureSets: cannot load signature" )
461+
462+ sigs.add sync_committee_message_signature_set (
463+ fork, genesis_validators_root, previous_slot, beacon_block_root, pubkey, sig
464+ )
465+
466+ # 8. BLS to execution changes
467+ when consensusFork >= ConsensusFork .Capella :
468+ for bls_change in signed_block.message.body.bls_to_execution_changes:
469+ # Otherwise, expensive loadWithCache can be spammed with irrelevant pubkeys
470+ ? check_bls_to_execution_change (
471+ genesis_fork_version, forkyState.data, bls_change, {skipBlsValidation}
472+ )
472473
473- block :
474- # 8. BLS to execution changes
475- when typeof (signed_block).kind >= ConsensusFork .Capella :
476- withState (state):
477- when consensusFork >= ConsensusFork .Capella :
478- for bls_change in signed_block.message.body.bls_to_execution_changes:
479- let sig = bls_change.signature.load.valueOr:
480- return err (" collectSignatureSets: cannot load BLS to execution change signature" )
481-
482- # Otherwise, expensive loadWithCache can be spammed with irrelevant pubkeys
483- ? check_bls_to_execution_change (
484- genesis_fork_version, forkyState.data, bls_change, {skipBlsValidation})
485-
486- let validator_pubkey =
487- bls_change.message.from_bls_pubkey.loadWithCache.valueOr:
488- return err (" collectSignatureSets: cannot load BLS to execution change pubkey" )
489-
490- sigs.add bls_to_execution_change_signature_set (
491- genesis_fork_version, genesis_validators_root, bls_change.message,
492- validator_pubkey, sig)
474+ let
475+ sig = bls_change.signature.load.valueOr:
476+ return
477+ err (" collectSignatureSets: cannot load BLS to execution change signature" )
478+ validator_pubkey = bls_change.message.from_bls_pubkey.loadWithCache.valueOr:
479+ return err (" collectSignatureSets: cannot load BLS to execution change pubkey" )
480+
481+ sigs.add bls_to_execution_change_signature_set (
482+ genesis_fork_version, genesis_validators_root, bls_change.message,
483+ validator_pubkey, sig,
484+ )
493485
494486 ok ()
495487
0 commit comments