Bladeren bron

Improve add transaction (#1164)

* fix(wallet): move transaction ID calculation before database operations

* fix(sql): remove on ys from on conflict transaction insert

Since the id is created from the ys we know that if there is a conflict
the ys are the same and do not need to be updated.

* feat: bench for transactio id

* chore: fmt
tsk 3 weken geleden
bovenliggende
commit
95aa64477a

+ 1 - 0
Cargo.toml

@@ -66,6 +66,7 @@ clap = { version = "4.5.31", features = ["derive"] }
 ciborium = { version = "0.2.2", default-features = false, features = ["std"] }
 cbor-diag = "0.1.12"
 config = { version = "0.15.11", features = ["toml"] }
+criterion = "0.6.0"
 futures = { version = "0.3.28", default-features = false, features = ["async-await"] }
 lightning-invoice = { version = "0.33.0", features = ["serde", "std"] }
 lightning = { version = "0.1.2", default-features = false, features = ["std"]}

+ 5 - 0
crates/cdk-common/Cargo.toml

@@ -53,3 +53,8 @@ wasm-bindgen-futures = "0.4"
 rand.workspace = true
 bip39.workspace = true
 wasm-bindgen-test = "0.3"
+criterion.workspace = true
+
+[[bench]]
+name = "transaction_id_benchmark"
+harness = false

+ 29 - 0
crates/cdk-common/benches/transaction_id_benchmark.rs

@@ -0,0 +1,29 @@
+use cashu::nuts::nut01::SecretKey;
+use cashu::PublicKey;
+use cdk_common::wallet::TransactionId;
+use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
+
+fn generate_public_keys(count: usize) -> Vec<PublicKey> {
+    (0..count)
+        .map(|_| SecretKey::generate().public_key())
+        .collect()
+}
+
+fn bench_transaction_id(c: &mut Criterion) {
+    let mut group = c.benchmark_group("TransactionId::new");
+
+    let sizes = vec![1, 10, 50, 100, 500];
+
+    for size in sizes {
+        let public_keys = generate_public_keys(size);
+
+        group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, _| {
+            b.iter(|| TransactionId::new(public_keys.clone()));
+        });
+    }
+
+    group.finish();
+}
+
+criterion_group!(benches, bench_transaction_id);
+criterion_main!(benches);

+ 3 - 1
crates/cdk-redb/src/wallet/mod.rs

@@ -827,6 +827,8 @@ impl WalletDatabase for WalletRedbDatabase {
 
     #[instrument(skip(self))]
     async fn add_transaction(&self, transaction: Transaction) -> Result<(), Self::Err> {
+        let id = transaction.id();
+
         let write_txn = self.db.begin_write().map_err(Error::from)?;
 
         {
@@ -835,7 +837,7 @@ impl WalletDatabase for WalletRedbDatabase {
                 .map_err(Error::from)?;
             table
                 .insert(
-                    transaction.id().as_slice(),
+                    id.as_slice(),
                     serde_json::to_string(&transaction)
                         .map_err(Error::from)?
                         .as_str(),

+ 5 - 3
crates/cdk-sql-common/src/wallet/mod.rs

@@ -954,7 +954,6 @@ ON CONFLICT(id) DO UPDATE SET
 
     #[instrument(skip(self))]
     async fn add_transaction(&self, transaction: Transaction) -> Result<(), Self::Err> {
-        let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
         let mint_url = transaction.mint_url.to_string();
         let direction = transaction.direction.to_string();
         let unit = transaction.unit.to_string();
@@ -966,6 +965,10 @@ ON CONFLICT(id) DO UPDATE SET
             .flat_map(|y| y.to_bytes().to_vec())
             .collect::<Vec<_>>();
 
+        let id = transaction.id();
+
+        let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
+
         query(
             r#"
 INSERT INTO transactions
@@ -978,7 +981,6 @@ ON CONFLICT(id) DO UPDATE SET
     unit = excluded.unit,
     amount = excluded.amount,
     fee = excluded.fee,
-    ys = excluded.ys,
     timestamp = excluded.timestamp,
     memo = excluded.memo,
     metadata = excluded.metadata,
@@ -988,7 +990,7 @@ ON CONFLICT(id) DO UPDATE SET
 ;
         "#,
         )?
-        .bind("id", transaction.id().as_slice().to_vec())
+        .bind("id", id.as_slice().to_vec())
         .bind("mint_url", mint_url)
         .bind("direction", direction)
         .bind("unit", unit)

+ 1 - 1
crates/cdk/Cargo.toml

@@ -143,7 +143,7 @@ rand.workspace = true
 cdk-sqlite.workspace = true
 bip39.workspace = true
 tracing-subscriber.workspace = true
-criterion = "0.6.0"
+criterion.workspace = true
 reqwest = { workspace = true }
 anyhow.workspace = true
 ureq = { version = "3.1.0", features = ["json"] }