Fatdb integration with CLI (#1464)
* fatdb integration * --fat-db * rerun with --pruning=archive comment
This commit is contained in:
		
							parent
							
								
									0a513ad06e
								
							
						
					
					
						commit
						d8a4cca817
					
				@ -214,8 +214,8 @@ impl Account {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Commit the `storage_overlay` to the backing DB and update `storage_root`.
 | 
						/// Commit the `storage_overlay` to the backing DB and update `storage_root`.
 | 
				
			||||||
	pub fn commit_storage(&mut self, db: &mut AccountDBMut) {
 | 
						pub fn commit_storage(&mut self, trie_factory: &TrieFactory, db: &mut AccountDBMut) {
 | 
				
			||||||
		let mut t = SecTrieDBMut::from_existing(db, &mut self.storage_root)
 | 
							let mut t = trie_factory.from_existing(db, &mut self.storage_root)
 | 
				
			||||||
			.expect("Account storage_root initially set to zero (valid) and only altered by SecTrieDBMut. \
 | 
								.expect("Account storage_root initially set to zero (valid) and only altered by SecTrieDBMut. \
 | 
				
			||||||
				SecTrieDBMut would not set it to an invalid state root. Therefore the root is valid and DB creation \
 | 
									SecTrieDBMut would not set it to an invalid state root. Therefore the root is valid and DB creation \
 | 
				
			||||||
				using it will not fail.");
 | 
									using it will not fail.");
 | 
				
			||||||
@ -275,7 +275,7 @@ mod tests {
 | 
				
			|||||||
		let rlp = {
 | 
							let rlp = {
 | 
				
			||||||
			let mut a = Account::new_contract(69.into(), 0.into());
 | 
								let mut a = Account::new_contract(69.into(), 0.into());
 | 
				
			||||||
			a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64)));
 | 
								a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64)));
 | 
				
			||||||
			a.commit_storage(&mut db);
 | 
								a.commit_storage(&Default::default(), &mut db);
 | 
				
			||||||
			a.init_code(vec![]);
 | 
								a.init_code(vec![]);
 | 
				
			||||||
			a.commit_code(&mut db);
 | 
								a.commit_code(&mut db);
 | 
				
			||||||
			a.rlp()
 | 
								a.rlp()
 | 
				
			||||||
@ -313,7 +313,7 @@ mod tests {
 | 
				
			|||||||
		let mut db = AccountDBMut::new(&mut db, &Address::new());
 | 
							let mut db = AccountDBMut::new(&mut db, &Address::new());
 | 
				
			||||||
		a.set_storage(0.into(), 0x1234.into());
 | 
							a.set_storage(0.into(), 0x1234.into());
 | 
				
			||||||
		assert_eq!(a.storage_root(), None);
 | 
							assert_eq!(a.storage_root(), None);
 | 
				
			||||||
		a.commit_storage(&mut db);
 | 
							a.commit_storage(&Default::default(), &mut db);
 | 
				
			||||||
		assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
 | 
							assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -323,11 +323,11 @@ mod tests {
 | 
				
			|||||||
		let mut db = MemoryDB::new();
 | 
							let mut db = MemoryDB::new();
 | 
				
			||||||
		let mut db = AccountDBMut::new(&mut db, &Address::new());
 | 
							let mut db = AccountDBMut::new(&mut db, &Address::new());
 | 
				
			||||||
		a.set_storage(0.into(), 0x1234.into());
 | 
							a.set_storage(0.into(), 0x1234.into());
 | 
				
			||||||
		a.commit_storage(&mut db);
 | 
							a.commit_storage(&Default::default(), &mut db);
 | 
				
			||||||
		a.set_storage(1.into(), 0x1234.into());
 | 
							a.set_storage(1.into(), 0x1234.into());
 | 
				
			||||||
		a.commit_storage(&mut db);
 | 
							a.commit_storage(&Default::default(), &mut db);
 | 
				
			||||||
		a.set_storage(1.into(), 0.into());
 | 
							a.set_storage(1.into(), 0.into());
 | 
				
			||||||
		a.commit_storage(&mut db);
 | 
							a.commit_storage(&Default::default(), &mut db);
 | 
				
			||||||
		assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
 | 
							assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -254,7 +254,7 @@ mod tests {
 | 
				
			|||||||
		spec.ensure_db_good(db.as_hashdb_mut());
 | 
							spec.ensure_db_good(db.as_hashdb_mut());
 | 
				
			||||||
		let last_hashes = vec![genesis_header.hash()];
 | 
							let last_hashes = vec![genesis_header.hash()];
 | 
				
			||||||
		let vm_factory = Default::default();
 | 
							let vm_factory = Default::default();
 | 
				
			||||||
		let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
							let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, None, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
				
			||||||
		let b = b.close_and_lock();
 | 
							let b = b.close_and_lock();
 | 
				
			||||||
		let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap();
 | 
							let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap();
 | 
				
			||||||
		assert!(b.try_seal(engine.deref(), seal).is_ok());
 | 
							assert!(b.try_seal(engine.deref(), seal).is_ok());
 | 
				
			||||||
 | 
				
			|||||||
@ -222,6 +222,7 @@ impl<'x> OpenBlock<'x> {
 | 
				
			|||||||
	pub fn new(
 | 
						pub fn new(
 | 
				
			||||||
		engine: &'x Engine,
 | 
							engine: &'x Engine,
 | 
				
			||||||
		vm_factory: &'x EvmFactory,
 | 
							vm_factory: &'x EvmFactory,
 | 
				
			||||||
 | 
							trie_factory: TrieFactory,
 | 
				
			||||||
		tracing: bool,
 | 
							tracing: bool,
 | 
				
			||||||
		db: Box<JournalDB>,
 | 
							db: Box<JournalDB>,
 | 
				
			||||||
		parent: &Header,
 | 
							parent: &Header,
 | 
				
			||||||
@ -231,7 +232,7 @@ impl<'x> OpenBlock<'x> {
 | 
				
			|||||||
		gas_range_target: (U256, U256),
 | 
							gas_range_target: (U256, U256),
 | 
				
			||||||
		extra_data: Bytes,
 | 
							extra_data: Bytes,
 | 
				
			||||||
	) -> Result<Self, Error> {
 | 
						) -> Result<Self, Error> {
 | 
				
			||||||
		let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce()));
 | 
							let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce(), trie_factory));
 | 
				
			||||||
		let mut r = OpenBlock {
 | 
							let mut r = OpenBlock {
 | 
				
			||||||
			block: ExecutedBlock::new(state, tracing),
 | 
								block: ExecutedBlock::new(state, tracing),
 | 
				
			||||||
			engine: engine,
 | 
								engine: engine,
 | 
				
			||||||
@ -481,16 +482,17 @@ pub fn enact(
 | 
				
			|||||||
	parent: &Header,
 | 
						parent: &Header,
 | 
				
			||||||
	last_hashes: LastHashes,
 | 
						last_hashes: LastHashes,
 | 
				
			||||||
	dao_rescue_block_gas_limit: Option<U256>,
 | 
						dao_rescue_block_gas_limit: Option<U256>,
 | 
				
			||||||
	vm_factory: &EvmFactory
 | 
						vm_factory: &EvmFactory,
 | 
				
			||||||
 | 
						trie_factory: TrieFactory,
 | 
				
			||||||
) -> Result<LockedBlock, Error> {
 | 
					) -> Result<LockedBlock, Error> {
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if ::log::max_log_level() >= ::log::LogLevel::Trace {
 | 
							if ::log::max_log_level() >= ::log::LogLevel::Trace {
 | 
				
			||||||
			let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce()));
 | 
								let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce(), trie_factory.clone()));
 | 
				
			||||||
			trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()));
 | 
								trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, header.author().clone(), (3141562.into(), 31415620.into()), header.extra_data().clone()));
 | 
						let mut b = try!(OpenBlock::new(engine, vm_factory, trie_factory, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, header.author().clone(), (3141562.into(), 31415620.into()), header.extra_data().clone()));
 | 
				
			||||||
	b.set_difficulty(*header.difficulty());
 | 
						b.set_difficulty(*header.difficulty());
 | 
				
			||||||
	b.set_gas_limit(*header.gas_limit());
 | 
						b.set_gas_limit(*header.gas_limit());
 | 
				
			||||||
	b.set_timestamp(header.timestamp());
 | 
						b.set_timestamp(header.timestamp());
 | 
				
			||||||
@ -509,11 +511,12 @@ pub fn enact_bytes(
 | 
				
			|||||||
	parent: &Header,
 | 
						parent: &Header,
 | 
				
			||||||
	last_hashes: LastHashes,
 | 
						last_hashes: LastHashes,
 | 
				
			||||||
	dao_rescue_block_gas_limit: Option<U256>,
 | 
						dao_rescue_block_gas_limit: Option<U256>,
 | 
				
			||||||
	vm_factory: &EvmFactory
 | 
						vm_factory: &EvmFactory,
 | 
				
			||||||
 | 
						trie_factory: TrieFactory,
 | 
				
			||||||
) -> Result<LockedBlock, Error> {
 | 
					) -> Result<LockedBlock, Error> {
 | 
				
			||||||
	let block = BlockView::new(block_bytes);
 | 
						let block = BlockView::new(block_bytes);
 | 
				
			||||||
	let header = block.header();
 | 
						let header = block.header();
 | 
				
			||||||
	enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)
 | 
						enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory, trie_factory)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
 | 
					/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
 | 
				
			||||||
@ -526,10 +529,11 @@ pub fn enact_verified(
 | 
				
			|||||||
	parent: &Header,
 | 
						parent: &Header,
 | 
				
			||||||
	last_hashes: LastHashes,
 | 
						last_hashes: LastHashes,
 | 
				
			||||||
	dao_rescue_block_gas_limit: Option<U256>,
 | 
						dao_rescue_block_gas_limit: Option<U256>,
 | 
				
			||||||
	vm_factory: &EvmFactory
 | 
						vm_factory: &EvmFactory,
 | 
				
			||||||
 | 
						trie_factory: TrieFactory,
 | 
				
			||||||
) -> Result<LockedBlock, Error> {
 | 
					) -> Result<LockedBlock, Error> {
 | 
				
			||||||
	let view = BlockView::new(&block.bytes);
 | 
						let view = BlockView::new(&block.bytes);
 | 
				
			||||||
	enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)
 | 
						enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory, trie_factory)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
 | 
					/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
 | 
				
			||||||
@ -542,10 +546,11 @@ pub fn enact_and_seal(
 | 
				
			|||||||
	parent: &Header,
 | 
						parent: &Header,
 | 
				
			||||||
	last_hashes: LastHashes,
 | 
						last_hashes: LastHashes,
 | 
				
			||||||
	dao_rescue_block_gas_limit: Option<U256>,
 | 
						dao_rescue_block_gas_limit: Option<U256>,
 | 
				
			||||||
	vm_factory: &EvmFactory
 | 
						vm_factory: &EvmFactory,
 | 
				
			||||||
 | 
						trie_factory: TrieFactory,
 | 
				
			||||||
) -> Result<SealedBlock, Error> {
 | 
					) -> Result<SealedBlock, Error> {
 | 
				
			||||||
	let header = BlockView::new(block_bytes).header_view();
 | 
						let header = BlockView::new(block_bytes).header_view();
 | 
				
			||||||
	Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)).seal(engine, header.seal())))
 | 
						Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory, trie_factory)).seal(engine, header.seal())))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[cfg(test)]
 | 
					#[cfg(test)]
 | 
				
			||||||
@ -565,7 +570,7 @@ mod tests {
 | 
				
			|||||||
		spec.ensure_db_good(db.as_hashdb_mut());
 | 
							spec.ensure_db_good(db.as_hashdb_mut());
 | 
				
			||||||
		let last_hashes = vec![genesis_header.hash()];
 | 
							let last_hashes = vec![genesis_header.hash()];
 | 
				
			||||||
		let vm_factory = Default::default();
 | 
							let vm_factory = Default::default();
 | 
				
			||||||
		let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
							let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
				
			||||||
		let b = b.close_and_lock();
 | 
							let b = b.close_and_lock();
 | 
				
			||||||
		let _ = b.seal(engine.deref(), vec![]);
 | 
							let _ = b.seal(engine.deref(), vec![]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -581,7 +586,7 @@ mod tests {
 | 
				
			|||||||
		let mut db = db_result.take();
 | 
							let mut db = db_result.take();
 | 
				
			||||||
		spec.ensure_db_good(db.as_hashdb_mut());
 | 
							spec.ensure_db_good(db.as_hashdb_mut());
 | 
				
			||||||
		let vm_factory = Default::default();
 | 
							let vm_factory = Default::default();
 | 
				
			||||||
		let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
 | 
							let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
 | 
				
			||||||
			.close_and_lock().seal(engine.deref(), vec![]).unwrap();
 | 
								.close_and_lock().seal(engine.deref(), vec![]).unwrap();
 | 
				
			||||||
		let orig_bytes = b.rlp_bytes();
 | 
							let orig_bytes = b.rlp_bytes();
 | 
				
			||||||
		let orig_db = b.drain();
 | 
							let orig_db = b.drain();
 | 
				
			||||||
@ -589,7 +594,7 @@ mod tests {
 | 
				
			|||||||
		let mut db_result = get_temp_journal_db();
 | 
							let mut db_result = get_temp_journal_db();
 | 
				
			||||||
		let mut db = db_result.take();
 | 
							let mut db = db_result.take();
 | 
				
			||||||
		spec.ensure_db_good(db.as_hashdb_mut());
 | 
							spec.ensure_db_good(db.as_hashdb_mut());
 | 
				
			||||||
		let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap();
 | 
							let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default(), Default::default()).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		assert_eq!(e.rlp_bytes(), orig_bytes);
 | 
							assert_eq!(e.rlp_bytes(), orig_bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -609,7 +614,7 @@ mod tests {
 | 
				
			|||||||
		let mut db = db_result.take();
 | 
							let mut db = db_result.take();
 | 
				
			||||||
		spec.ensure_db_good(db.as_hashdb_mut());
 | 
							spec.ensure_db_good(db.as_hashdb_mut());
 | 
				
			||||||
		let vm_factory = Default::default();
 | 
							let vm_factory = Default::default();
 | 
				
			||||||
		let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
							let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
				
			||||||
		let mut uncle1_header = Header::new();
 | 
							let mut uncle1_header = Header::new();
 | 
				
			||||||
		uncle1_header.extra_data = b"uncle1".to_vec();
 | 
							uncle1_header.extra_data = b"uncle1".to_vec();
 | 
				
			||||||
		let mut uncle2_header = Header::new();
 | 
							let mut uncle2_header = Header::new();
 | 
				
			||||||
@ -624,7 +629,7 @@ mod tests {
 | 
				
			|||||||
		let mut db_result = get_temp_journal_db();
 | 
							let mut db_result = get_temp_journal_db();
 | 
				
			||||||
		let mut db = db_result.take();
 | 
							let mut db = db_result.take();
 | 
				
			||||||
		spec.ensure_db_good(db.as_hashdb_mut());
 | 
							spec.ensure_db_good(db.as_hashdb_mut());
 | 
				
			||||||
		let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap();
 | 
							let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default(), Default::default()).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let bytes = e.rlp_bytes();
 | 
							let bytes = e.rlp_bytes();
 | 
				
			||||||
		assert_eq!(bytes, orig_bytes);
 | 
							assert_eq!(bytes, orig_bytes);
 | 
				
			||||||
 | 
				
			|||||||
@ -94,6 +94,7 @@ pub struct Client {
 | 
				
			|||||||
	panic_handler: Arc<PanicHandler>,
 | 
						panic_handler: Arc<PanicHandler>,
 | 
				
			||||||
	verifier: Box<Verifier>,
 | 
						verifier: Box<Verifier>,
 | 
				
			||||||
	vm_factory: Arc<EvmFactory>,
 | 
						vm_factory: Arc<EvmFactory>,
 | 
				
			||||||
 | 
						trie_factory: TrieFactory,
 | 
				
			||||||
	miner: Arc<Miner>,
 | 
						miner: Arc<Miner>,
 | 
				
			||||||
	io_channel: IoChannel<NetSyncMessage>,
 | 
						io_channel: IoChannel<NetSyncMessage>,
 | 
				
			||||||
	queue_transactions: AtomicUsize,
 | 
						queue_transactions: AtomicUsize,
 | 
				
			||||||
@ -175,6 +176,7 @@ impl Client {
 | 
				
			|||||||
			panic_handler: panic_handler,
 | 
								panic_handler: panic_handler,
 | 
				
			||||||
			verifier: verification::new(config.verifier_type),
 | 
								verifier: verification::new(config.verifier_type),
 | 
				
			||||||
			vm_factory: Arc::new(EvmFactory::new(config.vm_type)),
 | 
								vm_factory: Arc::new(EvmFactory::new(config.vm_type)),
 | 
				
			||||||
 | 
								trie_factory: TrieFactory::new(config.trie_spec),
 | 
				
			||||||
			miner: miner,
 | 
								miner: miner,
 | 
				
			||||||
			io_channel: message_channel,
 | 
								io_channel: message_channel,
 | 
				
			||||||
			queue_transactions: AtomicUsize::new(0),
 | 
								queue_transactions: AtomicUsize::new(0),
 | 
				
			||||||
@ -233,7 +235,7 @@ impl Client {
 | 
				
			|||||||
		let last_hashes = self.build_last_hashes(header.parent_hash.clone());
 | 
							let last_hashes = self.build_last_hashes(header.parent_hash.clone());
 | 
				
			||||||
		let db = self.state_db.lock().unwrap().boxed_clone();
 | 
							let db = self.state_db.lock().unwrap().boxed_clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, self.dao_rescue_block_gas_limit(header.parent_hash.clone()), &self.vm_factory);
 | 
							let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, self.dao_rescue_block_gas_limit(header.parent_hash.clone()), &self.vm_factory, self.trie_factory.clone());
 | 
				
			||||||
		if let Err(e) = enact_result {
 | 
							if let Err(e) = enact_result {
 | 
				
			||||||
			warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
 | 
								warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
 | 
				
			||||||
			return Err(());
 | 
								return Err(());
 | 
				
			||||||
@ -418,13 +420,17 @@ impl Client {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			let root = HeaderView::new(&header).state_root();
 | 
								let root = HeaderView::new(&header).state_root();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			State::from_existing(db, root, self.engine.account_start_nonce()).ok()
 | 
								State::from_existing(db, root, self.engine.account_start_nonce(), self.trie_factory.clone()).ok()
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Get a copy of the best block's state.
 | 
						/// Get a copy of the best block's state.
 | 
				
			||||||
	pub fn state(&self) -> State {
 | 
						pub fn state(&self) -> State {
 | 
				
			||||||
		State::from_existing(self.state_db.lock().unwrap().boxed_clone(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
 | 
							State::from_existing(
 | 
				
			||||||
 | 
								self.state_db.lock().unwrap().boxed_clone(),
 | 
				
			||||||
 | 
								HeaderView::new(&self.best_block_header()).state_root(),
 | 
				
			||||||
 | 
								self.engine.account_start_nonce(),
 | 
				
			||||||
 | 
								self.trie_factory.clone())
 | 
				
			||||||
			.expect("State root of best block header always valid.")
 | 
								.expect("State root of best block header always valid.")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -809,6 +815,7 @@ impl MiningBlockChainClient for Client {
 | 
				
			|||||||
		let mut open_block = OpenBlock::new(
 | 
							let mut open_block = OpenBlock::new(
 | 
				
			||||||
			engine,
 | 
								engine,
 | 
				
			||||||
			&self.vm_factory,
 | 
								&self.vm_factory,
 | 
				
			||||||
 | 
								self.trie_factory.clone(),
 | 
				
			||||||
			false,	// TODO: this will need to be parameterised once we want to do immediate mining insertion.
 | 
								false,	// TODO: this will need to be parameterised once we want to do immediate mining insertion.
 | 
				
			||||||
			self.state_db.lock().unwrap().boxed_clone(),
 | 
								self.state_db.lock().unwrap().boxed_clone(),
 | 
				
			||||||
			&self.chain.block_header(&h).expect("h is best block hash: so it's header must exist: qed"),
 | 
								&self.chain.block_header(&h).expect("h is best block hash: so it's header must exist: qed"),
 | 
				
			||||||
 | 
				
			|||||||
@ -20,6 +20,7 @@ pub use trace::{Config as TraceConfig, Switch};
 | 
				
			|||||||
pub use evm::VMType;
 | 
					pub use evm::VMType;
 | 
				
			||||||
pub use verification::VerifierType;
 | 
					pub use verification::VerifierType;
 | 
				
			||||||
use util::journaldb;
 | 
					use util::journaldb;
 | 
				
			||||||
 | 
					use util::trie::TrieSpec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Client state db compaction profile
 | 
					/// Client state db compaction profile
 | 
				
			||||||
#[derive(Debug, PartialEq)]
 | 
					#[derive(Debug, PartialEq)]
 | 
				
			||||||
@ -45,6 +46,8 @@ pub struct ClientConfig {
 | 
				
			|||||||
	pub tracing: TraceConfig,
 | 
						pub tracing: TraceConfig,
 | 
				
			||||||
	/// VM type.
 | 
						/// VM type.
 | 
				
			||||||
	pub vm_type: VMType,
 | 
						pub vm_type: VMType,
 | 
				
			||||||
 | 
						/// Trie type.
 | 
				
			||||||
 | 
						pub trie_spec: TrieSpec,
 | 
				
			||||||
	/// The JournalDB ("pruning") algorithm to use.
 | 
						/// The JournalDB ("pruning") algorithm to use.
 | 
				
			||||||
	pub pruning: journaldb::Algorithm,
 | 
						pub pruning: journaldb::Algorithm,
 | 
				
			||||||
	/// The name of the client instance.
 | 
						/// The name of the client instance.
 | 
				
			||||||
 | 
				
			|||||||
@ -325,7 +325,7 @@ mod tests {
 | 
				
			|||||||
		spec.ensure_db_good(db.as_hashdb_mut());
 | 
							spec.ensure_db_good(db.as_hashdb_mut());
 | 
				
			||||||
		let last_hashes = vec![genesis_header.hash()];
 | 
							let last_hashes = vec![genesis_header.hash()];
 | 
				
			||||||
		let vm_factory = Default::default();
 | 
							let vm_factory = Default::default();
 | 
				
			||||||
		let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
							let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
				
			||||||
		let b = b.close();
 | 
							let b = b.close();
 | 
				
			||||||
		assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
 | 
							assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -340,7 +340,7 @@ mod tests {
 | 
				
			|||||||
		spec.ensure_db_good(db.as_hashdb_mut());
 | 
							spec.ensure_db_good(db.as_hashdb_mut());
 | 
				
			||||||
		let last_hashes = vec![genesis_header.hash()];
 | 
							let last_hashes = vec![genesis_header.hash()];
 | 
				
			||||||
		let vm_factory = Default::default();
 | 
							let vm_factory = Default::default();
 | 
				
			||||||
		let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
							let mut b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
 | 
				
			||||||
		let mut uncle = Header::new();
 | 
							let mut uncle = Header::new();
 | 
				
			||||||
		let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
 | 
							let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
 | 
				
			||||||
		uncle.author = uncle_author.clone();
 | 
							uncle.author = uncle_author.clone();
 | 
				
			||||||
 | 
				
			|||||||
@ -67,7 +67,7 @@ mod tests {
 | 
				
			|||||||
		let mut db_result = get_temp_journal_db();
 | 
							let mut db_result = get_temp_journal_db();
 | 
				
			||||||
		let mut db = db_result.take();
 | 
							let mut db = db_result.take();
 | 
				
			||||||
		spec.ensure_db_good(db.as_hashdb_mut());
 | 
							spec.ensure_db_good(db.as_hashdb_mut());
 | 
				
			||||||
		let s = State::from_existing(db, genesis_header.state_root.clone(), engine.account_start_nonce()).unwrap();
 | 
							let s = State::from_existing(db, genesis_header.state_root.clone(), engine.account_start_nonce(), Default::default()).unwrap();
 | 
				
			||||||
		assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000001")), U256::from(1u64));
 | 
							assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000001")), U256::from(1u64));
 | 
				
			||||||
		assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000002")), U256::from(1u64));
 | 
							assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000002")), U256::from(1u64));
 | 
				
			||||||
		assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000003")), U256::from(1u64));
 | 
							assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000003")), U256::from(1u64));
 | 
				
			||||||
 | 
				
			|||||||
@ -42,6 +42,7 @@ pub struct State {
 | 
				
			|||||||
	cache: RefCell<HashMap<Address, Option<Account>>>,
 | 
						cache: RefCell<HashMap<Address, Option<Account>>>,
 | 
				
			||||||
	snapshots: RefCell<Vec<HashMap<Address, Option<Option<Account>>>>>,
 | 
						snapshots: RefCell<Vec<HashMap<Address, Option<Option<Account>>>>>,
 | 
				
			||||||
	account_start_nonce: U256,
 | 
						account_start_nonce: U256,
 | 
				
			||||||
 | 
						trie_factory: TrieFactory,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SEC_TRIE_DB_UNWRAP_STR: &'static str = "A state can only be created with valid root. Creating a SecTrieDB with a valid root will not fail. \
 | 
					const SEC_TRIE_DB_UNWRAP_STR: &'static str = "A state can only be created with valid root. Creating a SecTrieDB with a valid root will not fail. \
 | 
				
			||||||
@ -50,11 +51,11 @@ const SEC_TRIE_DB_UNWRAP_STR: &'static str = "A state can only be created with v
 | 
				
			|||||||
impl State {
 | 
					impl State {
 | 
				
			||||||
	/// Creates new state with empty state root
 | 
						/// Creates new state with empty state root
 | 
				
			||||||
	#[cfg(test)]
 | 
						#[cfg(test)]
 | 
				
			||||||
	pub fn new(mut db: Box<JournalDB>, account_start_nonce: U256) -> State {
 | 
						pub fn new(mut db: Box<JournalDB>, account_start_nonce: U256, trie_factory: TrieFactory) -> State {
 | 
				
			||||||
		let mut root = H256::new();
 | 
							let mut root = H256::new();
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			// init trie and reset root too null
 | 
								// init trie and reset root too null
 | 
				
			||||||
			let _ = SecTrieDBMut::new(db.as_hashdb_mut(), &mut root);
 | 
								let _ = trie_factory.create(db.as_hashdb_mut(), &mut root);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		State {
 | 
							State {
 | 
				
			||||||
@ -63,22 +64,26 @@ impl State {
 | 
				
			|||||||
			cache: RefCell::new(HashMap::new()),
 | 
								cache: RefCell::new(HashMap::new()),
 | 
				
			||||||
			snapshots: RefCell::new(Vec::new()),
 | 
								snapshots: RefCell::new(Vec::new()),
 | 
				
			||||||
			account_start_nonce: account_start_nonce,
 | 
								account_start_nonce: account_start_nonce,
 | 
				
			||||||
 | 
								trie_factory: trie_factory,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Creates new state with existing state root
 | 
						/// Creates new state with existing state root
 | 
				
			||||||
	pub fn from_existing(db: Box<JournalDB>, root: H256, account_start_nonce: U256) -> Result<State, TrieError> {
 | 
						pub fn from_existing(db: Box<JournalDB>, root: H256, account_start_nonce: U256, trie_factory: TrieFactory) -> Result<State, TrieError> {
 | 
				
			||||||
		if !db.as_hashdb().contains(&root) {
 | 
							if !db.as_hashdb().contains(&root) {
 | 
				
			||||||
			Err(TrieError::InvalidStateRoot)
 | 
								return Err(TrieError::InvalidStateRoot);
 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			Ok(State {
 | 
					 | 
				
			||||||
				db: db,
 | 
					 | 
				
			||||||
				root: root,
 | 
					 | 
				
			||||||
				cache: RefCell::new(HashMap::new()),
 | 
					 | 
				
			||||||
				snapshots: RefCell::new(Vec::new()),
 | 
					 | 
				
			||||||
				account_start_nonce: account_start_nonce,
 | 
					 | 
				
			||||||
			})
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let state = State {
 | 
				
			||||||
 | 
								db: db,
 | 
				
			||||||
 | 
								root: root,
 | 
				
			||||||
 | 
								cache: RefCell::new(HashMap::new()),
 | 
				
			||||||
 | 
								snapshots: RefCell::new(Vec::new()),
 | 
				
			||||||
 | 
								account_start_nonce: account_start_nonce,
 | 
				
			||||||
 | 
								trie_factory: trie_factory,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Ok(state)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Create a recoverable snaphot of this state
 | 
						/// Create a recoverable snaphot of this state
 | 
				
			||||||
@ -156,7 +161,7 @@ impl State {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/// Determine whether an account exists.
 | 
						/// Determine whether an account exists.
 | 
				
			||||||
	pub fn exists(&self, a: &Address) -> bool {
 | 
						pub fn exists(&self, a: &Address) -> bool {
 | 
				
			||||||
		let db = SecTrieDB::new(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
 | 
							let db = self.trie_factory.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
 | 
				
			||||||
		self.cache.borrow().get(&a).unwrap_or(&None).is_some() || db.contains(&a)
 | 
							self.cache.borrow().get(&a).unwrap_or(&None).is_some() || db.contains(&a)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -242,7 +247,10 @@ impl State {
 | 
				
			|||||||
				for a in &addresses {
 | 
									for a in &addresses {
 | 
				
			||||||
					if self.code(a).map_or(false, |c| c.sha3() == broken_dao) {
 | 
										if self.code(a).map_or(false, |c| c.sha3() == broken_dao) {
 | 
				
			||||||
						// Figure out if the balance has been reduced.
 | 
											// Figure out if the balance has been reduced.
 | 
				
			||||||
						let maybe_original = SecTrieDB::new(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR).get(&a).map(Account::from_rlp);
 | 
											let maybe_original = self.trie_factory
 | 
				
			||||||
 | 
												.readonly(self.db.as_hashdb(), &self.root)
 | 
				
			||||||
 | 
												.expect(SEC_TRIE_DB_UNWRAP_STR)
 | 
				
			||||||
 | 
												.get(&a).map(Account::from_rlp);
 | 
				
			||||||
						if maybe_original.map_or(false, |original| *original.balance() > self.balance(a)) {
 | 
											if maybe_original.map_or(false, |original| *original.balance() > self.balance(a)) {
 | 
				
			||||||
							return Err(Error::Transaction(TransactionError::DAORescue));
 | 
												return Err(Error::Transaction(TransactionError::DAORescue));
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
@ -262,14 +270,14 @@ impl State {
 | 
				
			|||||||
	/// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit.
 | 
						/// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit.
 | 
				
			||||||
	/// `accounts` is mutable because we may need to commit the code or storage and record that.
 | 
						/// `accounts` is mutable because we may need to commit the code or storage and record that.
 | 
				
			||||||
	#[cfg_attr(feature="dev", allow(match_ref_pats))]
 | 
						#[cfg_attr(feature="dev", allow(match_ref_pats))]
 | 
				
			||||||
	pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap<Address, Option<Account>>) {
 | 
						pub fn commit_into(trie_factory: &TrieFactory, db: &mut HashDB, root: &mut H256, accounts: &mut HashMap<Address, Option<Account>>) {
 | 
				
			||||||
		// first, commit the sub trees.
 | 
							// first, commit the sub trees.
 | 
				
			||||||
		// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?
 | 
							// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?
 | 
				
			||||||
		for (address, ref mut a) in accounts.iter_mut() {
 | 
							for (address, ref mut a) in accounts.iter_mut() {
 | 
				
			||||||
			match a {
 | 
								match a {
 | 
				
			||||||
				&mut&mut Some(ref mut account) => {
 | 
									&mut&mut Some(ref mut account) => {
 | 
				
			||||||
					let mut account_db = AccountDBMut::new(db, address);
 | 
										let mut account_db = AccountDBMut::new(db, address);
 | 
				
			||||||
					account.commit_storage(&mut account_db);
 | 
										account.commit_storage(trie_factory, &mut account_db);
 | 
				
			||||||
					account.commit_code(&mut account_db);
 | 
										account.commit_code(&mut account_db);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				&mut&mut None => {}
 | 
									&mut&mut None => {}
 | 
				
			||||||
@ -277,7 +285,7 @@ impl State {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			let mut trie = SecTrieDBMut::from_existing(db, root).unwrap();
 | 
								let mut trie = trie_factory.from_existing(db, root).unwrap();
 | 
				
			||||||
			for (address, ref a) in accounts.iter() {
 | 
								for (address, ref a) in accounts.iter() {
 | 
				
			||||||
				match **a {
 | 
									match **a {
 | 
				
			||||||
					Some(ref account) => trie.insert(address, &account.rlp()),
 | 
										Some(ref account) => trie.insert(address, &account.rlp()),
 | 
				
			||||||
@ -290,7 +298,7 @@ impl State {
 | 
				
			|||||||
	/// Commits our cached account changes into the trie.
 | 
						/// Commits our cached account changes into the trie.
 | 
				
			||||||
	pub fn commit(&mut self) {
 | 
						pub fn commit(&mut self) {
 | 
				
			||||||
		assert!(self.snapshots.borrow().is_empty());
 | 
							assert!(self.snapshots.borrow().is_empty());
 | 
				
			||||||
		Self::commit_into(self.db.as_hashdb_mut(), &mut self.root, self.cache.borrow_mut().deref_mut());
 | 
							Self::commit_into(&self.trie_factory, self.db.as_hashdb_mut(), &mut self.root, self.cache.borrow_mut().deref_mut());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#[cfg(test)]
 | 
						#[cfg(test)]
 | 
				
			||||||
@ -340,7 +348,7 @@ impl State {
 | 
				
			|||||||
	fn get<'a>(&'a self, a: &Address, require_code: bool) -> &'a Option<Account> {
 | 
						fn get<'a>(&'a self, a: &Address, require_code: bool) -> &'a Option<Account> {
 | 
				
			||||||
		let have_key = self.cache.borrow().contains_key(a);
 | 
							let have_key = self.cache.borrow().contains_key(a);
 | 
				
			||||||
		if !have_key {
 | 
							if !have_key {
 | 
				
			||||||
			let db = SecTrieDB::new(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
 | 
								let db = self.trie_factory.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
 | 
				
			||||||
			self.insert_cache(a, db.get(&a).map(Account::from_rlp))
 | 
								self.insert_cache(a, db.get(&a).map(Account::from_rlp))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if require_code {
 | 
							if require_code {
 | 
				
			||||||
@ -361,7 +369,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 {
 | 
						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);
 | 
							let have_key = self.cache.borrow().contains_key(a);
 | 
				
			||||||
		if !have_key {
 | 
							if !have_key {
 | 
				
			||||||
			let db = SecTrieDB::new(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
 | 
								let db = self.trie_factory.readonly(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR);
 | 
				
			||||||
			self.insert_cache(a, db.get(&a).map(Account::from_rlp))
 | 
								self.insert_cache(a, db.get(&a).map(Account::from_rlp))
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			self.note_cache(a);
 | 
								self.note_cache(a);
 | 
				
			||||||
@ -396,6 +404,7 @@ impl Clone for State {
 | 
				
			|||||||
			cache: RefCell::new(self.cache.borrow().clone()),
 | 
								cache: RefCell::new(self.cache.borrow().clone()),
 | 
				
			||||||
			snapshots: RefCell::new(self.snapshots.borrow().clone()),
 | 
								snapshots: RefCell::new(self.snapshots.borrow().clone()),
 | 
				
			||||||
			account_start_nonce: self.account_start_nonce.clone(),
 | 
								account_start_nonce: self.account_start_nonce.clone(),
 | 
				
			||||||
 | 
								trie_factory: self.trie_factory.clone(),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1179,7 +1188,7 @@ fn code_from_database() {
 | 
				
			|||||||
		state.drop()
 | 
							state.drop()
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let state = State::from_existing(db, root, U256::from(0u8)).unwrap();
 | 
						let state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap();
 | 
				
			||||||
	assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
 | 
						assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1194,7 +1203,7 @@ fn storage_at_from_database() {
 | 
				
			|||||||
		state.drop()
 | 
							state.drop()
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let s = State::from_existing(db, root, U256::from(0u8)).unwrap();
 | 
						let s = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap();
 | 
				
			||||||
	assert_eq!(s.storage_at(&a, &H256::from(&U256::from(01u64))), H256::from(&U256::from(69u64)));
 | 
						assert_eq!(s.storage_at(&a, &H256::from(&U256::from(01u64))), H256::from(&U256::from(69u64)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1211,7 +1220,7 @@ fn get_from_database() {
 | 
				
			|||||||
		state.drop()
 | 
							state.drop()
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let state = State::from_existing(db, root, U256::from(0u8)).unwrap();
 | 
						let state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap();
 | 
				
			||||||
	assert_eq!(state.balance(&a), U256::from(69u64));
 | 
						assert_eq!(state.balance(&a), U256::from(69u64));
 | 
				
			||||||
	assert_eq!(state.nonce(&a), U256::from(1u64));
 | 
						assert_eq!(state.nonce(&a), U256::from(1u64));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1244,7 +1253,7 @@ fn remove_from_database() {
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let (root, db) = {
 | 
						let (root, db) = {
 | 
				
			||||||
		let mut state = State::from_existing(db, root, U256::from(0u8)).unwrap();
 | 
							let mut state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap();
 | 
				
			||||||
		assert_eq!(state.exists(&a), true);
 | 
							assert_eq!(state.exists(&a), true);
 | 
				
			||||||
		assert_eq!(state.nonce(&a), U256::from(1u64));
 | 
							assert_eq!(state.nonce(&a), U256::from(1u64));
 | 
				
			||||||
		state.kill_account(&a);
 | 
							state.kill_account(&a);
 | 
				
			||||||
@ -1254,7 +1263,7 @@ fn remove_from_database() {
 | 
				
			|||||||
		state.drop()
 | 
							state.drop()
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let state = State::from_existing(db, root, U256::from(0u8)).unwrap();
 | 
						let state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap();
 | 
				
			||||||
	assert_eq!(state.exists(&a), false);
 | 
						assert_eq!(state.exists(&a), false);
 | 
				
			||||||
	assert_eq!(state.nonce(&a), U256::from(0u64));
 | 
						assert_eq!(state.nonce(&a), U256::from(0u64));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -175,6 +175,7 @@ pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_numbe
 | 
				
			|||||||
		let mut b = OpenBlock::new(
 | 
							let mut b = OpenBlock::new(
 | 
				
			||||||
			test_engine.deref(),
 | 
								test_engine.deref(),
 | 
				
			||||||
			&vm_factory,
 | 
								&vm_factory,
 | 
				
			||||||
 | 
								Default::default(),
 | 
				
			||||||
			false,
 | 
								false,
 | 
				
			||||||
			db,
 | 
								db,
 | 
				
			||||||
			&last_header,
 | 
								&last_header,
 | 
				
			||||||
@ -315,7 +316,7 @@ pub fn get_temp_state() -> GuardedTempResult<State> {
 | 
				
			|||||||
	let journal_db = get_temp_journal_db_in(temp.as_path());
 | 
						let journal_db = get_temp_journal_db_in(temp.as_path());
 | 
				
			||||||
	GuardedTempResult {
 | 
						GuardedTempResult {
 | 
				
			||||||
	    _temp: temp,
 | 
						    _temp: temp,
 | 
				
			||||||
		result: Some(State::new(journal_db, U256::from(0u8)))
 | 
							result: Some(State::new(journal_db, U256::from(0), Default::default())),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -325,7 +326,7 @@ pub fn get_temp_journal_db_in(path: &Path) -> Box<JournalDB> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub fn get_temp_state_in(path: &Path) -> State {
 | 
					pub fn get_temp_state_in(path: &Path) -> State {
 | 
				
			||||||
	let journal_db = get_temp_journal_db_in(path);
 | 
						let journal_db = get_temp_journal_db_in(path);
 | 
				
			||||||
	State::new(journal_db, U256::from(0u8))
 | 
						State::new(journal_db, U256::from(0), Default::default())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn get_good_dummy_block_seq(count: usize) -> Vec<Bytes> {
 | 
					pub fn get_good_dummy_block_seq(count: usize) -> Vec<Bytes> {
 | 
				
			||||||
 | 
				
			|||||||
@ -203,6 +203,7 @@ Database Options:
 | 
				
			|||||||
  --db-compaction TYPE     Database compaction type. TYPE may be one of:
 | 
					  --db-compaction TYPE     Database compaction type. TYPE may be one of:
 | 
				
			||||||
                           ssd - suitable for SSDs and fast HDDs;
 | 
					                           ssd - suitable for SSDs and fast HDDs;
 | 
				
			||||||
                           hdd - suitable for slow HDDs [default: ssd].
 | 
					                           hdd - suitable for slow HDDs [default: ssd].
 | 
				
			||||||
 | 
					  --fat-db                 Fat database.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Import/Export Options:
 | 
					Import/Export Options:
 | 
				
			||||||
  --from BLOCK             Export from block BLOCK, which may be an index or
 | 
					  --from BLOCK             Export from block BLOCK, which may be an index or
 | 
				
			||||||
@ -362,6 +363,7 @@ pub struct Args {
 | 
				
			|||||||
	pub flag_ipcapi: Option<String>,
 | 
						pub flag_ipcapi: Option<String>,
 | 
				
			||||||
	pub flag_db_cache_size: Option<usize>,
 | 
						pub flag_db_cache_size: Option<usize>,
 | 
				
			||||||
	pub flag_db_compaction: String,
 | 
						pub flag_db_compaction: String,
 | 
				
			||||||
 | 
						pub flag_fat_db: bool,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn print_version() {
 | 
					pub fn print_version() {
 | 
				
			||||||
 | 
				
			|||||||
@ -333,6 +333,14 @@ impl Configuration {
 | 
				
			|||||||
			_ => { die!("Invalid pruning method given."); }
 | 
								_ => { die!("Invalid pruning method given."); }
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if self.args.flag_fat_db {
 | 
				
			||||||
 | 
								if let journaldb::Algorithm::Archive = client_config.pruning {
 | 
				
			||||||
 | 
									client_config.trie_spec = TrieSpec::Fat;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									die!("Fatdb is not supported. Please rerun with --pruning=archive")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// forced state db cache size if provided
 | 
							// forced state db cache size if provided
 | 
				
			||||||
		client_config.db_cache_size = self.args.flag_db_cache_size.and_then(|cs| Some(cs / 4));
 | 
							client_config.db_cache_size = self.args.flag_db_cache_size.and_then(|cs| Some(cs / 4));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user