@@ -196,7 +196,7 @@ fn body_signature<'a>(header: &'a MultiEraHeader) -> Option<&'a [u8]> {
196196
197197#[ cfg( test) ]
198198mod tests {
199- use acropolis_common:: { genesis_values:: GenesisValues , Era } ;
199+ use acropolis_common:: { genesis_values:: GenesisValues , serialization :: Bech32Conversion , Era } ;
200200 use pallas:: ledger:: traverse:: MultiEraHeader ;
201201
202202 use super :: * ;
@@ -213,7 +213,7 @@ mod tests {
213213 MultiEraHeader :: decode ( Era :: Shelley as u8 , None , & block_header_4490511) . unwrap ( ) ;
214214
215215 let ocert_counters = HashMap :: new ( ) ;
216- let active_spos = Vec :: new ( ) ;
216+ let active_spos = vec ! [ ] ;
217217
218218 let result = validate_block_kes (
219219 & block_header,
@@ -228,4 +228,206 @@ mod tests {
228228 } ) ;
229229 assert ! ( result. is_ok( ) ) ;
230230 }
231+
232+ #[ test]
233+ fn test_4556956_block ( ) {
234+ let slots_per_kes_period = 129600 ;
235+ let max_kes_evolutions = 62 ;
236+ let genesis_values = GenesisValues :: mainnet ( ) ;
237+
238+ let block_header_4556956: Vec < u8 > =
239+ hex:: decode ( include_str ! ( "./data/4556956.cbor" ) ) . unwrap ( ) ;
240+ let block_header =
241+ MultiEraHeader :: decode ( Era :: Shelley as u8 , None , & block_header_4556956) . unwrap ( ) ;
242+
243+ let ocert_counters = HashMap :: from_iter ( [ (
244+ PoolId :: from_bech32 ( "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy" )
245+ . unwrap ( ) ,
246+ 1 ,
247+ ) ] ) ;
248+ let active_spos =
249+ vec ! [
250+ PoolId :: from_bech32( "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy" )
251+ . unwrap( ) ,
252+ ] ;
253+
254+ let result = validate_block_kes (
255+ & block_header,
256+ & ocert_counters,
257+ & active_spos,
258+ & genesis_values. genesis_delegs ,
259+ slots_per_kes_period,
260+ max_kes_evolutions,
261+ )
262+ . and_then ( |kes_validations| {
263+ kes_validations. iter ( ) . try_for_each ( |assert| assert ( ) . map_err ( Box :: new) )
264+ } ) ;
265+ assert ! ( result. is_ok( ) ) ;
266+ }
267+
268+ #[ test]
269+ fn test_4556956_block_with_wrong_ocert_counter ( ) {
270+ let slots_per_kes_period = 129600 ;
271+ let max_kes_evolutions = 62 ;
272+ let genesis_values = GenesisValues :: mainnet ( ) ;
273+
274+ let block_header_4556956: Vec < u8 > =
275+ hex:: decode ( include_str ! ( "./data/4556956.cbor" ) ) . unwrap ( ) ;
276+ let block_header =
277+ MultiEraHeader :: decode ( Era :: Shelley as u8 , None , & block_header_4556956) . unwrap ( ) ;
278+
279+ let ocert_counters = HashMap :: from_iter ( [ (
280+ PoolId :: from_bech32 ( "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy" )
281+ . unwrap ( ) ,
282+ 2 ,
283+ ) ] ) ;
284+ let active_spos =
285+ vec ! [
286+ PoolId :: from_bech32( "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy" )
287+ . unwrap( ) ,
288+ ] ;
289+
290+ let result = validate_block_kes (
291+ & block_header,
292+ & ocert_counters,
293+ & active_spos,
294+ & genesis_values. genesis_delegs ,
295+ slots_per_kes_period,
296+ max_kes_evolutions,
297+ )
298+ . and_then ( |kes_validations| {
299+ kes_validations. iter ( ) . try_for_each ( |assert| assert ( ) . map_err ( Box :: new) )
300+ } ) ;
301+ assert ! ( result. is_err( ) ) ;
302+ assert_eq ! (
303+ result. unwrap_err( ) ,
304+ Box :: new( KesValidationError :: OperationalCertificateError (
305+ OperationalCertificateError :: CounterTooSmallOcert {
306+ latest_counter: 2 ,
307+ declared_counter: 1
308+ }
309+ ) )
310+ ) ;
311+ }
312+
313+ #[ test]
314+ fn test_4556956_block_with_missing_ocert_counter_and_active_spos ( ) {
315+ let slots_per_kes_period = 129600 ;
316+ let max_kes_evolutions = 62 ;
317+ let genesis_values = GenesisValues :: mainnet ( ) ;
318+
319+ let block_header_4556956: Vec < u8 > =
320+ hex:: decode ( include_str ! ( "./data/4556956.cbor" ) ) . unwrap ( ) ;
321+ let block_header =
322+ MultiEraHeader :: decode ( Era :: Shelley as u8 , None , & block_header_4556956) . unwrap ( ) ;
323+
324+ let ocert_counters = HashMap :: new ( ) ;
325+ let active_spos = vec ! [ ] ;
326+
327+ let result = validate_block_kes (
328+ & block_header,
329+ & ocert_counters,
330+ & active_spos,
331+ & genesis_values. genesis_delegs ,
332+ slots_per_kes_period,
333+ max_kes_evolutions,
334+ )
335+ . and_then ( |kes_validations| {
336+ kes_validations. iter ( ) . try_for_each ( |assert| assert ( ) . map_err ( Box :: new) )
337+ } ) ;
338+ assert ! ( result. is_err( ) ) ;
339+ assert_eq ! (
340+ result. unwrap_err( ) ,
341+ Box :: new( KesValidationError :: NoOCertCounter {
342+ pool_id: PoolId :: from_bech32(
343+ "pool1pu5jlj4q9w9jlxeu370a3c9myx47md5j5m2str0naunn2q3lkdy"
344+ )
345+ . unwrap( ) ,
346+ } )
347+ ) ;
348+ }
349+
350+ #[ test]
351+ fn test_7854823_praos_block ( ) {
352+ let slots_per_kes_period = 129600 ;
353+ let max_kes_evolutions = 62 ;
354+ let genesis_values = GenesisValues :: mainnet ( ) ;
355+
356+ let block_header_7854823: Vec < u8 > =
357+ hex:: decode ( include_str ! ( "./data/7854823.cbor" ) ) . unwrap ( ) ;
358+ let block_header =
359+ MultiEraHeader :: decode ( Era :: Babbage as u8 , None , & block_header_7854823) . unwrap ( ) ;
360+
361+ let ocert_counters = HashMap :: from_iter ( [ (
362+ PoolId :: from_bech32 ( "pool195gdnmj6smzuakm4etxsxw3fgh8asqc4awtcskpyfnkpcvh2v8t" )
363+ . unwrap ( ) ,
364+ 11 ,
365+ ) ] ) ;
366+ let active_spos =
367+ vec ! [
368+ PoolId :: from_bech32( "pool195gdnmj6smzuakm4etxsxw3fgh8asqc4awtcskpyfnkpcvh2v8t" )
369+ . unwrap( ) ,
370+ ] ;
371+
372+ let result = validate_block_kes (
373+ & block_header,
374+ & ocert_counters,
375+ & active_spos,
376+ & genesis_values. genesis_delegs ,
377+ slots_per_kes_period,
378+ max_kes_evolutions,
379+ )
380+ . and_then ( |kes_validations| {
381+ kes_validations. iter ( ) . try_for_each ( |assert| assert ( ) . map_err ( Box :: new) )
382+ } ) ;
383+ assert ! ( result. is_ok( ) ) ;
384+ }
385+
386+ #[ test]
387+ fn test_7854823_praos_block_with_overincremented_ocert_counter ( ) {
388+ let slots_per_kes_period = 129600 ;
389+ let max_kes_evolutions = 62 ;
390+ let genesis_values = GenesisValues :: mainnet ( ) ;
391+
392+ let block_header_7854823: Vec < u8 > =
393+ hex:: decode ( include_str ! ( "./data/7854823.cbor" ) ) . unwrap ( ) ;
394+ let block_header =
395+ MultiEraHeader :: decode ( Era :: Babbage as u8 , None , & block_header_7854823) . unwrap ( ) ;
396+
397+ let ocert_counters = HashMap :: from_iter ( [ (
398+ PoolId :: from_bech32 ( "pool195gdnmj6smzuakm4etxsxw3fgh8asqc4awtcskpyfnkpcvh2v8t" )
399+ . unwrap ( ) ,
400+ // This is just for test case
401+ // actual on-chain value is 11
402+ // now ocert counter is incremented by 2
403+ 9 ,
404+ ) ] ) ;
405+ let active_spos =
406+ vec ! [
407+ PoolId :: from_bech32( "pool195gdnmj6smzuakm4etxsxw3fgh8asqc4awtcskpyfnkpcvh2v8t" )
408+ . unwrap( ) ,
409+ ] ;
410+
411+ let result = validate_block_kes (
412+ & block_header,
413+ & ocert_counters,
414+ & active_spos,
415+ & genesis_values. genesis_delegs ,
416+ slots_per_kes_period,
417+ max_kes_evolutions,
418+ )
419+ . and_then ( |kes_validations| {
420+ kes_validations. iter ( ) . try_for_each ( |assert| assert ( ) . map_err ( Box :: new) )
421+ } ) ;
422+ assert ! ( result. is_err( ) ) ;
423+ assert_eq ! (
424+ result. unwrap_err( ) ,
425+ Box :: new( KesValidationError :: OperationalCertificateError (
426+ OperationalCertificateError :: CounterOverIncrementedOcert {
427+ latest_counter: 9 ,
428+ declared_counter: 11 ,
429+ }
430+ ) )
431+ ) ;
432+ }
231433}
0 commit comments