Skip to content

Commit

Permalink
Make signing an async operation
Browse files Browse the repository at this point in the history
- to make an easier integration with Ledger in the future
  • Loading branch information
OBorce committed Dec 10, 2024
1 parent 912a389 commit fd89e56
Show file tree
Hide file tree
Showing 17 changed files with 2,190 additions and 1,011 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions wallet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ wallet-storage = { path = "./storage" }
wallet-types = { path = "./types" }
trezor-client = { git = "https://github.com/mintlayer/mintlayer-trezor-firmware", branch = "feature/mintlayer-pk", features = ["bitcoin", "mintlayer"], optional = true }

async-trait.workspace = true
bip39 = { workspace = true, default-features = false, features = ["std", "zeroize"] }
futures = { workspace = true, default-features = false }
hex.workspace = true
itertools.workspace = true
parity-scale-codec.workspace = true
Expand All @@ -38,6 +40,7 @@ zeroize.workspace = true

[dev-dependencies]
test-utils = { path = "../test-utils" }
tokio = { workspace = true, default-features = false, features = ["io-util", "macros", "net", "rt", "sync"] }

rstest.workspace = true
tempfile.workspace = true
Expand Down
40 changes: 20 additions & 20 deletions wallet/src/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub struct Account<K> {
account_info: AccountInfo,
}

impl<K: AccountKeyChains> Account<K> {
impl<K: AccountKeyChains + Sync> Account<K> {
/// Create a new account by providing a key chain
pub fn new(
chain_config: Arc<ChainConfig>,
Expand Down Expand Up @@ -654,7 +654,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn process_send_request_and_sign(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
request: SendRequest,
inputs: SelectedInputs,
change_addresses: BTreeMap<Currency, Address<Destination>>,
Expand All @@ -676,7 +676,7 @@ impl<K: AccountKeyChains> Account<K> {

fn decommission_stake_pool_impl(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
pool_id: PoolId,
pool_balance: Amount,
output_address: Option<Destination>,
Expand Down Expand Up @@ -739,7 +739,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn decommission_stake_pool(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
pool_id: PoolId,
pool_balance: Amount,
output_address: Option<Destination>,
Expand All @@ -756,7 +756,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn decommission_stake_pool_request(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
pool_id: PoolId,
pool_balance: Amount,
output_address: Option<Destination>,
Expand Down Expand Up @@ -900,7 +900,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn create_htlc_tx(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
output_value: OutputValue,
htlc: HashedTimelockContract,
median_time: BlockTimestamp,
Expand All @@ -923,7 +923,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn create_order_tx(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
ask_value: OutputValue,
give_value: OutputValue,
conclude_address: Address<Destination>,
Expand All @@ -949,7 +949,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn create_conclude_order_tx(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
order_id: OrderId,
order_info: RpcOrderInfo,
output_address: Option<Destination>,
Expand Down Expand Up @@ -1002,7 +1002,7 @@ impl<K: AccountKeyChains> Account<K> {
#[allow(clippy::too_many_arguments)]
pub fn create_fill_order_tx(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
order_id: OrderId,
order_info: RpcOrderInfo,
fill_amount_in_ask_currency: Amount,
Expand Down Expand Up @@ -1058,7 +1058,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn create_issue_nft_tx(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
nft_issue_arguments: IssueNftArguments,
median_time: BlockTimestamp,
fee_rate: CurrentFeeRate,
Expand Down Expand Up @@ -1119,7 +1119,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn mint_tokens(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
token_info: &UnconfirmedTokenInfo,
address: Address<Destination>,
amount: Amount,
Expand Down Expand Up @@ -1147,7 +1147,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn unmint_tokens(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
token_info: &UnconfirmedTokenInfo,
amount: Amount,
median_time: BlockTimestamp,
Expand All @@ -1174,7 +1174,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn lock_token_supply(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
token_info: &UnconfirmedTokenInfo,
median_time: BlockTimestamp,
fee_rate: CurrentFeeRate,
Expand All @@ -1198,7 +1198,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn freeze_token(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
token_info: &UnconfirmedTokenInfo,
is_token_unfreezable: IsTokenUnfreezable,
median_time: BlockTimestamp,
Expand All @@ -1225,7 +1225,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn unfreeze_token(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
token_info: &UnconfirmedTokenInfo,
median_time: BlockTimestamp,
fee_rate: CurrentFeeRate,
Expand All @@ -1249,7 +1249,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn change_token_authority(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
token_info: &UnconfirmedTokenInfo,
address: Address<Destination>,
median_time: BlockTimestamp,
Expand All @@ -1276,7 +1276,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn change_token_metadata_uri(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
token_info: &UnconfirmedTokenInfo,
metadata_uri: Vec<u8>,
median_time: BlockTimestamp,
Expand Down Expand Up @@ -1304,7 +1304,7 @@ impl<K: AccountKeyChains> Account<K> {
authority: Destination,
tx_input: TxInput,
outputs: Vec<TxOutput>,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
median_time: BlockTimestamp,
fee_rate: CurrentFeeRate,
) -> Result<SendRequest, WalletError> {
Expand Down Expand Up @@ -2128,7 +2128,7 @@ struct PreselectedInputAmounts {
pub burn: Amount,
}

impl<K: AccountKeyChains + VRFAccountKeyChains> Account<K> {
impl<K: AccountKeyChains + VRFAccountKeyChains + Sync> Account<K> {
fn get_vrf_public_key(
&mut self,
db_tx: &mut impl WalletStorageWriteLocked,
Expand Down Expand Up @@ -2199,7 +2199,7 @@ impl<K: AccountKeyChains + VRFAccountKeyChains> Account<K> {

pub fn create_stake_pool_tx(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
stake_pool_arguments: StakePoolDataArguments,
median_time: BlockTimestamp,
fee_rate: CurrentFeeRate,
Expand Down
22 changes: 12 additions & 10 deletions wallet/src/signer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use std::sync::Arc;

use async_trait::async_trait;
use common::{
address::AddressError,
chain::{
Expand Down Expand Up @@ -99,44 +100,45 @@ type SignerResult<T> = Result<T, SignerError>;

/// Signer trait responsible for signing transactions or challenges using a software or hardware
/// wallet
#[async_trait]
pub trait Signer {
/// Sign a partially signed transaction and return the before and after signature statuses.
fn sign_tx(
async fn sign_tx(
&mut self,
tx: PartiallySignedTransaction,
key_chain: &impl AccountKeyChains,
db_tx: &impl WalletStorageReadUnlocked,
key_chain: &(impl AccountKeyChains + Sync),
db_tx: &(impl WalletStorageReadUnlocked + Sync),
) -> SignerResult<(
PartiallySignedTransaction,
Vec<SignatureStatus>,
Vec<SignatureStatus>,
)>;

/// Sign an arbitrary message for a destination known to this key chain.
fn sign_challenge(
async fn sign_challenge(
&mut self,
message: &[u8],
destination: &Destination,
key_chain: &impl AccountKeyChains,
db_tx: &impl WalletStorageReadUnlocked,
key_chain: &(impl AccountKeyChains + Sync),
db_tx: &(impl WalletStorageReadUnlocked + Sync),
) -> SignerResult<ArbitraryMessageSignature>;

/// Sign a transaction intent. The number of `input_destinations` must be the same as
/// the number of inputs in the transaction; all of the destinations must be known
/// to this key chain.
fn sign_transaction_intent(
async fn sign_transaction_intent(
&mut self,
transaction: &Transaction,
input_destinations: &[Destination],
intent: &str,
key_chain: &impl AccountKeyChains,
db_tx: &impl WalletStorageReadUnlocked,
key_chain: &(impl AccountKeyChains + Sync),
db_tx: &(impl WalletStorageReadUnlocked + Sync),
) -> SignerResult<SignedTransactionIntent>;
}

pub trait SignerProvider {
type S: Signer;
type K: AccountKeyChains;
type K: AccountKeyChains + Sync;

fn provide(&mut self, chain_config: Arc<ChainConfig>, account_index: U31) -> Self::S;

Expand Down
20 changes: 11 additions & 9 deletions wallet/src/signer/software_signer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

use std::sync::Arc;

use async_trait::async_trait;
use common::chain::{
htlc::HtlcSecret,
signature::{
Expand Down Expand Up @@ -253,12 +254,13 @@ impl SoftwareSigner {
}
}

#[async_trait]
impl Signer for SoftwareSigner {
fn sign_tx(
async fn sign_tx(
&mut self,
ptx: PartiallySignedTransaction,
key_chain: &impl AccountKeyChains,
db_tx: &impl WalletStorageReadUnlocked,
key_chain: &(impl AccountKeyChains + Sync),
db_tx: &(impl WalletStorageReadUnlocked + Sync),
) -> SignerResult<(
PartiallySignedTransaction,
Vec<SignatureStatus>,
Expand Down Expand Up @@ -359,12 +361,12 @@ impl Signer for SoftwareSigner {
Ok((ptx.with_witnesses(witnesses), prev_statuses, new_statuses))
}

fn sign_challenge(
async fn sign_challenge(
&mut self,
message: &[u8],
destination: &Destination,
key_chain: &impl AccountKeyChains,
db_tx: &impl WalletStorageReadUnlocked,
key_chain: &(impl AccountKeyChains + Sync),
db_tx: &(impl WalletStorageReadUnlocked + Sync),
) -> SignerResult<ArbitraryMessageSignature> {
let private_key = self
.get_private_key_for_destination(destination, key_chain, db_tx)?
Expand All @@ -380,13 +382,13 @@ impl Signer for SoftwareSigner {
Ok(sig)
}

fn sign_transaction_intent(
async fn sign_transaction_intent(
&mut self,
transaction: &Transaction,
input_destinations: &[Destination],
intent: &str,
key_chain: &impl AccountKeyChains,
db_tx: &impl WalletStorageReadUnlocked,
key_chain: &(impl AccountKeyChains + Sync),
db_tx: &(impl WalletStorageReadUnlocked + Sync),
) -> SignerResult<SignedTransactionIntent> {
SignedTransactionIntent::produce_from_transaction(
transaction,
Expand Down
Loading

0 comments on commit fd89e56

Please sign in to comment.