@@ -6,22 +6,31 @@ use polkadot_sdk::{
66 Executable , Pallet ,
77 } ,
88 sp_core:: { self , H160 } ,
9+ sp_externalities:: Externalities ,
910 sp_io:: TestExternalities ,
1011} ;
1112use revive_env:: { AccountId , BlockAuthor , ExtBuilder , Runtime , System , Timestamp } ;
1213use std:: {
1314 fmt:: Debug ,
1415 sync:: { Arc , Mutex } ,
1516} ;
16- pub struct TestEnv ( pub Arc < Mutex < TestExternalities > > ) ;
1717
18- impl Default for TestEnv {
18+ pub ( crate ) struct Inner {
19+ pub externalities : TestExternalities ,
20+ pub depth : usize ,
21+ }
22+
23+ #[ derive( Default ) ]
24+ pub struct TestEnv ( pub ( crate ) Arc < Mutex < Inner > > ) ;
25+
26+ impl Default for Inner {
1927 fn default ( ) -> Self {
20- Self ( Arc :: new ( Mutex :: new (
21- ExtBuilder :: default ( )
28+ Self {
29+ externalities : ExtBuilder :: default ( )
2230 . balance_genesis_config ( vec ! [ ( H160 :: from_low_u64_be( 1 ) , 1000 ) ] )
2331 . build ( ) ,
24- ) ) )
32+ depth : 0 ,
33+ }
2534 }
2635}
2736
@@ -33,9 +42,10 @@ impl Debug for TestEnv {
3342
3443impl Clone for TestEnv {
3544 fn clone ( & self ) -> Self {
36- let mut externalities = ExtBuilder :: default ( ) . build ( ) ;
37- externalities. backend = self . 0 . lock ( ) . unwrap ( ) . as_backend ( ) ;
38- Self ( Arc :: new ( Mutex :: new ( externalities) ) )
45+ let mut inner: Inner = Default :: default ( ) ;
46+ inner. externalities . backend = self . 0 . lock ( ) . unwrap ( ) . externalities . as_backend ( ) ;
47+ inner. depth = self . 0 . lock ( ) . unwrap ( ) . depth ;
48+ Self ( Arc :: new ( Mutex :: new ( inner) ) )
3949 }
4050}
4151
@@ -44,20 +54,36 @@ impl TestEnv {
4454 Self ( self . 0 . clone ( ) )
4555 }
4656
57+ pub fn start_snapshotting ( & mut self ) {
58+ let mut state = self . 0 . lock ( ) . unwrap ( ) ;
59+ state. depth += 1 ;
60+ state. externalities . ext ( ) . storage_start_transaction ( ) ;
61+ }
62+
63+ pub fn revert ( & mut self , depth : usize ) {
64+ let mut state = self . 0 . lock ( ) . unwrap ( ) ;
65+ while state. depth > depth + 1 {
66+ state. externalities . ext ( ) . storage_rollback_transaction ( ) . unwrap ( ) ;
67+ state. depth -= 1 ;
68+ }
69+ state. externalities . ext ( ) . storage_rollback_transaction ( ) . unwrap ( ) ;
70+ state. externalities . ext ( ) . storage_start_transaction ( ) ;
71+ }
72+
4773 pub fn execute_with < R , F : FnOnce ( ) -> R > ( & mut self , f : F ) -> R {
48- self . 0 . lock ( ) . unwrap ( ) . execute_with ( f)
74+ self . 0 . lock ( ) . unwrap ( ) . externalities . execute_with ( f)
4975 }
5076
5177 pub fn get_nonce ( & mut self , account : Address ) -> u32 {
52- self . 0 . lock ( ) . unwrap ( ) . execute_with ( || {
78+ self . 0 . lock ( ) . unwrap ( ) . externalities . execute_with ( || {
5379 System :: account_nonce ( AccountId :: to_fallback_account_id ( & H160 :: from_slice (
5480 account. as_slice ( ) ,
5581 ) ) )
5682 } )
5783 }
5884
5985 pub fn set_nonce ( & mut self , address : Address , nonce : u64 ) {
60- self . 0 . lock ( ) . unwrap ( ) . execute_with ( || {
86+ self . 0 . lock ( ) . unwrap ( ) . externalities . execute_with ( || {
6187 let account_id =
6288 AccountId :: to_fallback_account_id ( & H160 :: from_slice ( address. as_slice ( ) ) ) ;
6389
@@ -69,7 +95,7 @@ impl TestEnv {
6995
7096 pub fn set_chain_id ( & mut self , new_chain_id : u64 ) {
7197 // Set chain id in pallet-revive runtime.
72- self . 0 . lock ( ) . unwrap ( ) . execute_with ( || {
98+ self . 0 . lock ( ) . unwrap ( ) . externalities . execute_with ( || {
7399 <revive_env:: Runtime as polkadot_sdk:: pallet_revive:: Config >:: ChainId :: set (
74100 & new_chain_id,
75101 ) ;
@@ -78,14 +104,14 @@ impl TestEnv {
78104
79105 pub fn set_block_number ( & mut self , new_height : U256 ) {
80106 // Set block number in pallet-revive runtime.
81- self . 0 . lock ( ) . unwrap ( ) . execute_with ( || {
107+ self . 0 . lock ( ) . unwrap ( ) . externalities . execute_with ( || {
82108 System :: set_block_number ( new_height. try_into ( ) . expect ( "Block number exceeds u64" ) ) ;
83109 } ) ;
84110 }
85111
86112 pub fn set_timestamp ( & mut self , new_timestamp : U256 ) {
87113 // Set timestamp in pallet-revive runtime (milliseconds).
88- self . 0 . lock ( ) . unwrap ( ) . execute_with ( || {
114+ self . 0 . lock ( ) . unwrap ( ) . externalities . execute_with ( || {
89115 let timestamp_ms = new_timestamp. saturating_to :: < u64 > ( ) . saturating_mul ( 1000 ) ;
90116 Timestamp :: set_timestamp ( timestamp_ms) ;
91117 } ) ;
@@ -97,7 +123,7 @@ impl TestEnv {
97123 new_runtime_code : & Bytes ,
98124 ecx : Ecx < ' _ , ' _ , ' _ > ,
99125 ) -> Result {
100- self . 0 . lock ( ) . unwrap ( ) . execute_with ( || {
126+ self . 0 . lock ( ) . unwrap ( ) . externalities . execute_with ( || {
101127 let origin_address = H160 :: from_slice ( ecx. tx . caller . as_slice ( ) ) ;
102128 let origin_account = AccountId :: to_fallback_account_id ( & origin_address) ;
103129
@@ -153,6 +179,7 @@ impl TestEnv {
153179 self . 0
154180 . lock ( )
155181 . unwrap ( )
182+ . externalities
156183 . execute_with ( || {
157184 pallet_revive:: Pallet :: < Runtime > :: get_storage ( target_address_h160, slot. into ( ) )
158185 } )
@@ -169,6 +196,7 @@ impl TestEnv {
169196 self . 0
170197 . lock ( )
171198 . unwrap ( )
199+ . externalities
172200 . execute_with ( || {
173201 pallet_revive:: Pallet :: < Runtime > :: set_storage (
174202 target_address_h160,
@@ -184,7 +212,7 @@ impl TestEnv {
184212 let amount_pvm =
185213 sp_core:: U256 :: from_little_endian ( & amount. as_le_bytes ( ) ) . min ( u128:: MAX . into ( ) ) ;
186214
187- self . 0 . lock ( ) . unwrap ( ) . execute_with ( || {
215+ self . 0 . lock ( ) . unwrap ( ) . externalities . execute_with ( || {
188216 let h160_addr = H160 :: from_slice ( address. as_slice ( ) ) ;
189217 pallet_revive:: Pallet :: < Runtime > :: set_evm_balance ( & h160_addr, amount_pvm)
190218 . expect ( "failed to set evm balance" ) ;
@@ -195,6 +223,7 @@ impl TestEnv {
195223 self . 0
196224 . lock ( )
197225 . unwrap ( )
226+ . externalities
198227 . execute_with ( || {
199228 let h160_addr = H160 :: from_slice ( address. as_slice ( ) ) ;
200229 pallet_revive:: Pallet :: < Runtime > :: evm_balance ( & h160_addr)
@@ -204,7 +233,7 @@ impl TestEnv {
204233 }
205234
206235 pub fn set_block_author ( & mut self , new_author : Address ) {
207- self . 0 . lock ( ) . unwrap ( ) . execute_with ( || {
236+ self . 0 . lock ( ) . unwrap ( ) . externalities . execute_with ( || {
208237 let account_id32 =
209238 AccountId :: to_fallback_account_id ( & H160 :: from_slice ( new_author. as_slice ( ) ) ) ;
210239 BlockAuthor :: set ( & account_id32) ;
0 commit comments