refactor: itest as lib

This commit is contained in:
thesimplekid
2024-09-09 20:44:13 +01:00
parent 0367e0cd4e
commit 59deb34143
8 changed files with 353 additions and 548 deletions

View File

@@ -23,6 +23,8 @@ cdk-axum = { path = "../cdk-axum"}
cdk-fake-wallet = { path = "../cdk-fake-wallet" }
tower-http = { version = "0.4.4", features = ["cors"] }
futures = { version = "0.3.28", default-features = false }
once_cell = "1.19.0"
uuid = { version = "1", features = ["v4"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { version = "1", features = [

View File

@@ -1,106 +0,0 @@
//! Test calc fee
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use anyhow::Result;
use bip39::Mnemonic;
use cdk::amount::SplitTarget;
use cdk::cdk_database::WalletMemoryDatabase;
use cdk::mint_url::MintUrl;
use cdk::nuts::CurrencyUnit;
use cdk::Wallet;
use cdk_integration_tests::{create_backends_fake_wallet, start_mint, wallet_mint, MINT_URL};
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
pub async fn test_mint_fee() -> Result<()> {
tokio::spawn(async move {
let ln_backends = create_backends_fake_wallet();
let mut supported_units = HashMap::new();
supported_units.insert(CurrencyUnit::Sat, (1, 32));
start_mint(ln_backends, supported_units)
.await
.expect("Could not start mint")
});
tokio::time::sleep(Duration::from_millis(500)).await;
let mnemonic = Mnemonic::generate(12)?;
let wallet = Wallet::new(
MINT_URL,
CurrencyUnit::Sat,
Arc::new(WalletMemoryDatabase::default()),
&mnemonic.to_seed_normalized(""),
None,
)?;
let wallet = Arc::new(wallet);
wallet_mint(
Arc::clone(&wallet),
10000.into(),
SplitTarget::Value(1.into()),
)
.await
.unwrap();
println!("Minted");
let proofs = wallet
.localstore
.get_proofs(Some(MintUrl::from_str(MINT_URL)?), None, None, None)
.await?;
let proofs: Vec<cdk::nuts::Proof> = proofs.into_iter().map(|p| p.proof).collect();
let five_proofs = proofs[..5].to_vec();
let fee = wallet.get_proofs_fee(&five_proofs).await?;
// Check wallet gets fee calc correct
assert_eq!(fee, 1.into());
let _swap = wallet
.swap(None, SplitTarget::Value(1.into()), five_proofs, None, false)
.await?;
let wallet_bal = wallet.total_balance().await?;
// Check 1 sat was paid in fees for the swap
assert_eq!(wallet_bal, 9999.into());
let proofs = wallet
.localstore
.get_proofs(Some(MintUrl::from_str(MINT_URL)?), None, None, None)
.await?;
let proofs: Vec<cdk::nuts::Proof> = proofs.into_iter().map(|p| p.proof).collect();
let thousand_proofs = proofs[..1001].to_vec();
let fee = wallet.get_proofs_fee(&thousand_proofs).await?;
// Check wallet gets fee calc correct
assert_eq!(fee, 2.into());
let _swap = wallet
.swap(
None,
SplitTarget::Value(1.into()),
thousand_proofs,
None,
false,
)
.await?;
let wallet_bal = wallet.total_balance().await?;
// Check 1 sat was paid in fees for the swap
assert_eq!(wallet_bal, 9997.into());
Ok(())
}

View File

@@ -1,88 +1,370 @@
//! Mint integration tests
//! Mint tests
use cdk::amount::{Amount, SplitTarget};
use cdk::dhke::construct_proofs;
use cdk::util::unix_time;
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::OnceCell;
use anyhow::{bail, Result};
use bip39::Mnemonic;
use cdk::amount::SplitTarget;
use cdk::cdk_database::WalletMemoryDatabase;
use cdk::nuts::CurrencyUnit;
use cdk::wallet::SendKind;
use cdk::Error;
use cdk::Wallet;
use cdk_integration_tests::{create_backends_fake_wallet, start_mint, wallet_mint, MINT_URL};
use cdk::cdk_database::mint_memory::MintMemoryDatabase;
use cdk::nuts::{
CurrencyUnit, Id, MintBolt11Request, MintInfo, Nuts, PreMintSecrets, Proofs, SecretKey,
SpendingConditions, SwapRequest,
};
use cdk::Mint;
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
pub async fn test_mint_double_receive() -> Result<()> {
tokio::spawn(async move {
let ln_backends = create_backends_fake_wallet();
pub const MINT_URL: &str = "http://127.0.0.1:8088";
let mut supported_units = HashMap::new();
supported_units.insert(CurrencyUnit::Sat, (0, 64));
static INSTANCE: OnceCell<Mint> = OnceCell::const_new();
start_mint(ln_backends, supported_units)
.await
.expect("Could not start mint")
});
async fn new_mint(fee: u64) -> Mint {
let mut supported_units = HashMap::new();
supported_units.insert(CurrencyUnit::Sat, (fee, 32));
tokio::time::sleep(Duration::from_millis(500)).await;
let nuts = Nuts::new()
.nut07(true)
.nut08(true)
.nut09(true)
.nut10(true)
.nut11(true)
.nut12(true)
.nut14(true);
let mnemonic = Mnemonic::generate(12)?;
let mint_info = MintInfo::new().nuts(nuts);
let wallet = Wallet::new(
let mnemonic = Mnemonic::generate(12).unwrap();
let mint = Mint::new(
MINT_URL,
CurrencyUnit::Sat,
Arc::new(WalletMemoryDatabase::default()),
&mnemonic.to_seed_normalized(""),
None,
)?;
mint_info,
Arc::new(MintMemoryDatabase::default()),
supported_units,
)
.await
.unwrap();
let wallet = Arc::new(wallet);
mint
}
wallet_mint(Arc::clone(&wallet), 100.into(), SplitTarget::default()).await?;
println!("Minted");
async fn initialize() -> &'static Mint {
INSTANCE.get_or_init(|| new_mint(0)).await
}
let token = wallet
.send(
10.into(),
None,
None,
&SplitTarget::default(),
&SendKind::default(),
false,
async fn mint_proofs(
mint: &Mint,
amount: Amount,
split_target: &SplitTarget,
keys: cdk::nuts::Keys,
) -> Result<Proofs> {
let request_lookup = uuid::Uuid::new_v4().to_string();
let mint_quote = mint
.new_mint_quote(
MINT_URL.parse()?,
"".to_string(),
CurrencyUnit::Sat,
amount,
unix_time() + 36000,
request_lookup.to_string(),
)
.await?;
let mnemonic = Mnemonic::generate(12)?;
mint.pay_mint_quote_for_request_id(&request_lookup).await?;
let keyset_id = Id::from(&keys);
let wallet_two = Wallet::new(
MINT_URL,
CurrencyUnit::Sat,
Arc::new(WalletMemoryDatabase::default()),
&mnemonic.to_seed_normalized(""),
None,
let premint = PreMintSecrets::random(keyset_id, amount, split_target)?;
let mint_request = MintBolt11Request {
quote: mint_quote.id,
outputs: premint.blinded_messages(),
};
let after_mint = mint.process_mint_request(mint_request).await?;
let proofs = construct_proofs(
after_mint.signatures,
premint.rs(),
premint.secrets(),
&keys,
)?;
let rec = wallet_two
.receive(&token.to_string(), SplitTarget::default(), &[], &[])
.await?;
println!("Received: {}", rec);
Ok(proofs)
}
// Attempt to receive again
if let Err(err) = wallet
.receive(&token.to_string(), SplitTarget::default(), &[], &[])
.await
{
match err {
Error::TokenAlreadySpent => (),
_ => {
println!("{}", err);
bail!("Expected an already spent error");
}
}
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_mint_double_spend() -> Result<()> {
let mint = initialize().await;
let keys = mint.pubkeys().await?.keysets.first().unwrap().clone().keys;
let keyset_id = Id::from(&keys);
let proofs = mint_proofs(mint, 100.into(), &SplitTarget::default(), keys).await?;
let preswap = PreMintSecrets::random(keyset_id, 100.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(proofs.clone(), preswap.blinded_messages());
let swap = mint.process_swap_request(swap_request).await;
assert!(swap.is_ok());
let preswap_two = PreMintSecrets::random(keyset_id, 100.into(), &SplitTarget::default())?;
let swap_two_request = SwapRequest::new(proofs, preswap_two.blinded_messages());
match mint.process_swap_request(swap_two_request).await {
Ok(_) => bail!("Proofs double spent"),
Err(err) => match err {
cdk::Error::TokenAlreadySpent => (),
_ => bail!("Wrong error returned"),
},
}
Ok(())
}
/// This attempts to swap for more outputs then inputs.
/// This will work if the mint does not check for outputs amounts overflowing
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_attempt_to_swap_by_overflowing() -> Result<()> {
let mint = initialize().await;
let keys = mint.pubkeys().await?.keysets.first().unwrap().clone().keys;
let keyset_id = Id::from(&keys);
let proofs = mint_proofs(mint, 100.into(), &SplitTarget::default(), keys).await?;
let amount = 2_u64.pow(63);
let pre_mint_amount =
PreMintSecrets::random(keyset_id, amount.into(), &SplitTarget::default())?;
let pre_mint_amount_two =
PreMintSecrets::random(keyset_id, amount.into(), &SplitTarget::default())?;
let mut pre_mint = PreMintSecrets::random(keyset_id, 1.into(), &SplitTarget::default())?;
pre_mint.combine(pre_mint_amount);
pre_mint.combine(pre_mint_amount_two);
let swap_request = SwapRequest::new(proofs.clone(), pre_mint.blinded_messages());
match mint.process_swap_request(swap_request).await {
Ok(_) => bail!("Swap occurred with overflow"),
Err(err) => match err {
cdk::Error::NUT03(cdk::nuts::nut03::Error::Amount(_)) => (),
_ => {
println!("{:?}", err);
bail!("Wrong error returned in swap overflow")
}
},
}
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
pub async fn test_p2pk_swap() -> Result<()> {
let mint = initialize().await;
let keys = mint.pubkeys().await?.keysets.first().unwrap().clone().keys;
let keyset_id = Id::from(&keys);
let proofs = mint_proofs(mint, 100.into(), &SplitTarget::default(), keys).await?;
let secret = SecretKey::generate();
let spending_conditions = SpendingConditions::new_p2pk(secret.public_key(), None);
let pre_swap = PreMintSecrets::with_conditions(
keyset_id,
100.into(),
&SplitTarget::default(),
&spending_conditions,
)?;
let swap_request = SwapRequest::new(proofs.clone(), pre_swap.blinded_messages());
let keys = mint.pubkeys().await?.keysets.first().cloned().unwrap().keys;
let post_swap = mint.process_swap_request(swap_request).await?;
let mut proofs = construct_proofs(
post_swap.signatures,
pre_swap.rs(),
pre_swap.secrets(),
&keys,
)?;
let pre_swap = PreMintSecrets::random(keyset_id, 100.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(proofs.clone(), pre_swap.blinded_messages());
match mint.process_swap_request(swap_request).await {
Ok(_) => bail!("Proofs spent without sig"),
Err(err) => match err {
cdk::Error::NUT11(cdk::nuts::nut11::Error::SignaturesNotProvided) => (),
_ => {
println!("{:?}", err);
bail!("Wrong error returned")
}
},
}
for proof in &mut proofs {
proof.sign_p2pk(secret.clone())?;
}
let swap_request = SwapRequest::new(proofs.clone(), pre_swap.blinded_messages());
let attempt_swap = mint.process_swap_request(swap_request).await;
assert!(attempt_swap.is_ok());
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_swap_unbalanced() -> Result<()> {
let mint = initialize().await;
let keys = mint.pubkeys().await?.keysets.first().unwrap().clone().keys;
let keyset_id = Id::from(&keys);
let proofs = mint_proofs(mint, 100.into(), &SplitTarget::default(), keys).await?;
let preswap = PreMintSecrets::random(keyset_id, 95.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(proofs.clone(), preswap.blinded_messages());
match mint.process_swap_request(swap_request).await {
Ok(_) => bail!("Swap was allowed unbalanced"),
Err(err) => match err {
cdk::Error::TransactionUnbalanced(_, _, _) => (),
_ => bail!("Wrong error returned"),
},
}
let preswap = PreMintSecrets::random(keyset_id, 101.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(proofs.clone(), preswap.blinded_messages());
match mint.process_swap_request(swap_request).await {
Ok(_) => bail!("Swap was allowed unbalanced"),
Err(err) => match err {
cdk::Error::TransactionUnbalanced(_, _, _) => (),
_ => bail!("Wrong error returned"),
},
}
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_swap_overpay_underpay_fee() -> Result<()> {
let mint = new_mint(1).await;
mint.rotate_keyset(CurrencyUnit::Sat, 1, 32, 1).await?;
let keys = mint.pubkeys().await?.keysets.first().unwrap().clone().keys;
let keyset_id = Id::from(&keys);
let proofs = mint_proofs(&mint, 1000.into(), &SplitTarget::default(), keys).await?;
let preswap = PreMintSecrets::random(keyset_id, 9998.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(proofs.clone(), preswap.blinded_messages());
// Attempt to swap overpaying fee
match mint.process_swap_request(swap_request).await {
Ok(_) => bail!("Swap was allowed unbalanced"),
Err(err) => match err {
cdk::Error::TransactionUnbalanced(_, _, _) => (),
_ => {
println!("{:?}", err);
bail!("Wrong error returned")
}
},
}
let preswap = PreMintSecrets::random(keyset_id, 1000.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(proofs.clone(), preswap.blinded_messages());
// Attempt to swap underpaying fee
match mint.process_swap_request(swap_request).await {
Ok(_) => bail!("Swap was allowed unbalanced"),
Err(err) => match err {
cdk::Error::TransactionUnbalanced(_, _, _) => (),
_ => {
println!("{:?}", err);
bail!("Wrong error returned")
}
},
}
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_mint_enforce_fee() -> Result<()> {
let mint = new_mint(1).await;
let keys = mint.pubkeys().await?.keysets.first().unwrap().clone().keys;
let keyset_id = Id::from(&keys);
let mut proofs = mint_proofs(&mint, 1010.into(), &SplitTarget::Value(1.into()), keys).await?;
let five_proofs: Vec<_> = proofs.drain(..5).collect();
let preswap = PreMintSecrets::random(keyset_id, 5.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(five_proofs.clone(), preswap.blinded_messages());
// Attempt to swap underpaying fee
match mint.process_swap_request(swap_request).await {
Ok(_) => bail!("Swap was allowed unbalanced"),
Err(err) => match err {
cdk::Error::TransactionUnbalanced(_, _, _) => (),
_ => {
println!("{:?}", err);
bail!("Wrong error returned")
}
},
}
let preswap = PreMintSecrets::random(keyset_id, 4.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(five_proofs.clone(), preswap.blinded_messages());
let _ = mint.process_swap_request(swap_request).await?;
let thousnad_proofs: Vec<_> = proofs.drain(..1001).collect();
let preswap = PreMintSecrets::random(keyset_id, 1000.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(thousnad_proofs.clone(), preswap.blinded_messages());
// Attempt to swap underpaying fee
match mint.process_swap_request(swap_request).await {
Ok(_) => bail!("Swap was allowed unbalanced"),
Err(err) => match err {
cdk::Error::TransactionUnbalanced(_, _, _) => (),
_ => {
println!("{:?}", err);
bail!("Wrong error returned")
}
},
}
let preswap = PreMintSecrets::random(keyset_id, 999.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(thousnad_proofs.clone(), preswap.blinded_messages());
let _ = mint.process_swap_request(swap_request).await?;
Ok(())
}

View File

@@ -1,118 +0,0 @@
use std::collections::HashMap;
use std::time::Duration;
use anyhow::{bail, Result};
use cdk::amount::SplitTarget;
use cdk::dhke::construct_proofs;
use cdk::nuts::{CurrencyUnit, PreMintSecrets, SwapRequest};
use cdk::Amount;
use cdk::HttpClient;
use cdk_integration_tests::{create_backends_fake_wallet, mint_proofs, start_mint, MINT_URL};
/// This attempts to swap for more outputs then inputs.
/// This will work if the mint does not check for outputs amounts overflowing
async fn attempt_to_swap_by_overflowing() -> Result<()> {
let wallet_client = HttpClient::new();
let mint_keys = wallet_client.get_mint_keys(MINT_URL.parse()?).await?;
let mint_keys = mint_keys.first().unwrap();
let keyset_id = mint_keys.id;
let pre_swap_proofs = mint_proofs(MINT_URL, 1.into(), keyset_id, mint_keys).await?;
println!(
"Pre swap amount: {:?}",
Amount::try_sum(pre_swap_proofs.iter().map(|p| p.amount))?
);
println!(
"Pre swap amounts: {:?}",
pre_swap_proofs
.iter()
.map(|p| p.amount)
.collect::<Vec<Amount>>()
);
// Construct messages that will overflow
let amount = 2_u64.pow(63);
let pre_mint_amount =
PreMintSecrets::random(keyset_id, amount.into(), &SplitTarget::default())?;
let pre_mint_amount_two =
PreMintSecrets::random(keyset_id, amount.into(), &SplitTarget::default())?;
let mut pre_mint = PreMintSecrets::random(keyset_id, 1.into(), &SplitTarget::default())?;
pre_mint.combine(pre_mint_amount);
pre_mint.combine(pre_mint_amount_two);
let swap_request = SwapRequest::new(pre_swap_proofs.clone(), pre_mint.blinded_messages());
let swap_response = match wallet_client
.post_swap(MINT_URL.parse()?, swap_request)
.await
{
Ok(res) => res,
// In the context of this test an error response here is good.
// It means the mint does not allow us to swap for more then we should by overflowing
Err(_err) => return Ok(()),
};
let post_swap_proofs = construct_proofs(
swap_response.signatures,
pre_mint.rs(),
pre_mint.secrets(),
&mint_keys.clone().keys,
)?;
println!(
"Pre swap amount: {:?}",
Amount::try_sum(pre_swap_proofs.iter().map(|p| p.amount)).expect("Amount overflowed")
);
println!(
"Post swap amount: {:?}",
Amount::try_sum(post_swap_proofs.iter().map(|p| p.amount)).expect("Amount Overflowed")
);
println!(
"Pre swap amounts: {:?}",
pre_swap_proofs
.iter()
.map(|p| p.amount)
.collect::<Vec<Amount>>()
);
println!(
"Post swap amounts: {:?}",
post_swap_proofs
.iter()
.map(|p| p.amount)
.collect::<Vec<Amount>>()
);
bail!("Should not have been able to swap")
}
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
pub async fn test_overflow() -> Result<()> {
tokio::spawn(async move {
let ln_backends = create_backends_fake_wallet();
let mut supported_units = HashMap::new();
supported_units.insert(CurrencyUnit::Sat, (0, 32));
start_mint(ln_backends, supported_units)
.await
.expect("Could not start mint")
});
// Wait for mint server to start
tokio::time::sleep(Duration::from_millis(500)).await;
let result = attempt_to_swap_by_overflowing().await;
assert!(result.is_ok());
Ok(())
}

View File

@@ -1,88 +0,0 @@
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use anyhow::Result;
use bip39::Mnemonic;
use cdk::amount::SplitTarget;
use cdk::cdk_database::WalletMemoryDatabase;
use cdk::nuts::{CurrencyUnit, SecretKey, SpendingConditions};
use cdk::wallet::SendKind;
use cdk::{Amount, Wallet};
use cdk_integration_tests::{create_backends_fake_wallet, start_mint, wallet_mint, MINT_URL};
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
pub async fn test_p2pk_swap() -> Result<()> {
tokio::spawn(async move {
let ln_backends = create_backends_fake_wallet();
let mut supported_units = HashMap::new();
supported_units.insert(CurrencyUnit::Sat, (0, 32));
start_mint(ln_backends, supported_units)
.await
.expect("Could not start mint")
});
tokio::time::sleep(Duration::from_millis(500)).await;
let mnemonic = Mnemonic::generate(12)?;
let wallet = Wallet::new(
MINT_URL,
CurrencyUnit::Sat,
Arc::new(WalletMemoryDatabase::default()),
&mnemonic.to_seed_normalized(""),
None,
)?;
let wallet = Arc::new(wallet);
// Mint 100 sats for the wallet
wallet_mint(Arc::clone(&wallet), 100.into(), SplitTarget::default()).await?;
let secret = SecretKey::generate();
let spending_conditions = SpendingConditions::new_p2pk(secret.public_key(), None);
let amount = Amount::from(10);
let token = wallet
.send(
amount,
None,
Some(spending_conditions),
&SplitTarget::None,
&SendKind::default(),
false,
)
.await?;
let attempt_amount = wallet
.receive(&token.to_string(), SplitTarget::default(), &[], &[])
.await;
// This should fail since the token is not signed
assert!(attempt_amount.is_err());
let wrong_secret = SecretKey::generate();
let received_amount = wallet
.receive(
&token.to_string(),
SplitTarget::default(),
&[wrong_secret],
&[],
)
.await;
assert!(received_amount.is_err());
let received_amount = wallet
.receive(&token.to_string(), SplitTarget::default(), &[secret], &[])
.await
.unwrap();
assert_eq!(received_amount, amount);
Ok(())
}

View File

@@ -1,61 +0,0 @@
//! Test that if a wallet attempts to swap for less outputs then inputs correct error is returned
use std::collections::HashMap;
use std::time::Duration;
use anyhow::{bail, Result};
use cdk::amount::SplitTarget;
use cdk::nuts::{CurrencyUnit, PreMintSecrets, SwapRequest};
use cdk::Error;
use cdk::HttpClient;
use cdk_integration_tests::{create_backends_fake_wallet, mint_proofs, start_mint, MINT_URL};
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
pub async fn test_unbalanced_swap() -> Result<()> {
tokio::spawn(async move {
let ln_backends = create_backends_fake_wallet();
let mut supported_units = HashMap::new();
supported_units.insert(CurrencyUnit::Sat, (0, 32));
start_mint(ln_backends, supported_units)
.await
.expect("Could not start mint")
});
// Wait for mint server to start
tokio::time::sleep(Duration::from_millis(500)).await;
let wallet_client = HttpClient::new();
let mint_keys = wallet_client.get_mint_keys(MINT_URL.parse()?).await?;
let mint_keys = mint_keys.first().unwrap();
let keyset_id = mint_keys.id;
let pre_swap_proofs = mint_proofs(MINT_URL, 10.into(), keyset_id, mint_keys).await?;
let pre_mint = PreMintSecrets::random(keyset_id, 9.into(), &SplitTarget::default())?;
let swap_request = SwapRequest::new(pre_swap_proofs.clone(), pre_mint.blinded_messages());
let _swap_response = match wallet_client
.post_swap(MINT_URL.parse()?, swap_request)
.await
{
Ok(res) => res,
// In the context of this test an error response here is good.
// It means the mint does not allow us to swap for more then we should by overflowing
Err(err) => match err {
Error::TransactionUnbalanced(_, _, _) => {
return Ok(());
}
_ => {
println!("{}", err);
bail!("Wrong error code returned");
}
},
};
bail!("Transaction should not have succeeded")
}

View File

@@ -1,113 +0,0 @@
//! Fee tests for over and underpaying
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use anyhow::{bail, Result};
use bip39::Mnemonic;
use cdk::cdk_database::WalletMemoryDatabase;
use cdk::mint_url::MintUrl;
use cdk::nuts::{CurrencyUnit, SwapRequest};
use cdk::wallet::client::HttpClient;
use cdk::Wallet;
use cdk::{amount::SplitTarget, nuts::PreMintSecrets};
use cdk_integration_tests::{create_backends_fake_wallet, start_mint, wallet_mint, MINT_URL};
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
pub async fn test_swap_overpay_underpay() -> Result<()> {
tokio::spawn(async move {
let ln_backends = create_backends_fake_wallet();
let mut supported_units = HashMap::new();
supported_units.insert(CurrencyUnit::Sat, (1, 32));
start_mint(ln_backends, supported_units)
.await
.expect("Could not start mint")
});
tokio::time::sleep(Duration::from_millis(500)).await;
let mnemonic = Mnemonic::generate(12)?;
let wallet = Wallet::new(
MINT_URL,
CurrencyUnit::Sat,
Arc::new(WalletMemoryDatabase::default()),
&mnemonic.to_seed_normalized(""),
None,
)?;
let wallet = Arc::new(wallet);
wallet_mint(
Arc::clone(&wallet),
10000.into(),
SplitTarget::Value(1.into()),
)
.await
.unwrap();
println!("Minted");
let proofs = wallet
.localstore
.get_proofs(Some(MintUrl::from_str(MINT_URL)?), None, None, None)
.await?;
let proofs: Vec<cdk::nuts::Proof> = proofs.into_iter().map(|p| p.proof).collect();
let keyset_id = proofs.first().unwrap().keyset_id;
let pre_swap_proofs = proofs[..1000].to_vec();
// Attempt to swap while overpaying fee
let pre_swap_secret = PreMintSecrets::random(keyset_id, 450.into(), &SplitTarget::default())?;
let swap_request =
SwapRequest::new(pre_swap_proofs.clone(), pre_swap_secret.blinded_messages());
let wallet_client = HttpClient::new();
match wallet_client
.post_swap(MINT_URL.parse()?, swap_request)
.await
{
Ok(_res) => {
bail!("Swap should not have succeeded");
}
Err(err) => match err {
cdk::error::Error::TransactionUnbalanced(_, _, _) => (),
_ => {
println!("{:?}", err);
bail!("Swap returned the wrong error when overpaying fee");
}
},
};
// Attempt to swap while underpaying fee
let pre_swap_secret = PreMintSecrets::random(keyset_id, 1000.into(), &SplitTarget::default())?;
let swap_request =
SwapRequest::new(pre_swap_proofs.clone(), pre_swap_secret.blinded_messages());
match wallet_client
.post_swap(MINT_URL.parse()?, swap_request)
.await
{
Ok(_res) => {
bail!("Swap should not have succeeded");
}
// In the context of this test an error response here is good.
// It means the mint does not allow us to swap for more then we should by overflowing
Err(err) => match err {
cdk::error::Error::TransactionUnbalanced(_, _, _) => (),
_ => {
println!("{:?}", err);
bail!("Swap returned the wrong error when underpaying fee");
}
},
};
Ok(())
}

View File

@@ -511,8 +511,10 @@ impl Mint {
Ok(KeysResponse {
keysets: keysets
.values()
.filter(|k| active_keysets.contains(&k.id))
.map(|k| k.clone().into())
.filter_map(|k| match active_keysets.contains(&k.id) {
true => Some(k.clone().into()),
false => None,
})
.collect(),
})
}
@@ -1648,4 +1650,9 @@ mod tests {
Ok(())
}
#[tokio::test]
async fn test_over_pay_fee() -> anyhow::Result<()> {
Ok(())
}
}