diff --git a/Cargo.lock b/Cargo.lock
index 6b082ab8c3aafdbdad92ea086e67e4a17c3bfb0d..62bfb7f2eb603a413c376f094c5e68a37ce1a956 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1403,6 +1403,7 @@ dependencies = [
  "jsonrpc-core",
  "log",
  "maplit",
+ "pallet-certification",
  "pallet-grandpa",
  "pallet-transaction-payment-rpc",
  "pallet-transaction-payment-rpc-runtime-api",
diff --git a/node/Cargo.toml b/node/Cargo.toml
index 199ad31b104e2452bd5d3b493f528e8faf48f04e..1df3d4884aafe6de654216664a5a8cf2a91b6533 100644
--- a/node/Cargo.toml
+++ b/node/Cargo.toml
@@ -31,6 +31,7 @@ common-runtime = { path = '../runtime/common' }
 g1-runtime = { path = '../runtime/g1' }
 gdev-runtime = { path = '../runtime/gdev' }
 gtest-runtime = { path = '../runtime/gtest' }
+pallet-certification = { path = '../pallets/certification' }
 
 # crates.io dependencies
 async-io = "1.3"
diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs
index b43a097208f1a23730fd426eb15a271f93f8907e..e160f97c782cdd140814c9b6d3ac0bafc1bdcf22 100644
--- a/node/src/chain_spec.rs
+++ b/node/src/chain_spec.rs
@@ -22,7 +22,7 @@ use common_runtime::IdtyIndex;
 use common_runtime::{entities::IdtyName, AccountId, Signature};
 use sp_core::{Pair, Public};
 use sp_runtime::traits::{IdentifyAccount, Verify};
-use std::collections::{BTreeMap, BTreeSet};
+use std::collections::BTreeMap;
 
 pub type AccountPublic = <Signature as Verify>::Signer;
 
@@ -49,13 +49,22 @@ where
     AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
 }
 
-fn clique_wot(initial_identities_len: usize) -> BTreeMap<IdtyIndex, BTreeSet<IdtyIndex>> {
+fn clique_wot(
+    initial_identities_len: usize,
+    cert_validity_period: common_runtime::BlockNumber,
+) -> BTreeMap<IdtyIndex, BTreeMap<IdtyIndex, common_runtime::BlockNumber>> {
     let mut certs_by_issuer = BTreeMap::new();
     for i in 1..=initial_identities_len {
         certs_by_issuer.insert(
             i as IdtyIndex,
             (1..=initial_identities_len)
-                .filter_map(|j| if i != j { Some(j as IdtyIndex) } else { None })
+                .filter_map(|j| {
+                    if i != j {
+                        Some((j as IdtyIndex, cert_validity_period))
+                    } else {
+                        None
+                    }
+                })
                 .collect(),
         );
     }
diff --git a/node/src/chain_spec/gdev.rs b/node/src/chain_spec/gdev.rs
index e8f19d2761f70d06fb3dd3ea7e8037a0249abacf..33f4294bd59046874f77185ac939c88b744f0702 100644
--- a/node/src/chain_spec/gdev.rs
+++ b/node/src/chain_spec/gdev.rs
@@ -133,7 +133,10 @@ fn devnet_genesis(
                 .collect(),
         },
         strong_cert: StrongCertConfig {
-            certs_by_issuer: clique_wot(initial_identities.len()),
+            certs_by_issuer: clique_wot(
+                initial_identities.len(),
+                gdev_runtime::parameters::ValidityPeriod::get(),
+            ),
             phantom: std::marker::PhantomData,
         },
         ud_accounts_storage: UdAccountsStorageConfig {
diff --git a/node/src/chain_spec/gtest.rs b/node/src/chain_spec/gtest.rs
index 95c58d6bb22f7066266a786d331365fa6c3c790e..f509baa06e2aa90c5e93d63fc0f89bca92ba7665 100644
--- a/node/src/chain_spec/gtest.rs
+++ b/node/src/chain_spec/gtest.rs
@@ -187,7 +187,10 @@ fn devnet_genesis(
                 .collect(),
         },
         strong_cert: StrongCertConfig {
-            certs_by_issuer: clique_wot(initial_identities.len()),
+            certs_by_issuer: clique_wot(
+                initial_identities.len(),
+                gtest_runtime::parameters::ValidityPeriod::get(),
+            ),
             phantom: std::marker::PhantomData,
         },
         ud_accounts_storage: UdAccountsStorageConfig {
@@ -249,7 +252,10 @@ fn testnet_genesis(
                 .collect(),
         },
         strong_cert: StrongCertConfig {
-            certs_by_issuer: clique_wot(initial_identities.len()),
+            certs_by_issuer: clique_wot(
+                initial_identities.len(),
+                gdev_runtime::parameters::ValidityPeriod::get(),
+            ),
             phantom: std::marker::PhantomData,
         },
         ud_accounts_storage: UdAccountsStorageConfig {
diff --git a/pallets/certification/src/lib.rs b/pallets/certification/src/lib.rs
index 85abc2f3b99e97d3caad459903b59f945760fae8..e3488589856867d71f45da02d27c11c72c583282 100644
--- a/pallets/certification/src/lib.rs
+++ b/pallets/certification/src/lib.rs
@@ -39,7 +39,7 @@ pub mod pallet {
     use super::*;
     use frame_support::pallet_prelude::*;
     use frame_system::pallet_prelude::*;
-    use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
+    use sp_std::collections::btree_map::BTreeMap;
 
     /// The current storage version.
     const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
@@ -87,7 +87,7 @@ pub mod pallet {
 
     #[pallet::genesis_config]
     pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
-        pub certs_by_issuer: BTreeMap<T::IdtyIndex, BTreeSet<T::IdtyIndex>>,
+        pub certs_by_issuer: BTreeMap<T::IdtyIndex, BTreeMap<T::IdtyIndex, T::BlockNumber>>,
         pub phantom: PhantomData<I>,
     }
 
@@ -109,7 +109,7 @@ pub mod pallet {
             let mut certs_by_receiver = BTreeMap::<T::IdtyIndex, Vec<T::IdtyIndex>>::new();
             for (issuer, receivers) in &self.certs_by_issuer {
                 assert!(
-                    !receivers.contains(issuer),
+                    !receivers.contains_key(issuer),
                     "Identity cannot certify it-self."
                 );
                 assert!(
@@ -122,11 +122,11 @@ pub mod pallet {
                     *issuer,
                     IdtyCertMeta {
                         issued_count: receivers.len() as u8,
-                        next_issuable_on: T::CertPeriod::get(),
+                        next_issuable_on: sp_runtime::traits::Zero::zero(),
                         received_count: 0,
                     },
                 );
-                for receiver in receivers {
+                for receiver in receivers.keys() {
                     certs_by_receiver
                         .entry(*receiver)
                         .or_default()
@@ -142,26 +142,47 @@ pub mod pallet {
                 issuers.sort();
                 <StorageCertsByReceiver<T, I>>::insert(receiver, issuers);
             }
-            // Write StorageIdtyCertMeta
-            for (issuer, cert_meta) in cert_meta_by_issuer {
-                <StorageIdtyCertMeta<T, I>>::insert(issuer, cert_meta);
-            }
-            // Write StorageCertsByIssuer && StorageCertsRemovableOn
-            let mut all_couples = Vec::new();
+            // Write StorageCertsByIssuer
+            let mut certs_removable_on =
+                BTreeMap::<T::BlockNumber, Vec<(T::IdtyIndex, T::IdtyIndex)>>::new();
             for (issuer, receivers) in &self.certs_by_issuer {
-                for receiver in receivers {
-                    all_couples.push((*issuer, *receiver));
+                for (receiver, removable_on) in receivers {
+                    certs_removable_on
+                        .entry(*removable_on)
+                        .or_default()
+                        .push((*issuer, *receiver));
+
+                    use sp_runtime::traits::Saturating as _;
+                    let issuer_next_issuable_on = removable_on
+                        .saturating_add(T::CertPeriod::get())
+                        .saturating_sub(T::ValidityPeriod::get());
+                    if let Some(cert_meta) = cert_meta_by_issuer.get_mut(issuer) {
+                        if cert_meta.next_issuable_on < issuer_next_issuable_on {
+                            cert_meta.next_issuable_on = issuer_next_issuable_on;
+                        }
+                    }
+                    let renewable_on = removable_on.saturating_sub(
+                        T::ValidityPeriod::get().saturating_sub(T::CertRenewablePeriod::get()),
+                    );
+
                     <StorageCertsByIssuer<T, I>>::insert(
                         issuer,
                         receiver,
                         CertValue {
-                            renewable_on: T::CertRenewablePeriod::get(),
-                            removable_on: T::ValidityPeriod::get(),
+                            renewable_on,
+                            removable_on: *removable_on,
                         },
                     );
                 }
             }
-            <StorageCertsRemovableOn<T, I>>::insert(T::ValidityPeriod::get(), all_couples);
+            // Write StorageIdtyCertMeta
+            for (issuer, cert_meta) in cert_meta_by_issuer {
+                <StorageIdtyCertMeta<T, I>>::insert(issuer, cert_meta);
+            }
+            // Write storage StorageCertsRemovableOn
+            for (removable_on, certs) in certs_removable_on {
+                <StorageCertsRemovableOn<T, I>>::insert(removable_on, certs);
+            }
         }
     }
 
diff --git a/pallets/certification/src/tests.rs b/pallets/certification/src/tests.rs
index 72017eebbca868ebadac330d6a5f5976bd8f8a06..c044907491ccd2c6803d488803425a1ffaca0ca6 100644
--- a/pallets/certification/src/tests.rs
+++ b/pallets/certification/src/tests.rs
@@ -14,11 +14,12 @@
 // You should have received a copy of the GNU Affero General Public License
 // along with Substrate-Libre-Currency. If not, see <https://www.gnu.org/licenses/>.
 
+use crate::mock::Event as RuntimeEvent;
 use crate::mock::*;
-use crate::Error;
+use crate::{Error, Event};
 use frame_support::assert_ok;
 //use frame_system::{EventRecord, Phase};
-use maplit::{btreemap, btreeset};
+use maplit::btreemap;
 use sp_std::collections::btree_map::BTreeMap;
 
 #[test]
@@ -35,10 +36,84 @@ fn test_must_receive_cert_before_can_issue() {
     });
 }
 
+#[test]
+fn test_genesis_build() {
+    new_test_ext(DefaultCertificationConfig {
+        certs_by_issuer: btreemap![
+            0 => btreemap![
+                1 => 10,
+                2 => 5,
+            ],
+            1 => btreemap![
+                0 => 7,
+                2 => 4,
+            ],
+            2 => btreemap![
+                0 => 9,
+                1 => 3,
+            ],
+        ],
+        phantom: core::marker::PhantomData,
+    })
+    .execute_with(|| {
+        run_to_block(1);
+        // Verify state of idty 0
+        assert_eq!(
+            DefaultCertification::idty_cert_meta(0),
+            Some(crate::IdtyCertMeta {
+                issued_count: 2,
+                next_issuable_on: 2,
+                received_count: 2,
+            })
+        );
+        // Verify state of idty 1
+        assert_eq!(
+            DefaultCertification::idty_cert_meta(1),
+            Some(crate::IdtyCertMeta {
+                issued_count: 2,
+                next_issuable_on: 0,
+                received_count: 2,
+            })
+        );
+        // Verify state of idty 2
+        assert_eq!(
+            DefaultCertification::idty_cert_meta(2),
+            Some(crate::IdtyCertMeta {
+                issued_count: 2,
+                next_issuable_on: 1,
+                received_count: 2,
+            })
+        );
+        // Cert 2->1 must be removable at block #3
+        assert_eq!(
+            DefaultCertification::certs_removable_on(3),
+            Some(vec![(2, 1)]),
+        );
+        // Cert 2->0 cannot be renewed before #5
+        assert_eq!(
+            DefaultCertification::add_cert(Origin::root(), 2, 0),
+            Err(Error::<Test, _>::NotRespectRenewablePeriod.into())
+        );
+
+        run_to_block(3);
+        // Cert 2->1 must have expired
+        assert_eq!(
+            System::events()[0].event,
+            RuntimeEvent::DefaultCertification(Event::RemovedCert {
+                issuer: 2,
+                issuer_issued_count: 1,
+                receiver: 1,
+                receiver_received_count: 1,
+                expiration: true,
+            },)
+        );
+    });
+}
+
 #[test]
 fn test_cert_period() {
     new_test_ext(DefaultCertificationConfig {
-        certs_by_issuer: btreemap![0 => btreeset![1]],
+        certs_by_issuer: btreemap![0 => btreemap![1 => 10]],
         phantom: core::marker::PhantomData,
     })
     .execute_with(|| {
@@ -61,7 +136,7 @@ fn test_cert_period() {
 #[test]
 fn test_renewable_period() {
     new_test_ext(DefaultCertificationConfig {
-        certs_by_issuer: btreemap![0 => btreeset![1]],
+        certs_by_issuer: btreemap![0 => btreemap![1 => 10]],
         phantom: core::marker::PhantomData,
     })
     .execute_with(|| {
diff --git a/runtime/g1/src/lib.rs b/runtime/g1/src/lib.rs
index ae5cdce9adbdcaab40fafa6f1ae00f7b97a9ed88..822b91855b8afbe5077a02860c8f209bc7dde992 100644
--- a/runtime/g1/src/lib.rs
+++ b/runtime/g1/src/lib.rs
@@ -22,7 +22,7 @@
 #[cfg(feature = "std")]
 include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
 
-mod parameters;
+pub mod parameters;
 
 pub use self::parameters::*;
 pub use common_runtime::{
diff --git a/runtime/gdev/src/lib.rs b/runtime/gdev/src/lib.rs
index e1cefe2068383165ca2108dd0c24c6d133ab5b4d..badbc7991bc3e390aac401688312578e5d98f152 100644
--- a/runtime/gdev/src/lib.rs
+++ b/runtime/gdev/src/lib.rs
@@ -22,7 +22,7 @@
 #[cfg(feature = "std")]
 include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
 
-mod parameters;
+pub mod parameters;
 
 pub use self::parameters::*;
 pub use common_runtime::{
diff --git a/runtime/gtest/src/lib.rs b/runtime/gtest/src/lib.rs
index b7b3900403a90c3e68fd4684c66633e93f7f4172..d1d02aa77e2221b518d12ecfc07ecb3dfa34ce37 100644
--- a/runtime/gtest/src/lib.rs
+++ b/runtime/gtest/src/lib.rs
@@ -22,7 +22,7 @@
 #[cfg(feature = "std")]
 include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
 
-mod parameters;
+pub mod parameters;
 
 pub use self::parameters::*;
 pub use common_runtime::{