Skip to content

Commit

Permalink
electra: attestatoin sending (#6296)
Browse files Browse the repository at this point in the history
  • Loading branch information
arnetheduck committed May 17, 2024
1 parent 045c4cf commit d191b35
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 13 deletions.
15 changes: 14 additions & 1 deletion beacon_chain/gossip_processing/gossip_validation.nim
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,20 @@ func check_aggregation_count(
func check_aggregation_count(
attestation: electra.Attestation, singular: bool):
Result[void, ValidationError] =
debugComment "it's sometimes not"
block:
let ones = attestation.committee_bits.countOnes()
if singular and ones != 1:
return errReject("Attestation must have a single committee bit set")
elif not singular and ones < 1:
return errReject("Attestation must have at least one committee bit set")

block:
let ones = attestation.aggregation_bits.countOnes()
if singular and ones != 1:
return errReject("Attestation must have a single attestation bit set")
elif not singular and ones < 1:
return errReject("Attestation must have at least one attestation bit set")

ok()

func check_attestation_subnet(
Expand Down
3 changes: 2 additions & 1 deletion beacon_chain/networking/eth2_network.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2571,7 +2571,8 @@ proc getWallEpoch(node: Eth2Node): Epoch =
node.getBeaconTime().slotOrZero.epoch

proc broadcastAttestation*(
node: Eth2Node, subnet_id: SubnetId, attestation: phase0.Attestation):
node: Eth2Node, subnet_id: SubnetId,
attestation: phase0.Attestation | electra.Attestation):
Future[SendResult] {.async: (raises: [CancelledError], raw: true).} =
# Regardless of the contents of the attestation,
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/altair/p2p-interface.md#transitioning-the-gossip
Expand Down
22 changes: 22 additions & 0 deletions beacon_chain/spec/datatypes/electra.nim
Original file line number Diff line number Diff line change
Expand Up @@ -735,3 +735,25 @@ func shortLog*(v: electra.Attestation | electra.TrustedAttestation): auto =
data: shortLog(v.data),
signature: shortLog(v.signature)
)

func init*(
T: type Attestation,
committee_index: CommitteeIndex,
indices_in_committee: openArray[uint64],
committee_len: int,
data: AttestationData,
signature: ValidatorSig): Result[T, cstring] =
var committee_bits: AttestationCommitteeBits
committee_bits[int(committee_index)] = true

var bits = ElectraCommitteeValidatorsBits.init(committee_len)
for index_in_committee in indices_in_committee:
if index_in_committee >= committee_len.uint64: return err("Invalid index for committee")
bits.setBit index_in_committee

ok Attestation(
aggregation_bits: bits,
committee_bits: committee_bits,
data: data,
signature: signature
)
10 changes: 10 additions & 0 deletions beacon_chain/spec/forks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1527,3 +1527,13 @@ template init*(T: type ForkedMaybeBlindedBeaconBlock,
blindedData: blck),
consensusValue: cvalue,
executionValue: evalue)

func committee_index*(
v: phase0.Attestation, on_chain: static bool = false): uint64 =
v.data.index

func committee_index*(v: electra.Attestation, on_chain: static bool): uint64 =
when on_chain:
{.error: "cannot get single committee_index for on_chain attestation".}
else:
uint64 v.committee_bits.get_committee_index_one().expect("network attestation")
27 changes: 19 additions & 8 deletions beacon_chain/validators/beacon_validators.nim
Original file line number Diff line number Diff line change
Expand Up @@ -337,19 +337,26 @@ proc createAndSendAttestation(node: BeaconNode,
error_msg = res.error()
return
res.get()
attestation = registered.toAttestation(signature)
epoch = registered.data.slot.epoch

registered.validator.doppelgangerActivity(attestation.data.slot.epoch)
registered.validator.doppelgangerActivity(epoch)

# Logged in the router
let res = await node.router.routeAttestation(
attestation, subnet_id, checkSignature = false)
let
consensusFork = node.dag.cfg.consensusForkAtEpoch(epoch)
res =
if consensusFork >= ConsensusFork.Electra:
await node.router.routeAttestation(
registered.toElectraAttestation(signature), subnet_id, checkSignature = false)
else:
await node.router.routeAttestation(
registered.toAttestation(signature), subnet_id, checkSignature = false)
if not res.isOk():
return

if node.config.dumpEnabled:
dump(
node.config.dumpDirOutgoing, attestation.data,
node.config.dumpDirOutgoing, registered.data,
registered.validator.pubkey)

proc getBlockProposalEth1Data*(node: BeaconNode,
Expand Down Expand Up @@ -497,7 +504,6 @@ proc makeBeaconBlockForHeadAndSlot*(
warn "Eth1 deposits not available. Skipping block proposal", slot
return err("Eth1 deposits not available")

debugComment "b_v makeBeaconBlockForHeadAndSlot doesn't know how to get Electra attestations because attpool doesn't either"
let
attestations =
when PayloadType.kind == ConsensusFork.Electra:
Expand Down Expand Up @@ -1344,6 +1350,7 @@ proc sendAttestations(node: BeaconNode, head: BlockRef, slot: Slot) =
return
committees_per_slot = get_committee_count_per_slot(epochRef.shufflingRef)
fork = node.dag.forkAtEpoch(slot.epoch)
consensusFork = node.dag.cfg.consensusForkAtEpoch(slot.epoch)
genesis_validators_root = node.dag.genesis_validators_root
registeredRes = node.attachedValidators.slashingProtection.withContext:
var tmp: seq[(RegisteredAttestation, SubnetId)]
Expand All @@ -1359,7 +1366,11 @@ proc sendAttestations(node: BeaconNode, head: BlockRef, slot: Slot) =
let
validator = node.getValidatorForDuties(validator_index, slot).valueOr:
continue
data = makeAttestationData(epochRef, attestationHead, committee_index)
data =
if consensusFork >= ConsensusFork.Electra:
makeAttestationData(epochRef, attestationHead, CommitteeIndex(0))
else:
makeAttestationData(epochRef, attestationHead, committee_index)
# TODO signing_root is recomputed in produceAndSignAttestation/signAttestation just after
signingRoot = compute_attestation_signing_root(
fork, genesis_validators_root, data)
Expand All @@ -1376,7 +1387,7 @@ proc sendAttestations(node: BeaconNode, head: BlockRef, slot: Slot) =
continue

tmp.add((RegisteredAttestation(
validator: validator,
validator: validator, committee_index: committee_index,
index_in_committee: uint64 index_in_committee,
committee_len: committee.len(), data: data), subnet_id
))
Expand Down
7 changes: 4 additions & 3 deletions beacon_chain/validators/message_router.nim
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ proc routeSignedBeaconBlock*(
ok(blockRef)

proc routeAttestation*(
router: ref MessageRouter, attestation: phase0.Attestation,
router: ref MessageRouter,
attestation: phase0.Attestation | electra.Attestation,
subnet_id: SubnetId, checkSignature: bool):
Future[SendResult] {.async: (raises: [CancelledError]).} =
## Process and broadcast attestation - processing will register the it with
Expand Down Expand Up @@ -223,7 +224,7 @@ proc routeAttestation*(
return ok()

proc routeAttestation*(
router: ref MessageRouter, attestation: phase0.Attestation):
router: ref MessageRouter, attestation: phase0.Attestation | electra.Attestation):
Future[SendResult] {.async: (raises: [CancelledError]).} =
# Compute subnet, then route attestation
let
Expand All @@ -240,7 +241,7 @@ proc routeAttestation*(
attestation = shortLog(attestation)
return
committee_index =
shufflingRef.get_committee_index(attestation.data.index).valueOr:
shufflingRef.get_committee_index(attestation.committee_index()).valueOr:
notice "Invalid committee index in attestation",
attestation = shortLog(attestation)
return err("Invalid committee index in attestation")
Expand Down
8 changes: 8 additions & 0 deletions beacon_chain/validators/validator_duties.nim
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type
# the slashing protection database and is therefore ready to be signed and
# sent
validator*: AttachedValidator
committee_index*: CommitteeIndex
index_in_committee*: uint64
committee_len*: int
data*: AttestationData
Expand All @@ -36,6 +37,13 @@ proc toAttestation*(
[registered.index_in_committee], registered.committee_len,
registered.data, signature).expect("valid data")

proc toElectraAttestation*(
registered: RegisteredAttestation, signature: ValidatorSig):
electra.Attestation =
electra.Attestation.init(
registered.committee_index, [registered.index_in_committee],
registered.committee_len, registered.data, signature).expect("valid data")

proc waitAfterBlockCutoff*(clock: BeaconClock, slot: Slot,
head: Opt[BlockRef] = Opt.none(BlockRef))
{.async: (raises: [CancelledError]).} =
Expand Down

0 comments on commit d191b35

Please sign in to comment.