diff --git a/zcash_client_sqlite/src/prepared.rs b/zcash_client_sqlite/src/prepared.rs index b64c72348..f80114ae5 100644 --- a/zcash_client_sqlite/src/prepared.rs +++ b/zcash_client_sqlite/src/prepared.rs @@ -89,9 +89,9 @@ impl<'a, P> DataConnStmtCache<'a, P> { )?, stmt_update_tx_data: wallet_db.conn.prepare( "UPDATE transactions - SET expiry_height = :expiry_height, - raw = :raw, - fee = IFNULL(:fee, fee) + SET expiry_height = :expiry_height, + raw = :raw, + fee = IFNULL(:fee, fee) WHERE txid = :txid", )?, stmt_select_tx_ref: wallet_db.conn.prepare( @@ -135,12 +135,17 @@ impl<'a, P> DataConnStmtCache<'a, P> { )?, stmt_update_sent_note: wallet_db.conn.prepare( "UPDATE sent_notes - SET from_account = ?, address = ?, value = ?, memo = ? - WHERE tx = ? AND output_pool = ? AND output_index = ?", + SET from_account = :account, + address = :address, + value = :value, + memo = IFNULL(:memo, memo) + WHERE tx = :tx + AND output_pool = :output_pool + AND output_index = :output_index", )?, stmt_insert_sent_note: wallet_db.conn.prepare( "INSERT INTO sent_notes (tx, output_pool, output_index, from_account, address, value, memo) - VALUES (?, ?, ?, ?, ?, ?, ?)", + VALUES (:tx, :output_pool, :output_index, :from_account, :address, :value, :memo)" )?, stmt_insert_witness: wallet_db.conn.prepare( "INSERT INTO sapling_witnesses (note, block, witness) @@ -396,7 +401,12 @@ impl<'a, P> DataConnStmtCache<'a, P> { (":value", &(value as i64)), (":rcm", &rcm.as_ref()), (":nf", &nf.as_ref().map(|nf| nf.0.as_ref())), - (":memo", &memo.map(|m| m.as_slice())), + ( + ":memo", + &memo + .filter(|m| *m != &MemoBytes::empty()) + .map(|m| m.as_slice()), + ), (":is_change", &is_change), ]; @@ -433,7 +443,12 @@ impl<'a, P> DataConnStmtCache<'a, P> { (":value", &(value as i64)), (":rcm", &rcm.as_ref()), (":nf", &nf.as_ref().map(|nf| nf.0.as_ref())), - (":memo", &memo.map(|m| m.as_slice())), + ( + ":memo", + &memo + .filter(|m| *m != &MemoBytes::empty()) + .map(|m| m.as_slice()), + ), (":is_change", &is_change), (":tx", &tx_ref), (":output_index", &(output_index as i64)), @@ -478,18 +493,21 @@ impl<'a, P> DataConnStmtCache<'a, P> { value: Amount, memo: Option<&MemoBytes>, ) -> Result<(), SqliteClientError> { - let ivalue: i64 = value.into(); - self.stmt_insert_sent_note.execute(params![ - tx_ref, - pool_type.typecode(), - (output_index as i64), - u32::from(account), - to_str, - ivalue, - memo.filter(|m| *m != &MemoBytes::empty()) - .map(|m| m.as_slice()), - ])?; - + let sql_args: &[(&str, &dyn ToSql)] = &[ + (":tx", &tx_ref), + (":output_pool", &pool_type.typecode()), + (":output_index", &i64::try_from(output_index).unwrap()), + (":from_account", &u32::from(account)), + (":address", &to_str), + (":value", &i64::from(value)), + ( + ":memo", + &memo + .filter(|m| *m != &MemoBytes::empty()) + .map(|m| m.as_slice()), + ), + ]; + self.stmt_insert_sent_note.execute_named(sql_args)?; Ok(()) } @@ -507,17 +525,21 @@ impl<'a, P> DataConnStmtCache<'a, P> { pool_type: PoolType, output_index: usize, ) -> Result { - let ivalue: i64 = value.into(); - match self.stmt_update_sent_note.execute(params![ - u32::from(account), - to_str, - ivalue, - memo.filter(|m| *m != &MemoBytes::empty()) - .map(|m| m.as_slice()), - tx_ref, - pool_type.typecode(), - output_index as i64, - ])? { + let sql_args: &[(&str, &dyn ToSql)] = &[ + (":account", &u32::from(account)), + (":address", &to_str), + (":value", &i64::from(value)), + ( + ":memo", + &memo + .filter(|m| *m != &MemoBytes::empty()) + .map(|m| m.as_slice()), + ), + (":tx", &tx_ref), + (":output_pool", &pool_type.typecode()), + (":output_index", &i64::try_from(output_index).unwrap()), + ]; + match self.stmt_update_sent_note.execute_named(sql_args)? { 0 => Ok(false), 1 => Ok(true), _ => unreachable!("tx_output constraint is marked as UNIQUE"), diff --git a/zcash_client_sqlite/src/wallet/init.rs b/zcash_client_sqlite/src/wallet/init.rs index a8dae4d6c..9613d12fc 100644 --- a/zcash_client_sqlite/src/wallet/init.rs +++ b/zcash_client_sqlite/src/wallet/init.rs @@ -849,7 +849,6 @@ mod tests { received_notes.is_change AS is_change, CASE WHEN received_notes.memo IS NULL THEN 0 - WHEN received_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0 ELSE 1 END AS memo_present FROM transactions @@ -866,7 +865,6 @@ mod tests { false AS is_change, CASE WHEN sent_notes.memo IS NULL THEN 0 - WHEN sent_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0 ELSE 1 END AS memo_present FROM transactions @@ -883,7 +881,6 @@ mod tests { SUM( CASE WHEN received_notes.memo IS NULL THEN 0 - WHEN received_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0 ELSE 1 END ) AS memo_count, @@ -906,7 +903,6 @@ mod tests { SUM( CASE WHEN sent_notes.memo IS NULL THEN 0 - WHEN sent_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0 ELSE 1 END ) AS memo_count, diff --git a/zcash_client_sqlite/src/wallet/init/migrations/add_transaction_views.rs b/zcash_client_sqlite/src/wallet/init/migrations/add_transaction_views.rs index bd65b607e..32eba4f7a 100644 --- a/zcash_client_sqlite/src/wallet/init/migrations/add_transaction_views.rs +++ b/zcash_client_sqlite/src/wallet/init/migrations/add_transaction_views.rs @@ -102,6 +102,12 @@ impl RusqliteMigration for Migration

{ } } + transaction.execute_batch( + "UPDATE sent_notes SET memo = NULL + WHERE memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'; + UPDATE received_notes SET memo = NULL + WHERE memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';")?; + transaction.execute_batch( "CREATE VIEW v_tx_sent AS SELECT transactions.id_tx AS id_tx, @@ -115,7 +121,6 @@ impl RusqliteMigration for Migration

{ SUM( CASE WHEN sent_notes.memo IS NULL THEN 0 - WHEN sent_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0 ELSE 1 END ) AS memo_count, @@ -136,7 +141,6 @@ impl RusqliteMigration for Migration

{ SUM( CASE WHEN received_notes.memo IS NULL THEN 0 - WHEN received_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0 ELSE 1 END ) AS memo_count, @@ -172,7 +176,6 @@ impl RusqliteMigration for Migration

{ received_notes.is_change AS is_change, CASE WHEN received_notes.memo IS NULL THEN 0 - WHEN received_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0 ELSE 1 END AS memo_present FROM transactions @@ -189,7 +192,6 @@ impl RusqliteMigration for Migration

{ false AS is_change, CASE WHEN sent_notes.memo IS NULL THEN 0 - WHEN sent_notes.memo = X'F600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' THEN 0 ELSE 1 END AS memo_present FROM transactions @@ -214,7 +216,7 @@ mod tests { #[cfg(feature = "transparent-inputs")] use { - crate::wallet::init::{init_wallet_db_internal, WalletMigration2}, + crate::wallet::init::WalletMigration2, rusqlite::params, zcash_client_backend::{encoding::AddressCodec, keys::UnifiedSpendingKey}, zcash_primitives::{ @@ -231,13 +233,20 @@ mod tests { }, }; - use crate::{tests, wallet::init::init_wallet_db, WalletDb}; + use crate::{ + tests, + wallet::init::{ + init_wallet_db, init_wallet_db_internal, + migrations::addresses_table::ADDRESSES_TABLE_MIGRATION, + }, + WalletDb, + }; #[test] fn transaction_views() { let data_file = NamedTempFile::new().unwrap(); let mut db_data = WalletDb::for_path(data_file.path(), tests::network()).unwrap(); - init_wallet_db(&mut db_data, None).unwrap(); + init_wallet_db_internal(&mut db_data, None, Some(ADDRESSES_TABLE_MIGRATION)).unwrap(); db_data.conn.execute_batch( "INSERT INTO accounts (account, ufvk) VALUES (0, ''); @@ -257,6 +266,8 @@ mod tests { VALUES (0, 1, 0, '', 7, '', 'b', true, X'63');", ).unwrap(); + init_wallet_db(&mut db_data, None).unwrap(); + let mut q = db_data .conn .prepare("SELECT received_total, received_note_count, memo_count FROM v_tx_received")