Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand OperationFailure::Other error #1719

Merged
merged 13 commits into from
Mar 20, 2023
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
- Maker/taker pubkeys were added to new columns in `stats_swaps` table in [#1665](https://github.com/KomodoPlatform/atomicDEX-API/pull/1665)
- Get rid of unnecessary / old dependencies: `crossterm`, `crossterm_winapi`, `mio 0.7.13`, `miow`, `ntapi`, `signal-hook`, `signal-hook-mio` in [#1710](https://github.com/KomodoPlatform/atomicDEX-API/pull/1710)
- A bug that caused EVM swap payments validation to fail because the tx was not available yet in the RPC node when calling `eth_getTransactionByHash` was fixed in [#1716](https://github.com/KomodoPlatform/atomicDEX-API/pull/1716). `eth_getTransactionByHash` in now retried in `wait_for_confirmations` until tx is found in the RPC node, this makes sure that the transaction is returned from `eth_getTransactionByHash` later when validating.
- `OperationFailure::Other` error was expanded. New error variants were matched with `HwRpcError`, so error type will be `HwError`, not `InternalError` [#1719](https://github.com/KomodoPlatform/atomicDEX-API/pull/1719)


## v1.0.0-beta - 2023-03-08
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,23 @@ impl InitUtxoStandardError {
HwError::CannotChooseDevice { .. } => InitUtxoStandardError::HwError(HwRpcError::FoundMultipleDevices),
HwError::ConnectionTimedOut { timeout } => InitUtxoStandardError::TaskTimedOut { duration: timeout },
HwError::FoundUnexpectedDevice => InitUtxoStandardError::HwError(HwRpcError::FoundUnexpectedDevice),
HwError::Failure(error) => InitUtxoStandardError::CoinCreationError { ticker, error },
HwError::InvalidPin
| HwError::UnexpectedMessage
| HwError::ButtonExpected
| HwError::DataError
| HwError::PinExpected
| HwError::InvalidSignature
| HwError::ProcessError
| HwError::NotEnoughFunds
| HwError::NotInitialized
| HwError::WipeCodeMismatch
| HwError::InvalidSession
| HwError::FirmwareError
| HwError::FailureMessageNotFound
| HwError::UserCancelled => InitUtxoStandardError::CoinCreationError {
ticker,
error: hw_error.to_string(),
},
other => InitUtxoStandardError::Internal(other.to_string()),
}
}
Expand Down
79 changes: 75 additions & 4 deletions mm2src/crypto/src/hw_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use hw_common::primitives::Bip32Error;
use mm2_err_handle::prelude::*;
use serde::Serialize;
use std::time::Duration;
use trezor::{TrezorError, TrezorUserInteraction};
use trezor::{OperationFailure, TrezorError, TrezorUserInteraction};

pub type HwResult<T> = Result<T, MmError<HwError>>;

Expand All @@ -28,11 +28,25 @@ pub enum HwError {
},
#[display(fmt = "Invalid xpub received from a device: '{}'", _0)]
InvalidXpub(String),
Failure(String),
UnderlyingError(String),
ProtocolError(String),
UnexpectedUserInteractionRequest(TrezorUserInteraction),
Internal(String),
InvalidPin,
UnexpectedMessage,
ButtonExpected,
DataError,
PinExpected,
InvalidSignature,
ProcessError,
NotEnoughFunds,
NotInitialized,
WipeCodeMismatch,
InvalidSession,
FirmwareError,
FailureMessageNotFound,
UserCancelled,
PongMessageMismatch,
}

impl From<TrezorError> for HwError {
Expand All @@ -44,10 +58,25 @@ impl From<TrezorError> for HwError {
TrezorError::DeviceDisconnected => HwError::DeviceDisconnected,
TrezorError::UnderlyingError(_) => HwError::UnderlyingError(error),
TrezorError::ProtocolError(_) | TrezorError::UnexpectedMessageType(_) => HwError::Internal(error),
// TODO handle the failure correctly later
TrezorError::Failure(_) => HwError::Failure(error),
TrezorError::Failure(failure) => match failure {
OperationFailure::InvalidPin => HwError::InvalidPin,
OperationFailure::UnexpectedMessage => HwError::UnexpectedMessage,
OperationFailure::ButtonExpected => HwError::ButtonExpected,
OperationFailure::DataError => HwError::DataError,
OperationFailure::PinExpected => HwError::PinExpected,
OperationFailure::InvalidSignature => HwError::InvalidSignature,
OperationFailure::ProcessError => HwError::ProcessError,
OperationFailure::NotEnoughFunds => HwError::NotEnoughFunds,
OperationFailure::NotInitialized => HwError::NotInitialized,
OperationFailure::WipeCodeMismatch => HwError::WipeCodeMismatch,
OperationFailure::InvalidSession => HwError::InvalidSession,
OperationFailure::FirmwareError => HwError::FirmwareError,
OperationFailure::FailureMessageNotFound => HwError::FailureMessageNotFound,
OperationFailure::UserCancelled => HwError::UserCancelled,
},
TrezorError::UnexpectedInteractionRequest(req) => HwError::UnexpectedUserInteractionRequest(req),
TrezorError::Internal(_) => HwError::Internal(error),
TrezorError::PongMessageMismatch => HwError::PongMessageMismatch,
}
}
}
Expand All @@ -69,6 +98,34 @@ pub enum HwRpcError {
FoundMultipleDevices,
#[display(fmt = "Found unexpected device. Please re-initialize Hardware wallet")]
FoundUnexpectedDevice,
#[display(fmt = "Pin is invalid")]
InvalidPin,
#[display(fmt = "Unexpected message")]
UnexpectedMessage,
#[display(fmt = "Button expected")]
ButtonExpected,
#[display(fmt = "Got data error")]
DataError,
#[display(fmt = "Pin expected")]
PinExpected,
#[display(fmt = "Invalid signature")]
InvalidSignature,
#[display(fmt = "Got process error")]
ProcessError,
#[display(fmt = "Not enough funds")]
NotEnoughFunds,
#[display(fmt = "Not initialized")]
NotInitialized,
#[display(fmt = "Wipe code mismatch")]
WipeCodeMismatch,
#[display(fmt = "Invalid session")]
InvalidSession,
#[display(fmt = "Got firmware error")]
FirmwareError,
#[display(fmt = "Failure message not found")]
FailureMessageNotFound,
#[display(fmt = "User cancelled action")]
UserCancelled,
}

/// The trait is implemented for those error enumerations that have `HwRpcError` variant.
Expand All @@ -90,6 +147,20 @@ where
HwError::CannotChooseDevice { .. } => T::hw_rpc_error(HwRpcError::FoundMultipleDevices),
HwError::ConnectionTimedOut { timeout } => T::timeout(timeout),
HwError::FoundUnexpectedDevice => T::hw_rpc_error(HwRpcError::FoundUnexpectedDevice),
HwError::InvalidPin => T::hw_rpc_error(HwRpcError::InvalidPin),
HwError::UnexpectedMessage => T::hw_rpc_error(HwRpcError::UnexpectedMessage),
HwError::ButtonExpected => T::hw_rpc_error(HwRpcError::ButtonExpected),
HwError::DataError => T::hw_rpc_error(HwRpcError::DataError),
HwError::PinExpected => T::hw_rpc_error(HwRpcError::PinExpected),
HwError::InvalidSignature => T::hw_rpc_error(HwRpcError::InvalidSignature),
HwError::ProcessError => T::hw_rpc_error(HwRpcError::ProcessError),
HwError::NotEnoughFunds => T::hw_rpc_error(HwRpcError::NotEnoughFunds),
HwError::NotInitialized => T::hw_rpc_error(HwRpcError::NotInitialized),
HwError::WipeCodeMismatch => T::hw_rpc_error(HwRpcError::WipeCodeMismatch),
HwError::InvalidSession => T::hw_rpc_error(HwRpcError::InvalidSession),
HwError::FirmwareError => T::hw_rpc_error(HwRpcError::FirmwareError),
HwError::FailureMessageNotFound => T::hw_rpc_error(HwRpcError::FailureMessageNotFound),
HwError::UserCancelled => T::hw_rpc_error(HwRpcError::UserCancelled),
other => T::internal(other.to_string()),
}
}
5 changes: 2 additions & 3 deletions mm2src/trezor/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,10 @@ impl<'a> TrezorSession<'a> {
};

let result_handler = ResultHandler::<()>::new(move |pong: proto_common::Success| {
if pong.message == Some(ping_message.clone()) {
if pong.message == Some(ping_message) {
Ok(())
} else {
let error = format!("Expected '{ping_message}' PONG message, found: {:?}", pong.message);
MmError::err(TrezorError::Failure(OperationFailure::Other(error)))
MmError::err(TrezorError::PongMessageMismatch)
shamardy marked this conversation as resolved.
Show resolved Hide resolved
}
});
self.call(req, result_handler).await
Expand Down
39 changes: 30 additions & 9 deletions mm2src/trezor/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,25 @@ pub enum TrezorError {
#[display(fmt = "Unexpected interaction request: {:?}", _0)]
UnexpectedInteractionRequest(TrezorUserInteraction),
Internal(String),
PongMessageMismatch,
}

#[derive(Debug, Display)]
#[derive(Clone, Debug, Display)]
pub enum OperationFailure {
InvalidPin,
/// TODO expand it to other types.
#[display(fmt = "Operation failed due to unknown reason: {}", _0)]
Other(String),
UnexpectedMessage,
ButtonExpected,
DataError,
PinExpected,
InvalidSignature,
ProcessError,
NotEnoughFunds,
NotInitialized,
WipeCodeMismatch,
InvalidSession,
FirmwareError,
FailureMessageNotFound,
UserCancelled,
}

impl From<Failure> for OperationFailure {
Expand All @@ -48,15 +59,25 @@ impl From<Failure> for OperationFailure {
Some(FailureType::FailurePinInvalid) | Some(FailureType::FailurePinMismatch) => {
OperationFailure::InvalidPin
},
_ => OperationFailure::Other(format!("{:?}", failure)),
Some(FailureType::FailureActionCancelled) | Some(FailureType::FailurePinCancelled) => {
OperationFailure::UserCancelled
},
Some(FailureType::FailureUnexpectedMessage) => OperationFailure::UnexpectedMessage,
Some(FailureType::FailureButtonExpected) => OperationFailure::ButtonExpected,
Some(FailureType::FailureDataError) => OperationFailure::DataError,
Some(FailureType::FailurePinExpected) => OperationFailure::PinExpected,
Some(FailureType::FailureInvalidSignature) => OperationFailure::InvalidSignature,
Some(FailureType::FailureProcessError) => OperationFailure::ProcessError,
Some(FailureType::FailureNotEnoughFunds) => OperationFailure::NotEnoughFunds,
Some(FailureType::FailureNotInitialized) => OperationFailure::NotInitialized,
Some(FailureType::FailureWipeCodeMismatch) => OperationFailure::WipeCodeMismatch,
Some(FailureType::FailureInvalidSession) => OperationFailure::InvalidSession,
Some(FailureType::FailureFirmwareError) => OperationFailure::FirmwareError,
None => OperationFailure::FailureMessageNotFound,
}
}
}

impl From<OperationFailure> for TrezorError {
fn from(failure: OperationFailure) -> Self { TrezorError::Failure(failure) }
}

impl From<DecodeError> for TrezorError {
fn from(e: DecodeError) -> Self { TrezorError::ProtocolError(e.to_string()) }
}
Expand Down