diff --git a/Cargo.lock b/Cargo.lock index 87cbd1b2ba97eb1a403c51196eb7a0e4593f6b89..0b88cbebc588b99b985266093373be14b7255b93 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 5cfd27b861408fa8cbf9c7309e049d9e6f869b80..4ba1915963210246595c49d0ce65c1930be20820 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 f9be5665a148f5eec45b77cecc2be5b11a14c54b..6ec5b6dadf6c470f53deaa9e43d9d06e70bb2afe 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 0000000000000000000000000000000000000000..13f6bfd39f198d6b1eaa7283a61de5c84b227599 --- /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 0000000000000000000000000000000000000000..b44d97e0ecef21d79df26e4b8db02585822f5ab4 --- /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 0000000000000000000000000000000000000000..b52aa7cdde9976d1280d0a0d190b073928891d7e --- /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 0000000000000000000000000000000000000000..c55d0cbacd82a7dadfffcbccaed378f12d515099 --- /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 0000000000000000000000000000000000000000..87ad7db41a6010d8c3fd496d018fa872e5b3e823 --- /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 657f4825a78028d6263b19a3d01940ac6e5ee7d4..429ff3d69652b6013384bad9a79639e7cf3a8122 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;