JournalDB -> Box<JournalDB>, and it's a trait.

This commit is contained in:
Gav Wood
2016-03-11 12:54:48 +01:00
parent 99e577ad2f
commit 756f964130
7 changed files with 116 additions and 89 deletions

View File

@@ -171,7 +171,7 @@ pub struct SealedBlock {
impl<'x> OpenBlock<'x> {
/// Create a new OpenBlock ready for transaction pushing.
pub fn new(engine: &'x Engine, db: JournalDB, parent: &Header, last_hashes: LastHashes, author: Address, extra_data: Bytes) -> Self {
pub fn new(engine: &'x Engine, db: Box<JournalDB + Send>, parent: &Header, last_hashes: LastHashes, author: Address, extra_data: Bytes) -> Self {
let mut r = OpenBlock {
block: ExecutedBlock::new(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce())),
engine: engine,
@@ -317,7 +317,7 @@ impl ClosedBlock {
}
/// Drop this object and return the underlieing database.
pub fn drain(self) -> JournalDB { self.block.state.drop().1 }
pub fn drain(self) -> Box<JournalDB + Send> { self.block.state.drop().1 }
}
impl SealedBlock {
@@ -331,7 +331,7 @@ impl SealedBlock {
}
/// Drop this object and return the underlieing database.
pub fn drain(self) -> JournalDB { self.block.state.drop().1 }
pub fn drain(self) -> Box<JournalDB + Send> { self.block.state.drop().1 }
}
impl IsBlock for SealedBlock {
@@ -339,10 +339,10 @@ impl IsBlock for SealedBlock {
}
/// Enact the block given by block header, transactions and uncles
pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, db: JournalDB, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, db: Box<JournalDB + Send>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
{
if ::log::max_log_level() >= ::log::LogLevel::Trace {
let s = State::from_existing(db.clone(), parent.state_root().clone(), engine.account_start_nonce());
let s = State::from_existing(db.spawn(), parent.state_root().clone(), engine.account_start_nonce());
trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()));
}
}
@@ -357,20 +357,20 @@ pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Head
}
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, db: JournalDB, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, db: Box<JournalDB + Send>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
let block = BlockView::new(block_bytes);
let header = block.header();
enact(&header, &block.transactions(), &block.uncles(), engine, db, parent, last_hashes)
}
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, db: JournalDB, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, db: Box<JournalDB + Send>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
let view = BlockView::new(&block.bytes);
enact(&block.header, &block.transactions, &view.uncles(), engine, db, parent, last_hashes)
}
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, db: JournalDB, parent: &Header, last_hashes: LastHashes) -> Result<SealedBlock, Error> {
pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, db: Box<JournalDB + Send>, parent: &Header, last_hashes: LastHashes) -> Result<SealedBlock, Error> {
let header = BlockView::new(block_bytes).header_view();
Ok(try!(try!(enact_bytes(block_bytes, engine, db, parent, last_hashes)).seal(engine, header.seal())))
}

View File

@@ -214,7 +214,7 @@ impl ClientReport {
pub struct Client<V = CanonVerifier> where V: Verifier {
chain: Arc<RwLock<BlockChain>>,
engine: Arc<Box<Engine>>,
state_db: Mutex<JournalDB>,
state_db: Mutex<Box<JournalDB + Send>>,
block_queue: RwLock<BlockQueue>,
report: RwLock<ClientReport>,
import_lock: Mutex<()>,
@@ -253,8 +253,8 @@ impl<V> Client<V> where V: Verifier {
state_path.push("state");
let engine = Arc::new(try!(spec.to_engine()));
let mut state_db = JournalDB::from_prefs(state_path.to_str().unwrap(), config.prefer_journal);
if state_db.is_empty() && engine.spec().ensure_db_good(&mut state_db) {
let mut state_db = Box::new(OptionOneDB::from_prefs(state_path.to_str().unwrap(), config.prefer_journal));
if state_db.is_empty() && engine.spec().ensure_db_good(state_db.deref_mut()) {
state_db.commit(0, &engine.spec().genesis_header().hash(), None).expect("Error commiting genesis state to state DB");
}
@@ -336,7 +336,7 @@ impl<V> Client<V> where V: Verifier {
// Enact Verified Block
let parent = chain_has_parent.unwrap();
let last_hashes = self.build_last_hashes(header.parent_hash.clone());
let db = self.state_db.lock().unwrap().clone();
let db = self.state_db.lock().unwrap().spawn();
let enact_result = enact_verified(&block, engine, db, &parent, last_hashes);
if let Err(e) = enact_result {
@@ -438,7 +438,7 @@ impl<V> Client<V> where V: Verifier {
/// Get a copy of the best block's state.
pub fn state(&self) -> State {
State::from_existing(self.state_db.lock().unwrap().clone(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
State::from_existing(self.state_db.lock().unwrap().spawn(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
}
/// Get info on the cache.
@@ -507,7 +507,7 @@ impl<V> Client<V> where V: Verifier {
let h = self.chain.read().unwrap().best_block_hash();
let mut b = OpenBlock::new(
self.engine.deref().deref(),
self.state_db.lock().unwrap().clone(),
self.state_db.lock().unwrap().spawn(),
match self.chain.read().unwrap().block_header(&h) { Some(ref x) => x, None => {return;} },
self.build_last_hashes(h.clone()),
self.author(),

View File

@@ -31,7 +31,7 @@ pub type ApplyResult = Result<Receipt, Error>;
/// Representation of the entire state of all accounts in the system.
pub struct State {
db: JournalDB,
db: Box<JournalDB + Send>,
root: H256,
cache: RefCell<HashMap<Address, Option<Account>>>,
snapshots: RefCell<Vec<HashMap<Address, Option<Option<Account>>>>>,
@@ -41,11 +41,11 @@ pub struct State {
impl State {
/// Creates new state with empty state root
#[cfg(test)]
pub fn new(mut db: JournalDB, account_start_nonce: U256) -> State {
pub fn new(mut db: Box<JournalDB + Send>, account_start_nonce: U256) -> State {
let mut root = H256::new();
{
// init trie and reset root too null
let _ = SecTrieDBMut::new(&mut db, &mut root);
let _ = SecTrieDBMut::new(db.deref_mut(), &mut root);
}
State {
@@ -58,10 +58,10 @@ impl State {
}
/// Creates new state with existing state root
pub fn from_existing(db: JournalDB, root: H256, account_start_nonce: U256) -> State {
pub fn from_existing(db: Box<JournalDB + Send>, root: H256, account_start_nonce: U256) -> State {
{
// trie should panic! if root does not exist
let _ = SecTrieDB::new(&db, &root);
let _ = SecTrieDB::new(db.as_hashdb(), &root);
}
State {
@@ -126,7 +126,7 @@ impl State {
}
/// Destroy the current object and return root and database.
pub fn drop(self) -> (H256, JournalDB) {
pub fn drop(self) -> (H256, Box<JournalDB + Send>) {
(self.root, self.db)
}
@@ -148,7 +148,7 @@ impl State {
/// Determine whether an account exists.
pub fn exists(&self, a: &Address) -> bool {
self.cache.borrow().get(&a).unwrap_or(&None).is_some() || SecTrieDB::new(&self.db, &self.root).contains(&a)
self.cache.borrow().get(&a).unwrap_or(&None).is_some() || SecTrieDB::new(self.db.as_hashdb(), &self.root).contains(&a)
}
/// Get the balance of account `a`.
@@ -163,7 +163,7 @@ impl State {
/// Mutate storage of account `address` so that it is `value` for `key`.
pub fn storage_at(&self, address: &Address, key: &H256) -> H256 {
self.get(address, false).as_ref().map_or(H256::new(), |a|a.storage_at(&AccountDB::new(&self.db, address), key))
self.get(address, false).as_ref().map_or(H256::new(), |a|a.storage_at(&AccountDB::new(self.db.as_hashdb(), address), key))
}
/// Mutate storage of account `a` so that it is `value` for `key`.
@@ -253,7 +253,7 @@ impl State {
/// Commits our cached account changes into the trie.
pub fn commit(&mut self) {
assert!(self.snapshots.borrow().is_empty());
Self::commit_into(&mut self.db, &mut self.root, self.cache.borrow_mut().deref_mut());
Self::commit_into(self.db.as_hashdb_mut(), &mut self.root, self.cache.borrow_mut().deref_mut());
}
#[cfg(test)]
@@ -285,11 +285,11 @@ impl State {
fn get<'a>(&'a self, a: &Address, require_code: bool) -> &'a Option<Account> {
let have_key = self.cache.borrow().contains_key(a);
if !have_key {
self.insert_cache(a, SecTrieDB::new(&self.db, &self.root).get(&a).map(Account::from_rlp))
self.insert_cache(a, SecTrieDB::new(self.db.as_hashdb(), &self.root).get(&a).map(Account::from_rlp))
}
if require_code {
if let Some(ref mut account) = self.cache.borrow_mut().get_mut(a).unwrap().as_mut() {
account.cache_code(&AccountDB::new(&self.db, a));
account.cache_code(&AccountDB::new(self.db.as_hashdb(), a));
}
}
unsafe { ::std::mem::transmute(self.cache.borrow().get(a).unwrap()) }
@@ -305,7 +305,7 @@ impl State {
fn require_or_from<'a, F: FnOnce() -> Account, G: FnOnce(&mut Account)>(&self, a: &Address, require_code: bool, default: F, not_default: G) -> &'a mut Account {
let have_key = self.cache.borrow().contains_key(a);
if !have_key {
self.insert_cache(a, SecTrieDB::new(&self.db, &self.root).get(&a).map(Account::from_rlp))
self.insert_cache(a, SecTrieDB::new(self.db.as_hashdb(), &self.root).get(&a).map(Account::from_rlp))
} else {
self.note_cache(a);
}
@@ -318,7 +318,7 @@ impl State {
unsafe { ::std::mem::transmute(self.cache.borrow_mut().get_mut(a).unwrap().as_mut().map(|account| {
if require_code {
account.cache_code(&AccountDB::new(&self.db, a));
account.cache_code(&AccountDB::new(self.db.as_hashdb(), a));
}
account
}).unwrap()) }

View File

@@ -250,9 +250,9 @@ pub fn generate_dummy_empty_blockchain() -> GuardedTempResult<BlockChain> {
}
}
pub fn get_temp_journal_db() -> GuardedTempResult<JournalDB> {
pub fn get_temp_journal_db() -> GuardedTempResult<Box<JournalDB + Send>> {
let temp = RandomTempPath::new();
let journal_db = JournalDB::new(temp.as_str());
let journal_db = Box::new(OptionOneDB::new(temp.as_str()));
GuardedTempResult {
_temp: temp,
result: Some(journal_db)
@@ -268,8 +268,8 @@ pub fn get_temp_state() -> GuardedTempResult<State> {
}
}
pub fn get_temp_journal_db_in(path: &Path) -> JournalDB {
JournalDB::new(path.to_str().unwrap())
pub fn get_temp_journal_db_in(path: &Path) -> Box<JournalDB + Send> {
Box::new(OptionOneDB::new(path.to_str().unwrap()))
}
pub fn get_temp_state_in(path: &Path) -> State {