Skip to content

Commit

Permalink
fix: delete multiple proofs
Browse files Browse the repository at this point in the history
  • Loading branch information
ngutech21 committed Apr 1, 2024
1 parent c3b1198 commit db24ac4
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 8 deletions.
82 changes: 81 additions & 1 deletion integrationtests/tests/tests_lnd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ async fn test_bolt11_mint() -> anyhow::Result<()> {
assert!(keysets.is_ok());

// create wallet
let localstore = SqliteLocalStore::with_in_memory().await?;
let tmp_dir = tempfile::tempdir()?;
let wallet_file = tmp_dir.path().join("wallet.db");
let localstore = SqliteLocalStore::with_path(wallet_file.to_str().unwrap().to_owned()).await?;
let wallet = WalletBuilder::default()
.with_client(client)
.with_localstore(localstore)
Expand Down Expand Up @@ -195,5 +197,83 @@ async fn test_bolt11_mint() -> anyhow::Result<()> {
let balance = wallet.get_balance().await?;
assert_eq!(5_000, balance);

// send tokens
let exported_tokens = wallet.send_tokens(100).await?;
assert_eq!(100, exported_tokens.total_amount());
let balance = wallet.get_balance().await?;
assert_eq!(4_900, balance);
Ok(())
}

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_bolt11_send() -> anyhow::Result<()> {
// create postgres container that will be destroyed after the test is done
let docker = clients::Cli::default();
let node = Postgres::default().with_host_auth();
let img = RunnableImage::from(node).with_tag("16.2-alpine");
let node = docker.run(img);
let host_port = node.get_host_port_ipv4(5432);

fund_mint_lnd(2_000_000).await?;
open_channel_with_wallet(500_000).await?;

// start mint server
tokio::spawn(async move {
let lnd_settings = LndLightningSettings::new(
lnd_client::LND_MINT_ADDRESS.parse().expect("invalid url"),
"../data/lnd-mint/tls.cert".into(),
"../data/lnd-mint/data/chain/bitcoin/regtest/admin.macaroon".into(),
);

start_mint(host_port, LightningType::Lnd(lnd_settings.clone()), None)
.await
.expect("Could not start mint server");
});

// Wait for the server to start
tokio::time::sleep(Duration::from_millis(800)).await;

let client = CrossPlatformHttpClient::new();
let mint_url = Url::parse("http://127.0.0.1:8686")?;
let keys = client.get_keys(&mint_url).await;
assert!(keys.is_ok());

let keysets = client.get_keysets(&mint_url).await;
assert!(keysets.is_ok());

// create wallet
let tmp_dir = tempfile::tempdir()?;
let wallet_file = tmp_dir.path().join("wallet.db");
let localstore = SqliteLocalStore::with_path(wallet_file.to_str().unwrap().to_owned()).await?;
let wallet = WalletBuilder::default()
.with_client(client)
.with_localstore(localstore)
.with_mint_url(mint_url)
.build()
.await?;

// get initial balance
let balance = wallet.get_balance().await?;
assert_eq!(0, balance, "Initial balance should be 0");

// mint some tokens
let mint_amount = 2_000;
let mint_quote = wallet.create_quote_bolt11(mint_amount).await?;
let hash = mint_quote.clone().quote;

sleep_until(Instant::now() + Duration::from_millis(1_000)).await;
let mint_result = wallet
.mint_tokens(&PaymentMethod::Bolt11, mint_amount.into(), hash.clone())
.await?;
assert_eq!(2_000, mint_result.total_amount());

let balance = wallet.get_balance().await?;
assert_eq!(2_000, balance);

// send tokens
let exported_tokens = wallet.send_tokens(100).await?;
assert_eq!(100, exported_tokens.total_amount());
let balance = wallet.get_balance().await?;
assert_eq!(1_900, balance);
Ok(())
}
55 changes: 48 additions & 7 deletions moksha-wallet/src/localstore/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,21 @@ impl LocalStore for SqliteLocalStore {
.proofs()
.iter()
.map(|p| p.secret.to_owned())
.collect::<Vec<_>>()
.join(", ");
.collect::<Vec<_>>();

let placeholders: Vec<String> = (1..=proof_secrets.len())
.map(|i| format!("?{}", i))
.collect();
let sql = format!(
"DELETE FROM proofs WHERE secret IN ({})",
placeholders.join(",")
);
let mut query = sqlx::query(&sql);
for secret in &proof_secrets {
query = query.bind(secret);
}
query.execute(&mut **tx).await?;

sqlx::query("DELETE FROM proofs WHERE secret in (?);")
.bind(proof_secrets)
.execute(&mut **tx)
.await?;
Ok(())
}

Expand Down Expand Up @@ -99,7 +107,7 @@ impl LocalStore for SqliteLocalStore {
) -> Result<(), MokshaWalletError> {
sqlx::query(
r#"INSERT INTO keysets (keyset_id, mint_url, currency_unit, last_index, public_keys, active) VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT(keyset_id, mint_url) DO UPDATE SET currency_unit = $3, last_index = $4, public_keys = $5, active = $6;
ON CONFLICT(keyset_id, mint_url) DO UPDATE SET currency_unit = $3, public_keys = $5, active = $6;
"#)
.bind(keyset.keyset_id.to_owned())
.bind(keyset.mint_url.as_str())
Expand Down Expand Up @@ -262,4 +270,37 @@ mod tests {
tx.commit().await?;
Ok(())
}

#[tokio::test]
async fn test_delete_multiple_proofs() -> anyhow::Result<()> {
let localstore = SqliteLocalStore::with_in_memory().await?;
let mut tx = localstore.begin_tx().await?;

let tokens: TokenV3 = read_fixture("token_60.cashu")?
.trim()
.to_string()
.try_into()?;
localstore.add_proofs(&mut tx, &tokens.proofs()).await?;

let loaded_tokens = localstore.get_proofs(&mut tx).await?;

assert_eq!(tokens.proofs(), loaded_tokens);

let proofs = tokens
.tokens
.first()
.expect("Tokens is empty")
.proofs
.proofs();
let proof_4 = proofs.first().expect("Proof is empty").to_owned();
let proof_8 = proofs.get(1).expect("Proof is empty").to_owned();

let delete_proofs = vec![proof_4, proof_8].into();
localstore.delete_proofs(&mut tx, &delete_proofs).await?;

let result_tokens = localstore.get_proofs(&mut tx).await?;
assert_eq!(48, result_tokens.total_amount());
tx.commit().await?;
Ok(())
}
}

0 comments on commit db24ac4

Please sign in to comment.