diff --git a/Cargo.lock b/Cargo.lock index ff92cbade30..c212b8e5a95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4361,11 +4361,9 @@ dependencies = [ "hex", "loupe", "memoffset 0.8.0", - "near-account-id", "near-crypto", "near-primitives", "near-primitives-core", - "near-rpc-error-macro", "near-stdx", "near-test-contracts", "near-vm-compiler", diff --git a/chain/jsonrpc/res/rpc_errors_schema.json b/chain/jsonrpc/res/rpc_errors_schema.json index 5bd88fcd74b..1279c61751e 100644 --- a/chain/jsonrpc/res/rpc_errors_schema.json +++ b/chain/jsonrpc/res/rpc_errors_schema.json @@ -1,425 +1,5 @@ { "schema": { - "AltBn128InvalidInput": { - "name": "AltBn128InvalidInput", - "subtypes": [], - "props": { - "msg": "" - } - }, - "BadUTF16": { - "name": "BadUTF16", - "subtypes": [], - "props": {} - }, - "BadUTF8": { - "name": "BadUTF8", - "subtypes": [], - "props": {} - }, - "BalanceExceeded": { - "name": "BalanceExceeded", - "subtypes": [], - "props": {} - }, - "CallIndirectOOB": { - "name": "CallIndirectOOB", - "subtypes": [], - "props": {} - }, - "CannotAppendActionToJointPromise": { - "name": "CannotAppendActionToJointPromise", - "subtypes": [], - "props": {} - }, - "CannotReturnJointPromise": { - "name": "CannotReturnJointPromise", - "subtypes": [], - "props": {} - }, - "CodeDoesNotExist": { - "name": "CodeDoesNotExist", - "subtypes": [], - "props": { - "account_id": "" - } - }, - "CompilationError": { - "name": "CompilationError", - "subtypes": [ - "CodeDoesNotExist", - "PrepareError", - "WasmerCompileError" - ], - "props": {} - }, - "ContractSizeExceeded": { - "name": "ContractSizeExceeded", - "subtypes": [], - "props": { - "limit": "", - "size": "" - } - }, - "Deprecated": { - "name": "Deprecated", - "subtypes": [], - "props": { - "method_name": "" - } - }, - "Deserialization": { - "name": "Deserialization", - "subtypes": [], - "props": {} - }, - "ECRecoverError": { - "name": "ECRecoverError", - "subtypes": [], - "props": { - "msg": "" - } - }, - "Ed25519VerifyInvalidInput": { - "name": "Ed25519VerifyInvalidInput", - "subtypes": [], - "props": { - "msg": "" - } - }, - "EmptyMethodName": { - "name": "EmptyMethodName", - "subtypes": [], - "props": {} - }, - "GasExceeded": { - "name": "GasExceeded", - "subtypes": [], - "props": {} - }, - "GasInstrumentation": { - "name": "GasInstrumentation", - "subtypes": [], - "props": {} - }, - "GasLimitExceeded": { - "name": "GasLimitExceeded", - "subtypes": [], - "props": {} - }, - "GenericTrap": { - "name": "GenericTrap", - "subtypes": [], - "props": {} - }, - "GuestPanic": { - "name": "GuestPanic", - "subtypes": [], - "props": { - "panic_msg": "" - } - }, - "HostError": { - "name": "HostError", - "subtypes": [ - "BadUTF16", - "BadUTF8", - "GasExceeded", - "GasLimitExceeded", - "BalanceExceeded", - "EmptyMethodName", - "GuestPanic", - "IntegerOverflow", - "InvalidPromiseIndex", - "CannotAppendActionToJointPromise", - "CannotReturnJointPromise", - "InvalidPromiseResultIndex", - "InvalidRegisterId", - "IteratorWasInvalidated", - "MemoryAccessViolation", - "InvalidReceiptIndex", - "InvalidIteratorIndex", - "InvalidAccountId", - "InvalidMethodName", - "InvalidPublicKey", - "ProhibitedInView", - "NumberOfLogsExceeded", - "KeyLengthExceeded", - "ValueLengthExceeded", - "TotalLogLengthExceeded", - "NumberPromisesExceeded", - "NumberInputDataDependenciesExceeded", - "ReturnedValueLengthExceeded", - "ContractSizeExceeded", - "Deprecated", - "ECRecoverError", - "AltBn128InvalidInput", - "Ed25519VerifyInvalidInput" - ], - "props": {} - }, - "IllegalArithmetic": { - "name": "IllegalArithmetic", - "subtypes": [], - "props": {} - }, - "IncorrectCallIndirectSignature": { - "name": "IncorrectCallIndirectSignature", - "subtypes": [], - "props": {} - }, - "IndirectCallToNull": { - "name": "IndirectCallToNull", - "subtypes": [], - "props": {} - }, - "Instantiate": { - "name": "Instantiate", - "subtypes": [], - "props": {} - }, - "IntegerOverflow": { - "name": "IntegerOverflow", - "subtypes": [], - "props": {} - }, - "InternalMemoryDeclared": { - "name": "InternalMemoryDeclared", - "subtypes": [], - "props": {} - }, - "InvalidAccountId": { - "name": "InvalidAccountId", - "subtypes": [], - "props": { - "account_id": "" - } - }, - "InvalidIteratorIndex": { - "name": "InvalidIteratorIndex", - "subtypes": [], - "props": { - "iterator_index": "" - } - }, - "InvalidMethodName": { - "name": "InvalidMethodName", - "subtypes": [], - "props": {} - }, - "InvalidPromiseIndex": { - "name": "InvalidPromiseIndex", - "subtypes": [], - "props": { - "promise_idx": "" - } - }, - "InvalidPromiseResultIndex": { - "name": "InvalidPromiseResultIndex", - "subtypes": [], - "props": { - "result_idx": "" - } - }, - "InvalidPublicKey": { - "name": "InvalidPublicKey", - "subtypes": [], - "props": {} - }, - "InvalidReceiptIndex": { - "name": "InvalidReceiptIndex", - "subtypes": [], - "props": { - "receipt_index": "" - } - }, - "InvalidRegisterId": { - "name": "InvalidRegisterId", - "subtypes": [], - "props": { - "register_id": "" - } - }, - "IteratorWasInvalidated": { - "name": "IteratorWasInvalidated", - "subtypes": [], - "props": { - "iterator_index": "" - } - }, - "KeyLengthExceeded": { - "name": "KeyLengthExceeded", - "subtypes": [], - "props": { - "length": "", - "limit": "" - } - }, - "Memory": { - "name": "Memory", - "subtypes": [], - "props": {} - }, - "MemoryAccessViolation": { - "name": "MemoryAccessViolation", - "subtypes": [], - "props": {} - }, - "MemoryOutOfBounds": { - "name": "MemoryOutOfBounds", - "subtypes": [], - "props": {} - }, - "MethodEmptyName": { - "name": "MethodEmptyName", - "subtypes": [], - "props": {} - }, - "MethodInvalidSignature": { - "name": "MethodInvalidSignature", - "subtypes": [], - "props": {} - }, - "MethodNotFound": { - "name": "MethodNotFound", - "subtypes": [], - "props": {} - }, - "MethodResolveError": { - "name": "MethodResolveError", - "subtypes": [ - "MethodEmptyName", - "MethodNotFound", - "MethodInvalidSignature" - ], - "props": {} - }, - "MisalignedAtomicAccess": { - "name": "MisalignedAtomicAccess", - "subtypes": [], - "props": {} - }, - "NumberInputDataDependenciesExceeded": { - "name": "NumberInputDataDependenciesExceeded", - "subtypes": [], - "props": { - "limit": "", - "number_of_input_data_dependencies": "" - } - }, - "NumberOfLogsExceeded": { - "name": "NumberOfLogsExceeded", - "subtypes": [], - "props": { - "limit": "" - } - }, - "NumberPromisesExceeded": { - "name": "NumberPromisesExceeded", - "subtypes": [], - "props": { - "limit": "", - "number_of_promises": "" - } - }, - "PrepareError": { - "name": "PrepareError", - "subtypes": [ - "Serialization", - "Deserialization", - "InternalMemoryDeclared", - "GasInstrumentation", - "StackHeightInstrumentation", - "Instantiate", - "Memory", - "TooManyFunctions", - "TooManyLocals" - ], - "props": {} - }, - "ProhibitedInView": { - "name": "ProhibitedInView", - "subtypes": [], - "props": { - "method_name": "" - } - }, - "ReturnedValueLengthExceeded": { - "name": "ReturnedValueLengthExceeded", - "subtypes": [], - "props": { - "length": "", - "limit": "" - } - }, - "Serialization": { - "name": "Serialization", - "subtypes": [], - "props": {} - }, - "StackHeightInstrumentation": { - "name": "StackHeightInstrumentation", - "subtypes": [], - "props": {} - }, - "StackOverflow": { - "name": "StackOverflow", - "subtypes": [], - "props": {} - }, - "TooManyFunctions": { - "name": "TooManyFunctions", - "subtypes": [], - "props": {} - }, - "TooManyLocals": { - "name": "TooManyLocals", - "subtypes": [], - "props": {} - }, - "TotalLogLengthExceeded": { - "name": "TotalLogLengthExceeded", - "subtypes": [], - "props": { - "length": "", - "limit": "" - } - }, - "Unreachable": { - "name": "Unreachable", - "subtypes": [], - "props": {} - }, - "ValueLengthExceeded": { - "name": "ValueLengthExceeded", - "subtypes": [], - "props": { - "length": "", - "limit": "" - } - }, - "WasmTrap": { - "name": "WasmTrap", - "subtypes": [ - "Unreachable", - "IncorrectCallIndirectSignature", - "MemoryOutOfBounds", - "CallIndirectOOB", - "IllegalArithmetic", - "MisalignedAtomicAccess", - "IndirectCallToNull", - "StackOverflow", - "GenericTrap" - ], - "props": {} - }, - "WasmerCompileError": { - "name": "WasmerCompileError", - "subtypes": [], - "props": { - "msg": "" - } - }, "AccessKeyNotFound": { "name": "AccessKeyNotFound", "subtypes": [], @@ -524,6 +104,28 @@ "total_number_of_bytes": "" } }, + "AltBn128InvalidInput": { + "name": "AltBn128InvalidInput", + "subtypes": [], + "props": { + "msg": "" + } + }, + "BadUTF16": { + "name": "BadUTF16", + "subtypes": [], + "props": {} + }, + "BadUTF8": { + "name": "BadUTF8", + "subtypes": [], + "props": {} + }, + "BalanceExceeded": { + "name": "BalanceExceeded", + "subtypes": [], + "props": {} + }, "BalanceMismatchError": { "name": "BalanceMismatchError", "subtypes": [], @@ -542,6 +144,45 @@ "tx_burnt_amount": "" } }, + "CallIndirectOOB": { + "name": "CallIndirectOOB", + "subtypes": [], + "props": {} + }, + "CannotAppendActionToJointPromise": { + "name": "CannotAppendActionToJointPromise", + "subtypes": [], + "props": {} + }, + "CannotReturnJointPromise": { + "name": "CannotReturnJointPromise", + "subtypes": [], + "props": {} + }, + "CodeDoesNotExist": { + "name": "CodeDoesNotExist", + "subtypes": [], + "props": { + "account_id": "" + } + }, + "CompilationError": { + "name": "CompilationError", + "subtypes": [ + "CodeDoesNotExist", + "PrepareError", + "WasmerCompileError" + ], + "props": {} + }, + "ContractSizeExceeded": { + "name": "ContractSizeExceeded", + "subtypes": [], + "props": { + "limit": "", + "size": "" + } + }, "CostOverflow": { "name": "CostOverflow", "subtypes": [], @@ -635,6 +276,37 @@ "subtypes": [], "props": {} }, + "Deprecated": { + "name": "Deprecated", + "subtypes": [], + "props": { + "method_name": "" + } + }, + "Deserialization": { + "name": "Deserialization", + "subtypes": [], + "props": {} + }, + "ECRecoverError": { + "name": "ECRecoverError", + "subtypes": [], + "props": { + "msg": "" + } + }, + "Ed25519VerifyInvalidInput": { + "name": "Ed25519VerifyInvalidInput", + "subtypes": [], + "props": { + "msg": "" + } + }, + "EmptyMethodName": { + "name": "EmptyMethodName", + "subtypes": [], + "props": {} + }, "Expired": { "name": "Expired", "subtypes": [], @@ -648,16 +320,102 @@ "limit": "" } }, - "FunctionCallMethodNameLengthExceeded": { - "name": "FunctionCallMethodNameLengthExceeded", + "FunctionCallMethodNameLengthExceeded": { + "name": "FunctionCallMethodNameLengthExceeded", + "subtypes": [], + "props": { + "length": "", + "limit": "" + } + }, + "FunctionCallZeroAttachedGas": { + "name": "FunctionCallZeroAttachedGas", + "subtypes": [], + "props": {} + }, + "GasExceeded": { + "name": "GasExceeded", + "subtypes": [], + "props": {} + }, + "GasInstrumentation": { + "name": "GasInstrumentation", + "subtypes": [], + "props": {} + }, + "GasLimitExceeded": { + "name": "GasLimitExceeded", + "subtypes": [], + "props": {} + }, + "GenericTrap": { + "name": "GenericTrap", + "subtypes": [], + "props": {} + }, + "GuestPanic": { + "name": "GuestPanic", + "subtypes": [], + "props": { + "panic_msg": "" + } + }, + "HostError": { + "name": "HostError", + "subtypes": [ + "BadUTF16", + "BadUTF8", + "GasExceeded", + "GasLimitExceeded", + "BalanceExceeded", + "EmptyMethodName", + "GuestPanic", + "IntegerOverflow", + "InvalidPromiseIndex", + "CannotAppendActionToJointPromise", + "CannotReturnJointPromise", + "InvalidPromiseResultIndex", + "InvalidRegisterId", + "IteratorWasInvalidated", + "MemoryAccessViolation", + "InvalidReceiptIndex", + "InvalidIteratorIndex", + "InvalidAccountId", + "InvalidMethodName", + "InvalidPublicKey", + "ProhibitedInView", + "NumberOfLogsExceeded", + "KeyLengthExceeded", + "ValueLengthExceeded", + "TotalLogLengthExceeded", + "NumberPromisesExceeded", + "NumberInputDataDependenciesExceeded", + "ReturnedValueLengthExceeded", + "ContractSizeExceeded", + "Deprecated", + "ECRecoverError", + "AltBn128InvalidInput", + "Ed25519VerifyInvalidInput" + ], + "props": {} + }, + "IllegalArithmetic": { + "name": "IllegalArithmetic", + "subtypes": [], + "props": {} + }, + "IncorrectCallIndirectSignature": { + "name": "IncorrectCallIndirectSignature", + "subtypes": [], + "props": {} + }, + "IndirectCallToNull": { + "name": "IndirectCallToNull", "subtypes": [], - "props": { - "length": "", - "limit": "" - } + "props": {} }, - "FunctionCallZeroAttachedGas": { - "name": "FunctionCallZeroAttachedGas", + "Instantiate": { + "name": "Instantiate", "subtypes": [], "props": {} }, @@ -670,6 +428,16 @@ "stake": "" } }, + "IntegerOverflow": { + "name": "IntegerOverflow", + "subtypes": [], + "props": {} + }, + "InternalMemoryDeclared": { + "name": "InternalMemoryDeclared", + "subtypes": [], + "props": {} + }, "InvalidAccessKeyError": { "name": "InvalidAccessKeyError", "subtypes": [ @@ -682,6 +450,11 @@ ], "props": {} }, + "InvalidAccountId": { + "name": "InvalidAccountId", + "subtypes": [], + "props": {} + }, "InvalidChain": { "name": "InvalidChain", "subtypes": [], @@ -694,6 +467,18 @@ "account_id": "" } }, + "InvalidIteratorIndex": { + "name": "InvalidIteratorIndex", + "subtypes": [], + "props": { + "iterator_index": "" + } + }, + "InvalidMethodName": { + "name": "InvalidMethodName", + "subtypes": [], + "props": {} + }, "InvalidNonce": { "name": "InvalidNonce", "subtypes": [], @@ -709,6 +494,32 @@ "account_id": "" } }, + "InvalidPromiseIndex": { + "name": "InvalidPromiseIndex", + "subtypes": [], + "props": { + "promise_idx": "" + } + }, + "InvalidPromiseResultIndex": { + "name": "InvalidPromiseResultIndex", + "subtypes": [], + "props": { + "result_idx": "" + } + }, + "InvalidPublicKey": { + "name": "InvalidPublicKey", + "subtypes": [], + "props": {} + }, + "InvalidReceiptIndex": { + "name": "InvalidReceiptIndex", + "subtypes": [], + "props": { + "receipt_index": "" + } + }, "InvalidReceiverId": { "name": "InvalidReceiverId", "subtypes": [], @@ -716,6 +527,13 @@ "account_id": "" } }, + "InvalidRegisterId": { + "name": "InvalidRegisterId", + "subtypes": [], + "props": { + "register_id": "" + } + }, "InvalidSignature": { "name": "InvalidSignature", "subtypes": [], @@ -748,6 +566,21 @@ ], "props": {} }, + "IteratorWasInvalidated": { + "name": "IteratorWasInvalidated", + "subtypes": [], + "props": { + "iterator_index": "" + } + }, + "KeyLengthExceeded": { + "name": "KeyLengthExceeded", + "subtypes": [], + "props": { + "length": "", + "limit": "" + } + }, "LackBalanceForState": { "name": "LackBalanceForState", "subtypes": [], @@ -756,6 +589,31 @@ "amount": "" } }, + "Memory": { + "name": "Memory", + "subtypes": [], + "props": {} + }, + "MemoryAccessViolation": { + "name": "MemoryAccessViolation", + "subtypes": [], + "props": {} + }, + "MemoryOutOfBounds": { + "name": "MemoryOutOfBounds", + "subtypes": [], + "props": {} + }, + "MethodEmptyName": { + "name": "MethodEmptyName", + "subtypes": [], + "props": {} + }, + "MethodInvalidSignature": { + "name": "MethodInvalidSignature", + "subtypes": [], + "props": {} + }, "MethodNameMismatch": { "name": "MethodNameMismatch", "subtypes": [], @@ -763,6 +621,25 @@ "method_name": "" } }, + "MethodNotFound": { + "name": "MethodNotFound", + "subtypes": [], + "props": {} + }, + "MethodResolveError": { + "name": "MethodResolveError", + "subtypes": [ + "MethodEmptyName", + "MethodNotFound", + "MethodInvalidSignature" + ], + "props": {} + }, + "MisalignedAtomicAccess": { + "name": "MisalignedAtomicAccess", + "subtypes": [], + "props": {} + }, "NonceTooLarge": { "name": "NonceTooLarge", "subtypes": [], @@ -790,6 +667,29 @@ "signer_id": "" } }, + "NumberInputDataDependenciesExceeded": { + "name": "NumberInputDataDependenciesExceeded", + "subtypes": [], + "props": { + "limit": "", + "number_of_input_data_dependencies": "" + } + }, + "NumberOfLogsExceeded": { + "name": "NumberOfLogsExceeded", + "subtypes": [], + "props": { + "limit": "" + } + }, + "NumberPromisesExceeded": { + "name": "NumberPromisesExceeded", + "subtypes": [], + "props": { + "limit": "", + "number_of_promises": "" + } + }, "OnlyImplicitAccountCreationAllowed": { "name": "OnlyImplicitAccountCreationAllowed", "subtypes": [], @@ -797,6 +697,28 @@ "account_id": "" } }, + "PrepareError": { + "name": "PrepareError", + "subtypes": [ + "Serialization", + "Deserialization", + "InternalMemoryDeclared", + "GasInstrumentation", + "StackHeightInstrumentation", + "Instantiate", + "Memory", + "TooManyFunctions", + "TooManyLocals" + ], + "props": {} + }, + "ProhibitedInView": { + "name": "ProhibitedInView", + "subtypes": [], + "props": { + "method_name": "" + } + }, "ReceiptValidationError": { "name": "ReceiptValidationError", "subtypes": [ @@ -823,6 +745,19 @@ "subtypes": [], "props": {} }, + "ReturnedValueLengthExceeded": { + "name": "ReturnedValueLengthExceeded", + "subtypes": [], + "props": { + "length": "", + "limit": "" + } + }, + "Serialization": { + "name": "Serialization", + "subtypes": [], + "props": {} + }, "SignerDoesNotExist": { "name": "SignerDoesNotExist", "subtypes": [], @@ -830,6 +765,34 @@ "signer_id": "" } }, + "StackHeightInstrumentation": { + "name": "StackHeightInstrumentation", + "subtypes": [], + "props": {} + }, + "StackOverflow": { + "name": "StackOverflow", + "subtypes": [], + "props": {} + }, + "TooManyFunctions": { + "name": "TooManyFunctions", + "subtypes": [], + "props": {} + }, + "TooManyLocals": { + "name": "TooManyLocals", + "subtypes": [], + "props": {} + }, + "TotalLogLengthExceeded": { + "name": "TotalLogLengthExceeded", + "subtypes": [], + "props": { + "length": "", + "limit": "" + } + }, "TotalNumberOfActionsExceeded": { "name": "TotalNumberOfActionsExceeded", "subtypes": [], @@ -879,6 +842,11 @@ ], "props": {} }, + "Unreachable": { + "name": "Unreachable", + "subtypes": [], + "props": {} + }, "UnsuitableStakingKey": { "name": "UnsuitableStakingKey", "subtypes": [], @@ -894,6 +862,36 @@ "version": "" } }, + "ValueLengthExceeded": { + "name": "ValueLengthExceeded", + "subtypes": [], + "props": { + "length": "", + "limit": "" + } + }, + "WasmTrap": { + "name": "WasmTrap", + "subtypes": [ + "Unreachable", + "IncorrectCallIndirectSignature", + "MemoryOutOfBounds", + "CallIndirectOOB", + "IllegalArithmetic", + "MisalignedAtomicAccess", + "IndirectCallToNull", + "StackOverflow", + "GenericTrap" + ], + "props": {} + }, + "WasmerCompileError": { + "name": "WasmerCompileError", + "subtypes": [], + "props": { + "msg": "" + } + }, "Closed": { "name": "Closed", "subtypes": [], diff --git a/core/primitives/src/errors.rs b/core/primitives/src/errors.rs index f1678de9336..9ede1561aba 100644 --- a/core/primitives/src/errors.rs +++ b/core/primitives/src/errors.rs @@ -5,7 +5,6 @@ use borsh::{BorshDeserialize, BorshSerialize}; use near_crypto::PublicKey; use near_primitives_core::types::ProtocolVersion; use near_rpc_error_macro::RpcError; -use near_vm_runner::logic::errors::FunctionCallErrorSer; use std::fmt::{Debug, Display}; /// Error returned in the ExecutionOutcome in case of failure @@ -469,7 +468,7 @@ pub enum ActionErrorKind { minimum_stake: Balance, }, /// An error occurred during a `FunctionCall` Action, parameter is debug message. - FunctionCallError(FunctionCallErrorSer), + FunctionCallError(FunctionCallError), /// Error occurs when a new `ActionReceipt` created by the `FunctionCall` action fails /// receipt validation. NewReceiptValidationError(ReceiptValidationError), @@ -897,3 +896,298 @@ impl From for EpochError { EpochError::IOErr(error.to_string()) } } + +#[derive( + Debug, + Clone, + PartialEq, + Eq, + BorshDeserialize, + BorshSerialize, + RpcError, + serde::Deserialize, + serde::Serialize, +)] +/// Error that can occur while preparing or executing Wasm smart-contract. +pub enum PrepareError { + /// Error happened while serializing the module. + Serialization, + /// Error happened while deserializing the module. + Deserialization, + /// Internal memory declaration has been found in the module. + InternalMemoryDeclared, + /// Gas instrumentation failed. + /// + /// This most likely indicates the module isn't valid. + GasInstrumentation, + /// Stack instrumentation failed. + /// + /// This most likely indicates the module isn't valid. + StackHeightInstrumentation, + /// Error happened during instantiation. + /// + /// This might indicate that `start` function trapped, or module isn't + /// instantiable and/or unlinkable. + Instantiate, + /// Error creating memory. + Memory, + /// Contract contains too many functions. + TooManyFunctions, + /// Contract contains too many locals. + TooManyLocals, +} + +/// A kind of a trap happened during execution of a binary +#[derive( + Debug, + Clone, + PartialEq, + Eq, + BorshDeserialize, + BorshSerialize, + RpcError, + serde::Deserialize, + serde::Serialize, + strum::IntoStaticStr, +)] +pub enum WasmTrap { + /// An `unreachable` opcode was executed. + Unreachable, + /// Call indirect incorrect signature trap. + IncorrectCallIndirectSignature, + /// Memory out of bounds trap. + MemoryOutOfBounds, + /// Call indirect out of bounds trap. + CallIndirectOOB, + /// An arithmetic exception, e.g. divided by zero. + IllegalArithmetic, + /// Misaligned atomic access trap. + MisalignedAtomicAccess, + /// Indirect call to null. + IndirectCallToNull, + /// Stack overflow. + StackOverflow, + /// Generic trap. + GenericTrap, +} + +#[derive( + Debug, + Clone, + PartialEq, + Eq, + BorshDeserialize, + BorshSerialize, + RpcError, + serde::Deserialize, + serde::Serialize, + strum::IntoStaticStr, +)] +pub enum HostError { + /// String encoding is bad UTF-16 sequence + BadUTF16, + /// String encoding is bad UTF-8 sequence + BadUTF8, + /// Exceeded the prepaid gas + GasExceeded, + /// Exceeded the maximum amount of gas allowed to burn per contract + GasLimitExceeded, + /// Exceeded the account balance + BalanceExceeded, + /// Tried to call an empty method name + EmptyMethodName, + /// Smart contract panicked + GuestPanic { panic_msg: String }, + /// IntegerOverflow happened during a contract execution + IntegerOverflow, + /// `promise_idx` does not correspond to existing promises + InvalidPromiseIndex { promise_idx: u64 }, + /// Actions can only be appended to non-joint promise. + CannotAppendActionToJointPromise, + /// Returning joint promise is currently prohibited + CannotReturnJointPromise, + /// Accessed invalid promise result index + InvalidPromiseResultIndex { result_idx: u64 }, + /// Accessed invalid register id + InvalidRegisterId { register_id: u64 }, + /// Iterator `iterator_index` was invalidated after its creation by performing a mutable operation on trie + IteratorWasInvalidated { iterator_index: u64 }, + /// Accessed memory outside the bounds + MemoryAccessViolation, + /// VM Logic returned an invalid receipt index + InvalidReceiptIndex { receipt_index: u64 }, + /// Iterator index `iterator_index` does not exist + InvalidIteratorIndex { iterator_index: u64 }, + /// VM Logic returned an invalid account id + InvalidAccountId, + /// VM Logic returned an invalid method name + InvalidMethodName, + /// VM Logic provided an invalid public key + InvalidPublicKey, + /// `method_name` is not allowed in view calls + ProhibitedInView { method_name: String }, + /// The total number of logs will exceed the limit. + NumberOfLogsExceeded { limit: u64 }, + /// The storage key length exceeded the limit. + KeyLengthExceeded { length: u64, limit: u64 }, + /// The storage value length exceeded the limit. + ValueLengthExceeded { length: u64, limit: u64 }, + /// The total log length exceeded the limit. + TotalLogLengthExceeded { length: u64, limit: u64 }, + /// The maximum number of promises within a FunctionCall exceeded the limit. + NumberPromisesExceeded { number_of_promises: u64, limit: u64 }, + /// The maximum number of input data dependencies exceeded the limit. + NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 }, + /// The returned value length exceeded the limit. + ReturnedValueLengthExceeded { length: u64, limit: u64 }, + /// The contract size for DeployContract action exceeded the limit. + ContractSizeExceeded { size: u64, limit: u64 }, + /// The host function was deprecated. + Deprecated { method_name: String }, + /// General errors for ECDSA recover. + ECRecoverError { msg: String }, + /// Invalid input to alt_bn128 familiy of functions (e.g., point which isn't + /// on the curve). + AltBn128InvalidInput { msg: String }, + /// Invalid input to ed25519 signature verification function (e.g. signature cannot be + /// derived from bytes). + Ed25519VerifyInvalidInput { msg: String }, +} + +#[derive( + Debug, + Clone, + PartialEq, + Eq, + BorshDeserialize, + BorshSerialize, + RpcError, + serde::Deserialize, + serde::Serialize, + strum::IntoStaticStr, +)] +pub enum MethodResolveError { + MethodEmptyName, + MethodNotFound, + MethodInvalidSignature, +} + +#[derive( + Debug, + Clone, + PartialEq, + Eq, + BorshDeserialize, + BorshSerialize, + RpcError, + serde::Deserialize, + serde::Serialize, + strum::IntoStaticStr, +)] +pub enum CompilationError { + CodeDoesNotExist { + account_id: AccountId, + }, + PrepareError(PrepareError), + /// This is for defense in depth. + /// We expect our runtime-independent preparation code to fully catch all invalid wasms, + /// but, if it ever misses something we’ll emit this error + WasmerCompileError { + msg: String, + }, +} + +/// Serializable version of `near-vm-runner::FunctionCallError`. +/// +/// Must never reorder/remove elements, can only add new variants at the end (but do that very +/// carefully). It describes stable serialization format, and only used by serialization logic. +#[derive( + Debug, + Clone, + PartialEq, + Eq, + BorshDeserialize, + BorshSerialize, + serde::Serialize, + serde::Deserialize, +)] +pub enum FunctionCallError { + /// Wasm compilation error + CompilationError(CompilationError), + /// Wasm binary env link error + /// + /// Note: this is only to deserialize old data, use execution error for new data + LinkError { + msg: String, + }, + /// Import/export resolve error + MethodResolveError(MethodResolveError), + /// A trap happened during execution of a binary + /// + /// Note: this is only to deserialize old data, use execution error for new data + WasmTrap(WasmTrap), + WasmUnknownError, + /// Note: this is only to deserialize old data, use execution error for new data + HostError(HostError), + // Unused, can be reused by a future error but must be exactly one error to keep ExecutionError + // error borsh serialized at correct index + _EVMError, + ExecutionError(String), +} + +impl From for MethodResolveError { + fn from(outer_err: near_vm_runner::logic::errors::MethodResolveError) -> Self { + use near_vm_runner::logic::errors::MethodResolveError as MRE; + match outer_err { + MRE::MethodEmptyName => Self::MethodEmptyName, + MRE::MethodNotFound => Self::MethodNotFound, + MRE::MethodInvalidSignature => Self::MethodInvalidSignature, + } + } +} + +impl From for PrepareError { + fn from(outer_err: near_vm_runner::logic::errors::PrepareError) -> Self { + use near_vm_runner::logic::errors::PrepareError as PE; + match outer_err { + PE::Serialization => Self::Serialization, + PE::Deserialization => Self::Deserialization, + PE::InternalMemoryDeclared => Self::InternalMemoryDeclared, + PE::GasInstrumentation => Self::GasInstrumentation, + PE::StackHeightInstrumentation => Self::StackHeightInstrumentation, + PE::Instantiate => Self::Instantiate, + PE::Memory => Self::Memory, + PE::TooManyFunctions => Self::TooManyFunctions, + PE::TooManyLocals => Self::TooManyLocals, + } + } +} + +impl From for CompilationError { + fn from(outer_err: near_vm_runner::logic::errors::CompilationError) -> Self { + use near_vm_runner::logic::errors::CompilationError as CE; + match outer_err { + CE::CodeDoesNotExist { account_id } => Self::CodeDoesNotExist { + account_id: account_id.parse().expect("account_id in error must be valid"), + }, + CE::PrepareError(pe) => Self::PrepareError(pe.into()), + CE::WasmerCompileError { msg } => Self::WasmerCompileError { msg }, + } + } +} + +impl From for FunctionCallError { + fn from(outer_err: near_vm_runner::logic::errors::FunctionCallError) -> Self { + use near_vm_runner::logic::errors::FunctionCallError as FCE; + match outer_err { + FCE::CompilationError(e) => Self::CompilationError(e.into()), + FCE::MethodResolveError(e) => Self::MethodResolveError(e.into()), + // Note: We deliberately collapse all execution errors for + // serialization to make the DB representation less dependent + // on specific types in Rust code. + FCE::HostError(ref _e) => Self::ExecutionError(outer_err.to_string()), + FCE::LinkError { msg } => Self::ExecutionError(format!("Link Error: {}", msg)), + FCE::WasmTrap(ref _e) => Self::ExecutionError(outer_err.to_string()), + } + } +} diff --git a/integration-tests/src/tests/client/features/limit_contract_functions_number.rs b/integration-tests/src/tests/client/features/limit_contract_functions_number.rs index 5d5af25b4d5..29a7ad5dacd 100644 --- a/integration-tests/src/tests/client/features/limit_contract_functions_number.rs +++ b/integration-tests/src/tests/client/features/limit_contract_functions_number.rs @@ -4,11 +4,12 @@ use assert_matches::assert_matches; use near_chain::ChainGenesis; use near_chain_configs::Genesis; use near_client::test_utils::TestEnv; -use near_primitives::errors::{ActionErrorKind, TxExecutionError}; +use near_primitives::errors::{ + ActionErrorKind, CompilationError, FunctionCallError, PrepareError, TxExecutionError, +}; use near_primitives::runtime::config_store::RuntimeConfigStore; use near_primitives::version::ProtocolFeature; use near_primitives::views::FinalExecutionStatus; -use near_vm_runner::logic::errors::{CompilationError, FunctionCallErrorSer, PrepareError}; use nearcore::config::GenesisExt; fn verify_contract_limits_upgrade( @@ -64,7 +65,7 @@ fn verify_contract_limits_upgrade( status => panic!("expected transaction to fail, got {:?}", status), }; match e.kind { - ActionErrorKind::FunctionCallError(FunctionCallErrorSer::CompilationError( + ActionErrorKind::FunctionCallError(FunctionCallError::CompilationError( CompilationError::PrepareError(e), )) if e == expected_prepare_err => (), kind => panic!("got unexpected action error kind: {:?}", kind), diff --git a/integration-tests/src/tests/runtime/test_evil_contracts.rs b/integration-tests/src/tests/runtime/test_evil_contracts.rs index ef0ad89a2a4..e6c11c6783f 100644 --- a/integration-tests/src/tests/runtime/test_evil_contracts.rs +++ b/integration-tests/src/tests/runtime/test_evil_contracts.rs @@ -1,7 +1,6 @@ use crate::node::{Node, RuntimeNode}; -use near_primitives::errors::{ActionError, ActionErrorKind}; +use near_primitives::errors::{ActionError, ActionErrorKind, FunctionCallError}; use near_primitives::views::FinalExecutionStatus; -use near_vm_runner::logic::errors::FunctionCallErrorSer; use std::mem::size_of; use assert_matches::assert_matches; @@ -129,7 +128,7 @@ fn test_evil_abort() { FinalExecutionStatus::Failure( ActionError { index: Some(0), - kind: ActionErrorKind::FunctionCallError(FunctionCallErrorSer::ExecutionError( + kind: ActionErrorKind::FunctionCallError(FunctionCallError::ExecutionError( "String encoding is bad UTF-16 sequence.".to_string() )) } diff --git a/integration-tests/src/tests/standard_cases/mod.rs b/integration-tests/src/tests/standard_cases/mod.rs index 38e94ba2a76..65a91e5ee20 100644 --- a/integration-tests/src/tests/standard_cases/mod.rs +++ b/integration-tests/src/tests/standard_cases/mod.rs @@ -9,7 +9,8 @@ use near_jsonrpc_primitives::errors::ServerError; use near_primitives::account::{AccessKey, AccessKeyPermission, FunctionCallPermission}; use near_primitives::config::{ActionCosts, ExtCosts}; use near_primitives::errors::{ - ActionError, ActionErrorKind, InvalidAccessKeyError, InvalidTxError, TxExecutionError, + ActionError, ActionErrorKind, FunctionCallError, InvalidAccessKeyError, InvalidTxError, + MethodResolveError, TxExecutionError, }; use near_primitives::hash::{hash, CryptoHash}; use near_primitives::types::{AccountId, Balance, TrieNodesCount}; @@ -17,7 +18,6 @@ use near_primitives::views::{ AccessKeyView, AccountView, ExecutionMetadataView, FinalExecutionOutcomeView, FinalExecutionStatus, }; -use near_vm_runner::logic::errors::{FunctionCallErrorSer, MethodResolveError}; use nearcore::config::{NEAR_BASE, TESTING_INIT_BALANCE, TESTING_INIT_STAKE}; use crate::node::Node; @@ -89,7 +89,7 @@ pub fn test_smart_contract_panic(node: impl Node) { FinalExecutionStatus::Failure( ActionError { index: Some(0), - kind: ActionErrorKind::FunctionCallError(FunctionCallErrorSer::ExecutionError( + kind: ActionErrorKind::FunctionCallError(FunctionCallError::ExecutionError( "Smart contract panicked: WAT?".to_string() )) } @@ -127,7 +127,7 @@ pub fn test_smart_contract_bad_method_name(node: impl Node) { FinalExecutionStatus::Failure( ActionError { index: Some(0), - kind: ActionErrorKind::FunctionCallError(FunctionCallErrorSer::MethodResolveError( + kind: ActionErrorKind::FunctionCallError(FunctionCallError::MethodResolveError( MethodResolveError::MethodNotFound )) } @@ -151,7 +151,7 @@ pub fn test_smart_contract_empty_method_name_with_no_tokens(node: impl Node) { FinalExecutionStatus::Failure( ActionError { index: Some(0), - kind: ActionErrorKind::FunctionCallError(FunctionCallErrorSer::MethodResolveError( + kind: ActionErrorKind::FunctionCallError(FunctionCallError::MethodResolveError( MethodResolveError::MethodEmptyName )) } @@ -175,7 +175,7 @@ pub fn test_smart_contract_empty_method_name_with_tokens(node: impl Node) { FinalExecutionStatus::Failure( ActionError { index: Some(0), - kind: ActionErrorKind::FunctionCallError(FunctionCallErrorSer::MethodResolveError( + kind: ActionErrorKind::FunctionCallError(FunctionCallError::MethodResolveError( MethodResolveError::MethodEmptyName )) } diff --git a/runtime/near-vm-runner/Cargo.toml b/runtime/near-vm-runner/Cargo.toml index b739c731ff2..95c3dd4f7d1 100644 --- a/runtime/near-vm-runner/Cargo.toml +++ b/runtime/near-vm-runner/Cargo.toml @@ -36,10 +36,8 @@ tracing.workspace = true wasmparser.workspace = true wasmtime = { workspace = true, optional = true } -near-account-id.workspace = true near-crypto.workspace = true near-primitives-core.workspace = true -near-rpc-error-macro.workspace = true # Old versions of pwasm-utils we need to preserve backwards compatibility under # old protocol versions. @@ -126,8 +124,6 @@ nightly = [ sandbox = [] io_trace = [] -dump_errors_schema = ["near-rpc-error-macro/dump_errors_schema"] - # Use this feature to enable counting of fees and costs applied. costs_counting = [] diff --git a/runtime/near-vm-runner/src/logic/errors.rs b/runtime/near-vm-runner/src/logic/errors.rs index 42a8388f7aa..6dd35cc65ec 100644 --- a/runtime/near-vm-runner/src/logic/errors.rs +++ b/runtime/near-vm-runner/src/logic/errors.rs @@ -1,6 +1,4 @@ use borsh::{BorshDeserialize, BorshSerialize}; -use near_account_id::AccountId; -use near_rpc_error_macro::RpcError; use std::any::Any; use std::fmt::{self, Error, Formatter}; use std::io; @@ -55,44 +53,7 @@ pub enum FunctionCallError { HostError(HostError), } -/// Serializable version of `FunctionCallError`. Must never reorder/remove elements, can only -/// add new variants at the end (but do that very carefully). -/// It describes stable serialization format, and only used by serialization logic. -#[derive( - Debug, - Clone, - PartialEq, - Eq, - BorshDeserialize, - BorshSerialize, - serde::Serialize, - serde::Deserialize, -)] -pub enum FunctionCallErrorSer { - /// Wasm compilation error - CompilationError(CompilationError), - /// Wasm binary env link error - /// - /// Note: this is only to deserialize old data, use execution error for new data - LinkError { - msg: String, - }, - /// Import/export resolve error - MethodResolveError(MethodResolveError), - /// A trap happened during execution of a binary - /// - /// Note: this is only to deserialize old data, use execution error for new data - WasmTrap(WasmTrap), - WasmUnknownError, - /// Note: this is only to deserialize old data, use execution error for new data - HostError(HostError), - // Unused, can be reused by a future error but must be exactly one error to keep ExecutionError - // error borsh serialized at correct index - _EVMError, - ExecutionError(String), -} - -#[derive(Debug, strum::IntoStaticStr, thiserror::Error)] +#[derive(Debug, thiserror::Error, strum::IntoStaticStr)] pub enum CacheError { #[error("cache read error")] ReadError(#[source] io::Error), @@ -104,18 +65,7 @@ pub enum CacheError { SerializationError { hash: [u8; 32] }, } /// A kind of a trap happened during execution of a binary -#[derive( - Debug, - Clone, - PartialEq, - Eq, - BorshDeserialize, - BorshSerialize, - RpcError, - serde::Deserialize, - serde::Serialize, - strum::IntoStaticStr, -)] +#[derive(Debug, Clone, PartialEq, Eq, strum::IntoStaticStr)] pub enum WasmTrap { /// An `unreachable` opcode was executed. Unreachable, @@ -137,39 +87,17 @@ pub enum WasmTrap { GenericTrap, } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - BorshDeserialize, - BorshSerialize, - RpcError, - serde::Deserialize, - serde::Serialize, - strum::IntoStaticStr, -)] +#[derive(Debug, Clone, PartialEq, Eq, strum::IntoStaticStr)] pub enum MethodResolveError { MethodEmptyName, MethodNotFound, MethodInvalidSignature, } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - BorshDeserialize, - BorshSerialize, - RpcError, - serde::Deserialize, - serde::Serialize, - strum::IntoStaticStr, -)] +#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize, strum::IntoStaticStr)] pub enum CompilationError { CodeDoesNotExist { - account_id: AccountId, + account_id: Box, }, PrepareError(PrepareError), /// This is for defense in depth. @@ -180,17 +108,7 @@ pub enum CompilationError { }, } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - BorshDeserialize, - BorshSerialize, - RpcError, - serde::Deserialize, - serde::Serialize, -)] +#[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. @@ -220,18 +138,7 @@ pub enum PrepareError { TooManyLocals, } -#[derive( - Debug, - Clone, - PartialEq, - Eq, - BorshDeserialize, - BorshSerialize, - RpcError, - serde::Deserialize, - serde::Serialize, - strum::IntoStaticStr, -)] +#[derive(Debug, Clone, PartialEq, Eq, strum::IntoStaticStr)] pub enum HostError { /// String encoding is bad UTF-16 sequence BadUTF16, @@ -259,8 +166,6 @@ pub enum HostError { InvalidPromiseResultIndex { result_idx: u64 }, /// Accessed invalid register id InvalidRegisterId { register_id: u64 }, - /// Iterator `iterator_index` was invalidated after its creation by performing a mutable operation on trie - IteratorWasInvalidated { iterator_index: u64 }, /// Accessed memory outside the bounds MemoryAccessViolation, /// VM Logic returned an invalid receipt index @@ -323,27 +228,6 @@ pub enum InconsistentStateError { IntegerOverflow, } -impl From for FunctionCallErrorSer { - fn from(outer_err: FunctionCallError) -> Self { - match outer_err { - FunctionCallError::CompilationError(e) => FunctionCallErrorSer::CompilationError(e), - FunctionCallError::MethodResolveError(e) => FunctionCallErrorSer::MethodResolveError(e), - // Note: We deliberately collapse all execution errors for - // serialization to make the DB representation less dependent - // on specific types in Rust code. - FunctionCallError::HostError(ref _e) => { - FunctionCallErrorSer::ExecutionError(outer_err.to_string()) - } - FunctionCallError::LinkError { msg } => { - FunctionCallErrorSer::ExecutionError(format!("Link Error: {}", msg)) - } - FunctionCallError::WasmTrap(ref _e) => { - FunctionCallErrorSer::ExecutionError(outer_err.to_string()) - } - } - } -} - impl From for VMLogicError { fn from(err: HostError) -> Self { VMLogicError::HostError(err) @@ -476,36 +360,81 @@ impl std::fmt::Display for HostError { BadUTF8 => write!(f, "String encoding is bad UTF-8 sequence."), BadUTF16 => write!(f, "String encoding is bad UTF-16 sequence."), GasExceeded => write!(f, "Exceeded the prepaid gas."), - GasLimitExceeded => write!(f, "Exceeded the maximum amount of gas allowed to burn per contract."), + GasLimitExceeded => { + write!(f, "Exceeded the maximum amount of gas allowed to burn per contract.") + } BalanceExceeded => write!(f, "Exceeded the account balance."), EmptyMethodName => write!(f, "Tried to call an empty method name."), GuestPanic { panic_msg } => write!(f, "Smart contract panicked: {}", panic_msg), IntegerOverflow => write!(f, "Integer overflow."), - InvalidIteratorIndex { iterator_index } => write!(f, "Iterator index {:?} does not exist", iterator_index), - InvalidPromiseIndex { promise_idx } => write!(f, "{:?} does not correspond to existing promises", promise_idx), - CannotAppendActionToJointPromise => write!(f, "Actions can only be appended to non-joint promise."), - CannotReturnJointPromise => write!(f, "Returning joint promise is currently prohibited."), - InvalidPromiseResultIndex { result_idx } => write!(f, "Accessed invalid promise result index: {:?}", result_idx), - InvalidRegisterId { register_id } => write!(f, "Accessed invalid register id: {:?}", register_id), - IteratorWasInvalidated { iterator_index } => write!(f, "Iterator {:?} was invalidated after its creation by performing a mutable operation on trie", iterator_index), + InvalidIteratorIndex { iterator_index } => { + write!(f, "Iterator index {:?} does not exist", iterator_index) + } + InvalidPromiseIndex { promise_idx } => { + write!(f, "{:?} does not correspond to existing promises", promise_idx) + } + CannotAppendActionToJointPromise => { + write!(f, "Actions can only be appended to non-joint promise.") + } + CannotReturnJointPromise => { + write!(f, "Returning joint promise is currently prohibited.") + } + InvalidPromiseResultIndex { result_idx } => { + write!(f, "Accessed invalid promise result index: {:?}", result_idx) + } + InvalidRegisterId { register_id } => { + write!(f, "Accessed invalid register id: {:?}", register_id) + } MemoryAccessViolation => write!(f, "Accessed memory outside the bounds."), - InvalidReceiptIndex { receipt_index } => write!(f, "VM Logic returned an invalid receipt index: {:?}", receipt_index), + InvalidReceiptIndex { receipt_index } => { + write!(f, "VM Logic returned an invalid receipt index: {:?}", receipt_index) + } InvalidAccountId => write!(f, "VM Logic returned an invalid account id"), InvalidMethodName => write!(f, "VM Logic returned an invalid method name"), InvalidPublicKey => write!(f, "VM Logic provided an invalid public key"), - ProhibitedInView { method_name } => write!(f, "{} is not allowed in view calls", method_name), - NumberOfLogsExceeded { limit } => write!(f, "The number of logs will exceed the limit {}", limit), - KeyLengthExceeded { length, limit } => write!(f, "The length of a storage key {} exceeds the limit {}", length, limit), - ValueLengthExceeded { length, limit } => write!(f, "The length of a storage value {} exceeds the limit {}", length, limit), - TotalLogLengthExceeded{ length, limit } => write!(f, "The length of a log message {} exceeds the limit {}", length, limit), - NumberPromisesExceeded { number_of_promises, limit } => write!(f, "The number of promises within a FunctionCall {} exceeds the limit {}", number_of_promises, limit), - NumberInputDataDependenciesExceeded { number_of_input_data_dependencies, limit } => write!(f, "The number of input data dependencies {} exceeds the limit {}", number_of_input_data_dependencies, limit), - ReturnedValueLengthExceeded { length, limit } => write!(f, "The length of a returned value {} exceeds the limit {}", length, limit), - ContractSizeExceeded { size, limit } => write!(f, "The size of a contract code in DeployContract action {} exceeds the limit {}", size, limit), - Deprecated {method_name}=> write!(f, "Attempted to call deprecated host function {}", method_name), + ProhibitedInView { method_name } => { + write!(f, "{} is not allowed in view calls", method_name) + } + NumberOfLogsExceeded { limit } => { + write!(f, "The number of logs will exceed the limit {}", limit) + } + KeyLengthExceeded { length, limit } => { + write!(f, "The length of a storage key {} exceeds the limit {}", length, limit) + } + ValueLengthExceeded { length, limit } => { + write!(f, "The length of a storage value {} exceeds the limit {}", length, limit) + } + TotalLogLengthExceeded { length, limit } => { + write!(f, "The length of a log message {} exceeds the limit {}", length, limit) + } + NumberPromisesExceeded { number_of_promises, limit } => write!( + f, + "The number of promises within a FunctionCall {} exceeds the limit {}", + number_of_promises, limit + ), + NumberInputDataDependenciesExceeded { number_of_input_data_dependencies, limit } => { + write!( + f, + "The number of input data dependencies {} exceeds the limit {}", + number_of_input_data_dependencies, limit + ) + } + ReturnedValueLengthExceeded { length, limit } => { + write!(f, "The length of a returned value {} exceeds the limit {}", length, limit) + } + ContractSizeExceeded { size, limit } => write!( + f, + "The size of a contract code in DeployContract action {} exceeds the limit {}", + size, limit + ), + Deprecated { method_name } => { + write!(f, "Attempted to call deprecated host function {}", method_name) + } AltBn128InvalidInput { msg } => write!(f, "AltBn128 invalid input: {}", msg), ECRecoverError { msg } => write!(f, "ECDSA recover error: {}", msg), - Ed25519VerifyInvalidInput { msg } => write!(f, "ED25519 signature verification error: {}", msg), + Ed25519VerifyInvalidInput { msg } => { + write!(f, "ED25519 signature verification error: {}", msg) + } } } } diff --git a/runtime/near-vm-runner/src/logic/tests/promises.rs b/runtime/near-vm-runner/src/logic/tests/promises.rs index 98b068e79c7..d85b7c5e762 100644 --- a/runtime/near-vm-runner/src/logic/tests/promises.rs +++ b/runtime/near-vm-runner/src/logic/tests/promises.rs @@ -4,17 +4,16 @@ use crate::logic::tests::vm_logic_builder::VMLogicBuilder; use crate::logic::types::PromiseResult; use crate::logic::VMLogic; use borsh::BorshSerialize; -use near_account_id::AccountId; use near_crypto::PublicKey; use serde_json; -#[derive(serde::Serialize)] -struct ReceiptView<'a> { - receiver_id: &'a AccountId, - actions: &'a [Action], -} +fn vm_receipts<'a>(logic: &'a VMLogic) -> Vec { + #[derive(serde::Serialize)] + struct ReceiptView<'a, T> { + receiver_id: T, + actions: &'a [Action], + } -fn vm_receipts<'a>(logic: &'a VMLogic) -> Vec> { logic .receipt_manager() .action_receipts diff --git a/runtime/runtime/Cargo.toml b/runtime/runtime/Cargo.toml index 22a7dc366ec..9321c338d1a 100644 --- a/runtime/runtime/Cargo.toml +++ b/runtime/runtime/Cargo.toml @@ -40,7 +40,6 @@ nightly = [ "near-vm-runner/nightly", ] default = [] -dump_errors_schema = ["near-vm-runner/dump_errors_schema"] nightly_protocol = [ "near-chain-configs/nightly_protocol", "near-o11y/nightly_protocol", diff --git a/runtime/runtime/src/actions.rs b/runtime/runtime/src/actions.rs index f03f4ef9d9b..82386289880 100644 --- a/runtime/runtime/src/actions.rs +++ b/runtime/runtime/src/actions.rs @@ -31,8 +31,7 @@ use near_store::{ StorageError, TrieUpdate, }; use near_vm_runner::logic::errors::{ - CompilationError, FunctionCallError, FunctionCallErrorSer, InconsistentStateError, - VMRunnerError, + CompilationError, FunctionCallError, InconsistentStateError, VMRunnerError, }; use near_vm_runner::logic::types::PromiseResult; use near_vm_runner::logic::{ActionCosts, VMContext, VMOutcome}; @@ -58,7 +57,7 @@ pub(crate) fn execute_function_call( Ok(Some(code)) => code, Ok(None) => { let error = FunctionCallError::CompilationError(CompilationError::CodeDoesNotExist { - account_id: account_id.clone(), + account_id: account_id.as_str().into(), }); return Ok(VMOutcome::nop_outcome(error)); } @@ -241,8 +240,7 @@ pub(crate) fn action_function_call( } // Update action result with the abort error converted to the // transaction runtime's format of errors. - let ser: FunctionCallErrorSer = err.into(); - let action_err: ActionError = ActionErrorKind::FunctionCallError(ser).into(); + let action_err: ActionError = ActionErrorKind::FunctionCallError(err.into()).into(); result.result = Err(action_err); } result.gas_burnt = safe_add_gas(result.gas_burnt, outcome.burnt_gas)?;