From 631df0fe5665bc9e5b578825605474b913fd782e Mon Sep 17 00:00:00 2001 From: Wei Tang Date: Tue, 11 Sep 2018 16:28:31 +0800 Subject: [PATCH] Fix checkpointing when creating contract failed (#9514) --- ethcore/src/state/mod.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/ethcore/src/state/mod.rs b/ethcore/src/state/mod.rs index fb843c9cc2e..98f877617d0 100644 --- a/ethcore/src/state/mod.rs +++ b/ethcore/src/state/mod.rs @@ -421,16 +421,7 @@ impl State { **prev = checkpoint; } else { for (k, v) in checkpoint.drain() { - match prev.entry(k) { - Entry::Occupied(mut e) => { - if e.get().is_none() { - e.insert(v); - } - }, - Entry::Vacant(e) => { - e.insert(v); - } - } + prev.entry(k).or_insert(v); } } } @@ -2462,6 +2453,25 @@ mod tests { assert_eq!(state.storage_at(&a, &k).unwrap(), H256::from(U256::from(1))); } + #[test] + fn create_contract_fail() { + let mut state = get_temp_state(); + let orig_root = state.root().clone(); + let a: Address = 1000.into(); + + state.checkpoint(); // c1 + state.new_contract(&a, U256::zero(), U256::zero()).unwrap(); + state.add_balance(&a, &U256::from(1), CleanupMode::ForceCreate).unwrap(); + state.checkpoint(); // c2 + state.add_balance(&a, &U256::from(1), CleanupMode::ForceCreate).unwrap(); + state.discard_checkpoint(); // discard c2 + state.revert_to_checkpoint(); // revert to c1 + assert_eq!(state.exists(&a).unwrap(), false); + + state.commit().unwrap(); + assert_eq!(orig_root, state.root().clone()); + } + #[test] fn create_empty() { let mut state = get_temp_state();