From 6a1ffdcf5fbd1b47b6ff96c19547ee2f4e7a99c3 Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Mon, 22 Apr 2019 21:02:48 +0200 Subject: [PATCH] wip: [ref] blockchain:dubp:use rules engine --- Cargo.lock | 18 +++++++ lib/modules/blockchain/blockchain/Cargo.toml | 4 ++ .../blockchain/src/dubp/check/global/mod.rs | 18 ++----- .../check/global/protocol_versions/mod.rs | 27 ++++++++++ .../check/global/protocol_versions/v11.rs | 23 +++++++++ .../src/dubp/check/global/rules/all_rules.rs | 36 ++++++++++++++ .../src/dubp/check/global/rules/br_g03.rs | 45 +++++++++++++++++ .../src/dubp/check/global/rules/mod.rs | 49 +++++++++++++++++++ lib/modules/blockchain/blockchain/src/lib.rs | 3 +- 9 files changed, 208 insertions(+), 15 deletions(-) create mode 100644 lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions/mod.rs create mode 100644 lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions/v11.rs create mode 100644 lib/modules/blockchain/blockchain/src/dubp/check/global/rules/all_rules.rs create mode 100644 lib/modules/blockchain/blockchain/src/dubp/check/global/rules/br_g03.rs create mode 100644 lib/modules/blockchain/blockchain/src/dubp/check/global/rules/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 87cbd1b2..0b88cbeb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -393,12 +393,15 @@ dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "json-pest-parser 0.1.0", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "pbr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rules-engine 0.1.0", "serde 1.0.86 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unwrap 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1079,6 +1082,15 @@ name = "rprompt" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rules-engine" +version = "0.1.0" +dependencies = [ + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rust-crypto-wasm" version = "0.3.1" @@ -1368,6 +1380,11 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "unwrap" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "url" version = "1.7.2" @@ -1583,6 +1600,7 @@ dependencies = [ "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +"checksum unwrap 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e33648dd74328e622c7be51f3b40a303c63f93e6fa5f08778b6203a4c25c20f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" "checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" diff --git a/lib/modules/blockchain/blockchain/Cargo.toml b/lib/modules/blockchain/blockchain/Cargo.toml index 5cfd27b8..4ba19159 100644 --- a/lib/modules/blockchain/blockchain/Cargo.toml +++ b/lib/modules/blockchain/blockchain/Cargo.toml @@ -23,13 +23,17 @@ duniter-network = { path = "../../../core/network" } durs-wot = { path = "../../../tools/wot" } failure = "0.1.5" json-pest-parser = { path = "../../../tools/json-pest-parser" } +lazy_static = "1.3.0" log = "0.4.*" +maplit = "1.0.1" num_cpus = "1.8.*" pbr = "1.0.*" rayon = "1.0.3" +rules-engine = { path = "../../../tools/rules-engine" } serde = "1.0.*" serde_json = "1.0.*" threadpool = "1.7.*" +unwrap = "1.2.1" [dev-dependencies] dup-crypto-tests-tools = { path = "../../../tests-tools/crypto-tests-tools" } diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global/mod.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global/mod.rs index f9be5665..6ec5b6da 100644 --- a/lib/modules/blockchain/blockchain/src/dubp/check/global/mod.rs +++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/mod.rs @@ -15,6 +15,9 @@ //! Sub-module checking if a block complies with all the rules of the (DUBP DUniter Blockchain Protocol). +mod protocol_versions; +mod rules; + use super::InvalidBlockError; use crate::dubp::BlockError; use dubp_documents::documents::block::BlockDocument; @@ -22,23 +25,10 @@ use dubp_documents::*; use dup_crypto::keys::PubKey; use durs_blockchain_dal::*; use durs_wot::*; +pub use rules::InvalidRuleError; use std::cmp::Ordering; use std::collections::HashMap; -#[derive(Fail, Debug, Copy, Clone)] -pub enum InvalidRuleError { - #[fail(display = "BR_G99: different currency")] - DifferentCurrency, - #[fail(display = "BR_G03: wrong previous issuer")] - WrongPreviousIssuer, - #[fail(display = "BR_G100: issuer is not a member")] - NotMemberIssuer, - #[fail(display = "BR_G04: wrong issuers count")] - WrongIssuersCount, - #[fail(display = "BR_G05: genesis: issuers frame must be 1")] - WrongIssuersFrame, -} - #[inline] fn invalid_rule_error(error: InvalidRuleError) -> BlockError { BlockError::InvalidBlock(InvalidBlockError::InvalidRule(error)) diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions/mod.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions/mod.rs new file mode 100644 index 00000000..13f6bfd3 --- /dev/null +++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions/mod.rs @@ -0,0 +1,27 @@ +// Copyright (C) 2018 The Duniter Project Developers. +// +// 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(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 00000000..b44d97e0 --- /dev/null +++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/protocol_versions/v11.rs @@ -0,0 +1,23 @@ +// Copyright (C) 2018 The Duniter Project Developers. +// +// 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::pr(vec![99usize, 3, 100, 4, 5])].into() +} 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 00000000..b52aa7cd --- /dev/null +++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/all_rules.rs @@ -0,0 +1,36 @@ +// Copyright (C) 2018 The Duniter Project Developers. +// +// 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 lazy_static::lazy_static; + +use super::br_g03; +use super::RuleDatas; +use crate::dubp::check::global::rules::InvalidRuleError; +use rules_engine::rule::{Rule, RuleNumber}; +use std::collections::BTreeMap; + +lazy_static! { + pub static ref ALL_RULES: BTreeMap<RuleNumber, Rule<RuleDatas<'static>, InvalidRuleError>> = + get_all_rules(); +} + +#[inline] +pub fn get_all_rules<'a>() -> BTreeMap<RuleNumber, Rule<RuleDatas<'a>, InvalidRuleError>> { + btreemap![ + RuleNumber(3) => br_g03::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 00000000..c55d0cba --- /dev/null +++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/br_g03.rs @@ -0,0 +1,45 @@ +// Copyright (C) 2018 The Duniter Project Developers. +// +// 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 of blockchain protocol + +use super::{InvalidRuleError, RuleDatas}; +use rules_engine::rule::{Rule, RuleFn, RuleFnRef, RuleNumber}; +use rules_engine::ProtocolVersion; +use unwrap::unwrap; + +#[inline] +pub fn rule<'a>() -> Rule<RuleDatas<'a>, InvalidRuleError> { + unwrap!(Rule::new( + RuleNumber(3), + btreemap![ + ProtocolVersion(10) => RuleFn::Ref(v10 as RuleFnRef<RuleDatas, InvalidRuleError>), + ] + )) +} + +fn v10(rule_datas: &RuleDatas) -> Result<(), InvalidRuleError> { + let RuleDatas { + ref block, + ref previous_block, + .. + } = rule_datas; + + if Some(previous_block.issuers[0]) == block.previous_issuer { + Ok(()) + } else { + Err(InvalidRuleError::WrongPreviousIssuer) + } +} diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/mod.rs b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/mod.rs new file mode 100644 index 00000000..87ad7db4 --- /dev/null +++ b/lib/modules/blockchain/blockchain/src/dubp/check/global/rules/mod.rs @@ -0,0 +1,49 @@ +// Copyright (C) 2018 The Duniter Project Developers. +// +// 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 + +mod all_rules; +mod br_g03; + +use dubp_documents::documents::block::BlockDocument; +use dup_crypto::keys::PubKey; +use durs_blockchain_dal::*; +use durs_wot::*; +use std::collections::HashMap; + +#[derive(Debug)] +pub struct RuleDatas<'a> { + block: &'a BlockDocument, + previous_block: &'a BlockDocument, + blockchain_db: BinDB<LocalBlockchainV10Datas>, + wot_dbs: WotsV10DBs, + wot_index: HashMap<PubKey, NodeId>, + current_frame: Option<HashMap<PubKey, usize>>, +} + +#[derive(Copy, Clone, Debug, Eq, Fail, PartialEq)] +pub enum InvalidRuleError { + #[fail(display = "BR_G99: different currency")] + DifferentCurrency, + #[fail(display = "BR_G03: wrong previous issuer")] + WrongPreviousIssuer, + #[fail(display = "BR_G100: issuer is not a member")] + NotMemberIssuer, + #[fail(display = "BR_G04: wrong issuers count")] + WrongIssuersCount, + #[fail(display = "BR_G05: wrong issuers frame size")] + WrongIssuersFrame, +} diff --git a/lib/modules/blockchain/blockchain/src/lib.rs b/lib/modules/blockchain/blockchain/src/lib.rs index 657f4825..429ff3d6 100644 --- a/lib/modules/blockchain/blockchain/src/lib.rs +++ b/lib/modules/blockchain/blockchain/src/lib.rs @@ -20,7 +20,6 @@ missing_docs, missing_debug_implementations, missing_copy_implementations, - trivial_casts, trivial_numeric_casts, unsafe_code, unstable_features, @@ -32,6 +31,8 @@ extern crate failure; #[macro_use] extern crate log; +#[macro_use] +extern crate maplit; mod constants; mod dbex; -- GitLab