From e3211e89594d73d9bf59196c8e3f8c2075c14c91 Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux <hugo.trentesaux@lilo.org> Date: Tue, 16 May 2023 17:45:51 +0200 Subject: [PATCH] fix certification period on renewal (nodes/rust/duniter-v2s!165) * fix certification period on renewal --- pallets/certification/src/lib.rs | 9 ++- pallets/certification/src/mock.rs | 1 + pallets/certification/src/tests.rs | 107 ++++++++++++++++++++++++++++- 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs index a734fcdeb..b062da444 100644 --- a/pallets/certification/src/lib.rs +++ b/pallets/certification/src/lib.rs @@ -392,7 +392,7 @@ pub mod pallet { // INTERNAL FUNCTIONS // impl<T: Config<I>, I: 'static> Pallet<T, I> { - /// perform cert add + /// perform cert addition or renewal fn do_add_cert( block_number: T::BlockNumber, issuer: T::IdtyIndex, @@ -438,6 +438,7 @@ pub mod pallet { cert_meta.received_count }); + // emit NewCert event Self::deposit_event(Event::NewCert { issuer, issuer_issued_count, @@ -451,12 +452,18 @@ pub mod pallet { receiver_received_count, ); } else { + // Update next_issuable_on in StorageIdtyCertMeta for issuer + StorageIdtyCertMeta::<T, I>::mutate(issuer, |issuer_idty_cert_meta| { + issuer_idty_cert_meta.next_issuable_on = block_number + T::CertPeriod::get(); + }); + // emit RenewedCert event Self::deposit_event(Event::RenewedCert { issuer, receiver }); } Ok(().into()) } /// remove the certifications due to expire on the given block + // (run at on_initialize step) fn prune_certifications(block_number: T::BlockNumber) -> Weight { let mut total_weight = Weight::zero(); diff --git a/pallets/certification/src/mock.rs b/pallets/certification/src/mock.rs index f5cf93032..b93e515cf 100644 --- a/pallets/certification/src/mock.rs +++ b/pallets/certification/src/mock.rs @@ -129,6 +129,7 @@ pub fn run_to_block(n: u64) { while System::block_number() < n { DefaultCertification::on_finalize(System::block_number()); System::on_finalize(System::block_number()); + System::reset_events(); System::set_block_number(System::block_number() + 1); System::on_initialize(System::block_number()); DefaultCertification::on_initialize(System::block_number()); diff --git a/pallets/certification/src/tests.rs b/pallets/certification/src/tests.rs index 01d1b064f..856788409 100644 --- a/pallets/certification/src/tests.rs +++ b/pallets/certification/src/tests.rs @@ -16,7 +16,7 @@ use crate::mock::*; use crate::{Error, Event}; -use frame_support::assert_ok; +use frame_support::{assert_noop, assert_ok}; use maplit::btreemap; use sp_std::collections::btree_map::BTreeMap; @@ -261,3 +261,108 @@ fn test_cert_renewal() { })); }); } + +// when renewing a certification, issuer should not be able to emit a new cert before certification delay +#[test] +fn test_cert_renewal_cert_delay() { + new_test_ext(DefaultCertificationConfig { + apply_cert_period_at_genesis: false, + certs_by_receiver: btreemap![ + 0 => btreemap![ + 1 => Some(5), + 2 => Some(20), + ], + 1 => btreemap![ + 0 => Some(20), + 2 => Some(20), + ], + 2 => btreemap![ + 0 => Some(20), + 1 => Some(20), + ], + ], + }) + .execute_with(|| { + run_to_block(2); + // renew certification from bob to alice + assert_eq!( + DefaultCertification::add_cert(RuntimeOrigin::signed(1), 1, 0), + Ok(().into()) + ); + System::assert_last_event(RuntimeEvent::DefaultCertification(Event::RenewedCert { + issuer: 1, + receiver: 0, + })); + + run_to_block(3); + // try to renew again + assert_noop!( + DefaultCertification::add_cert(RuntimeOrigin::signed(1), 1, 0), + Error::<Test, _>::NotRespectCertPeriod, + ); + // no renewal event should be emitted + assert_eq!(System::events().last(), None); + }); +} + +// when renewing a certification, the certification should not expire before new expiration +#[test] +fn test_cert_renewal_expiration() { + new_test_ext(DefaultCertificationConfig { + apply_cert_period_at_genesis: false, + certs_by_receiver: btreemap![ + 0 => btreemap![ + 1 => Some(5), + 2 => Some(20), + ], + 1 => btreemap![ + 0 => Some(20), + 2 => Some(20), + ], + 2 => btreemap![ + 0 => Some(20), + 1 => Some(20), + ], + ], + }) + .execute_with(|| { + run_to_block(2); + // renew certification from bob to alice + // this certification should expire 10 blocks later (at block 12) + assert_eq!( + DefaultCertification::add_cert(RuntimeOrigin::signed(1), 1, 0), + Ok(().into()) + ); + System::assert_last_event(RuntimeEvent::DefaultCertification(Event::RenewedCert { + issuer: 1, + receiver: 0, + })); + + run_to_block(4); + // renew certification from bob to alice again + // this certification should expire 10 blocks later (at block 14) + assert_eq!( + DefaultCertification::add_cert(RuntimeOrigin::signed(1), 1, 0), + Ok(().into()) + ); + System::assert_last_event(RuntimeEvent::DefaultCertification(Event::RenewedCert { + issuer: 1, + receiver: 0, + })); + + // no certification should expire at these blocks + // hint : prune_certifications checks that the certification has not been renewed + run_to_block(12); + assert_eq!(System::events().last(), None); + + run_to_block(14); + // expiry of previously renewed cert + System::assert_last_event(RuntimeEvent::DefaultCertification(Event::RemovedCert { + issuer: 1, + issuer_issued_count: 1, + receiver: 0, + receiver_received_count: 1, + expiration: true, + })); + }); +} -- GitLab