Skip to content

Commit

Permalink
use VMError instead of String in FunctionCall error
Browse files Browse the repository at this point in the history
  • Loading branch information
lexfrl committed Dec 12, 2019
1 parent 5007890 commit 775c141
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 45 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions core/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ actix = "0.8.1"
borsh = "0.2.10"

near-crypto = { path = "../crypto" }
near-vm-errors = { path = "../../runtime/near-vm-errors" }

[features]
default = ["jemallocator"]
Expand Down
6 changes: 4 additions & 2 deletions core/primitives/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::types::{AccountId, Balance, Nonce};
use borsh::{BorshDeserialize, BorshSerialize};
use near_crypto::PublicKey;
// TODO: looks like in this crate we're trying to avoid inner deps, but I can't find a better solution so far
use near_vm_errors::VMError;
use std::fmt::Display;

/// Internal
Expand Down Expand Up @@ -64,7 +66,7 @@ pub enum ActionError {
RentUnpaid(AccountId, Balance),
TriesToUnstake(AccountId),
TriesToStake(AccountId, Balance, Balance, Balance),
FunctionCallError(String), // TODO type
FunctionCallError(VMError),
}

impl Display for InvalidTxError {
Expand Down Expand Up @@ -316,7 +318,7 @@ impl Display for ActionError {
"Account {:?} can't be deleted. It has {}, which is enough to cover the rent",
account_id, balance
),
ActionError::FunctionCallError(s) => write!(f, "{}", s),
ActionError::FunctionCallError(s) => write!(f, "FunctionCall action error: {}", s),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions runtime/near-vm-errors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ Error that can occur inside Near Runtime encapsulated in a separate crate. Might
"""

[dependencies]
borsh = "0.2.10"
41 changes: 21 additions & 20 deletions runtime/near-vm-errors/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
use borsh::{BorshDeserialize, BorshSerialize};
use std::fmt;

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize)]
pub enum VMError {
FunctionCallError(FunctionCallError),
FunctionExecError(FunctionExecError),
StorageError(Vec<u8>),
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FunctionCallError {
#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize)]
pub enum FunctionExecError {
CompilationError(CompilationError),
LinkError(String),
ResolveError(MethodResolveError),
WasmTrap(String),
HostError(HostError),
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize)]
pub enum MethodResolveError {
MethodEmptyName,
MethodUTF8Error,
MethodNotFound,
MethodInvalidSignature,
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize)]
pub enum CompilationError {
CodeDoesNotExist(String),
PrepareError(PrepareError),
WasmerCompileError(String),
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize)]
/// Error that can occur while preparing or executing Wasm smart-contract.
pub enum PrepareError {
/// Error happened while serializing the module.
Expand Down Expand Up @@ -62,7 +63,7 @@ pub enum PrepareError {
Memory,
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize)]
pub enum HostError {
BadUTF16,
BadUTF8,
Expand All @@ -87,7 +88,7 @@ pub enum HostError {
ProhibitedInView(String),
}

#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, BorshDeserialize, BorshSerialize)]
pub enum HostErrorOrStorageError {
HostError(HostError),
/// Error from underlying storage, serialized
Expand All @@ -102,7 +103,7 @@ impl From<HostError> for HostErrorOrStorageError {

impl From<PrepareError> for VMError {
fn from(err: PrepareError) -> Self {
VMError::FunctionCallError(FunctionCallError::CompilationError(
VMError::FunctionExecError(FunctionExecError::CompilationError(
CompilationError::PrepareError(err),
))
}
Expand All @@ -125,14 +126,14 @@ impl fmt::Display for PrepareError {
}
}

impl fmt::Display for FunctionCallError {
impl fmt::Display for FunctionExecError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
FunctionCallError::CompilationError(e) => e.fmt(f),
FunctionCallError::ResolveError(e) => e.fmt(f),
FunctionCallError::HostError(e) => e.fmt(f),
FunctionCallError::LinkError(s) => write!(f, "{}", s),
FunctionCallError::WasmTrap(s) => write!(f, "WebAssembly trap: {}", s),
FunctionExecError::CompilationError(e) => e.fmt(f),
FunctionExecError::ResolveError(e) => e.fmt(f),
FunctionExecError::HostError(e) => e.fmt(f),
FunctionExecError::LinkError(s) => write!(f, "{}", s),
FunctionExecError::WasmTrap(s) => write!(f, "WebAssembly trap: {}", s),
}
}
}
Expand All @@ -158,7 +159,7 @@ impl fmt::Display for MethodResolveError {
impl fmt::Display for VMError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
VMError::FunctionCallError(err) => fmt::Display::fmt(err, f),
VMError::FunctionExecError(err) => fmt::Display::fmt(err, f),
VMError::StorageError(_err) => write!(f, "StorageError"),
}
}
Expand Down Expand Up @@ -195,20 +196,20 @@ impl std::fmt::Display for HostError {

#[cfg(test)]
mod tests {
use crate::{CompilationError, FunctionCallError, MethodResolveError, PrepareError, VMError};
use crate::{CompilationError, FunctionExecError, MethodResolveError, PrepareError, VMError};

#[test]
fn test_display() {
// TODO: proper printing
assert_eq!(
VMError::FunctionCallError(FunctionCallError::ResolveError(
VMError::FunctionExecError(FunctionExecError::ResolveError(
MethodResolveError::MethodInvalidSignature
))
.to_string(),
"MethodInvalidSignature"
);
assert_eq!(
VMError::FunctionCallError(FunctionCallError::CompilationError(
VMError::FunctionExecError(FunctionExecError::CompilationError(
CompilationError::PrepareError(PrepareError::StackHeightInstrumentation)
))
.to_string(),
Expand Down
24 changes: 12 additions & 12 deletions runtime/near-vm-runner/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use near_vm_errors::{CompilationError, FunctionCallError, MethodResolveError, VMError};
use near_vm_errors::{CompilationError, FunctionExecError, MethodResolveError, VMError};
use near_vm_logic::HostErrorOrStorageError;

pub trait IntoVMError {
Expand All @@ -10,7 +10,7 @@ impl IntoVMError for wasmer_runtime::error::Error {
use wasmer_runtime::error::Error;
match self {
Error::CompileError(err) => err.into_vm_error(),
Error::LinkError(err) => VMError::FunctionCallError(FunctionCallError::LinkError(
Error::LinkError(err) => VMError::FunctionExecError(FunctionExecError::LinkError(
format!("{:.500}", Error::LinkError(err).to_string()),
)),
Error::RuntimeError(err) => err.into_vm_error(),
Expand All @@ -33,7 +33,7 @@ impl IntoVMError for wasmer_runtime::error::CallError {

impl IntoVMError for wasmer_runtime::error::CompileError {
fn into_vm_error(self) -> VMError {
VMError::FunctionCallError(FunctionCallError::CompilationError(
VMError::FunctionExecError(FunctionExecError::CompilationError(
CompilationError::WasmerCompileError(self.to_string()),
))
}
Expand All @@ -43,14 +43,14 @@ impl IntoVMError for wasmer_runtime::error::ResolveError {
fn into_vm_error(self) -> VMError {
use wasmer_runtime::error::ResolveError as WasmerResolveError;
match self {
WasmerResolveError::Signature { .. } => VMError::FunctionCallError(
FunctionCallError::ResolveError(MethodResolveError::MethodInvalidSignature),
WasmerResolveError::Signature { .. } => VMError::FunctionExecError(
FunctionExecError::ResolveError(MethodResolveError::MethodInvalidSignature),
),
WasmerResolveError::ExportNotFound { .. } => VMError::FunctionCallError(
FunctionCallError::ResolveError(MethodResolveError::MethodNotFound),
WasmerResolveError::ExportNotFound { .. } => VMError::FunctionExecError(
FunctionExecError::ResolveError(MethodResolveError::MethodNotFound),
),
WasmerResolveError::ExportWrongType { .. } => VMError::FunctionCallError(
FunctionCallError::ResolveError(MethodResolveError::MethodNotFound),
WasmerResolveError::ExportWrongType { .. } => VMError::FunctionExecError(
FunctionExecError::ResolveError(MethodResolveError::MethodNotFound),
),
}
}
Expand All @@ -61,7 +61,7 @@ impl IntoVMError for wasmer_runtime::error::RuntimeError {
use wasmer_runtime::error::RuntimeError;
match &self {
RuntimeError::Trap { msg } => {
VMError::FunctionCallError(FunctionCallError::WasmTrap(msg.to_string()))
VMError::FunctionExecError(FunctionExecError::WasmTrap(msg.to_string()))
}
RuntimeError::Error { data } => {
if let Some(err) = data.downcast_ref::<HostErrorOrStorageError>() {
Expand All @@ -70,7 +70,7 @@ impl IntoVMError for wasmer_runtime::error::RuntimeError {
VMError::StorageError(s.clone())
}
HostErrorOrStorageError::HostError(h) => {
VMError::FunctionCallError(FunctionCallError::HostError(h.clone()))
VMError::FunctionExecError(FunctionExecError::HostError(h.clone()))
}
}
} else {
Expand All @@ -79,7 +79,7 @@ impl IntoVMError for wasmer_runtime::error::RuntimeError {
data.type_id(),
self.to_string()
);
VMError::FunctionCallError(FunctionCallError::WasmTrap("unknown".to_string()))
VMError::FunctionExecError(FunctionExecError::WasmTrap("unknown".to_string()))
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions runtime/near-vm-runner/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::errors::IntoVMError;
use crate::memory::WasmerMemory;
use crate::{cache, imports};
use near_runtime_fees::RuntimeFeesConfig;
use near_vm_errors::{FunctionCallError, MethodResolveError, VMError};
use near_vm_errors::{FunctionExecError, MethodResolveError, VMError};
use near_vm_logic::types::PromiseResult;
use near_vm_logic::{External, VMConfig, VMContext, VMLogic, VMOutcome};
use wasmer_runtime::Module;
Expand All @@ -16,12 +16,12 @@ fn check_method(module: &Module, method_name: &str) -> Result<(), VMError> {
if sig.params().is_empty() && sig.returns().is_empty() {
Ok(())
} else {
Err(VMError::FunctionCallError(FunctionCallError::ResolveError(
Err(VMError::FunctionExecError(FunctionExecError::ResolveError(
MethodResolveError::MethodInvalidSignature,
)))
}
} else {
Err(VMError::FunctionCallError(FunctionCallError::ResolveError(
Err(VMError::FunctionExecError(FunctionExecError::ResolveError(
MethodResolveError::MethodNotFound,
)))
}
Expand Down Expand Up @@ -51,7 +51,7 @@ pub fn run<'a>(
if method_name.is_empty() {
return (
None,
Some(VMError::FunctionCallError(FunctionCallError::ResolveError(
Some(VMError::FunctionExecError(FunctionExecError::ResolveError(
MethodResolveError::MethodEmptyName,
))),
);
Expand All @@ -77,7 +77,7 @@ pub fn run<'a>(
Err(_) => {
return (
None,
Some(VMError::FunctionCallError(FunctionCallError::ResolveError(
Some(VMError::FunctionExecError(FunctionExecError::ResolveError(
MethodResolveError::MethodUTF8Error,
))),
)
Expand Down
11 changes: 5 additions & 6 deletions runtime/runtime/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::config::RuntimeConfig;
use crate::ext::RuntimeExt;
use crate::{ActionResult, ApplyState};
use near_primitives::errors::ActionError;
use near_vm_errors::{CompilationError, FunctionCallError};
use near_vm_errors::{CompilationError, FunctionExecError};
use near_vm_runner::VMError;

/// Number of epochs it takes to unstake.
Expand Down Expand Up @@ -119,10 +119,10 @@ pub(crate) fn action_function_call(
let code = match get_code_with_cache(state_update, account_id, &account) {
Ok(Some(code)) => code,
Ok(None) => {
let error = FunctionCallError::CompilationError(CompilationError::CodeDoesNotExist(
account_id.clone(),
let error = VMError::FunctionExecError(FunctionExecError::CompilationError(
CompilationError::CodeDoesNotExist(account_id.clone()),
));
result.result = Err(ActionError::FunctionCallError(error.to_string()));
result.result = Err(ActionError::FunctionCallError(error));
return Ok(());
}
Err(e) => {
Expand Down Expand Up @@ -179,8 +179,7 @@ pub(crate) fn action_function_call(
borsh::BorshDeserialize::try_from_slice(&storage).expect("Borsh cannot fail");
return Err(err);
}
// TODO(#1731): Handle VMError::FunctionCallError better.
result.result = Err(ActionError::FunctionCallError(err.to_string()));
result.result = Err(ActionError::FunctionCallError(err));
if let Some(outcome) = outcome {
result.gas_burnt += outcome.burnt_gas;
result.gas_burnt_for_function_call += outcome.burnt_gas;
Expand Down

0 comments on commit 775c141

Please sign in to comment.