@@ -3,15 +3,15 @@ use fuel_core_client::client::types::{
3
3
Block as FuelBlock , Consensus as FuelConsensus , Header as FuelHeader ,
4
4
PoAConsensus as FuelPoAConsensus ,
5
5
} ,
6
- primitives:: { BlockId as FuelBlockId , Bytes32 as FuelBytes32 , PublicKey as FuelPublicKey } ,
6
+ primitives:: { BlockId as FuelBlockId , Bytes32 as FuelBytes32 } ,
7
7
} ;
8
8
use fuel_crypto:: { Hasher , Message } ;
9
9
10
10
use crate :: { block:: ValidatedFuelBlock , Error , Result , Validator } ;
11
11
12
12
#[ derive( Debug ) ]
13
13
pub struct BlockValidator {
14
- producer_pub_key : FuelPublicKey ,
14
+ producer_addr : [ u8 ; 32 ] ,
15
15
}
16
16
17
17
impl Validator for BlockValidator {
@@ -21,12 +21,12 @@ impl Validator for BlockValidator {
21
21
}
22
22
23
23
impl BlockValidator {
24
- pub fn new ( producer_pub_key : FuelPublicKey ) -> Self {
25
- Self { producer_pub_key }
24
+ pub fn new ( producer_addr : [ u8 ; 32 ] ) -> Self {
25
+ Self { producer_addr }
26
26
}
27
27
28
28
fn _validate ( & self , fuel_block : & FuelBlock ) -> Result < ValidatedFuelBlock > {
29
- self . validate_public_key ( fuel_block) ?;
29
+ self . validate_producer_addr ( fuel_block) ?;
30
30
Self :: validate_block_id ( fuel_block) ?;
31
31
self . validate_block_signature ( fuel_block) ?;
32
32
@@ -36,18 +36,18 @@ impl BlockValidator {
36
36
} )
37
37
}
38
38
39
- fn validate_public_key ( & self , fuel_block : & FuelBlock ) -> Result < ( ) > {
40
- let Some ( producer_pub_key ) = fuel_block. block_producer ( ) else {
39
+ fn validate_producer_addr ( & self , fuel_block : & FuelBlock ) -> Result < ( ) > {
40
+ let Some ( producer_addr ) = fuel_block. block_producer ( ) . map ( |key| key . hash ( ) ) else {
41
41
return Err ( Error :: BlockValidation (
42
42
"producer public key not found in fuel block" . to_string ( ) ,
43
43
) ) ;
44
44
} ;
45
45
46
- if * producer_pub_key != self . producer_pub_key {
46
+ if * producer_addr != self . producer_addr {
47
47
return Err ( Error :: BlockValidation ( format ! (
48
- "producer public key `{producer_pub_key:x}` does not match \
49
- expected public key `{:x}`." ,
50
- self . producer_pub_key
48
+ "producer addr '{}' does not match expected addr '{}'." ,
49
+ hex :: encode ( producer_addr ) ,
50
+ hex :: encode ( self . producer_addr )
51
51
) ) ) ;
52
52
}
53
53
@@ -75,16 +75,23 @@ impl BlockValidator {
75
75
) ) ;
76
76
} ;
77
77
78
- let block_id_message = Message :: from_bytes ( * fuel_block. id ) ;
79
-
80
- signature
81
- . verify ( & self . producer_pub_key , & block_id_message)
82
- . map_err ( |_| {
78
+ let recovered_producer_addr = * signature
79
+ . recover ( & Message :: from_bytes ( * fuel_block. id ) )
80
+ . map_err ( |e| {
83
81
Error :: BlockValidation ( format ! (
84
- "signature validation failed for fuel block with id: `{:x}` and pub key: `{:x}`" ,
85
- fuel_block. id, & self . producer_pub_key
82
+ "failed to recover public key from PoAConsensus signature: {e:?}" ,
86
83
) )
87
- } ) ?;
84
+ } ) ?
85
+ . hash ( ) ;
86
+
87
+ if recovered_producer_addr != self . producer_addr {
88
+ return Err ( Error :: BlockValidation ( format ! (
89
+ "recovered producer addr `{}` does not match \
90
+ expected addr`{}`.",
91
+ hex:: encode( recovered_producer_addr) ,
92
+ hex:: encode( self . producer_addr)
93
+ ) ) ) ;
94
+ }
88
95
89
96
Ok ( ( ) )
90
97
}
@@ -146,17 +153,17 @@ mod tests {
146
153
#[ should_panic( expected = "producer public key not found in fuel block" ) ]
147
154
fn validate_public_key_missing ( ) {
148
155
let fuel_block = given_a_block ( None ) ;
149
- let validator = BlockValidator :: new ( FuelPublicKey :: default ( ) ) ;
156
+ let validator = BlockValidator :: new ( [ 0 ; 32 ] ) ;
150
157
151
158
validator. validate ( & fuel_block) . unwrap ( ) ;
152
159
}
153
160
154
161
#[ test]
155
- #[ should_panic( expected = "does not match expected public key " ) ]
162
+ #[ should_panic( expected = "does not match expected addr " ) ]
156
163
fn validate_public_key_mistmach ( ) {
157
164
let secret_key = given_secret_key ( ) ;
158
165
let fuel_block = given_a_block ( Some ( secret_key) ) ;
159
- let validator = BlockValidator :: new ( FuelPublicKey :: default ( ) ) ;
166
+ let validator = BlockValidator :: new ( [ 0 ; 32 ] ) ;
160
167
161
168
validator. validate ( & fuel_block) . unwrap ( ) ;
162
169
}
@@ -167,7 +174,7 @@ mod tests {
167
174
let secret_key = given_secret_key ( ) ;
168
175
let mut fuel_block = given_a_block ( Some ( secret_key) ) ;
169
176
fuel_block. header . height = 42 ; // Change a value to get a different block id
170
- let validator = BlockValidator :: new ( secret_key. public_key ( ) ) ;
177
+ let validator = BlockValidator :: new ( * secret_key. public_key ( ) . hash ( ) ) ;
171
178
172
179
validator. validate ( & fuel_block) . unwrap ( ) ;
173
180
}
@@ -178,20 +185,29 @@ mod tests {
178
185
let secret_key = given_secret_key ( ) ;
179
186
let mut fuel_block = given_a_block ( Some ( secret_key) ) ;
180
187
fuel_block. consensus = FuelConsensus :: Unknown ;
181
- let validator = BlockValidator :: new ( secret_key. public_key ( ) ) ;
188
+ let validator = BlockValidator :: new ( * secret_key. public_key ( ) . hash ( ) ) ;
182
189
183
190
validator. validate ( & fuel_block) . unwrap ( ) ;
184
191
}
185
192
186
193
#[ test]
187
- #[ should_panic( expected = "signature validation failed for fuel block with id:" ) ]
194
+ #[ should_panic(
195
+ expected = "recovered producer addr `286b769a36b01cebc43cd9820ba709b438b14566e16a287c36881194eacc45c6` does not match expected addr`f95112e76de29dca6ed315c5a5be7855e62dee55478077cf209554d5bfb7cd85`."
196
+ ) ]
188
197
fn validate_block_consensus_invalid_signature ( ) {
189
- let secret_key = given_secret_key ( ) ;
190
- let mut fuel_block = given_a_block ( Some ( secret_key) ) ;
198
+ let correct_secret_key = given_secret_key ( ) ;
199
+
200
+ let mut fuel_block = given_a_block ( Some ( correct_secret_key) ) ;
201
+ let invalid_signature = {
202
+ let different_secret_key = SecretKey :: random ( & mut StdRng :: seed_from_u64 ( 43 ) ) ;
203
+ let id_message = Message :: from_bytes ( * fuel_block. id ) ;
204
+ Signature :: sign ( & different_secret_key, & id_message)
205
+ } ;
206
+
191
207
fuel_block. consensus = FuelConsensus :: PoAConsensus ( FuelPoAConsensus {
192
- signature : Signature :: default ( ) ,
208
+ signature : invalid_signature ,
193
209
} ) ;
194
- let validator = BlockValidator :: new ( secret_key . public_key ( ) ) ;
210
+ let validator = BlockValidator :: new ( * correct_secret_key . public_key ( ) . hash ( ) ) ;
195
211
196
212
validator. validate ( & fuel_block) . unwrap ( ) ;
197
213
}
@@ -200,7 +216,7 @@ mod tests {
200
216
fn validate_fuel_block ( ) {
201
217
let secret_key = given_secret_key ( ) ;
202
218
let fuel_block = given_a_block ( Some ( secret_key) ) ;
203
- let validator = BlockValidator :: new ( secret_key. public_key ( ) ) ;
219
+ let validator = BlockValidator :: new ( * secret_key. public_key ( ) . hash ( ) ) ;
204
220
205
221
validator. validate ( & fuel_block) . unwrap ( ) ;
206
222
}
0 commit comments