use Engine to order blockchain
This commit is contained in:
parent
76d7ec84bb
commit
67c24dcb95
@ -33,6 +33,7 @@ use blockchain::update::ExtrasUpdate;
|
|||||||
use blockchain::{CacheSize, ImportRoute, Config};
|
use blockchain::{CacheSize, ImportRoute, Config};
|
||||||
use db::{self, Writable, Readable, CacheUpdatePolicy};
|
use db::{self, Writable, Readable, CacheUpdatePolicy};
|
||||||
use cache_manager::CacheManager;
|
use cache_manager::CacheManager;
|
||||||
|
use engines::Engine;
|
||||||
|
|
||||||
const LOG_BLOOMS_LEVELS: usize = 3;
|
const LOG_BLOOMS_LEVELS: usize = 3;
|
||||||
const LOG_BLOOMS_ELEMENTS_PER_INDEX: usize = 16;
|
const LOG_BLOOMS_ELEMENTS_PER_INDEX: usize = 16;
|
||||||
@ -182,6 +183,8 @@ pub struct BlockChain {
|
|||||||
pending_best_block: RwLock<Option<BestBlock>>,
|
pending_best_block: RwLock<Option<BestBlock>>,
|
||||||
pending_block_hashes: RwLock<HashMap<BlockNumber, H256>>,
|
pending_block_hashes: RwLock<HashMap<BlockNumber, H256>>,
|
||||||
pending_transaction_addresses: RwLock<HashMap<H256, Option<TransactionAddress>>>,
|
pending_transaction_addresses: RwLock<HashMap<H256, Option<TransactionAddress>>>,
|
||||||
|
|
||||||
|
engine: Arc<Engine>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockProvider for BlockChain {
|
impl BlockProvider for BlockChain {
|
||||||
@ -387,8 +390,8 @@ impl<'a> Iterator for AncestryIter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BlockChain {
|
impl BlockChain {
|
||||||
/// Create new instance of blockchain from given Genesis
|
/// Create new instance of blockchain from given Genesis and block picking rules of Engine.
|
||||||
pub fn new(config: Config, genesis: &[u8], db: Arc<Database>) -> BlockChain {
|
pub fn new(config: Config, genesis: &[u8], db: Arc<Database>, engine: Arc<Engine>) -> BlockChain {
|
||||||
// 400 is the avarage size of the key
|
// 400 is the avarage size of the key
|
||||||
let cache_man = CacheManager::new(config.pref_cache_size, config.max_cache_size, 400);
|
let cache_man = CacheManager::new(config.pref_cache_size, config.max_cache_size, 400);
|
||||||
|
|
||||||
@ -411,6 +414,7 @@ impl BlockChain {
|
|||||||
pending_best_block: RwLock::new(None),
|
pending_best_block: RwLock::new(None),
|
||||||
pending_block_hashes: RwLock::new(HashMap::new()),
|
pending_block_hashes: RwLock::new(HashMap::new()),
|
||||||
pending_transaction_addresses: RwLock::new(HashMap::new()),
|
pending_transaction_addresses: RwLock::new(HashMap::new()),
|
||||||
|
engine: engine,
|
||||||
};
|
};
|
||||||
|
|
||||||
// load best block
|
// load best block
|
||||||
@ -799,13 +803,12 @@ impl BlockChain {
|
|||||||
let number = header.number();
|
let number = header.number();
|
||||||
let parent_hash = header.parent_hash();
|
let parent_hash = header.parent_hash();
|
||||||
let parent_details = self.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash));
|
let parent_details = self.block_details(&parent_hash).unwrap_or_else(|| panic!("Invalid parent hash: {:?}", parent_hash));
|
||||||
let total_difficulty = parent_details.total_difficulty + header.difficulty();
|
let is_new_best = self.engine.is_new_best_block(self.best_block_total_difficulty(), HeaderView::new(&self.best_block_header()), &parent_details, header);
|
||||||
let is_new_best = total_difficulty > self.best_block_total_difficulty();
|
|
||||||
|
|
||||||
BlockInfo {
|
BlockInfo {
|
||||||
hash: hash,
|
hash: hash,
|
||||||
number: number,
|
number: number,
|
||||||
total_difficulty: total_difficulty,
|
total_difficulty: parent_details.total_difficulty + header.difficulty(),
|
||||||
location: if is_new_best {
|
location: if is_new_best {
|
||||||
// on new best block we need to make sure that all ancestors
|
// on new best block we need to make sure that all ancestors
|
||||||
// are moved to "canon chain"
|
// are moved to "canon chain"
|
||||||
@ -1226,11 +1229,16 @@ mod tests {
|
|||||||
use views::BlockView;
|
use views::BlockView;
|
||||||
use transaction::{Transaction, Action};
|
use transaction::{Transaction, Action};
|
||||||
use log_entry::{LogEntry, LocalizedLogEntry};
|
use log_entry::{LogEntry, LocalizedLogEntry};
|
||||||
|
use spec::Spec;
|
||||||
|
|
||||||
fn new_db(path: &str) -> Arc<Database> {
|
fn new_db(path: &str) -> Arc<Database> {
|
||||||
Arc::new(Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), path).unwrap())
|
Arc::new(Database::open(&DatabaseConfig::with_columns(::db::NUM_COLUMNS), path).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_chain(genesis: &[u8], db: Arc<Database>) -> BlockChain {
|
||||||
|
BlockChain::new(Config::default(), genesis, db, Spec::new_null().engine)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_cache_best_block() {
|
fn should_cache_best_block() {
|
||||||
// given
|
// given
|
||||||
@ -1241,7 +1249,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
assert_eq!(bc.best_block_number(), 0);
|
assert_eq!(bc.best_block_number(), 0);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@ -1267,7 +1275,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
|
|
||||||
assert_eq!(bc.genesis_hash(), genesis_hash.clone());
|
assert_eq!(bc.genesis_hash(), genesis_hash.clone());
|
||||||
assert_eq!(bc.best_block_hash(), genesis_hash.clone());
|
assert_eq!(bc.best_block_hash(), genesis_hash.clone());
|
||||||
@ -1298,7 +1306,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
|
|
||||||
let mut block_hashes = vec![genesis_hash.clone()];
|
let mut block_hashes = vec![genesis_hash.clone()];
|
||||||
let mut batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
@ -1334,7 +1342,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
|
|
||||||
let mut batch =db.transaction();
|
let mut batch =db.transaction();
|
||||||
for b in &[&b1a, &b1b, &b2a, &b2b, &b3a, &b3b, &b4a, &b4b, &b5a, &b5b] {
|
for b in &[&b1a, &b1b, &b2a, &b2b, &b3a, &b3b, &b4a, &b4b, &b5a, &b5b] {
|
||||||
@ -1396,7 +1404,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
|
|
||||||
let mut batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
let _ = bc.insert_block(&mut batch, &b1a, vec![]);
|
let _ = bc.insert_block(&mut batch, &b1a, vec![]);
|
||||||
@ -1484,7 +1492,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
|
|
||||||
let mut batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
let _ = bc.insert_block(&mut batch, &b1a, vec![]);
|
let _ = bc.insert_block(&mut batch, &b1a, vec![]);
|
||||||
@ -1546,7 +1554,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
|
|
||||||
let mut batch = db.transaction();
|
let mut batch = db.transaction();
|
||||||
let ir1 = bc.insert_block(&mut batch, &b1, vec![]);
|
let ir1 = bc.insert_block(&mut batch, &b1, vec![]);
|
||||||
@ -1662,7 +1670,7 @@ mod tests {
|
|||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
{
|
{
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
assert_eq!(bc.best_block_hash(), genesis_hash);
|
assert_eq!(bc.best_block_hash(), genesis_hash);
|
||||||
let mut batch =db.transaction();
|
let mut batch =db.transaction();
|
||||||
bc.insert_block(&mut batch, &first, vec![]);
|
bc.insert_block(&mut batch, &first, vec![]);
|
||||||
@ -1673,7 +1681,7 @@ mod tests {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
|
|
||||||
assert_eq!(bc.best_block_hash(), first_hash);
|
assert_eq!(bc.best_block_hash(), first_hash);
|
||||||
}
|
}
|
||||||
@ -1728,7 +1736,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
let mut batch =db.transaction();
|
let mut batch =db.transaction();
|
||||||
bc.insert_block(&mut batch, &b1, vec![]);
|
bc.insert_block(&mut batch, &b1, vec![]);
|
||||||
db.write(batch).unwrap();
|
db.write(batch).unwrap();
|
||||||
@ -1788,7 +1796,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
insert_block(&db, &bc, &b1, vec![Receipt {
|
insert_block(&db, &bc, &b1, vec![Receipt {
|
||||||
state_root: H256::default(),
|
state_root: H256::default(),
|
||||||
gas_used: 10_000.into(),
|
gas_used: 10_000.into(),
|
||||||
@ -1892,7 +1900,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
|
|
||||||
let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5);
|
let blocks_b1 = bc.blocks_with_bloom(&bloom_b1, 0, 5);
|
||||||
let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5);
|
let blocks_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5);
|
||||||
@ -1949,7 +1957,7 @@ mod tests {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap();
|
let uncle = canon_chain.fork(1).generate(&mut finalizer.fork()).unwrap();
|
||||||
|
|
||||||
let mut batch =db.transaction();
|
let mut batch =db.transaction();
|
||||||
@ -1968,7 +1976,7 @@ mod tests {
|
|||||||
|
|
||||||
// re-loading the blockchain should load the correct best block.
|
// re-loading the blockchain should load the correct best block.
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
assert_eq!(bc.best_block_number(), 5);
|
assert_eq!(bc.best_block_number(), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1985,7 +1993,7 @@ mod tests {
|
|||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = new_db(temp.as_str());
|
let db = new_db(temp.as_str());
|
||||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
let bc = new_chain(&genesis, db.clone());
|
||||||
|
|
||||||
let mut batch =db.transaction();
|
let mut batch =db.transaction();
|
||||||
bc.insert_block(&mut batch, &first, vec![]);
|
bc.insert_block(&mut batch, &first, vec![]);
|
||||||
|
@ -23,7 +23,7 @@ use time::precise_time_ns;
|
|||||||
|
|
||||||
// util
|
// util
|
||||||
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock};
|
use util::{Bytes, PerfTimer, Itertools, Mutex, RwLock};
|
||||||
use util::journaldb::{self, JournalDB};
|
use util::journaldb;
|
||||||
use util::{U256, H256, H520, Address, H2048, Uint};
|
use util::{U256, H256, H520, Address, H2048, Uint};
|
||||||
use util::sha3::*;
|
use util::sha3::*;
|
||||||
use util::TrieFactory;
|
use util::TrieFactory;
|
||||||
@ -170,7 +170,7 @@ impl Client {
|
|||||||
let gb = spec.genesis_block();
|
let gb = spec.genesis_block();
|
||||||
|
|
||||||
let db = Arc::new(try!(Database::open(&db_config, &path.to_str().unwrap()).map_err(ClientError::Database)));
|
let db = Arc::new(try!(Database::open(&db_config, &path.to_str().unwrap()).map_err(ClientError::Database)));
|
||||||
let chain = Arc::new(BlockChain::new(config.blockchain.clone(), &gb, db.clone()));
|
let chain = Arc::new(BlockChain::new(config.blockchain.clone(), &gb, db.clone(), spec.engine.clone()));
|
||||||
let tracedb = RwLock::new(TraceDB::new(config.tracing.clone(), db.clone(), chain.clone()));
|
let tracedb = RwLock::new(TraceDB::new(config.tracing.clone(), db.clone(), chain.clone()));
|
||||||
|
|
||||||
let journal_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
|
let journal_db = journaldb::new(db.clone(), config.pruning, ::db::COL_STATE);
|
||||||
@ -689,7 +689,7 @@ impl snapshot::DatabaseRestore for Client {
|
|||||||
try!(db.restore(new_db));
|
try!(db.restore(new_db));
|
||||||
|
|
||||||
*state_db = StateDB::new(journaldb::new(db.clone(), self.pruning, ::db::COL_STATE));
|
*state_db = StateDB::new(journaldb::new(db.clone(), self.pruning, ::db::COL_STATE));
|
||||||
*chain = Arc::new(BlockChain::new(self.config.blockchain.clone(), &[], db.clone()));
|
*chain = Arc::new(BlockChain::new(self.config.blockchain.clone(), &[], db.clone(), self.engine.clone()));
|
||||||
*tracedb = TraceDB::new(self.config.tracing.clone(), db.clone(), chain.clone());
|
*tracedb = TraceDB::new(self.config.tracing.clone(), db.clone(), chain.clone());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ use engines::Engine;
|
|||||||
use error::Error;
|
use error::Error;
|
||||||
use ids::BlockID;
|
use ids::BlockID;
|
||||||
use service::ClientIoMessage;
|
use service::ClientIoMessage;
|
||||||
|
use spec::Spec;
|
||||||
|
|
||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
|
|
||||||
@ -97,7 +98,7 @@ impl Restoration {
|
|||||||
let raw_db = Arc::new(try!(Database::open(params.db_config, &*params.db_path.to_string_lossy())
|
let raw_db = Arc::new(try!(Database::open(params.db_config, &*params.db_path.to_string_lossy())
|
||||||
.map_err(UtilError::SimpleString)));
|
.map_err(UtilError::SimpleString)));
|
||||||
|
|
||||||
let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone());
|
let chain = BlockChain::new(Default::default(), params.genesis, raw_db.clone(), Spec::new_null().engine);
|
||||||
let blocks = try!(BlockRebuilder::new(chain, manifest.block_number));
|
let blocks = try!(BlockRebuilder::new(chain, manifest.block_number));
|
||||||
|
|
||||||
let root = manifest.state_root.clone();
|
let root = manifest.state_root.clone();
|
||||||
@ -629,4 +630,4 @@ mod tests {
|
|||||||
service.restore_state_chunk(Default::default(), vec![]);
|
service.restore_state_chunk(Default::default(), vec![]);
|
||||||
service.restore_block_chunk(Default::default(), vec![]);
|
service.restore_block_chunk(Default::default(), vec![]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ use util::kvdb::{Database, DatabaseConfig};
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use spec::Spec;
|
||||||
|
|
||||||
fn chunk_and_restore(amount: u64) {
|
fn chunk_and_restore(amount: u64) {
|
||||||
let mut canon_chain = ChainGenerator::default();
|
let mut canon_chain = ChainGenerator::default();
|
||||||
let mut finalizer = BlockFinalizer::default();
|
let mut finalizer = BlockFinalizer::default();
|
||||||
@ -39,8 +41,10 @@ fn chunk_and_restore(amount: u64) {
|
|||||||
let mut snapshot_path = new_path.as_path().to_owned();
|
let mut snapshot_path = new_path.as_path().to_owned();
|
||||||
snapshot_path.push("SNAP");
|
snapshot_path.push("SNAP");
|
||||||
|
|
||||||
|
let new_chain = |db| BlockChain::new(Default::default(), &genesis, db, Spec::new_null().engine);
|
||||||
|
|
||||||
let old_db = Arc::new(Database::open(&db_cfg, orig_path.as_str()).unwrap());
|
let old_db = Arc::new(Database::open(&db_cfg, orig_path.as_str()).unwrap());
|
||||||
let bc = BlockChain::new(Default::default(), &genesis, old_db.clone());
|
let bc = new_chain(old_db.clone());
|
||||||
|
|
||||||
// build the blockchain.
|
// build the blockchain.
|
||||||
let mut batch = old_db.transaction();
|
let mut batch = old_db.transaction();
|
||||||
@ -67,9 +71,9 @@ fn chunk_and_restore(amount: u64) {
|
|||||||
}).unwrap();
|
}).unwrap();
|
||||||
|
|
||||||
// restore it.
|
// restore it.
|
||||||
let new_db = Arc::new(Database::open(&db_cfg, new_path.as_str()).unwrap());
|
let restored_db = Arc::new(Database::open(&db_cfg, new_path.as_str()).unwrap());
|
||||||
let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone());
|
let restored_chain = new_chain(restored_db.clone());
|
||||||
let mut rebuilder = BlockRebuilder::new(new_chain, amount).unwrap();
|
let mut rebuilder = BlockRebuilder::new(restored_chain, amount).unwrap();
|
||||||
let reader = PackedReader::new(&snapshot_path).unwrap().unwrap();
|
let reader = PackedReader::new(&snapshot_path).unwrap().unwrap();
|
||||||
let engine = ::engines::NullEngine::new(Default::default(), Default::default());
|
let engine = ::engines::NullEngine::new(Default::default(), Default::default());
|
||||||
for chunk_hash in &reader.manifest().block_hashes {
|
for chunk_hash in &reader.manifest().block_hashes {
|
||||||
@ -81,8 +85,8 @@ fn chunk_and_restore(amount: u64) {
|
|||||||
rebuilder.glue_chunks();
|
rebuilder.glue_chunks();
|
||||||
|
|
||||||
// and test it.
|
// and test it.
|
||||||
let new_chain = BlockChain::new(Default::default(), &genesis, new_db);
|
let restored_chain = new_chain(restored_db);
|
||||||
assert_eq!(new_chain.best_block_hash(), best_hash);
|
assert_eq!(restored_chain.best_block_hash(), best_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user