@@ -64,6 +64,192 @@ pub static CHAINSPEC_SYMLINK: Lazy<PathBuf> = Lazy::new(|| {
6464} ) ;
6565
6666#[ test]
67+ fn vm2_should_return_output_to_caller ( ) {
68+ let chainspec_config = ChainspecConfig :: from_chainspec_path ( & * CHAINSPEC_SYMLINK )
69+ . expect ( "must get chainspec config" ) ;
70+
71+ let mut executor = make_executor ( & chainspec_config) ;
72+ let ( global_state, mut state_root_hash, _tempdir) = make_global_state_with_genesis ( ) ;
73+ let address_generator = make_address_generator ( ) ;
74+
75+ let install_request = base_install_request_builder ( & chainspec_config)
76+ . with_wasm_bytes ( read_wasm ( "vm2-harness.wasm" ) )
77+ . with_shared_address_generator ( Arc :: clone ( & address_generator) )
78+ . with_transferred_value ( 0 )
79+ . with_entry_point ( "initialize" . to_string ( ) )
80+ . with_input ( Bytes :: from ( b"" . as_slice ( ) ) )
81+ . build ( )
82+ . expect ( "should build" ) ;
83+
84+ let create_result = run_create_contract (
85+ & mut executor,
86+ & global_state,
87+ state_root_hash,
88+ install_request,
89+ ) ;
90+
91+ let contract_hash = EntityAddr :: SmartContract ( * create_result. smart_contract_addr ( ) ) ;
92+ state_root_hash = global_state
93+ . commit_effects ( state_root_hash, create_result. effects ( ) . clone ( ) )
94+ . expect ( "Should commit" ) ;
95+
96+ let input = borsh:: to_vec ( & ( String :: from ( "hi" ) , ) )
97+ . map ( Bytes :: from)
98+ . unwrap ( ) ;
99+
100+ let execute_request = base_execute_builder ( & chainspec_config)
101+ . with_initiator ( * DEFAULT_ACCOUNT_HASH )
102+ . with_caller_key ( Key :: Account ( * DEFAULT_ACCOUNT_HASH ) )
103+ . with_gas_limit ( DEFAULT_GAS_LIMIT )
104+ . with_transaction_hash ( TRANSACTION_HASH )
105+ . with_execution_kind ( ExecutionKind :: Stored {
106+ address : contract_hash. value ( ) ,
107+ entry_point : "entry_point_without_state_with_args_and_output" . to_string ( ) ,
108+ } )
109+ . with_transferred_value ( 0 )
110+ . with_shared_address_generator ( Arc :: clone ( & address_generator) )
111+ . with_block_time ( Timestamp :: now ( ) . into ( ) )
112+ . with_state_hash ( state_root_hash)
113+ . with_block_height ( 2 )
114+ . with_parent_block_hash ( BlockHash :: new ( Digest :: hash ( b"block" ) ) )
115+ . with_input ( input)
116+ . with_runtime_native_config ( make_runtime_config ( & chainspec_config) )
117+ . build ( )
118+ . expect ( "should build" ) ;
119+
120+ let result = expect_successful_execution (
121+ & mut executor,
122+ & global_state,
123+ state_root_hash,
124+ execute_request,
125+ ) ;
126+ assert ! ( result. host_error. is_none( ) , "should be success" ) ;
127+ let out = result. output ( ) . expect ( "should have output" ) ;
128+ let returned: String = borsh:: from_slice ( out) . expect ( "borsh string" ) ;
129+ assert_eq ! ( returned, "hiextra" ) ;
130+ }
131+
132+ #[ test]
133+ fn vm2_rollback_should_return_to_caller_with_data ( ) {
134+ let chainspec_config = ChainspecConfig :: from_chainspec_path ( & * CHAINSPEC_SYMLINK )
135+ . expect ( "must get chainspec config" ) ;
136+
137+ let mut executor = make_executor ( & chainspec_config) ;
138+ let ( global_state, mut state_root_hash, _tempdir) = make_global_state_with_genesis ( ) ;
139+ let address_generator = make_address_generator ( ) ;
140+
141+ let install_request = base_install_request_builder ( & chainspec_config)
142+ . with_wasm_bytes ( read_wasm ( "vm2-harness.wasm" ) )
143+ . with_shared_address_generator ( Arc :: clone ( & address_generator) )
144+ . with_transferred_value ( 0 )
145+ . with_entry_point ( "initialize" . to_string ( ) )
146+ . with_input ( Bytes :: from ( b"" . as_slice ( ) ) )
147+ . build ( )
148+ . expect ( "should build" ) ;
149+ let create_result = run_create_contract (
150+ & mut executor,
151+ & global_state,
152+ state_root_hash,
153+ install_request,
154+ ) ;
155+ let contract_hash = EntityAddr :: SmartContract ( * create_result. smart_contract_addr ( ) ) ;
156+ state_root_hash = global_state
157+ . commit_effects ( state_root_hash, create_result. effects ( ) . clone ( ) )
158+ . expect ( "Should commit" ) ;
159+
160+ let input = borsh:: to_vec ( & ( ) ) . map ( Bytes :: from) . unwrap ( ) ;
161+ let execute_request = base_execute_builder ( & chainspec_config)
162+ . with_initiator ( * DEFAULT_ACCOUNT_HASH )
163+ . with_caller_key ( Key :: Account ( * DEFAULT_ACCOUNT_HASH ) )
164+ . with_gas_limit ( DEFAULT_GAS_LIMIT )
165+ . with_transaction_hash ( TRANSACTION_HASH )
166+ . with_execution_kind ( ExecutionKind :: Stored {
167+ address : contract_hash. value ( ) ,
168+ entry_point : "emit_revert_with_data" . to_string ( ) ,
169+ } )
170+ . with_transferred_value ( 0 )
171+ . with_shared_address_generator ( Arc :: clone ( & address_generator) )
172+ . with_block_time ( Timestamp :: now ( ) . into ( ) )
173+ . with_state_hash ( state_root_hash)
174+ . with_block_height ( 2 )
175+ . with_parent_block_hash ( BlockHash :: new ( Digest :: hash ( b"bl0ck" ) ) )
176+ . with_input ( input)
177+ . with_runtime_native_config ( make_runtime_config ( & chainspec_config) )
178+ . build ( )
179+ . expect ( "should build" ) ;
180+
181+ let result = executor
182+ . execute_with_provider ( state_root_hash, & global_state, execute_request)
183+ . expect ( "exec ok" ) ;
184+ match result. host_error {
185+ Some ( CallError :: CalleeRolledBack ) => { }
186+ Some ( other) => panic ! ( "expected CalleeRolledBack got {other:?}" ) ,
187+ None => panic ! ( "expected error" ) ,
188+ }
189+
190+ let out = result. output ( ) . expect ( "should carry rollback data" ) ;
191+ assert ! ( !out. is_empty( ) , "rollback should return some data" ) ;
192+ }
193+
194+ #[ test]
195+ fn vm2_revert_should_abort_whole_stack ( ) {
196+ let chainspec_config = ChainspecConfig :: from_chainspec_path ( & * CHAINSPEC_SYMLINK )
197+ . expect ( "must get chainspec config" ) ;
198+
199+ let mut executor = make_executor ( & chainspec_config) ;
200+ let ( global_state, mut state_root_hash, _tempdir) = make_global_state_with_genesis ( ) ;
201+ let address_generator = make_address_generator ( ) ;
202+
203+ let install_request = base_install_request_builder ( & chainspec_config)
204+ . with_wasm_bytes ( read_wasm ( "vm2-harness.wasm" ) )
205+ . with_shared_address_generator ( Arc :: clone ( & address_generator) )
206+ . with_transferred_value ( 0 )
207+ . with_entry_point ( "initialize" . to_string ( ) )
208+ . with_input ( Bytes :: from ( b"" . as_slice ( ) ) )
209+ . build ( )
210+ . expect ( "should build" ) ;
211+ let create_result = run_create_contract (
212+ & mut executor,
213+ & global_state,
214+ state_root_hash,
215+ install_request,
216+ ) ;
217+ let contract_hash = EntityAddr :: SmartContract ( * create_result. smart_contract_addr ( ) ) ;
218+ state_root_hash = global_state
219+ . commit_effects ( state_root_hash, create_result. effects ( ) . clone ( ) )
220+ . expect ( "Should commit" ) ;
221+
222+ let input = borsh:: to_vec ( & ( ) ) . map ( Bytes :: from) . unwrap ( ) ;
223+ let execute_request = base_execute_builder ( & chainspec_config)
224+ . with_initiator ( * DEFAULT_ACCOUNT_HASH )
225+ . with_caller_key ( Key :: Account ( * DEFAULT_ACCOUNT_HASH ) )
226+ . with_gas_limit ( DEFAULT_GAS_LIMIT )
227+ . with_transaction_hash ( TRANSACTION_HASH )
228+ . with_execution_kind ( ExecutionKind :: Stored {
229+ address : contract_hash. value ( ) ,
230+ entry_point : "emit_revert_without_data" . to_string ( ) ,
231+ } )
232+ . with_transferred_value ( 0 )
233+ . with_shared_address_generator ( Arc :: clone ( & address_generator) )
234+ . with_block_time ( Timestamp :: now ( ) . into ( ) )
235+ . with_state_hash ( state_root_hash)
236+ . with_block_height ( 2 )
237+ . with_parent_block_hash ( BlockHash :: new ( Digest :: hash ( b"bl0ck" ) ) )
238+ . with_input ( input)
239+ . with_runtime_native_config ( make_runtime_config ( & chainspec_config) )
240+ . build ( )
241+ . expect ( "should build" ) ;
242+
243+ let result = executor
244+ . execute_with_provider ( state_root_hash, & global_state, execute_request)
245+ . expect ( "exec ok" ) ;
246+ match result. host_error {
247+ Some ( CallError :: Api ( _) ) => { }
248+ Some ( other) => panic ! ( "expected Api(_) got {other:?}" ) ,
249+ None => panic ! ( "expected error" ) ,
250+ }
251+ }
252+
67253fn harness ( ) {
68254 let chainspec_config = ChainspecConfig :: from_chainspec_path ( & * CHAINSPEC_SYMLINK )
69255 . expect ( "must get chainspec config" ) ;
@@ -257,11 +443,11 @@ fn should_revert_invalid_system_option() {
257443 if let Ok ( exec_result) = result {
258444 assert ! ( exec_result. host_error. is_some( ) , "should have error" ) ;
259445 match exec_result. host_error {
260- Some ( CallError :: CalleeReverted ) => {
446+ Some ( CallError :: CalleeRolledBack ) => {
261447 // noop, expected outcome
262448 }
263449 Some ( err) => {
264- panic ! ( "expected: CalleeReverted actual: {}" , err) ;
450+ panic ! ( "expected: CalleeRolledBack actual: {}" , err) ;
265451 }
266452 None => {
267453 panic ! ( "should have error" )
@@ -1321,10 +1507,12 @@ fn casper_return_fails_if_contract_uses_unsupported_flags() {
13211507 let result = executor. execute_with_provider ( state_root_hash, & global_state, execute_request) ;
13221508 assert ! ( result. is_err( ) ) ;
13231509 let err: ExecuteWithProviderError = result. expect_err ( "should have error details" ) ;
1324- assert ! ( matches!(
1325- err,
1326- ExecuteWithProviderError :: Execute ( ExecuteError :: ReturnFlagsNotSupported ( 2 ) )
1327- ) ) ;
1510+ match err {
1511+ ExecuteWithProviderError :: Execute ( ExecuteError :: ReturnFlagsNotSupported ( v) ) => {
1512+ assert ! ( v != 0 , "invalid flags should be non-zero" ) ;
1513+ }
1514+ other => panic ! ( "expected ReturnFlagsNotSupported, got {other:?}" ) ,
1515+ }
13281516}
13291517
13301518#[ test]
0 commit comments