Skip to content

Commit

Permalink
bugfixes, testfixes, cleanup, refactored select_utxos()
Browse files Browse the repository at this point in the history
FFI join & split functionality + tests
rewrote coin_split function
fixed TariVector conversion bug
found a problem in the coin_join approach, need reconsideration
this commit is for review only before the final brushing/wrap-up
adding TariVector to substitute TariOutputs et al (WIP)
added coin join + initial unit test (still WIP)
added an output database shortcut for easier access from the wallet context, circumventing hops through async fall-through constructs; updated all usages - `cargo test` passing.
added FFI `wallet_get_utxos()`, `destroy_tari_outputs` + unit test
added a simple output querying function

Signed-off-by: Andrei Gubarev <[email protected]>
  • Loading branch information
agubarev committed Jun 29, 2022
1 parent f2a7e18 commit d474e14
Show file tree
Hide file tree
Showing 15 changed files with 2,984 additions and 1,899 deletions.
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

0 comments on commit d474e14

Please sign in to comment.