From 06367ba3ab267cd9f899c374b423dff2a34f0a16 Mon Sep 17 00:00:00 2001 From: Runtian Zhou Date: Thu, 26 Oct 2023 11:27:12 -0700 Subject: [PATCH] [api] Add contextual information to VMStatus::Error --- api/src/tests/transactions_test.rs | 26 +++++++++++++++++++ api/src/transactions.rs | 20 ++++++++++++-- .../move-vm/types/src/values/values_impl.rs | 5 +++- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/api/src/tests/transactions_test.rs b/api/src/tests/transactions_test.rs index 7a4c1cf9a201e..d472110446757 100644 --- a/api/src/tests/transactions_test.rs +++ b/api/src/tests/transactions_test.rs @@ -1372,6 +1372,32 @@ async fn test_gas_estimation_static_override() { context.check_golden_output(resp); } +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn simulation_failure_error_message() { + let mut context = new_test_context(current_function_name!()); + let admin0 = context.root_account().await; + + // script { + // fun main() { + // 1/0; + // } + // } + + let output = context.simulate_transaction(&admin0, json!({ + "type": "script_payload", + "code": { + "bytecode": "a11ceb0b030000000105000100000000050601000000000000000600000000000000001a0102", + }, + "type_arguments": [], + "arguments": [], + }), 200).await; + + assert!(output.as_array().unwrap()[0]["vm_status"] + .as_str() + .unwrap() + .contains("Division by zero")); +} + fn gen_string(len: u64) -> String { let mut rng = thread_rng(); std::iter::repeat(()) diff --git a/api/src/transactions.rs b/api/src/transactions.rs index 7039fb3476e2b..6829d82b0785e 100644 --- a/api/src/transactions.rs +++ b/api/src/transactions.rs @@ -39,6 +39,7 @@ use aptos_types::{ vm_status::StatusCode, }; use aptos_vm::{data_cache::AsMoveResolver, AptosVM}; +use move_core_types::vm_status::VMStatus; use poem_openapi::{ param::{Path, Query}, payload::Json, @@ -1188,7 +1189,7 @@ impl TransactionsApi { // Simulate transaction let state_view = self.context.latest_state_view_poem(&ledger_info)?; let move_resolver = state_view.as_move_resolver(); - let (_, output) = AptosVM::simulate_signed_transaction(&txn, &move_resolver); + let (vm_status, output) = AptosVM::simulate_signed_transaction(&txn, &move_resolver); let version = ledger_info.version(); // Ensure that all known statuses return their values in the output (even if they aren't supposed to) @@ -1230,7 +1231,22 @@ impl TransactionsApi { let mut user_transactions = Vec::new(); for transaction in transactions.into_iter() { match transaction { - Transaction::UserTransaction(user_txn) => user_transactions.push(*user_txn), + Transaction::UserTransaction(user_txn) => { + let mut txn = *user_txn; + match &vm_status { + VMStatus::Error { + message: Some(msg), .. + } + | VMStatus::ExecutionFailure { + message: Some(msg), .. + } => { + txn.info.vm_status += + format!("\nExecution failed with status: {}", msg).as_str(); + }, + _ => (), + } + user_transactions.push(txn); + }, _ => { return Err(SubmitTransactionError::internal_with_code( "Simulation transaction resulted in a non-UserTransaction", diff --git a/third_party/move/move-vm/types/src/values/values_impl.rs b/third_party/move/move-vm/types/src/values/values_impl.rs index 3c94feafdfbf6..cec718f44b029 100644 --- a/third_party/move/move-vm/types/src/values/values_impl.rs +++ b/third_party/move/move-vm/types/src/values/values_impl.rs @@ -1517,7 +1517,10 @@ impl IntegerValue { return Err(PartialVMError::new(StatusCode::INTERNAL_TYPE_ERROR).with_message(msg)); }, }; - res.ok_or_else(|| PartialVMError::new(StatusCode::ARITHMETIC_ERROR)) + res.ok_or_else(|| { + PartialVMError::new(StatusCode::ARITHMETIC_ERROR) + .with_message("Division by zero error".to_string()) + }) } pub fn rem_checked(self, other: Self) -> PartialVMResult {