Skip to content
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(wallet_ffi): add coin join and split #4218

Merged
merged 10 commits into from
Jun 29, 2022
2 changes: 2 additions & 0 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ pub async fn coin_split(
}?;

let (tx_id, tx, amount) = output_service
.create_coin_split(amount_per_split, num_splits as usize, fee_per_gram, None)
.create_coin_split(vec![], amount_per_split, num_splits as usize, fee_per_gram)
.await?;
transaction_service
.submit_transaction(tx_id, tx, amount, "Coin split".into())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -599,21 +599,15 @@ impl wallet_server::Wallet for WalletGrpcServer {
async fn coin_split(&self, request: Request<CoinSplitRequest>) -> Result<Response<CoinSplitResponse>, Status> {
let message = request.into_inner();

let lock_height = if message.lock_height == 0 {
None
} else {
Some(message.lock_height)
};

let mut wallet = self.wallet.clone();

let tx_id = wallet
.coin_split(
vec![], // TODO: refactor grpc to accept and use commitments
MicroTari::from(message.amount_per_split),
message.split_count as usize,
MicroTari::from(message.fee_per_gram),
message.message,
lock_height,
)
.await
.map_err(|e| Status::internal(format!("{:?}", e)))?;
Expand Down
1 change: 1 addition & 0 deletions base_layer/wallet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ tempfile = "3.1.0"
thiserror = "1.0.26"
tower = "0.4"
prost = "0.9"
itertools = "0.10.3"

[dependencies.tari_core]
path = "../../base_layer/core"
Expand Down
4 changes: 4 additions & 0 deletions base_layer/wallet/src/output_manager_service/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ pub enum OutputManagerError {
InvalidMessageError(String),
#[error("Key manager service error : {0}")]
KeyManagerServiceError(#[from] KeyManagerServiceError),
#[error("No commitments were provided")]
NoCommitmentsProvided,
#[error("Invalid argument: {0}")]
InvalidArgument(String),
}

#[derive(Debug, Error)]
Expand Down
40 changes: 35 additions & 5 deletions base_layer/wallet/src/output_manager_service/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::{fmt, fmt::Formatter, sync::Arc};
use aes_gcm::Aes256Gcm;
use tari_common_types::{
transaction::TxId,
types::{HashOutput, PrivateKey, PublicKey},
types::{Commitment, HashOutput, PrivateKey, PublicKey},
};
use tari_core::{
covenants::Covenant,
Expand Down Expand Up @@ -108,7 +108,11 @@ pub enum OutputManagerRequest {
GetInvalidOutputs,
ValidateUtxos,
RevalidateTxos,
CreateCoinSplit((MicroTari, usize, MicroTari, Option<u64>)),
CreateCoinSplit((Vec<Commitment>, MicroTari, usize, MicroTari)),
CreateCoinJoin {
commitments: Vec<Commitment>,
fee_per_gram: MicroTari,
},
ApplyEncryption(Box<Aes256Gcm>),
RemoveEncryption,
GetPublicRewindKeys,
Expand Down Expand Up @@ -172,7 +176,15 @@ impl fmt::Display for OutputManagerRequest {
GetInvalidOutputs => write!(f, "GetInvalidOutputs"),
ValidateUtxos => write!(f, "ValidateUtxos"),
RevalidateTxos => write!(f, "RevalidateTxos"),
CreateCoinSplit(v) => write!(f, "CreateCoinSplit ({})", v.0),
CreateCoinSplit(v) => write!(f, "CreateCoinSplit ({:?})", v.0),
CreateCoinJoin {
commitments,
fee_per_gram,
} => write!(
f,
"CreateCoinJoin: commitments={:#?}, fee_per_gram={}",
commitments, fee_per_gram,
),
ApplyEncryption(_) => write!(f, "ApplyEncryption"),
RemoveEncryption => write!(f, "RemoveEncryption"),
GetCoinbaseTransaction(_) => write!(f, "GetCoinbaseTransaction"),
Expand Down Expand Up @@ -663,18 +675,18 @@ impl OutputManagerHandle {
/// Returns (tx_id, tx, utxos_total_value).
pub async fn create_coin_split(
&mut self,
commitments: Vec<Commitment>,
amount_per_split: MicroTari,
split_count: usize,
fee_per_gram: MicroTari,
lock_height: Option<u64>,
) -> Result<(TxId, Transaction, MicroTari), OutputManagerError> {
match self
.handle
.call(OutputManagerRequest::CreateCoinSplit((
commitments,
amount_per_split,
split_count,
fee_per_gram,
lock_height,
)))
.await??
{
Expand All @@ -683,6 +695,24 @@ impl OutputManagerHandle {
}
}

pub async fn create_coin_join(
&mut self,
commitments: Vec<Commitment>,
fee_per_gram: MicroTari,
) -> Result<(TxId, Transaction, MicroTari), OutputManagerError> {
match self
.handle
.call(OutputManagerRequest::CreateCoinJoin {
commitments,
fee_per_gram,
})
.await??
{
OutputManagerResponse::Transaction(result) => Ok(result),
_ => Err(OutputManagerError::UnexpectedApiResponse),
}
}

pub async fn create_htlc_refund_transaction(
&mut self,
output: HashOutput,
Expand Down
22 changes: 17 additions & 5 deletions base_layer/wallet/src/output_manager_service/input_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ use std::{
fmt::{Display, Formatter},
};

use tari_common_types::types::PublicKey;

use crate::output_manager_service::storage::models::DbUnblindedOutput;
use tari_common_types::types::{Commitment, PublicKey};

#[derive(Debug, Clone, Default)]
pub struct UtxoSelectionCriteria {
Expand All @@ -43,6 +41,13 @@ impl UtxoSelectionCriteria {
}
}

pub fn smallest_first() -> Self {
Self {
filter: UtxoSelectionFilter::Standard,
ordering: UtxoSelectionOrdering::SmallestFirst,
}
}

pub fn for_token(unique_id: Vec<u8>, parent_public_key: Option<PublicKey>) -> Self {
Self {
filter: UtxoSelectionFilter::TokenOutput {
Expand All @@ -52,6 +57,13 @@ impl UtxoSelectionCriteria {
ordering: UtxoSelectionOrdering::Default,
}
}

pub fn specific(commitments: Vec<Commitment>) -> Self {
Self {
filter: UtxoSelectionFilter::SpecificOutputs { commitments },
ordering: UtxoSelectionOrdering::Default,
}
}
}

impl Display for UtxoSelectionCriteria {
Expand Down Expand Up @@ -100,7 +112,7 @@ pub enum UtxoSelectionFilter {
parent_public_key: Option<PublicKey>,
},
/// Selects specific outputs. All outputs must be exist and be spendable.
SpecificOutputs { outputs: Vec<DbUnblindedOutput> },
SpecificOutputs { commitments: Vec<Commitment> },
}

impl Default for UtxoSelectionFilter {
Expand All @@ -118,7 +130,7 @@ impl Display for UtxoSelectionFilter {
UtxoSelectionFilter::TokenOutput { .. } => {
write!(f, "TokenOutput{{..}}")
},
UtxoSelectionFilter::SpecificOutputs { outputs } => {
UtxoSelectionFilter::SpecificOutputs { commitments: outputs } => {
write!(f, "Specific({} output(s))", outputs.len())
},
}
Expand Down
Loading