Skip to main content

flow_lib/
errors.rs

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(Box<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(Box::new(
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        ) => {
249            RpcResponseErrorData::SendTransactionPreflightFailure(*rpc_simulate_transaction_result)
250        }
251        AsRpcResponseErrorDataImpl::NodeUnhealthy { num_slots_behind } => {
252            RpcResponseErrorData::NodeUnhealthy { num_slots_behind }
253        }
254    })
255}
256
257serde_conv!(pub AsRpcResponseErrorData, RpcResponseErrorData, ser_rpc_response_error_data, de_rpc_response_error_data);
258
259#[serde_as]
260#[derive(Serialize, Deserialize)]
261pub enum AsRpcErrorImpl {
262    RpcRequestError(String),
263    RpcResponseError {
264        code: i64,
265        message: String,
266        #[serde_as(as = "Box<AsRpcResponseErrorData>")]
267        data: Box<RpcResponseErrorData>,
268    },
269    ParseError(String),
270    ForUser(String),
271}
272
273fn ser_rpc_error(error: &RpcError) -> AsRpcErrorImpl {
274    match error {
275        RpcError::RpcRequestError(error) => AsRpcErrorImpl::RpcRequestError(error.clone()),
276        RpcError::RpcResponseError {
277            code,
278            message,
279            data,
280        } => AsRpcErrorImpl::RpcResponseError {
281            code: *code,
282            message: message.clone(),
283            data: Box::new(clone_rpc_response_error(data)),
284        },
285        RpcError::ParseError(error) => AsRpcErrorImpl::ParseError(error.clone()),
286        RpcError::ForUser(error) => AsRpcErrorImpl::ForUser(error.clone()),
287    }
288}
289
290fn de_rpc_error(error: AsRpcErrorImpl) -> Result<RpcError, Infallible> {
291    Ok(match error {
292        AsRpcErrorImpl::RpcRequestError(error) => RpcError::RpcRequestError(error),
293        AsRpcErrorImpl::RpcResponseError {
294            code,
295            message,
296            data,
297        } => RpcError::RpcResponseError {
298            code,
299            message,
300            data: *data,
301        },
302        AsRpcErrorImpl::ParseError(error) => RpcError::ParseError(error),
303        AsRpcErrorImpl::ForUser(error) => RpcError::ForUser(error),
304    })
305}
306
307serde_conv!(pub AsRpcEeror, RpcError, ser_rpc_error, de_rpc_error);
308
309#[serde_as]
310#[derive(Serialize, Deserialize)]
311pub enum AsClientErrorKindImpl {
312    Io(#[serde_as(as = "AsIoError")] io::Error),
313    Middleware(#[serde_as(as = "AsAnyhow")] anyhow::Error),
314    RpcError(#[serde_as(as = "Box<AsRpcEeror>")] Box<RpcError>),
315    SigningError(#[serde_as(as = "AsSignerError")] SignerError),
316    TransactionError(TransactionError),
317    Custom(String),
318}
319
320#[derive(Serialize, Deserialize)]
321pub enum AsErrorKindImpl {
322    NotFound,
323    PermissionDenied,
324    ConnectionRefused,
325    ConnectionReset,
326    HostUnreachable,
327    NetworkUnreachable,
328    ConnectionAborted,
329    NotConnected,
330    AddrInUse,
331    AddrNotAvailable,
332    NetworkDown,
333    BrokenPipe,
334    AlreadyExists,
335    WouldBlock,
336    NotADirectory,
337    IsADirectory,
338    DirectoryNotEmpty,
339    ReadOnlyFilesystem,
340    StaleNetworkFileHandle,
341    InvalidInput,
342    InvalidData,
343    TimedOut,
344    WriteZero,
345    StorageFull,
346    NotSeekable,
347    QuotaExceeded,
348    FileTooLarge,
349    ResourceBusy,
350    ExecutableFileBusy,
351    Deadlock,
352    CrossesDevices,
353    TooManyLinks,
354    InvalidFilename,
355    ArgumentListTooLong,
356    Interrupted,
357    Unsupported,
358    UnexpectedEof,
359    OutOfMemory,
360    Other,
361}
362
363fn ser_error_kind(kind: &io::ErrorKind) -> AsErrorKindImpl {
364    match kind {
365        io::ErrorKind::NotFound => AsErrorKindImpl::NotFound,
366        io::ErrorKind::PermissionDenied => AsErrorKindImpl::PermissionDenied,
367        io::ErrorKind::ConnectionRefused => AsErrorKindImpl::ConnectionRefused,
368        io::ErrorKind::ConnectionReset => AsErrorKindImpl::ConnectionReset,
369        io::ErrorKind::HostUnreachable => AsErrorKindImpl::HostUnreachable,
370        io::ErrorKind::NetworkUnreachable => AsErrorKindImpl::NetworkUnreachable,
371        io::ErrorKind::ConnectionAborted => AsErrorKindImpl::ConnectionAborted,
372        io::ErrorKind::NotConnected => AsErrorKindImpl::NotConnected,
373        io::ErrorKind::AddrInUse => AsErrorKindImpl::AddrInUse,
374        io::ErrorKind::AddrNotAvailable => AsErrorKindImpl::AddrNotAvailable,
375        io::ErrorKind::NetworkDown => AsErrorKindImpl::NetworkDown,
376        io::ErrorKind::BrokenPipe => AsErrorKindImpl::BrokenPipe,
377        io::ErrorKind::AlreadyExists => AsErrorKindImpl::AlreadyExists,
378        io::ErrorKind::WouldBlock => AsErrorKindImpl::WouldBlock,
379        io::ErrorKind::NotADirectory => AsErrorKindImpl::NotADirectory,
380        io::ErrorKind::IsADirectory => AsErrorKindImpl::IsADirectory,
381        io::ErrorKind::DirectoryNotEmpty => AsErrorKindImpl::DirectoryNotEmpty,
382        io::ErrorKind::ReadOnlyFilesystem => AsErrorKindImpl::ReadOnlyFilesystem,
383        io::ErrorKind::StaleNetworkFileHandle => AsErrorKindImpl::StaleNetworkFileHandle,
384        io::ErrorKind::InvalidInput => AsErrorKindImpl::InvalidInput,
385        io::ErrorKind::InvalidData => AsErrorKindImpl::InvalidData,
386        io::ErrorKind::TimedOut => AsErrorKindImpl::TimedOut,
387        io::ErrorKind::WriteZero => AsErrorKindImpl::WriteZero,
388        io::ErrorKind::StorageFull => AsErrorKindImpl::StorageFull,
389        io::ErrorKind::NotSeekable => AsErrorKindImpl::NotSeekable,
390        io::ErrorKind::QuotaExceeded => AsErrorKindImpl::QuotaExceeded,
391        io::ErrorKind::FileTooLarge => AsErrorKindImpl::FileTooLarge,
392        io::ErrorKind::ResourceBusy => AsErrorKindImpl::ResourceBusy,
393        io::ErrorKind::ExecutableFileBusy => AsErrorKindImpl::ExecutableFileBusy,
394        io::ErrorKind::Deadlock => AsErrorKindImpl::Deadlock,
395        io::ErrorKind::CrossesDevices => AsErrorKindImpl::CrossesDevices,
396        io::ErrorKind::TooManyLinks => AsErrorKindImpl::TooManyLinks,
397        io::ErrorKind::InvalidFilename => AsErrorKindImpl::InvalidFilename,
398        io::ErrorKind::ArgumentListTooLong => AsErrorKindImpl::ArgumentListTooLong,
399        io::ErrorKind::Interrupted => AsErrorKindImpl::Interrupted,
400        io::ErrorKind::Unsupported => AsErrorKindImpl::Unsupported,
401        io::ErrorKind::UnexpectedEof => AsErrorKindImpl::UnexpectedEof,
402        io::ErrorKind::OutOfMemory => AsErrorKindImpl::OutOfMemory,
403        io::ErrorKind::Other => AsErrorKindImpl::Other,
404        _ => AsErrorKindImpl::Other,
405    }
406}
407
408fn de_error_kind(kind: AsErrorKindImpl) -> Result<io::ErrorKind, Infallible> {
409    Ok(match kind {
410        AsErrorKindImpl::NotFound => io::ErrorKind::NotFound,
411        AsErrorKindImpl::PermissionDenied => io::ErrorKind::PermissionDenied,
412        AsErrorKindImpl::ConnectionRefused => io::ErrorKind::ConnectionRefused,
413        AsErrorKindImpl::ConnectionReset => io::ErrorKind::ConnectionReset,
414        AsErrorKindImpl::HostUnreachable => io::ErrorKind::HostUnreachable,
415        AsErrorKindImpl::NetworkUnreachable => io::ErrorKind::NetworkUnreachable,
416        AsErrorKindImpl::ConnectionAborted => io::ErrorKind::ConnectionAborted,
417        AsErrorKindImpl::NotConnected => io::ErrorKind::NotConnected,
418        AsErrorKindImpl::AddrInUse => io::ErrorKind::AddrInUse,
419        AsErrorKindImpl::AddrNotAvailable => io::ErrorKind::AddrNotAvailable,
420        AsErrorKindImpl::NetworkDown => io::ErrorKind::NetworkDown,
421        AsErrorKindImpl::BrokenPipe => io::ErrorKind::BrokenPipe,
422        AsErrorKindImpl::AlreadyExists => io::ErrorKind::AlreadyExists,
423        AsErrorKindImpl::WouldBlock => io::ErrorKind::WouldBlock,
424        AsErrorKindImpl::NotADirectory => io::ErrorKind::NotADirectory,
425        AsErrorKindImpl::IsADirectory => io::ErrorKind::IsADirectory,
426        AsErrorKindImpl::DirectoryNotEmpty => io::ErrorKind::DirectoryNotEmpty,
427        AsErrorKindImpl::ReadOnlyFilesystem => io::ErrorKind::ReadOnlyFilesystem,
428        AsErrorKindImpl::StaleNetworkFileHandle => io::ErrorKind::StaleNetworkFileHandle,
429        AsErrorKindImpl::InvalidInput => io::ErrorKind::InvalidInput,
430        AsErrorKindImpl::InvalidData => io::ErrorKind::InvalidData,
431        AsErrorKindImpl::TimedOut => io::ErrorKind::TimedOut,
432        AsErrorKindImpl::WriteZero => io::ErrorKind::WriteZero,
433        AsErrorKindImpl::StorageFull => io::ErrorKind::StorageFull,
434        AsErrorKindImpl::NotSeekable => io::ErrorKind::NotSeekable,
435        AsErrorKindImpl::QuotaExceeded => io::ErrorKind::QuotaExceeded,
436        AsErrorKindImpl::FileTooLarge => io::ErrorKind::FileTooLarge,
437        AsErrorKindImpl::ResourceBusy => io::ErrorKind::ResourceBusy,
438        AsErrorKindImpl::ExecutableFileBusy => io::ErrorKind::ExecutableFileBusy,
439        AsErrorKindImpl::Deadlock => io::ErrorKind::Deadlock,
440        AsErrorKindImpl::CrossesDevices => io::ErrorKind::CrossesDevices,
441        AsErrorKindImpl::TooManyLinks => io::ErrorKind::TooManyLinks,
442        AsErrorKindImpl::InvalidFilename => io::ErrorKind::InvalidFilename,
443        AsErrorKindImpl::ArgumentListTooLong => io::ErrorKind::ArgumentListTooLong,
444        AsErrorKindImpl::Interrupted => io::ErrorKind::Interrupted,
445        AsErrorKindImpl::Unsupported => io::ErrorKind::Unsupported,
446        AsErrorKindImpl::UnexpectedEof => io::ErrorKind::UnexpectedEof,
447        AsErrorKindImpl::OutOfMemory => io::ErrorKind::OutOfMemory,
448        AsErrorKindImpl::Other => io::ErrorKind::Other,
449    })
450}
451
452serde_conv!(pub AsErrorKind, io::ErrorKind, ser_error_kind, de_error_kind);
453
454#[serde_as]
455#[derive(Serialize, Deserialize)]
456pub struct AsIoErrorImpl {
457    #[serde_as(as = "AsErrorKind")]
458    pub kind: io::ErrorKind,
459    pub msg: String,
460}
461
462fn ser_io_error(error: &io::Error) -> AsIoErrorImpl {
463    AsIoErrorImpl {
464        kind: error.kind(),
465        msg: error.to_string(),
466    }
467}
468
469fn de_io_error(error: AsIoErrorImpl) -> Result<io::Error, Infallible> {
470    Ok(io::Error::new(error.kind, error.msg))
471}
472
473serde_conv!(pub AsIoError, io::Error, ser_io_error, de_io_error);
474
475serde_conv!(
476    pub AsAnyhow,
477    anyhow::Error,
478    |error: &anyhow::Error| error.to_string(),
479    |error: String| Ok::<_, Infallible>(anyhow::Error::msg(error))
480);
481
482#[derive(Serialize, Deserialize)]
483pub enum AsPresignerErrorImpl {
484    VerificationFailure,
485}
486
487fn ser_presigner_error(error: &PresignerError) -> AsPresignerErrorImpl {
488    match error {
489        PresignerError::VerificationFailure => AsPresignerErrorImpl::VerificationFailure,
490    }
491}
492
493fn de_presigner_error(error: AsPresignerErrorImpl) -> Result<PresignerError, Infallible> {
494    Ok(match error {
495        AsPresignerErrorImpl::VerificationFailure => PresignerError::VerificationFailure,
496    })
497}
498
499serde_conv!(
500    AsPresignerError,
501    PresignerError,
502    ser_presigner_error,
503    de_presigner_error
504);
505
506#[serde_as]
507#[derive(Serialize, Deserialize)]
508pub enum AsSignerErrorImpl {
509    KeypairPubkeyMismatch,
510    NotEnoughSigners,
511    TransactionError(TransactionError),
512    Custom(String),
513    PresignerError(#[serde_as(as = "AsPresignerError")] PresignerError),
514    Connection(String),
515    InvalidInput(String),
516    NoDeviceFound,
517    Protocol(String),
518    UserCancel(String),
519    TooManySigners,
520}
521
522fn ser_signer_error(error: &SignerError) -> AsSignerErrorImpl {
523    match clone_signer_error(error) {
524        SignerError::KeypairPubkeyMismatch => AsSignerErrorImpl::KeypairPubkeyMismatch,
525        SignerError::NotEnoughSigners => AsSignerErrorImpl::NotEnoughSigners,
526        SignerError::TransactionError(transaction_error) => {
527            AsSignerErrorImpl::TransactionError(transaction_error)
528        }
529        SignerError::Custom(error) => AsSignerErrorImpl::Custom(error),
530        SignerError::PresignerError(presigner_error) => {
531            AsSignerErrorImpl::PresignerError(presigner_error)
532        }
533        SignerError::Connection(error) => AsSignerErrorImpl::Connection(error),
534        SignerError::InvalidInput(error) => AsSignerErrorImpl::InvalidInput(error),
535        SignerError::NoDeviceFound => AsSignerErrorImpl::NoDeviceFound,
536        SignerError::Protocol(error) => AsSignerErrorImpl::Protocol(error),
537        SignerError::UserCancel(error) => AsSignerErrorImpl::UserCancel(error),
538        SignerError::TooManySigners => AsSignerErrorImpl::TooManySigners,
539    }
540}
541
542fn de_signer_error(error: AsSignerErrorImpl) -> Result<SignerError, Infallible> {
543    Ok(match error {
544        AsSignerErrorImpl::KeypairPubkeyMismatch => SignerError::KeypairPubkeyMismatch,
545        AsSignerErrorImpl::NotEnoughSigners => SignerError::NotEnoughSigners,
546        AsSignerErrorImpl::TransactionError(transaction_error) => {
547            SignerError::TransactionError(transaction_error)
548        }
549        AsSignerErrorImpl::Custom(error) => SignerError::Custom(error),
550        AsSignerErrorImpl::PresignerError(presigner_error) => {
551            SignerError::PresignerError(presigner_error)
552        }
553        AsSignerErrorImpl::Connection(error) => SignerError::Connection(error),
554        AsSignerErrorImpl::InvalidInput(error) => SignerError::InvalidInput(error),
555        AsSignerErrorImpl::NoDeviceFound => SignerError::NoDeviceFound,
556        AsSignerErrorImpl::Protocol(error) => SignerError::Protocol(error),
557        AsSignerErrorImpl::UserCancel(error) => SignerError::UserCancel(error),
558        AsSignerErrorImpl::TooManySigners => SignerError::TooManySigners,
559    })
560}
561
562serde_conv!(
563    pub AsSignerError,
564    SignerError,
565    ser_signer_error,
566    de_signer_error
567);
568
569fn clone_rpc_response_error(data: &RpcResponseErrorData) -> RpcResponseErrorData {
570    match data {
571        RpcResponseErrorData::Empty => RpcResponseErrorData::Empty,
572        RpcResponseErrorData::SendTransactionPreflightFailure(result) => {
573            RpcResponseErrorData::SendTransactionPreflightFailure(result.clone())
574        }
575        RpcResponseErrorData::NodeUnhealthy { num_slots_behind } => {
576            RpcResponseErrorData::NodeUnhealthy {
577                num_slots_behind: *num_slots_behind,
578            }
579        }
580    }
581}
582
583fn clone_rpc_error(error: &RpcError) -> RpcError {
584    match error {
585        RpcError::RpcRequestError(error) => RpcError::RpcRequestError(error.clone()),
586        RpcError::RpcResponseError {
587            code,
588            message,
589            data,
590        } => RpcError::RpcResponseError {
591            code: *code,
592            message: message.clone(),
593            data: clone_rpc_response_error(data),
594        },
595        RpcError::ParseError(error) => RpcError::ParseError(error.clone()),
596        RpcError::ForUser(error) => RpcError::ForUser(error.clone()),
597    }
598}
599
600fn clone_presigner_error(error: &PresignerError) -> PresignerError {
601    match error {
602        PresignerError::VerificationFailure => PresignerError::VerificationFailure,
603    }
604}
605
606fn clone_signer_error(error: &SignerError) -> SignerError {
607    match error {
608        SignerError::KeypairPubkeyMismatch => SignerError::KeypairPubkeyMismatch,
609        SignerError::NotEnoughSigners => SignerError::NotEnoughSigners,
610        SignerError::TransactionError(error) => SignerError::TransactionError(error.clone()),
611        SignerError::Custom(error) => SignerError::Custom(error.clone()),
612        SignerError::PresignerError(error) => {
613            SignerError::PresignerError(clone_presigner_error(error))
614        }
615        SignerError::Connection(error) => SignerError::Connection(error.clone()),
616        SignerError::InvalidInput(error) => SignerError::InvalidInput(error.clone()),
617        SignerError::NoDeviceFound => SignerError::NoDeviceFound,
618        SignerError::Protocol(error) => SignerError::Protocol(error.clone()),
619        SignerError::UserCancel(error) => SignerError::UserCancel(error.clone()),
620        SignerError::TooManySigners => SignerError::TooManySigners,
621    }
622}
623
624fn ser_kind(kind: &ClientErrorKind) -> AsClientErrorKindImpl {
625    match kind {
626        ClientErrorKind::Io(error) => {
627            AsClientErrorKindImpl::Io(io::Error::new(error.kind(), error.to_string()))
628        }
629        ClientErrorKind::Reqwest(error) => AsClientErrorKindImpl::Custom(error.to_string()),
630        ClientErrorKind::Middleware(error) => {
631            AsClientErrorKindImpl::Middleware(anyhow!(format!("{:#}", error)))
632        }
633        ClientErrorKind::RpcError(error) => {
634            AsClientErrorKindImpl::RpcError(Box::new(clone_rpc_error(error)))
635        }
636        ClientErrorKind::SerdeJson(error) => AsClientErrorKindImpl::Custom(error.to_string()),
637        ClientErrorKind::SigningError(error) => {
638            AsClientErrorKindImpl::SigningError(clone_signer_error(error))
639        }
640        ClientErrorKind::TransactionError(error) => {
641            AsClientErrorKindImpl::TransactionError(error.clone())
642        }
643        ClientErrorKind::Custom(error) => AsClientErrorKindImpl::Custom(error.clone()),
644    }
645}
646
647fn de_kind(kind: AsClientErrorKindImpl) -> Result<ClientErrorKind, Infallible> {
648    Ok(match kind {
649        AsClientErrorKindImpl::Io(error) => ClientErrorKind::Io(error),
650        AsClientErrorKindImpl::Middleware(error) => ClientErrorKind::Middleware(error),
651        AsClientErrorKindImpl::RpcError(rpc_error) => ClientErrorKind::RpcError(*rpc_error),
652        AsClientErrorKindImpl::SigningError(signer_error) => {
653            ClientErrorKind::SigningError(signer_error)
654        }
655        AsClientErrorKindImpl::TransactionError(transaction_error) => {
656            ClientErrorKind::TransactionError(transaction_error)
657        }
658        AsClientErrorKindImpl::Custom(error) => ClientErrorKind::Custom(error),
659    })
660}
661
662serde_conv!(pub AsClientErrorKind, ClientErrorKind, ser_kind, de_kind);
663
664#[serde_as]
665#[derive(Serialize, Deserialize)]
666pub struct AsClientErrorImpl {
667    #[serde_as(as = "Option<AsRpcRequest>")]
668    pub request: Option<RpcRequest>,
669    #[serde_as(as = "Box<AsClientErrorKind>")]
670    pub kind: Box<ClientErrorKind>,
671}
672
673fn clone_client_error_kind(kind: &ClientErrorKind) -> Box<ClientErrorKind> {
674    Box::new(de_kind(ser_kind(kind)).unwrap())
675}
676
677fn ser_client_error(error: &ClientError) -> AsClientErrorImpl {
678    AsClientErrorImpl {
679        request: error.request,
680        kind: clone_client_error_kind(&error.kind),
681    }
682}
683
684fn de_client_error(error: AsClientErrorImpl) -> Result<ClientError, Infallible> {
685    Ok(ClientError {
686        request: error.request,
687        kind: error.kind,
688    })
689}
690
691serde_conv!(
692    pub AsClientError,
693    ClientError,
694    ser_client_error,
695    de_client_error
696);
697
698#[derive(Serialize, Deserialize)]
699pub enum AsCompileErrorImpl {
700    AccountIndexOverflow,
701    AddressTableLookupIndexOverflow,
702    UnknownInstructionKey(Pubkey),
703}
704
705fn ser_CompileError(error: &CompileError) -> AsCompileErrorImpl {
706    match error {
707        CompileError::AccountIndexOverflow => AsCompileErrorImpl::AccountIndexOverflow,
708        CompileError::AddressTableLookupIndexOverflow => {
709            AsCompileErrorImpl::AddressTableLookupIndexOverflow
710        }
711        CompileError::UnknownInstructionKey(pubkey) => {
712            AsCompileErrorImpl::UnknownInstructionKey(*pubkey)
713        }
714    }
715}
716
717fn de_CompileError(error: AsCompileErrorImpl) -> Result<CompileError, Infallible> {
718    Ok(match error {
719        AsCompileErrorImpl::AccountIndexOverflow => CompileError::AccountIndexOverflow,
720        AsCompileErrorImpl::AddressTableLookupIndexOverflow => {
721            CompileError::AddressTableLookupIndexOverflow
722        }
723        AsCompileErrorImpl::UnknownInstructionKey(pubkey) => {
724            CompileError::UnknownInstructionKey(pubkey)
725        }
726    })
727}
728
729serde_conv!(pub AsCompileError, CompileError, ser_CompileError, de_CompileError);
730
731#[derive(Serialize, Deserialize)]
732pub enum AsSanitizeErrorImpl {
733    IndexOutOfBounds,
734    ValueOutOfBounds,
735    InvalidValue,
736}
737
738fn ser_SanitizeError(error: &SanitizeError) -> AsSanitizeErrorImpl {
739    match error {
740        SanitizeError::IndexOutOfBounds => AsSanitizeErrorImpl::IndexOutOfBounds,
741        SanitizeError::ValueOutOfBounds => AsSanitizeErrorImpl::ValueOutOfBounds,
742        SanitizeError::InvalidValue => AsSanitizeErrorImpl::InvalidValue,
743    }
744}
745
746fn de_SanitizeError(error: AsSanitizeErrorImpl) -> Result<SanitizeError, Infallible> {
747    Ok(match error {
748        AsSanitizeErrorImpl::IndexOutOfBounds => SanitizeError::IndexOutOfBounds,
749        AsSanitizeErrorImpl::ValueOutOfBounds => SanitizeError::ValueOutOfBounds,
750        AsSanitizeErrorImpl::InvalidValue => SanitizeError::InvalidValue,
751    })
752}
753
754serde_conv!(pub AsSanitizeError, SanitizeError, ser_SanitizeError, de_SanitizeError);
755
756#[derive(Serialize, Deserialize)]
757pub enum AsMailboxErrorImpl {
758    Closed,
759    Timeout,
760}
761
762fn ser_MailboxError(error: &MailboxError) -> AsMailboxErrorImpl {
763    match error {
764        MailboxError::Closed => AsMailboxErrorImpl::Closed,
765        MailboxError::Timeout => AsMailboxErrorImpl::Timeout,
766    }
767}
768
769fn de_MailboxError(error: AsMailboxErrorImpl) -> Result<MailboxError, Infallible> {
770    Ok(match error {
771        AsMailboxErrorImpl::Closed => MailboxError::Closed,
772        AsMailboxErrorImpl::Timeout => MailboxError::Timeout,
773    })
774}
775
776serde_conv!(pub AsMailboxError, MailboxError, ser_MailboxError, de_MailboxError);
777
778serde_conv!(pub AsCancelled, Canceled, |_| (), |_: ()| Ok::<_, Infallible>(Canceled));