import module

This commit is contained in:
debris 2016-10-31 03:12:44 +01:00
parent 260986da9c
commit 05ed9567e9
12 changed files with 235 additions and 2 deletions

10
Cargo.lock generated
View File

@ -6,6 +6,7 @@ dependencies = [
"clap 2.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
"db 0.1.0",
"env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"import 0.1.0",
"keys 0.1.0",
"message 0.1.0",
"miner 0.1.0",
@ -219,6 +220,15 @@ dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "import"
version = "0.1.0"
dependencies = [
"chain 0.1.0",
"primitives 0.1.0",
"serialization 0.1.0",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"

View File

@ -17,6 +17,7 @@ script = { path = "script" }
db = { path = "db" }
verification = { path = "verification" }
sync = { path = "sync" }
import = { path = "import" }
[[bin]]
path = "pbtc/main.rs"

9
import/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "import"
version = "0.1.0"
authors = ["debris <marek.kotewicz@gmail.com>"]
[dependencies]
primitives = { path = "../primitives" }
chain = { path = "../chain" }
serialization = { path = "../serialization" }

68
import/src/blk.rs Normal file
View File

@ -0,0 +1,68 @@
use std::{io, fs, path};
use ser::{ReadIterator, deserialize_iterator, Error as ReaderError};
use block::Block;
use fs::{read_blk_dir, ReadBlkDir};
pub fn open_blk_file<P>(path: P) -> Result<BlkFile, io::Error> where P: AsRef<path::Path> {
let file = try!(fs::File::open(path));
let blk_file = BlkFile {
reader: deserialize_iterator(file),
};
Ok(blk_file)
}
pub struct BlkFile {
reader: ReadIterator<fs::File, Block>,
}
impl Iterator for BlkFile {
type Item = Result<Block, ReaderError>;
fn next(&mut self) -> Option<Self::Item> {
self.reader.next()
}
}
pub fn open_blk_dir<P>(path: P) -> Result<BlkDir, io::Error> where P: AsRef<path::Path> {
let dir_iter = try!(read_blk_dir(path));
let blk_dir = BlkDir {
dir_iter: dir_iter,
current_file: None,
};
Ok(blk_dir)
}
pub struct BlkDir {
dir_iter: ReadBlkDir,
current_file: Option<BlkFile>,
}
impl Iterator for BlkDir {
type Item = Result<Block, ReaderError>;
fn next(&mut self) -> Option<Self::Item> {
// TODO: use chained iterators instead
let next_file = match self.current_file {
Some(ref mut file) => match file.next() {
Some(block) => return Some(block),
None => self.dir_iter.next(),
},
None => self.dir_iter.next(),
};
match next_file {
Some(Ok(next_file)) => {
self.current_file = match open_blk_file(next_file.path) {
Err(_) => return Some(Err(ReaderError::MalformedData)),
Ok(file) => Some(file),
};
self.next()
},
Some(Err(_)) => {
Some(Err(ReaderError::MalformedData))
},
None => None,
}
}
}

23
import/src/block.rs Normal file
View File

@ -0,0 +1,23 @@
use std::io;
use hash::H32;
use ser::{Deserializable, Reader, Error as ReaderError};
use chain;
#[derive(Debug, PartialEq)]
pub struct Block {
magic: H32,
block_size: u32,
block: chain::Block,
}
impl Deserializable for Block {
fn deserialize<T>(reader: &mut Reader<T>) -> Result<Self, ReaderError> where T: io::Read {
let block = Block {
magic: try!(reader.read()),
block_size: try!(reader.read()),
block: try!(reader.read()),
};
Ok(block)
}
}

87
import/src/fs.rs Normal file
View File

@ -0,0 +1,87 @@
use std::{io, fs, path};
/// Creates an iterator over all blk .dat files
pub fn read_blk_dir<P>(path: P) -> Result<ReadBlkDir, io::Error> where P: AsRef<path::Path> {
let read_blk_dir = ReadBlkDir {
read_dir: try!(fs::read_dir(path)),
};
Ok(read_blk_dir)
}
pub struct ReadBlkDir {
read_dir: fs::ReadDir,
}
pub struct BlkEntry {
pub path: path::PathBuf,
}
fn is_blk_file_name(file_name: &str) -> bool {
if file_name.len() != 12 || !file_name.starts_with("blk") || !file_name.ends_with(".dat") {
return false;
}
file_name[3..8].parse::<u32>().is_ok()
}
impl BlkEntry {
fn from_dir_entry(dir_entry: fs::DirEntry) -> Option<Self> {
match dir_entry.metadata() {
Err(_) => return None,
Ok(ref metadata) => {
if !metadata.is_file() {
return None;
}
}
}
match dir_entry.file_name().into_string() {
Err(_) => return None,
Ok(ref file_name) => {
if !is_blk_file_name(file_name) {
return None;
}
}
}
let entry = BlkEntry {
path: dir_entry.path(),
};
Some(entry)
}
}
impl Iterator for ReadBlkDir {
type Item = Result<BlkEntry, io::Error>;
fn next(&mut self) -> Option<Self::Item> {
let mut result = None;
while result.is_none() {
match self.read_dir.next() {
None => return None,
Some(Err(err)) => return Some(Err(err)),
Some(Ok(entry)) => {
result = BlkEntry::from_dir_entry(entry);
}
}
}
result.map(Ok)
}
}
#[cfg(test)]
mod test {
use super::is_blk_file_name;
#[test]
fn test_is_blk_file_name() {
assert!(is_blk_file_name("blk00000.dat"));
assert!(is_blk_file_name("blk00232.dat"));
assert!(!is_blk_file_name("blk0000.dat"));
assert!(!is_blk_file_name("blk00000.daw"));
assert!(!is_blk_file_name("blk00032.daw"));
assert!(!is_blk_file_name("blk000ff.dat"));
}
}

11
import/src/lib.rs Normal file
View File

@ -0,0 +1,11 @@
extern crate primitives;
extern crate serialization as ser;
extern crate chain;
mod blk;
mod block;
mod fs;
pub use primitives::{hash, bytes};
pub use blk::{open_blk_file, open_blk_dir};

View File

@ -29,4 +29,9 @@ args:
- diskdb:
long: diskdb
help: Use disk storage instead of in-memory one
- import:
long: import
value_name: PATH
help: Import blocks from bitcoin core database
takes_value: true

View File

@ -9,6 +9,7 @@ pub struct Config {
pub seednode: Option<String>,
pub print_to_console: bool,
pub use_disk_database: bool,
pub import_path: Option<String>,
}
pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
@ -34,6 +35,11 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
None => None,
};
let import_path = match matches.value_of("import") {
Some(s) => Some(try!(s.parse().map_err(|_| "Invalid import path".to_owned()))),
None => None,
};
let config = Config {
print_to_console: print_to_console,
magic: magic,
@ -41,6 +47,7 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
connect: connect,
seednode: seednode,
use_disk_database: use_disk_database,
import_path: import_path,
};
Ok(config)

View File

@ -2,15 +2,16 @@
#[macro_use]
extern crate clap;
extern crate db;
extern crate env_logger;
extern crate db;
extern crate chain;
extern crate keys;
extern crate script;
extern crate message;
extern crate p2p;
extern crate sync;
extern crate import;
mod config;
@ -54,11 +55,21 @@ fn init_db(db: &Arc<db::Store>) {
}
}
fn import_blockchain(db_path: &str) {
for _block in import::open_blk_dir(db_path).expect("TODO") {
// import logic goes here
}
}
fn run() -> Result<(), String> {
let yaml = load_yaml!("cli.yml");
let matches = clap::App::from_yaml(yaml).get_matches();
let cfg = try!(config::parse(&matches));
if let Some(ref import_path) = cfg.import_path {
import_blockchain(import_path);
}
let mut el = event_loop();
let p2p_cfg = p2p::Config {

View File

@ -9,5 +9,5 @@ pub mod stream;
pub use primitives::{hash, bytes};
pub use compact_integer::CompactInteger;
pub use self::reader::{Reader, Deserializable, deserialize, deserialize_iterator, Error};
pub use self::reader::{Reader, Deserializable, deserialize, deserialize_iterator, ReadIterator, Error};
pub use self::stream::{Stream, Serializable, serialize, serialized_list_size};

View File

@ -13,5 +13,6 @@ cargo test\
-p script\
-p serialization\
-p sync\
-p import\
-p pbtc\
-p verification