浏览代码

chore: add overflow test

thesimplekid 7 月之前
父节点
当前提交
30f1e28491
共有 1 个文件被更改,包括 135 次插入0 次删除
  1. 135 0
      crates/cdk-integration-tests/tests/overflow.rs

+ 135 - 0
crates/cdk-integration-tests/tests/overflow.rs

@@ -0,0 +1,135 @@
+use std::time::Duration;
+
+use anyhow::{bail, Result};
+use cdk::amount::SplitTarget;
+use cdk::dhke::construct_proofs;
+use cdk::nuts::{CurrencyUnit, MintQuoteState, PreMintSecrets, SwapRequest};
+use cdk::Amount;
+use cdk::HttpClient;
+use cdk_integration_tests::{create_backends_fake_wallet, start_mint, MINT_URL};
+use tokio::time::sleep;
+
+/// This attemps 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 mint_quote = wallet_client
+        .post_mint_quote(MINT_URL.parse()?, 100.into(), CurrencyUnit::Sat)
+        .await?;
+
+    loop {
+        let status = wallet_client
+            .get_mint_quote_status(MINT_URL.parse()?, &mint_quote.quote)
+            .await?;
+
+        if status.state == MintQuoteState::Paid {
+            break;
+        }
+        println!("{:?}", status);
+
+        sleep(Duration::from_secs(2)).await;
+    }
+
+    let premint_secrets =
+        PreMintSecrets::random(keyset_id.clone(), 1.into(), &SplitTarget::default())?;
+
+    let mint_response = wallet_client
+        .post_mint(
+            MINT_URL.parse()?,
+            &mint_quote.quote,
+            premint_secrets.clone(),
+        )
+        .await?;
+
+    let pre_swap_proofs = construct_proofs(
+        mint_response.signatures,
+        premint_secrets.rs(),
+        premint_secrets.secrets(),
+        &mint_keys.clone().keys,
+    )?;
+
+    // Construct messages that will overflow
+
+    let amount = 2_u64.pow(63);
+
+    let pre_mint_amount =
+        PreMintSecrets::random(keyset_id.clone(), amount.into(), &SplitTarget::default())?;
+    let pre_mint_amount_two =
+        PreMintSecrets::random(keyset_id.clone(), amount.into(), &SplitTarget::default())?;
+
+    let mut pre_mint =
+        PreMintSecrets::random(keyset_id.clone(), 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: {:?}",
+        pre_swap_proofs.iter().map(|p| p.amount).sum::<Amount>()
+    );
+    println!(
+        "Post swap amount: {:?}",
+        post_swap_proofs.iter().map(|p| p.amount).sum::<Amount>()
+    );
+
+    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();
+
+        start_mint(ln_backends).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(())
+}