11use  { 
22    crate :: CertificateId , 
33    bitvec:: prelude:: * , 
4-     solana_bls_signatures:: { 
5-         BlsError ,  Pubkey  as  BlsPubkey ,  PubkeyProjective ,  Signature ,  SignatureProjective , 
6-     } , 
4+     solana_bls_signatures:: { BlsError ,  Pubkey  as  BlsPubkey ,  PubkeyProjective ,  SignatureProjective } , 
75    solana_runtime:: epoch_stakes:: BLSPubkeyToRankMap , 
86    solana_vote:: alpenglow:: { 
97        bls_message:: { CertificateMessage ,  VoteMessage } , 
@@ -29,70 +27,56 @@ pub enum CertificateError {
2927    ValidatorDoesNotExist ( usize ) , 
3028} 
3129
32- //TODO(wen): Maybe we can merge all the below functions into CertificateMessage . 
30+ /// A builder for creating a `CertificateMessage` by efficiently aggregating BLS signatures . 
3331#[ derive( Clone ) ]  
34- pub  struct  VoteCertificate ( CertificateMessage ) ; 
32+ pub  struct  VoteCertificateBuilder  { 
33+     certificate :  Certificate , 
34+     signature :  SignatureProjective , 
35+     bitmap :  BitVec < u8 ,  Lsb0 > , 
36+ } 
3537
36- impl  From < CertificateMessage >  for  VoteCertificate  { 
37-     fn  from ( certificate_message :  CertificateMessage )  -> Self  { 
38-         Self ( certificate_message) 
38+ impl  TryFrom < CertificateMessage >  for  VoteCertificateBuilder  { 
39+     type  Error  = CertificateError ; 
40+ 
41+     fn  try_from ( message :  CertificateMessage )  -> Result < Self ,  Self :: Error >  { 
42+         let  projective_signature = SignatureProjective :: try_from ( message. signature ) ?; 
43+         Ok ( VoteCertificateBuilder  { 
44+             certificate :  message. certificate , 
45+             signature :  projective_signature, 
46+             bitmap :  message. bitmap , 
47+         } ) 
3948    } 
4049} 
4150
42- impl  VoteCertificate  { 
51+ impl  VoteCertificateBuilder  { 
4352    pub  fn  new ( certificate_id :  CertificateId )  -> Self  { 
44-         VoteCertificate ( CertificateMessage  { 
53+         Self  { 
4554            certificate :  certificate_id. into ( ) , 
46-             signature :  Signature :: default ( ) , 
55+             signature :  SignatureProjective :: identity ( ) , 
4756            bitmap :  BitVec :: < u8 ,  Lsb0 > :: repeat ( false ,  MAXIMUM_VALIDATORS ) , 
48-         } ) 
57+         } 
4958    } 
5059
51-     pub  fn  aggregate < ' a ,  ' b ,  T > ( & mut  self ,  messages :  T ) 
52-     where 
53-         T :  Iterator < Item  = & ' a  VoteMessage > , 
54-         Self :  ' b , 
55-         ' b :  ' a , 
56-     { 
57-         let  signature = & mut  self . 0 . signature ; 
58-         // TODO: signature aggregation can be done out-of-order; 
59-         // consider aggregating signatures separately in parallel 
60-         let  mut  current_signature = if  signature == & Signature :: default ( )  { 
61-             SignatureProjective :: identity ( ) 
62-         }  else  { 
63-             SignatureProjective :: try_from ( * signature) . expect ( "Invalid signature" ) 
64-         } ; 
65- 
66-         // aggregate the votes 
67-         let  bitmap = & mut  self . 0 . bitmap ; 
60+     /// Aggregates a slice of `VoteMessage`s into the builder. 
61+ pub  fn  aggregate ( & mut  self ,  messages :  & [ VoteMessage ] )  -> Result < ( ) ,  CertificateError >  { 
6862        for  vote_message in  messages { 
69-             // set bit-vector for the validator 
70-             // 
71-             // TODO: This only accounts for one type of vote. Update this after 
72-             // we have a base3 encoding implementation. 
73-             assert ! ( 
74-                 bitmap. len( )  > vote_message. rank as  usize , 
75-                 "Vote rank {} exceeds bitmap length {}" , 
76-                 vote_message. rank, 
77-                 bitmap. len( ) 
78-             ) ; 
79-             assert ! ( 
80-                 bitmap. get( vote_message. rank as  usize ) . as_deref( )  != Some ( & true ) , 
81-                 "Conflicting vote check should make this unreachable {vote_message:?}" 
82-             ) ; 
83-             bitmap. set ( vote_message. rank  as  usize ,  true ) ; 
84-             // aggregate the signature 
85-             current_signature
86-                 . aggregate_with ( [ & vote_message. signature ] ) 
87-                 . expect ( 
88-                     "Failed to aggregate signature: {vote_message.signature:?} into {current_signature:?}" 
89-                 ) ; 
63+             if  self . bitmap . len ( )  <= vote_message. rank  as  usize  { 
64+                 return  Err ( CertificateError :: ValidatorDoesNotExist ( 
65+                     vote_message. rank  as  usize , 
66+                 ) ) ; 
67+             } 
68+             self . bitmap . set ( vote_message. rank  as  usize ,  true ) ; 
9069        } 
91-         * signature = Signature :: from ( current_signature) ; 
70+         let  signature_iter = messages. iter ( ) . map ( |vote_message| & vote_message. signature ) ; 
71+         Ok ( self . signature . aggregate_with ( signature_iter) ?) 
9272    } 
9373
94-     pub  fn  certificate ( self )  -> CertificateMessage  { 
95-         self . 0 
74+     pub  fn  build ( self )  -> CertificateMessage  { 
75+         CertificateMessage  { 
76+             certificate :  self . certificate , 
77+             signature :  self . signature . into ( ) , 
78+             bitmap :  self . bitmap , 
79+         } 
9680    } 
9781} 
9882
0 commit comments