pchain_runtime/error.rs
1/*
2 Copyright © 2023, ParallelChain Lab
3 Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
4*/
5
6//! Defines [TransitionError] which is set of error definitions in state transitions.
7//!
8//! Transition Error is not failure code specified in [ExitStatus], which is not included
9//! in the block for transaction failure. The error types are for the purpose of diagnosis.
10
11use pchain_types::blockchain::ExitStatus;
12
13use crate::contract::{FuncError, MethodCallError};
14
15/// Descriptive error definitions of a Transition
16#[derive(Clone, Debug, PartialEq, Eq)]
17pub enum TransitionError {
18 /// Nonce is not current nonce.
19 WrongNonce,
20
21 /// Not enough balance to pay for gas limit.
22 NotEnoughBalanceForGasLimit,
23
24 /// Not enough balance to pay for transfer.
25 NotEnoughBalanceForTransfer,
26
27 /// Gas limit was insufficient to cover pre-execution costs.
28 PreExecutionGasExhausted,
29
30 /// The contract bytecode contains disallowed opcodes.
31 DisallowedOpcode,
32
33 /// Contract cannot be compiled into machine code (it is probably invalid WASM).
34 CannotCompile,
35
36 /// Contract does not export the METHOD_CONTRACT method.
37 NoExportedContractMethod,
38
39 /// Deployment failed for some other reason.
40 OtherDeployError,
41
42 /// Deployment failed because the Contract already exists (CBI version was set for the account)
43 ContractAlreadyExists,
44
45 /// Contract cannot be found in state
46 NoContractcode,
47
48 /// Fail to load Contract from the CBI
49 InvalidCBI,
50
51 /// Gas limit was insufficient to cover execution proper costs.
52 ExecutionProperGasExhausted,
53
54 /// Runtime error during execution proper of the entree smart contract.
55 RuntimeError,
56
57 /// Gas limit was insufficient to cover execution proper costs of an internal transaction.
58 InternalExecutionProperGasExhaustion,
59
60 /// Runtime error during execution proper of an internal transaction.
61 InternalRuntimeError,
62
63 /// Staking Command - Create Pool fails because the pool already exists
64 PoolAlreadyExists,
65
66 /// Staking Command fails for non-existing pool
67 PoolNotExists,
68
69 /// Staking Command - Unstake Deposit fails because the Pool has no stakes.
70 PoolHasNoStakes,
71
72 /// Staking Command fails because pool policy is invalid.
73 /// Scenarios such as
74 /// 1. commission fee is greater than 100
75 /// 2. commission fee is as same as the origin onw
76 InvalidPoolPolicy,
77
78 /// Staking Command - Create Deposits fails because the deposits already exists
79 DepositsAlreadyExists,
80
81 /// Staking Command fails because the deposits does not exist.
82 DepositsNotExists,
83
84 /// Staking Command - Set Deposit Settings fails because the deposit amount
85 InvalidDepositPolicy,
86
87 /// Staking Command fails because the specified amount does not match with the requirement of the operation.
88 /// Scenarios such as
89 /// 1. Stake power has already reached upper limit (deposit amount) for Command - Stake Deposit
90 /// 2. Stake power is not enough to stay in the delegated stakes for Command - Stake Deposit
91 /// 3. Stake power has already reached lower limit for Command - Withdrawal Deposit
92 InvalidStakeAmount,
93
94 /// Transaction commands are empty
95 InvalidCommands,
96
97 /// There is more than 1 NextEpoch Command in a transaction.
98 InvalidNextEpochCommand,
99}
100
101impl From<MethodCallError> for TransitionError {
102 fn from(call_error: MethodCallError) -> Self {
103 match call_error {
104 MethodCallError::GasExhaustion => TransitionError::ExecutionProperGasExhausted,
105 MethodCallError::NoExportedMethod(_) => TransitionError::RuntimeError,
106 MethodCallError::Runtime(e) => {
107 // check for internal errors
108 match e.downcast::<FuncError>() {
109 Err(_) => TransitionError::RuntimeError,
110 Ok(FuncError::GasExhaustionError) => {
111 TransitionError::ExecutionProperGasExhausted
112 }
113 Ok(_) => TransitionError::InternalRuntimeError,
114 }
115 }
116 }
117 }
118}
119
120impl<'a> From<&'a TransitionError> for ExitStatus {
121 fn from(value: &'a TransitionError) -> Self {
122 match value {
123 TransitionError::ExecutionProperGasExhausted
124 | TransitionError::InternalExecutionProperGasExhaustion => ExitStatus::GasExhausted,
125 _ => ExitStatus::Failed,
126 }
127 }
128}