Conversation
ecf51c0 to
abe8a88
Compare
59bd742 to
9099e90
Compare
abe8a88 to
89285d1
Compare
5f20a4f to
4c64407
Compare
ImplOfAnImpl
left a comment
There was a problem hiding this comment.
I haven't dug into the code much yet, will continue next week.
Tests assume the ledger app repo is cloned next to this one with name ledger-mintlayer
To be honest, I'm not a huge fan of this approach. And also of the fact that the emulator is always started automatically. E.g. in the Trezor case it was sometimes useful to see the emulator logs to understand what went wrong.
Was there any particular reason to do it this way instead of expecting the emuator to be running?
f21e82b to
75ff652
Compare
61292c5 to
eeb6484
Compare
75ff652 to
96016cf
Compare
5d3edf0 to
d6fd484
Compare
39d3e58 to
d6fd484
Compare
| pub async fn get_app_name<L: Exchange>(ledger: &mut L) -> Result<Vec<u8>, ledger_lib::Error> { | ||
| let msg_buf = [CLA, Ins::APP_NAME, 0, P2::DONE]; | ||
| ledger.exchange(&msg_buf, Duration::from_millis(100)).await | ||
| } | ||
|
|
||
| #[allow(dead_code)] | ||
| pub async fn check_current_app<L: Exchange>(ledger: &mut L) -> SignerResult<()> { | ||
| let resp = get_app_name(ledger) | ||
| .await | ||
| .map_err(|err| LedgerError::DeviceError(err.to_string()))?; |
There was a problem hiding this comment.
I don't think it's a good way to check for our app, because the INS values are app-specific.
There is a standard way to obtain the app name via CLA=0xB0 and INS=1. E.g. here it's handled by the SDK on the device - https://github.com/LedgerHQ/ledger-device-rust-sdk/blob/4262899a325b9b2fe10f2524d8e4b2f9fec38b83/ledger_device_sdk/src/io_legacy.rs#L330-L331
(The INS is processed inside the handle_bolos_apdu function).
Also, ledger-proto contains something called AppInfoReq which mentions CLA 0xB0 and INS 1, so I guess you don't have to construct the APDU by hand and parse the request.
There was a problem hiding this comment.
For some reason it always returns "app" for app name and the OS version instead of the opened app. So, I kept our own instructions.
There was a problem hiding this comment.
For some reason it always returns "app" for app name and the OS version instead of the opened app. So, I kept our own instructions.
Well, I tried sending [b0, 1, 0, 0] to my NanoSPlus and got "Mintlayer"/"0.1.0" for our app and "Ethereum"/"1.18.0" for Ethereum.
What device are you using? Can you double check?
In any case, this has to be investigated further. If b0/01 doesn't work indeed, we must at least document that fact, mentioning the particular situations.
There was a problem hiding this comment.
For some reason it always returns "app"
So I suppose you were using the emulator, for which this is documented behavior.
In such a case IMO it's better to detect if we're using an emulator (or I guess we could assume that any tcp transport corresponds to an emulator) and skip the app name/version check in that case.
Alternatively, we could go with with a custom APDU. But in this case it has to be handled more carefully. E.g. a) expect that the whole APDU may fail, e.g. with ClaNotSupported or InsNotSupported (because the current app doesn't support it), or with something like WrongP1P2/WrongApduLength (because in the current app this APDU means something else and has different parameters); b) expect that APDU may be handled successfully, but the result is garbage (again, because in the current app this APDU means something else).
The first approach looks easier to implement.
d6fd484 to
2d5300b
Compare
| Finish, | ||
| } | ||
|
|
||
| async fn auto_confirmer(mut control_msg_rx: mpsc::Receiver<ControlMessage>, handle: PodmanHandle) { |
There was a problem hiding this comment.
-
Let's have a way to disable the auto-confirmer, to be able to see what the tests are really doing. E.g. for trezor we have the TREZOR_TESTS_AUTO_CONFIRM env var, so we can also have LEDGER_TESTS_AUTO_CONFIRM.
-
If you disable auto-confirmation (I did it by commenting out the "handle.button" calls below), you'll notice that when running e.g.
test_fixed_signatures2::case_1, you have to click the right button 19 times while the device is showing "Review transaction" without any indication that something is happening. I guess it's when the transaction data is being sent in chunks. But in any case, just sending data shouldn't require the user to perform clicks, clicking should only be needed to go to another screen., -
At some point during signing, a message is shown "Press right button to continue message or press both to skip". If both buttons are pressed, it goes straight to "Sign transaction", if the right one is pressed, it also shows a few extra screens related to fees. So:
a) Is this something our app controls? If so, IMO it's better to disable it and always show all the screens.
b) Otherwise we're testing only one of the possible successful flows, which is not great. I guess in such a case we shouldn't just click arbitrary and instead have a list of button clicks that must be performed for each test and also a way to check what is currently shown on the screen (e.g. in the simplest case it could be a list of pairs ("regex that checks the expected contents of the current screen", "button click to go to the next screen")). Though this approach seems to be the correct one, as it'll also allow us to have negative tests, where the operation is aborted by the user (and ideally we should do the same for Trezor tests), it'll probably be hard to implement, so I'd go with the option a) for now, if possible.
| msg_buf.extend([APDU_CLASS, ins, p1, p2]); | ||
| msg_buf.push(chunk.len() as u8); | ||
| msg_buf.extend(chunk); | ||
| resp = exchange_message(ledger, &msg_buf).await?; |
There was a problem hiding this comment.
Again, let's not ignore intermediate results. If they are supposed to be empty vecs, let's do sanity checks on that.
4f56961 to
132141f
Compare
50d5293 to
a7d86d1
Compare
ImplOfAnImpl
left a comment
There was a problem hiding this comment.
Seems to be fine (except for a few comments), but I'd like to take another look after I return from my vacation.
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: mintlayer/mintlayer-ledger-app | ||
| ref: feature/mintlayer-app |
There was a problem hiding this comment.
Plz don't forget to update this
e4b8812 to
74954ab
Compare
ImplOfAnImpl
left a comment
There was a problem hiding this comment.
I don't want to review this again, so I suggest merging it after applying the comments. The ledger tests will have to be disabled on CI, but it's better to enable the code itself, to make sure it compiles.
Plz make sure that all the comments have been addressed before merging
wallet/src/wallet/mod.rs
Outdated
| #[cfg(feature = "trezor")] | ||
| (WalletType::Ledger, WalletType::Ledger) => {} |
| ChainType::Signet => CoinType::Regtest, | ||
| ChainType::Regtest => CoinType::Signet, |
common/src/primitives_converters.rs
Outdated
| fn try_convert_from(value: VRFPublicKey) -> Result<Self, PrimitivesConvertersError> { | ||
| match value.kind() { | ||
| VRFKeyKind::Schnorrkel => { | ||
| let key: SchnorrkelPublicKey = value.try_into().unwrap(); |
There was a problem hiding this comment.
Return an error instead of unwrapping
common/src/primitives_converters.rs
Outdated
| fn try_convert_from(value: PublicKey) -> Result<Self, PrimitivesConvertersError> { | ||
| match value.kind() { | ||
| KeyKind::Secp256k1Schnorr => { | ||
| let key: Secp256k1PublicKey = value.try_into().unwrap(); |
There was a problem hiding this comment.
Return an error instead of unwrapping
|
|
||
| - name: Update local dependency repositories | ||
| run: sudo apt-get update |
There was a problem hiding this comment.
"Update the list of available system packages"
| #[error("The file being loaded is a software wallet and does not correspond to the connected hardware wallet")] | ||
| HardwareWalletDifferentFile, | ||
| #[error("The file being loaded is a Ledger wallet and cannot be used with the connected Trezor wallet")] | ||
| LedgerWalletDifferentFile, |
There was a problem hiding this comment.
WalletFileIsLedgerWallet ?
| #[error("Duplicate UTXO input: {0:?}")] | ||
| DuplicateUtxoInput(UtxoOutPoint), | ||
| #[error("Wallet not initialized")] | ||
| WalletNotInitialized, |
There was a problem hiding this comment.
Use this error in the trezor signer too, instead of WalletError::WalletNotInitialized?
Or vice versa. Why the inconsistency?
wallet/types/src/hw_data.rs
Outdated
| Stax, | ||
| Flex, | ||
| NanoGen5, | ||
| Unknown(u16), |
There was a problem hiding this comment.
This u16 is usb-specific, it's better to make it an optional named field usb_pid, same as is rust-ledger
| @@ -72,6 +72,11 @@ pub enum WalletExtraInfo { | |||
| // Note: semver::Version is not serializable, so we can't use it here. | |||
There was a problem hiding this comment.
Plz move this comment out of the TrezorWallet variant, as it applies to LedgerWallet too
| #[cfg(feature = "trezor")] | ||
| Self::Ledger => WalletType::Ledger, |
|
Forgot to mention: I wasn't able to open a ledger wallet in wallet-cli via the |
74954ab to
65d813c
Compare
Tests assume the ledger app is already running in the emulator same as Trezor tests