11import { Signature , aggregateSignatures } from "@chainsafe/blst" ;
22import { BitArray } from "@chainsafe/ssz" ;
33import { ChainForkConfig } from "@lodestar/config" ;
4- import { isForkPostElectra } from "@lodestar/params" ;
5- import { Attestation , RootHex , Slot , isElectraAttestation } from "@lodestar/types" ;
4+ import { MAX_COMMITTEES_PER_SLOT , isForkPostElectra } from "@lodestar/params" ;
5+ import { Attestation , RootHex , SingleAttestation , Slot , isElectraSingleAttestation } from "@lodestar/types" ;
66import { assert , MapDef } from "@lodestar/utils" ;
77import { IClock } from "../../util/clock.js" ;
88import { InsertOutcome , OpPoolError , OpPoolErrorCode } from "./types.js" ;
@@ -105,7 +105,13 @@ export class AttestationPool {
105105 * - Valid committeeIndex
106106 * - Valid data
107107 */
108- add ( committeeIndex : CommitteeIndex , attestation : Attestation , attDataRootHex : RootHex ) : InsertOutcome {
108+ add (
109+ committeeIndex : CommitteeIndex ,
110+ attestation : SingleAttestation ,
111+ attDataRootHex : RootHex ,
112+ committeeValidatorIndex : number ,
113+ committeeSize : number
114+ ) : InsertOutcome {
109115 const slot = attestation . data . slot ;
110116 const fork = this . config . getForkName ( slot ) ;
111117 const lowestPermissibleSlot = this . lowestPermissibleSlot ;
@@ -129,9 +135,9 @@ export class AttestationPool {
129135 if ( isForkPostElectra ( fork ) ) {
130136 // Electra only: this should not happen because attestation should be validated before reaching this
131137 assert . notNull ( committeeIndex , "Committee index should not be null in attestation pool post-electra" ) ;
132- assert . true ( isElectraAttestation ( attestation ) , "Attestation should be type electra.Attestation " ) ;
138+ assert . true ( isElectraSingleAttestation ( attestation ) , "Attestation should be type electra.SingleAttestation " ) ;
133139 } else {
134- assert . true ( ! isElectraAttestation ( attestation ) , "Attestation should be type phase0.Attestation" ) ;
140+ assert . true ( ! isElectraSingleAttestation ( attestation ) , "Attestation should be type phase0.Attestation" ) ;
135141 committeeIndex = null ; // For pre-electra, committee index info is encoded in attDataRootIndex
136142 }
137143
@@ -144,10 +150,10 @@ export class AttestationPool {
144150 const aggregate = aggregateByIndex . get ( committeeIndex ) ;
145151 if ( aggregate ) {
146152 // Aggregate mutating
147- return aggregateAttestationInto ( aggregate , attestation ) ;
153+ return aggregateAttestationInto ( aggregate , attestation , committeeValidatorIndex ) ;
148154 }
149155 // Create new aggregate
150- aggregateByIndex . set ( committeeIndex , attestationToAggregate ( attestation ) ) ;
156+ aggregateByIndex . set ( committeeIndex , attestationToAggregate ( attestation , committeeValidatorIndex , committeeSize ) ) ;
151157 return InsertOutcome . NewData ;
152158 }
153159
@@ -216,8 +222,18 @@ export class AttestationPool {
216222/**
217223 * Aggregate a new attestation into `aggregate` mutating it
218224 */
219- function aggregateAttestationInto ( aggregate : AggregateFast , attestation : Attestation ) : InsertOutcome {
220- const bitIndex = attestation . aggregationBits . getSingleTrueBit ( ) ;
225+ function aggregateAttestationInto (
226+ aggregate : AggregateFast ,
227+ attestation : SingleAttestation ,
228+ committeeValidatorIndex : number
229+ ) : InsertOutcome {
230+ let bitIndex : number | null ;
231+
232+ if ( isElectraSingleAttestation ( attestation ) ) {
233+ bitIndex = committeeValidatorIndex ;
234+ } else {
235+ bitIndex = attestation . aggregationBits . getSingleTrueBit ( ) ;
236+ }
221237
222238 // Should never happen, attestations are verified against this exact condition before
223239 assert . notNull ( bitIndex , "Invalid attestation in pool, not exactly one bit set" ) ;
@@ -234,13 +250,16 @@ function aggregateAttestationInto(aggregate: AggregateFast, attestation: Attesta
234250/**
235251 * Format `contribution` into an efficient `aggregate` to add more contributions in with aggregateContributionInto()
236252 */
237- function attestationToAggregate ( attestation : Attestation ) : AggregateFast {
238- if ( isElectraAttestation ( attestation ) ) {
253+ function attestationToAggregate (
254+ attestation : SingleAttestation ,
255+ committeeValidatorIndex : number ,
256+ committeeSize : number
257+ ) : AggregateFast {
258+ if ( isElectraSingleAttestation ( attestation ) ) {
239259 return {
240260 data : attestation . data ,
241- // clone because it will be mutated
242- aggregationBits : attestation . aggregationBits . clone ( ) ,
243- committeeBits : attestation . committeeBits ,
261+ aggregationBits : BitArray . fromSingleBit ( committeeSize , committeeValidatorIndex ) ,
262+ committeeBits : BitArray . fromSingleBit ( MAX_COMMITTEES_PER_SLOT , attestation . committeeIndex ) ,
244263 signature : signatureFromBytesNoCheck ( attestation . signature ) ,
245264 } ;
246265 }
0 commit comments