diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs b/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs index 0c9959bae305d01dd121f60d7127e2871d1a796e..cb3b0bf49ea891795454b8131e6a407c46656a33 100644 --- a/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs +++ b/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs @@ -23,12 +23,36 @@ use dubp_documents::*; use dup_crypto::keys::PubKey; use durs_blockchain_dal::*; use durs_wot::*; +use std::cmp::Ordering; use std::collections::HashMap; -#[derive(Debug, Copy, Clone)] +#[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, +} + +#[derive(Fail, Debug, Copy, Clone)] pub enum InvalidBlockError { + #[fail(display = "Error: not found previous block")] NoPreviousBlock, + #[fail(display = "Error: version decrease in new block")] VersionDecrease, + #[fail(display = "Error at {}", _0)] + InvalidRule(InvalidRuleError), +} + +#[inline] +fn invalid_rule_error(error: InvalidRuleError) -> BlockError { + BlockError::InvalidBlock(InvalidBlockError::InvalidRule(error)) } pub fn verify_block_validity<W: WebOfTrust>( @@ -37,6 +61,7 @@ pub fn verify_block_validity<W: WebOfTrust>( _certs_db: &BinDB<CertsExpirV10Datas>, _wot_index: &HashMap<PubKey, NodeId>, _wot_db: &BinDB<W>, + identities_db: &BinDB<IdentitiesV10Datas>, ) -> Result<(), BlockError> { // Rules that do not concern genesis block if block.number.0 > 0 { @@ -56,6 +81,68 @@ pub fn verify_block_validity<W: WebOfTrust>( if previous_block.version > block.version { return Err(BlockError::InvalidBlock(InvalidBlockError::VersionDecrease)); } + + // BR_G99 - same currency + if previous_block.currency != block.currency { + return Err(invalid_rule_error(InvalidRuleError::DifferentCurrency)); + } + + // BR_G03 - previous issuer + if Some(previous_block.issuers[0]) != block.previous_issuer { + return Err(invalid_rule_error(InvalidRuleError::WrongPreviousIssuer)); + } + + // BR_G100 - issuer is member + match readers::identity::get_identity(identities_db, &block.issuers[0])? + .expect("safe unwrap") + .state + { + entities::identity::DALIdentityState::Member(_) => {} + _ => return Err(invalid_rule_error(InvalidRuleError::NotMemberIssuer)), + } + + // BR_G04 - issuers count + let mut issuers: Vec<PubKey> = vec![]; + for i in (previous_block.issuers_frame as u32)..=previous_block.number.0 { + let issuer = readers::block::get_block_in_local_blockchain(blockchain_db, BlockId(i))? + .expect("safe unwrap") + .issuers[0]; + if !issuers.contains(&issuer) { + issuers.push(issuer); + } + } + if issuers.len() != block.issuers_count { + return Err(invalid_rule_error(InvalidRuleError::WrongIssuersCount)); + } + + //BR_G05 - issuers frame + if block.issuers_frame + != previous_block.issuers_frame + + match previous_block.issuers_frame_var.cmp(&0) { + Ordering::Less => -1, + Ordering::Greater => 1, + Ordering::Equal => 0, + } + { + return Err(invalid_rule_error(InvalidRuleError::WrongIssuersFrame)); + } + } + // Only rules that do concern genesis block + else { + // BR_G03 - previous issuer + if block.previous_issuer != None { + return Err(invalid_rule_error(InvalidRuleError::WrongPreviousIssuer)); + } + + // BR_G04 - issuers count + if block.issuers_count != 0 { + return Err(invalid_rule_error(InvalidRuleError::WrongIssuersCount)); + } + + // BR_G05 - issuers count + if block.issuers_frame != 1 { + return Err(invalid_rule_error(InvalidRuleError::WrongIssuersFrame)); + } } Ok(()) diff --git a/lib/modules/blockchain/blockchain/src/dubp/mod.rs b/lib/modules/blockchain/blockchain/src/dubp/mod.rs index 0cb4208c8c4cb36784ba01fe0388913b5791f9b6..fc0b823ca7a9e32851de860b3db03ecef97322e0 100644 --- a/lib/modules/blockchain/blockchain/src/dubp/mod.rs +++ b/lib/modules/blockchain/blockchain/src/dubp/mod.rs @@ -98,6 +98,7 @@ pub fn check_and_apply_block( &bc.wot_databases.certs_db, &bc.wot_index, &bc.wot_databases.wot_db, + &bc.wot_databases.identities_db, )?; Ok(CheckAndApplyBlockReturn::ValidBlock(apply_valid_block( diff --git a/lib/modules/blockchain/blockchain/src/lib.rs b/lib/modules/blockchain/blockchain/src/lib.rs index 81bfe17695f4a8e37eb6eabc203f0800a0d2fa3d..657f4825a78028d6263b19a3d01940ac6e5ee7d4 100644 --- a/lib/modules/blockchain/blockchain/src/lib.rs +++ b/lib/modules/blockchain/blockchain/src/lib.rs @@ -28,8 +28,8 @@ unused_qualifications )] -//#[macro_use] -//extern crate failure; +#[macro_use] +extern crate failure; #[macro_use] extern crate log;