Merge branch 'master' of github.com:ethcore/parity-bitcoin into test_scripts

This commit is contained in:
debris 2016-11-18 00:46:06 +01:00
commit 6fa1ce326a
15 changed files with 341 additions and 258 deletions

31
db/src/block_provider.rs Normal file
View File

@ -0,0 +1,31 @@
use super::BlockRef;
use primitives::hash::H256;
use primitives::bytes::Bytes;
use chain;
pub trait BlockProvider {
/// resolves number by block hash
fn block_number(&self, hash: &H256) -> Option<u32>;
/// resolves hash by block number
fn block_hash(&self, number: u32) -> Option<H256>;
/// resolves header bytes by block reference (number/hash)
fn block_header_bytes(&self, block_ref: BlockRef) -> Option<Bytes>;
/// resolves deserialized block body by block reference (number/hash)
fn block(&self, block_ref: BlockRef) -> Option<chain::Block>;
/// returns true if store contains given block
fn contains_block(&self, block_ref: BlockRef) -> bool {
self.block_header_bytes(block_ref).is_some()
}
/// resolves list of block transactions by block reference (number/hash)
fn block_transaction_hashes(&self, block_ref: BlockRef) -> Vec<H256>;
/// returns all transactions in the block by block reference (number/hash)
fn block_transactions(&self, block_ref: BlockRef) -> Vec<chain::Transaction>;
}

41
db/src/block_stapler.rs Normal file
View File

@ -0,0 +1,41 @@
use primitives::hash::H256;
use super::BlockLocation;
use chain;
use error::Error;
#[derive(Debug)]
pub struct Reorganization {
pub height: u32,
canonized: Vec<H256>,
decanonized: Vec<H256>,
}
impl Reorganization {
pub fn new(height: u32) -> Reorganization {
Reorganization { height: height, canonized: Vec::new(), decanonized: Vec::new() }
}
pub fn push_canonized(&mut self, hash: &H256) {
self.canonized.push(hash.clone());
}
pub fn push_decanonized(&mut self, hash: &H256) {
self.decanonized.push(hash.clone());
}
}
#[derive(Debug)]
pub enum BlockInsertedChain {
Disconnected,
Main,
Side,
Reorganized(Reorganization),
}
pub trait BlockStapler {
/// return the location of this block once if it ever gets inserted
fn accepted_location(&self, header: &chain::BlockHeader) -> Option<BlockLocation>;
/// insert block in the storage
fn insert_block(&self, block: &chain::Block) -> Result<BlockInsertedChain, Error>;
}

75
db/src/error.rs Normal file
View File

@ -0,0 +1,75 @@
use primitives::hash::H256;
use std;
#[derive(Debug)]
/// Database error
pub enum Error {
/// Rocksdb error
DB(String),
/// Io error
Io(std::io::Error),
/// Invalid meta info (while opening the database)
Meta(MetaError),
/// Database blockchain consistency error
Consistency(ConsistencyError),
}
impl Error {
pub fn unknown_hash(h: &H256) -> Self {
Error::Consistency(ConsistencyError::Unknown(h.clone()))
}
pub fn unknown_number(n: u32) -> Self {
Error::Consistency(ConsistencyError::UnknownNumber(n))
}
pub fn double_spend(h: &H256) -> Self {
Error::Consistency(ConsistencyError::DoubleSpend(h.clone()))
}
pub fn not_main(h: &H256) -> Self {
Error::Consistency(ConsistencyError::NotMain(h.clone()))
}
pub fn reorganize(h: &H256) -> Self {
Error::Consistency(ConsistencyError::Reorganize(h.clone()))
}
}
#[derive(Debug, PartialEq)]
pub enum ConsistencyError {
/// Unknown hash
Unknown(H256),
/// Unknown number
UnknownNumber(u32),
/// Not the block from the main chain
NotMain(H256),
/// Fork too long
ForkTooLong,
/// Main chain block transaction attempts to double-spend
DoubleSpend(H256),
/// Transaction tries to spend
UnknownSpending(H256),
/// Chain has no best block
NoBestBlock,
/// Failed reorganization caused by block
Reorganize(H256),
}
#[derive(Debug, PartialEq)]
pub enum MetaError {
UnsupportedVersion,
}
impl From<String> for Error {
fn from(err: String) -> Error {
Error::DB(err)
}
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Error {
Error::Io(err)
}
}

View File

@ -21,6 +21,12 @@ mod storage;
#[cfg(feature="dev")]
mod test_storage;
mod transaction_meta;
mod block_provider;
mod block_stapler;
mod transaction_provider;
mod transaction_meta_provider;
mod error;
mod update_context;
pub enum BlockRef {
Number(u32),
@ -33,9 +39,16 @@ pub enum BlockLocation {
Side(u32),
}
pub type SharedStore = std::sync::Arc<Store + Send + Sync>;
pub use best_block::BestBlock;
pub use storage::{Storage, Store, Error, BlockInsertedChain};
pub use storage::{Storage, Store};
pub use error::Error;
pub use kvdb::Database;
pub use transaction_provider::TransactionProvider;
pub use transaction_meta_provider::TransactionMetaProvider;
pub use block_stapler::{BlockStapler, BlockInsertedChain};
pub use block_provider::BlockProvider;
#[cfg(feature="dev")]
pub use test_storage::TestStorage;

View File

@ -2,7 +2,7 @@
use std::{self, fs};
use std::path::Path;
use kvdb::{DBTransaction, Database, DatabaseConfig};
use kvdb::{Database, DatabaseConfig};
use byteorder::{LittleEndian, ByteOrder};
use primitives::hash::H256;
use primitives::bytes::Bytes;
@ -11,15 +11,21 @@ use serialization;
use chain::{self, RepresentH256};
use parking_lot::RwLock;
use transaction_meta::TransactionMeta;
use std::collections::HashMap;
const COL_COUNT: u32 = 10;
const COL_META: u32 = 0;
const COL_BLOCK_HASHES: u32 = 1;
const COL_BLOCK_HEADERS: u32 = 2;
const COL_BLOCK_TRANSACTIONS: u32 = 3;
const COL_TRANSACTIONS: u32 = 4;
const COL_TRANSACTIONS_META: u32 = 5;
use error::{Error, ConsistencyError, MetaError};
use update_context::UpdateContext;
use block_provider::BlockProvider;
use transaction_provider::TransactionProvider;
use transaction_meta_provider::TransactionMetaProvider;
use block_stapler::{BlockStapler, BlockInsertedChain, Reorganization};
pub const COL_COUNT: u32 = 10;
pub const COL_META: u32 = 0;
pub const COL_BLOCK_HASHES: u32 = 1;
pub const COL_BLOCK_HEADERS: u32 = 2;
pub const COL_BLOCK_TRANSACTIONS: u32 = 3;
pub const COL_TRANSACTIONS: u32 = 4;
pub const COL_TRANSACTIONS_META: u32 = 5;
const COL_BLOCK_NUMBERS: u32 = 6;
const _COL_RESERVED3: u32 = 7;
const _COL_RESERVED4: u32 = 8;
@ -31,52 +37,9 @@ const DB_VERSION: u32 = 1;
const MAX_FORK_ROUTE_PRESET: usize = 128;
/// Blockchain storage interface
pub trait Store : Send + Sync {
pub trait Store : BlockProvider + BlockStapler + TransactionProvider + TransactionMetaProvider {
/// get best block
fn best_block(&self) -> Option<BestBlock>;
/// resolves number by block hash
fn block_number(&self, hash: &H256) -> Option<u32>;
/// resolves hash by block number
fn block_hash(&self, number: u32) -> Option<H256>;
/// resolves header bytes by block reference (number/hash)
fn block_header_bytes(&self, block_ref: BlockRef) -> Option<Bytes>;
/// resolves list of block transactions by block reference (number/hash)
fn block_transaction_hashes(&self, block_ref: BlockRef) -> Vec<H256>;
/// resolves transaction body bytes by transaction hash
fn transaction_bytes(&self, hash: &H256) -> Option<Bytes>;
/// resolves serialized transaction info by transaction hash
fn transaction(&self, hash: &H256) -> Option<chain::Transaction>;
/// returns all transactions in the block by block reference (number/hash)
fn block_transactions(&self, block_ref: BlockRef) -> Vec<chain::Transaction>;
/// resolves deserialized block body by block reference (number/hash)
fn block(&self, block_ref: BlockRef) -> Option<chain::Block>;
/// returns true if store contains given block
fn contains_block(&self, block_ref: BlockRef) -> bool {
self.block_header_bytes(block_ref).is_some()
}
/// returns true if store contains given transaction
fn contains_transaction(&self, hash: &H256) -> bool {
self.transaction(hash).is_some()
}
/// insert block in the storage
fn insert_block(&self, block: &chain::Block) -> Result<BlockInsertedChain, Error>;
/// get transaction metadata
fn transaction_meta(&self, hash: &H256) -> Option<TransactionMeta>;
/// return the location of this block once if it ever gets inserted
fn accepted_location(&self, header: &chain::BlockHeader) -> Option<BlockLocation>;
}
/// Blockchain storage with rocksdb database
@ -85,77 +48,9 @@ pub struct Storage {
best_block: RwLock<Option<BestBlock>>,
}
#[derive(Debug, PartialEq)]
pub enum MetaError {
UnsupportedVersion,
}
#[derive(Debug)]
/// Database error
pub enum Error {
/// Rocksdb error
DB(String),
/// Io error
Io(std::io::Error),
/// Invalid meta info (while opening the database)
Meta(MetaError),
/// Database blockchain consistency error
Consistency(ConsistencyError),
}
impl Error {
fn unknown_hash(h: &H256) -> Self {
Error::Consistency(ConsistencyError::Unknown(h.clone()))
}
fn unknown_number(n: u32) -> Self {
Error::Consistency(ConsistencyError::UnknownNumber(n))
}
fn double_spend(h: &H256) -> Self {
Error::Consistency(ConsistencyError::DoubleSpend(h.clone()))
}
fn not_main(h: &H256) -> Self {
Error::Consistency(ConsistencyError::NotMain(h.clone()))
}
fn reorganize(h: &H256) -> Self {
Error::Consistency(ConsistencyError::Reorganize(h.clone()))
}
}
#[derive(Debug, PartialEq)]
pub enum ConsistencyError {
/// Unknown hash
Unknown(H256),
/// Unknown number
UnknownNumber(u32),
/// Not the block from the main chain
NotMain(H256),
/// Fork too long
ForkTooLong,
/// Main chain block transaction attempts to double-spend
DoubleSpend(H256),
/// Transaction tries to spend
UnknownSpending(H256),
/// Chain has no best block
NoBestBlock,
/// Failed reorganization caused by block
Reorganize(H256),
}
impl From<String> for Error {
fn from(err: String) -> Error {
Error::DB(err)
}
}
impl From<std::io::Error> for Error {
fn from(err: std::io::Error) -> Error {
Error::Io(err)
}
}
const KEY_VERSION: &'static[u8] = b"version";
const KEY_BEST_BLOCK_NUMBER: &'static[u8] = b"best_block_number";
const KEY_BEST_BLOCK_HASH: &'static[u8] = b"best_block_hash";
fn u32_key(num: u32) -> [u8; 4] {
let mut result = [0u8; 4];
@ -163,78 +58,6 @@ fn u32_key(num: u32) -> [u8; 4] {
result
}
const KEY_VERSION: &'static[u8] = b"version";
const KEY_BEST_BLOCK_NUMBER: &'static[u8] = b"best_block_number";
const KEY_BEST_BLOCK_HASH: &'static[u8] = b"best_block_hash";
struct UpdateContext {
pub meta: HashMap<H256, TransactionMeta>,
pub db_transaction: DBTransaction,
meta_snapshot: Option<HashMap<H256, TransactionMeta>>,
}
impl UpdateContext {
pub fn new(db: &Database) -> Self {
UpdateContext {
meta: HashMap::new(),
db_transaction: db.transaction(),
meta_snapshot: None,
}
}
pub fn apply(mut self, db: &Database) -> Result<(), Error> {
// actually saving meta
for (hash, meta) in self.meta.drain() {
self.db_transaction.put(Some(COL_TRANSACTIONS_META), &*hash, &meta.into_bytes());
}
try!(db.write(self.db_transaction));
Ok(())
}
pub fn restore_point(&mut self) {
// todo: optimize clone here
self.meta_snapshot = Some(self.meta.clone());
self.db_transaction.remember();
}
pub fn restore(&mut self) {
if let Some(meta_snapshot) = std::mem::replace(&mut self.meta_snapshot, None) {
self.meta = meta_snapshot;
self.db_transaction.rollback();
}
}
}
#[derive(Debug)]
pub struct Reorganization {
height: u32,
canonized: Vec<H256>,
decanonized: Vec<H256>,
}
impl Reorganization {
fn new(height: u32) -> Reorganization {
Reorganization { height: height, canonized: Vec::new(), decanonized: Vec::new() }
}
fn push_canonized(&mut self, hash: &H256) {
self.canonized.push(hash.clone());
}
fn push_decanonized(&mut self, hash: &H256) {
self.decanonized.push(hash.clone());
}
}
#[derive(Debug)]
pub enum BlockInsertedChain {
Disconnected,
Main,
Side,
Reorganized(Reorganization),
}
impl Storage {
/// new storage at the selected path
@ -557,11 +380,7 @@ impl Storage {
}
}
impl Store for Storage {
fn best_block(&self) -> Option<BestBlock> {
self.best_block.read().clone()
}
impl BlockProvider for Storage {
fn block_number(&self, hash: &H256) -> Option<u32> {
self.get(COL_BLOCK_NUMBERS, &**hash)
.map(|val| LittleEndian::read_u32(&val))
@ -588,10 +407,6 @@ impl Store for Storage {
.unwrap_or_default()
}
fn transaction_bytes(&self, hash: &H256) -> Option<Bytes> {
self.get(COL_TRANSACTIONS, &**hash)
}
fn block(&self, block_ref: BlockRef) -> Option<chain::Block> {
self.resolve_hash(block_ref).and_then(|block_hash|
self.get(COL_BLOCK_HEADERS, &*block_hash)
@ -608,6 +423,9 @@ impl Store for Storage {
})
)
}
}
impl BlockStapler for Storage {
fn insert_block(&self, block: &chain::Block) -> Result<BlockInsertedChain, Error> {
@ -744,20 +562,6 @@ impl Store for Storage {
Ok(result)
}
fn transaction(&self, hash: &H256) -> Option<chain::Transaction> {
self.transaction_bytes(hash).and_then(|tx_bytes| {
serialization::deserialize(tx_bytes.as_ref()).map_err(
|e| self.db_error(format!("Error deserializing transaction, possible db corruption ({:?})", e))
).ok()
})
}
fn transaction_meta(&self, hash: &H256) -> Option<TransactionMeta> {
self.get(COL_TRANSACTIONS_META, &**hash).map(|val|
TransactionMeta::from_bytes(&val).unwrap_or_else(|e| panic!("Invalid transaction metadata: db corrupted? ({:?})", e))
)
}
fn accepted_location(&self, header: &chain::BlockHeader) -> Option<BlockLocation> {
let best_number = match self.best_block() {
None => { return Some(BlockLocation::Main(0)); },
@ -781,10 +585,46 @@ impl Store for Storage {
}
}
impl TransactionProvider for Storage {
fn transaction_bytes(&self, hash: &H256) -> Option<Bytes> {
self.get(COL_TRANSACTIONS, &**hash)
}
fn transaction(&self, hash: &H256) -> Option<chain::Transaction> {
self.transaction_bytes(hash).map(|tx_bytes| {
serialization::deserialize(tx_bytes.as_ref())
.unwrap_or_else(|e| panic!("Failed to deserialize transaction: db corrupted? ({:?})", e))
})
}
}
impl TransactionMetaProvider for Storage {
fn transaction_meta(&self, hash: &H256) -> Option<TransactionMeta> {
self.get(COL_TRANSACTIONS_META, &**hash).map(|val|
TransactionMeta::from_bytes(&val).unwrap_or_else(|e| panic!("Invalid transaction metadata: db corrupted? ({:?})", e))
)
}
}
impl Store for Storage {
fn best_block(&self) -> Option<BestBlock> {
self.best_block.read().clone()
}
}
#[cfg(test)]
mod tests {
use super::{Storage, Store, UpdateContext, Error, ConsistencyError, BlockInsertedChain};
use block_provider::BlockProvider;
use block_stapler::{BlockStapler, BlockInsertedChain};
use transaction_meta_provider::TransactionMetaProvider;
use transaction_provider::TransactionProvider;
use update_context::UpdateContext;
use error::{ConsistencyError, Error};
use super::{Storage, Store};
use devtools::RandomTempPath;
use chain::{Block, RepresentH256};
use super::super::{BlockRef, BlockLocation};

View File

@ -1,6 +1,9 @@
//! Test storage
use super::{BlockRef, Store, Error, BestBlock, BlockLocation, BlockInsertedChain};
use super::{
BlockRef, Store, Error, BestBlock, BlockLocation, BlockInsertedChain, BlockProvider,
BlockStapler, TransactionMetaProvider, TransactionProvider,
};
use chain::{self, Block, RepresentH256};
use primitives::hash::H256;
use serialization;
@ -59,10 +62,7 @@ impl TestStorage {
}
}
impl Store for TestStorage {
fn best_block(&self) -> Option<BestBlock> {
self.data.read().best_block.clone()
}
impl BlockProvider for TestStorage {
fn block_number(&self, hash: &H256) -> Option<u32> {
let data = self.data.read();
@ -89,17 +89,6 @@ impl Store for TestStorage {
.unwrap_or(Vec::new())
}
fn transaction_bytes(&self, hash: &H256) -> Option<Bytes> {
self.transaction(hash).map(|tx| serialization::serialize(&tx))
}
fn transaction(&self, hash: &H256) -> Option<chain::Transaction> {
let data = self.data.read();
data.blocks.iter().flat_map(|(_, b)| b.transactions())
.find(|ref tx| tx.hash() == *hash)
.cloned()
}
fn block_transactions(&self, block_ref: BlockRef) -> Vec<chain::Transaction> {
self.block(block_ref)
.map(|b| b.transactions().iter().cloned().collect())
@ -112,6 +101,9 @@ impl Store for TestStorage {
.and_then(|ref h| data.blocks.get(h))
.cloned()
}
}
impl BlockStapler for TestStorage {
fn insert_block(&self, block: &chain::Block) -> Result<BlockInsertedChain, Error> {
let hash = block.hash();
@ -147,11 +139,6 @@ impl Store for TestStorage {
Ok(BlockInsertedChain::Main)
}
// just spawns new meta so far, use real store for proper tests
fn transaction_meta(&self, hash: &H256) -> Option<TransactionMeta> {
self.transaction(hash).map(|tx| TransactionMeta::new(0, tx.outputs.len()))
}
// supports only main chain in test storage
fn accepted_location(&self, header: &chain::BlockHeader) -> Option<BlockLocation> {
if self.best_block().is_none() { return Some(BlockLocation::Main(0)); }
@ -161,6 +148,32 @@ impl Store for TestStorage {
None
}
}
impl TransactionProvider for TestStorage {
fn transaction_bytes(&self, hash: &H256) -> Option<Bytes> {
self.transaction(hash).map(|tx| serialization::serialize(&tx))
}
fn transaction(&self, hash: &H256) -> Option<chain::Transaction> {
let data = self.data.read();
data.blocks.iter().flat_map(|(_, b)| b.transactions())
.find(|ref tx| tx.hash() == *hash)
.cloned()
}
}
impl TransactionMetaProvider for TestStorage {
// just spawns new meta so far, use real store for proper tests
fn transaction_meta(&self, hash: &H256) -> Option<TransactionMeta> {
self.transaction(hash).map(|tx| TransactionMeta::new(0, tx.outputs.len()))
}
}
impl Store for TestStorage {
fn best_block(&self) -> Option<BestBlock> {
self.data.read().best_block.clone()
}
}

View File

@ -0,0 +1,7 @@
use transaction_meta::TransactionMeta;
use primitives::hash::H256;
pub trait TransactionMetaProvider {
/// get transaction metadata
fn transaction_meta(&self, hash: &H256) -> Option<TransactionMeta>;
}

View File

@ -0,0 +1,18 @@
use primitives::hash::H256;
use primitives::bytes::Bytes;
use chain;
pub trait TransactionProvider {
/// returns true if store contains given transaction
fn contains_transaction(&self, hash: &H256) -> bool {
self.transaction(hash).is_some()
}
/// resolves transaction body bytes by transaction hash
fn transaction_bytes(&self, hash: &H256) -> Option<Bytes>;
/// resolves serialized transaction info by transaction hash
fn transaction(&self, hash: &H256) -> Option<chain::Transaction>;
}

46
db/src/update_context.rs Normal file
View File

@ -0,0 +1,46 @@
use kvdb::{DBTransaction, Database};
use transaction_meta::TransactionMeta;
use std::collections::HashMap;
use storage::COL_TRANSACTIONS_META;
use primitives::hash::H256;
use error::Error;
use std;
pub struct UpdateContext {
pub meta: HashMap<H256, TransactionMeta>,
pub db_transaction: DBTransaction,
meta_snapshot: Option<HashMap<H256, TransactionMeta>>,
}
impl UpdateContext {
pub fn new(db: &Database) -> Self {
UpdateContext {
meta: HashMap::new(),
db_transaction: db.transaction(),
meta_snapshot: None,
}
}
pub fn apply(mut self, db: &Database) -> Result<(), Error> {
// actually saving meta
for (hash, meta) in self.meta.drain() {
self.db_transaction.put(Some(COL_TRANSACTIONS_META), &*hash, &meta.into_bytes());
}
try!(db.write(self.db_transaction));
Ok(())
}
pub fn restore_point(&mut self) {
// todo: optimize clone here
self.meta_snapshot = Some(self.meta.clone());
self.db_transaction.remember();
}
pub fn restore(&mut self) {
if let Some(meta_snapshot) = std::mem::replace(&mut self.meta_snapshot, None) {
self.meta = meta_snapshot;
self.db_transaction.rollback();
}
}
}

View File

@ -5,7 +5,7 @@ use chain::RepresentH256;
use {db, APP_INFO};
use config::Config;
pub fn open_db(_cfg: &Config) -> Arc<db::Store> {
pub fn open_db(_cfg: &Config) -> db::SharedStore {
let db_path = app_dir(AppDataType::UserData, &APP_INFO, "db").expect("Failed to get app dir");
Arc::new(db::Storage::new(db_path).expect("Failed to open database"))
}
@ -16,7 +16,7 @@ pub fn node_table_path() -> PathBuf {
node_table
}
pub fn init_db(cfg: &Config, db: &Arc<db::Store>) -> Result<(), String> {
pub fn init_db(cfg: &Config, db: &db::SharedStore) -> Result<(), String> {
// insert genesis block if db is empty
let genesis_block = cfg.magic.genesis_block();
match db.block_hash(0) {

View File

@ -10,7 +10,7 @@ pub struct BlocksWriter {
}
impl BlocksWriter {
pub fn new(storage: Arc<db::Store>) -> BlocksWriter {
pub fn new(storage: db::SharedStore) -> BlocksWriter {
BlocksWriter {
storage: storage.clone(),
verifier: ChainVerifier::new(storage),

View File

@ -49,12 +49,12 @@ pub enum Error {
}
/// Create blocks writer.
pub fn create_sync_blocks_writer(db: Arc<db::Store>) -> blocks_writer::BlocksWriter {
pub fn create_sync_blocks_writer(db: db::SharedStore) -> blocks_writer::BlocksWriter {
blocks_writer::BlocksWriter::new(db)
}
/// Create inbound synchronization connections factory for given `db`.
pub fn create_sync_connection_factory(handle: &Handle, consensus_params: ConsensusParams, db: Arc<db::Store>) -> p2p::LocalSyncNodeRef {
pub fn create_sync_connection_factory(handle: &Handle, consensus_params: ConsensusParams, db: db::SharedStore) -> p2p::LocalSyncNodeRef {
use synchronization_chain::Chain as SyncChain;
use synchronization_executor::LocalSynchronizationTaskExecutor as SyncExecutor;
use local_node::LocalNode as SyncNode;

View File

@ -101,7 +101,7 @@ pub struct Chain {
/// Best storage block (stored for optimizations)
best_storage_block: db::BestBlock,
/// Local blocks storage
storage: Arc<db::Store>,
storage: db::SharedStore,
/// In-memory queue of blocks hashes
hash_chain: HashQueueChain,
/// In-memory queue of blocks headers
@ -134,7 +134,7 @@ impl BlockState {
impl Chain {
/// Create new `Chain` with given storage
pub fn new(storage: Arc<db::Store>) -> Self {
pub fn new(storage: db::SharedStore) -> Self {
// we only work with storages with genesis block
let genesis_block_hash = storage.block_hash(0)
.expect("storage with genesis block is required");
@ -166,7 +166,7 @@ impl Chain {
}
/// Get storage
pub fn storage(&self) -> Arc<db::Store> {
pub fn storage(&self) -> db::SharedStore {
self.storage.clone()
}
@ -667,6 +667,7 @@ mod tests {
use primitives::hash::H256;
use devtools::RandomTempPath;
use test_data;
use db::BlockStapler;
#[test]
fn chain_empty() {

View File

@ -1114,12 +1114,12 @@ pub mod tests {
use db;
use devtools::RandomTempPath;
fn create_disk_storage() -> Arc<db::Store> {
fn create_disk_storage() -> db::SharedStore {
let path = RandomTempPath::create_dir();
Arc::new(db::Storage::new(path.as_path()).unwrap())
}
fn create_sync(storage: Option<Arc<db::Store>>) -> (Core, Handle, Arc<Mutex<DummyTaskExecutor>>, ChainRef, Arc<Mutex<SynchronizationClient<DummyTaskExecutor>>>) {
fn create_sync(storage: Option<db::SharedStore>) -> (Core, Handle, Arc<Mutex<DummyTaskExecutor>>, ChainRef, Arc<Mutex<SynchronizationClient<DummyTaskExecutor>>>) {
let event_loop = event_loop();
let handle = event_loop.handle();
let storage = match storage {

View File

@ -1,7 +1,5 @@
//! Bitcoin chain verifier
use std::sync::Arc;
use db::{self, BlockRef, BlockLocation};
use chain::{self, RepresentH256};
use super::{Verify, VerificationResult, Chain, Error, TransactionError, ContinueVerify};
@ -13,7 +11,7 @@ const MAX_BLOCK_SIGOPS: usize = 20000;
const MAX_BLOCK_SIZE: usize = 1000000;
pub struct ChainVerifier {
store: Arc<db::Store>,
store: db::SharedStore,
verify_p2sh: bool,
verify_clocktimeverify: bool,
skip_pow: bool,
@ -21,7 +19,7 @@ pub struct ChainVerifier {
}
impl ChainVerifier {
pub fn new(store: Arc<db::Store>) -> Self {
pub fn new(store: db::SharedStore) -> Self {
ChainVerifier {
store: store,
verify_p2sh: false,
@ -275,7 +273,7 @@ mod tests {
use super::ChainVerifier;
use super::super::{Verify, Chain, Error, TransactionError};
use db::{TestStorage, Storage, Store};
use db::{TestStorage, Storage, Store, BlockStapler};
use test_data;
use std::sync::Arc;
use devtools::RandomTempPath;