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
feat: ledger key manager interface #5644
feat: ledger key manager interface #5644
Conversation
Test Results (CI) 3 files 120 suites 34m 16s ⏱️ Results for commit 85d8b85. ♻️ This comment has been updated with latest results. |
Test Results (Integration tests) 2 files 11 suites 41m 12s ⏱️ For more details on these failures, see this check. Results for commit 85d8b85. ♻️ This comment has been updated with latest results. |
This PR was previously tracked on #5609 but stopped updating when new commits were pushed. This is the same PR but updated against development and with fixes in the test suite which is now green. |
I added a fix for the failing cucumber test - see #5645 |
chrono = { version = "0.4.19", default-features = false } | ||
clap = { version = "3.2", features = ["derive", "env"] } | ||
config = "0.13.0" | ||
crossterm = { version = "0.25.0" } | ||
digest = "0.10" | ||
futures = { version = "^0.3.16", default-features = false, features = ["alloc"] } | ||
log4rs = { git = "https://github.com/tari-project/log4rs.git", default_features = false, features = ["config_parsing", "threshold_filter", "yaml_format", "console_appender", "rolling_file_appender", "compound_policy", "size_trigger", "fixed_window_roller", "delete_roller"] } | ||
ledger-transport-hid = { git = "https://github.com/Zondax/ledger-rs" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lock to a commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @brianp, I can appreciate that this was a lot of work, however, I am not a fan of this approach.
In this PR we create a lot of scaffolding just to be able to create a ledger-specific or software-specific transaction key manager. My recommendations:
-
Initial startup
- Add a command line switch to force the use of the ledger hardware wallet - if the ledger is not attached and the app not started panic with the error message - if attached and app started ok.
- If the ledger is attached but the wallet is started without the switch, ask the user if this should be a hardware console wallet, if yes follow the logic as if the command line switch was present.
When started ok, earmark the console wallet as a ledger-only console wallet - consecutive startups without the ledger attached and the app started must panic.
-
Key manager
- We should not differentiate outside of the key manager if we have a ledger or not, so no
ledger_key_manager
. - The key manager should be aware if a hardware wallet should be used and if it is a ledger and later on perhaps a trezor if that is added.
- Inside the key manager whenever we have to use a secret key, for example inside
inner/get_receiver_partial_metadata_signature(..)
, the appropriate software or hardware branch is called. There are not that many places where this branching will be necessary. All ledger-specific code can go intokey_manager/ledger.rs
, and later on we can addkey_manager/trezor.rs
.
- We should not differentiate outside of the key manager if we have a ledger or not, so no
-
Private keys to be managed
Both spend and script private keys should be managed by the ledger, but with the difference that the spend private key should be returned from the ledger to be used inside the key manager where needed and the script private key should never leave the ledger.This will mean that range-proof bulletproofs can be constructed outside the ledger but not without it, and script signatures will be wholly constructed inside the ledger.- The same index must be used to obtain the matching set of
spend and scriptprivate keys, as is currently the case with the software key manager.
-
Spending scriptsIf both spend and script private keys are managed by the ledger, a hardware wallet will be able to receive an interactive transaction with any type of script, and will not be able to be sussed out as a hardware wallet by penny/poking transactions.
The ledger implementation very much follows this RFC: tari-project/rfcs#98 As per the RFC, this allows us to receive transactions without the hardware wallet being online, allowing it to be a cold storage wallet. |
46329dc
to
4b254d1
Compare
eacace9
to
41934fb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK - scripts/install_ubuntu_dependencies.sh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice so far, just one comment for now, apart form the CI/clippy errors.
Ok(_) => { | ||
println!("Device found."); | ||
let account = prompt_ledger_account().expect("An account value"); | ||
Some(WalletType::Ledger(account)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The TRANSPORT
lazy static should be assigned a value
Ok(_) => { | |
println!("Device found."); | |
let account = prompt_ledger_account().expect("An account value"); | |
Some(WalletType::Ledger(account)) | |
Ok(transport) => { | |
*TRANSPORT.lock().expect("lock exists") = Some(transport); | |
println!("Device found."); | |
let account = prompt_ledger_account().expect("An account value"); | |
Some(WalletType::Ledger(account)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This actually sent me on a wild goose chase trying to find where the code had previously been removed.
But, we don't actually need to assign this here. We check to make sure the ledger is present to see if we should create a ledger backed wallet. But the ledger could be unplugged anytime between this prompt, and performing a transaction. It doesn't need to be plugged in at all times. We need to check to see if it's present again, only during script and meta data sig generation for send transactions.
ac183a1
to
2618697
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK
@@ -429,6 +443,40 @@ where TBackend: KeyManagerBackend<PublicKey> + 'static | |||
// Transaction input section (transactions > transaction_components > transaction_input) | |||
// ----------------------------------------------------------------------------------------------------------------- | |||
|
|||
pub async fn get_script_private_key(&self, script_key_id: &TariKeyId) -> Result<PrivateKey, TransactionError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for now, but in the actual implementation we should ver get this script key out of the ledger, we should ask the ledger to sign the script signature for us and we should get that out
c5e5a9f
to
29efb44
Compare
29efb44
to
b2c5030
Compare
50a5805
to
85d8b85
Compare
Description
This PR expands the console wallet and key manager interfaces to support hardware wallets. It does not introduce functionality to communicate with the hardware wallet, simply the interface to support it. Another PR will be opened swapping out the placeholder software key manager for the hardware key manager where appropriate.
Motivation and Context
So people can use their most excellent hardware wallets with the MinoTari console wallet.
How Has This Been Tested?
Manually on osx
What process can a PR reviewer use to test or verify this change?
Breaking Changes