Open JerryKwan opened 2 years ago
This isn't really a bug, in that you shouldn't be making an Error
status with OUT_OF_GAS
, it should be an execution failure
@tnowacki Thanks for looking into this. You are right, OUT_OF_GAS should be an VMStatus::ExecutionFailure not VMStatus::Error, but in the current implementation a lot of StatusCode's status_type() will return StatusType::Execution https://github.com/move-language/move/blob/75fb97eee86966d2c8e6be96fe21da969250e36c/language/move-core/types/src/vm_status.rs#L673-L708 https://github.com/move-language/move/blob/75fb97eee86966d2c8e6be96fe21da969250e36c/language/move-core/types/src/vm_status.rs#L122-L137 And regarding the place where VMStatus::Error(StatusCode::OUT_OF_GAS) generated, GasStatus::deduct_gas() will return PartialVMError::new(StatusCode::OUT_OF_GAS), and PartialVMError::finish(self, location: Location) -> VMError, and VMError::into_vm_status will return VMStatus::Error(major_status) other than VMStatus::ExecutionFailure if location is Location::Undefined. But most of the time VMRuntime::execute_function_impl() use Location::Undefined https://github.com/move-language/move/blob/75fb97eee86966d2c8e6be96fe21da969250e36c/language/move-vm/types/src/gas_schedule.rs#L82-L97 https://github.com/move-language/move/blob/75fb97eee86966d2c8e6be96fe21da969250e36c/language/move-binary-format/src/errors.rs#L55-L123 https://github.com/move-language/move/blob/750903126278ae325461b8c5c9d24f1c708965f5/language/move-vm/runtime/src/runtime.rs#L312-L377
a lot of StatusCode's status_type() will return StatusType::Execution
Thats why there is an assert to make sure they aren't marked as errors in the wrong category
And regarding the place where VMStatus::Error(StatusCode::OUT_OF_GAS) generated, GasStatus::deduct_gas() will return PartialVMError::new(StatusCode::OUT_OF_GAS), and PartialVMError::finish(self, location: Location) -> VMError, and VMError::into_vm_status will return VMStatus::Error(major_status) other than VMStatus::ExecutionFailure if location is Location::Undefined. But most of the time VMRuntime::execute_function_impl() use Location::Undefined
Yeah I remember someone looking at this long ago. I would be okay with OUT_OF_GAS being special cased here. As it can happen at a specific point, but might not (if gas is being charged by the adapter or someone else outside of execution)
@tnowacki Sometimes It's hard to distinguish VMStatus::ExecutionFailure and VMStatus::Execution. Especially when using PartialVMError::finish(self, location: Location) -> VMError, because it's not available to get the location all the time. BTW, Is there any way to get the location where error happens? such as from a Session object like session.runtime.loader.xx?
I'm not sure I fully understand the question. The location for the error is setting is all rather manual at each site, but is informed by contextual information
@tnowacki Regarding this issue, it's better if we can remove or change the debug_assert logic And if there is an easy way to get the location of the error from the context, then it will be much easier to fix the panic such as VMStatus::Error{ StatusCode::OUT_OF_GAS }, that is to say we can set the location of error other than Location::Undefined in the logic like the following https://github.com/starcoinorg/starcoin/blob/9d7fad31575f20ae3ed0aa60b686663c7afef31c/vm/vm-runtime/src/starcoin_vm.rs#L1233-L1253
@tnowacki In the current implementation of Move, the error result of cost_strategy .deduct_gas , that's to say PartialVMError { major_status: OUT_OF_GAS, sub_status: None, message: None, indices: [], offsets: [] } will never be converted to VMStatus::ExecutionFailure , it will be always VMStatus::Error, as you can see from the following code snippets https://github.com/move-language/move/blob/8958b40e97a4f94a588e5365fdb90ec18f00d888/language/move-binary-format/src/errors.rs#L86-L122
Gotcha, I'd be okay with saying then that its an execution error... or an out of gas error :)
@tnowacki Any suggestions about how to correct the existing logic? We can remove or correct the assert_debug in https://github.com/move-language/move/blob/75fb97eee86966d2c8e6be96fe21da969250e36c/language/move-core/types/src/vm_status.rs#L133 or we can remove/correct the return statement in https://github.com/move-language/move/blob/8958b40e97a4f94a588e5365fdb90ec18f00d888/language/move-binary-format/src/errors.rs#L104 and https://github.com/move-language/move/blob/8958b40e97a4f94a588e5365fdb90ec18f00d888/language/move-binary-format/src/errors.rs#L109 Or we can add explicit StatusType named OutOfGas?
@tnowacki Any suggestions about how we can handle this? thank you
Sorry yeah to be clear what I had meant. I'd be okay with with this debug_assert!(code.status_type() != StatusType::Execution || code == StatusCode::OUT_OF_GAS);
This would be consistent with the check in keep_or_discard
@tnowacki Thanks for looking into this. That sounds reasonable.
🐛 Bug
panic occurred when invoking status_type() in debug mode if status is VMStatus::Error{StatusCode::OUT_OF_GAS} The backtrace is something like the following
To reproduce
Code snippet to reproduce
Stack trace/error message
Expected Behavior
status_code return the status code normally, no panic occurred
System information
Please complete the following information:
Additional context
Add any other context about the problem here.