Skip to content
Snippets Groups Projects
Commit 4c5c8554 authored by Éloïs's avatar Éloïs
Browse files

[fix] #69 + migrate wot i/o file to rustbreak

parent f52ebeaa
No related branches found
No related tags found
1 merge request!64Resolve "[wotb] Data Legacy wot not compile with bincode 1.0.0"
...@@ -84,15 +84,6 @@ dependencies = [ ...@@ -84,15 +84,6 @@ dependencies = [
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "bincode"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "bincode" name = "bincode"
version = "1.0.0" version = "1.0.0"
...@@ -409,7 +400,7 @@ dependencies = [ ...@@ -409,7 +400,7 @@ dependencies = [
name = "duniter-wotb" name = "duniter-wotb"
version = "0.8.0-a0.6" version = "0.8.0-a0.6"
dependencies = [ dependencies = [
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.57 (registry+https://github.com/rust-lang/crates.io-index)",
...@@ -1443,7 +1434,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" ...@@ -1443,7 +1434,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557" "checksum base64 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30e93c03064e7590d0466209155251b90c22e37fab1daf2771582598b5827557"
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" "checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
"checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" "checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007"
"checksum bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9a6301db0b49fb63551bc15b5ae348147101cdf323242b93ec7546d5002ff1af"
"checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0" "checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
......
...@@ -17,14 +17,16 @@ use duniter_crypto::keys::*; ...@@ -17,14 +17,16 @@ use duniter_crypto::keys::*;
use duniter_dal::block::DALBlock; use duniter_dal::block::DALBlock;
use duniter_dal::sources::SourceAmount; use duniter_dal::sources::SourceAmount;
use duniter_dal::writers::requests::*; use duniter_dal::writers::requests::*;
use duniter_dal::ForkId; use duniter_dal::{BinDB, ForkId};
use duniter_documents::blockchain::v10::documents::transaction::{TxAmount, TxBase}; use duniter_documents::blockchain::v10::documents::transaction::{TxAmount, TxBase};
use duniter_documents::blockchain::v10::documents::BlockDocument; use duniter_documents::blockchain::v10::documents::BlockDocument;
use duniter_documents::blockchain::Document; use duniter_documents::blockchain::Document;
use duniter_documents::BlockId; use duniter_documents::BlockId;
use duniter_wotb::data::NewLinkResult; use duniter_wotb::data::NewLinkResult;
use duniter_wotb::{NodeId, WebOfTrust}; use duniter_wotb::{NodeId, WebOfTrust};
use rustbreak::backend::Backend;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::Debug;
#[derive(Debug)] #[derive(Debug)]
/// Stores all queries to apply in database to "apply" the block /// Stores all queries to apply in database to "apply" the block
...@@ -41,10 +43,10 @@ pub enum ApplyValidBlockError { ...@@ -41,10 +43,10 @@ pub enum ApplyValidBlockError {
RevokeUnknowNodeId(), RevokeUnknowNodeId(),
} }
pub fn apply_valid_block<W: WebOfTrust + Sync>( pub fn apply_valid_block<W: WebOfTrust, B: Backend + Debug>(
block: &BlockDocument, block: &BlockDocument,
wot_index: &mut HashMap<PubKey, NodeId>, wot_index: &mut HashMap<PubKey, NodeId>,
wot: &mut W, wot_db: &BinDB<W, B>,
expire_certs: &HashMap<(NodeId, NodeId), BlockId>, expire_certs: &HashMap<(NodeId, NodeId), BlockId>,
old_fork_id: Option<ForkId>, old_fork_id: Option<ForkId>,
) -> Result<ValidBlockApplyReqs, ApplyValidBlockError> { ) -> Result<ValidBlockApplyReqs, ApplyValidBlockError> {
...@@ -63,8 +65,16 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>( ...@@ -63,8 +65,16 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>(
let pubkey = joiner.clone().issuers()[0]; let pubkey = joiner.clone().issuers()[0];
if let Some(idty_doc) = identities.get(&pubkey) { if let Some(idty_doc) = identities.get(&pubkey) {
// Newcomer // Newcomer
let wotb_id = NodeId(wot.size()); let wotb_id = NodeId(
wot.add_node(); wot_db
.read(|db| db.size())
.expect("Fatal error : fail to read WotDB !"),
);
wot_db
.write(|db| {
db.add_node();
})
.expect("Fail to write in WotDB");
wot_index.insert(pubkey, wotb_id); wot_index.insert(pubkey, wotb_id);
wot_dbs_requests.push(WotsDBsWriteQuery::CreateIdentity( wot_dbs_requests.push(WotsDBsWriteQuery::CreateIdentity(
wotb_id, wotb_id,
...@@ -76,7 +86,11 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>( ...@@ -76,7 +86,11 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>(
} else { } else {
// Renewer // Renewer
let wotb_id = wot_index[&joiner.issuers()[0]]; let wotb_id = wot_index[&joiner.issuers()[0]];
wot.set_enabled(wotb_id, true); wot_db
.write(|db| {
db.set_enabled(wotb_id, true);
})
.expect("Fail to write in WotDB");
wot_dbs_requests.push(WotsDBsWriteQuery::RenewalIdentity( wot_dbs_requests.push(WotsDBsWriteQuery::RenewalIdentity(
joiner.issuers()[0], joiner.issuers()[0],
wotb_id, wotb_id,
...@@ -89,7 +103,11 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>( ...@@ -89,7 +103,11 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>(
let pubkey = active.issuers()[0]; let pubkey = active.issuers()[0];
if !identities.contains_key(&pubkey) { if !identities.contains_key(&pubkey) {
let wotb_id = wot_index[&pubkey]; let wotb_id = wot_index[&pubkey];
wot.set_enabled(wotb_id, true); wot_db
.write(|db| {
db.set_enabled(wotb_id, true);
})
.expect("Fail to write in WotDB");
wot_dbs_requests.push(WotsDBsWriteQuery::RenewalIdentity( wot_dbs_requests.push(WotsDBsWriteQuery::RenewalIdentity(
pubkey, pubkey,
wotb_id, wotb_id,
...@@ -104,7 +122,11 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>( ...@@ -104,7 +122,11 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>(
} else { } else {
return Err(ApplyValidBlockError::ExcludeUnknowNodeId()); return Err(ApplyValidBlockError::ExcludeUnknowNodeId());
}; };
wot.set_enabled(*wot_id, false); wot_db
.write(|db| {
db.set_enabled(*wot_id, false);
})
.expect("Fail to write in WotDB");
wot_dbs_requests.push(WotsDBsWriteQuery::ExcludeIdentity( wot_dbs_requests.push(WotsDBsWriteQuery::ExcludeIdentity(
exclusion, exclusion,
block.blockstamp(), block.blockstamp(),
...@@ -117,7 +139,11 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>( ...@@ -117,7 +139,11 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>(
} else { } else {
return Err(ApplyValidBlockError::RevokeUnknowNodeId()); return Err(ApplyValidBlockError::RevokeUnknowNodeId());
}; };
wot.set_enabled(*wot_id, false); wot_db
.write(|db| {
db.set_enabled(*wot_id, false);
})
.expect("Fail to write in WotDB");
wot_dbs_requests.push(WotsDBsWriteQuery::RevokeIdentity( wot_dbs_requests.push(WotsDBsWriteQuery::RevokeIdentity(
compact_revoc.issuer, compact_revoc.issuer,
block.blockstamp(), block.blockstamp(),
...@@ -128,7 +154,9 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>( ...@@ -128,7 +154,9 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>(
let compact_cert = certification.to_compact_document(); let compact_cert = certification.to_compact_document();
let wotb_node_from = wot_index[&compact_cert.issuer]; let wotb_node_from = wot_index[&compact_cert.issuer];
let wotb_node_to = wot_index[&compact_cert.target]; let wotb_node_to = wot_index[&compact_cert.target];
let result = wot.add_link(wotb_node_from, wotb_node_to); wot_db
.write(|db| {
let result = db.add_link(wotb_node_from, wotb_node_to);
match result { match result {
NewLinkResult::Ok(_) => {} NewLinkResult::Ok(_) => {}
_ => panic!( _ => panic!(
...@@ -136,6 +164,8 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>( ...@@ -136,6 +164,8 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>(
wotb_node_from.0, wotb_node_to.0, result wotb_node_from.0, wotb_node_to.0, result
), ),
} }
})
.expect("Fail to read WotDB");
wot_dbs_requests.push(WotsDBsWriteQuery::CreateCert( wot_dbs_requests.push(WotsDBsWriteQuery::CreateCert(
compact_cert.issuer, compact_cert.issuer,
wotb_node_from, wotb_node_from,
...@@ -154,7 +184,9 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>( ...@@ -154,7 +184,9 @@ pub fn apply_valid_block<W: WebOfTrust + Sync>(
} }
if let Some(du_amount) = block.dividend { if let Some(du_amount) = block.dividend {
if du_amount > 0 { if du_amount > 0 {
let members_wot_ids = wot.get_enabled(); let members_wot_ids = wot_db
.read(|db| db.get_enabled())
.expect("Fail to read WotDB");
let mut members_pubkeys = Vec::new(); let mut members_pubkeys = Vec::new();
for (pubkey, wotb_id) in wot_index { for (pubkey, wotb_id) in wot_index {
if members_wot_ids.contains(wotb_id) { if members_wot_ids.contains(wotb_id) {
......
...@@ -22,6 +22,8 @@ use duniter_dal::*; ...@@ -22,6 +22,8 @@ use duniter_dal::*;
use duniter_documents::blockchain::Document; use duniter_documents::blockchain::Document;
use duniter_documents::{BlockHash, BlockId, Blockstamp, PreviousBlockstamp}; use duniter_documents::{BlockHash, BlockId, Blockstamp, PreviousBlockstamp};
use duniter_network::NetworkBlock; use duniter_network::NetworkBlock;
use rustbreak::backend::Backend;
use std::fmt::Debug;
use *; use *;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
...@@ -53,13 +55,13 @@ impl From<ApplyValidBlockError> for BlockError { ...@@ -53,13 +55,13 @@ impl From<ApplyValidBlockError> for BlockError {
} }
} }
pub fn check_and_apply_block<W: WebOfTrust + Sync>( pub fn check_and_apply_block<W: WebOfTrust, B: Backend + Debug>(
blocks_databases: &BlocksV10DBs, blocks_databases: &BlocksV10DBs,
certs_db: &BinFileDB<CertsExpirV10Datas>, certs_db: &BinFileDB<CertsExpirV10Datas>,
block: &Block, block: &Block,
current_blockstamp: &Blockstamp, current_blockstamp: &Blockstamp,
wotb_index: &mut HashMap<PubKey, NodeId>, wotb_index: &mut HashMap<PubKey, NodeId>,
wot: &mut W, wot_db: &BinDB<W, B>,
forks_states: &[ForkStatus], forks_states: &[ForkStatus],
) -> Result<ValidBlockApplyReqs, BlockError> { ) -> Result<ValidBlockApplyReqs, BlockError> {
let (block_doc, already_have_block) = match *block { let (block_doc, already_have_block) = match *block {
...@@ -102,7 +104,7 @@ pub fn check_and_apply_block<W: WebOfTrust + Sync>( ...@@ -102,7 +104,7 @@ pub fn check_and_apply_block<W: WebOfTrust + Sync>(
return Ok(apply_valid_block( return Ok(apply_valid_block(
&block_doc, &block_doc,
wotb_index, wotb_index,
wot, wot_db,
&expire_certs, &expire_certs,
old_fork_id, old_fork_id,
)?); )?);
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
use duniter_crypto::keys::*; use duniter_crypto::keys::*;
use duniter_dal::identity::DALIdentity; use duniter_dal::identity::DALIdentity;
use duniter_documents::blockchain::v10::documents::transaction::*; use duniter_documents::blockchain::v10::documents::transaction::*;
use duniter_documents::Blockstamp;
use duniter_module::DuniterConf; use duniter_module::DuniterConf;
use duniter_wotb::data::rusty::RustyWebOfTrust; use duniter_wotb::data::rusty::RustyWebOfTrust;
use std::time::*; use std::time::*;
...@@ -135,18 +134,17 @@ pub fn dbex_wot(conf: &DuniterConf, query: &DBExWotQuery) { ...@@ -135,18 +134,17 @@ pub fn dbex_wot(conf: &DuniterConf, query: &DBExWotQuery) {
let wot_reverse_index: HashMap<NodeId, &PubKey> = let wot_reverse_index: HashMap<NodeId, &PubKey> =
wot_index.iter().map(|(p, id)| (*id, p)).collect(); wot_index.iter().map(|(p, id)| (*id, p)).collect();
// Get wot path // Open wot db
let wot_path = duniter_conf::get_wot_path(conf.profile().clone().to_string(), &conf.currency()); let wot_db = open_wot_db::<RustyWebOfTrust>(&db_path).expect("Fail to open WotDB !");
// Open wot file
let (wot, wot_blockstamp): (RustyWebOfTrust, Blockstamp) =
open_wot_file(&WOT_FILE_FORMATER, &wot_path, *INFINITE_SIG_STOCK);
// Print wot blockstamp // Print wot blockstamp
println!("Wot : Current blockstamp = {}.", wot_blockstamp); //println!("Wot : Current blockstamp = {}.", wot_blockstamp);
// Print members count // Print members count
let members_count = wot.get_enabled().len(); let members_count = wot_db
.read(|db| db.get_enabled())
.expect("Fail to read WotDB")
.len();
println!(" Members count = {}.", members_count); println!(" Members count = {}.", members_count);
match *query { match *query {
...@@ -162,8 +160,9 @@ pub fn dbex_wot(conf: &DuniterConf, query: &DBExWotQuery) { ...@@ -162,8 +160,9 @@ pub fn dbex_wot(conf: &DuniterConf, query: &DBExWotQuery) {
wot_id.0, wot_id.0,
pubkey.to_string() pubkey.to_string()
); );
let sources = wot let sources = wot_db
.get_links_source(wot_id) .read(|db| db.get_links_source(wot_id))
.expect("Fail to read WotDB")
.expect("Fail to get links source !"); .expect("Fail to get links source !");
println!("Certifiers : {}", sources.len()); println!("Certifiers : {}", sources.len());
for (i, source) in sources.iter().enumerate() { for (i, source) in sources.iter().enumerate() {
......
...@@ -47,6 +47,7 @@ mod ts_parsers; ...@@ -47,6 +47,7 @@ mod ts_parsers;
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::fmt::Debug;
use std::ops::Deref; use std::ops::Deref;
use std::path::PathBuf; use std::path::PathBuf;
use std::str; use std::str;
...@@ -73,9 +74,8 @@ use duniter_network::{ ...@@ -73,9 +74,8 @@ use duniter_network::{
NetworkBlock, NetworkDocument, NetworkEvent, NetworkRequest, NetworkResponse, NodeFullId, NetworkBlock, NetworkDocument, NetworkEvent, NetworkRequest, NetworkResponse, NodeFullId,
}; };
use duniter_wotb::data::rusty::RustyWebOfTrust; use duniter_wotb::data::rusty::RustyWebOfTrust;
use duniter_wotb::operations::file::BinaryFileFormater;
use duniter_wotb::{NodeId, WebOfTrust}; use duniter_wotb::{NodeId, WebOfTrust};
use rustbreak::backend::FileBackend; use rustbreak::backend::{Backend, FileBackend};
/// The blocks are requested by packet groups. This constant sets the block packet size. /// The blocks are requested by packet groups. This constant sets the block packet size.
pub static CHUNK_SIZE: &'static u32 = &50; pub static CHUNK_SIZE: &'static u32 = &50;
...@@ -83,8 +83,6 @@ pub static CHUNK_SIZE: &'static u32 = &50; ...@@ -83,8 +83,6 @@ pub static CHUNK_SIZE: &'static u32 = &50;
pub static INFINITE_SIG_STOCK: &'static usize = &4_000_000_000; pub static INFINITE_SIG_STOCK: &'static usize = &4_000_000_000;
/// The blocks are requested by packet groups. This constant sets the number of packets per group. /// The blocks are requested by packet groups. This constant sets the number of packets per group.
pub static MAX_BLOCKS_REQUEST: &'static u32 = &500; pub static MAX_BLOCKS_REQUEST: &'static u32 = &500;
/// There can be several implementations of the wot file backup, this constant fixes the implementation used by the blockchain module.
pub static WOT_FILE_FORMATER: BinaryFileFormater = BinaryFileFormater {};
/// Blockchain Module /// Blockchain Module
#[derive(Debug)] #[derive(Debug)]
...@@ -300,12 +298,12 @@ impl BlockchainModule { ...@@ -300,12 +298,12 @@ impl BlockchainModule {
} }
} }
} }
fn receive_network_documents<W: WebOfTrust + Sync>( fn receive_network_documents<W: WebOfTrust, B: Backend + Debug>(
&mut self, &mut self,
network_documents: &[NetworkDocument], network_documents: &[NetworkDocument],
current_blockstamp: &Blockstamp, current_blockstamp: &Blockstamp,
wotb_index: &mut HashMap<PubKey, NodeId>, wotb_index: &mut HashMap<PubKey, NodeId>,
wot: &mut W, wot_db: &BinDB<W, B>,
) -> Blockstamp { ) -> Blockstamp {
let mut blockchain_documents = Vec::new(); let mut blockchain_documents = Vec::new();
let mut current_blockstamp = *current_blockstamp; let mut current_blockstamp = *current_blockstamp;
...@@ -321,7 +319,7 @@ impl BlockchainModule { ...@@ -321,7 +319,7 @@ impl BlockchainModule {
&Block::NetworkBlock(network_block), &Block::NetworkBlock(network_block),
&current_blockstamp, &current_blockstamp,
wotb_index, wotb_index,
wot, wot_db,
&self.forks_states, &self.forks_states,
) { ) {
Ok(ValidBlockApplyReqs(block_req, wot_dbs_reqs, currency_dbs_reqs)) => { Ok(ValidBlockApplyReqs(block_req, wot_dbs_reqs, currency_dbs_reqs)) => {
...@@ -440,12 +438,12 @@ impl BlockchainModule { ...@@ -440,12 +438,12 @@ impl BlockchainModule {
} }
} }
} }
fn receive_blocks<W: WebOfTrust + Sync>( fn receive_blocks<W: WebOfTrust, B: Backend + Debug>(
&mut self, &mut self,
blocks_in_box: &[Box<NetworkBlock>], blocks_in_box: &[Box<NetworkBlock>],
current_blockstamp: &Blockstamp, current_blockstamp: &Blockstamp,
wotb_index: &mut HashMap<PubKey, NodeId>, wotb_index: &mut HashMap<PubKey, NodeId>,
wot: &mut W, wot: &BinDB<W, B>,
) -> Blockstamp { ) -> Blockstamp {
debug!("BlockchainModule : receive_blocks()"); debug!("BlockchainModule : receive_blocks()");
let blocks: Vec<&NetworkBlock> = blocks_in_box.into_iter().map(|b| b.deref()).collect(); let blocks: Vec<&NetworkBlock> = blocks_in_box.into_iter().map(|b| b.deref()).collect();
...@@ -455,7 +453,7 @@ impl BlockchainModule { ...@@ -455,7 +453,7 @@ impl BlockchainModule {
let mut save_currency_dbs = false; let mut save_currency_dbs = false;
for block in blocks { for block in blocks {
if let Ok(ValidBlockApplyReqs(bc_db_query, wot_dbs_queries, tx_dbs_queries)) = if let Ok(ValidBlockApplyReqs(bc_db_query, wot_dbs_queries, tx_dbs_queries)) =
check_and_apply_block::<W>( check_and_apply_block::<W, B>(
&self.blocks_databases, &self.blocks_databases,
&self.wot_databases.certs_db, &self.wot_databases.certs_db,
&Block::NetworkBlock(block), &Block::NetworkBlock(block),
...@@ -513,8 +511,9 @@ impl BlockchainModule { ...@@ -513,8 +511,9 @@ impl BlockchainModule {
pub fn start_blockchain(&mut self, blockchain_receiver: &mpsc::Receiver<DuniterMessage>) -> () { pub fn start_blockchain(&mut self, blockchain_receiver: &mpsc::Receiver<DuniterMessage>) -> () {
info!("BlockchainModule::start_blockchain()"); info!("BlockchainModule::start_blockchain()");
// Get wot path // Get dbs path
let wot_path = duniter_conf::get_wot_path(self.conf_profile.clone(), &self.currency); let dbs_path =
duniter_conf::get_blockchain_db_path(self.conf_profile.as_str(), &self.currency);
// Get wotb index // Get wotb index
let mut wotb_index: HashMap<PubKey, NodeId> = let mut wotb_index: HashMap<PubKey, NodeId> =
...@@ -522,11 +521,7 @@ impl BlockchainModule { ...@@ -522,11 +521,7 @@ impl BlockchainModule {
.expect("Fatal eror : get_wotb_index : Fail to read blockchain databases"); .expect("Fatal eror : get_wotb_index : Fail to read blockchain databases");
// Open wot file // Open wot file
let (mut wot, mut _wot_blockstamp) = open_wot_file::<RustyWebOfTrust, BinaryFileFormater>( let wot_db = open_wot_db::<RustyWebOfTrust>(&dbs_path).expect("Fail to open WotDB !");
&WOT_FILE_FORMATER,
&wot_path,
self.currency_params.sig_stock,
);
// Get current block // Get current block
let mut current_blockstamp = duniter_dal::block::get_current_blockstamp( let mut current_blockstamp = duniter_dal::block::get_current_blockstamp(
...@@ -640,7 +635,7 @@ impl BlockchainModule { ...@@ -640,7 +635,7 @@ impl BlockchainModule {
network_docs, network_docs,
&current_blockstamp, &current_blockstamp,
&mut wotb_index, &mut wotb_index,
&mut wot, &wot_db,
); );
current_blockstamp = new_current_blockstamp; current_blockstamp = new_current_blockstamp;
} }
...@@ -667,7 +662,7 @@ impl BlockchainModule { ...@@ -667,7 +662,7 @@ impl BlockchainModule {
blocks, blocks,
&current_blockstamp, &current_blockstamp,
&mut wotb_index, &mut wotb_index,
&mut wot, &wot_db,
); );
if current_blockstamp != new_current_blockstamp { if current_blockstamp != new_current_blockstamp {
current_blockstamp = new_current_blockstamp; current_blockstamp = new_current_blockstamp;
...@@ -728,7 +723,7 @@ impl BlockchainModule { ...@@ -728,7 +723,7 @@ impl BlockchainModule {
&Block::LocalBlock(&stackable_block.block), &Block::LocalBlock(&stackable_block.block),
&current_blockstamp, &current_blockstamp,
&mut wotb_index, &mut wotb_index,
&mut wot, &wot_db,
&self.forks_states, &self.forks_states,
) { ) {
// Apply db requests // Apply db requests
......
...@@ -26,8 +26,7 @@ use duniter_dal::writers::requests::*; ...@@ -26,8 +26,7 @@ use duniter_dal::writers::requests::*;
use duniter_dal::ForkId; use duniter_dal::ForkId;
use duniter_documents::{BlockHash, BlockId, Hash}; use duniter_documents::{BlockHash, BlockId, Hash};
use duniter_network::NetworkBlock; use duniter_network::NetworkBlock;
use duniter_wotb::operations::file::FileFormater; use duniter_wotb::NodeId;
use duniter_wotb::{NodeId, WebOfTrust};
use rustbreak::{deser::Bincode, MemoryDatabase}; use rustbreak::{deser::Bincode, MemoryDatabase};
use std::collections::{HashMap, VecDeque}; use std::collections::{HashMap, VecDeque};
use std::fs; use std::fs;
...@@ -80,34 +79,10 @@ pub fn sync_ts( ...@@ -80,34 +79,10 @@ pub fn sync_ts(
let mut current_blockstamp = *current_blockstamp; let mut current_blockstamp = *current_blockstamp;
// Get wot path // Get wot path
let wot_path = duniter_conf::get_wot_path(profile.clone().to_string(), currency); let db_path = duniter_conf::get_blockchain_db_path(&profile, &currency);
// Open wot file // Open wot db
let (mut wot, mut _wot_blockstamp): (RustyWebOfTrust, Blockstamp) = let wot_db = open_wot_db::<RustyWebOfTrust>(&db_path).expect("Fail to open WotDB !");
if wot_path.as_path().exists() {
match WOT_FILE_FORMATER.from_file(
wot_path
.as_path()
.to_str()
.expect("Fail to convert path to str"),
*INFINITE_SIG_STOCK,
) {
Ok((wot, binary_blockstamp)) => match str::from_utf8(&binary_blockstamp) {
Ok(str_blockstamp) => (
wot,
Blockstamp::from_string(str_blockstamp)
.expect("Fail to deserialize wot blockcstamp"),
),
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
},
Err(e) => panic!("Fatal Error : fail te read wot file : {:?}", e),
}
} else {
(
RustyWebOfTrust::new(*INFINITE_SIG_STOCK),
Blockstamp::default(),
)
};
// Get verification level // Get verification level
let _verif_level = if cautious { let _verif_level = if cautious {
...@@ -496,7 +471,6 @@ pub fn sync_ts( ...@@ -496,7 +471,6 @@ pub fn sync_ts(
block_doc.currency.clone(), block_doc.currency.clone(),
block_doc.parameters.unwrap(), block_doc.parameters.unwrap(),
)); ));
wot.set_max_link(currency_params.sig_stock);
get_currency_params = true; get_currency_params = true;
} else { } else {
panic!("The genesis block are None parameters !"); panic!("The genesis block are None parameters !");
...@@ -522,10 +496,10 @@ pub fn sync_ts( ...@@ -522,10 +496,10 @@ pub fn sync_ts(
// Apply block // Apply block
let apply_valid_block_begin = SystemTime::now(); let apply_valid_block_begin = SystemTime::now();
if let Ok(ValidBlockApplyReqs(block_req, wot_db_reqs, currency_db_reqs)) = if let Ok(ValidBlockApplyReqs(block_req, wot_db_reqs, currency_db_reqs)) =
apply_valid_block::<RustyWebOfTrust>( apply_valid_block::<RustyWebOfTrust, FileBackend>(
&block_doc, &block_doc,
&mut wotb_index, &mut wotb_index,
&mut wot, &wot_db,
&expire_certs, &expire_certs,
None, None,
) { ) {
...@@ -609,13 +583,7 @@ pub fn sync_ts( ...@@ -609,13 +583,7 @@ pub fn sync_ts(
info!("Sync : send End signal to tx job."); info!("Sync : send End signal to tx job.");
// Save wot file // Save wot file
WOT_FILE_FORMATER wot_db.save().expect("Fail to save wotb db");
.to_file(
&wot,
current_blockstamp.to_string().as_bytes(),
wot_path.as_path().to_str().unwrap(),
)
.expect("Fatal Error: Fail to write wotb in file !");
let main_job_duration = let main_job_duration =
SystemTime::now().duration_since(main_job_begin).unwrap() - all_wait_duration; SystemTime::now().duration_since(main_job_begin).unwrap() - all_wait_duration;
......
...@@ -52,7 +52,6 @@ pub mod writers; ...@@ -52,7 +52,6 @@ pub mod writers;
use duniter_crypto::keys::*; use duniter_crypto::keys::*;
use duniter_documents::blockchain::v10::documents::transaction::*; use duniter_documents::blockchain::v10::documents::transaction::*;
use duniter_documents::{BlockHash, BlockId, Blockstamp, Hash, PreviousBlockstamp}; use duniter_documents::{BlockHash, BlockId, Blockstamp, Hash, PreviousBlockstamp};
use duniter_wotb::operations::file::FileFormater;
use duniter_wotb::{NodeId, WebOfTrust}; use duniter_wotb::{NodeId, WebOfTrust};
use rustbreak::backend::{Backend, FileBackend, MemoryBackend}; use rustbreak::backend::{Backend, FileBackend, MemoryBackend};
use rustbreak::error::{RustbreakError, RustbreakErrorKind}; use rustbreak::error::{RustbreakError, RustbreakErrorKind};
...@@ -326,12 +325,13 @@ pub fn open_db<D: Serialize + DeserializeOwned + Debug + Default + Clone + Send> ...@@ -326,12 +325,13 @@ pub fn open_db<D: Serialize + DeserializeOwned + Debug + Default + Clone + Send>
} }
} }
/// Open wot file (cf. duniter-wot crate) /// Open wot db (cf. duniter-wot crate)
pub fn open_wot_file<W: WebOfTrust, WF: FileFormater>( pub fn open_wot_db<W: WebOfTrust>(dbs_folder_path: &PathBuf) -> Result<BinFileDB<W>, DALError> {
file_formater: &WF, open_db::<W>(dbs_folder_path, "wot.db")
wot_path: &PathBuf, }
sig_stock: usize,
) -> (W, Blockstamp) { // Open wot file (cf. duniter-wot crate)
/*pub fn open_wot_file<W: WebOfTrust>(wot_path: &PathBuf, sig_stock: usize) -> (W, Blockstamp) {
if wot_path.as_path().exists() { if wot_path.as_path().exists() {
match file_formater.from_file( match file_formater.from_file(
wot_path wot_path
...@@ -353,4 +353,4 @@ pub fn open_wot_file<W: WebOfTrust, WF: FileFormater>( ...@@ -353,4 +353,4 @@ pub fn open_wot_file<W: WebOfTrust, WF: FileFormater>(
} else { } else {
(W::new(sig_stock), Blockstamp::default()) (W::new(sig_stock), Blockstamp::default())
} }
} }*/
...@@ -14,7 +14,7 @@ path = "lib.rs" ...@@ -14,7 +14,7 @@ path = "lib.rs"
[dependencies] [dependencies]
serde = "1.0.57" serde = "1.0.57"
serde_derive = "1.0.57" serde_derive = "1.0.57"
bincode = "0.9.2" bincode = "1.0.0"
byteorder = "1.2.3" byteorder = "1.2.3"
rayon = "1.0.1" rayon = "1.0.1"
......
// Copyright (C) 2017-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/>.
//! Provide a legacy implementation of `WebOfTrust` storage and calculations.
//! Its mostly translated directly from the original C++ code.
use std::collections::hash_set::Iter;
use std::collections::HashSet;
use std::fs::File;
use std::io::prelude::*;
use bincode::{deserialize, serialize, Infinite};
use super::{HasLinkResult, NewLinkResult, RemLinkResult};
use NodeId;
use WebOfTrust;
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Node {
id: NodeId,
/// Is the node enabled ?
pub enabled: bool,
certs: HashSet<NodeId>,
issued_count: usize,
}
impl Node {
/// Create a new node.
pub fn new(id: usize) -> Node {
Node {
id: NodeId(id),
enabled: true,
certs: HashSet::new(),
issued_count: 0,
}
}
/// Getter of node id.
pub fn id(&self) -> NodeId {
self.id
}
/// Add a certification from this node to the given node.
///
/// Certification will fail if this node already used all its certs.
pub fn link_to(&mut self, to: &mut Node, max_certs: usize) -> NewLinkResult {
if self.issued_count >= max_certs {
NewLinkResult::AllCertificationsUsed(to.certs.len())
} else if to.certs.contains(&self.id()) {
NewLinkResult::AlreadyCertified(to.certs.len())
} else {
to.certs.insert(self.id());
self.issued_count += 1;
NewLinkResult::Ok(to.certs.len())
}
}
/// Remove a certification (if it exist) from this node to the given node.
pub fn unlink_to(&mut self, to: &mut Node) -> RemLinkResult {
if to.certs.contains(&self.id()) {
to.certs.remove(&self.id());
self.issued_count -= 1;
RemLinkResult::Removed(to.certs.len())
} else {
RemLinkResult::UnknownCert(to.certs.len())
}
}
/// Tells if this node has a link from the given node.
pub fn has_link_from(&self, from: &Node) -> bool {
self.certs.contains(&from.id())
}
/// Tells if this node has a link to the given node.
pub fn has_link_to(&self, to: &Node) -> bool {
to.has_link_from(self)
}
/// Give an iterator of node certs.
pub fn links_iter(&self) -> Iter<NodeId> {
self.certs.iter()
}
/// Getter of the issued count.
pub fn issued_count(&self) -> usize {
self.issued_count
}
}
/// Store a Web of Trust.
///
/// Allow to create/remove nodes and links between them.
///
/// It provides methods to find sentries nodes, find all paths
/// between 2 nodes and to compute distances in the web.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LegacyWebOfTrust {
nodes: Vec<Node>,
/// Maxiumum amout of certifications a node can provide.
///
/// It can be changed afterward, and will be accounted for every future calculations.
///
/// In practice it should not change after initialization.
pub max_cert: usize,
}
impl LegacyWebOfTrust {
/// Read `WoT` from file.
pub fn legacy_from_file(path: &str) -> Option<LegacyWebOfTrust> {
let mut file = match File::open(path) {
Ok(file) => file,
Err(_) => return None,
};
let mut content: Vec<u8> = vec![];
if file.read_to_end(&mut content).is_err() {
return None;
}
match deserialize::<LegacyWebOfTrust>(&content[..]) {
Ok(wot) => Some(wot),
Err(_) => None,
}
}
/// Write `WoT` to file.
pub fn legacy_to_file(&self, path: &str) -> bool {
let encoded: Vec<u8> = serialize(self, Infinite).unwrap();
match File::create(path) {
Ok(mut buffer) => buffer.write_all(&encoded).is_ok(),
Err(_) => false,
}
}
}
impl WebOfTrust for LegacyWebOfTrust {
fn new(max_cert: usize) -> LegacyWebOfTrust {
LegacyWebOfTrust {
nodes: vec![],
max_cert,
}
}
fn get_max_link(&self) -> usize {
self.max_cert
}
fn set_max_link(&mut self, max_link: usize) {
self.max_cert = max_link;
}
fn add_node(&mut self) -> NodeId {
let node_id = self.nodes.len();
self.nodes.push(Node::new(node_id));
NodeId(node_id)
}
fn rem_node(&mut self) -> Option<NodeId> {
self.nodes.pop();
if !self.nodes.is_empty() {
Some(NodeId(self.nodes.iter().len() - 1))
} else {
None
}
}
fn size(&self) -> usize {
self.nodes.iter().count()
}
fn is_enabled(&self, node: NodeId) -> Option<bool> {
if node.0 >= self.size() {
None
} else {
Some(self.nodes[node.0].enabled)
}
}
fn set_enabled(&mut self, node: NodeId, state: bool) -> Option<bool> {
if node.0 >= self.size() {
None
} else {
self.nodes[node.0].enabled = state;
Some(state)
}
}
fn get_enabled(&self) -> Vec<NodeId> {
self.nodes
.iter()
.filter(|x| x.enabled)
.map(|x| x.id())
.collect()
}
fn get_disabled(&self) -> Vec<NodeId> {
self.nodes
.iter()
.filter(|x| !x.enabled)
.map(|x| x.id())
.collect()
}
fn add_link(&mut self, from: NodeId, to: NodeId) -> NewLinkResult {
if from.0 == to.0 {
NewLinkResult::SelfLinkingForbidden()
} else if from.0 >= self.size() {
NewLinkResult::UnknownSource()
} else if to.0 >= self.size() {
NewLinkResult::UnknownTarget()
} else if from.0 < to.0 {
// split `nodes` in two part to allow borrowing 2 nodes at the same time
let (start, end) = self.nodes.split_at_mut(to.0);
start[from.0].link_to(&mut end[0], self.max_cert)
} else {
// split `nodes` in two part to allow borrowing 2 nodes at the same time
let (start, end) = self.nodes.split_at_mut(from.0);
end[0].link_to(&mut start[to.0], self.max_cert)
}
}
fn rem_link(&mut self, from: NodeId, to: NodeId) -> RemLinkResult {
if from.0 >= self.size() {
RemLinkResult::UnknownSource()
} else if to.0 >= self.size() {
RemLinkResult::UnknownTarget()
} else if from.0 < to.0 {
// split `nodes` in two part to allow borrowing 2 nodes at the same time
let (start, end) = self.nodes.split_at_mut(to.0);
start[from.0].unlink_to(&mut end[0])
} else {
// split `nodes` in two part to allow borrowing 2 nodes at the same time
let (start, end) = self.nodes.split_at_mut(from.0);
end[0].unlink_to(&mut start[to.0])
}
}
fn has_link(&self, from: NodeId, to: NodeId) -> HasLinkResult {
if from.0 >= self.size() {
HasLinkResult::UnknownSource()
} else if to.0 >= self.size() {
HasLinkResult::UnknownTarget()
} else {
HasLinkResult::Link(self.nodes[from.0].has_link_to(&self.nodes[to.0]))
}
}
fn is_sentry(&self, node: NodeId, sentry_requirement: usize) -> Option<bool> {
if node.0 >= self.size() {
return None;
}
let node = &self.nodes[node.0];
Some(
node.enabled
&& node.issued_count() >= sentry_requirement
&& node.links_iter().count() >= sentry_requirement,
)
}
fn get_sentries(&self, sentry_requirement: usize) -> Vec<NodeId> {
self.nodes
.iter()
.filter(|x| {
x.enabled
&& x.issued_count() >= sentry_requirement
&& x.links_iter().count() >= sentry_requirement
})
.map(|x| x.id())
.collect()
}
fn get_non_sentries(&self, sentry_requirement: usize) -> Vec<NodeId> {
self.nodes
.iter()
.filter(|x| {
x.enabled
&& (x.issued_count < sentry_requirement
|| x.links_iter().count() < sentry_requirement)
})
.map(|x| x.id())
.collect()
}
fn get_links_source(&self, target: NodeId) -> Option<Vec<NodeId>> {
if target.0 >= self.size() {
None
} else {
Some(self.nodes[target.0].certs.iter().cloned().collect())
}
}
fn issued_count(&self, id: NodeId) -> Option<usize> {
if id.0 >= self.size() {
None
} else {
Some(self.nodes[id.0].issued_count)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use tests::generic_wot_test;
#[test]
fn node_tests() {
// Correct node id
assert_eq!(Node::new(1).id().0, 1);
// Create 2 nodes
let mut node1 = Node::new(1);
let mut node2 = Node::new(2);
// Default value
assert_eq!(node1.issued_count(), 0);
assert_eq!(node2.links_iter().count(), 0);
assert!(!node1.has_link_to(&node2));
assert!(!node2.has_link_to(&node2));
assert!(!node1.has_link_from(&node1));
assert!(!node2.has_link_from(&node1));
// New link 1 -> 2
match node1.link_to(&mut node2, 10) {
NewLinkResult::Ok(1) => (),
_ => panic!(),
};
assert_eq!(node1.issued_count(), 1);
assert_eq!(node2.links_iter().count(), 1);
assert!(node1.has_link_to(&node2));
assert!(!node2.has_link_to(&node2));
assert!(!node1.has_link_from(&node1));
assert!(node2.has_link_from(&node1));
// Existing link 1 -> 2
match node1.link_to(&mut node2, 10) {
NewLinkResult::AlreadyCertified(1) => (),
_ => panic!(),
};
assert_eq!(node1.issued_count(), 1);
assert_eq!(node2.links_iter().count(), 1);
assert!(node1.has_link_to(&node2));
assert!(!node2.has_link_to(&node2));
assert!(!node1.has_link_from(&node1));
assert!(node2.has_link_from(&node1));
// Max certification count
let mut node3 = Node::new(3);
match node1.link_to(&mut node3, 1) {
NewLinkResult::AllCertificationsUsed(0) => (),
_ => panic!(),
};
assert_eq!(node1.issued_count(), 1);
assert_eq!(node2.links_iter().count(), 1);
assert_eq!(node3.links_iter().count(), 0);
assert!(node1.has_link_to(&node2));
assert!(!node2.has_link_to(&node2));
assert!(!node1.has_link_from(&node1));
assert!(node2.has_link_from(&node1));
}
#[test]
fn wot_tests() {
generic_wot_test::<LegacyWebOfTrust>();
}
}
...@@ -17,9 +17,12 @@ ...@@ -17,9 +17,12 @@
//! `LegacyWebOfTrust` is almost a translation of the legacy C++ coden while //! `LegacyWebOfTrust` is almost a translation of the legacy C++ coden while
//! `RustyWebOfTrust` is a brand new implementation with a more "rusty" style. //! `RustyWebOfTrust` is a brand new implementation with a more "rusty" style.
pub mod legacy;
pub mod rusty; pub mod rusty;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::fmt::Debug;
/// Wrapper for a node id. /// Wrapper for a node id.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct NodeId(pub usize); pub struct NodeId(pub usize);
...@@ -70,7 +73,7 @@ pub enum HasLinkResult { ...@@ -70,7 +73,7 @@ pub enum HasLinkResult {
/// Trait for a Web Of Trust. /// Trait for a Web Of Trust.
/// Allow to provide other implementations of the `WoT` logic instead of the legacy C++ /// Allow to provide other implementations of the `WoT` logic instead of the legacy C++
/// translated one. /// translated one.
pub trait WebOfTrust: Clone + Sync { pub trait WebOfTrust: Clone + Debug + Default + DeserializeOwned + Send + Serialize + Sync {
/// Create a new Web of Trust with the maximum of links a node can issue. /// Create a new Web of Trust with the maximum of links a node can issue.
fn new(max_links: usize) -> Self; fn new(max_links: usize) -> Self;
......
...@@ -22,7 +22,7 @@ use NodeId; ...@@ -22,7 +22,7 @@ use NodeId;
use WebOfTrust; use WebOfTrust;
/// A node in the `WoT` graph. /// A node in the `WoT` graph.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
struct Node { struct Node {
/// Is this node enabled ? /// Is this node enabled ?
enabled: bool, enabled: bool,
...@@ -44,7 +44,7 @@ impl Node { ...@@ -44,7 +44,7 @@ impl Node {
} }
/// A more idiomatic implementation of a Web of Trust. /// A more idiomatic implementation of a Web of Trust.
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RustyWebOfTrust { pub struct RustyWebOfTrust {
/// List of nodes in the WoT. /// List of nodes in the WoT.
nodes: Vec<Node>, nodes: Vec<Node>,
...@@ -52,6 +52,15 @@ pub struct RustyWebOfTrust { ...@@ -52,6 +52,15 @@ pub struct RustyWebOfTrust {
max_links: usize, max_links: usize,
} }
impl Default for RustyWebOfTrust {
fn default() -> RustyWebOfTrust {
RustyWebOfTrust {
nodes: Vec::new(),
max_links: 4_000_000_000,
}
}
}
impl WebOfTrust for RustyWebOfTrust { impl WebOfTrust for RustyWebOfTrust {
fn new(max_links: usize) -> RustyWebOfTrust { fn new(max_links: usize) -> RustyWebOfTrust {
RustyWebOfTrust { RustyWebOfTrust {
......
...@@ -116,6 +116,14 @@ impl FileFormater for BinaryFileFormater { ...@@ -116,6 +116,14 @@ impl FileFormater for BinaryFileFormater {
// Read up to nodes_states_size bytes (nodes_states) // Read up to nodes_states_size bytes (nodes_states)
let file_pointing_to_links = let file_pointing_to_links =
file_pointing_to_nodes_states.split_off(nodes_states_size as usize); file_pointing_to_nodes_states.split_off(nodes_states_size as usize);
let count_total_bytes_read = file_pointing_to_links.len()
+ nodes_states_size as usize
+ 4
+ blockstamp_size as usize
+ 4;
if count_total_bytes_read != file_size as usize {
panic!("not read all wot file !");
}
// Apply nodes state // Apply nodes state
let mut count_remaining_nodes = nodes_count; let mut count_remaining_nodes = nodes_count;
for byte in file_pointing_to_nodes_states { for byte in file_pointing_to_nodes_states {
...@@ -159,6 +167,9 @@ impl FileFormater for BinaryFileFormater { ...@@ -159,6 +167,9 @@ impl FileFormater for BinaryFileFormater {
count_bytes += 1; count_bytes += 1;
} }
} }
if count_bytes % 3 != 0 {
panic!("not read all wot file !");
}
Ok((wot, file_pointing_to_blockstamp)) Ok((wot, file_pointing_to_blockstamp))
} }
...@@ -182,7 +193,7 @@ impl FileFormater for BinaryFileFormater { ...@@ -182,7 +193,7 @@ impl FileFormater for BinaryFileFormater {
let mut bytes: Vec<u8> = Vec::with_capacity(4); let mut bytes: Vec<u8> = Vec::with_capacity(4);
bytes.write_u32::<BigEndian>(nodes_count).unwrap(); bytes.write_u32::<BigEndian>(nodes_count).unwrap();
buffer.append(&mut bytes); buffer.append(&mut bytes);
// Write enable state by groups of 8 (count links at the same time) // Write enable state by groups of 8
let mut enable_states: u8 = 0; let mut enable_states: u8 = 0;
let mut factor: u8 = 128; let mut factor: u8 = 128;
for n in 0..nodes_count { for n in 0..nodes_count {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment