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 db::{self, Writable, Readable, CacheUpdatePolicy}; | ||||
| use cache_manager::CacheManager; | ||||
| use engines::Engine; | ||||
| 
 | ||||
| const LOG_BLOOMS_LEVELS: usize = 3; | ||||
| const LOG_BLOOMS_ELEMENTS_PER_INDEX: usize = 16; | ||||
| @ -182,6 +183,8 @@ pub struct BlockChain { | ||||
| 	pending_best_block: RwLock<Option<BestBlock>>, | ||||
| 	pending_block_hashes: RwLock<HashMap<BlockNumber, H256>>, | ||||
| 	pending_transaction_addresses: RwLock<HashMap<H256, Option<TransactionAddress>>>, | ||||
| 
 | ||||
| 	engine: Arc<Engine>, | ||||
| } | ||||
| 
 | ||||
| impl BlockProvider for BlockChain { | ||||
| @ -387,8 +390,8 @@ impl<'a> Iterator for AncestryIter<'a> { | ||||
| } | ||||
| 
 | ||||
| impl BlockChain { | ||||
| 	/// Create new instance of blockchain from given Genesis
 | ||||
| 	pub fn new(config: Config, genesis: &[u8], db: Arc<Database>) -> BlockChain { | ||||
| 	/// Create new instance of blockchain from given Genesis and block picking rules of Engine.
 | ||||
| 	pub fn new(config: Config, genesis: &[u8], db: Arc<Database>, engine: Arc<Engine>) -> BlockChain { | ||||
| 		// 400 is the avarage size of the key
 | ||||
| 		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_block_hashes: RwLock::new(HashMap::new()), | ||||
| 			pending_transaction_addresses: RwLock::new(HashMap::new()), | ||||
| 			engine: engine, | ||||
| 		}; | ||||
| 
 | ||||
| 		// load best block
 | ||||
| @ -799,13 +803,12 @@ impl BlockChain { | ||||
| 		let number = header.number(); | ||||
| 		let parent_hash = header.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 = total_difficulty > self.best_block_total_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); | ||||
| 
 | ||||
| 		BlockInfo { | ||||
| 			hash: hash, | ||||
| 			number: number, | ||||
| 			total_difficulty: total_difficulty, | ||||
| 			total_difficulty: parent_details.total_difficulty + header.difficulty(), | ||||
| 			location: if is_new_best { | ||||
| 				// on new best block we need to make sure that all ancestors
 | ||||
| 				// are moved to "canon chain"
 | ||||
| @ -1226,11 +1229,16 @@ mod tests { | ||||
| 	use views::BlockView; | ||||
| 	use transaction::{Transaction, Action}; | ||||
| 	use log_entry::{LogEntry, LocalizedLogEntry}; | ||||
| 	use spec::Spec; | ||||
| 
 | ||||
| 	fn new_db(path: &str) -> Arc<Database> { | ||||
| 		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] | ||||
| 	fn should_cache_best_block() { | ||||
| 		// given
 | ||||
| @ -1241,7 +1249,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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); | ||||
| 
 | ||||
| 		// when
 | ||||
| @ -1267,7 +1275,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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.best_block_hash(), genesis_hash.clone()); | ||||
| @ -1298,7 +1306,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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 batch = db.transaction(); | ||||
| @ -1334,7 +1342,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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(); | ||||
| 		for b in &[&b1a, &b1b, &b2a, &b2b, &b3a, &b3b, &b4a, &b4b, &b5a, &b5b] { | ||||
| @ -1396,7 +1404,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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 _ = bc.insert_block(&mut batch, &b1a, vec![]); | ||||
| @ -1484,7 +1492,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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 _ = bc.insert_block(&mut batch, &b1a, vec![]); | ||||
| @ -1546,7 +1554,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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 ir1 = bc.insert_block(&mut batch, &b1, vec![]); | ||||
| @ -1662,7 +1670,7 @@ mod tests { | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		{ | ||||
| 			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); | ||||
| 			let mut batch =db.transaction(); | ||||
| 			bc.insert_block(&mut batch, &first, vec![]); | ||||
| @ -1673,7 +1681,7 @@ mod tests { | ||||
| 
 | ||||
| 		{ | ||||
| 			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); | ||||
| 		} | ||||
| @ -1728,7 +1736,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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(); | ||||
| 		bc.insert_block(&mut batch, &b1, vec![]); | ||||
| 		db.write(batch).unwrap(); | ||||
| @ -1788,7 +1796,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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 { | ||||
| 			state_root: H256::default(), | ||||
| 			gas_used: 10_000.into(), | ||||
| @ -1892,7 +1900,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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_b2 = bc.blocks_with_bloom(&bloom_b2, 0, 5); | ||||
| @ -1949,7 +1957,7 @@ mod tests { | ||||
| 
 | ||||
| 		{ | ||||
| 			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 mut batch =db.transaction(); | ||||
| @ -1968,7 +1976,7 @@ mod tests { | ||||
| 
 | ||||
| 		// re-loading the blockchain should load the correct best block.
 | ||||
| 		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); | ||||
| 	} | ||||
| 
 | ||||
| @ -1985,7 +1993,7 @@ mod tests { | ||||
| 
 | ||||
| 		let temp = RandomTempPath::new(); | ||||
| 		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(); | ||||
| 		bc.insert_block(&mut batch, &first, vec![]); | ||||
|  | ||||
| @ -23,7 +23,7 @@ use time::precise_time_ns; | ||||
| 
 | ||||
| // util
 | ||||
| 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::sha3::*; | ||||
| use util::TrieFactory; | ||||
| @ -170,7 +170,7 @@ impl Client { | ||||
| 		let gb = spec.genesis_block(); | ||||
| 
 | ||||
| 		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 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)); | ||||
| 
 | ||||
| 		*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()); | ||||
| 		Ok(()) | ||||
| 	} | ||||
|  | ||||
| @ -32,6 +32,7 @@ use engines::Engine; | ||||
| use error::Error; | ||||
| use ids::BlockID; | ||||
| use service::ClientIoMessage; | ||||
| use spec::Spec; | ||||
| 
 | ||||
| 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()) | ||||
| 			.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 root = manifest.state_root.clone(); | ||||
| @ -629,4 +630,4 @@ mod tests { | ||||
| 		service.restore_state_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 spec::Spec; | ||||
| 
 | ||||
| fn chunk_and_restore(amount: u64) { | ||||
| 	let mut canon_chain = ChainGenerator::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(); | ||||
| 	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 bc = BlockChain::new(Default::default(), &genesis, old_db.clone()); | ||||
| 	let bc = new_chain(old_db.clone()); | ||||
| 
 | ||||
| 	// build the blockchain.
 | ||||
| 	let mut batch = old_db.transaction(); | ||||
| @ -67,9 +71,9 @@ fn chunk_and_restore(amount: u64) { | ||||
| 	}).unwrap(); | ||||
| 
 | ||||
| 	// restore it.
 | ||||
| 	let new_db = Arc::new(Database::open(&db_cfg, new_path.as_str()).unwrap()); | ||||
| 	let new_chain = BlockChain::new(Default::default(), &genesis, new_db.clone()); | ||||
| 	let mut rebuilder = BlockRebuilder::new(new_chain, amount).unwrap(); | ||||
| 	let restored_db = Arc::new(Database::open(&db_cfg, new_path.as_str()).unwrap()); | ||||
| 	let restored_chain = new_chain(restored_db.clone()); | ||||
| 	let mut rebuilder = BlockRebuilder::new(restored_chain, amount).unwrap(); | ||||
| 	let reader = PackedReader::new(&snapshot_path).unwrap().unwrap(); | ||||
| 	let engine = ::engines::NullEngine::new(Default::default(), Default::default()); | ||||
| 	for chunk_hash in &reader.manifest().block_hashes { | ||||
| @ -81,8 +85,8 @@ fn chunk_and_restore(amount: u64) { | ||||
| 	rebuilder.glue_chunks(); | ||||
| 
 | ||||
| 	// and test it.
 | ||||
| 	let new_chain = BlockChain::new(Default::default(), &genesis, new_db); | ||||
| 	assert_eq!(new_chain.best_block_hash(), best_hash); | ||||
| 	let restored_chain = new_chain(restored_db); | ||||
| 	assert_eq!(restored_chain.best_block_hash(), best_hash); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user