Skip to content

Latest commit

 

History

History
325 lines (235 loc) · 15.4 KB

07-errors.md

File metadata and controls

325 lines (235 loc) · 15.4 KB

Error Conditions

This document specifies the error conditions in the FVM and the associated error codes/numbers.

Conventions:

Names in this document match those used in the reference FVM implementation:

  • UPPER_SNAKE_CASE names are exit codes.
    • The SYS_ prefix namespaces "system" exit codes.
    • The USR_ prefix namespaces "user" (or "standard") exit codes.
  • CamelCase names are error numbers.

Exit Codes

Exit codes are numeric, 32bit integer codes that signal the outcome of the execution.

A 0 exit code (OK) is an implied exit code: it is generated when the actor returns normally. This is the only exit code that can carry a return value (an arbitrary IPLD object).

Non-zero exit code are either:

  1. explicitly signalled by an actor through an early abort operation
  2. explicitly generated by the VM because it encountered an abnormality during execution

In both cases, a non-zero exit code indicates that execution was interrupted and that the actors state was left unchanged. A non-zero exit code may not be accompanied by a return value.

Exit codes appear on-chain inside the message receipt, and therefore form part of consensus.

System Non-Zero Exit Codes

System non-zero exit codes are generated by the VM itself to indicate that the message itself failed to apply. Actors may not call vm::abort with any system exit code.

Code Status Description
1 SYS_SENDER_INVALID sender doesn't exist
2 SYS_SENDER_STATE_INVALID message sender is not in a valid state to send the message
3 reserved
4 SYS_ILLEGAL_INSTRUCTION message receiver trapped
5 SYS_INVALID_RECEIVER receiver doesn't exist and can't be automatically created
6 SYS_INSUFFICIENT_FUNDS sender didn't have the requisite funds
7 SYS_OUT_OF_GAS out of gas
8 reserved
9 SYS_ILLEGAL_EXIT_CODE message receiver aborted with an system exit code
10 SYS_ASSERTION_FAILED some internal assertion failed
11 SYS_MISSING_RETURN the actor returned a block handle that doesn't exist
13-15 reserved

Notes:

  1. If a message sender doesn't exist on-chain, the VM will return a receipt with the SYS_SENDER_INVALID exit code.
  2. If an actor calls vm::abort with a system exit code, that exit code will be replaced with SYS_ILLEGAL_EXIT_CODE.
  3. If an actor traps (often a memory violation), the exit code SYS_ILLEGAL_INSTRUCTION will be returned. User-level assertions (e.g., a go/rust panic, an uncaught exception, etc.) should cleanly abort with USR_ASSERTION_FAILED. SYS_ILLEGAL_INSTRUCTION means that the actor failed in a way that it couldn't (or didn't) handle itself.
  4. If a message runs out of gas, the VM will return a receipt with the SYS_OUT_OF_GAS exit code.
  5. Most of these exit codes are only reflected on-chain and will not be observed in internal sends. The exceptions are:
    • SYS_ILLEGAL_EXIT_CODE if the called actor aborted with a system exit code.
    • SYS_ILLEGAL_INSTRUCTION if the called actor crashed.
    • SYS_MISSING_RETURN if the actor returns an invalid block handle.

Changes from pre-FVM Filecoin:

  1. Removed SYS_INVALID_METHOD (3). Dispatch is now handled inside actor code which should exit with the equivalent USR_UNHANDLED_MESSAGE.
  2. Removed SYS_FORBIDDEN (8). Caller verification is a userspace operation, we'll now exit with USR_FORBIDDEN.
  3. Replaced SYS_ILLEGAL_ARGUMENT with SYS_ASSERTION_FAILED to more accurately reflect its usage. When this appears on-chain, it means that a message hit some internal Filecoin assert that shouldn't happen.

Standard Non-Zero Exit Codes

Standard non-zero exit codes are codes returned by actors to indicate common failure conditions.

Code Status Description
16 USR_ILLEGAL_ARGUMENT invalid message parameters
17 USR_NOT_FOUND message referenced something that doesn't exist
18 USR_FORBIDDEN operation forbidden
19 USR_INSUFFICIENT_FUNDS insufficient funds for operation
20 USR_ILLEGAL_STATE the actor is in an illegal state
21 USR_SERIALIZATION actor failed to serialize or deserialize some state
22 USR_UNHANDLED_MESSAGE actor cannot handle this message
23 USR_UNSPECIFIED the actor failed with an unspecified error
24 USR_ASSERTION_FAILED the actor failed some user-level assertion
25-31 reserved

Changes from pre-FVM Filecoin:

  1. Added USR_UNHANDLED_MESSAGE (replacing SYS_INVALID_METHOD).
  2. Added USR_UNSPECIFIED. This indicates that something unspecified went wrong, but we don't know what the cause is. This is a sane default exit code when accurately determining the underlying error is expensive, unreliable, complex, etc.
  3. Added USR_ASSERTION_FAILED. This means that the actor failed some user-level assertion (e.g., the actor paniced, threw an uncaught exception, etc.).

Syscall Error Numbers

Syscall error numbers (ErrorNumber) are returned by syscalls to actors. They indicate that the syscall failed (without any side effects). The actor may choose to handle the error and continue, or abort (usually with one of the standard non-zero exit codes).

A return value of "0" means that the syscall succeeded.

Number Name Description
1 IllegalArgument invalid syscall parameters
2 IllegalOperation actor is not in the correct state to perform operation
3 LimitExceeded some limit was exceeded (e.g. lookback limit)
4 AssertionFailed some internal assertion failed
5 InsufficientFunds attempted to send more than balance
6 NotFound resource not found
7 InvalidHandle block handle invalid
8 IllegalCid cid creation parameters (hash/length) were invalid
9 IllegalCodec specified codec is not allowed
10 Serialization block format did not match specified codec
11 Forbidden operation is forbidden

Changes from pre-FVM Filecoin:

Before the FVM, Filecoin didn't have a concept of syscall error numbers, only exit codes. However:

  1. Pre-FVM, most syscalls returned string errors with no exit codes attached.

  2. There is no reliable mapping from syscall errors to exit codes. For example:

    1. If a syscall returns IllegalArgument, it means that an illegal argument was passed to the syscall.
    2. If an actor exits with USR_ILLEGAL_ARGUMENT, it means the message parameters weren't allowed.

    1 does not imply 2. An actor may pass illegal arguments to a syscall due to a bug in the actor, illegal state, etc.

Notes:

  • We intentionally use IllegalArgument instead of Serialization in non-IPLD syscalls, even if we're using CBOR.

  • AssertionFailed is a special error that indicates that some internal assertion failed and that there is likely something wrong with a system actor or the Filecoin state-tree itself. It exists to allow the network to continue in the face of bugs where the network continuing is likely less harmful than the bug itself.

    It can't be caught by normal actors (and turns into a SYS_ASSERTION_FAILED exit code on-chain), but may be caught by some system actors (e.g., cron).

    Uses:

    • actor::create_actor fails because the init actor is in a bad state.
    • actor::resolve_address fails because the init actor is in a bad state.

Error Numbers By Syscall

ipld::open

Error Reason
NotFound when the target block isn't in the reachable set.
IllegalArgument if there's something wrong with the CID.

ipld::create

Error Reason
LimitExceeded if the block is too big.
NotFound one of the blocks's children isn't in the reachable set
IllegalCodec if the passed codec isn't supported.
Serialization if the passed block doesn't match the passed codec.
IllegalArgument if the block isn't in memory, etc.

ipld::read

Error Reason
InvalidHandle if the handle isn't known.
IllegalArgument if the passed buffer isn't valid, in memory, etc.

ipld::stat

Error Reason
InvalidHandle if the handle isn't known.

ipld::cid

Error Reason
InvalidHandle if the handle isn't known.
IllegalCid hash code and/or hash length aren't supported.
IllegalArgument if the passed buffer isn't valid, in memory, etc.

self::root

Error Reason
IllegalOperation actor hasn't set the root yet, or has been deleted.
IllegalArgument if the passed buffer isn't valid, in memory, etc.

self::set_root

Error Reason
IllegalOperation actor has been deleted
NotFound specified root CID is not in the reachable set.

self::self_destruct

Error Reason
NotFound beneficiary isn't found
Forbidden beneficiary is not allowed (usually means beneficiary is self)
IllegalArgument if the passed address buffer isn't valid, in memory, etc.

message::*

Cannot fail.

network::*

Cannot fail.

actor::resolve_address

Error Reason
NotFound target actor doesn't exist
IllegalArgument if the passed address buffer isn't valid, in memory, etc.

actor::get_actor_code_cid

Error Reason
NotFound target actor doesn't exist
IllegalArgument if the passed address buffer isn't valid, in memory, etc.

actor::new_actor_address

TODO (likely needs to go)

actor::create_actor

TODO

crypto::verify_signature

Error Reason
IllegalArgument signature, address, or plaintext buffers are invalid.

crypto::hash_blake2b

Error Reason
IllegalArgument invalid buffer

crypto::verify_seal

Error Reason
IllegalArgument anything

crypto::verify_post

Error Reason
IllegalArgument anything

crypto::compute_unsealed_sector_cid

Error Reason
IllegalArgument everything else

crypto::verify_consensus_fault

Error Reason
LimitExceeded exceeded lookback limit finding block.
IllegalArgument something else

crypto::verify_aggregate_seals

Error Reason
LimitExceeded exceeds seal aggregation limit.
IllegalArgument something is malformed

crypto::batch_verify_seals

Error Reason
IllegalArgument if malformed params

rand::get_*_randomness

Error Reason
LimitExceeded lookback exceeds limit.
IllegalArgument invalid buffer, etc.

gas::charge_gas

Error Reason
IllegalArgument invalid name buffer.

send::send

A syscall error in send means the caller did something wrong. If the callee panics, exceeds some limit, aborts, aborts with an invalid code, etc., the syscall will succeed and the failure will be reflected in the exit code contained in the syscall's return value.

Error Reason
NotFound target actor does not exist and cannot be created.
InsufficientFunds tried to send more FIL than available.
InvalidHandle parameters block not found.
LimitExceeded recursion limit reached.
IllegalArgument invalid recipient address buffer.