sqlite: get and set last poll timestamp
This commit is contained in:
parent
8fb74d1cf9
commit
a2b79f1b07
@ -43,7 +43,7 @@ use miniscript::bitcoin::{
|
||||
secp256k1,
|
||||
};
|
||||
|
||||
const DB_VERSION: i64 = 5;
|
||||
const DB_VERSION: i64 = 6;
|
||||
|
||||
/// Last database version for which Bitcoin transactions were not stored in database. In practice
|
||||
/// this meant we relied on the bitcoind watchonly wallet to store them for us.
|
||||
@ -371,6 +371,20 @@ impl SqliteConn {
|
||||
.expect("Database must be available");
|
||||
}
|
||||
|
||||
// Sqlite supports i64 integers so we use u32 for the timestamp.
|
||||
/// Set the last poll timestamp, where `timestamp` is seconds since UNIX epoch.
|
||||
pub fn set_wallet_last_poll_timestamp(&mut self, timestamp: u32) -> Result<(), SqliteDbError> {
|
||||
db_exec(&mut self.conn, |db_tx| {
|
||||
db_tx
|
||||
.execute(
|
||||
"UPDATE wallets SET last_poll_timestamp = (?1) WHERE id = (?2)",
|
||||
rusqlite::params![timestamp, WALLET_ID],
|
||||
)
|
||||
.map(|_| ())
|
||||
})
|
||||
.map_err(SqliteDbError::Rusqlite)
|
||||
}
|
||||
|
||||
/// Get all the coins from DB, optionally filtered by coin status and/or outpoint.
|
||||
pub fn coins(
|
||||
&mut self,
|
||||
@ -2384,7 +2398,7 @@ CREATE TABLE labels (
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn v0_to_v5_migration() {
|
||||
fn v0_to_v6_migration() {
|
||||
let secp = secp256k1::Secp256k1::verification_only();
|
||||
|
||||
// Create a database with version 0, using the old schema.
|
||||
@ -2490,7 +2504,7 @@ CREATE TABLE labels (
|
||||
{
|
||||
let mut conn = db.connection().unwrap();
|
||||
let version = conn.db_version();
|
||||
assert_eq!(version, 5);
|
||||
assert_eq!(version, 6);
|
||||
}
|
||||
// We should now be able to insert another PSBT, to query both, and the first PSBT must
|
||||
// have no associated timestamp.
|
||||
@ -2552,11 +2566,19 @@ CREATE TABLE labels (
|
||||
assert_eq!(db_labels[0].value, "hello");
|
||||
}
|
||||
|
||||
// In v6, we can get and set the last poll timestamp.
|
||||
{
|
||||
let mut conn = db.connection().unwrap();
|
||||
assert!(conn.db_wallet().last_poll_timestamp.is_none());
|
||||
conn.set_wallet_last_poll_timestamp(1234567).unwrap();
|
||||
assert_eq!(conn.db_wallet().last_poll_timestamp, Some(1234567));
|
||||
}
|
||||
|
||||
fs::remove_dir_all(tmp_dir).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn v3_to_v5_migration() {
|
||||
fn v3_to_v6_migration() {
|
||||
let secp = secp256k1::Secp256k1::verification_only();
|
||||
|
||||
// Create a database with version 3, using the old schema.
|
||||
@ -2718,10 +2740,10 @@ CREATE TABLE labels (
|
||||
|
||||
// Migrate the DB.
|
||||
maybe_apply_migration(&db_path, &bitcoin_txs).unwrap();
|
||||
assert_eq!(conn.db_version(), 5);
|
||||
assert_eq!(conn.db_version(), 6);
|
||||
// Migrating twice will be a no-op. No need to pass `bitcoin_txs` second time.
|
||||
maybe_apply_migration(&db_path, &[]).unwrap();
|
||||
assert!(conn.db_version() == 5);
|
||||
assert!(conn.db_version() == 6);
|
||||
let coins_post = conn.coins(&[], &[]);
|
||||
assert_eq!(coins_pre, coins_post);
|
||||
}
|
||||
|
||||
@ -30,7 +30,8 @@ CREATE TABLE wallets (
|
||||
main_descriptor TEXT NOT NULL,
|
||||
deposit_derivation_index INTEGER NOT NULL,
|
||||
change_derivation_index INTEGER NOT NULL,
|
||||
rescan_timestamp INTEGER
|
||||
rescan_timestamp INTEGER,
|
||||
last_poll_timestamp INTEGER
|
||||
);
|
||||
|
||||
/* Our (U)TxOs.
|
||||
@ -140,6 +141,7 @@ pub struct DbWallet {
|
||||
pub deposit_derivation_index: bip32::ChildNumber,
|
||||
pub change_derivation_index: bip32::ChildNumber,
|
||||
pub rescan_timestamp: Option<u32>,
|
||||
pub last_poll_timestamp: Option<u32>,
|
||||
}
|
||||
|
||||
impl TryFrom<&rusqlite::Row<'_>> for DbWallet {
|
||||
@ -159,6 +161,7 @@ impl TryFrom<&rusqlite::Row<'_>> for DbWallet {
|
||||
let change_derivation_index = bip32::ChildNumber::from(der_idx);
|
||||
|
||||
let rescan_timestamp = row.get(5)?;
|
||||
let last_poll_timestamp = row.get(6)?;
|
||||
|
||||
Ok(DbWallet {
|
||||
id,
|
||||
@ -167,6 +170,7 @@ impl TryFrom<&rusqlite::Row<'_>> for DbWallet {
|
||||
deposit_derivation_index,
|
||||
change_derivation_index,
|
||||
rescan_timestamp,
|
||||
last_poll_timestamp,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,6 +294,19 @@ fn migrate_v4_to_v5(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn migrate_v5_to_v6(conn: &mut rusqlite::Connection) -> Result<(), SqliteDbError> {
|
||||
db_exec(conn, |tx| {
|
||||
tx.execute(
|
||||
"ALTER TABLE wallets ADD COLUMN last_poll_timestamp INTEGER",
|
||||
rusqlite::params![],
|
||||
)?;
|
||||
tx.execute("UPDATE version SET version = 6", rusqlite::params![])?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check the database version and if necessary apply the migrations to upgrade it to the current
|
||||
/// one. The `bitcoin_txs` parameter is here for the migration from versions 4 and earlier, which
|
||||
/// did not store the Bitcoin transactions in database, to versions 5 and later, which do. For a
|
||||
@ -342,6 +355,11 @@ pub fn maybe_apply_migration(
|
||||
migrate_v4_to_v5(&mut conn, bitcoin_txs)?;
|
||||
log::warn!("Migration from database version 4 to version 5 successful.");
|
||||
}
|
||||
5 => {
|
||||
log::warn!("Upgrading database from version 5 to version 6.");
|
||||
migrate_v5_to_v6(&mut conn)?;
|
||||
log::warn!("Migration from database version 5 to version 6 successful.");
|
||||
}
|
||||
_ => return Err(SqliteDbError::UnsupportedVersion(version)),
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user