Skip to content

Commit

Permalink
Merge #1523: backport: fix fetching of coins txids before migration
Browse files Browse the repository at this point in the history
ed39630 fix fetching of coins txids before migration (edouardparis)

Pull request description:

  backport of #1522

ACKs for top commit:
  edouardparis:
    Self-ACK ed39630

Tree-SHA512: 1446950a6fe5f2b1ebe77903a8c023cc61bf146a7a01f8a5f7d86344c6fb01ef0bf8266f487ff09811a49214c151c13e65ab2935943c735661a9cd8980c24a54
  • Loading branch information
edouardparis committed Jan 7, 2025
2 parents c43d3bf + ed39630 commit e72dd8b
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 7 deletions.
139 changes: 139 additions & 0 deletions lianad/src/database/sqlite/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,28 @@ impl SqliteConn {
.expect("Db must not fail")
}

pub fn db_list_all_txids(&mut self) -> Vec<bitcoin::Txid> {
db_query(
&mut self.conn,
"
SELECT txid AS id
FROM coins
UNION
SELECT spend_txid AS id
FROM coins
WHERE spend_txid IS NOT NULL
",
rusqlite::params![],
|row| {
let txid: Vec<u8> = row.get(0)?;
let txid: bitcoin::Txid =
encode::deserialize(&txid).expect("We only store valid txids");
Ok(txid)
},
)
.expect("Db must not fail")
}

/// Store transactions in database, ignoring any that already exist.
pub fn new_txs(&mut self, txs: &[bitcoin::Transaction]) {
db_exec(&mut self.conn, |db_tx| {
Expand Down Expand Up @@ -2371,6 +2393,123 @@ CREATE TABLE labels (
fs::remove_dir_all(tmp_dir).unwrap();
}

#[test]
fn sqlite_list_all_txids() {
let (tmp_dir, _, _, db) = dummy_db();

{
let mut conn = db.connection().unwrap();

let txs: Vec<_> = (0..7)
.map(|i| bitcoin::Transaction {
version: bitcoin::transaction::Version::TWO,
lock_time: bitcoin::absolute::LockTime::from_height(i).unwrap(),
input: vec![bitcoin::TxIn::default()], // a single input
output: vec![bitcoin::TxOut::minimal_non_dust(ScriptBuf::default())], // a single output,
})
.collect();
conn.new_txs(&txs);

let coins = [
Coin {
outpoint: bitcoin::OutPoint::new(txs.first().unwrap().txid(), 1),
is_immature: false,
block_info: None,
amount: bitcoin::Amount::from_sat(98765),
derivation_index: bip32::ChildNumber::from_normal_idx(10).unwrap(),
is_change: false,
spend_txid: None,
spend_block: None,
is_from_self: false,
},
Coin {
outpoint: bitcoin::OutPoint::new(txs.get(1).unwrap().txid(), 2),
is_immature: false,
block_info: Some(BlockInfo {
height: 101_095,
time: 1_121_000,
}),
amount: bitcoin::Amount::from_sat(98765),
derivation_index: bip32::ChildNumber::from_normal_idx(100).unwrap(),
is_change: false,
spend_txid: None,
spend_block: None,
is_from_self: false,
},
Coin {
outpoint: bitcoin::OutPoint::new(txs.get(2).unwrap().txid(), 3),
is_immature: false,
block_info: Some(BlockInfo {
height: 101_099,
time: 1_122_000,
}),
amount: bitcoin::Amount::from_sat(98765),
derivation_index: bip32::ChildNumber::from_normal_idx(1000).unwrap(),
is_change: false,
spend_txid: Some(txs.get(3).unwrap().txid()),
spend_block: Some(BlockInfo {
height: 101_199,
time: 1_123_000,
}),
is_from_self: false,
},
Coin {
outpoint: bitcoin::OutPoint::new(txs.get(4).unwrap().txid(), 4),
is_immature: true,
block_info: Some(BlockInfo {
height: 101_100,
time: 1_124_000,
}),
amount: bitcoin::Amount::from_sat(98765),
derivation_index: bip32::ChildNumber::from_normal_idx(10000).unwrap(),
is_change: false,
spend_txid: None,
spend_block: None,
is_from_self: false,
},
Coin {
outpoint: bitcoin::OutPoint::new(txs.get(5).unwrap().txid(), 5),
is_immature: false,
block_info: Some(BlockInfo {
height: 101_102,
time: 1_125_000,
}),
amount: bitcoin::Amount::from_sat(98765),
derivation_index: bip32::ChildNumber::from_normal_idx(100000).unwrap(),
is_change: false,
spend_txid: Some(txs.get(6).unwrap().txid()),
spend_block: Some(BlockInfo {
height: 101_105,
time: 1_126_000,
}),
is_from_self: false,
},
];
conn.new_unspent_coins(&coins);
conn.confirm_coins(
&coins
.iter()
.filter_map(|c| c.block_info.map(|b| (c.outpoint, b.height, b.time)))
.collect::<Vec<_>>(),
);
conn.confirm_spend(
&coins
.iter()
.filter_map(|c| {
c.spend_block
.as_ref()
.map(|b| (c.outpoint, c.spend_txid.unwrap(), b.height, b.time))
})
.collect::<Vec<_>>(),
);

let db_txids = conn.db_list_all_txids();
assert_eq!(db_txids.len(), txs.len());
}

fs::remove_dir_all(tmp_dir).unwrap();
}

#[test]
fn sqlite_list_saved_txids() {
let (tmp_dir, _, _, db) = dummy_db();
Expand Down
9 changes: 2 additions & 7 deletions lianad/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{
};

use std::{
collections, error, fmt, fs, io, path,
error, fmt, fs, io, path,
sync::{self, mpsc},
thread,
};
Expand Down Expand Up @@ -217,12 +217,7 @@ fn setup_sqlite(
let bit = bitcoind.as_ref().ok_or(StartupError::DbMigrateBitcoinTxs(
"a connection to a Bitcoin backend is required",
))?;
let coins = conn.db_coins(&[]);
let coins_txids = coins
.iter()
.map(|c| c.outpoint.txid)
.chain(coins.iter().filter_map(|c| c.spend_txid))
.collect::<collections::HashSet<_>>();
let coins_txids = conn.db_list_all_txids();
coins_txids
.into_iter()
.map(|txid| bit.get_transaction(&txid).map(|res| res.tx))
Expand Down

0 comments on commit e72dd8b

Please sign in to comment.