1#![allow(non_snake_case)]
2
3use std::convert::Infallible;
4use std::io;
5
6use actix::MailboxError;
7use anyhow::anyhow;
8use futures::channel::oneshot::Canceled;
9use serde::{Deserialize, Serialize};
10use serde_with::{serde_as, serde_conv};
11use solana_message::CompileError;
12use solana_program::clock::Slot;
13use solana_pubkey::Pubkey;
14use solana_rpc_client_api::client_error::{Error as ClientError, ErrorKind as ClientErrorKind};
15use solana_rpc_client_api::request::{RpcError, RpcRequest, RpcResponseErrorData};
16use solana_rpc_client_api::response::RpcSimulateTransactionResult;
17use solana_sanitize::SanitizeError;
18use solana_signer::{PresignerError, SignerError};
19use solana_transaction_error::TransactionError;
20
21#[derive(Serialize, Deserialize)]
22pub enum AsRpcRequestImpl {
23 Custom,
24 DeregisterNode,
25 GetAccountInfo,
26 GetBalance,
27 GetBlock,
28 GetBlockHeight,
29 GetBlockProduction,
30 GetBlocks,
31 GetBlocksWithLimit,
32 GetBlockTime,
33 GetClusterNodes,
34 GetEpochInfo,
35 GetEpochSchedule,
36 GetFeeForMessage,
37 GetFirstAvailableBlock,
38 GetGenesisHash,
39 GetHealth,
40 GetIdentity,
41 GetInflationGovernor,
42 GetInflationRate,
43 GetInflationReward,
44 GetLargestAccounts,
45 GetLatestBlockhash,
46 GetLeaderSchedule,
47 GetMaxRetransmitSlot,
48 GetMaxShredInsertSlot,
49 GetMinimumBalanceForRentExemption,
50 GetMultipleAccounts,
51 GetProgramAccounts,
52 GetRecentPerformanceSamples,
53 GetRecentPrioritizationFees,
54 GetHighestSnapshotSlot,
55 GetSignaturesForAddress,
56 GetSignatureStatuses,
57 GetSlot,
58 GetSlotLeader,
59 GetSlotLeaders,
60 GetStorageTurn,
61 GetStorageTurnRate,
62 GetSlotsPerSegment,
63 GetStakeMinimumDelegation,
64 GetStoragePubkeysForSlot,
65 GetSupply,
66 GetTokenAccountBalance,
67 GetTokenAccountsByDelegate,
68 GetTokenAccountsByOwner,
69 GetTokenLargestAccounts,
70 GetTokenSupply,
71 GetTransaction,
72 GetTransactionCount,
73 GetVersion,
74 GetVoteAccounts,
75 IsBlockhashValid,
76 MinimumLedgerSlot,
77 RegisterNode,
78 RequestAirdrop,
79 SendTransaction,
80 SimulateTransaction,
81 SignVote,
82}
83
84fn ser_rpc_request(r: &RpcRequest) -> AsRpcRequestImpl {
85 match r {
86 RpcRequest::Custom { .. } => AsRpcRequestImpl::Custom,
87 RpcRequest::DeregisterNode => AsRpcRequestImpl::DeregisterNode,
88 RpcRequest::GetAccountInfo => AsRpcRequestImpl::GetAccountInfo,
89 RpcRequest::GetBalance => AsRpcRequestImpl::GetBalance,
90 RpcRequest::GetBlock => AsRpcRequestImpl::GetBlock,
91 RpcRequest::GetBlockHeight => AsRpcRequestImpl::GetBlockHeight,
92 RpcRequest::GetBlockProduction => AsRpcRequestImpl::GetBlockProduction,
93 RpcRequest::GetBlocks => AsRpcRequestImpl::GetBlocks,
94 RpcRequest::GetBlocksWithLimit => AsRpcRequestImpl::GetBlocksWithLimit,
95 RpcRequest::GetBlockTime => AsRpcRequestImpl::GetBlockTime,
96 RpcRequest::GetClusterNodes => AsRpcRequestImpl::GetClusterNodes,
97 RpcRequest::GetEpochInfo => AsRpcRequestImpl::GetEpochInfo,
98 RpcRequest::GetEpochSchedule => AsRpcRequestImpl::GetEpochSchedule,
99 RpcRequest::GetFeeForMessage => AsRpcRequestImpl::GetFeeForMessage,
100 RpcRequest::GetFirstAvailableBlock => AsRpcRequestImpl::GetFirstAvailableBlock,
101 RpcRequest::GetGenesisHash => AsRpcRequestImpl::GetGenesisHash,
102 RpcRequest::GetHealth => AsRpcRequestImpl::GetHealth,
103 RpcRequest::GetIdentity => AsRpcRequestImpl::GetIdentity,
104 RpcRequest::GetInflationGovernor => AsRpcRequestImpl::GetInflationGovernor,
105 RpcRequest::GetInflationRate => AsRpcRequestImpl::GetInflationRate,
106 RpcRequest::GetInflationReward => AsRpcRequestImpl::GetInflationReward,
107 RpcRequest::GetLargestAccounts => AsRpcRequestImpl::GetLargestAccounts,
108 RpcRequest::GetLatestBlockhash => AsRpcRequestImpl::GetLatestBlockhash,
109 RpcRequest::GetLeaderSchedule => AsRpcRequestImpl::GetLeaderSchedule,
110 RpcRequest::GetMaxRetransmitSlot => AsRpcRequestImpl::GetMaxRetransmitSlot,
111 RpcRequest::GetMaxShredInsertSlot => AsRpcRequestImpl::GetMaxShredInsertSlot,
112 RpcRequest::GetMinimumBalanceForRentExemption => {
113 AsRpcRequestImpl::GetMinimumBalanceForRentExemption
114 }
115 RpcRequest::GetMultipleAccounts => AsRpcRequestImpl::GetMultipleAccounts,
116 RpcRequest::GetProgramAccounts => AsRpcRequestImpl::GetProgramAccounts,
117 RpcRequest::GetRecentPerformanceSamples => AsRpcRequestImpl::GetRecentPerformanceSamples,
118 RpcRequest::GetRecentPrioritizationFees => AsRpcRequestImpl::GetRecentPrioritizationFees,
119 RpcRequest::GetHighestSnapshotSlot => AsRpcRequestImpl::GetHighestSnapshotSlot,
120 RpcRequest::GetSignaturesForAddress => AsRpcRequestImpl::GetSignaturesForAddress,
121 RpcRequest::GetSignatureStatuses => AsRpcRequestImpl::GetSignatureStatuses,
122 RpcRequest::GetSlot => AsRpcRequestImpl::GetSlot,
123 RpcRequest::GetSlotLeader => AsRpcRequestImpl::GetSlotLeader,
124 RpcRequest::GetSlotLeaders => AsRpcRequestImpl::GetSlotLeaders,
125 RpcRequest::GetStorageTurn => AsRpcRequestImpl::GetStorageTurn,
126 RpcRequest::GetStorageTurnRate => AsRpcRequestImpl::GetStorageTurnRate,
127 RpcRequest::GetSlotsPerSegment => AsRpcRequestImpl::GetSlotsPerSegment,
128 RpcRequest::GetStakeMinimumDelegation => AsRpcRequestImpl::GetStakeMinimumDelegation,
129 RpcRequest::GetStoragePubkeysForSlot => AsRpcRequestImpl::GetStoragePubkeysForSlot,
130 RpcRequest::GetSupply => AsRpcRequestImpl::GetSupply,
131 RpcRequest::GetTokenAccountBalance => AsRpcRequestImpl::GetTokenAccountBalance,
132 RpcRequest::GetTokenAccountsByDelegate => AsRpcRequestImpl::GetTokenAccountsByDelegate,
133 RpcRequest::GetTokenAccountsByOwner => AsRpcRequestImpl::GetTokenAccountsByOwner,
134 RpcRequest::GetTokenLargestAccounts => AsRpcRequestImpl::GetTokenLargestAccounts,
135 RpcRequest::GetTokenSupply => AsRpcRequestImpl::GetTokenSupply,
136 RpcRequest::GetTransaction => AsRpcRequestImpl::GetTransaction,
137 RpcRequest::GetTransactionCount => AsRpcRequestImpl::GetTransactionCount,
138 RpcRequest::GetVersion => AsRpcRequestImpl::GetVersion,
139 RpcRequest::GetVoteAccounts => AsRpcRequestImpl::GetVoteAccounts,
140 RpcRequest::IsBlockhashValid => AsRpcRequestImpl::IsBlockhashValid,
141 RpcRequest::MinimumLedgerSlot => AsRpcRequestImpl::MinimumLedgerSlot,
142 RpcRequest::RegisterNode => AsRpcRequestImpl::RegisterNode,
143 RpcRequest::RequestAirdrop => AsRpcRequestImpl::RequestAirdrop,
144 RpcRequest::SendTransaction => AsRpcRequestImpl::SendTransaction,
145 RpcRequest::SimulateTransaction => AsRpcRequestImpl::SimulateTransaction,
146 RpcRequest::SignVote => AsRpcRequestImpl::SignVote,
147 }
148}
149
150fn de_rpc_request(r: AsRpcRequestImpl) -> Result<RpcRequest, Infallible> {
151 Ok(match r {
152 AsRpcRequestImpl::Custom => RpcRequest::Custom { method: "unknown" },
153 AsRpcRequestImpl::DeregisterNode => RpcRequest::DeregisterNode,
154 AsRpcRequestImpl::GetAccountInfo => RpcRequest::GetAccountInfo,
155 AsRpcRequestImpl::GetBalance => RpcRequest::GetBalance,
156 AsRpcRequestImpl::GetBlock => RpcRequest::GetBlock,
157 AsRpcRequestImpl::GetBlockHeight => RpcRequest::GetBlockHeight,
158 AsRpcRequestImpl::GetBlockProduction => RpcRequest::GetBlockProduction,
159 AsRpcRequestImpl::GetBlocks => RpcRequest::GetBlocks,
160 AsRpcRequestImpl::GetBlocksWithLimit => RpcRequest::GetBlocksWithLimit,
161 AsRpcRequestImpl::GetBlockTime => RpcRequest::GetBlockTime,
162 AsRpcRequestImpl::GetClusterNodes => RpcRequest::GetClusterNodes,
163 AsRpcRequestImpl::GetEpochInfo => RpcRequest::GetEpochInfo,
164 AsRpcRequestImpl::GetEpochSchedule => RpcRequest::GetEpochSchedule,
165 AsRpcRequestImpl::GetFeeForMessage => RpcRequest::GetFeeForMessage,
166 AsRpcRequestImpl::GetFirstAvailableBlock => RpcRequest::GetFirstAvailableBlock,
167 AsRpcRequestImpl::GetGenesisHash => RpcRequest::GetGenesisHash,
168 AsRpcRequestImpl::GetHealth => RpcRequest::GetHealth,
169 AsRpcRequestImpl::GetIdentity => RpcRequest::GetIdentity,
170 AsRpcRequestImpl::GetInflationGovernor => RpcRequest::GetInflationGovernor,
171 AsRpcRequestImpl::GetInflationRate => RpcRequest::GetInflationRate,
172 AsRpcRequestImpl::GetInflationReward => RpcRequest::GetInflationReward,
173 AsRpcRequestImpl::GetLargestAccounts => RpcRequest::GetLargestAccounts,
174 AsRpcRequestImpl::GetLatestBlockhash => RpcRequest::GetLatestBlockhash,
175 AsRpcRequestImpl::GetLeaderSchedule => RpcRequest::GetLeaderSchedule,
176 AsRpcRequestImpl::GetMaxRetransmitSlot => RpcRequest::GetMaxRetransmitSlot,
177 AsRpcRequestImpl::GetMaxShredInsertSlot => RpcRequest::GetMaxShredInsertSlot,
178 AsRpcRequestImpl::GetMinimumBalanceForRentExemption => {
179 RpcRequest::GetMinimumBalanceForRentExemption
180 }
181 AsRpcRequestImpl::GetMultipleAccounts => RpcRequest::GetMultipleAccounts,
182 AsRpcRequestImpl::GetProgramAccounts => RpcRequest::GetProgramAccounts,
183 AsRpcRequestImpl::GetRecentPerformanceSamples => RpcRequest::GetRecentPerformanceSamples,
184 AsRpcRequestImpl::GetRecentPrioritizationFees => RpcRequest::GetRecentPrioritizationFees,
185 AsRpcRequestImpl::GetHighestSnapshotSlot => RpcRequest::GetHighestSnapshotSlot,
186 AsRpcRequestImpl::GetSignaturesForAddress => RpcRequest::GetSignaturesForAddress,
187 AsRpcRequestImpl::GetSignatureStatuses => RpcRequest::GetSignatureStatuses,
188 AsRpcRequestImpl::GetSlot => RpcRequest::GetSlot,
189 AsRpcRequestImpl::GetSlotLeader => RpcRequest::GetSlotLeader,
190 AsRpcRequestImpl::GetSlotLeaders => RpcRequest::GetSlotLeaders,
191 AsRpcRequestImpl::GetStorageTurn => RpcRequest::GetStorageTurn,
192 AsRpcRequestImpl::GetStorageTurnRate => RpcRequest::GetStorageTurnRate,
193 AsRpcRequestImpl::GetSlotsPerSegment => RpcRequest::GetSlotsPerSegment,
194 AsRpcRequestImpl::GetStakeMinimumDelegation => RpcRequest::GetStakeMinimumDelegation,
195 AsRpcRequestImpl::GetStoragePubkeysForSlot => RpcRequest::GetStoragePubkeysForSlot,
196 AsRpcRequestImpl::GetSupply => RpcRequest::GetSupply,
197 AsRpcRequestImpl::GetTokenAccountBalance => RpcRequest::GetTokenAccountBalance,
198 AsRpcRequestImpl::GetTokenAccountsByDelegate => RpcRequest::GetTokenAccountsByDelegate,
199 AsRpcRequestImpl::GetTokenAccountsByOwner => RpcRequest::GetTokenAccountsByOwner,
200 AsRpcRequestImpl::GetTokenLargestAccounts => RpcRequest::GetTokenLargestAccounts,
201 AsRpcRequestImpl::GetTokenSupply => RpcRequest::GetTokenSupply,
202 AsRpcRequestImpl::GetTransaction => RpcRequest::GetTransaction,
203 AsRpcRequestImpl::GetTransactionCount => RpcRequest::GetTransactionCount,
204 AsRpcRequestImpl::GetVersion => RpcRequest::GetVersion,
205 AsRpcRequestImpl::GetVoteAccounts => RpcRequest::GetVoteAccounts,
206 AsRpcRequestImpl::IsBlockhashValid => RpcRequest::IsBlockhashValid,
207 AsRpcRequestImpl::MinimumLedgerSlot => RpcRequest::MinimumLedgerSlot,
208 AsRpcRequestImpl::RegisterNode => RpcRequest::RegisterNode,
209 AsRpcRequestImpl::RequestAirdrop => RpcRequest::RequestAirdrop,
210 AsRpcRequestImpl::SendTransaction => RpcRequest::SendTransaction,
211 AsRpcRequestImpl::SimulateTransaction => RpcRequest::SimulateTransaction,
212 AsRpcRequestImpl::SignVote => RpcRequest::SignVote,
213 })
214}
215
216serde_conv!(pub AsRpcRequest, RpcRequest, ser_rpc_request, de_rpc_request);
217
218#[derive(Serialize, Deserialize)]
219pub enum AsRpcResponseErrorDataImpl {
220 Empty,
221 SendTransactionPreflightFailure(RpcSimulateTransactionResult),
222 NodeUnhealthy { num_slots_behind: Option<Slot> },
223}
224
225fn ser_rpc_response_error_data(error: &RpcResponseErrorData) -> AsRpcResponseErrorDataImpl {
226 match error {
227 RpcResponseErrorData::Empty => AsRpcResponseErrorDataImpl::Empty,
228 RpcResponseErrorData::SendTransactionPreflightFailure(rpc_simulate_transaction_result) => {
229 AsRpcResponseErrorDataImpl::SendTransactionPreflightFailure(
230 rpc_simulate_transaction_result.clone(),
231 )
232 }
233 RpcResponseErrorData::NodeUnhealthy { num_slots_behind } => {
234 AsRpcResponseErrorDataImpl::NodeUnhealthy {
235 num_slots_behind: *num_slots_behind,
236 }
237 }
238 }
239}
240
241fn de_rpc_response_error_data(
242 error: AsRpcResponseErrorDataImpl,
243) -> Result<RpcResponseErrorData, Infallible> {
244 Ok(match error {
245 AsRpcResponseErrorDataImpl::Empty => RpcResponseErrorData::Empty,
246 AsRpcResponseErrorDataImpl::SendTransactionPreflightFailure(
247 rpc_simulate_transaction_result,
248 ) => RpcResponseErrorData::SendTransactionPreflightFailure(rpc_simulate_transaction_result),
249 AsRpcResponseErrorDataImpl::NodeUnhealthy { num_slots_behind } => {
250 RpcResponseErrorData::NodeUnhealthy { num_slots_behind }
251 }
252 })
253}
254
255serde_conv!(pub AsRpcResponseErrorData, RpcResponseErrorData, ser_rpc_response_error_data, de_rpc_response_error_data);
256
257#[serde_as]
258#[derive(Serialize, Deserialize)]
259pub enum AsRpcErrorImpl {
260 RpcRequestError(String),
261 RpcResponseError {
262 code: i64,
263 message: String,
264 #[serde_as(as = "AsRpcResponseErrorData")]
265 data: RpcResponseErrorData,
266 },
267 ParseError(String),
268 ForUser(String),
269}
270
271fn ser_rpc_error(error: &RpcError) -> AsRpcErrorImpl {
272 match error {
273 RpcError::RpcRequestError(error) => AsRpcErrorImpl::RpcRequestError(error.clone()),
274 RpcError::RpcResponseError {
275 code,
276 message,
277 data,
278 } => AsRpcErrorImpl::RpcResponseError {
279 code: *code,
280 message: message.clone(),
281 data: clone_rpc_response_error(data),
282 },
283 RpcError::ParseError(error) => AsRpcErrorImpl::ParseError(error.clone()),
284 RpcError::ForUser(error) => AsRpcErrorImpl::ForUser(error.clone()),
285 }
286}
287
288fn de_rpc_error(error: AsRpcErrorImpl) -> Result<RpcError, Infallible> {
289 Ok(match error {
290 AsRpcErrorImpl::RpcRequestError(error) => RpcError::RpcRequestError(error),
291 AsRpcErrorImpl::RpcResponseError {
292 code,
293 message,
294 data,
295 } => RpcError::RpcResponseError {
296 code,
297 message,
298 data,
299 },
300 AsRpcErrorImpl::ParseError(error) => RpcError::ParseError(error),
301 AsRpcErrorImpl::ForUser(error) => RpcError::ForUser(error),
302 })
303}
304
305serde_conv!(pub AsRpcEeror, RpcError, ser_rpc_error, de_rpc_error);
306
307#[serde_as]
308#[derive(Serialize, Deserialize)]
309pub enum AsClientErrorKindImpl {
310 Io(#[serde_as(as = "AsIoError")] io::Error),
311 Middleware(#[serde_as(as = "AsAnyhow")] anyhow::Error),
312 RpcError(#[serde_as(as = "AsRpcEeror")] RpcError),
313 SigningError(#[serde_as(as = "AsSignerError")] SignerError),
314 TransactionError(TransactionError),
315 Custom(String),
316}
317
318#[derive(Serialize, Deserialize)]
319pub enum AsErrorKindImpl {
320 NotFound,
321 PermissionDenied,
322 ConnectionRefused,
323 ConnectionReset,
324 HostUnreachable,
325 NetworkUnreachable,
326 ConnectionAborted,
327 NotConnected,
328 AddrInUse,
329 AddrNotAvailable,
330 NetworkDown,
331 BrokenPipe,
332 AlreadyExists,
333 WouldBlock,
334 NotADirectory,
335 IsADirectory,
336 DirectoryNotEmpty,
337 ReadOnlyFilesystem,
338 StaleNetworkFileHandle,
339 InvalidInput,
340 InvalidData,
341 TimedOut,
342 WriteZero,
343 StorageFull,
344 NotSeekable,
345 QuotaExceeded,
346 FileTooLarge,
347 ResourceBusy,
348 ExecutableFileBusy,
349 Deadlock,
350 CrossesDevices,
351 TooManyLinks,
352 InvalidFilename,
353 ArgumentListTooLong,
354 Interrupted,
355 Unsupported,
356 UnexpectedEof,
357 OutOfMemory,
358 Other,
359}
360
361fn ser_error_kind(kind: &io::ErrorKind) -> AsErrorKindImpl {
362 match kind {
363 io::ErrorKind::NotFound => AsErrorKindImpl::NotFound,
364 io::ErrorKind::PermissionDenied => AsErrorKindImpl::PermissionDenied,
365 io::ErrorKind::ConnectionRefused => AsErrorKindImpl::ConnectionRefused,
366 io::ErrorKind::ConnectionReset => AsErrorKindImpl::ConnectionReset,
367 io::ErrorKind::HostUnreachable => AsErrorKindImpl::HostUnreachable,
368 io::ErrorKind::NetworkUnreachable => AsErrorKindImpl::NetworkUnreachable,
369 io::ErrorKind::ConnectionAborted => AsErrorKindImpl::ConnectionAborted,
370 io::ErrorKind::NotConnected => AsErrorKindImpl::NotConnected,
371 io::ErrorKind::AddrInUse => AsErrorKindImpl::AddrInUse,
372 io::ErrorKind::AddrNotAvailable => AsErrorKindImpl::AddrNotAvailable,
373 io::ErrorKind::NetworkDown => AsErrorKindImpl::NetworkDown,
374 io::ErrorKind::BrokenPipe => AsErrorKindImpl::BrokenPipe,
375 io::ErrorKind::AlreadyExists => AsErrorKindImpl::AlreadyExists,
376 io::ErrorKind::WouldBlock => AsErrorKindImpl::WouldBlock,
377 io::ErrorKind::NotADirectory => AsErrorKindImpl::NotADirectory,
378 io::ErrorKind::IsADirectory => AsErrorKindImpl::IsADirectory,
379 io::ErrorKind::DirectoryNotEmpty => AsErrorKindImpl::DirectoryNotEmpty,
380 io::ErrorKind::ReadOnlyFilesystem => AsErrorKindImpl::ReadOnlyFilesystem,
381 io::ErrorKind::StaleNetworkFileHandle => AsErrorKindImpl::StaleNetworkFileHandle,
382 io::ErrorKind::InvalidInput => AsErrorKindImpl::InvalidInput,
383 io::ErrorKind::InvalidData => AsErrorKindImpl::InvalidData,
384 io::ErrorKind::TimedOut => AsErrorKindImpl::TimedOut,
385 io::ErrorKind::WriteZero => AsErrorKindImpl::WriteZero,
386 io::ErrorKind::StorageFull => AsErrorKindImpl::StorageFull,
387 io::ErrorKind::NotSeekable => AsErrorKindImpl::NotSeekable,
388 io::ErrorKind::QuotaExceeded => AsErrorKindImpl::QuotaExceeded,
389 io::ErrorKind::FileTooLarge => AsErrorKindImpl::FileTooLarge,
390 io::ErrorKind::ResourceBusy => AsErrorKindImpl::ResourceBusy,
391 io::ErrorKind::ExecutableFileBusy => AsErrorKindImpl::ExecutableFileBusy,
392 io::ErrorKind::Deadlock => AsErrorKindImpl::Deadlock,
393 io::ErrorKind::CrossesDevices => AsErrorKindImpl::CrossesDevices,
394 io::ErrorKind::TooManyLinks => AsErrorKindImpl::TooManyLinks,
395 io::ErrorKind::InvalidFilename => AsErrorKindImpl::InvalidFilename,
396 io::ErrorKind::ArgumentListTooLong => AsErrorKindImpl::ArgumentListTooLong,
397 io::ErrorKind::Interrupted => AsErrorKindImpl::Interrupted,
398 io::ErrorKind::Unsupported => AsErrorKindImpl::Unsupported,
399 io::ErrorKind::UnexpectedEof => AsErrorKindImpl::UnexpectedEof,
400 io::ErrorKind::OutOfMemory => AsErrorKindImpl::OutOfMemory,
401 io::ErrorKind::Other => AsErrorKindImpl::Other,
402 _ => AsErrorKindImpl::Other,
403 }
404}
405
406fn de_error_kind(kind: AsErrorKindImpl) -> Result<io::ErrorKind, Infallible> {
407 Ok(match kind {
408 AsErrorKindImpl::NotFound => io::ErrorKind::NotFound,
409 AsErrorKindImpl::PermissionDenied => io::ErrorKind::PermissionDenied,
410 AsErrorKindImpl::ConnectionRefused => io::ErrorKind::ConnectionRefused,
411 AsErrorKindImpl::ConnectionReset => io::ErrorKind::ConnectionReset,
412 AsErrorKindImpl::HostUnreachable => io::ErrorKind::HostUnreachable,
413 AsErrorKindImpl::NetworkUnreachable => io::ErrorKind::NetworkUnreachable,
414 AsErrorKindImpl::ConnectionAborted => io::ErrorKind::ConnectionAborted,
415 AsErrorKindImpl::NotConnected => io::ErrorKind::NotConnected,
416 AsErrorKindImpl::AddrInUse => io::ErrorKind::AddrInUse,
417 AsErrorKindImpl::AddrNotAvailable => io::ErrorKind::AddrNotAvailable,
418 AsErrorKindImpl::NetworkDown => io::ErrorKind::NetworkDown,
419 AsErrorKindImpl::BrokenPipe => io::ErrorKind::BrokenPipe,
420 AsErrorKindImpl::AlreadyExists => io::ErrorKind::AlreadyExists,
421 AsErrorKindImpl::WouldBlock => io::ErrorKind::WouldBlock,
422 AsErrorKindImpl::NotADirectory => io::ErrorKind::NotADirectory,
423 AsErrorKindImpl::IsADirectory => io::ErrorKind::IsADirectory,
424 AsErrorKindImpl::DirectoryNotEmpty => io::ErrorKind::DirectoryNotEmpty,
425 AsErrorKindImpl::ReadOnlyFilesystem => io::ErrorKind::ReadOnlyFilesystem,
426 AsErrorKindImpl::StaleNetworkFileHandle => io::ErrorKind::StaleNetworkFileHandle,
427 AsErrorKindImpl::InvalidInput => io::ErrorKind::InvalidInput,
428 AsErrorKindImpl::InvalidData => io::ErrorKind::InvalidData,
429 AsErrorKindImpl::TimedOut => io::ErrorKind::TimedOut,
430 AsErrorKindImpl::WriteZero => io::ErrorKind::WriteZero,
431 AsErrorKindImpl::StorageFull => io::ErrorKind::StorageFull,
432 AsErrorKindImpl::NotSeekable => io::ErrorKind::NotSeekable,
433 AsErrorKindImpl::QuotaExceeded => io::ErrorKind::QuotaExceeded,
434 AsErrorKindImpl::FileTooLarge => io::ErrorKind::FileTooLarge,
435 AsErrorKindImpl::ResourceBusy => io::ErrorKind::ResourceBusy,
436 AsErrorKindImpl::ExecutableFileBusy => io::ErrorKind::ExecutableFileBusy,
437 AsErrorKindImpl::Deadlock => io::ErrorKind::Deadlock,
438 AsErrorKindImpl::CrossesDevices => io::ErrorKind::CrossesDevices,
439 AsErrorKindImpl::TooManyLinks => io::ErrorKind::TooManyLinks,
440 AsErrorKindImpl::InvalidFilename => io::ErrorKind::InvalidFilename,
441 AsErrorKindImpl::ArgumentListTooLong => io::ErrorKind::ArgumentListTooLong,
442 AsErrorKindImpl::Interrupted => io::ErrorKind::Interrupted,
443 AsErrorKindImpl::Unsupported => io::ErrorKind::Unsupported,
444 AsErrorKindImpl::UnexpectedEof => io::ErrorKind::UnexpectedEof,
445 AsErrorKindImpl::OutOfMemory => io::ErrorKind::OutOfMemory,
446 AsErrorKindImpl::Other => io::ErrorKind::Other,
447 })
448}
449
450serde_conv!(pub AsErrorKind, io::ErrorKind, ser_error_kind, de_error_kind);
451
452#[serde_as]
453#[derive(Serialize, Deserialize)]
454pub struct AsIoErrorImpl {
455 #[serde_as(as = "AsErrorKind")]
456 pub kind: io::ErrorKind,
457 pub msg: String,
458}
459
460fn ser_io_error(error: &io::Error) -> AsIoErrorImpl {
461 AsIoErrorImpl {
462 kind: error.kind(),
463 msg: error.to_string(),
464 }
465}
466
467fn de_io_error(error: AsIoErrorImpl) -> Result<io::Error, Infallible> {
468 Ok(io::Error::new(error.kind, error.msg))
469}
470
471serde_conv!(pub AsIoError, io::Error, ser_io_error, de_io_error);
472
473serde_conv!(
474 pub AsAnyhow,
475 anyhow::Error,
476 |error: &anyhow::Error| error.to_string(),
477 |error: String| Ok::<_, Infallible>(anyhow::Error::msg(error))
478);
479
480#[derive(Serialize, Deserialize)]
481pub enum AsPresignerErrorImpl {
482 VerificationFailure,
483}
484
485fn ser_presigner_error(error: &PresignerError) -> AsPresignerErrorImpl {
486 match error {
487 PresignerError::VerificationFailure => AsPresignerErrorImpl::VerificationFailure,
488 }
489}
490
491fn de_presigner_error(error: AsPresignerErrorImpl) -> Result<PresignerError, Infallible> {
492 Ok(match error {
493 AsPresignerErrorImpl::VerificationFailure => PresignerError::VerificationFailure,
494 })
495}
496
497serde_conv!(
498 AsPresignerError,
499 PresignerError,
500 ser_presigner_error,
501 de_presigner_error
502);
503
504#[serde_as]
505#[derive(Serialize, Deserialize)]
506pub enum AsSignerErrorImpl {
507 KeypairPubkeyMismatch,
508 NotEnoughSigners,
509 TransactionError(TransactionError),
510 Custom(String),
511 PresignerError(#[serde_as(as = "AsPresignerError")] PresignerError),
512 Connection(String),
513 InvalidInput(String),
514 NoDeviceFound,
515 Protocol(String),
516 UserCancel(String),
517 TooManySigners,
518}
519
520fn ser_signer_error(error: &SignerError) -> AsSignerErrorImpl {
521 match clone_signer_error(error) {
522 SignerError::KeypairPubkeyMismatch => AsSignerErrorImpl::KeypairPubkeyMismatch,
523 SignerError::NotEnoughSigners => AsSignerErrorImpl::NotEnoughSigners,
524 SignerError::TransactionError(transaction_error) => {
525 AsSignerErrorImpl::TransactionError(transaction_error)
526 }
527 SignerError::Custom(error) => AsSignerErrorImpl::Custom(error),
528 SignerError::PresignerError(presigner_error) => {
529 AsSignerErrorImpl::PresignerError(presigner_error)
530 }
531 SignerError::Connection(error) => AsSignerErrorImpl::Connection(error),
532 SignerError::InvalidInput(error) => AsSignerErrorImpl::InvalidInput(error),
533 SignerError::NoDeviceFound => AsSignerErrorImpl::NoDeviceFound,
534 SignerError::Protocol(error) => AsSignerErrorImpl::Protocol(error),
535 SignerError::UserCancel(error) => AsSignerErrorImpl::UserCancel(error),
536 SignerError::TooManySigners => AsSignerErrorImpl::TooManySigners,
537 }
538}
539
540fn de_signer_error(error: AsSignerErrorImpl) -> Result<SignerError, Infallible> {
541 Ok(match error {
542 AsSignerErrorImpl::KeypairPubkeyMismatch => SignerError::KeypairPubkeyMismatch,
543 AsSignerErrorImpl::NotEnoughSigners => SignerError::NotEnoughSigners,
544 AsSignerErrorImpl::TransactionError(transaction_error) => {
545 SignerError::TransactionError(transaction_error)
546 }
547 AsSignerErrorImpl::Custom(error) => SignerError::Custom(error),
548 AsSignerErrorImpl::PresignerError(presigner_error) => {
549 SignerError::PresignerError(presigner_error)
550 }
551 AsSignerErrorImpl::Connection(error) => SignerError::Connection(error),
552 AsSignerErrorImpl::InvalidInput(error) => SignerError::InvalidInput(error),
553 AsSignerErrorImpl::NoDeviceFound => SignerError::NoDeviceFound,
554 AsSignerErrorImpl::Protocol(error) => SignerError::Protocol(error),
555 AsSignerErrorImpl::UserCancel(error) => SignerError::UserCancel(error),
556 AsSignerErrorImpl::TooManySigners => SignerError::TooManySigners,
557 })
558}
559
560serde_conv!(
561 pub AsSignerError,
562 SignerError,
563 ser_signer_error,
564 de_signer_error
565);
566
567fn clone_rpc_response_error(data: &RpcResponseErrorData) -> RpcResponseErrorData {
568 match data {
569 RpcResponseErrorData::Empty => RpcResponseErrorData::Empty,
570 RpcResponseErrorData::SendTransactionPreflightFailure(result) => {
571 RpcResponseErrorData::SendTransactionPreflightFailure(result.clone())
572 }
573 RpcResponseErrorData::NodeUnhealthy { num_slots_behind } => {
574 RpcResponseErrorData::NodeUnhealthy {
575 num_slots_behind: *num_slots_behind,
576 }
577 }
578 }
579}
580
581fn clone_rpc_error(error: &RpcError) -> RpcError {
582 match error {
583 RpcError::RpcRequestError(error) => RpcError::RpcRequestError(error.clone()),
584 RpcError::RpcResponseError {
585 code,
586 message,
587 data,
588 } => RpcError::RpcResponseError {
589 code: *code,
590 message: message.clone(),
591 data: clone_rpc_response_error(data),
592 },
593 RpcError::ParseError(error) => RpcError::ParseError(error.clone()),
594 RpcError::ForUser(error) => RpcError::ForUser(error.clone()),
595 }
596}
597
598fn clone_presigner_error(error: &PresignerError) -> PresignerError {
599 match error {
600 PresignerError::VerificationFailure => PresignerError::VerificationFailure,
601 }
602}
603
604fn clone_signer_error(error: &SignerError) -> SignerError {
605 match error {
606 SignerError::KeypairPubkeyMismatch => SignerError::KeypairPubkeyMismatch,
607 SignerError::NotEnoughSigners => SignerError::NotEnoughSigners,
608 SignerError::TransactionError(error) => SignerError::TransactionError(error.clone()),
609 SignerError::Custom(error) => SignerError::Custom(error.clone()),
610 SignerError::PresignerError(error) => {
611 SignerError::PresignerError(clone_presigner_error(error))
612 }
613 SignerError::Connection(error) => SignerError::Connection(error.clone()),
614 SignerError::InvalidInput(error) => SignerError::InvalidInput(error.clone()),
615 SignerError::NoDeviceFound => SignerError::NoDeviceFound,
616 SignerError::Protocol(error) => SignerError::Protocol(error.clone()),
617 SignerError::UserCancel(error) => SignerError::UserCancel(error.clone()),
618 SignerError::TooManySigners => SignerError::TooManySigners,
619 }
620}
621
622fn ser_kind(kind: &ClientErrorKind) -> AsClientErrorKindImpl {
623 match kind {
624 ClientErrorKind::Io(error) => {
625 AsClientErrorKindImpl::Io(io::Error::new(error.kind(), error.to_string()))
626 }
627 ClientErrorKind::Reqwest(error) => AsClientErrorKindImpl::Custom(error.to_string()),
628 ClientErrorKind::Middleware(error) => {
629 AsClientErrorKindImpl::Middleware(anyhow!(format!("{:#}", error)))
630 }
631 ClientErrorKind::RpcError(error) => AsClientErrorKindImpl::RpcError(clone_rpc_error(error)),
632 ClientErrorKind::SerdeJson(error) => AsClientErrorKindImpl::Custom(error.to_string()),
633 ClientErrorKind::SigningError(error) => {
634 AsClientErrorKindImpl::SigningError(clone_signer_error(error))
635 }
636 ClientErrorKind::TransactionError(error) => {
637 AsClientErrorKindImpl::TransactionError(error.clone())
638 }
639 ClientErrorKind::Custom(error) => AsClientErrorKindImpl::Custom(error.clone()),
640 }
641}
642
643fn de_kind(kind: AsClientErrorKindImpl) -> Result<ClientErrorKind, Infallible> {
644 Ok(match kind {
645 AsClientErrorKindImpl::Io(error) => ClientErrorKind::Io(error),
646 AsClientErrorKindImpl::Middleware(error) => ClientErrorKind::Middleware(error),
647 AsClientErrorKindImpl::RpcError(rpc_error) => ClientErrorKind::RpcError(rpc_error),
648 AsClientErrorKindImpl::SigningError(signer_error) => {
649 ClientErrorKind::SigningError(signer_error)
650 }
651 AsClientErrorKindImpl::TransactionError(transaction_error) => {
652 ClientErrorKind::TransactionError(transaction_error)
653 }
654 AsClientErrorKindImpl::Custom(error) => ClientErrorKind::Custom(error),
655 })
656}
657
658serde_conv!(pub AsClientErrorKind, ClientErrorKind, ser_kind, de_kind);
659
660#[serde_as]
661#[derive(Serialize, Deserialize)]
662pub struct AsClientErrorImpl {
663 #[serde_as(as = "Option<AsRpcRequest>")]
664 pub request: Option<RpcRequest>,
665 #[serde_as(as = "Box<AsClientErrorKind>")]
666 pub kind: Box<ClientErrorKind>,
667}
668
669fn clone_client_error_kind(kind: &ClientErrorKind) -> Box<ClientErrorKind> {
670 Box::new(de_kind(ser_kind(kind)).unwrap())
671}
672
673fn ser_client_error(error: &ClientError) -> AsClientErrorImpl {
674 AsClientErrorImpl {
675 request: error.request.clone(),
676 kind: clone_client_error_kind(&error.kind),
677 }
678}
679
680fn de_client_error(error: AsClientErrorImpl) -> Result<ClientError, Infallible> {
681 Ok(ClientError {
682 request: error.request,
683 kind: error.kind,
684 })
685}
686
687serde_conv!(
688 pub AsClientError,
689 ClientError,
690 ser_client_error,
691 de_client_error
692);
693
694#[derive(Serialize, Deserialize)]
695pub enum AsCompileErrorImpl {
696 AccountIndexOverflow,
697 AddressTableLookupIndexOverflow,
698 UnknownInstructionKey(Pubkey),
699}
700
701fn ser_CompileError(error: &CompileError) -> AsCompileErrorImpl {
702 match error {
703 CompileError::AccountIndexOverflow => AsCompileErrorImpl::AccountIndexOverflow,
704 CompileError::AddressTableLookupIndexOverflow => {
705 AsCompileErrorImpl::AddressTableLookupIndexOverflow
706 }
707 CompileError::UnknownInstructionKey(pubkey) => {
708 AsCompileErrorImpl::UnknownInstructionKey(*pubkey)
709 }
710 }
711}
712
713fn de_CompileError(error: AsCompileErrorImpl) -> Result<CompileError, Infallible> {
714 Ok(match error {
715 AsCompileErrorImpl::AccountIndexOverflow => CompileError::AccountIndexOverflow,
716 AsCompileErrorImpl::AddressTableLookupIndexOverflow => {
717 CompileError::AddressTableLookupIndexOverflow
718 }
719 AsCompileErrorImpl::UnknownInstructionKey(pubkey) => {
720 CompileError::UnknownInstructionKey(pubkey)
721 }
722 })
723}
724
725serde_conv!(pub AsCompileError, CompileError, ser_CompileError, de_CompileError);
726
727#[derive(Serialize, Deserialize)]
728pub enum AsSanitizeErrorImpl {
729 IndexOutOfBounds,
730 ValueOutOfBounds,
731 InvalidValue,
732}
733
734fn ser_SanitizeError(error: &SanitizeError) -> AsSanitizeErrorImpl {
735 match error {
736 SanitizeError::IndexOutOfBounds => AsSanitizeErrorImpl::IndexOutOfBounds,
737 SanitizeError::ValueOutOfBounds => AsSanitizeErrorImpl::ValueOutOfBounds,
738 SanitizeError::InvalidValue => AsSanitizeErrorImpl::InvalidValue,
739 }
740}
741
742fn de_SanitizeError(error: AsSanitizeErrorImpl) -> Result<SanitizeError, Infallible> {
743 Ok(match error {
744 AsSanitizeErrorImpl::IndexOutOfBounds => SanitizeError::IndexOutOfBounds,
745 AsSanitizeErrorImpl::ValueOutOfBounds => SanitizeError::ValueOutOfBounds,
746 AsSanitizeErrorImpl::InvalidValue => SanitizeError::InvalidValue,
747 })
748}
749
750serde_conv!(pub AsSanitizeError, SanitizeError, ser_SanitizeError, de_SanitizeError);
751
752#[derive(Serialize, Deserialize)]
753pub enum AsMailboxErrorImpl {
754 Closed,
755 Timeout,
756}
757
758fn ser_MailboxError(error: &MailboxError) -> AsMailboxErrorImpl {
759 match error {
760 MailboxError::Closed => AsMailboxErrorImpl::Closed,
761 MailboxError::Timeout => AsMailboxErrorImpl::Timeout,
762 }
763}
764
765fn de_MailboxError(error: AsMailboxErrorImpl) -> Result<MailboxError, Infallible> {
766 Ok(match error {
767 AsMailboxErrorImpl::Closed => MailboxError::Closed,
768 AsMailboxErrorImpl::Timeout => MailboxError::Timeout,
769 })
770}
771
772serde_conv!(pub AsMailboxError, MailboxError, ser_MailboxError, de_MailboxError);
773
774serde_conv!(pub AsCancelled, Canceled, |_| (), |_: ()| Ok::<_, Infallible>(Canceled));