Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
rename State::snapshot to checkpoint to avoid confusion (#2796)
Browse files Browse the repository at this point in the history
  • Loading branch information
rphmeier authored and gavofyork committed Oct 22, 2016
1 parent 3ff1ca8 commit 8e5c9ff
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 56 deletions.
14 changes: 7 additions & 7 deletions ethcore/src/executive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ impl<'a> Executive<'a> {
vm_tracer: &mut V
) -> evm::Result<U256> where T: Tracer, V: VMTracer {
// backup used in case of running out of gas
self.state.snapshot();
self.state.checkpoint();

// at first, transfer value to destination
if let ActionValue::Transfer(val) = params.value {
Expand All @@ -269,7 +269,7 @@ impl<'a> Executive<'a> {
let cost = self.engine.cost_of_builtin(&params.code_address, data);
if cost <= params.gas {
self.engine.execute_builtin(&params.code_address, data, &mut output);
self.state.discard_snapshot();
self.state.discard_checkpoint();

// trace only top level calls to builtins to avoid DDoS attacks
if self.depth == 0 {
Expand All @@ -289,7 +289,7 @@ impl<'a> Executive<'a> {
Ok(params.gas - cost)
} else {
// just drain the whole gas
self.state.revert_to_snapshot();
self.state.revert_to_checkpoint();

tracer.trace_failed_call(trace_info, vec![], evm::Error::OutOfGas.into());

Expand Down Expand Up @@ -335,7 +335,7 @@ impl<'a> Executive<'a> {
res
} else {
// otherwise it's just a basic transaction, only do tracing, if necessary.
self.state.discard_snapshot();
self.state.discard_checkpoint();

tracer.trace_call(trace_info, U256::zero(), trace_output, vec![]);
Ok(params.gas)
Expand All @@ -354,7 +354,7 @@ impl<'a> Executive<'a> {
vm_tracer: &mut V
) -> evm::Result<U256> where T: Tracer, V: VMTracer {
// backup used in case of running out of gas
self.state.snapshot();
self.state.checkpoint();

// part of substate that may be reverted
let mut unconfirmed_substate = Substate::new();
Expand Down Expand Up @@ -485,10 +485,10 @@ impl<'a> Executive<'a> {
| Err(evm::Error::BadInstruction {.. })
| Err(evm::Error::StackUnderflow {..})
| Err(evm::Error::OutOfStack {..}) => {
self.state.revert_to_snapshot();
self.state.revert_to_checkpoint();
},
Ok(_) | Err(evm::Error::Internal) => {
self.state.discard_snapshot();
self.state.discard_checkpoint();
substate.accrue(un_substate);
}
}
Expand Down
98 changes: 49 additions & 49 deletions ethcore/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,24 +167,24 @@ impl AccountEntry {
/// Upon destruction all the local cache data propagated into the global cache.
/// Propagated items might be rejected if current state is non-canonical.
///
/// State snapshotting.
/// State checkpointing.
///
/// A new snapshot can be created with `snapshot()`. Snapshots can be
/// A new checkpoint can be created with `checkpoint()`. checkpoints can be
/// created in a hierarchy.
/// When a snapshot is active all changes are applied directly into
/// `cache` and the original value is copied into an active snapshot.
/// Reverting a snapshot with `revert_to_snapshot` involves copying
/// original values from the latest snapshot back into `cache`. The code
/// When a checkpoint is active all changes are applied directly into
/// `cache` and the original value is copied into an active checkpoint.
/// Reverting a checkpoint with `revert_to_checkpoint` involves copying
/// original values from the latest checkpoint back into `cache`. The code
/// takes care not to overwrite cached storage while doing that.
/// Snapshot can be discateded with `discard_snapshot`. All of the orignal
/// backed-up values are moved into a parent snapshot (if any).
/// checkpoint can be discateded with `discard_checkpoint`. All of the orignal
/// backed-up values are moved into a parent checkpoint (if any).
///
pub struct State {
db: StateDB,
root: H256,
cache: RefCell<HashMap<Address, AccountEntry>>,
// The original account is preserved in
snapshots: RefCell<Vec<HashMap<Address, Option<AccountEntry>>>>,
checkpoints: RefCell<Vec<HashMap<Address, Option<AccountEntry>>>>,
account_start_nonce: U256,
factories: Factories,
}
Expand Down Expand Up @@ -213,7 +213,7 @@ impl State {
db: db,
root: root,
cache: RefCell::new(HashMap::new()),
snapshots: RefCell::new(Vec::new()),
checkpoints: RefCell::new(Vec::new()),
account_start_nonce: account_start_nonce,
factories: factories,
}
Expand All @@ -229,45 +229,45 @@ impl State {
db: db,
root: root,
cache: RefCell::new(HashMap::new()),
snapshots: RefCell::new(Vec::new()),
checkpoints: RefCell::new(Vec::new()),
account_start_nonce: account_start_nonce,
factories: factories
};

Ok(state)
}

/// Create a recoverable snaphot of this state.
pub fn snapshot(&mut self) {
self.snapshots.get_mut().push(HashMap::new());
/// Create a recoverable checkpoint of this state.
pub fn checkpoint(&mut self) {
self.checkpoints.get_mut().push(HashMap::new());
}

/// Merge last snapshot with previous.
pub fn discard_snapshot(&mut self) {
// merge with previous snapshot
let last = self.snapshots.get_mut().pop();
if let Some(mut snapshot) = last {
if let Some(ref mut prev) = self.snapshots.get_mut().last_mut() {
/// Merge last checkpoint with previous.
pub fn discard_checkpoint(&mut self) {
// merge with previous checkpoint
let last = self.checkpoints.get_mut().pop();
if let Some(mut checkpoint) = last {
if let Some(ref mut prev) = self.checkpoints.get_mut().last_mut() {
if prev.is_empty() {
**prev = snapshot;
**prev = checkpoint;
} else {
for (k, v) in snapshot.drain() {
for (k, v) in checkpoint.drain() {
prev.entry(k).or_insert(v);
}
}
}
}
}

/// Revert to the last snapshot and discard it.
pub fn revert_to_snapshot(&mut self) {
if let Some(mut snapshot) = self.snapshots.get_mut().pop() {
for (k, v) in snapshot.drain() {
/// Revert to the last checkpoint and discard it.
pub fn revert_to_checkpoint(&mut self) {
if let Some(mut checkpoint) = self.checkpoints.get_mut().pop() {
for (k, v) in checkpoint.drain() {
match v {
Some(v) => {
match self.cache.get_mut().entry(k) {
Entry::Occupied(mut e) => {
// Merge snapshotted changes back into the main account
// Merge checkpointed changes back into the main account
// storage preserving the cache.
e.get_mut().overwrite_with(v);
},
Expand All @@ -293,14 +293,14 @@ impl State {

fn insert_cache(&self, address: &Address, account: AccountEntry) {
// Dirty account which is not in the cache means this is a new account.
// It goes directly into the snapshot as there's nothing to rever to.
// It goes directly into the checkpoint as there's nothing to rever to.
//
// In all other cases account is read as clean first, and after that made
// dirty in and added to the snapshot with `note_cache`.
// dirty in and added to the checkpoint with `note_cache`.
if account.is_dirty() {
if let Some(ref mut snapshot) = self.snapshots.borrow_mut().last_mut() {
if !snapshot.contains_key(address) {
snapshot.insert(address.clone(), self.cache.borrow_mut().insert(address.clone(), account));
if let Some(ref mut checkpoint) = self.checkpoints.borrow_mut().last_mut() {
if !checkpoint.contains_key(address) {
checkpoint.insert(address.clone(), self.cache.borrow_mut().insert(address.clone(), account));
return;
}
}
Expand All @@ -309,9 +309,9 @@ impl State {
}

fn note_cache(&self, address: &Address) {
if let Some(ref mut snapshot) = self.snapshots.borrow_mut().last_mut() {
if !snapshot.contains_key(address) {
snapshot.insert(address.clone(), self.cache.borrow().get(address).map(AccountEntry::clone_dirty));
if let Some(ref mut checkpoint) = self.checkpoints.borrow_mut().last_mut() {
if !checkpoint.contains_key(address) {
checkpoint.insert(address.clone(), self.cache.borrow().get(address).map(AccountEntry::clone_dirty));
}
}
}
Expand Down Expand Up @@ -548,7 +548,7 @@ impl State {

/// Commits our cached account changes into the trie.
pub fn commit(&mut self) -> Result<(), Error> {
assert!(self.snapshots.borrow().is_empty());
assert!(self.checkpoints.borrow().is_empty());
Self::commit_into(&self.factories, &mut self.db, &mut self.root, &mut *self.cache.borrow_mut())
}

Expand All @@ -561,15 +561,15 @@ impl State {
#[cfg(feature = "json-tests")]
/// Populate the state from `accounts`.
pub fn populate_from(&mut self, accounts: PodState) {
assert!(self.snapshots.borrow().is_empty());
assert!(self.checkpoints.borrow().is_empty());
for (add, acc) in accounts.drain().into_iter() {
self.cache.borrow_mut().insert(add, AccountEntry::new_dirty(Some(Account::from_pod(acc))));
}
}

/// Populate a PodAccount map from this state.
pub fn to_pod(&self) -> PodState {
assert!(self.snapshots.borrow().is_empty());
assert!(self.checkpoints.borrow().is_empty());
// TODO: handle database rather than just the cache.
// will need fat db.
PodState::from(self.cache.borrow().iter().fold(BTreeMap::new(), |mut m, (add, opt)| {
Expand Down Expand Up @@ -739,7 +739,7 @@ impl Clone for State {
db: self.db.boxed_clone(),
root: self.root.clone(),
cache: RefCell::new(cache),
snapshots: RefCell::new(Vec::new()),
checkpoints: RefCell::new(Vec::new()),
account_start_nonce: self.account_start_nonce.clone(),
factories: self.factories.clone(),
}
Expand Down Expand Up @@ -1777,34 +1777,34 @@ fn ensure_cached() {
}

#[test]
fn snapshot_basic() {
fn checkpoint_basic() {
let mut state_result = get_temp_state();
let mut state = state_result.reference_mut();
let a = Address::zero();
state.snapshot();
state.checkpoint();
state.add_balance(&a, &U256::from(69u64));
assert_eq!(state.balance(&a), U256::from(69u64));
state.discard_snapshot();
state.discard_checkpoint();
assert_eq!(state.balance(&a), U256::from(69u64));
state.snapshot();
state.checkpoint();
state.add_balance(&a, &U256::from(1u64));
assert_eq!(state.balance(&a), U256::from(70u64));
state.revert_to_snapshot();
state.revert_to_checkpoint();
assert_eq!(state.balance(&a), U256::from(69u64));
}

#[test]
fn snapshot_nested() {
fn checkpoint_nested() {
let mut state_result = get_temp_state();
let mut state = state_result.reference_mut();
let a = Address::zero();
state.snapshot();
state.snapshot();
state.checkpoint();
state.checkpoint();
state.add_balance(&a, &U256::from(69u64));
assert_eq!(state.balance(&a), U256::from(69u64));
state.discard_snapshot();
state.discard_checkpoint();
assert_eq!(state.balance(&a), U256::from(69u64));
state.revert_to_snapshot();
state.revert_to_checkpoint();
assert_eq!(state.balance(&a), U256::from(0));
}

Expand Down

0 comments on commit 8e5c9ff

Please sign in to comment.