Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
82 changes: 78 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,36 @@ 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,
#[display(fmt = "PONG message mismatch after ping")]
PongMessageMismatch,
}

/// The trait is implemented for those error enumerations that have `HwRpcError` variant.
Expand All @@ -90,6 +149,21 @@ 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),
HwError::PongMessageMismatch => T::hw_rpc_error(HwRpcError::PongMessageMismatch),
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)
Comment thread
shamardy marked this conversation as 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