Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
merge with master
Browse files Browse the repository at this point in the history
  • Loading branch information
rphmeier committed Aug 18, 2016
2 parents a22813e + 9adf775 commit 1462f4b
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 85 deletions.
78 changes: 38 additions & 40 deletions ethcore/src/blockchain/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ use blockchain::best_block::BestBlock;
use types::tree_route::TreeRoute;
use blockchain::update::ExtrasUpdate;
use blockchain::{CacheSize, ImportRoute, Config};
use db::{Writable, Readable, CacheUpdatePolicy};
use client::{DB_COL_EXTRA, DB_COL_HEADERS, DB_COL_BODIES};
use db::{self, Writable, Readable, CacheUpdatePolicy};
use cache_manager::CacheManager;

const LOG_BLOOMS_LEVELS: usize = 3;
Expand Down Expand Up @@ -143,7 +142,7 @@ enum CacheID {
impl bc::group::BloomGroupDatabase for BlockChain {
fn blooms_at(&self, position: &bc::group::GroupPosition) -> Option<bc::group::BloomGroup> {
let position = LogGroupPosition::from(position.clone());
let result = self.db.read_with_cache(DB_COL_EXTRA, &self.blocks_blooms, &position).map(Into::into);
let result = self.db.read_with_cache(db::COL_EXTRA, &self.blocks_blooms, &position).map(Into::into);
self.cache_man.lock().note_used(CacheID::BlocksBlooms(position));
result
}
Expand Down Expand Up @@ -183,7 +182,7 @@ impl BlockProvider for BlockChain {
/// Returns true if the given block is known
/// (though not necessarily a part of the canon chain).
fn is_known(&self, hash: &H256) -> bool {
self.db.exists_with_cache(DB_COL_EXTRA, &self.block_details, hash)
self.db.exists_with_cache(db::COL_EXTRA, &self.block_details, hash)
}

fn first_block(&self) -> H256 {
Expand Down Expand Up @@ -224,7 +223,7 @@ impl BlockProvider for BlockChain {
}

// Read from DB and populate cache
let opt = self.db.get(DB_COL_HEADERS, hash)
let opt = self.db.get(db::COL_HEADERS, hash)
.expect("Low level database error. Some issue with disk?");

let result = match opt {
Expand Down Expand Up @@ -260,7 +259,7 @@ impl BlockProvider for BlockChain {
}

// Read from DB and populate cache
let opt = self.db.get(DB_COL_BODIES, hash)
let opt = self.db.get(db::COL_BODIES, hash)
.expect("Low level database error. Some issue with disk?");

let result = match opt {
Expand All @@ -280,28 +279,28 @@ impl BlockProvider for BlockChain {

/// Get the familial details concerning a block.
fn block_details(&self, hash: &H256) -> Option<BlockDetails> {
let result = self.db.read_with_cache(DB_COL_EXTRA, &self.block_details, hash);
let result = self.db.read_with_cache(db::COL_EXTRA, &self.block_details, hash);
self.cache_man.lock().note_used(CacheID::BlockDetails(hash.clone()));
result
}

/// Get the hash of given block's number.
fn block_hash(&self, index: BlockNumber) -> Option<H256> {
let result = self.db.read_with_cache(DB_COL_EXTRA, &self.block_hashes, &index);
let result = self.db.read_with_cache(db::COL_EXTRA, &self.block_hashes, &index);
self.cache_man.lock().note_used(CacheID::BlockHashes(index));
result
}

/// Get the address of transaction with given hash.
fn transaction_address(&self, hash: &H256) -> Option<TransactionAddress> {
let result = self.db.read_with_cache(DB_COL_EXTRA, &self.transaction_addresses, hash);
let result = self.db.read_with_cache(db::COL_EXTRA, &self.transaction_addresses, hash);
self.cache_man.lock().note_used(CacheID::TransactionAddresses(hash.clone()));
result
}

/// Get receipts of block with given hash.
fn block_receipts(&self, hash: &H256) -> Option<BlockReceipts> {
let result = self.db.read_with_cache(DB_COL_EXTRA, &self.block_receipts, hash);
let result = self.db.read_with_cache(db::COL_EXTRA, &self.block_receipts, hash);
self.cache_man.lock().note_used(CacheID::BlockReceipts(hash.clone()));
result
}
Expand Down Expand Up @@ -363,7 +362,7 @@ impl BlockChain {
};

// load best block
let best_block_hash = match bc.db.get(DB_COL_EXTRA, b"best").unwrap() {
let best_block_hash = match bc.db.get(db::COL_EXTRA, b"best").unwrap() {
Some(best) => {
H256::from_slice(&best)
}
Expand All @@ -382,14 +381,14 @@ impl BlockChain {
};

let 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));
batch.put(db::COL_HEADERS, &hash, block.header_rlp().as_raw());
batch.put(db::COL_BODIES, &hash, &Self::block_to_body(genesis));

batch.write(DB_COL_EXTRA, &hash, &details);
batch.write(DB_COL_EXTRA, &header.number(), &hash);
batch.write(db::COL_EXTRA, &hash, &details);
batch.write(db::COL_EXTRA, &header.number(), &hash);

batch.put(DB_COL_EXTRA, b"best", &hash);
batch.put(DB_COL_EXTRA, b"first", &hash);
batch.put(db::COL_EXTRA, b"best", &hash);
batch.put(db::COL_EXTRA, b"first", &hash);
bc.db.write(batch).expect("Low level database error. Some issue with disk?");
hash
}
Expand All @@ -401,7 +400,7 @@ impl BlockChain {
let best_block_total_difficulty = bc.block_details(&best_block_hash).unwrap().total_difficulty;
let best_block_rlp = bc.block(&best_block_hash).unwrap();

let raw_first = bc.db.get(DB_COL_EXTRA, b"first").unwrap().map_or(Vec::new(), |v| v.to_vec());
let raw_first = bc.db.get(db::COL_EXTRA, b"first").unwrap().map_or(Vec::new(), |v| v.to_vec());

// binary search for the first block.
if raw_first.is_empty() {
Expand All @@ -421,7 +420,7 @@ impl BlockChain {
}

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

bc.first_block = hash;
Expand All @@ -445,7 +444,7 @@ impl BlockChain {
/// Returns true if the given parent block has given child
/// (though not necessarily a part of the canon chain).
fn is_known_child(&self, parent: &H256, hash: &H256) -> bool {
self.db.read_with_cache(DB_COL_EXTRA, &self.block_details, parent).map_or(false, |d| d.children.contains(hash))
self.db.read_with_cache(db::COL_EXTRA, &self.block_details, parent).map_or(false, |d| d.children.contains(hash))
}

/// Rewind to a previous block
Expand All @@ -454,22 +453,22 @@ impl BlockChain {
use db::Key;
let 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() {
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);
if best_block_hash == self.genesis_hash() {
return None;
}
if let Some(extras) = self.db.read(DB_COL_EXTRA, &best_block_hash) as Option<BlockDetails> {
if let Some(extras) = self.db.read(db::COL_EXTRA, &best_block_hash) as Option<BlockDetails> {
type DetailsKey = Key<BlockDetails, Target=H264>;
batch.delete(DB_COL_EXTRA, &(DetailsKey::key(&best_block_hash)));
batch.delete(db::COL_EXTRA, &(DetailsKey::key(&best_block_hash)));
let hash = extras.parent;
let range = extras.number as bc::Number .. extras.number as bc::Number;
let chain = bc::group::BloomGroupChain::new(self.blooms_config, self);
let changes = chain.replace(&range, vec![]);
for (k, v) in changes.into_iter() {
batch.write(DB_COL_EXTRA, &LogGroupPosition::from(k), &BloomGroup::from(v));
batch.write(db::COL_EXTRA, &LogGroupPosition::from(k), &BloomGroup::from(v));
}
batch.put(DB_COL_EXTRA, b"best", &hash);
batch.put(db::COL_EXTRA, b"best", &hash);

let best_block_total_difficulty = self.block_details(&hash).unwrap().total_difficulty;
let best_block_rlp = self.block(&hash).unwrap();
Expand All @@ -482,9 +481,9 @@ impl BlockChain {
block: best_block_rlp,
};
// update parent extras
if let Some(mut details) = self.db.read(DB_COL_EXTRA, &hash) as Option<BlockDetails> {
if let Some(mut details) = self.db.read(db::COL_EXTRA, &hash) as Option<BlockDetails> {
details.children.clear();
batch.write(DB_COL_EXTRA, &hash, &details);
batch.write(db::COL_EXTRA, &hash, &details);
}
self.db.write(batch).expect("Writing to db failed");
self.block_details.write().clear();
Expand Down Expand Up @@ -612,8 +611,8 @@ impl BlockChain {
let compressed_body = UntrustedRlp::new(&Self::block_to_body(bytes)).compress(RlpType::Blocks);

// store block in db
batch.put(DB_COL_HEADERS, &hash, &compressed_header);
batch.put(DB_COL_BODIES, &hash, &compressed_body);
batch.put(db::COL_HEADERS, &hash, &compressed_header);
batch.put(db::COL_BODIES, &hash, &compressed_body);

let maybe_parent = self.block_details(&header.parent_hash());

Expand Down Expand Up @@ -691,7 +690,7 @@ impl BlockChain {


let mut write_details = self.block_details.write();
batch.extend_with_cache(DB_COL_EXTRA, &mut *write_details, update, CacheUpdatePolicy::Overwrite);
batch.extend_with_cache(db::COL_EXTRA, &mut *write_details, update, CacheUpdatePolicy::Overwrite);

self.cache_man.lock().note_used(CacheID::BlockDetails(block_hash));

Expand All @@ -715,8 +714,8 @@ impl BlockChain {
assert!(self.pending_best_block.read().is_none());

// store block in db
batch.put_compressed(DB_COL_HEADERS, &hash, block.header_rlp().as_raw().to_vec());
batch.put_compressed(DB_COL_BODIES, &hash, Self::block_to_body(bytes));
batch.put_compressed(db::COL_HEADERS, &hash, block.header_rlp().as_raw().to_vec());
batch.put_compressed(db::COL_BODIES, &hash, Self::block_to_body(bytes));

let info = self.block_info(&header);

Expand Down Expand Up @@ -788,7 +787,7 @@ impl BlockChain {
let block_hashes: Vec<_> = update.block_details.keys().cloned().collect();

let mut write_details = self.block_details.write();
batch.extend_with_cache(DB_COL_EXTRA, &mut *write_details, update.block_details, CacheUpdatePolicy::Overwrite);
batch.extend_with_cache(db::COL_EXTRA, &mut *write_details, update.block_details, CacheUpdatePolicy::Overwrite);

let mut cache_man = self.cache_man.lock();
for hash in block_hashes {
Expand All @@ -798,12 +797,12 @@ impl BlockChain {

{
let mut write_receipts = self.block_receipts.write();
batch.extend_with_cache(DB_COL_EXTRA, &mut *write_receipts, update.block_receipts, CacheUpdatePolicy::Remove);
batch.extend_with_cache(db::COL_EXTRA, &mut *write_receipts, update.block_receipts, CacheUpdatePolicy::Remove);
}

{
let mut write_blocks_blooms = self.blocks_blooms.write();
batch.extend_with_cache(DB_COL_EXTRA, &mut *write_blocks_blooms, update.blocks_blooms, CacheUpdatePolicy::Remove);
batch.extend_with_cache(db::COL_EXTRA, &mut *write_blocks_blooms, update.blocks_blooms, CacheUpdatePolicy::Remove);
}

// These cached values must be updated last with all three locks taken to avoid
Expand All @@ -814,7 +813,7 @@ impl BlockChain {
match update.info.location {
BlockLocation::Branch => (),
_ => if is_best {
batch.put(DB_COL_EXTRA, b"best", &update.info.hash);
batch.put(db::COL_EXTRA, b"best", &update.info.hash);
*best_block = Some(BestBlock {
hash: update.info.hash,
number: update.info.number,
Expand All @@ -826,8 +825,8 @@ impl BlockChain {
let mut write_hashes = self.pending_block_hashes.write();
let mut write_txs = self.pending_transaction_addresses.write();

batch.extend_with_cache(DB_COL_EXTRA, &mut *write_hashes, update.block_hashes, CacheUpdatePolicy::Overwrite);
batch.extend_with_cache(DB_COL_EXTRA, &mut *write_txs, update.transactions_addresses, CacheUpdatePolicy::Overwrite);
batch.extend_with_cache(db::COL_EXTRA, &mut *write_hashes, update.block_hashes, CacheUpdatePolicy::Overwrite);
batch.extend_with_cache(db::COL_EXTRA, &mut *write_txs, update.transactions_addresses, CacheUpdatePolicy::Overwrite);
}
}

Expand Down Expand Up @@ -1124,10 +1123,9 @@ mod tests {
use devtools::*;
use blockchain::generator::{ChainGenerator, ChainIterator, BlockFinalizer};
use views::BlockView;
use client;

fn new_db(path: &str) -> Arc<Database> {
Arc::new(Database::open(&DatabaseConfig::with_columns(client::DB_NO_OF_COLUMNS), path).unwrap())
Arc::new(Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), path).unwrap())
}

#[test]
Expand Down
18 changes: 2 additions & 16 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,20 +143,6 @@ pub struct Client {

const HISTORY: u64 = 1200;

// database columns
/// Column for State
pub const DB_COL_STATE: Option<u32> = Some(0);
/// Column for Block headers
pub const DB_COL_HEADERS: Option<u32> = Some(1);
/// Column for Block bodies
pub const DB_COL_BODIES: Option<u32> = Some(2);
/// Column for Extras
pub const DB_COL_EXTRA: Option<u32> = Some(3);
/// Column for Traces
pub const DB_COL_TRACE: Option<u32> = Some(4);
/// Number of columns in DB
pub const DB_NO_OF_COLUMNS: Option<u32> = Some(5);

/// Append a path element to the given path and return the string.
pub fn append_path<P>(path: P, item: &str) -> String where P: AsRef<Path> {
let mut p = path.as_ref().to_path_buf();
Expand All @@ -175,7 +161,7 @@ impl Client {
) -> Result<Arc<Client>, ClientError> {
let path = path.to_path_buf();
let gb = spec.genesis_block();
let mut db_config = DatabaseConfig::with_columns(DB_NO_OF_COLUMNS);
let mut db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS);
db_config.cache_size = config.db_cache_size;
db_config.compaction = config.db_compaction.compaction_profile();
db_config.wal = config.db_wal;
Expand All @@ -184,7 +170,7 @@ impl Client {
let chain = Arc::new(BlockChain::new(config.blockchain, &gb, db.clone()));
let tracedb = Arc::new(try!(TraceDB::new(config.tracing, db.clone(), chain.clone())));

let mut state_db = journaldb::new(db.clone(), config.pruning, DB_COL_STATE);
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));
Expand Down
25 changes: 23 additions & 2 deletions ethcore/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,46 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

//! Extras db utils.
//! Database utilities and definitions.
use std::ops::Deref;
use std::hash::Hash;
use std::collections::HashMap;
use util::{DBTransaction, Database, RwLock};
use util::rlp::{encode, Encodable, decode, Decodable};


// database columns
/// Column for State
pub const COL_STATE: Option<u32> = Some(0);
/// Column for Block headers
pub const COL_HEADERS: Option<u32> = Some(1);
/// Column for Block bodies
pub const COL_BODIES: Option<u32> = Some(2);
/// Column for Extras
pub const COL_EXTRA: Option<u32> = Some(3);
/// Column for Traces
pub const COL_TRACE: Option<u32> = Some(4);
/// Number of columns in DB
pub const NUM_COLUMNS: Option<u32> = Some(5);

/// Modes for updating caches.
#[derive(Clone, Copy)]
pub enum CacheUpdatePolicy {
/// Overwrite entries.
Overwrite,
/// Remove entries.
Remove,
}

/// A cache for arbitrary key-value pairs.
pub trait Cache<K, V> {
/// Insert an entry into the cache and get the old value.
fn insert(&mut self, k: K, v: V) -> Option<V>;

/// Remove an entry from the cache, getting the old value if it existed.
fn remove(&mut self, k: &K) -> Option<V>;

/// Query the cache for a key's associated value.
fn get(&self, k: &K) -> Option<&V>;
}

Expand All @@ -53,6 +73,7 @@ impl<K, V> Cache<K, V> for HashMap<K, V> where K: Hash + Eq {

/// Should be used to get database key associated with given value.
pub trait Key<T> {
/// The db key associated with this value.
type Target: Deref<Target = [u8]>;

/// Returns db key.
Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,11 @@ pub mod migrations;
pub mod miner;
pub mod snapshot;
pub mod action_params;
pub mod db;
#[macro_use] pub mod evm;

mod cache_manager;
mod blooms;
mod db;
mod common;
mod basic_types;
mod env_info;
Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/snapshot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ impl StateRebuilder {
/// Create a new state rebuilder to write into the given backing DB.
pub fn new(db: Arc<Database>, pruning: Algorithm) -> Self {
StateRebuilder {
db: journaldb::new(db.clone(), pruning, ::client::DB_COL_STATE),
db: journaldb::new(db.clone(), pruning, ::db::COL_STATE),
state_root: SHA3_NULL_RLP,
}
}
Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/snapshot/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct Restoration {
impl Restoration {
// make a new restoration, building databases in the given path.
fn new(manifest: &ManifestData, pruning: Algorithm, path: &Path, gb: &[u8]) -> Result<Self, Error> {
let cfg = DatabaseConfig::with_columns(::client::DB_NO_OF_COLUMNS);
let cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS);
let raw_db = Arc::new(try!(Database::open(&cfg, &*path.to_string_lossy())
.map_err(UtilError::SimpleString)));

Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/snapshot/tests/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fn chunk_and_restore(amount: u64) {
let mut canon_chain = ChainGenerator::default();
let mut finalizer = BlockFinalizer::default();
let genesis = canon_chain.generate(&mut finalizer).unwrap();
let db_cfg = DatabaseConfig::with_columns(::client::DB_NO_OF_COLUMNS);
let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS);

let orig_path = RandomTempPath::create_dir();
let new_path = RandomTempPath::create_dir();
Expand Down
Loading

0 comments on commit 1462f4b

Please sign in to comment.