diff --git a/Cargo.lock b/Cargo.lock
index ce368dbec3eb022ab9e7392fd54e1eaf3bebc74f..11408c7aefb898e2108a200d4c23348c8208c1be 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -943,10 +943,12 @@ dependencies = [
  "json-pest-parser 0.2.0",
  "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mockall 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pbr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rules-engine 0.1.0",
  "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/lib/modules-lib/bc-db-reader/src/indexes/identities.rs b/lib/modules-lib/bc-db-reader/src/indexes/identities.rs
index b1067c13e55be570d50bc95622b68651c6f09b7f..80eeddc859c5286e3afaa93d2c733ed7d7d75745 100644
--- a/lib/modules-lib/bc-db-reader/src/indexes/identities.rs
+++ b/lib/modules-lib/bc-db-reader/src/indexes/identities.rs
@@ -135,16 +135,8 @@ pub fn get_identities<DB: BcDbInReadTx>(
     }
 }
 
-/// Get identity by pubkey in databases
-pub fn get_identity_by_pubkey<DB: BcDbInReadTx>(
-    db: &DB,
-    pubkey: &PubKey,
-) -> Result<Option<DbIdentity>, DbError> {
-    get_identity_by_pubkey_(db, pubkey)
-}
-
 /// Get identity by pubkey
-pub fn get_identity_by_pubkey_<DB: BcDbInReadTx>(
+pub fn get_identity_by_pubkey<DB: BcDbInReadTx>(
     db: &DB,
     pubkey: &PubKey,
 ) -> Result<Option<DbIdentity>, DbError> {
@@ -172,16 +164,19 @@ pub fn get_identity_by_wot_id<DB: BcDbInReadTx>(
     }
 }
 
-/// Get uid from pubkey
+/// Get identity state from pubkey
 #[inline]
-pub fn get_uid<DB: BcDbInReadTx>(db: &DB, pubkey: &PubKey) -> Result<Option<String>, DbError> {
-    Ok(get_identity_by_pubkey(db, pubkey)?.map(|db_idty| db_idty.idty_doc.username().to_owned()))
+pub fn get_idty_state_by_pubkey<DB: BcDbInReadTx>(
+    db: &DB,
+    pubkey: &PubKey,
+) -> Result<Option<DbIdentityState>, DbError> {
+    Ok(get_identity_by_pubkey(db, pubkey)?.map(|db_idty| db_idty.state))
 }
 
 /// Get uid from pubkey
 #[inline]
-pub fn get_uid_<DB: BcDbInReadTx>(db: &DB, pubkey: &PubKey) -> Result<Option<String>, DbError> {
-    Ok(get_identity_by_pubkey_(db, pubkey)?.map(|db_idty| db_idty.idty_doc.username().to_owned()))
+pub fn get_uid<DB: BcDbInReadTx>(db: &DB, pubkey: &PubKey) -> Result<Option<String>, DbError> {
+    Ok(get_identity_by_pubkey(db, pubkey)?.map(|db_idty| db_idty.idty_doc.username().to_owned()))
 }
 
 /// Get wot id from uid
diff --git a/lib/modules-lib/bc-db-reader/src/traits.rs b/lib/modules-lib/bc-db-reader/src/traits.rs
index 544a2776707ad5119b51bf696df23f820be4ef4b..bf4a36e737a19770b4142bfc93c97695cc1f61d3 100644
--- a/lib/modules-lib/bc-db-reader/src/traits.rs
+++ b/lib/modules-lib/bc-db-reader/src/traits.rs
@@ -17,6 +17,7 @@
 // ! Define read only trait
 
 use crate::blocks::DbBlock;
+use crate::indexes::identities::{DbIdentity, DbIdentityState};
 use crate::{BcDbWithReaderStruct, DbReadable, DbReader};
 use dubp_common_doc::{BlockNumber, Blockstamp};
 use dup_crypto::keys::PubKey;
@@ -83,15 +84,20 @@ pub trait BcDbInReadTx: BcDbWithReader {
         numbers: Vec<BlockNumber>,
     ) -> Result<Vec<DbBlock>, DbError>;
     fn get_uid_from_pubkey(&self, pubkey: &PubKey) -> Result<Option<String>, DbError>;
+    fn get_idty_state_by_pubkey(&self, pubkey: &PubKey)
+        -> Result<Option<DbIdentityState>, DbError>;
+    fn get_identity_by_pubkey(&self, pubkey: &PubKey) -> Result<Option<DbIdentity>, DbError>;
 }
 
 impl<T> BcDbInReadTx for T
 where
     T: BcDbWithReader + durs_common_tools::traits::NotMock,
 {
+    #[inline]
     fn get_current_blockstamp(&self) -> Result<Option<Blockstamp>, DbError> {
         crate::current_meta_datas::get_current_blockstamp(self)
     }
+    #[inline]
     fn get_current_block(&self) -> Result<Option<DbBlock>, DbError> {
         if let Some(current_blockstamp) = crate::current_meta_datas::get_current_blockstamp(self)? {
             crate::blocks::get_db_block_in_local_blockchain(self, current_blockstamp.id)
@@ -99,6 +105,7 @@ where
             Ok(None)
         }
     }
+    #[inline]
     fn get_db_block_in_local_blockchain(
         &self,
         block_number: BlockNumber,
@@ -106,13 +113,26 @@ where
         crate::blocks::get_db_block_in_local_blockchain(self, block_number)
     }
     #[cfg(feature = "client-indexer")]
+    #[inline]
     fn get_db_blocks_in_local_blockchain(
         &self,
         numbers: Vec<BlockNumber>,
     ) -> Result<Vec<DbBlock>, DbError> {
         crate::blocks::get_blocks_in_local_blockchain_by_numbers(self, numbers)
     }
+    #[inline]
     fn get_uid_from_pubkey(&self, pubkey: &PubKey) -> Result<Option<String>, DbError> {
-        crate::indexes::identities::get_uid_(self, pubkey)
+        crate::indexes::identities::get_uid(self, pubkey)
+    }
+    #[inline]
+    fn get_idty_state_by_pubkey(
+        &self,
+        pubkey: &PubKey,
+    ) -> Result<Option<DbIdentityState>, DbError> {
+        crate::indexes::identities::get_idty_state_by_pubkey(self, pubkey)
+    }
+    #[inline]
+    fn get_identity_by_pubkey(&self, pubkey: &PubKey) -> Result<Option<DbIdentity>, DbError> {
+        crate::indexes::identities::get_identity_by_pubkey(self, pubkey)
     }
 }
diff --git a/lib/modules/blockchain/blockchain/Cargo.toml b/lib/modules/blockchain/blockchain/Cargo.toml
index bf03e517a8cac3cf1beee1e7eaa42eb3b64ece75..278cb2e340d4622557e64dc51f52393e2c51b3b2 100644
--- a/lib/modules/blockchain/blockchain/Cargo.toml
+++ b/lib/modules/blockchain/blockchain/Cargo.toml
@@ -28,9 +28,11 @@ durs-wot = { path = "../../../dubp/wot" }
 failure = "0.1.5"
 json-pest-parser = { path = "../../../tools/json-pest-parser" }
 log = "0.4.*"
+maplit = "1.0.1"
 num_cpus = "1.10.*"
 pbr = "1.0.*"
 rayon = "1.2.0"
+rules-engine = { path = "../../../tools/rules-engine" }
 serde = "1.0.*"
 serde_json = "1.0.*"
 threadpool = "1.7.*"
@@ -41,7 +43,9 @@ unwrap = "1.2.1"
 dup-crypto-tests-tools = { path = "../../../tests-tools/crypto-tests-tools" }
 dubp-user-docs-tests-tools = { path = "../../../tests-tools/user-docs-tests-tools" }
 dubp-blocks-tests-tools = { path = "../../../tests-tools/blocks-tests-tools" }
+durs-bc-db-reader = { path = "../../../modules-lib/bc-db-reader", features = ["mock"] }
 durs-common-tests-tools = { path = "../../../tests-tools/common-tests-tools" }
 maplit = "1.0.1"
+mockall = "0.5.2"
 pretty_assertions = "0.5.1"
 tempfile = "3.1.0"
diff --git a/lib/modules/blockchain/blockchain/src/dubp/check.rs b/lib/modules/blockchain/blockchain/src/dubp/check.rs
index f9a0c14ecf8137dd699a4196364ef6c6cf859ed7..cca4bd56964368932c633ddf685451b9ac3e9103 100644
--- a/lib/modules/blockchain/blockchain/src/dubp/check.rs
+++ b/lib/modules/blockchain/blockchain/src/dubp/check.rs
@@ -25,7 +25,7 @@ use crate::BlockchainModule;
 use dubp_block_doc::block::BlockDocumentTrait;
 use dubp_block_doc::BlockDocument;
 use dubp_common_doc::traits::Document;
-use dubp_common_doc::Blockstamp;
+use dubp_common_doc::{BlockNumber, Blockstamp};
 use durs_bc_db_reader::BcDbInReadTx;
 use durs_common_tools::traits::bool_ext::BoolExt;
 use unwrap::unwrap;
@@ -86,21 +86,28 @@ pub fn check_block<DB: BcDbInReadTx>(
             && unwrap!(block_doc.previous_hash()).to_string()
                 == bc.current_blockstamp.hash.0.to_string())
     {
-        debug!("check_block: block {} chainable!", block_doc.blockstamp());
-
         if bc.cautious_mode {
+            debug!("check_block: block {} chainable!", block_doc.blockstamp());
+
             // Local verification
             local::verify_local_validity_block(block_doc, bc.currency_params)
                 .map_err(CheckBlockError::Local)?;
 
             // Verify block validity (check all protocol rule, very long !)
-            global::verify_global_validity_block(
-                block_doc,
-                db,
-                &bc.wot_index,
-                &bc.wot_databases.wot_db,
-            )
-            .map_err(CheckBlockError::Global)?;
+            if block_doc.number() > BlockNumber(0) {
+                global::verify_global_validity_block(
+                    block_doc,
+                    db,
+                    &bc.wot_index,
+                    &bc.wot_databases.wot_db,
+                )
+                .map_err(CheckBlockError::Global)?;
+            }
+
+            debug!(
+                "check_block: block {} is fully valid.!",
+                block_doc.blockstamp()
+            );
         }
 
         Ok(BlockChainability::FullyValidAndChainableBLock)
diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global.rs
index a3f1d357023a801a03c2d685eefbb460821c8576..5baceee970b57b33b5c294eb65bae345394d6dcb 100644
--- a/lib/modules/blockchain/blockchain/src/dubp/check/global.rs
+++ b/lib/modules/blockchain/blockchain/src/dubp/check/global.rs
@@ -15,6 +15,12 @@
 
 //! Sub-module checking if a block complies with all the rules of the (DUBP DUniter Blockchain Protocol).
 
+mod protocol_versions;
+mod rules;
+
+pub use self::rules::InvalidRuleError;
+
+use self::rules::RuleNotSyncDatas;
 use dubp_block_doc::block::{BlockDocument, BlockDocumentTrait};
 use dubp_common_doc::traits::Document;
 use dubp_common_doc::BlockNumber;
@@ -23,11 +29,13 @@ use durs_bc_db_reader::{BcDbInReadTx, DbError};
 use durs_bc_db_writer::BinFreeStructDb;
 use durs_common_tools::traits::bool_ext::BoolExt;
 use durs_wot::*;
+use rules_engine::{EngineError, ProtocolVersion, RulesEngine};
 use std::collections::HashMap;
 
 #[derive(Debug)]
 pub enum GlobalVerifyBlockError {
     DbError(DbError),
+    InvalidRule(EngineError<InvalidRuleError>),
     NoPreviousBlock,
     VersionDecrease,
 }
@@ -48,25 +56,39 @@ where
     DB: BcDbInReadTx,
     W: WebOfTrust,
 {
-    // Rules that do not concern genesis block
-    if block.number().0 > 0 {
-        // Get previous block
-        let previous_block_opt = durs_bc_db_reader::blocks::get_block_in_local_blockchain(
-            db,
-            BlockNumber(block.number().0 - 1),
-        )?;
+    // Get previous block
+    let previous_block_opt = durs_bc_db_reader::blocks::get_block_in_local_blockchain(
+        db,
+        BlockNumber(block.number().0 - 1),
+    )?;
 
-        // Previous block must exist
-        previous_block_opt
-            .is_some()
-            .or_err(GlobalVerifyBlockError::NoPreviousBlock)?;
-        let previous_block = previous_block_opt.expect("safe unwrap");
+    // Previous block must exist
+    previous_block_opt
+        .is_some()
+        .or_err(GlobalVerifyBlockError::NoPreviousBlock)?;
+    let previous_block = previous_block_opt.expect("safe unwrap");
 
-        // Block version must not decrease
-        (block.version() >= previous_block.version())
-            .or_err(GlobalVerifyBlockError::VersionDecrease)?;
-    }
+    // Block version must not decrease
+    (block.version() >= previous_block.version())
+        .or_err(GlobalVerifyBlockError::VersionDecrease)?;
+
+    // Define rules datas
+    let mut rules_datas = rules::RuleDatas {
+        block,
+        previous_block: &previous_block,
+    };
+    let mut rules_not_sync_datas = RuleNotSyncDatas { db };
+
+    // Apply protocol v10
+    let engine = RulesEngine::new(rules::all_rules::get_all_rules());
+    engine
+        .apply_protocol(
+            protocol_versions::get_blockchain_protocol(),
+            ProtocolVersion(11),
+            &mut rules_datas,
+            &mut rules_not_sync_datas,
+        )
+        .map_err(GlobalVerifyBlockError::InvalidRule)?;
 
-    // TODO BR_G100 - issuerIsMember
     Ok(())
 }
diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions.rs
new file mode 100644
index 0000000000000000000000000000000000000000..87a62b6b3453160d3d0f5bba1f858342e447b781
--- /dev/null
+++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions.rs
@@ -0,0 +1,27 @@
+//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Sub-module manage blockchain protocol versions.
+
+mod v11;
+
+use rules_engine::{Protocol, ProtocolVersion};
+
+#[inline]
+pub fn get_blockchain_protocol() -> Protocol {
+    Protocol::new(maplit::btreemap![
+        ProtocolVersion(11) => v11::get_protocol_rules()
+    ])
+}
diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions/v11.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions/v11.rs
new file mode 100644
index 0000000000000000000000000000000000000000..aae07a8d47a9e0edfbb01be9494a06d74796ca6d
--- /dev/null
+++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions/v11.rs
@@ -0,0 +1,23 @@
+//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! List of rules applied for blockchain protocol V11.
+
+use rules_engine::{ProtocolRules, RulesGroup};
+
+#[inline]
+pub fn get_protocol_rules() -> ProtocolRules {
+    vec![RulesGroup::ser(vec![3usize, 100])].into()
+}
diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global/rules.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules.rs
new file mode 100644
index 0000000000000000000000000000000000000000..5010748ee4da5799a645a2318395fd7f7b196bed
--- /dev/null
+++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules.rs
@@ -0,0 +1,66 @@
+//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Sub-module define rules engine
+
+pub mod all_rules;
+mod br_g03;
+mod br_g100;
+
+use dubp_block_doc::BlockDocument;
+//use dup_crypto::keys::PubKey;
+use durs_bc_db_reader::indexes::identities::DbIdentityState;
+use durs_bc_db_reader::{BcDbInReadTx, DbError};
+//use durs_wot::*;
+use failure::Fail;
+//use std::collections::HashMap;
+
+#[derive(Debug)]
+pub struct RuleDatas<'a> {
+    pub(crate) block: &'a BlockDocument,
+    pub(crate) previous_block: &'a BlockDocument,
+    //db: &'a Db,
+    //wot_db: &BinFreeStructDb<W>,
+    //wot_index: HashMap<PubKey, NodeId>,
+    //current_frame: Option<HashMap<PubKey, usize>>,
+}
+
+pub struct RuleNotSyncDatas<'db, DB: BcDbInReadTx> {
+    pub(crate) db: &'db DB,
+}
+
+#[derive(Clone, Debug, Eq, Fail, PartialEq)]
+pub enum InvalidRuleError {
+    #[fail(display = "Database error: {:?}", _0)]
+    DbError(String),
+    #[fail(display = "BR_G99: different currency")]
+    _DifferentCurrency,
+    #[fail(display = "BR_G03: wrong previous issuer")]
+    WrongPreviousIssuer,
+    #[fail(display = "BR_G100: issuer is not a member (not exist)")]
+    IssuerNotExist,
+    #[fail(display = "BR_G100: issuer is not a member (issuer_state={:?})", _0)]
+    NotMemberIssuer(DbIdentityState),
+    #[fail(display = "BR_G04: wrong issuers count")]
+    _WrongIssuersCount,
+    #[fail(display = "BR_G05: wrong issuers frame size")]
+    _WrongIssuersFrame,
+}
+
+impl From<DbError> for InvalidRuleError {
+    fn from(e: DbError) -> Self {
+        Self::DbError(format!("{:?}", e))
+    }
+}
diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/all_rules.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/all_rules.rs
new file mode 100644
index 0000000000000000000000000000000000000000..c8938f46f28d34b30a70879724600f07b96f0fa4
--- /dev/null
+++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/all_rules.rs
@@ -0,0 +1,33 @@
+//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Sub-module define all rules of blockchain protocol.
+
+use super::br_g03;
+use super::br_g100;
+use super::{RuleDatas, RuleNotSyncDatas};
+use crate::dubp::check::global::rules::InvalidRuleError;
+use durs_bc_db_reader::BcDbInReadTx;
+use rules_engine::rule::{Rule, RuleNumber};
+use std::collections::BTreeMap;
+
+#[inline]
+pub fn get_all_rules<'d, 'db, DB: BcDbInReadTx>(
+) -> BTreeMap<RuleNumber, Rule<RuleDatas<'d>, RuleNotSyncDatas<'db, DB>, InvalidRuleError>> {
+    maplit::btreemap![
+        RuleNumber(3) => br_g03::rule(),
+        RuleNumber(100) => br_g100::rule(),
+    ]
+}
diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/br_g03.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/br_g03.rs
new file mode 100644
index 0000000000000000000000000000000000000000..9fbe8af18f0b2cb5974fad494d67dec6aff18b32
--- /dev/null
+++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/br_g03.rs
@@ -0,0 +1,50 @@
+//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Rule BR_G03 - previousIssuer
+
+use super::{InvalidRuleError, RuleDatas, RuleNotSyncDatas};
+use dubp_block_doc::BlockDocument;
+use durs_bc_db_reader::BcDbInReadTx;
+use durs_common_tools::traits::bool_ext::BoolExt;
+use rules_engine::rule::{Rule, RuleFn, RuleNumber};
+use rules_engine::ProtocolVersion;
+use unwrap::unwrap;
+
+#[inline]
+pub fn rule<'d, 'db, DB: BcDbInReadTx>(
+) -> Rule<RuleDatas<'d>, RuleNotSyncDatas<'db, DB>, InvalidRuleError> {
+    unwrap!(Rule::new(
+        RuleNumber(3),
+        maplit::btreemap![
+            ProtocolVersion(10) => RuleFn::Ref(v10),
+        ]
+    ))
+}
+
+fn v10(rule_datas: &RuleDatas) -> Result<(), InvalidRuleError> {
+    let RuleDatas {
+        ref block,
+        ref previous_block,
+        ..
+    } = rule_datas;
+    let BlockDocument::V10(ref block) = block;
+    let BlockDocument::V10(ref previous_block) = previous_block;
+
+    (Some(previous_block.issuers[0]) == block.previous_issuer)
+        .or_err(InvalidRuleError::WrongPreviousIssuer)?;
+
+    Ok(())
+}
diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/br_g100.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/br_g100.rs
new file mode 100644
index 0000000000000000000000000000000000000000..3cb201dfc9dc1fb0ab8af38b06690dc47938dd4b
--- /dev/null
+++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/br_g100.rs
@@ -0,0 +1,111 @@
+//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+//! Rule BR_G100 - issuerIsMember
+
+use super::{InvalidRuleError, RuleDatas, RuleNotSyncDatas};
+use dubp_common_doc::traits::Document;
+use durs_bc_db_reader::indexes::identities::DbIdentityState;
+use durs_bc_db_reader::BcDbInReadTx;
+use rules_engine::rule::{Rule, RuleFn, RuleNumber};
+use rules_engine::ProtocolVersion;
+use unwrap::unwrap;
+
+#[inline]
+pub fn rule<'d, 'db, DB: BcDbInReadTx>(
+) -> Rule<RuleDatas<'d>, RuleNotSyncDatas<'db, DB>, InvalidRuleError> {
+    unwrap!(Rule::new(
+        RuleNumber(100),
+        maplit::btreemap![
+            ProtocolVersion(10) => RuleFn::RefMut(v10),
+        ]
+    ))
+}
+
+fn v10<DB: BcDbInReadTx>(
+    datas: &mut RuleDatas,
+    not_sync_datas: &mut RuleNotSyncDatas<DB>,
+) -> Result<(), InvalidRuleError> {
+    let RuleDatas { ref block, .. } = datas;
+    let RuleNotSyncDatas { ref db } = not_sync_datas;
+
+    if let Some(idty_state) = db.get_idty_state_by_pubkey(&block.issuers()[0])? {
+        if let DbIdentityState::Member(_) = idty_state {
+            Ok(())
+        } else {
+            Err(InvalidRuleError::NotMemberIssuer(idty_state))
+        }
+    } else {
+        Err(InvalidRuleError::IssuerNotExist)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+    use dubp_block_doc::BlockDocument;
+    use durs_bc_db_reader::MockBcDbInReadTx;
+    use mockall::predicate::eq;
+
+    #[test]
+    fn test_br_g100_issuer_not_exist() {
+        let pubkey = dup_crypto_tests_tools::mocks::pubkey('A');
+        let block = BlockDocument::V10(dubp_blocks_tests_tools::mocks::gen_empty_issued_block_v10(
+            pubkey,
+        ));
+
+        let mut mock_db = MockBcDbInReadTx::new();
+        mock_db
+            .expect_get_idty_state_by_pubkey()
+            .times(1)
+            .with(eq(pubkey))
+            .returning(|_| Ok(None));
+
+        let mut datas = RuleDatas {
+            block: &block,
+            previous_block: &block,
+        };
+        let mut not_sync_datas = RuleNotSyncDatas { db: &mock_db };
+
+        assert_eq!(
+            Err(InvalidRuleError::IssuerNotExist),
+            v10(&mut datas, &mut not_sync_datas)
+        )
+    }
+
+    #[test]
+    fn test_br_g100_issuer_is_member() {
+        let pubkey = dup_crypto_tests_tools::mocks::pubkey('A');
+        let block = BlockDocument::V10(dubp_blocks_tests_tools::mocks::gen_empty_issued_block_v10(
+            pubkey,
+        ));
+
+        let mut mock_db = MockBcDbInReadTx::new();
+        mock_db
+            .expect_get_idty_state_by_pubkey()
+            .times(1)
+            .with(eq(pubkey))
+            .returning(|_| Ok(Some(DbIdentityState::Member(vec![1]))));
+
+        let mut datas = RuleDatas {
+            block: &block,
+            previous_block: &block,
+        };
+        let mut not_sync_datas = RuleNotSyncDatas { db: &mock_db };
+
+        assert_eq!(Ok(()), v10(&mut datas, &mut not_sync_datas))
+    }
+}
diff --git a/lib/modules/blockchain/blockchain/tests/apply_blocks_cautious.rs b/lib/modules/blockchain/blockchain/tests/apply_blocks_cautious.rs
new file mode 100644
index 0000000000000000000000000000000000000000..cb2bbbf4e1e80a7258cd2199f9c25e8bc58eea8d
--- /dev/null
+++ b/lib/modules/blockchain/blockchain/tests/apply_blocks_cautious.rs
@@ -0,0 +1,131 @@
+//  Copyright (C) 2017-2019  The AXIOM TEAM Association.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+mod common;
+
+use crate::common::*;
+use dubp_block_doc::BlockDocument;
+use dubp_currency_params::genesis_block_params::v10::BlockV10Parameters;
+use durs_blockchain::BlockchainModule;
+use durs_message::events::{BlockchainEvent, DursEvent};
+use durs_message::requests::DursReqContent;
+use durs_message::DursMsg;
+use durs_module::{
+    ModuleEvent, ModuleReqFullId, ModuleReqId, ModuleRole, ModuleStaticName, RouterThreadMessage,
+};
+use durs_network::events::NetworkEvent;
+use durs_network::requests::OldNetworkRequest;
+use pretty_assertions::assert_eq;
+use std::sync::mpsc::{channel, Receiver, Sender};
+
+#[cfg(unix)]
+#[test]
+fn test_apply_blocks_cautious() {
+    // Init test
+    let tmp_profile_path = common::init();
+
+    // Router channel
+    let (router_sender, router_receiver) = channel(); // RouterThreadMessage<DursMsg>
+
+    let genesis_params = BlockV10Parameters::default();
+
+    let mut bc = init_bc_module(
+        router_sender,
+        genesis_params,
+        tmp_profile_path.as_path(),
+        true,
+    );
+
+    // Create blockchain module channel
+    let (bc_sender, bc_receiver): (Sender<DursMsg>, Receiver<DursMsg>) = channel();
+
+    let handle = std::thread::spawn(move || {
+        bc.start_blockchain(&bc_receiver, None);
+    });
+
+    // Receive 11 requests GetBlocks
+    for i in 0..11 {
+        let msg = router_receiver
+            .recv()
+            .expect("blockchain module disconnected.");
+        if let RouterThreadMessage::ModuleMessage(durs_msg) = msg {
+            assert_eq!(
+                DursMsg::Request {
+                    req_from: BlockchainModule::name(),
+                    req_to: ModuleRole::InterNodesNetwork,
+                    req_id: ModuleReqId(i),
+                    req_content: DursReqContent::OldNetworkRequest(OldNetworkRequest::GetBlocks(
+                        ModuleReqFullId(BlockchainModule::name(), ModuleReqId(i)),
+                        50,
+                        i * 50
+                    )),
+                },
+                durs_msg
+            );
+            log::info!("Router receive: {:?}", durs_msg);
+        } else {
+            panic!("Expect ModuleMesage, found: {:?}", msg)
+        }
+    }
+
+    // Receive first g1-test chunk
+    let gt_chunk_0 = dubp_blocks_tests_tools::gt::get_gt_chunk(0);
+    receive_valid_blocks(&bc_sender, &router_receiver, gt_chunk_0);
+
+    // Receive second g1-test chunk
+    let gt_chunk_1 = dubp_blocks_tests_tools::gt::get_gt_chunk(1);
+    receive_valid_blocks(&bc_sender, &router_receiver, gt_chunk_1);
+
+    // Receive third g1-test chunk
+    let gt_chunk_2 = dubp_blocks_tests_tools::gt::get_gt_chunk(2);
+    receive_valid_blocks(&bc_sender, &router_receiver, gt_chunk_2);
+
+    // Stop and clean
+    common::stop_and_clean(bc_sender, handle, tmp_profile_path);
+}
+
+fn receive_valid_blocks(
+    bc_sender: &Sender<DursMsg>,
+    router_receiver: &Receiver<RouterThreadMessage<DursMsg>>,
+    blocks: Vec<BlockDocument>,
+) {
+    bc_sender
+        .send(DursMsg::Event {
+            event_from: ModuleStaticName("toto"),
+            event_type: ModuleEvent::NewBlockFromNetwork,
+            event_content: DursEvent::NetworkEvent(NetworkEvent::ReceiveBlocks(blocks.clone())),
+        })
+        .expect("Fail to send blocks to blockchain module.");
+    for block in blocks {
+        let msg = router_receiver
+            .recv()
+            .expect("blockchain module disconnected.");
+        if let RouterThreadMessage::ModuleMessage(durs_msg) = msg {
+            assert_eq!(
+                DursMsg::Event {
+                    event_from: ModuleStaticName("blockchain"),
+                    event_type: ModuleEvent::NewValidBlock,
+                    event_content: DursEvent::BlockchainEvent(Box::new(
+                        BlockchainEvent::StackUpValidBlock(Box::new(block))
+                    )),
+                },
+                durs_msg
+            );
+        //log::debug!("Router receive: {:?}", msg);
+        } else {
+            panic!("Expect ModuleMesage, found: {:?}", msg)
+        }
+    }
+}
diff --git a/lib/modules/blockchain/blockchain/tests/common.rs b/lib/modules/blockchain/blockchain/tests/common.rs
index 21ed4455372f50f47e1a7bffc3d953b9b914dd0b..35e5549d3b61ab16ab5aaaba1a10db0551532bed 100644
--- a/lib/modules/blockchain/blockchain/tests/common.rs
+++ b/lib/modules/blockchain/blockchain/tests/common.rs
@@ -55,9 +55,9 @@ pub fn init_bc_module(
     fake_router_sender: Sender<RouterThreadMessage<DursMsg>>,
     genesis_block_parameters: BlockV10Parameters,
     tmp_path: &Path,
+    cautious_mode: bool,
 ) -> BlockchainModule {
     let currency_name = CurrencyName(TEST_CURRENCY.to_owned());
-    let cautious_mode = false;
     //let profile_path = tmp_profile_path.to_owned();
 
     //let dbs_path = durs_conf::get_blockchain_db_path(profile_path.clone());
diff --git a/lib/modules/blockchain/blockchain/tests/revert_blocks.rs b/lib/modules/blockchain/blockchain/tests/revert_blocks.rs
index d966a7b661a275db6533dfb7cadcc4b688bb34ba..734aad9e0413c3f0132043b7a27135420919ccd5 100644
--- a/lib/modules/blockchain/blockchain/tests/revert_blocks.rs
+++ b/lib/modules/blockchain/blockchain/tests/revert_blocks.rs
@@ -34,7 +34,7 @@ use std::sync::mpsc::{channel, Receiver, Sender};
 
 #[cfg(unix)]
 #[test]
-fn test_revert_block() {
+fn test_revert_blocks() {
     // Init test
     let tmp_profile_path = common::init();
 
@@ -43,7 +43,12 @@ fn test_revert_block() {
 
     let genesis_params = BlockV10Parameters::default();
 
-    let mut bc = init_bc_module(router_sender, genesis_params, tmp_profile_path.as_path());
+    let mut bc = init_bc_module(
+        router_sender,
+        genesis_params,
+        tmp_profile_path.as_path(),
+        false,
+    );
 
     // Create blockchain module channel
     let (bc_sender, bc_receiver): (Sender<DursMsg>, Receiver<DursMsg>) = channel();
diff --git a/lib/tests-tools/blocks-tests-tools/src/mocks.rs b/lib/tests-tools/blocks-tests-tools/src/mocks.rs
index ad83d12825b5f1a4bf5ae820596d708caabbff93..c7f281efcef1d02dc0803540b6b7ac3bcf604ced 100644
--- a/lib/tests-tools/blocks-tests-tools/src/mocks.rs
+++ b/lib/tests-tools/blocks-tests-tools/src/mocks.rs
@@ -100,6 +100,14 @@ pub fn gen_empty_timed_block_v10(
     block
 }
 
+/// Generate empty issued block document
+/// (usefull for tests that only need issuer field)
+pub fn gen_empty_issued_block_v10(issuer: PubKey) -> BlockDocumentV10 {
+    let mut block = gen_empty_block_v10(BlockNumber(0));
+    block.issuers = vec![issuer];
+    block
+}
+
 fn gen_empty_block_v10(block_number: BlockNumber) -> BlockDocumentV10 {
     BlockDocumentV10 {
         version: 10,
diff --git a/lib/tools/rules-engine/src/lib.rs b/lib/tools/rules-engine/src/lib.rs
index 800711925a897ea2a5577ee33aa3c1d93240cae9..b9d23fc3924b8ccdae1f7cd72f666edfb94756a7 100644
--- a/lib/tools/rules-engine/src/lib.rs
+++ b/lib/tools/rules-engine/src/lib.rs
@@ -91,6 +91,11 @@ impl RulesGroup {
         RulesGroup::Ser(vec![RuleNumber(rule_number)])
     }
     #[inline]
+    /// Create serial set of rules
+    pub fn ser(rules_numbers: Vec<usize>) -> Self {
+        RulesGroup::Ser(rules_numbers.into_iter().map(|n| RuleNumber(n)).collect())
+    }
+    #[inline]
     /// Create parallel set of rules
     pub fn pr(rules_numbers: Vec<usize>) -> Self {
         RulesGroup::Par(rules_numbers.into_iter().map(RulesGroup::s1).collect())
@@ -98,14 +103,14 @@ impl RulesGroup {
 }
 
 /// Rules engine
-pub struct RulesEngine<D: Debug + Sync, E: Eq + Fail + PartialEq> {
+pub struct RulesEngine<D: Sync, DNotSync, E: Eq + Fail + PartialEq> {
     /// All rules
-    all_rules: BTreeMap<RuleNumber, Rule<D, E>>,
+    all_rules: BTreeMap<RuleNumber, Rule<D, DNotSync, E>>,
 }
 
-impl<D: Debug + Sync, E: Eq + Fail + PartialEq> RulesEngine<D, E> {
+impl<D: Sync, DNotSync, E: Eq + Fail + PartialEq> RulesEngine<D, DNotSync, E> {
     /// Create new rules engine
-    pub fn new(all_rules: BTreeMap<RuleNumber, Rule<D, E>>) -> Self {
+    pub fn new(all_rules: BTreeMap<RuleNumber, Rule<D, DNotSync, E>>) -> Self {
         RulesEngine { all_rules }
     }
 
@@ -148,9 +153,15 @@ impl<D: Debug + Sync, E: Eq + Fail + PartialEq> RulesEngine<D, E> {
         protocol_version: ProtocolVersion,
         rule_number: RuleNumber,
         rule_datas: &mut D,
+        rule_datas_not_sync: &mut DNotSync,
     ) -> Result<(), EngineError<E>> {
         if let Some(rule) = self.all_rules.get(&rule_number) {
-            rule.execute_mut(protocol_version, rule_number, rule_datas)
+            rule.execute_mut(
+                protocol_version,
+                rule_number,
+                rule_datas,
+                rule_datas_not_sync,
+            )
         } else {
             Err(EngineError::RuleNotExist {
                 rule_number,
@@ -165,6 +176,7 @@ impl<D: Debug + Sync, E: Eq + Fail + PartialEq> RulesEngine<D, E> {
         protocol: Protocol,
         protocol_version: ProtocolVersion,
         rule_datas: &mut D,
+        rule_datas_not_sync: &mut DNotSync,
     ) -> Result<(), EngineError<E>> {
         if let Some(protocol_rules) = protocol.get(protocol_version) {
             for rules_group in &protocol_rules.0 {
@@ -172,7 +184,12 @@ impl<D: Debug + Sync, E: Eq + Fail + PartialEq> RulesEngine<D, E> {
                     RulesGroup::Ser(rules_numbers) => rules_numbers
                         .iter()
                         .map(|rule_number| {
-                            self.apply_rule_mut(protocol_version, *rule_number, rule_datas)
+                            self.apply_rule_mut(
+                                protocol_version,
+                                *rule_number,
+                                rule_datas,
+                                rule_datas_not_sync,
+                            )
                         })
                         .collect(),
                     RulesGroup::Par(rules_group) => rules_group
@@ -254,12 +271,17 @@ mod tests {
         i: usize,
     }
 
+    #[derive(Debug)]
+    struct DatasNotSync {
+        j: usize,
+    }
+
     #[derive(Debug, Eq, Fail, PartialEq)]
     #[fail(display = "")]
     struct Error {}
 
-    fn r2_v1(datas: &mut Datas) -> Result<(), Error> {
-        if datas.i == 0 {
+    fn r2_v1(datas: &mut Datas, datas_not_sync: &mut DatasNotSync) -> Result<(), Error> {
+        if datas.i == 0 && datas_not_sync.j < 2 {
             datas.i += 1;
             Ok(())
         } else {
@@ -275,8 +297,8 @@ mod tests {
         }
     }
 
-    fn get_test_engine() -> RulesEngine<Datas, Error> {
-        let all_rules: BTreeMap<RuleNumber, Rule<Datas, Error>> = btreemap![
+    fn get_test_engine() -> RulesEngine<Datas, DatasNotSync, Error> {
+        let all_rules: BTreeMap<RuleNumber, Rule<Datas, DatasNotSync, Error>> = btreemap![
             RuleNumber(2) => Rule::new(RuleNumber(2), btreemap![
                 ProtocolVersion(1) => RuleFn::RefMut(r2_v1),
             ]).expect("Fail to create rule n°2"),
@@ -290,7 +312,7 @@ mod tests {
 
     #[test]
     fn rule_without_impl() {
-        if let Err(err) = Rule::<Datas, Error>::new(RuleNumber(1), btreemap![]) {
+        if let Err(err) = Rule::<Datas, DatasNotSync, Error>::new(RuleNumber(1), btreemap![]) {
             assert_eq!(
                 RuleWithoutImpl {
                     rule_number: RuleNumber(1),
@@ -310,12 +332,18 @@ mod tests {
         let engine = get_test_engine();
 
         let mut datas = Datas { i: 0 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol_empty: Protocol = Protocol::new(btreemap![
             ProtocolVersion(1) => Vec::<usize>::with_capacity(0).into()
         ]);
 
-        engine.apply_protocol(protocol_empty, ProtocolVersion(1), &mut datas)
+        engine.apply_protocol(
+            protocol_empty,
+            ProtocolVersion(1),
+            &mut datas,
+            &mut datas_not_sync,
+        )
     }
 
     #[test]
@@ -323,6 +351,7 @@ mod tests {
         let engine = get_test_engine();
 
         let mut datas = Datas { i: 0 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol_empty: Protocol = Protocol::new(btreemap![
             ProtocolVersion(1) => Vec::<usize>::with_capacity(0).into()
@@ -332,7 +361,12 @@ mod tests {
             Err(EngineError::ProtocolVersionNotExist {
                 protocol_version: ProtocolVersion(2),
             }),
-            engine.apply_protocol(protocol_empty, ProtocolVersion(2), &mut datas)
+            engine.apply_protocol(
+                protocol_empty,
+                ProtocolVersion(2),
+                &mut datas,
+                &mut datas_not_sync
+            )
         )
     }
 
@@ -341,6 +375,7 @@ mod tests {
         let engine = get_test_engine();
 
         let mut datas = Datas { i: 0 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol: Protocol = Protocol::new(btreemap![
             ProtocolVersion(1) => vec![1usize].into()
@@ -351,10 +386,16 @@ mod tests {
                 rule_number: RuleNumber(1),
                 protocol_version: ProtocolVersion(1)
             }),
-            engine.apply_protocol(protocol, ProtocolVersion(1), &mut datas)
+            engine.apply_protocol(
+                protocol,
+                ProtocolVersion(1),
+                &mut datas,
+                &mut datas_not_sync
+            )
         );
 
         let mut datas = Datas { i: 0 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol_par: Protocol = Protocol::new(btreemap![
             ProtocolVersion(1) => vec![RulesGroup::pr(vec![1usize])].into()
@@ -365,7 +406,12 @@ mod tests {
                 rule_number: RuleNumber(1),
                 protocol_version: ProtocolVersion(1)
             }),
-            engine.apply_protocol(protocol_par, ProtocolVersion(1), &mut datas)
+            engine.apply_protocol(
+                protocol_par,
+                ProtocolVersion(1),
+                &mut datas,
+                &mut datas_not_sync
+            )
         );
     }
 
@@ -374,6 +420,7 @@ mod tests {
         let engine = get_test_engine();
 
         let mut datas = Datas { i: 1 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol: Protocol = Protocol::new(btreemap![
             ProtocolVersion(1) => vec![2usize].into()
@@ -384,7 +431,12 @@ mod tests {
                 rule_number: RuleNumber(2),
                 cause: Error {},
             })),
-            engine.apply_protocol(protocol, ProtocolVersion(1), &mut datas)
+            engine.apply_protocol(
+                protocol,
+                ProtocolVersion(1),
+                &mut datas,
+                &mut datas_not_sync
+            )
         )
     }
 
@@ -393,6 +445,7 @@ mod tests {
         let engine = get_test_engine();
 
         let mut datas = Datas { i: 0 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol: Protocol = Protocol::new(btreemap![
             ProtocolVersion(2) => vec![RulesGroup::pr(vec![3usize])].into()
@@ -403,7 +456,12 @@ mod tests {
                 rule_number: RuleNumber(3),
                 cause: Error {},
             })),
-            engine.apply_protocol(protocol, ProtocolVersion(2), &mut datas)
+            engine.apply_protocol(
+                protocol,
+                ProtocolVersion(2),
+                &mut datas,
+                &mut datas_not_sync
+            )
         )
     }
 
@@ -412,6 +470,7 @@ mod tests {
         let engine = get_test_engine();
 
         let mut datas = Datas { i: 0 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol: Protocol = Protocol::new(btreemap![
             ProtocolVersion(1) => vec![2usize, 3].into()
@@ -422,7 +481,12 @@ mod tests {
                 protocol_version: ProtocolVersion(1),
                 rule_number: RuleNumber(3),
             }),
-            engine.apply_protocol(protocol, ProtocolVersion(1), &mut datas)
+            engine.apply_protocol(
+                protocol,
+                ProtocolVersion(1),
+                &mut datas,
+                &mut datas_not_sync
+            )
         )
     }
 
@@ -431,6 +495,7 @@ mod tests {
         let engine = get_test_engine();
 
         let mut datas = Datas { i: 0 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol: Protocol = Protocol::new(btreemap![
             ProtocolVersion(1) => vec![RulesGroup::pr(vec![3])].into()
@@ -441,7 +506,12 @@ mod tests {
                 protocol_version: ProtocolVersion(1),
                 rule_number: RuleNumber(3),
             }),
-            engine.apply_protocol(protocol, ProtocolVersion(1), &mut datas)
+            engine.apply_protocol(
+                protocol,
+                ProtocolVersion(1),
+                &mut datas,
+                &mut datas_not_sync
+            )
         )
     }
 
@@ -450,6 +520,7 @@ mod tests {
         let engine = get_test_engine();
 
         let mut datas = Datas { i: 1 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol: Protocol = Protocol::new(btreemap![
             ProtocolVersion(2) => vec![RulesGroup::pr(vec![2usize, 3])].into()
@@ -460,7 +531,12 @@ mod tests {
                 protocol_version: ProtocolVersion(2),
                 rule_number: RuleNumber(2),
             }),
-            engine.apply_protocol(protocol, ProtocolVersion(2), &mut datas)
+            engine.apply_protocol(
+                protocol,
+                ProtocolVersion(2),
+                &mut datas,
+                &mut datas_not_sync
+            )
         )
     }
 
@@ -469,11 +545,17 @@ mod tests {
         let engine = get_test_engine();
 
         let mut datas = Datas { i: 0 };
+        let mut datas_not_sync = DatasNotSync { j: 1 };
 
         let protocol: Protocol = Protocol::new(btreemap![
             ProtocolVersion(2) => vec![2usize, 3].into()
         ]);
 
-        engine.apply_protocol(protocol, ProtocolVersion(2), &mut datas)
+        engine.apply_protocol(
+            protocol,
+            ProtocolVersion(2),
+            &mut datas,
+            &mut datas_not_sync,
+        )
     }
 }
diff --git a/lib/tools/rules-engine/src/rule.rs b/lib/tools/rules-engine/src/rule.rs
index 62dfd220f3ad79c159a707da72c3de51fe84267f..0a164415cb713f3c36875503e6766dbd96dd8d90 100644
--- a/lib/tools/rules-engine/src/rule.rs
+++ b/lib/tools/rules-engine/src/rule.rs
@@ -44,12 +44,12 @@ pub struct RuleError<E: Eq + Fail + PartialEq> {
 pub type RuleFnRef<D, E> = fn(&D) -> Result<(), E>;
 
 /// Rule mutable execution function
-pub type RuleFnRefMut<D, E> = fn(&mut D) -> Result<(), E>;
+pub type RuleFnRefMut<D, DNotSync, E> = fn(&mut D, &mut DNotSync) -> Result<(), E>;
 
 /// Rule execution function
-pub enum RuleFn<D, E> {
+pub enum RuleFn<D, DNotSync, E> {
     Ref(RuleFnRef<D, E>),
-    RefMut(RuleFnRefMut<D, E>),
+    RefMut(RuleFnRefMut<D, DNotSync, E>),
 }
 
 #[derive(Debug, Copy, Clone, Eq, Fail, PartialEq)]
@@ -62,16 +62,16 @@ pub struct RuleWithoutImpl {
 }
 
 /// Rule
-pub struct Rule<D: Debug, E: Eq + Fail + PartialEq> {
+pub struct Rule<D, DNotSync, E: Eq + Fail + PartialEq> {
     /// Dictionary of the different versions of the rule execution function
-    rule_versions: BTreeMap<ProtocolVersion, RuleFn<D, E>>,
+    rule_versions: BTreeMap<ProtocolVersion, RuleFn<D, DNotSync, E>>,
 }
 
-impl<D: Debug, E: Eq + Fail + PartialEq> Rule<D, E> {
+impl<D, DNotSync, E: Eq + Fail + PartialEq> Rule<D, DNotSync, E> {
     /// Create new rule
     pub fn new(
         rule_number: RuleNumber,
-        rule_versions: BTreeMap<ProtocolVersion, RuleFn<D, E>>,
+        rule_versions: BTreeMap<ProtocolVersion, RuleFn<D, DNotSync, E>>,
     ) -> Result<Self, RuleWithoutImpl> {
         if rule_versions.is_empty() {
             Err(RuleWithoutImpl { rule_number })
@@ -86,7 +86,7 @@ impl<D: Debug, E: Eq + Fail + PartialEq> Rule<D, E> {
         rule_number: RuleNumber,
         rule_datas: &D,
     ) -> Result<(), EngineError<E>> {
-        let rule_opt: Option<(&ProtocolVersion, &RuleFn<D, E>)> =
+        let rule_opt: Option<(&ProtocolVersion, &RuleFn<D, DNotSync, E>)> =
             self.rule_versions.range(..=protocol_version).last();
         if let Some((_, rule_fn)) = rule_opt {
             match rule_fn {
@@ -114,13 +114,14 @@ impl<D: Debug, E: Eq + Fail + PartialEq> Rule<D, E> {
         protocol_version: ProtocolVersion,
         rule_number: RuleNumber,
         rule_datas: &mut D,
+        rule_datas_not_sync: &mut DNotSync,
     ) -> Result<(), EngineError<E>> {
-        let rule_opt: Option<(&ProtocolVersion, &RuleFn<D, E>)> =
+        let rule_opt: Option<(&ProtocolVersion, &RuleFn<D, DNotSync, E>)> =
             self.rule_versions.range(..=protocol_version).last();
         if let Some((_, rule_fn)) = rule_opt {
             match rule_fn {
                 RuleFn::Ref(rule_fn_ref) => rule_fn_ref(rule_datas),
-                RuleFn::RefMut(rule_fn_ref_mut) => rule_fn_ref_mut(rule_datas),
+                RuleFn::RefMut(rule_fn_ref_mut) => rule_fn_ref_mut(rule_datas, rule_datas_not_sync),
             }
             .map_err(|err| {
                 EngineError::RuleError(RuleError {