Skip to content

Commit

Permalink
remove internal locking from DBTransaction (openethereum#2003)
Browse files Browse the repository at this point in the history
  • Loading branch information
rphmeier authored and arkpar committed Aug 25, 2016
1 parent b18407b commit 2aef81c
Show file tree
Hide file tree
Showing 17 changed files with 121 additions and 119 deletions.
88 changes: 44 additions & 44 deletions ethcore/src/blockchain/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ impl BlockChain {
children: vec![]
};

let batch = DBTransaction::new(&db);
let mut batch = DBTransaction::new(&db);
batch.put(db::COL_HEADERS, &hash, block.header_rlp().as_raw());
batch.put(db::COL_BODIES, &hash, &Self::block_to_body(genesis));

Expand Down Expand Up @@ -419,7 +419,7 @@ impl BlockChain {
}
}

let batch = db.transaction();
let mut batch = db.transaction();
batch.put(db::COL_EXTRA, b"first", &hash);
db.write(batch).expect("Low level database error.");

Expand Down Expand Up @@ -451,7 +451,7 @@ impl BlockChain {
#[cfg(test)]
fn rewind(&self) -> Option<H256> {
use db::Key;
let batch = self.db.transaction();
let mut batch =self.db.transaction();
// track back to the best block we have in the blocks database
if let Some(best_block_hash) = self.db.get(db::COL_EXTRA, b"best").unwrap() {
let best_block_hash = H256::from_slice(&best_block_hash);
Expand Down Expand Up @@ -604,7 +604,7 @@ impl BlockChain {

assert!(self.pending_best_block.read().is_none());

let batch = self.db.transaction();
let mut batch = self.db.transaction();

let block_rlp = UntrustedRlp::new(bytes);
let compressed_header = block_rlp.at(0).unwrap().compress(RlpType::Blocks);
Expand All @@ -625,7 +625,7 @@ impl BlockChain {
location: BlockLocation::CanonChain,
};

self.prepare_update(&batch, ExtrasUpdate {
self.prepare_update(&mut batch, ExtrasUpdate {
block_hashes: self.prepare_block_hashes_update(bytes, &info),
block_details: self.prepare_block_details_update(bytes, &info),
block_receipts: self.prepare_block_receipts_update(receipts, &info),
Expand Down Expand Up @@ -659,7 +659,7 @@ impl BlockChain {
let mut update = HashMap::new();
update.insert(hash, block_details);

self.prepare_update(&batch, ExtrasUpdate {
self.prepare_update(&mut batch, ExtrasUpdate {
block_hashes: self.prepare_block_hashes_update(bytes, &info),
block_details: update,
block_receipts: self.prepare_block_receipts_update(receipts, &info),
Expand All @@ -682,7 +682,7 @@ impl BlockChain {
let mut parent_details = self.block_details(&block_hash)
.unwrap_or_else(|| panic!("Invalid block hash: {:?}", block_hash));

let batch = self.db.transaction();
let mut batch = self.db.transaction();
parent_details.children.push(child_hash);

let mut update = HashMap::new();
Expand All @@ -701,7 +701,7 @@ impl BlockChain {
/// Inserts the block into backing cache database.
/// Expects the block to be valid and already verified.
/// If the block is already known, does nothing.
pub fn insert_block(&self, batch: &DBTransaction, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
pub fn insert_block(&self, batch: &mut DBTransaction, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
// create views onto rlp
let block = BlockView::new(bytes);
let header = block.header_view();
Expand Down Expand Up @@ -782,7 +782,7 @@ impl BlockChain {
}

/// Prepares extras update.
fn prepare_update(&self, batch: &DBTransaction, update: ExtrasUpdate, is_best: bool) {
fn prepare_update(&self, batch: &mut DBTransaction, update: ExtrasUpdate, is_best: bool) {
{
let block_hashes: Vec<_> = update.block_details.keys().cloned().collect();

Expand Down Expand Up @@ -1147,8 +1147,8 @@ mod tests {
assert_eq!(bc.best_block_number(), 0);

// when
let batch = db.transaction();
bc.insert_block(&batch, &first, vec![]);
let mut batch =db.transaction();
bc.insert_block(&mut batch, &first, vec![]);
assert_eq!(bc.best_block_number(), 0);
bc.commit();
// NOTE no db.write here (we want to check if best block is cached)
Expand Down Expand Up @@ -1177,8 +1177,8 @@ mod tests {
assert_eq!(bc.block_hash(1), None);
assert_eq!(bc.block_details(&genesis_hash).unwrap().children, vec![]);

let batch = db.transaction();
bc.insert_block(&batch, &first, vec![]);
let mut batch =db.transaction();
bc.insert_block(&mut batch, &first, vec![]);
db.write(batch).unwrap();
bc.commit();

Expand All @@ -1203,11 +1203,11 @@ mod tests {
let bc = BlockChain::new(Config::default(), &genesis, db.clone());

let mut block_hashes = vec![genesis_hash.clone()];
let batch = db.transaction();
let mut batch =db.transaction();
for _ in 0..10 {
let block = canon_chain.generate(&mut finalizer).unwrap();
block_hashes.push(BlockView::new(&block).header_view().sha3());
bc.insert_block(&batch, &block, vec![]);
bc.insert_block(&mut batch, &block, vec![]);
bc.commit();
}
db.write(batch).unwrap();
Expand Down Expand Up @@ -1238,20 +1238,20 @@ mod tests {
let db = new_db(temp.as_str());
let bc = BlockChain::new(Config::default(), &genesis, db.clone());

let batch = db.transaction();
let mut batch =db.transaction();
for b in &[&b1a, &b1b, &b2a, &b2b, &b3a, &b3b, &b4a, &b4b, &b5a, &b5b] {
bc.insert_block(&batch, b, vec![]);
bc.insert_block(&mut batch, b, vec![]);
bc.commit();
}
bc.insert_block(&batch, &b1b, vec![]);
bc.insert_block(&batch, &b2a, vec![]);
bc.insert_block(&batch, &b2b, vec![]);
bc.insert_block(&batch, &b3a, vec![]);
bc.insert_block(&batch, &b3b, vec![]);
bc.insert_block(&batch, &b4a, vec![]);
bc.insert_block(&batch, &b4b, vec![]);
bc.insert_block(&batch, &b5a, vec![]);
bc.insert_block(&batch, &b5b, vec![]);
bc.insert_block(&mut batch, &b1b, vec![]);
bc.insert_block(&mut batch, &b2a, vec![]);
bc.insert_block(&mut batch, &b2b, vec![]);
bc.insert_block(&mut batch, &b3a, vec![]);
bc.insert_block(&mut batch, &b3b, vec![]);
bc.insert_block(&mut batch, &b4a, vec![]);
bc.insert_block(&mut batch, &b4b, vec![]);
bc.insert_block(&mut batch, &b5a, vec![]);
bc.insert_block(&mut batch, &b5b, vec![]);
db.write(batch).unwrap();

assert_eq!(
Expand Down Expand Up @@ -1286,17 +1286,17 @@ mod tests {
let db = new_db(temp.as_str());
let bc = BlockChain::new(Config::default(), &genesis, db.clone());

let batch = db.transaction();
let ir1 = bc.insert_block(&batch, &b1, vec![]);
let mut batch =db.transaction();
let ir1 = bc.insert_block(&mut batch, &b1, vec![]);
bc.commit();
let ir2 = bc.insert_block(&batch, &b2, vec![]);
let ir2 = bc.insert_block(&mut batch, &b2, vec![]);
bc.commit();
let ir3b = bc.insert_block(&batch, &b3b, vec![]);
let ir3b = bc.insert_block(&mut batch, &b3b, vec![]);
bc.commit();
db.write(batch).unwrap();
assert_eq!(bc.block_hash(3).unwrap(), b3b_hash);
let batch = db.transaction();
let ir3a = bc.insert_block(&batch, &b3a, vec![]);
let mut batch =db.transaction();
let ir3a = bc.insert_block(&mut batch, &b3a, vec![]);
bc.commit();
db.write(batch).unwrap();

Expand Down Expand Up @@ -1402,8 +1402,8 @@ mod tests {
let db = new_db(temp.as_str());
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
assert_eq!(bc.best_block_hash(), genesis_hash);
let batch = db.transaction();
bc.insert_block(&batch, &first, vec![]);
let mut batch =db.transaction();
bc.insert_block(&mut batch, &first, vec![]);
db.write(batch).unwrap();
bc.commit();
assert_eq!(bc.best_block_hash(), first_hash);
Expand Down Expand Up @@ -1467,8 +1467,8 @@ mod tests {
let temp = RandomTempPath::new();
let db = new_db(temp.as_str());
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
let batch = db.transaction();
bc.insert_block(&batch, &b1, vec![]);
let mut batch =db.transaction();
bc.insert_block(&mut batch, &b1, vec![]);
db.write(batch).unwrap();
bc.commit();

Expand All @@ -1480,8 +1480,8 @@ mod tests {
}

fn insert_block(db: &Arc<Database>, bc: &BlockChain, bytes: &[u8], receipts: Vec<Receipt>) -> ImportRoute {
let batch = db.transaction();
let res = bc.insert_block(&batch, bytes, receipts);
let mut batch =db.transaction();
let res = bc.insert_block(&mut batch, bytes, receipts);
db.write(batch).unwrap();
bc.commit();
res
Expand Down Expand Up @@ -1569,16 +1569,16 @@ mod tests {
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap();

let batch = db.transaction();
let mut batch =db.transaction();
// create a longer fork
for _ in 0..5 {
let canon_block = canon_chain.generate(&mut finalizer).unwrap();
bc.insert_block(&batch, &canon_block, vec![]);
bc.insert_block(&mut batch, &canon_block, vec![]);
bc.commit();
}

assert_eq!(bc.best_block_number(), 5);
bc.insert_block(&batch, &uncle, vec![]);
bc.insert_block(&mut batch, &uncle, vec![]);
db.write(batch).unwrap();
bc.commit();
}
Expand All @@ -1604,10 +1604,10 @@ mod tests {
let db = new_db(temp.as_str());
let bc = BlockChain::new(Config::default(), &genesis, db.clone());

let batch = db.transaction();
bc.insert_block(&batch, &first, vec![]);
let mut batch =db.transaction();
bc.insert_block(&mut batch, &first, vec![]);
bc.commit();
bc.insert_block(&batch, &second, vec![]);
bc.insert_block(&mut batch, &second, vec![]);
bc.commit();
db.write(batch).unwrap();

Expand Down
12 changes: 6 additions & 6 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ impl Client {

let mut state_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
if state_db.is_empty() && try!(spec.ensure_db_good(state_db.as_hashdb_mut())) {
let batch = DBTransaction::new(&db);
try!(state_db.commit(&batch, 0, &spec.genesis_header().hash(), None));
let mut batch = DBTransaction::new(&db);
try!(state_db.commit(&mut batch, 0, &spec.genesis_header().hash(), None));
try!(db.write(batch).map_err(ClientError::Database));
}

Expand Down Expand Up @@ -431,14 +431,14 @@ impl Client {

//let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));

let batch = DBTransaction::new(&self.db);
let mut batch = DBTransaction::new(&self.db);
// CHECK! I *think* this is fine, even if the state_root is equal to another
// already-imported block of the same number.
// TODO: Prove it with a test.
block.drain().commit(&batch, number, hash, ancient).expect("DB commit failed.");
block.drain().commit(&mut batch, number, hash, ancient).expect("DB commit failed.");

let route = self.chain.insert_block(&batch, block_data, receipts);
self.tracedb.import(&batch, TraceImportRequest {
let route = self.chain.insert_block(&mut batch, block_data, receipts);
self.tracedb.import(&mut batch, TraceImportRequest {
traces: traces.into(),
block_hash: hash.clone(),
block_number: number,
Expand Down
8 changes: 4 additions & 4 deletions ethcore/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ pub trait Key<T> {
/// Should be used to write value into database.
pub trait Writable {
/// Writes the value into the database.
fn write<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]>;
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]>;

/// Writes the value into the database and updates the cache.
fn write_with_cache<K, T, R>(&self, col: Option<u32>, cache: &mut Cache<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
fn write_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, key: K, value: T, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: Encodable,
R: Deref<Target = [u8]> {
Expand All @@ -102,7 +102,7 @@ pub trait Writable {
}

/// Writes the values into the database and updates the cache.
fn extend_with_cache<K, T, R>(&self, col: Option<u32>, cache: &mut Cache<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where
fn extend_with_cache<K, T, R>(&mut self, col: Option<u32>, cache: &mut Cache<K, T>, values: HashMap<K, T>, policy: CacheUpdatePolicy) where
K: Key<T, Target = R> + Hash + Eq,
T: Encodable,
R: Deref<Target = [u8]> {
Expand Down Expand Up @@ -169,7 +169,7 @@ pub trait Readable {
}

impl Writable for DBTransaction {
fn write<T, R>(&self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]> {
fn write<T, R>(&mut self, col: Option<u32>, key: &Key<T, Target = R>, value: &T) where T: Encodable, R: Deref<Target = [u8]> {
self.put(col, &key.key(), &encode(value));
}
}
Expand Down
4 changes: 2 additions & 2 deletions ethcore/src/snapshot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,8 @@ impl StateRebuilder {
}

let backing = self.db.backing().clone();
let batch = backing.transaction();
try!(self.db.inject(&batch));
let mut batch = backing.transaction();
try!(self.db.inject(&mut batch));
try!(backing.write(batch).map_err(::util::UtilError::SimpleString));
trace!(target: "snapshot", "current state root: {:?}", self.state_root);
Ok(())
Expand Down
8 changes: 5 additions & 3 deletions ethcore/src/snapshot/tests/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,16 @@ fn chunk_and_restore(amount: u64) {
let bc = BlockChain::new(Default::default(), &genesis, old_db.clone());

// build the blockchain.
let mut batch = old_db.transaction();
for _ in 0..amount {
let block = canon_chain.generate(&mut finalizer).unwrap();
let batch = old_db.transaction();
bc.insert_block(&batch, &block, vec![]);
bc.insert_block(&mut batch, &block, vec![]);
bc.commit();
old_db.write(batch).unwrap();
}

old_db.write(batch).unwrap();


let best_hash = bc.best_block_hash();

// snapshot it.
Expand Down
8 changes: 4 additions & 4 deletions ethcore/src/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult<BlockCh
let db = new_db(temp.as_str());
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone());

let batch = db.transaction();
let mut batch = db.transaction();
for block_order in 1..block_number {
bc.insert_block(&batch, &create_unverifiable_block(block_order, bc.best_block_hash()), vec![]);
bc.insert_block(&mut batch, &create_unverifiable_block(block_order, bc.best_block_hash()), vec![]);
bc.commit();
}
db.write(batch).unwrap();
Expand All @@ -278,9 +278,9 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempRes
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), db.clone());


let batch = db.transaction();
let mut batch = db.transaction();
for block_order in 1..block_number {
bc.insert_block(&batch, &create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None), vec![]);
bc.insert_block(&mut batch, &create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None), vec![]);
bc.commit();
}
db.write(batch).unwrap();
Expand Down
Loading

0 comments on commit 2aef81c

Please sign in to comment.