darkfid/
error.rs

1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18
19use darkfi::rpc::jsonrpc::{ErrorCode::ServerError, JsonError, JsonResult};
20
21/// Custom RPC errors available for darkfid.
22/// Please sort them sensefully.
23pub enum RpcError {
24    // Transaction-related errors
25    TxSimulationFail = -32110,
26    TxGasCalculationFail = -32111,
27
28    // State-related errors,
29    NotSynced = -32120,
30    UnknownBlockHeight = -32121,
31
32    // Parsing errors
33    ParseError = -32190,
34
35    // Contract-related errors
36    ContractZkasDbNotFound = -32200,
37    ContractStateNotFound = -32201,
38    ContractStateKeyNotFound = -32202,
39
40    // Miner errors
41    MinerMissingHeader = -32300,
42    MinerInvalidHeader = -32301,
43    MinerMissingRecipient = -32302,
44    MinerInvalidRecipient = -32303,
45    MinerInvalidRecipientPrefix = -32304,
46    MinerInvalidSpendHook = -32305,
47    MinerInvalidUserData = -32306,
48    MinerMissingNonce = -32307,
49    MinerInvalidNonce = -32308,
50    MinerMissingAddress = -32309,
51    MinerInvalidAddress = -32310,
52    MinerMissingAuxHash = -32311,
53    MinerInvalidAuxHash = -32312,
54    MinerMissingHeight = -32313,
55    MinerInvalidHeight = -32314,
56    MinerMissingPrevId = -32315,
57    MinerInvalidPrevId = -32316,
58    MinerMissingAuxBlob = -32317,
59    MinerInvalidAuxBlob = -32318,
60    MinerMissingBlob = -32319,
61    MinerInvalidBlob = -32320,
62    MinerMissingMerkleProof = -32321,
63    MinerInvalidMerkleProof = -32322,
64    MinerMissingPath = -32323,
65    MinerInvalidPath = -32324,
66    MinerMissingSeedHash = -32325,
67    MinerInvalidSeedHash = -32326,
68    MinerMerkleProofConstructionFailed = -32327,
69    MinerMoneroPowDataConstructionFailed = -32328,
70    MinerUnknownJob = -32329,
71}
72
73fn to_tuple(e: RpcError) -> (i32, String) {
74    let msg = match e {
75        // Transaction-related errors
76        RpcError::TxSimulationFail => "Failed simulating transaction state change",
77        RpcError::TxGasCalculationFail => "Failed to calculate transaction's gas",
78        // State-related errors
79        RpcError::NotSynced => "Blockchain is not synced",
80        RpcError::UnknownBlockHeight => "Did not find block height",
81        // Parsing errors
82        RpcError::ParseError => "Parse error",
83        // Contract-related errors
84        RpcError::ContractZkasDbNotFound => "zkas database not found for given contract",
85        RpcError::ContractStateNotFound => "Records not found for given contract state",
86        RpcError::ContractStateKeyNotFound => "Value not found for given contract state key",
87        // Miner errors
88        RpcError::MinerMissingHeader => "Request is missing the Header hash",
89        RpcError::MinerInvalidHeader => "Request Header hash is invalid",
90        RpcError::MinerMissingRecipient => "Request is missing the recipient wallet address",
91        RpcError::MinerInvalidRecipient => "Request recipient wallet address is invalid",
92        RpcError::MinerInvalidRecipientPrefix => {
93            "Request recipient wallet address prefix is invalid"
94        }
95        RpcError::MinerInvalidSpendHook => "Request spend hook is invalid",
96        RpcError::MinerInvalidUserData => "Request user data is invalid",
97        RpcError::MinerMissingNonce => "Request is missing the Header nonce",
98        RpcError::MinerInvalidNonce => "Request Header nonce is invalid",
99        RpcError::MinerMissingAddress => {
100            "Request is missing the recipient wallet address configuration"
101        }
102        RpcError::MinerInvalidAddress => {
103            "Request recipient wallet address configuration is invalid"
104        }
105        RpcError::MinerMissingAuxHash => "Request is missing the merge mining job (aux_hash)",
106        RpcError::MinerInvalidAuxHash => "Request merge mining job (aux_hash) is invalid",
107        RpcError::MinerMissingHeight => "Request is missing the Monero height",
108        RpcError::MinerInvalidHeight => "Request Monero height is invalid",
109        RpcError::MinerMissingPrevId => "Request is missing the hash of the previous Monero block",
110        RpcError::MinerInvalidPrevId => "Request hash of the previous Monero block is invalid",
111        RpcError::MinerMissingAuxBlob => "Request is missing the merge mining blob",
112        RpcError::MinerInvalidAuxBlob => "Request merge mining bob is invalid",
113        RpcError::MinerMissingBlob => "Request is missing the Monero block template",
114        RpcError::MinerInvalidBlob => "Request Monero block template is invalid",
115        RpcError::MinerMissingMerkleProof => "Request is missing the Merkle proof",
116        RpcError::MinerInvalidMerkleProof => "Request Merkle proof is invalid",
117        RpcError::MinerMissingPath => "Request is missing the Merkle proof path",
118        RpcError::MinerInvalidPath => "Request Merkle proof path is invalid",
119        RpcError::MinerMissingSeedHash => "Request is missing the RandomX seed key",
120        RpcError::MinerInvalidSeedHash => "Request RandomX seed key is invalid",
121        RpcError::MinerMerkleProofConstructionFailed => {
122            "failed constructing aux chain Merkle proof"
123        }
124        RpcError::MinerMoneroPowDataConstructionFailed => "Failed constructing Monero PoW data",
125        RpcError::MinerUnknownJob => "Request job is unknown",
126    };
127
128    (e as i32, msg.to_string())
129}
130
131pub fn server_error(e: RpcError, id: u16, msg: Option<&str>) -> JsonResult {
132    let (code, default_msg) = to_tuple(e);
133
134    if let Some(message) = msg {
135        return JsonError::new(ServerError(code), Some(message.to_string()), id).into()
136    }
137
138    JsonError::new(ServerError(code), Some(default_msg), id).into()
139}