diff --git a/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs b/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs index cb3b0bf49ea891795454b8131e6a407c46656a33..feb343cd184b07d51d395575e9506b47e650a59c 100644 --- a/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs +++ b/lib/modules/blockchain/blockchain/src/dubp/check/mod.rs @@ -55,94 +55,91 @@ fn invalid_rule_error(error: InvalidRuleError) -> BlockError { BlockError::InvalidBlock(InvalidBlockError::InvalidRule(error)) } +pub fn verify_genesis_block_validity(block: &BlockDocument) -> Result<(), BlockError> { + // 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(()) +} + pub fn verify_block_validity<W: WebOfTrust>( block: &BlockDocument, blockchain_db: &BinDB<LocalBlockchainV10Datas>, + identities_db: &BinDB<IdentitiesV10Datas>, _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 { - // Get previous block - let previous_block_opt = readers::block::get_block_in_local_blockchain( - blockchain_db, - BlockNumber(block.number.0 - 1), - )?; - - // Previous block must exist - if previous_block_opt.is_none() { - return Err(BlockError::InvalidBlock(InvalidBlockError::NoPreviousBlock)); - } - let previous_block = previous_block_opt.expect("safe unwrap"); - - // Block version must not decrease - 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)); - } + // Get previous block + let previous_block_opt = readers::block::get_block_in_local_blockchain( + blockchain_db, + BlockNumber(block.number.0 - 1), + )?; + + // Previous block must exist + if previous_block_opt.is_none() { + return Err(BlockError::InvalidBlock(InvalidBlockError::NoPreviousBlock)); } - // 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)); - } + let previous_block = previous_block_opt.expect("safe unwrap"); + + // Block version must not decrease + 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 issuers_frame = readers::block::get_current_frame( + &entities::block::DALBlock { + block: block.clone(), + expire_certs: None, + }, + blockchain_db, + )?; + if issuers_frame.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)); } Ok(()) diff --git a/lib/modules/blockchain/blockchain/src/dubp/mod.rs b/lib/modules/blockchain/blockchain/src/dubp/mod.rs index fc0b823ca7a9e32851de860b3db03ecef97322e0..4fbf68fdd3c965f0543d9949246ddaf556b4a0cc 100644 --- a/lib/modules/blockchain/blockchain/src/dubp/mod.rs +++ b/lib/modules/blockchain/blockchain/src/dubp/mod.rs @@ -92,14 +92,18 @@ pub fn check_and_apply_block( )?; // Verify block validity (check all protocol rule, very long !) - verify_block_validity( - &block_doc, - &bc.blocks_databases.blockchain_db, - &bc.wot_databases.certs_db, - &bc.wot_index, - &bc.wot_databases.wot_db, - &bc.wot_databases.identities_db, - )?; + if block_doc.number.0 == 0 { + verify_genesis_block_validity(&block_doc)?; + } else { + verify_block_validity( + &block_doc, + &bc.blocks_databases.blockchain_db, + &bc.wot_databases.identities_db, + &bc.wot_databases.certs_db, + &bc.wot_index, + &bc.wot_databases.wot_db, + )?; + } Ok(CheckAndApplyBlockReturn::ValidBlock(apply_valid_block( block_doc,