Skip to content

Commit

Permalink
fix inconsistent aggregation bits len in Electra (#6679)
Browse files Browse the repository at this point in the history
  • Loading branch information
tersec authored Oct 25, 2024
1 parent 8a6eab7 commit 58a34e0
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
36 changes: 25 additions & 11 deletions beacon_chain/spec/validator.nim
Original file line number Diff line number Diff line change
Expand Up @@ -565,21 +565,32 @@ func get_committee_index_one*(bits: AttestationCommitteeBits): Opt[CommitteeInde

proc compute_on_chain_aggregate*(
network_aggregates: openArray[electra.Attestation]): Opt[electra.Attestation] =
# aggregates = sorted(network_aggregates, key=lambda a: get_committee_indices(a.committee_bits)[0])
let aggregates = network_aggregates.sortedByIt(it.committee_bits.get_committee_index_one().expect("just one"))

let data = aggregates[0].data

var agg: AggregateSignature
var committee_bits: AttestationCommitteeBits
let
aggregates = network_aggregates.sortedByIt(
it.committee_bits.get_committee_index_one().expect("just one"))
data = aggregates[0].data

var totalLen = 0
var
agg: AggregateSignature
committee_bits: AttestationCommitteeBits
prev_committee_index: Opt[CommitteeIndex]
totalLen = 0
for i, a in aggregates:
let committee_index = ? get_committee_index_one(a.committee_bits)
if prev_committee_index.isNone:
prev_committee_index = Opt.some committee_index
elif committee_index.distinctBase <= prev_committee_index.get.distinctBase:
continue
prev_committee_index = Opt.some committee_index

totalLen += a.aggregation_bits.len

var aggregation_bits = ElectraCommitteeValidatorsBits.init(totalLen)
var pos = 0
var prev_committee_index: Opt[CommitteeIndex]
prev_committee_index.reset()

var
aggregation_bits = ElectraCommitteeValidatorsBits.init(totalLen)
pos = 0
filledLen = 0
for i, a in aggregates:
let
committee_index = ? get_committee_index_one(a.committee_bits)
Expand All @@ -594,6 +605,7 @@ proc compute_on_chain_aggregate*(
for b in a.aggregation_bits:
aggregation_bits[pos] = b
pos += 1
filledLen += a.aggregation_bits.len

let sig = ? a.signature.load() # Expensive
if first:
Expand All @@ -603,6 +615,8 @@ proc compute_on_chain_aggregate*(

committee_bits[int(committee_index)] = true

doAssert totalLen == filledLen

let signature = agg.finish()

ok electra.Attestation(
Expand Down
6 changes: 6 additions & 0 deletions tests/test_attestation_pool.nim
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,8 @@ suite "Attestation pool electra processing" & preset():

check:
verifyAttestationSignature(attestations[0])
check_attestation(
state[].electraData.data, attestations[0], {}, cache, true).isOk

# A single final chain aggregated attestation should be created
# with same data, 2 committee bits and 3 aggregation bits
Expand Down Expand Up @@ -1048,6 +1050,8 @@ suite "Attestation pool electra processing" & preset():
check:
attestations.len() == 1
attestations[0].aggregation_bits.countOnes() == 3
check_attestation(
state[].electraData.data, attestations[0], {}, cache, true).isOk
verifyAttestationSignature(attestations[0])
# Can get either aggregate here, random!
verifyAttestationSignature(pool[].getElectraAggregatedAttestation(
Expand All @@ -1063,6 +1067,8 @@ suite "Attestation pool electra processing" & preset():
check:
attestations.len() == 1
attestations[0].aggregation_bits.countOnes() == 4
check_attestation(
state[].electraData.data, attestations[0], {}, cache, true).isOk
verifyAttestationSignature(attestations[0])
verifyAttestationSignature(pool[].getElectraAggregatedAttestation(
1.Slot, hash_tree_root(attestations[0].data), 0.CommitteeIndex).get)
Expand Down

0 comments on commit 58a34e0

Please sign in to comment.