import module
This commit is contained in:
parent
260986da9c
commit
05ed9567e9
|
@ -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"
|
||||
|
|
|
@ -17,6 +17,7 @@ script = { path = "script" }
|
|||
db = { path = "db" }
|
||||
verification = { path = "verification" }
|
||||
sync = { path = "sync" }
|
||||
import = { path = "import" }
|
||||
|
||||
[[bin]]
|
||||
path = "pbtc/main.rs"
|
||||
|
|
|
@ -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" }
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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"));
|
||||
}
|
||||
}
|
|
@ -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};
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
13
pbtc/main.rs
13
pbtc/main.rs
|
@ -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 {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -13,5 +13,6 @@ cargo test\
|
|||
-p script\
|
||||
-p serialization\
|
||||
-p sync\
|
||||
-p import\
|
||||
-p pbtc\
|
||||
-p verification
|
||||
|
|
Loading…
Reference in New Issue