[beta] Backports (#8346)
* Warp-only sync with warp-barrier [blocknumber] flag. (#8228) * Warp-only sync with warp-after [blocknumber] flag. * Fix tests. * Fix configuration tests. * Rename to warp barrier. * Allow unsafe js eval on Parity Wallet. (#8204) * Update musicoin spec in line with gmc v2.6.2 (#8242) * Supress TemporaryInvalid verification failures. (#8256) * Include suicided accounts in state diff (#8297) * Include suicided accounts in state diff * Shorten form match -> if let * Test suicide trace diff in State * replace_home for password_files, reserved_peers and log_file (#8324) * replace_home for password_files, reserved_peers and log_file * typo: arg_log_file is Option * Enable UI by default, but only display info page. * Fix test. * Fix naming and remove old todo. * Change "wallet" with "browser UI"
This commit is contained in:
@@ -833,16 +833,26 @@ impl<B: Backend> State<B> {
|
||||
}))
|
||||
}
|
||||
|
||||
fn query_pod(&mut self, query: &PodState) -> trie::Result<()> {
|
||||
for (address, pod_account) in query.get() {
|
||||
// Return a list of all touched addresses in cache.
|
||||
fn touched_addresses(&self) -> Vec<Address> {
|
||||
assert!(self.checkpoints.borrow().is_empty());
|
||||
self.cache.borrow().iter().map(|(add, _)| *add).collect()
|
||||
}
|
||||
|
||||
fn query_pod(&mut self, query: &PodState, touched_addresses: &[Address]) -> trie::Result<()> {
|
||||
let pod = query.get();
|
||||
|
||||
for address in touched_addresses {
|
||||
if !self.ensure_cached(address, RequireCache::Code, true, |a| a.is_some())? {
|
||||
continue
|
||||
}
|
||||
|
||||
// needs to be split into two parts for the refcell code here
|
||||
// to work.
|
||||
for key in pod_account.storage.keys() {
|
||||
self.storage_at(address, key)?;
|
||||
if let Some(pod_account) = pod.get(address) {
|
||||
// needs to be split into two parts for the refcell code here
|
||||
// to work.
|
||||
for key in pod_account.storage.keys() {
|
||||
self.storage_at(address, key)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -852,9 +862,10 @@ impl<B: Backend> State<B> {
|
||||
/// Returns a `StateDiff` describing the difference from `orig` to `self`.
|
||||
/// Consumes self.
|
||||
pub fn diff_from<X: Backend>(&self, orig: State<X>) -> trie::Result<StateDiff> {
|
||||
let addresses_post = self.touched_addresses();
|
||||
let pod_state_post = self.to_pod();
|
||||
let mut state_pre = orig;
|
||||
state_pre.query_pod(&pod_state_post)?;
|
||||
state_pre.query_pod(&pod_state_post, &addresses_post)?;
|
||||
Ok(pod_state::diff_pod(&state_pre.to_pod(), &pod_state_post))
|
||||
}
|
||||
|
||||
@@ -2180,4 +2191,37 @@ mod tests {
|
||||
assert!(state.exists(&d).unwrap());
|
||||
assert!(!state.exists(&e).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_trace_diff_suicided_accounts() {
|
||||
use pod_account;
|
||||
|
||||
let a = 10.into();
|
||||
let db = get_temp_state_db();
|
||||
let (root, db) = {
|
||||
let mut state = State::new(db, U256::from(0), Default::default());
|
||||
state.add_balance(&a, &100.into(), CleanupMode::ForceCreate).unwrap();
|
||||
state.commit().unwrap();
|
||||
state.drop()
|
||||
};
|
||||
|
||||
let mut state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap();
|
||||
let original = state.clone();
|
||||
state.kill_account(&a);
|
||||
|
||||
assert_eq!(original.touched_addresses(), vec![]);
|
||||
assert_eq!(state.touched_addresses(), vec![a]);
|
||||
|
||||
let diff = state.diff_from(original).unwrap();
|
||||
let diff_map = diff.get();
|
||||
assert_eq!(diff_map.len(), 1);
|
||||
assert!(diff_map.get(&a).is_some());
|
||||
assert_eq!(diff_map.get(&a),
|
||||
pod_account::diff_pod(Some(&PodAccount {
|
||||
balance: U256::from(100),
|
||||
nonce: U256::zero(),
|
||||
code: Some(Default::default()),
|
||||
storage: Default::default()
|
||||
}), None).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ pub mod blocks {
|
||||
use super::{Kind, BlockLike};
|
||||
|
||||
use engines::EthEngine;
|
||||
use error::Error;
|
||||
use error::{Error, BlockError};
|
||||
use header::Header;
|
||||
use verification::{PreverifiedBlock, verify_block_basic, verify_block_unordered};
|
||||
|
||||
@@ -88,6 +88,10 @@ pub mod blocks {
|
||||
fn create(input: Self::Input, engine: &EthEngine) -> Result<Self::Unverified, Error> {
|
||||
match verify_block_basic(&input.header, &input.bytes, engine) {
|
||||
Ok(()) => Ok(input),
|
||||
Err(Error::Block(BlockError::TemporarilyInvalid(oob))) => {
|
||||
debug!(target: "client", "Block received too early {}: {:?}", input.hash(), oob);
|
||||
Err(BlockError::TemporarilyInvalid(oob).into())
|
||||
},
|
||||
Err(e) => {
|
||||
warn!(target: "client", "Stage 1 block verification failed for {}: {:?}", input.hash(), e);
|
||||
Err(e)
|
||||
|
||||
Reference in New Issue
Block a user