Skip to content

Commit 2609f17

Browse files
authored
Add snapshot functionality to ink_sandbox (#2261)
* Add Snapshot functionality * Add Snapshot testing * Add snapshot impl to sandbox_client
1 parent 11c637b commit 2609f17

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

crates/e2e/sandbox/src/api/system_api.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,4 +197,26 @@ mod tests {
197197
make_transfer(&mut sandbox, RECIPIENT, 1).expect("Failed to make transfer");
198198
assert!(!sandbox.events().is_empty());
199199
}
200+
201+
#[test]
202+
fn snapshot_works() {
203+
let mut sandbox = DefaultSandbox::default();
204+
205+
// Check state before
206+
let block_before = sandbox.block_number();
207+
let snapshot_before = sandbox.take_snapshot();
208+
209+
// Advance some blocks to have some state change
210+
let _ = sandbox.build_blocks(5);
211+
let block_after = sandbox.block_number();
212+
213+
// Check block number and state after
214+
assert_eq!(block_before + 5, block_after);
215+
216+
// Restore state
217+
sandbox.restore_snapshot(snapshot_before);
218+
219+
// Check state after restore
220+
assert_eq!(block_before, sandbox.block_number());
221+
}
200222
}

crates/e2e/sandbox/src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use pallet_contracts::{
2323
};
2424
/// Export pallets that are used in [`crate::create_sandbox`]
2525
pub use {
26+
frame_support::sp_runtime::testing::H256,
2627
frame_support::{
2728
self,
2829
sp_runtime::{
@@ -43,6 +44,18 @@ pub use {
4344
sp_io::TestExternalities,
4445
};
4546

47+
/// A snapshot of the storage.
48+
#[derive(Clone, Debug)]
49+
pub struct Snapshot {
50+
/// The storage raw key-value pairs.
51+
pub storage: RawStorage,
52+
/// The storage root hash.
53+
pub storage_root: StorageRoot,
54+
}
55+
56+
pub type RawStorage = Vec<(Vec<u8>, (Vec<u8>, i32))>;
57+
pub type StorageRoot = H256;
58+
4659
/// Alias for the balance type.
4760
type BalanceOf<R> =
4861
<<R as pallet_contracts::Config>::Currency as Inspect<AccountIdFor<R>>>::Balance;
@@ -118,4 +131,10 @@ pub trait Sandbox {
118131
fn convert_account_to_origin(
119132
account: AccountIdFor<Self::Runtime>,
120133
) -> <<Self::Runtime as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin;
134+
135+
/// Take a snapshot of the storage.
136+
fn take_snapshot(&mut self) -> Snapshot;
137+
138+
/// Restore the storage from the given snapshot.
139+
fn restore_snapshot(&mut self, snapshot: Snapshot);
121140
}

crates/e2e/sandbox/src/macros.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ mod construct_runtime {
115115
weights::Weight,
116116
};
117117

118+
use $crate::Snapshot;
119+
118120
// Define the runtime type as a collection of pallets
119121
construct_runtime!(
120122
pub enum $runtime {
@@ -289,6 +291,31 @@ mod construct_runtime {
289291
) -> <<Self::Runtime as $crate::frame_system::Config>::RuntimeCall as $crate::frame_support::sp_runtime::traits::Dispatchable>::RuntimeOrigin {
290292
Some(account).into()
291293
}
294+
295+
fn take_snapshot(&mut self) -> Snapshot {
296+
let mut backend = self.ext.as_backend().clone();
297+
let raw_key_values = backend
298+
.backend_storage_mut()
299+
.drain()
300+
.into_iter()
301+
.filter(|(_, (_, r))| *r > 0)
302+
.collect::<Vec<(Vec<u8>, (Vec<u8>, i32))>>();
303+
let root = backend.root().to_owned();
304+
Snapshot {
305+
storage: raw_key_values,
306+
storage_root: root,
307+
}
308+
}
309+
310+
fn restore_snapshot(&mut self, snapshot: Snapshot) {
311+
self.ext = $crate::TestExternalities::from_raw_snapshot(
312+
snapshot.storage,
313+
snapshot.storage_root,
314+
Default::default(),
315+
);
316+
}
317+
318+
292319
}
293320
}
294321

crates/e2e/src/sandbox_client.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ pub mod preset {
469469
Extension,
470470
RuntimeMetadataPrefixed,
471471
Sandbox,
472+
Snapshot,
472473
};
473474
pub use pallet_contracts_mock_network::*;
474475
use sp_runtime::traits::Dispatchable;
@@ -543,6 +544,37 @@ pub mod preset {
543544
{
544545
Some(account).into()
545546
}
547+
548+
fn take_snapshot(&mut self) -> Snapshot {
549+
EXT_PARAA.with(|v| {
550+
let v = v.borrow();
551+
let mut backend = v.as_backend().clone();
552+
let raw_key_values = backend
553+
.backend_storage_mut()
554+
.drain()
555+
.into_iter()
556+
.filter(|(_, (_, r))| *r > 0)
557+
.collect::<Vec<(Vec<u8>, (Vec<u8>, i32))>>();
558+
let root = backend.root().to_owned();
559+
560+
Snapshot {
561+
storage: raw_key_values,
562+
storage_root: root,
563+
}
564+
})
565+
}
566+
567+
fn restore_snapshot(&mut self, snapshot: ink_sandbox::Snapshot) {
568+
EXT_PARAA.with(|v| {
569+
let mut v = v.borrow_mut();
570+
571+
*v = ink_sandbox::TestExternalities::from_raw_snapshot(
572+
snapshot.storage,
573+
snapshot.storage_root,
574+
Default::default(),
575+
);
576+
})
577+
}
546578
}
547579
}
548580
}

0 commit comments

Comments
 (0)