Skip to content

Refactor/wallet async signing #1846

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 = "mintlayer-master", 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 @@ -39,6 +41,7 @@ zeroize.workspace = true
[dev-dependencies]
chainstate-test-framework = { path = "../chainstate/test-framework" }
test-utils = { path = "../test-utils" }
tokio = { workspace = true, default-features = false, features = ["io-util", "macros", "net", "rt", "sync"] }

ctor.workspace = true
rstest.workspace = true
Expand Down
46 changes: 23 additions & 23 deletions wallet/src/account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,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 @@ -689,7 +689,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 @@ -711,7 +711,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 @@ -775,7 +775,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 @@ -792,7 +792,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 @@ -943,7 +943,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 @@ -966,7 +966,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 @@ -992,7 +992,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 @@ -1062,7 +1062,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 @@ -1151,7 +1151,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn create_freeze_order_tx(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
order_id: OrderId,
order_info: RpcOrderInfo,
median_time: BlockTimestamp,
Expand All @@ -1176,7 +1176,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 @@ -1241,7 +1241,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 @@ -1269,7 +1269,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 @@ -1296,7 +1296,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 @@ -1320,7 +1320,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 @@ -1347,7 +1347,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 @@ -1371,7 +1371,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 @@ -1398,7 +1398,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 @@ -1426,7 +1426,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 All @@ -1448,7 +1448,7 @@ impl<K: AccountKeyChains> Account<K> {

pub fn create_stake_pool_with_vrf_key(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
mut stake_pool_arguments: StakePoolCreationArguments,
median_time: BlockTimestamp,
fee_rate: CurrentFeeRate,
Expand All @@ -1469,7 +1469,7 @@ impl<K: AccountKeyChains> Account<K> {
fn create_stake_pool_impl(
&mut self,
stake_pool_arguments: StakePoolCreationArguments,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
vrf_public_key: VRFPublicKey,
median_time: BlockTimestamp,
fee_rate: CurrentFeeRate,
Expand Down Expand Up @@ -2424,7 +2424,7 @@ struct PreselectedInputs {
total_input_fees: 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 @@ -2495,7 +2495,7 @@ impl<K: AccountKeyChains + VRFAccountKeyChains> Account<K> {

pub fn create_stake_pool(
&mut self,
db_tx: &mut impl WalletStorageWriteUnlocked,
db_tx: &mut impl WalletStorageWriteLocked,
mut stake_pool_arguments: StakePoolCreationArguments,
median_time: BlockTimestamp,
fee_rate: CurrentFeeRate,
Expand Down
24 changes: 13 additions & 11 deletions wallet/src/signer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod tests;

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 S: Signer + Send;
type K: AccountKeyChains + Sync + Send;

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 @@ -252,12 +253,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 @@ -357,12 +359,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 @@ -378,13 +380,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