Feature/trezor reconnect#1874
Conversation
4f6708d to
e0f00b5
Compare
69592f8 to
f16c3e3
Compare
8a33777 to
f8578ef
Compare
| Err(trezor_client::Error::TransportSendMessage( | ||
| trezor_client::transport::error::Error::Usb(rusb::Error::Io), | ||
| )) => { | ||
| let (mut new_client, data) = find_trezor_device()?; |
There was a problem hiding this comment.
Calling find_trezor_device on each operation is not a great idea. What if another device is returned?
There was a problem hiding this comment.
we check the public keys again, and if it is a different device we error out.
There was a problem hiding this comment.
we check the public keys again, and if it is a different device we error out.
I understand this, the point was that it looks conceptually wrong.
Currently, the question is why do we need it if you already call init_device every time. Can't it recover the session after a usb error?
And even if it can't, calling find_trezor_device still seems wrong. Perhaps then you should split find_trezor_device into 2 functions - the "find" part and the "connect" part, so that the former is still called only once.
There was a problem hiding this comment.
Perhaps then you should split find_trezor_device into 2 functions - the "find" part and the "connect" part, so that the former is still called only once.
I guess having a separate "connect" part won't be possible, because AvailableDevice is non-copyable. So we'll have to stick to calling find_trezor_device again.
There was a problem hiding this comment.
Currently, the question is why do we need it if you already call init_device every time. Can't it recover the session after a usb error?
Mainly for the case if the USB device disconnects for whatever reason.
| Err(trezor_client::Error::TransportSendMessage( | ||
| trezor_client::transport::error::Error::Usb(rusb::Error::Io), | ||
| )) => { |
There was a problem hiding this comment.
IMO instead of calling the operation and then checking for error we should just unconditionally call Trezor::initialize, passing to it the previosly obtained session_id (it's inside features). At least this is recommended in the docs.
There was a problem hiding this comment.
added an init_device(session_id) call which internally calls initialize before each operation.
82b71a8 to
c9c1c91
Compare
f8578ef to
c9c1c91
Compare
2df0787 to
cf6ce8c
Compare
48716c3 to
67609d5
Compare
cf6ce8c to
66a4f17
Compare
67609d5 to
220ace1
Compare
0401329 to
001afc6
Compare
ImplOfAnImpl
left a comment
There was a problem hiding this comment.
This PR is incomplete without changes to trezor_signer from #1895
I suggest moving those changes here (I mean the parts that are relevant for the "automatic" device selection), so that they can be reviewed together.
| fn find_trezor_device() -> Result<(Trezor, TrezorData, Vec<u8>), TrezorError> { | ||
| let mut devices = find_devices(false) | ||
| .into_iter() | ||
| .filter(|device| device.model == Model::Trezor || device.model == Model::TrezorEmulator) |
There was a problem hiding this comment.
So, what about TrezorLegacy aka Model One?
So, why don't we allow TrezorLegacy here?
There was a problem hiding this comment.
Added but I don't think it is supported, when I run the emulator it doesn't list the Mintlayer compatibility so it will alwasy be filtered out in the next step.
| Ok(_) => Ok(()), | ||
| // In case of a USB IO error try to reconnect, and try again | ||
| Err(trezor_client::Error::TransportSendMessage( | ||
| trezor_client::transport::error::Error::Usb(rusb::Error::Io), |
There was a problem hiding this comment.
I tried disconnecting the device physically and re-connecting it and the error I got here after that was rusb::Error::NoDevice.
So, it should be handled here as well.
I wonder if the error is device-dependent though (I use Safe 3).
Perhaps we should just catch all trezor_client::transport::error::Error::Usb errors here?
P.S. plz also update comments - you currently mention "I/O error" everywhere.
There was a problem hiding this comment.
Added matching on all USB errors
| Err(trezor_client::Error::TransportSendMessage( | ||
| trezor_client::transport::error::Error::Usb(rusb::Error::Io), | ||
| )) => { | ||
| let (mut new_client, data) = find_trezor_device()?; |
There was a problem hiding this comment.
Perhaps then you should split find_trezor_device into 2 functions - the "find" part and the "connect" part, so that the former is still called only once.
I guess having a separate "connect" part won't be possible, because AvailableDevice is non-copyable. So we'll have to stick to calling find_trezor_device again.
09952ef to
bc2d7f8
Compare
| if let Some(devices) = response.multiple_devices_available { | ||
| match devices { | ||
| wallet_rpc_lib::types::MultipleDevicesAvailable::Trezor { devices } => { | ||
| let choices = CreateWalletDeviceSelectMenu::new( | ||
| devices, | ||
| wallet_path, | ||
| CliHardwareWalletType::Trezor, | ||
| true, | ||
| ); | ||
| return Ok(ConsoleCommand::ChoiceMenu(Box::new(choices))); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
I wonder whether we should do the same on OpenWallet. The scenario is that the user resets their device, changing its device id. And then connects this device and another one and tries opening a previously created wallet. Currently this will fail with "multiple connected Trezor devices found".
The scenario is not very probable, but it makes sense to support it at least for completeness.
P.S. but if you do it, plz write a comment explaining why we do such things on OpenWallet, because it'll look non-obvious.
0ad3d75 to
e8d0ed6
Compare
| /// Optionally specify the ID for the trezor device to connect to in case there | ||
| /// are multiple trezor devices connected at the same time. | ||
| /// If not specified and there are multiple devices connected a choice will be presented | ||
| #[arg(long, conflicts_with_all(["mnemonic", "passphrase", "whether_to_store_seed_phrase"]))] |
There was a problem hiding this comment.
it should require hardware_wallet
| /// are multiple trezor devices connected at the same time. | ||
| /// If not specified and there are multiple devices connected a choice will be presented | ||
| #[arg(long, conflicts_with_all(["mnemonic", "passphrase", "whether_to_store_seed_phrase"]))] | ||
| trezor_device_id: Option<String>, |
There was a problem hiding this comment.
it seems like this string should be either device_id or included into HardwareWalletType::Trezor. Otherwise what happens when we add new wallet type?
e8d0ed6 to
844ee5b
Compare
844ee5b to
37def6a
Compare
If the trezor device returns an USB IO error it might mean that the trezor device has been disconnected, in that case try to reconnect to the device and try the failed operation again.