-
Notifications
You must be signed in to change notification settings - Fork 24
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
Refactor/wallet generic signer #1783
base: master
Are you sure you want to change the base?
Conversation
OBorce
commented
Jun 18, 2024
•
edited
Loading
edited
- add a generic signer provider for creating a software or a hardware signer
- make account key chain generic to allow using it with and without a VRF keychain
- add an implementation for the trezor signer
- copy auto generated trezor client to communicate with a connected trezor device
- add new hardware-wallet option when creating and opening a wallet in the CLI and RPC wallet commands
e1f4596
to
37b71b9
Compare
5ea96b9
to
b031a27
Compare
293c300
to
cfd9fe9
Compare
a99614e
to
626b7d1
Compare
626b7d1
to
fb2af0d
Compare
@@ -144,33 +153,44 @@ pub struct ControllerConfig { | |||
pub broadcast_to_mempool: bool, | |||
} | |||
|
|||
pub struct Controller<T, W> { | |||
pub enum WalletType2<B: storage::Backend + 'static> { |
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.
find a better name
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.
Not sure if it's a good idea, but: the existing Wallet
could become GenericWallet
and then WalletType2
can be just Wallet
.
signature_hash(sig.sighash_type(), ptx.tx(), &inputs_utxo_refs, i)?; | ||
|
||
if sig | ||
.verify_signature(&self.chain_config, destination, &sighash) |
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.
tx_verifier::input_check::signature_only_check::verify_tx_signature
should be used to verify htlc properly
726bb45
to
855cfce
Compare
@@ -267,7 +267,7 @@ def check_local_licenses(): | |||
template = re.compile('(?:' + r')\n(?:'.join(LICENSE_TEMPLATE) + ')') | |||
|
|||
ok = True | |||
for path in rs_sources(): | |||
for path in rs_sources(['wallet/trezor-client']): |
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.
remove?
@@ -200,6 +200,18 @@ impl Secp256k1ExtendedPublicKey { | |||
.into(), | |||
} | |||
} | |||
|
|||
pub fn from_hardware_wallet( |
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.
new
? information about hardware seems unnecessary at this level
@@ -122,6 +122,12 @@ impl ExtendedPublicKey { | |||
} | |||
} | |||
|
|||
pub fn from_hardware_public_key(public_key: Secp256k1ExtendedPublicKey) -> Self { |
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.
same
} | ||
#[cfg(feature = "trezor")] | ||
(WalletType::Trezor, _) => { | ||
let client = make_cold_wallet_rpc_client(Arc::clone(&self.chain_config)); |
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.
why cold mode? I thought that's the whole point that hardware wallet is both convenient and secure.
@@ -287,3 +287,6 @@ opt-level = 2 | |||
[profile.dist] | |||
inherits = "release" | |||
lto = "off" | |||
|
|||
[features] | |||
trezor = [] |
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.
I think it should be enabled in CI
|
||
fn make_signature( | ||
&self, | ||
signature: &Vec<MintlayerSignature>, |
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.
&[MintlayerSignature]
?
@@ -25,6 +25,8 @@ utils-networking = { path = "../utils/networking" } | |||
utxo = { path = "../utxo" } | |||
wallet-storage = { path = "./storage" } | |||
wallet-types = { path = "./types" } | |||
trezor-client = { git = "https://github.com/mintlayer/mintlayer-trezor-firmware", branch = "feature/mintlayer", features = ["bitcoin", "mintlayer"], optional = true } | |||
# trezor-client = { path = "../../trezor-firmware/rust/trezor-client", features = ["bitcoin", "mintlayer"], optional = true } |
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.
remove?
@@ -387,3 +387,10 @@ impl YesNo { | |||
} | |||
} | |||
} | |||
|
|||
#[derive(Debug, Clone, Copy, ValueEnum)] | |||
pub enum CLIHardwareWalletType { |
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.
CLI -> Cli?
|
||
use crate::{errors::WalletCliCommandError, ManageableWalletCommand, WalletManagementCommand}; | ||
// #[cfg(feature = "trezor")] | ||
// use crate::helper_types::CLIHardwareWalletType; |
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.
Remove?
match &self.wallet { | ||
WalletType2::Software(w) => w.seed_phrase(), | ||
#[cfg(feature = "trezor")] | ||
WalletType2::Trezor(w) => w.seed_phrase(), | ||
} |
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.
These match statements pollute the code; also, some of them are duplicated.
Perhaps it's better to encapsulate all of them inside impl WalletType2
?
P.S. Personally, I'd probably try to use https://github.com/kobzol/rust-delegate
for this. Not insisting on this, of course.
@@ -144,33 +153,44 @@ pub struct ControllerConfig { | |||
pub broadcast_to_mempool: bool, | |||
} | |||
|
|||
pub struct Controller<T, W> { | |||
pub enum WalletType2<B: storage::Backend + 'static> { |
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.
Not sure if it's a good idea, but: the existing Wallet
could become GenericWallet
and then WalletType2
can be just Wallet
.
3b2c77a
to
1cd8110
Compare
- it will rescan the blokchain on wallet creation - wallet-create will only scan forward from the current block height
1cd8110
to
c23f38d
Compare
MintlayerUnmintTokens, MintlayerUtxoType, | ||
}, | ||
}; | ||
#[allow(clippy::all)] |
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.
why is it required?
SignatureStatus::FullySigned, | ||
SignatureStatus::FullySigned, | ||
)), | ||
InputWitness::Standard(sig) => match destination { |
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.
we need a TODO and a github issue (so we won't forget) to support HTLC signing after my pr is merged
| TxOutput::Htlc(value, _) | ||
| TxOutput::LockThenTransfer(value, _, _) | ||
| TxOutput::Burn(value) => value.clone(), | ||
TxOutput::DelegateStaking(amount, _) => OutputValue::Coin(*amount), |
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.
Name of the function is too vague. Something like utxo_output_value
is better. This would make it clear why DelegateStaking
and Burn
which are not spendable should return None here (same as others instead of ZERO).
let db = Arc::new(Store::new(DefaultBackend::new_in_memory()).unwrap()); | ||
let mut db_tx = db.transaction_rw_unlocked(None).unwrap(); | ||
|
||
let master_key_chain = MasterKeyChain::new_from_mnemonic( |
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.
- why mnemonic?
- I don't fully understand how it's tested, this is run manually right? It looks like possible to run emulator with cli and automate this. Let's maybe discuss it because I'm afraid such functionality is not tested enough
|
||
fn find_trezor_device() -> Result<Trezor, TrezorError> { | ||
let mut devices = find_devices(false); | ||
let device = devices.pop().ok_or(TrezorError::NoDeviceFound)?; |
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.
should we filter for Model::Trezor
only?
|
||
/// Create a wallet using a connected hardware wallet. Only the public keys will be kept in | ||
/// the software wallet | ||
#[arg(long, conflicts_with_all(["mnemonic", "passphrase"]))] |
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.
it also conflicts with whether_to_store_seed_phrase
@@ -73,6 +103,10 @@ pub enum WalletManagementCommand { | |||
/// Force change the wallet type from hot to cold or from cold to hot | |||
#[arg(long)] | |||
force_change_wallet_type: bool, |
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.
looks like a conflict with hardware
Self::Trezor => WalletType::Trezor, | ||
} | ||
} | ||
pub fn user_supplied_menmonic(&self) -> bool { |
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.
typo
whether_to_store_seed_phrase: CliStoreSeedPhrase, | ||
|
||
/// Mnemonic phrase (12, 15, or 24 words as a single quoted argument). If not specified, a new mnemonic phrase is generated and printed. | ||
mnemonic: Option<String>, |
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.
should it be just String? btw we can remove mnemonic from CreateWallet
OutputValue::TokenV1(token_id, amount) => { | ||
let mut value = MintlayerOutputValue::new(); | ||
value.set_amount(amount.into_atoms().to_be_bytes().to_vec()); | ||
value.set_token_id(token_id.to_hash().as_bytes().to_vec()); |
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 looks out of sync with firmware code. I can't build it with pointing to feature/mintlayer-pk
branch either