@@ -8,7 +8,13 @@ use ssz_types::{VariableList, typenum::U4096};
88use tree_hash:: TreeHash ;
99use tree_hash_derive:: TreeHash ;
1010
11- use crate :: { attestation:: Attestation , state:: LeanState } ;
11+ #[ cfg( feature = "devnet2" ) ]
12+ use crate :: attestation:: AggregatedAttestation ;
13+ #[ cfg( feature = "devnet2" ) ]
14+ use crate :: attestation:: AggregatedAttestations ;
15+ #[ cfg( feature = "devnet1" ) ]
16+ use crate :: attestation:: Attestation ;
17+ use crate :: state:: LeanState ;
1218
1319#[ derive( Debug , PartialEq , Eq , Clone , Serialize , Deserialize , Encode , Decode ) ]
1420pub struct BlockSignatures {
@@ -34,18 +40,34 @@ impl SignedBlockWithAttestation {
3440 ) -> anyhow:: Result < bool > {
3541 let block = & self . message . block ;
3642 let signatures = & self . signature ;
43+ #[ cfg( feature = "devnet1" ) ]
3744 let mut all_attestations = block. body . attestations . to_vec ( ) ;
45+ #[ cfg( feature = "devnet2" ) ]
46+ let aggregated_attestations = & block. body . attestations ;
47+ #[ cfg( feature = "devnet2" ) ]
48+ let attestation_signatures = & signatures. attestation_signatures ;
3849
50+ #[ cfg( feature = "devnet1" ) ]
3951 all_attestations. push ( self . message . proposer_attestation . clone ( ) ) ;
4052
53+ #[ cfg( feature = "devnet1" ) ]
4154 ensure ! (
4255 signatures. len( ) == all_attestations. len( ) ,
4356 "Number of signatures {} does not match number of attestations {}" ,
4457 signatures. len( ) ,
4558 all_attestations. len( ) ,
4659 ) ;
60+ #[ cfg( feature = "devnet2" ) ]
61+ ensure ! (
62+ attestation_signatures. len( ) == aggregated_attestations. len( ) ,
63+ "Number of signatures {} does not match number of attestations {}" ,
64+ attestation_signatures. len( ) ,
65+ aggregated_attestations. len( ) ,
66+ ) ;
67+
4768 let validators = & parent_state. validators ;
4869
70+ #[ cfg( feature = "devnet1" ) ]
4971 for ( attestation, signature) in all_attestations. iter ( ) . zip ( signatures. iter ( ) ) {
5072 ensure ! (
5173 attestation. validator_id < validators. len( ) as u64 ,
@@ -69,6 +91,73 @@ impl SignedBlockWithAttestation {
6991 }
7092 }
7193
94+ #[ cfg( feature = "devnet2" ) ]
95+ {
96+ let mut signature_iter = attestation_signatures. iter ( ) ;
97+ for aggregated_attestation in aggregated_attestations. iter ( ) {
98+ let validator_ids: Vec < usize > = aggregated_attestation
99+ . aggregation_bits
100+ . iter ( )
101+ . enumerate ( )
102+ . filter ( |( _, bit) | * bit)
103+ . map ( |( index, _) | index)
104+ . collect ( ) ;
105+
106+ let attestation_root = aggregated_attestation. message . tree_hash_root ( ) ;
107+
108+ for validator_id in validator_ids {
109+ let signature = signature_iter. next ( ) . ok_or_else ( || {
110+ anyhow ! ( "Missing signature for validator index {validator_id}" )
111+ } ) ?;
112+
113+ ensure ! (
114+ validator_id < validators. len( ) ,
115+ "Validator index out of range"
116+ ) ;
117+
118+ let validator = validators
119+ . get ( validator_id)
120+ . ok_or_else ( || anyhow ! ( "Failed to get validator" ) ) ?;
121+
122+ if verify_signatures {
123+ let timer = start_timer ( & PQ_SIGNATURE_ATTESTATION_VERIFICATION_TIME , & [ ] ) ;
124+ ensure ! (
125+ signature. verify(
126+ & validator. public_key,
127+ aggregated_attestation. message. slot as u32 ,
128+ & attestation_root,
129+ ) ?,
130+ "Attestation signature verification failed"
131+ ) ;
132+ stop_timer ( timer) ;
133+ }
134+ }
135+ }
136+
137+ let proposer_attestation = & self . message . proposer_attestation ;
138+ let proposer_signature = & signatures. proposer_signature ;
139+
140+ ensure ! (
141+ proposer_attestation. validator_id < validators. len( ) as u64 ,
142+ "Proposer index out of range"
143+ ) ;
144+
145+ let proposer = validators
146+ . get ( proposer_attestation. validator_id as usize )
147+ . ok_or_else ( || anyhow ! ( "Failed to get proposer validator" ) ) ?;
148+
149+ if verify_signatures {
150+ ensure ! (
151+ proposer_signature. verify(
152+ & proposer. public_key,
153+ proposer_attestation. data. slot as u32 ,
154+ & proposer_attestation. data. tree_hash_root( ) ,
155+ ) ?,
156+ "Failed to verify"
157+ ) ;
158+ }
159+ }
160+
72161 Ok ( true )
73162 }
74163}
@@ -77,7 +166,10 @@ impl SignedBlockWithAttestation {
77166#[ derive( Debug , PartialEq , Eq , Clone , Serialize , Deserialize , Encode , Decode ) ]
78167pub struct BlockWithAttestation {
79168 pub block : Block ,
169+ #[ cfg( feature = "devnet1" ) ]
80170 pub proposer_attestation : Attestation ,
171+ #[ cfg( feature = "devnet2" ) ]
172+ pub proposer_attestation : AggregatedAttestations ,
81173}
82174
83175/// Represents a block in the Lean chain.
@@ -117,10 +209,10 @@ impl From<Block> for BlockHeader {
117209/// Represents the body of a block in the Lean chain.
118210#[ derive( Debug , PartialEq , Eq , Clone , Serialize , Deserialize , Encode , Decode , TreeHash ) ]
119211pub struct BlockBody {
120- #[ cfg( feature = "devnet2" ) ]
121- pub attestations : VariableList < AggregatedAttestations , U4096 > ,
122212 #[ cfg( feature = "devnet1" ) ]
123213 pub attestations : VariableList < Attestation , U4096 > ,
214+ #[ cfg( feature = "devnet2" ) ]
215+ pub attestations : VariableList < AggregatedAttestation , U4096 > ,
124216}
125217
126218#[ derive( Debug , PartialEq , Eq , Clone , Serialize , Deserialize , Encode , Decode , TreeHash ) ]
@@ -151,6 +243,7 @@ mod tests {
151243 attestations : Default :: default ( ) ,
152244 } ,
153245 } ,
246+ #[ cfg( feature = "devnet1" ) ]
154247 proposer_attestation : Attestation {
155248 validator_id : 0 ,
156249 data : AttestationData {
@@ -160,8 +253,24 @@ mod tests {
160253 source : Checkpoint :: default ( ) ,
161254 } ,
162255 } ,
256+ #[ cfg( feature = "devnet2" ) ]
257+ proposer_attestation : AggregatedAttestations {
258+ validator_id : 0 ,
259+ data : AttestationData {
260+ slot : 0 ,
261+ head : Checkpoint :: default ( ) ,
262+ target : Checkpoint :: default ( ) ,
263+ source : Checkpoint :: default ( ) ,
264+ } ,
265+ } ,
163266 } ,
267+ #[ cfg( feature = "devnet1" ) ]
164268 signature : VariableList :: default ( ) ,
269+ #[ cfg( feature = "devnet2" ) ]
270+ signature : BlockSignatures {
271+ attestation_signatures : VariableList :: default ( ) ,
272+ proposer_signature : Signature :: blank ( ) ,
273+ } ,
165274 } ;
166275
167276 let encode = signed_block_with_attestation. as_ssz_bytes ( ) ;
0 commit comments