1use kaspa_consensus_core::{subnets::SubnetworkConversionError, tx::TransactionId};
6use kaspa_utils::networking::IpAddress;
7use std::{net::AddrParseError, num::TryFromIntError};
8use thiserror::Error;
9use workflow_core::channel::ChannelError;
10
11use crate::{api::ctl::RpcState, RpcHash, RpcTransactionId, SubmitBlockRejectReason};
12
13#[derive(Clone, Debug, Error)]
14pub enum RpcError {
15 #[error("Not implemented")]
16 NotImplemented,
17
18 #[error("Integer downsize conversion error {0}")]
19 IntConversionError(#[from] TryFromIntError),
20
21 #[error("Hex parsing error: {0}")]
22 HexParsingError(#[from] faster_hex::Error),
23
24 #[error("Blue work parsing error {0}")]
25 RpcBlueWorkTypeParseError(std::num::ParseIntError),
26
27 #[error("Integer parsing error: {0}")]
28 ParseIntError(#[from] std::num::ParseIntError),
29
30 #[error("Ip address parsing error {0}")]
31 ParseIpAddressError(#[from] AddrParseError),
32
33 #[error("Wrong rpc api version format")]
34 RpcApiVersionFormatError,
35
36 #[error("Invalid script class: {0}")]
37 InvalidRpcScriptClass(String),
38
39 #[error("Missing required field {0}.{1}")]
40 MissingRpcFieldError(String, String),
41
42 #[error("Feature not supported")]
43 UnsupportedFeature,
44
45 #[error("Primitive to enum conversion error")]
46 PrimitiveToEnumConversionError,
47
48 #[error("Coinbase payload is above max length ({0}). Try to shorten the extra data.")]
49 CoinbasePayloadLengthAboveMax(usize),
50
51 #[error("Rejected transaction {0}: {1}")]
52 RejectedTransaction(RpcTransactionId, String),
53
54 #[error("Block {0} is invalid. No verbose data can be built.")]
55 InvalidBlock(RpcHash),
56
57 #[error("If includeTransactions is set, then includeBlockVerboseData must be set as well.")]
58 InvalidGetBlocksRequest,
59
60 #[error("Transaction {0} not found")]
61 TransactionNotFound(TransactionId),
62
63 #[error("Method unavailable. Run the node with the --utxoindex argument.")]
64 NoUtxoIndex,
65
66 #[error("Method unavailable. No connection manager is currently available.")]
67 NoConnectionManager,
68
69 #[error("Requested window size {0} is larger than max {1} allowed in RPC safe mode.")]
70 WindowSizeExceedingMaximum(u32, u32),
71
72 #[error("Requested window size {0} is larger than pruning point depth {1}.")]
73 WindowSizeExceedingPruningDepth(u32, u64),
74
75 #[error("Method unavailable in safe mode. Run the node with --unsaferpc argument.")]
76 UnavailableInSafeMode,
77
78 #[error("Cannot ban IP {0} because it has some permanent connection.")]
79 IpHasPermanentConnection(IpAddress),
80
81 #[error("IP {0} is not registered as banned.")]
82 IpIsNotBanned(IpAddress),
83
84 #[error("Block {0} doesn't have any merger block.")]
85 MergerNotFound(RpcHash),
86
87 #[error("Block was not submitted: {0}")]
88 SubmitBlockError(SubmitBlockRejectReason),
89
90 #[error(transparent)]
91 AddressError(#[from] kaspa_addresses::AddressError),
92
93 #[error(transparent)]
94 NetworkTypeError(#[from] kaspa_consensus_core::network::NetworkTypeError),
95
96 #[error(transparent)]
97 NetworkIdError(#[from] kaspa_consensus_core::network::NetworkIdError),
98
99 #[error(transparent)]
100 NotificationError(#[from] kaspa_notify::error::Error),
101
102 #[error(transparent)]
103 MiningManagerError(#[from] kaspa_mining_errors::manager::MiningManagerError),
104
105 #[error(transparent)]
106 ConsensusError(#[from] kaspa_consensus_core::errors::consensus::ConsensusError),
107
108 #[error(transparent)]
109 ScriptClassError(#[from] kaspa_txscript::script_class::Error),
110
111 #[error(transparent)]
112 NodeIdError(#[from] uuid::Error),
113
114 #[error("RPC Server (remote error) -> {0}")]
115 RpcSubsystem(String),
116
117 #[error("{0}")]
118 General(String),
119
120 #[error("RpcCtl dispatch error")]
121 RpcCtlDispatchError,
122
123 #[error("transaction query must either not filter transactions or include orphans")]
124 InconsistentMempoolTxQuery,
125
126 #[error(transparent)]
127 SubnetParsingError(#[from] SubnetworkConversionError),
128
129 #[error(transparent)]
130 WasmError(#[from] workflow_wasm::error::Error),
131
132 #[error("{0}")]
133 SerdeWasmBindgen(String),
134
135 #[error(transparent)]
136 ConsensusClient(#[from] kaspa_consensus_client::error::Error),
137}
138
139impl From<String> for RpcError {
140 fn from(value: String) -> Self {
141 RpcError::General(value)
142 }
143}
144
145impl From<&str> for RpcError {
146 fn from(value: &str) -> Self {
147 RpcError::General(value.to_string())
148 }
149}
150
151impl From<ChannelError<RpcState>> for RpcError {
152 fn from(_: ChannelError<RpcState>) -> Self {
153 RpcError::RpcCtlDispatchError
154 }
155}
156
157impl From<serde_wasm_bindgen::Error> for RpcError {
158 fn from(value: serde_wasm_bindgen::Error) -> Self {
159 RpcError::SerdeWasmBindgen(value.to_string())
160 }
161}
162
163pub type RpcResult<T> = std::result::Result<T, crate::RpcError>;