database: permit to remove coins from DB

This commit is contained in:
Antoine Poinsot 2023-02-02 16:35:18 +01:00
parent 62c4b9a01c
commit ed156543c9
No known key found for this signature in database
GPG Key ID: E13FC145CD3F4304
3 changed files with 35 additions and 0 deletions

View File

@ -89,6 +89,9 @@ pub trait DatabaseConnection {
/// Store new UTxOs. Coins must not already be in database.
fn new_unspent_coins(&mut self, coins: &[Coin]);
/// Remove some UTxOs from the database.
fn remove_coins(&mut self, coins: &[bitcoin::OutPoint]);
/// Mark a set of coins as being confirmed at a specified height and block time.
fn confirm_coins(&mut self, outpoints: &[(bitcoin::OutPoint, i32, u32)]);
@ -196,6 +199,10 @@ impl DatabaseConnection for SqliteConn {
self.new_unspent_coins(coins)
}
fn remove_coins(&mut self, outpoints: &[bitcoin::OutPoint]) {
self.remove_coins(outpoints)
}
fn confirm_coins<'a>(&mut self, outpoints: &[(bitcoin::OutPoint, i32, u32)]) {
self.confirm_coins(outpoints)
}

View File

@ -363,6 +363,21 @@ impl SqliteConn {
.expect("Database must be available")
}
/// Remove a set of coins from the database.
pub fn remove_coins(&mut self, outpoints: &[bitcoin::OutPoint]) {
db_exec(&mut self.conn, |db_tx| {
for outpoint in outpoints {
db_tx.execute(
"DELETE FROM coins WHERE txid = ?1 AND vout = ?2",
rusqlite::params![outpoint.txid.to_vec(), outpoint.vout,],
)?;
}
Ok(())
})
.expect("Database must be available")
}
/// Mark a set of coins as confirmed.
pub fn confirm_coins<'a>(
&mut self,
@ -705,6 +720,13 @@ mod tests {
conn.new_unspent_coins(&[coin_a]);
assert_eq!(conn.coins(CoinType::All)[0].outpoint, coin_a.outpoint);
// We can also remove it. Say the unconfirmed tx that created it got replaced.
conn.remove_coins(&[coin_a.outpoint]);
assert!(conn.coins(CoinType::All).is_empty());
// Add it back for the rest of the test.
conn.new_unspent_coins(&[coin_a]);
// We can query it by its outpoint
let coins = conn.db_coins(&[coin_a.outpoint]);
assert_eq!(coins.len(), 1);

View File

@ -220,6 +220,12 @@ impl DatabaseConnection for DummyDatabase {
}
}
fn remove_coins(&mut self, outpoints: &[bitcoin::OutPoint]) {
for op in outpoints {
self.db.write().unwrap().coins.remove(op);
}
}
fn confirm_coins<'a>(&mut self, outpoints: &[(bitcoin::OutPoint, i32, u32)]) {
for (op, height, time) in outpoints {
let mut db = self.db.write().unwrap();