diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 54c2a7a02..bcbceb9aa 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -594,9 +594,9 @@ mod tests { use factory::Factories; use state_db::StateDB; use views::BlockView; - use util::Address; + use util::{Address, TrieFactory}; use util::hash::FixedHash; - + use util::trie::TrieSpec; use std::sync::Arc; /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header @@ -637,7 +637,7 @@ mod tests { let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(&*spec.engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); @@ -653,7 +653,7 @@ mod tests { let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap() .close_and_lock().seal(engine, vec![]).unwrap(); @@ -662,7 +662,7 @@ mod tests { let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap(); assert_eq!(e.rlp_bytes(), orig_bytes); @@ -681,7 +681,7 @@ mod tests { let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let mut open_block = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes.clone(), Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut uncle1_header = Header::new(); @@ -697,7 +697,7 @@ mod tests { let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let e = enact_and_seal(&orig_bytes, engine, false, db, &genesis_header, last_hashes, Default::default()).unwrap(); let bytes = e.rlp_bytes(); diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index 830fcf9c8..0c6ce0f9b 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -315,6 +315,7 @@ impl Engine for AuthorityRound { #[cfg(test)] mod tests { use util::*; + use util::trie::TrieSpec; use env_info::EnvInfo; use header::Header; use error::{Error, BlockError}; @@ -384,9 +385,9 @@ mod tests { let engine = &*spec.engine; let genesis_header = spec.genesis_header(); let mut db1 = get_temp_state_db().take(); - spec.ensure_db_good(&mut db1).unwrap(); + spec.ensure_db_good(&mut db1, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let mut db2 = get_temp_state_db().take(); - spec.ensure_db_good(&mut db2).unwrap(); + spec.ensure_db_good(&mut db2, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b1 = OpenBlock::new(engine, Default::default(), false, db1, &genesis_header, last_hashes.clone(), addr1, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b1 = b1.close_and_lock(); diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 23a97967c..fb2f9bde6 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -184,6 +184,7 @@ impl Engine for BasicAuthority { #[cfg(test)] mod tests { use util::*; + use util::trie::TrieSpec; use block::*; use env_info::EnvInfo; use error::{BlockError, Error}; @@ -256,7 +257,7 @@ mod tests { let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index 3dc78d1a2..f50f7344b 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -68,6 +68,7 @@ impl Engine for InstantSeal { #[cfg(test)] mod tests { use util::*; + use util::trie::TrieSpec; use tests::helpers::*; use account_provider::AccountProvider; use spec::Spec; @@ -84,7 +85,7 @@ mod tests { let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index de2a85942..38a1df525 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -422,6 +422,7 @@ impl Header { #[cfg(test)] mod tests { use util::*; + use util::trie::TrieSpec; use block::*; use tests::helpers::*; use env_info::EnvInfo; @@ -438,7 +439,7 @@ mod tests { let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close(); @@ -452,7 +453,7 @@ mod tests { let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); let mut b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut uncle = Header::new(); diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index e236924ad..3916e5ccc 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -72,6 +72,7 @@ pub fn new_morden() -> Spec { load(include_bytes!("../../res/ethereum/morden.jso #[cfg(test)] mod tests { use util::*; + use util::trie::TrieSpec; use state::*; use super::*; use tests::helpers::*; @@ -84,7 +85,7 @@ mod tests { let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - spec.ensure_db_good(&mut db).unwrap(); + spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let s = State::from_existing(db, genesis_header.state_root().clone(), engine.account_start_nonce(), Default::default()).unwrap(); assert_eq!(s.balance(&"0000000000000000000000000000000000000001".into()), 1u64.into()); assert_eq!(s.balance(&"0000000000000000000000000000000000000002".into()), 1u64.into()); diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index adfb4f096..ea2ef378f 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -18,6 +18,7 @@ use ethkey::KeyPair; use io::*; use client::{BlockChainClient, Client, ClientConfig}; use util::*; +use util::trie::TrieSpec; use spec::*; use state_db::StateDB; use block::{OpenBlock, Drain}; @@ -157,7 +158,7 @@ pub fn generate_dummy_client_with_spec_and_data(get_test_spec: F, block_numbe let mut db_result = get_temp_state_db(); let mut db = db_result.take(); - test_spec.ensure_db_good(&mut db).unwrap(); + test_spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let genesis_header = test_spec.genesis_header(); let mut rolling_timestamp = 40; diff --git a/parity/blockchain.rs b/parity/blockchain.rs index b43cf478f..bc0509cb5 100644 --- a/parity/blockchain.rs +++ b/parity/blockchain.rs @@ -120,6 +120,8 @@ pub struct ExportState { pub at: BlockID, pub storage: bool, pub code: bool, + pub min_balance: Option, + pub max_balance: Option, } pub fn execute(cmd: BlockchainCmd) -> Result { @@ -402,10 +404,17 @@ fn execute_export_state(cmd: ExportState) -> Result { } for account in accounts.into_iter() { + + let balance = client.balance(&account, at).unwrap_or_else(U256::zero); + + if cmd.min_balance.map_or(false, |m| balance < m) || cmd.max_balance.map_or(false, |m| balance > m) { + continue; //filtered out + } + if i != 0 { out.write(b",").expect("Write error"); } - out.write_fmt(format_args!("\n\"0x{}\": {{\"balance\": \"{:x}\", \"nonce\": \"{:x}\"", account.hex(), client.balance(&account, at).unwrap_or_else(U256::zero), client.nonce(&account, at).unwrap_or_else(U256::zero))).expect("Write error"); + out.write_fmt(format_args!("\n\"0x{}\": {{\"balance\": \"{:x}\", \"nonce\": \"{:x}\"", account.hex(), balance, client.nonce(&account, at).unwrap_or_else(U256::zero))).expect("Write error"); let code = client.code(&account, at).unwrap_or(None).unwrap_or_else(Vec::new); if !code.is_empty() { out.write_fmt(format_args!(", \"code_hash\": \"0x{}\"", code.sha3().hex())).expect("Write error"); @@ -441,7 +450,7 @@ fn execute_export_state(cmd: ExportState) -> Result { out.write(b"}").expect("Write error"); i += 1; if i % 10000 == 0 { - info!("#{}", i); + info!("Account #{}", i); } last = Some(account); } diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 33e07c2d3..06a45b0e9 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -250,6 +250,8 @@ usage! { flag_no_seal_check: bool = false, or |_| None, flag_no_storage: bool = false, or |_| None, flag_no_code: bool = false, or |_| None, + flag_min_balance: Option = None, or |_| None, + flag_max_balance: Option = None, or |_| None, // -- Snapshot Optons flag_at: String = "latest", or |_| None, @@ -606,6 +608,10 @@ mod tests { flag_to: "latest".into(), flag_format: None, flag_no_seal_check: false, + flag_no_code: false, + flag_no_storage: false, + flag_min_balance: None, + flag_max_balance: None, // -- Snapshot Optons flag_at: "latest".into(), diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index 2a03642bc..b67af6110 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -277,6 +277,10 @@ Import/Export Options: (default: {flag_at}) --no-storage Don't export account storge. (default: {flag_no_storage}) --no-code Don't export account code. (default: {flag_no_code}) + --min-balance WEI Don't export accounts with balance less than specified. + (default: {flag_min_balance:?}) + --max-balance WEI Don't export accounts with balance greater than specified. + (default: {flag_max_balance:?}) Snapshot Options: --at BLOCK Take a snapshot at the given block, which may be an diff --git a/parity/configuration.rs b/parity/configuration.rs index 3e50eff01..aafd958a7 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -195,6 +195,8 @@ impl Configuration { at: try!(to_block_id(&self.args.flag_at)), storage: !self.args.flag_no_storage, code: !self.args.flag_no_code, + min_balance: self.args.flag_min_balance.and_then(|s| to_u256(&s).ok()), + max_balance: self.args.flag_max_balance.and_then(|s| to_u256(&s).ok()), }; Cmd::Blockchain(BlockchainCmd::ExportState(export_cmd)) } else {