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 {