From 14e540eae2e25d6848b49df062974df12cbc4962 Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux <hugo.trentesaux@lilo.org> Date: Wed, 3 May 2023 11:25:23 +0200 Subject: [PATCH] Fix certification renewal (nodes/rust/duniter-v2s!159) * fix same bug in cucumber test * fix(#109): handle certification renewal * test(#109): reveal certification renewal issue --- end2end-tests/tests/cucumber_tests.rs | 2 +- pallets/certification/src/lib.rs | 15 +++++++-- pallets/certification/src/tests.rs | 46 +++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/end2end-tests/tests/cucumber_tests.rs b/end2end-tests/tests/cucumber_tests.rs index 50ba89a58..cd7876032 100644 --- a/end2end-tests/tests/cucumber_tests.rs +++ b/end2end-tests/tests/cucumber_tests.rs @@ -416,7 +416,7 @@ async fn should_be_certified_by( .await?; // look for certification by issuer/receiver pair - match issuers.binary_search_by(|(issuer_, _)| issuer_index.cmp(issuer_)) { + match issuers.binary_search_by(|(issuer_, _)| issuer_.cmp(&issuer_index)) { Ok(_) => Ok(()), Err(_) => Err(anyhow::anyhow!( "no certification found from {} to {}: {:?}", diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs index 27fab1982..a734fcdeb 100644 --- a/pallets/certification/src/lib.rs +++ b/pallets/certification/src/lib.rs @@ -406,9 +406,16 @@ pub mod pallet { let mut created = false; CertsByReceiver::<T, I>::mutate_exists(receiver, |maybe_issuers| { let issuers = maybe_issuers.get_or_insert(Vec::with_capacity(0)); - if let Err(index) = issuers.binary_search_by(|(issuer_, _)| issuer.cmp(issuer_)) { - issuers.insert(index, (issuer, removable_on)); - created = true; + match issuers.binary_search_by(|(issuer_, _)| issuer_.cmp(&issuer)) { + // cert exists, must be renewed + Ok(index) => { + issuers[index] = (issuer, removable_on); + } + // cert does not exist, must be created + Err(index) => { + issuers.insert(index, (issuer, removable_on)); + created = true; + } } }); @@ -462,6 +469,7 @@ pub mod pallet { total_weight } /// perform the certification removal + /// if block number is given only remove cert if still set to expire at this block number fn remove_cert_inner( issuer: T::IdtyIndex, receiver: T::IdtyIndex, @@ -474,6 +482,7 @@ pub mod pallet { if let Ok(index) = issuers.binary_search_by(|(issuer_, _)| issuer_.cmp(&issuer)) { if let Some(block_number) = block_number_opt { if let Some((_, removable_on)) = issuers.get(index) { + // only remove cert if block number is matching if *removable_on == block_number { issuers.remove(index); removed = true; diff --git a/pallets/certification/src/tests.rs b/pallets/certification/src/tests.rs index c22880e8f..01d1b064f 100644 --- a/pallets/certification/src/tests.rs +++ b/pallets/certification/src/tests.rs @@ -176,6 +176,7 @@ fn test_cert_period() { }); } +// after given validity period, a certification should expire #[test] fn test_cert_expiry() { new_test_ext(DefaultCertificationConfig { @@ -215,3 +216,48 @@ fn test_cert_expiry() { })); }); } + +// when renewing a certification, it should not expire now, but later +#[test] +fn test_cert_renewal() { + 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(12); + // 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