Merge branch 'master' of github.com:ethcore/parity into move_hash
This commit is contained in:
@@ -25,7 +25,7 @@ semver = "0.2"
|
||||
bit-set = "0.4"
|
||||
time = "0.1"
|
||||
evmjit = { path = "../evmjit", optional = true }
|
||||
clippy = { version = "0.0.79", optional = true}
|
||||
clippy = { version = "0.0.80", optional = true}
|
||||
ethash = { path = "../ethash" }
|
||||
ethcore-util = { path = "../util" }
|
||||
ethcore-devtools = { path = "../devtools" }
|
||||
|
||||
@@ -20,6 +20,8 @@ use util::*;
|
||||
use pod_account::*;
|
||||
use account_db::*;
|
||||
|
||||
use std::cell::{Ref, RefCell};
|
||||
|
||||
/// Single account in the system.
|
||||
#[derive(Clone)]
|
||||
pub struct Account {
|
||||
@@ -136,7 +138,11 @@ impl Account {
|
||||
SecTrieDBMut would not set it to an invalid state root. Therefore the root is valid and DB creation \
|
||||
using it will not fail.");
|
||||
|
||||
(Filth::Clean, H256::from(db.get(key).map_or(U256::zero(), |v| -> U256 {decode(v)})))
|
||||
let item: U256 = match db.get(key){
|
||||
Ok(x) => x.map_or_else(U256::zero, decode),
|
||||
Err(e) => panic!("Encountered potential DB corruption: {}", e),
|
||||
};
|
||||
(Filth::Clean, item.into())
|
||||
}).1.clone()
|
||||
}
|
||||
|
||||
@@ -185,6 +191,12 @@ impl Account {
|
||||
pub fn is_dirty(&self) -> bool {
|
||||
self.filth == Filth::Dirty
|
||||
}
|
||||
|
||||
/// Mark account as clean.
|
||||
pub fn set_clean(&mut self) {
|
||||
self.filth = Filth::Clean
|
||||
}
|
||||
|
||||
/// Provide a database to get `code_hash`. Should not be called if it is a contract without code.
|
||||
pub fn cache_code(&mut self, db: &AccountDB) -> bool {
|
||||
// TODO: fill out self.code_cache;
|
||||
@@ -243,9 +255,13 @@ impl Account {
|
||||
if f == &Filth::Dirty {
|
||||
// cast key and value to trait type,
|
||||
// so we can call overloaded `to_bytes` method
|
||||
match v.is_zero() {
|
||||
true => { t.remove(k); },
|
||||
false => { t.insert(k, &encode(&U256::from(v.as_slice()))); },
|
||||
let res = match v.is_zero() {
|
||||
true => t.remove(k),
|
||||
false => t.insert(k, &encode(&U256::from(v.as_slice()))),
|
||||
};
|
||||
|
||||
if let Err(e) = res {
|
||||
warn!("Encountered potential DB corruption: {}", e);
|
||||
}
|
||||
*f = Filth::Clean;
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ pub struct OpenBlock<'x> {
|
||||
block: ExecutedBlock,
|
||||
engine: &'x Engine,
|
||||
vm_factory: &'x EvmFactory,
|
||||
last_hashes: LastHashes,
|
||||
last_hashes: Arc<LastHashes>,
|
||||
}
|
||||
|
||||
/// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
|
||||
@@ -204,7 +204,7 @@ pub struct OpenBlock<'x> {
|
||||
pub struct ClosedBlock {
|
||||
block: ExecutedBlock,
|
||||
uncle_bytes: Bytes,
|
||||
last_hashes: LastHashes,
|
||||
last_hashes: Arc<LastHashes>,
|
||||
unclosed_state: State,
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ impl<'x> OpenBlock<'x> {
|
||||
tracing: bool,
|
||||
db: Box<JournalDB>,
|
||||
parent: &Header,
|
||||
last_hashes: LastHashes,
|
||||
last_hashes: Arc<LastHashes>,
|
||||
author: Address,
|
||||
gas_range_target: (U256, U256),
|
||||
extra_data: Bytes,
|
||||
@@ -316,7 +316,7 @@ impl<'x> OpenBlock<'x> {
|
||||
author: self.block.base.header.author.clone(),
|
||||
timestamp: self.block.base.header.timestamp,
|
||||
difficulty: self.block.base.header.difficulty.clone(),
|
||||
last_hashes: self.last_hashes.clone(), // TODO: should be a reference.
|
||||
last_hashes: self.last_hashes.clone(),
|
||||
gas_used: self.block.receipts.last().map_or(U256::zero(), |r| r.gas_used),
|
||||
gas_limit: self.block.base.header.gas_limit.clone(),
|
||||
}
|
||||
@@ -498,7 +498,7 @@ pub fn enact(
|
||||
tracing: bool,
|
||||
db: Box<JournalDB>,
|
||||
parent: &Header,
|
||||
last_hashes: LastHashes,
|
||||
last_hashes: Arc<LastHashes>,
|
||||
vm_factory: &EvmFactory,
|
||||
trie_factory: TrieFactory,
|
||||
) -> Result<LockedBlock, Error> {
|
||||
@@ -531,7 +531,7 @@ pub fn enact_bytes(
|
||||
tracing: bool,
|
||||
db: Box<JournalDB>,
|
||||
parent: &Header,
|
||||
last_hashes: LastHashes,
|
||||
last_hashes: Arc<LastHashes>,
|
||||
vm_factory: &EvmFactory,
|
||||
trie_factory: TrieFactory,
|
||||
) -> Result<LockedBlock, Error> {
|
||||
@@ -548,7 +548,7 @@ pub fn enact_verified(
|
||||
tracing: bool,
|
||||
db: Box<JournalDB>,
|
||||
parent: &Header,
|
||||
last_hashes: LastHashes,
|
||||
last_hashes: Arc<LastHashes>,
|
||||
vm_factory: &EvmFactory,
|
||||
trie_factory: TrieFactory,
|
||||
) -> Result<LockedBlock, Error> {
|
||||
@@ -564,7 +564,7 @@ pub fn enact_and_seal(
|
||||
tracing: bool,
|
||||
db: Box<JournalDB>,
|
||||
parent: &Header,
|
||||
last_hashes: LastHashes,
|
||||
last_hashes: Arc<LastHashes>,
|
||||
vm_factory: &EvmFactory,
|
||||
trie_factory: TrieFactory,
|
||||
) -> Result<SealedBlock, Error> {
|
||||
@@ -586,8 +586,8 @@ mod tests {
|
||||
let genesis_header = spec.genesis_header();
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
spec.ensure_db_good(db.as_hashdb_mut());
|
||||
let last_hashes = vec![genesis_header.hash()];
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let vm_factory = Default::default();
|
||||
let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||
let b = b.close_and_lock();
|
||||
@@ -603,17 +603,18 @@ mod tests {
|
||||
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
spec.ensure_db_good(db.as_hashdb_mut());
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let vm_factory = Default::default();
|
||||
let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap()
|
||||
.close_and_lock().seal(engine.deref(), vec![]).unwrap();
|
||||
let orig_bytes = b.rlp_bytes();
|
||||
let orig_db = b.drain();
|
||||
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
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()], &Default::default(), Default::default()).unwrap();
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, last_hashes, &Default::default(), Default::default()).unwrap();
|
||||
|
||||
assert_eq!(e.rlp_bytes(), orig_bytes);
|
||||
|
||||
@@ -631,9 +632,10 @@ mod tests {
|
||||
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
spec.ensure_db_good(db.as_hashdb_mut());
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let vm_factory = Default::default();
|
||||
let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||
let mut uncle1_header = Header::new();
|
||||
uncle1_header.extra_data = b"uncle1".to_vec();
|
||||
let mut uncle2_header = Header::new();
|
||||
@@ -647,8 +649,8 @@ mod tests {
|
||||
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
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()], &Default::default(), Default::default()).unwrap();
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, last_hashes, &Default::default(), Default::default()).unwrap();
|
||||
|
||||
let bytes = e.rlp_bytes();
|
||||
assert_eq!(bytes, orig_bytes);
|
||||
|
||||
@@ -359,7 +359,7 @@ impl BlockChain {
|
||||
|
||||
let batch = DBTransaction::new(&db);
|
||||
batch.put(DB_COL_HEADERS, &hash, block.header_rlp().as_raw()).unwrap();
|
||||
batch.put(DB_COL_BODIES, &hash, &Self::block_to_body(&genesis)).unwrap();
|
||||
batch.put(DB_COL_BODIES, &hash, &Self::block_to_body(genesis)).unwrap();
|
||||
|
||||
batch.write(DB_COL_EXTRA, &hash, &details);
|
||||
batch.write(DB_COL_EXTRA, &header.number(), &hash);
|
||||
@@ -549,15 +549,11 @@ impl BlockChain {
|
||||
|
||||
assert!(self.pending_best_block.read().is_none());
|
||||
|
||||
let block_rlp = UntrustedRlp::new(bytes);
|
||||
let compressed_header = block_rlp.at(0).unwrap().compress(RlpType::Blocks);
|
||||
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).unwrap();
|
||||
batch.put(DB_COL_BODIES, &hash, &compressed_body).unwrap();
|
||||
batch.put_compressed(DB_COL_HEADERS, &hash, block.header_rlp().as_raw().to_vec()).unwrap();
|
||||
batch.put_compressed(DB_COL_BODIES, &hash, Self::block_to_body(bytes)).unwrap();
|
||||
|
||||
let info = self.block_info(bytes);
|
||||
let info = self.block_info(&header);
|
||||
|
||||
if let BlockLocation::BranchBecomingCanonChain(ref d) = info.location {
|
||||
info!(target: "reorg", "Reorg to {} ({} {} {})",
|
||||
@@ -582,10 +578,8 @@ impl BlockChain {
|
||||
}
|
||||
|
||||
/// Get inserted block info which is critical to prepare extras updates.
|
||||
fn block_info(&self, block_bytes: &[u8]) -> BlockInfo {
|
||||
let block = BlockView::new(block_bytes);
|
||||
let header = block.header_view();
|
||||
let hash = block.sha3();
|
||||
fn block_info(&self, header: &HeaderView) -> BlockInfo {
|
||||
let hash = header.sha3();
|
||||
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));
|
||||
@@ -1056,7 +1050,7 @@ mod tests {
|
||||
let bc = BlockChain::new(Config::default(), &genesis, db.clone());
|
||||
|
||||
let batch = db.transaction();
|
||||
for b in [&b1a, &b1b, &b2a, &b2b, &b3a, &b3b, &b4a, &b4b, &b5a, &b5b].iter() {
|
||||
for b in &[&b1a, &b1b, &b2a, &b2b, &b3a, &b3b, &b4a, &b4b, &b5a, &b5b] {
|
||||
bc.insert_block(&batch, b, vec![]);
|
||||
bc.commit();
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ impl Client {
|
||||
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);
|
||||
if state_db.is_empty() && spec.ensure_db_good(state_db.as_hashdb_mut()) {
|
||||
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));
|
||||
try!(db.write(batch).map_err(ClientError::Database));
|
||||
@@ -246,13 +246,13 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_last_hashes(&self, parent_hash: H256) -> LastHashes {
|
||||
fn build_last_hashes(&self, parent_hash: H256) -> Arc<LastHashes> {
|
||||
{
|
||||
let hashes = self.last_hashes.read();
|
||||
if hashes.front().map_or(false, |h| h == &parent_hash) {
|
||||
let mut res = Vec::from(hashes.clone());
|
||||
res.resize(256, H256::default());
|
||||
return res;
|
||||
return Arc::new(res);
|
||||
}
|
||||
}
|
||||
let mut last_hashes = LastHashes::new();
|
||||
@@ -268,7 +268,7 @@ impl Client {
|
||||
}
|
||||
let mut cached_hashes = self.last_hashes.write();
|
||||
*cached_hashes = VecDeque::from(last_hashes.clone());
|
||||
last_hashes
|
||||
Arc::new(last_hashes)
|
||||
}
|
||||
|
||||
fn check_and_close_block(&self, block: &PreverifiedBlock) -> Result<LockedBlock, ()> {
|
||||
@@ -413,6 +413,7 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
self.db.flush().expect("DB flush failed.");
|
||||
imported
|
||||
}
|
||||
|
||||
@@ -440,7 +441,7 @@ impl Client {
|
||||
// CHECK! I *think* this is fine, even if the state_root is equal to another
|
||||
// already-imported block of the same number.
|
||||
// TODO: Prove it with a test.
|
||||
block.drain().commit(&batch, number, hash, ancient).expect("State DB commit failed.");
|
||||
block.drain().commit(&batch, number, hash, ancient).expect("DB commit failed.");
|
||||
|
||||
let route = self.chain.insert_block(&batch, block_data, receipts);
|
||||
self.tracedb.import(&batch, TraceImportRequest {
|
||||
@@ -451,7 +452,7 @@ impl Client {
|
||||
retracted: route.retracted.len()
|
||||
});
|
||||
// Final commit to the DB
|
||||
self.db.write(batch).expect("State DB write failed.");
|
||||
self.db.write_buffered(batch).expect("DB write failed.");
|
||||
self.chain.commit();
|
||||
|
||||
self.update_last_hashes(&parent, hash);
|
||||
@@ -712,7 +713,7 @@ impl BlockChainClient for Client {
|
||||
x.state_diff = Some(state.diff_from(orig));
|
||||
}
|
||||
}
|
||||
ret.map_err(|ee| ReplayError::Execution(ee))
|
||||
ret.map_err(ReplayError::Execution)
|
||||
}
|
||||
|
||||
fn keep_alive(&self) {
|
||||
@@ -975,7 +976,7 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
|
||||
fn last_hashes(&self) -> LastHashes {
|
||||
self.build_last_hashes(self.chain.best_block_hash())
|
||||
(*self.build_last_hashes(self.chain.best_block_hash())).clone()
|
||||
}
|
||||
|
||||
fn queue_transactions(&self, transactions: Vec<Bytes>) {
|
||||
@@ -1059,6 +1060,7 @@ impl MiningBlockChainClient for Client {
|
||||
precise_time_ns() - start,
|
||||
);
|
||||
});
|
||||
self.db.flush().expect("DB flush failed.");
|
||||
Ok(h)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,15 @@ use trace::Error as TraceError;
|
||||
use util::UtilError;
|
||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
|
||||
use util::trie::TrieError;
|
||||
|
||||
/// Client configuration errors.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// TraceDB configuration error.
|
||||
Trace(TraceError),
|
||||
/// TrieDB-related error.
|
||||
Trie(TrieError),
|
||||
/// Database error
|
||||
Database(String),
|
||||
/// Util error
|
||||
@@ -19,16 +23,29 @@ impl From<TraceError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TrieError> for Error {
|
||||
fn from(err: TrieError) -> Self {
|
||||
Error::Trie(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UtilError> for Error {
|
||||
fn from(err: UtilError) -> Self {
|
||||
Error::Util(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> From<Box<E>> for Error where Error: From<E> {
|
||||
fn from(err: Box<E>) -> Self {
|
||||
Error::from(*err)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
match *self {
|
||||
Error::Trace(ref err) => write!(f, "{}", err),
|
||||
Error::Trie(ref err) => write!(f, "{}", err),
|
||||
Error::Util(ref err) => write!(f, "{}", err),
|
||||
Error::Database(ref s) => write!(f, "Database error: {}", s),
|
||||
}
|
||||
|
||||
@@ -262,7 +262,7 @@ impl MiningBlockChainClient for TestBlockChainClient {
|
||||
let genesis_header = self.spec.genesis_header();
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
self.spec.ensure_db_good(db.as_hashdb_mut());
|
||||
self.spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
|
||||
let last_hashes = vec![genesis_header.hash()];
|
||||
let mut open_block = OpenBlock::new(
|
||||
@@ -272,7 +272,7 @@ impl MiningBlockChainClient for TestBlockChainClient {
|
||||
false,
|
||||
db,
|
||||
&genesis_header,
|
||||
last_hashes,
|
||||
Arc::new(last_hashes),
|
||||
author,
|
||||
gas_range_target,
|
||||
extra_data
|
||||
|
||||
@@ -202,7 +202,7 @@ mod tests {
|
||||
author: 0.into(),
|
||||
timestamp: 0,
|
||||
difficulty: 0.into(),
|
||||
last_hashes: vec![],
|
||||
last_hashes: Arc::new(vec![]),
|
||||
gas_used: 0.into(),
|
||||
gas_limit: 0.into(),
|
||||
});
|
||||
@@ -250,8 +250,8 @@ mod tests {
|
||||
let genesis_header = spec.genesis_header();
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
spec.ensure_db_good(db.as_hashdb_mut());
|
||||
let last_hashes = vec![genesis_header.hash()];
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let vm_factory = Default::default();
|
||||
let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||
let b = b.close_and_lock();
|
||||
|
||||
@@ -84,8 +84,8 @@ mod tests {
|
||||
let genesis_header = spec.genesis_header();
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
spec.ensure_db_good(db.as_hashdb_mut());
|
||||
let last_hashes = vec![genesis_header.hash()];
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let vm_factory = Default::default();
|
||||
let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||
let b = b.close_and_lock();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::cmp;
|
||||
use std::sync::Arc;
|
||||
use util::{U256, Address, H256, Hashable};
|
||||
use header::BlockNumber;
|
||||
use ethjson;
|
||||
@@ -37,7 +38,7 @@ pub struct EnvInfo {
|
||||
/// The block gas limit.
|
||||
pub gas_limit: U256,
|
||||
/// The last 256 block hashes.
|
||||
pub last_hashes: LastHashes,
|
||||
pub last_hashes: Arc<LastHashes>,
|
||||
/// The gas used.
|
||||
pub gas_used: U256,
|
||||
}
|
||||
@@ -50,7 +51,7 @@ impl Default for EnvInfo {
|
||||
timestamp: 0,
|
||||
difficulty: 0.into(),
|
||||
gas_limit: 0.into(),
|
||||
last_hashes: vec![],
|
||||
last_hashes: Arc::new(vec![]),
|
||||
gas_used: 0.into(),
|
||||
}
|
||||
}
|
||||
@@ -65,8 +66,8 @@ impl From<ethjson::vm::Env> for EnvInfo {
|
||||
difficulty: e.difficulty.into(),
|
||||
gas_limit: e.gas_limit.into(),
|
||||
timestamp: e.timestamp.into(),
|
||||
last_hashes: (1..cmp::min(number + 1, 257)).map(|i| format!("{}", number - i).as_bytes().sha3()).collect(),
|
||||
gas_used: Default::default(),
|
||||
last_hashes: Arc::new((1..cmp::min(number + 1, 257)).map(|i| format!("{}", number - i).as_bytes().sha3()).collect()),
|
||||
gas_used: U256::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +258,10 @@ pub type ImportResult = Result<H256, Error>;
|
||||
|
||||
impl From<ClientError> for Error {
|
||||
fn from(err: ClientError) -> Error {
|
||||
Error::Client(err)
|
||||
match err {
|
||||
ClientError::Trie(err) => Error::Trie(err),
|
||||
_ => Error::Client(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,6 +341,12 @@ impl From<BlockImportError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl<E> From<Box<E>> for Error where Error: From<E> {
|
||||
fn from(err: Box<E>) -> Error {
|
||||
Error::from(*err)
|
||||
}
|
||||
}
|
||||
|
||||
binary_fixed_size!(BlockError);
|
||||
binary_fixed_size!(ImportError);
|
||||
binary_fixed_size!(TransactionError);
|
||||
|
||||
@@ -163,7 +163,9 @@ impl Engine for Ethash {
|
||||
for u in fields.uncles.iter() {
|
||||
fields.state.add_balance(u.author(), &(reward * U256::from(8 + u.number() - current_number) / U256::from(8)));
|
||||
}
|
||||
fields.state.commit();
|
||||
if let Err(e) = fields.state.commit() {
|
||||
warn!("Encountered error on state commit: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_block_basic(&self, header: &Header, _block: Option<&[u8]>) -> result::Result<(), Error> {
|
||||
@@ -352,8 +354,8 @@ mod tests {
|
||||
let genesis_header = spec.genesis_header();
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
spec.ensure_db_good(db.as_hashdb_mut());
|
||||
let last_hashes = vec![genesis_header.hash()];
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let vm_factory = Default::default();
|
||||
let b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||
let b = b.close();
|
||||
@@ -367,8 +369,8 @@ mod tests {
|
||||
let genesis_header = spec.genesis_header();
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
spec.ensure_db_good(db.as_hashdb_mut());
|
||||
let last_hashes = vec![genesis_header.hash()];
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let last_hashes = Arc::new(vec![genesis_header.hash()]);
|
||||
let vm_factory = Default::default();
|
||||
let mut b = OpenBlock::new(engine.deref(), &vm_factory, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap();
|
||||
let mut uncle = Header::new();
|
||||
@@ -396,7 +398,7 @@ mod tests {
|
||||
author: 0.into(),
|
||||
timestamp: 0,
|
||||
difficulty: 0.into(),
|
||||
last_hashes: vec![],
|
||||
last_hashes: Arc::new(vec![]),
|
||||
gas_used: 0.into(),
|
||||
gas_limit: 0.into(),
|
||||
});
|
||||
@@ -408,7 +410,7 @@ mod tests {
|
||||
author: 0.into(),
|
||||
timestamp: 0,
|
||||
difficulty: 0.into(),
|
||||
last_hashes: vec![],
|
||||
last_hashes: Arc::new(vec![]),
|
||||
gas_used: 0.into(),
|
||||
gas_limit: 0.into(),
|
||||
});
|
||||
|
||||
@@ -67,7 +67,7 @@ mod tests {
|
||||
let genesis_header = spec.genesis_header();
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
spec.ensure_db_good(db.as_hashdb_mut());
|
||||
spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let s = State::from_existing(db, genesis_header.state_root.clone(), engine.account_start_nonce(), Default::default()).unwrap();
|
||||
assert_eq!(s.balance(&"0000000000000000000000000000000000000001".parse().unwrap()), U256::from(1u64));
|
||||
assert_eq!(s.balance(&"0000000000000000000000000000000000000002".parse().unwrap()), U256::from(1u64));
|
||||
|
||||
@@ -324,7 +324,7 @@ mod tests {
|
||||
author: 0.into(),
|
||||
timestamp: 0,
|
||||
difficulty: 0.into(),
|
||||
last_hashes: vec![],
|
||||
last_hashes: Arc::new(vec![]),
|
||||
gas_used: 0.into(),
|
||||
gas_limit: 0.into(),
|
||||
}
|
||||
@@ -391,7 +391,9 @@ mod tests {
|
||||
{
|
||||
let env_info = &mut setup.env_info;
|
||||
env_info.number = test_env_number;
|
||||
env_info.last_hashes.push(test_hash.clone());
|
||||
let mut last_hashes = (*env_info.last_hashes).clone();
|
||||
last_hashes.push(test_hash.clone());
|
||||
env_info.last_hashes = Arc::new(last_hashes);
|
||||
}
|
||||
let state = setup.state.reference_mut();
|
||||
let mut tracer = NoopTracer;
|
||||
|
||||
@@ -20,6 +20,8 @@ use util::*;
|
||||
use basic_types::*;
|
||||
use time::get_time;
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
/// Type for Block number
|
||||
pub type BlockNumber = u64;
|
||||
|
||||
|
||||
@@ -62,7 +62,8 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
||||
let mut state_result = get_temp_state();
|
||||
let mut state = state_result.reference_mut();
|
||||
state.populate_from(pre);
|
||||
state.commit();
|
||||
state.commit()
|
||||
.expect(&format!("State test {} failed due to internal error.", name));
|
||||
let vm_factory = Default::default();
|
||||
let res = state.apply(&env, engine.deref(), &vm_factory, &transaction, false);
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use ethjson;
|
||||
use util::{H256, MemoryDB, TrieSpec, TrieFactory};
|
||||
use util::trie::{TrieFactory, TrieSpec};
|
||||
use util::hash::H256;
|
||||
use util::memorydb::MemoryDB;
|
||||
|
||||
fn test_trie(json: &[u8], trie: TrieSpec) -> Vec<String> {
|
||||
let tests = ethjson::trie::Test::load(json).unwrap();
|
||||
@@ -30,7 +32,8 @@ fn test_trie(json: &[u8], trie: TrieSpec) -> Vec<String> {
|
||||
for (key, value) in test.input.data.into_iter() {
|
||||
let key: Vec<u8> = key.into();
|
||||
let value: Vec<u8> = value.map_or_else(Vec::new, Into::into);
|
||||
t.insert(&key, &value);
|
||||
t.insert(&key, &value)
|
||||
.expect(&format!("Trie test '{:?}' failed due to internal error", name))
|
||||
}
|
||||
|
||||
if *t.root() != test.root.into() {
|
||||
@@ -46,7 +49,7 @@ fn test_trie(json: &[u8], trie: TrieSpec) -> Vec<String> {
|
||||
}
|
||||
|
||||
mod generic {
|
||||
use util::TrieSpec;
|
||||
use util::trie::TrieSpec;
|
||||
|
||||
fn do_json_test(json: &[u8]) -> Vec<String> {
|
||||
super::test_trie(json, TrieSpec::Generic)
|
||||
@@ -57,7 +60,7 @@ mod generic {
|
||||
}
|
||||
|
||||
mod secure {
|
||||
use util::TrieSpec;
|
||||
use util::trie::TrieSpec;
|
||||
|
||||
fn do_json_test(json: &[u8]) -> Vec<String> {
|
||||
super::test_trie(json, TrieSpec::Secure)
|
||||
|
||||
@@ -472,7 +472,7 @@ impl MinerService for Miner {
|
||||
|
||||
// TODO: merge this code with client.rs's fn call somwhow.
|
||||
let header = block.header();
|
||||
let last_hashes = chain.last_hashes();
|
||||
let last_hashes = Arc::new(chain.last_hashes());
|
||||
let env_info = EnvInfo {
|
||||
number: header.number(),
|
||||
author: *header.author(),
|
||||
|
||||
@@ -71,7 +71,9 @@ impl PodAccount {
|
||||
let mut r = H256::new();
|
||||
let mut t = SecTrieDBMut::new(db, &mut r);
|
||||
for (k, v) in &self.storage {
|
||||
t.insert(k, &encode(&U256::from(v.as_slice())));
|
||||
if let Err(e) = t.insert(k, &encode(&U256::from(v.as_slice()))) {
|
||||
warn!("Encountered potential DB corruption: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,7 +98,7 @@ impl From<ethjson::spec::Account> for PodAccount {
|
||||
PodAccount {
|
||||
balance: a.balance.map_or_else(U256::zero, Into::into),
|
||||
nonce: a.nonce.map_or_else(U256::zero, Into::into),
|
||||
code: a.code.map(Into::into).or(Some(Vec::new())),
|
||||
code: a.code.map(Into::into).or_else(|| Some(Vec::new())),
|
||||
storage: BTreeMap::new()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
use account_db::{AccountDB, AccountDBMut};
|
||||
use error::Error;
|
||||
use util::{U256, FixedHash, H256, Bytes, HashDB, SHA3_EMPTY, TrieDB};
|
||||
use util::rlp::{DecoderError, Rlp, RlpStream, Stream, UntrustedRlp, View};
|
||||
use util::rlp::{Rlp, RlpStream, Stream, UntrustedRlp, View};
|
||||
|
||||
// An alternate account structure from ::account::Account.
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
@@ -99,7 +99,7 @@ impl Account {
|
||||
}
|
||||
|
||||
// decode a fat rlp, and rebuild the storage trie as we go.
|
||||
pub fn from_fat_rlp(acct_db: &mut AccountDBMut, rlp: UntrustedRlp) -> Result<Self, DecoderError> {
|
||||
pub fn from_fat_rlp(acct_db: &mut AccountDBMut, rlp: UntrustedRlp) -> Result<Self, Error> {
|
||||
use util::{TrieDBMut, TrieMut};
|
||||
|
||||
let nonce = try!(rlp.val_at(0));
|
||||
@@ -120,7 +120,7 @@ impl Account {
|
||||
let k: Bytes = try!(pair_rlp.val_at(0));
|
||||
let v: Bytes = try!(pair_rlp.val_at(1));
|
||||
|
||||
storage_trie.insert(&k, &v);
|
||||
try!(storage_trie.insert(&k, &v));
|
||||
}
|
||||
}
|
||||
Ok(Account {
|
||||
@@ -157,7 +157,7 @@ mod tests {
|
||||
{
|
||||
let mut trie = SecTrieDBMut::new(&mut db, &mut root);
|
||||
for (k, v) in map.make() {
|
||||
trie.insert(&k, &v);
|
||||
trie.insert(&k, &v).unwrap();
|
||||
}
|
||||
}
|
||||
root
|
||||
|
||||
@@ -387,11 +387,11 @@ impl StateRebuilder {
|
||||
};
|
||||
|
||||
for (hash, thin_rlp) in pairs {
|
||||
account_trie.insert(&hash, &thin_rlp);
|
||||
try!(account_trie.insert(&hash, &thin_rlp));
|
||||
}
|
||||
}
|
||||
|
||||
let batch = DBTransaction::new(&self.db.backing());
|
||||
let batch = DBTransaction::new(self.db.backing());
|
||||
try!(self.db.commit(&batch, 0, &H256::zero(), None));
|
||||
try!(self.db.backing().write(batch).map_err(|e| Error::Util(e.into())));
|
||||
Ok(())
|
||||
|
||||
@@ -25,6 +25,8 @@ use super::seal::Generic as GenericSeal;
|
||||
use ethereum;
|
||||
use ethjson;
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
/// Parameters common to all engines.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct CommonParams {
|
||||
@@ -226,21 +228,21 @@ impl Spec {
|
||||
}
|
||||
|
||||
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
||||
pub fn ensure_db_good(&self, db: &mut HashDB) -> bool {
|
||||
pub fn ensure_db_good(&self, db: &mut HashDB) -> Result<bool, Box<TrieError>> {
|
||||
if !db.contains(&self.state_root()) {
|
||||
let mut root = H256::new();
|
||||
{
|
||||
let mut t = SecTrieDBMut::new(db, &mut root);
|
||||
for (address, account) in self.genesis_state.get().iter() {
|
||||
t.insert(address.as_slice(), &account.rlp());
|
||||
try!(t.insert(address.as_slice(), &account.rlp()));
|
||||
}
|
||||
}
|
||||
for (address, account) in self.genesis_state.get().iter() {
|
||||
account.insert_additional(&mut AccountDBMut::new(db, address));
|
||||
}
|
||||
assert!(db.contains(&self.state_root()));
|
||||
true
|
||||
} else { false }
|
||||
Ok(true)
|
||||
} else { Ok(false) }
|
||||
}
|
||||
|
||||
/// Loads spec from json file.
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::cell::{RefCell, RefMut};
|
||||
|
||||
use common::*;
|
||||
use engines::Engine;
|
||||
use executive::{Executive, TransactOptions};
|
||||
@@ -71,7 +73,7 @@ impl State {
|
||||
/// Creates new state with existing state root
|
||||
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) {
|
||||
return Err(TrieError::InvalidStateRoot);
|
||||
return Err(TrieError::InvalidStateRoot(root));
|
||||
}
|
||||
|
||||
let state = State {
|
||||
@@ -161,8 +163,7 @@ impl State {
|
||||
|
||||
/// Determine whether an account exists.
|
||||
pub fn exists(&self, a: &Address) -> bool {
|
||||
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.ensure_cached(a, false, |a| a.is_some())
|
||||
}
|
||||
|
||||
/// Get the balance of account `a`.
|
||||
@@ -238,8 +239,7 @@ impl State {
|
||||
|
||||
// TODO uncomment once to_pod() works correctly.
|
||||
// trace!("Applied transaction. Diff:\n{}\n", state_diff::diff_pod(&old, &self.to_pod()));
|
||||
self.commit();
|
||||
self.clear();
|
||||
try!(self.commit());
|
||||
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
||||
// trace!("Transaction receipt: {:?}", receipt);
|
||||
Ok(ApplyOutcome{receipt: receipt, trace: e.trace})
|
||||
@@ -248,7 +248,13 @@ impl State {
|
||||
/// 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.
|
||||
#[cfg_attr(feature="dev", allow(match_ref_pats))]
|
||||
pub fn commit_into(trie_factory: &TrieFactory, 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>>
|
||||
) -> Result<(), Error> {
|
||||
// first, commit the sub trees.
|
||||
// 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() {
|
||||
@@ -264,20 +270,25 @@ impl State {
|
||||
|
||||
{
|
||||
let mut trie = trie_factory.from_existing(db, root).unwrap();
|
||||
for (address, ref a) in accounts.iter() {
|
||||
for (address, ref mut a) in accounts.iter_mut() {
|
||||
match **a {
|
||||
Some(ref account) if account.is_dirty() => trie.insert(address, &account.rlp()),
|
||||
None => trie.remove(address),
|
||||
Some(ref mut account) if account.is_dirty() => {
|
||||
account.set_clean();
|
||||
try!(trie.insert(address, &account.rlp()))
|
||||
},
|
||||
None => try!(trie.remove(address)),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Commits our cached account changes into the trie.
|
||||
pub fn commit(&mut self) {
|
||||
pub fn commit(&mut self) -> Result<(), Error> {
|
||||
assert!(self.snapshots.borrow().is_empty());
|
||||
Self::commit_into(&self.trie_factory, 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, &mut *self.cache.borrow_mut())
|
||||
}
|
||||
|
||||
/// Clear state cache
|
||||
@@ -336,7 +347,11 @@ impl State {
|
||||
let have_key = self.cache.borrow().contains_key(a);
|
||||
if !have_key {
|
||||
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))
|
||||
let maybe_acc = match db.get(&a) {
|
||||
Ok(acc) => acc.map(Account::from_rlp),
|
||||
Err(e) => panic!("Potential DB corruption encountered: {}", e),
|
||||
};
|
||||
self.insert_cache(a, maybe_acc);
|
||||
}
|
||||
if require_code {
|
||||
if let Some(ref mut account) = self.cache.borrow_mut().get_mut(a).unwrap().as_mut() {
|
||||
@@ -348,33 +363,40 @@ impl State {
|
||||
}
|
||||
|
||||
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
|
||||
fn require<'a>(&'a self, a: &Address, require_code: bool) -> &'a mut Account {
|
||||
fn require<'a>(&'a self, a: &Address, require_code: bool) -> RefMut<'a, Account> {
|
||||
self.require_or_from(a, require_code, || Account::new_basic(U256::from(0u8), self.account_start_nonce), |_|{})
|
||||
}
|
||||
|
||||
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
|
||||
/// If it doesn't exist, make account equal the evaluation of `default`.
|
||||
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);
|
||||
if !have_key {
|
||||
fn require_or_from<'a, F: FnOnce() -> Account, G: FnOnce(&mut Account)>(&'a self, a: &Address, require_code: bool, default: F, not_default: G)
|
||||
-> RefMut<'a, Account>
|
||||
{
|
||||
let contains_key = self.cache.borrow().contains_key(a);
|
||||
if !contains_key {
|
||||
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))
|
||||
let maybe_acc = match db.get(&a) {
|
||||
Ok(acc) => acc.map(Account::from_rlp),
|
||||
Err(e) => panic!("Potential DB corruption encountered: {}", e),
|
||||
};
|
||||
|
||||
self.insert_cache(a, maybe_acc);
|
||||
} else {
|
||||
self.note_cache(a);
|
||||
}
|
||||
let preexists = self.cache.borrow().get(a).unwrap().is_none();
|
||||
if preexists {
|
||||
self.cache.borrow_mut().insert(a.clone(), Some(default()));
|
||||
} else {
|
||||
not_default(self.cache.borrow_mut().get_mut(a).unwrap().as_mut().unwrap());
|
||||
|
||||
match self.cache.borrow_mut().get_mut(a).unwrap() {
|
||||
&mut Some(ref mut acc) => not_default(acc),
|
||||
slot @ &mut None => *slot = Some(default()),
|
||||
}
|
||||
|
||||
unsafe { ::std::mem::transmute(self.cache.borrow_mut().get_mut(a).unwrap().as_mut().map(|account| {
|
||||
RefMut::map(self.cache.borrow_mut(), |c| {
|
||||
let account = c.get_mut(a).unwrap().as_mut().unwrap();
|
||||
if require_code {
|
||||
account.cache_code(&AccountDB::new(self.db.as_hashdb(), a));
|
||||
}
|
||||
account
|
||||
}).unwrap()) }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,12 +488,12 @@ fn should_work_when_cloned() {
|
||||
let mut state = get_temp_state_in(temp.as_path());
|
||||
assert_eq!(state.exists(&a), false);
|
||||
state.inc_nonce(&a);
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
state.clone()
|
||||
};
|
||||
|
||||
state.inc_nonce(&a);
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1281,7 +1303,7 @@ fn code_from_database() {
|
||||
state.require_or_from(&a, false, ||Account::new_contract(42.into(), 0.into()), |_|{});
|
||||
state.init_code(&a, vec![1, 2, 3]);
|
||||
assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
|
||||
state.drop()
|
||||
};
|
||||
@@ -1297,7 +1319,7 @@ fn storage_at_from_database() {
|
||||
let (root, db) = {
|
||||
let mut state = get_temp_state_in(temp.as_path());
|
||||
state.set_storage(&a, H256::from(&U256::from(01u64)), H256::from(&U256::from(69u64)));
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
state.drop()
|
||||
};
|
||||
|
||||
@@ -1313,7 +1335,7 @@ fn get_from_database() {
|
||||
let mut state = get_temp_state_in(temp.as_path());
|
||||
state.inc_nonce(&a);
|
||||
state.add_balance(&a, &U256::from(69u64));
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.balance(&a), U256::from(69u64));
|
||||
state.drop()
|
||||
};
|
||||
@@ -1344,7 +1366,7 @@ fn remove_from_database() {
|
||||
let (root, db) = {
|
||||
let mut state = get_temp_state_in(temp.as_path());
|
||||
state.inc_nonce(&a);
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.exists(&a), true);
|
||||
assert_eq!(state.nonce(&a), U256::from(1u64));
|
||||
state.drop()
|
||||
@@ -1355,7 +1377,7 @@ fn remove_from_database() {
|
||||
assert_eq!(state.exists(&a), true);
|
||||
assert_eq!(state.nonce(&a), U256::from(1u64));
|
||||
state.kill_account(&a);
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.exists(&a), false);
|
||||
assert_eq!(state.nonce(&a), U256::from(0u64));
|
||||
state.drop()
|
||||
@@ -1374,16 +1396,16 @@ fn alter_balance() {
|
||||
let b = address_from_u64(1u64);
|
||||
state.add_balance(&a, &U256::from(69u64));
|
||||
assert_eq!(state.balance(&a), U256::from(69u64));
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.balance(&a), U256::from(69u64));
|
||||
state.sub_balance(&a, &U256::from(42u64));
|
||||
assert_eq!(state.balance(&a), U256::from(27u64));
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.balance(&a), U256::from(27u64));
|
||||
state.transfer_balance(&a, &b, &U256::from(18u64));
|
||||
assert_eq!(state.balance(&a), U256::from(9u64));
|
||||
assert_eq!(state.balance(&b), U256::from(18u64));
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.balance(&a), U256::from(9u64));
|
||||
assert_eq!(state.balance(&b), U256::from(18u64));
|
||||
}
|
||||
@@ -1397,11 +1419,11 @@ fn alter_nonce() {
|
||||
assert_eq!(state.nonce(&a), U256::from(1u64));
|
||||
state.inc_nonce(&a);
|
||||
assert_eq!(state.nonce(&a), U256::from(2u64));
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.nonce(&a), U256::from(2u64));
|
||||
state.inc_nonce(&a);
|
||||
assert_eq!(state.nonce(&a), U256::from(3u64));
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.nonce(&a), U256::from(3u64));
|
||||
}
|
||||
|
||||
@@ -1412,7 +1434,7 @@ fn balance_nonce() {
|
||||
let a = Address::zero();
|
||||
assert_eq!(state.balance(&a), U256::from(0u64));
|
||||
assert_eq!(state.nonce(&a), U256::from(0u64));
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.balance(&a), U256::from(0u64));
|
||||
assert_eq!(state.nonce(&a), U256::from(0u64));
|
||||
}
|
||||
@@ -1423,7 +1445,7 @@ fn ensure_cached() {
|
||||
let mut state = state_result.reference_mut();
|
||||
let a = Address::zero();
|
||||
state.require(&a, false);
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.root().hex(), "0ce23f3c809de377b008a4a3ee94a0834aac8bec1f86e28ffe4fdb5a15b0c785");
|
||||
}
|
||||
|
||||
@@ -1463,7 +1485,7 @@ fn snapshot_nested() {
|
||||
fn create_empty() {
|
||||
let mut state_result = get_temp_state();
|
||||
let mut state = state_result.reference_mut();
|
||||
state.commit();
|
||||
state.commit().unwrap();
|
||||
assert_eq!(state.root().hex(), "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421");
|
||||
}
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_numbe
|
||||
|
||||
let mut db_result = get_temp_journal_db();
|
||||
let mut db = db_result.take();
|
||||
test_spec.ensure_db_good(db.as_hashdb_mut());
|
||||
test_spec.ensure_db_good(db.as_hashdb_mut()).unwrap();
|
||||
let vm_factory = Default::default();
|
||||
let genesis_header = test_spec.genesis_header();
|
||||
|
||||
@@ -160,7 +160,7 @@ pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_numbe
|
||||
false,
|
||||
db,
|
||||
&last_header,
|
||||
last_hashes.clone(),
|
||||
Arc::new(last_hashes.clone()),
|
||||
author.clone(),
|
||||
(3141562.into(), 31415620.into()),
|
||||
vec![]
|
||||
|
||||
Reference in New Issue
Block a user