electra: attestatoin sending (#6296)
This commit is contained in:
parent
045c4cf185
commit
d191b35e2e
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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)]
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
))
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
@ -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]).} =
|
||||
|
|
Loading…
Reference in New Issue