db: store derivation index also for addresses from the change desc
This doubles the storage required but there is no way around it if we want the poller to detect those coins without grinding.
This commit is contained in:
parent
4f3daa7741
commit
9b04a55147
@ -238,17 +238,22 @@ impl SqliteConn {
|
||||
// Update the address to derivation index mapping.
|
||||
// TODO: have this as a helper in descriptors.rs
|
||||
let next_la_index = next_index + LOOK_AHEAD_LIMIT - 1;
|
||||
let next_la_address = db_wallet
|
||||
let next_receive_address = db_wallet
|
||||
.main_descriptor
|
||||
.receive_descriptor()
|
||||
.derive(next_la_index.into(), secp)
|
||||
.address(network);
|
||||
db_tx
|
||||
.execute(
|
||||
"INSERT INTO addresses (address, derivation_index) VALUES (?1, ?2)",
|
||||
rusqlite::params![next_la_address.to_string(), next_la_index],
|
||||
)
|
||||
.map(|_| ())
|
||||
let next_change_address = db_wallet
|
||||
.main_descriptor
|
||||
.change_descriptor()
|
||||
.derive(next_la_index.into(), secp)
|
||||
.address(network);
|
||||
db_tx.execute(
|
||||
"INSERT INTO addresses (receive_address, change_address, derivation_index) VALUES (?1, ?2, ?3)",
|
||||
rusqlite::params![next_receive_address.to_string(), next_change_address.to_string(), next_la_index],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.expect("Database must be available")
|
||||
}
|
||||
@ -363,7 +368,7 @@ impl SqliteConn {
|
||||
pub fn db_address(&mut self, address: &bitcoin::Address) -> Option<DbAddress> {
|
||||
db_query(
|
||||
&mut self.conn,
|
||||
"SELECT * FROM addresses WHERE address = ?1",
|
||||
"SELECT * FROM addresses WHERE receive_address = ?1 OR change_address = ?1",
|
||||
rusqlite::params![address.to_string()],
|
||||
|row| row.try_into(),
|
||||
)
|
||||
@ -721,6 +726,15 @@ mod tests {
|
||||
let db_addr = conn.db_address(&addr).unwrap();
|
||||
assert_eq!(db_addr.derivation_index, 0.into());
|
||||
|
||||
// And also for the change address
|
||||
let addr = options
|
||||
.main_descriptor
|
||||
.change_descriptor()
|
||||
.derive(0.into(), &secp)
|
||||
.address(options.bitcoind_network);
|
||||
let db_addr = conn.db_address(&addr).unwrap();
|
||||
assert_eq!(db_addr.derivation_index, 0.into());
|
||||
|
||||
// There is the index for the 199th index (look-ahead limit)
|
||||
let addr = options
|
||||
.main_descriptor
|
||||
@ -742,6 +756,15 @@ mod tests {
|
||||
conn.increment_derivation_index(&secp);
|
||||
let db_addr = conn.db_address(&addr).unwrap();
|
||||
assert_eq!(db_addr.derivation_index, 200.into());
|
||||
|
||||
// Same for the change descriptor.
|
||||
let addr = options
|
||||
.main_descriptor
|
||||
.change_descriptor()
|
||||
.derive(200.into(), &secp)
|
||||
.address(options.bitcoind_network);
|
||||
let db_addr = conn.db_address(&addr).unwrap();
|
||||
assert_eq!(db_addr.derivation_index, 200.into());
|
||||
}
|
||||
|
||||
fs::remove_dir_all(&tmp_dir).unwrap();
|
||||
|
||||
@ -57,7 +57,8 @@ CREATE TABLE coins (
|
||||
* we can get the derivation index from the parent descriptor from bitcoind.
|
||||
*/
|
||||
CREATE TABLE addresses (
|
||||
address TEXT NOT NULL UNIQUE,
|
||||
receive_address TEXT NOT NULL UNIQUE,
|
||||
change_address TEXT NOT NULL UNIQUE,
|
||||
derivation_index INTEGER NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
@ -195,7 +196,8 @@ impl TryFrom<&rusqlite::Row<'_>> for DbCoin {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DbAddress {
|
||||
pub address: bitcoin::Address,
|
||||
pub receive_address: bitcoin::Address,
|
||||
pub change_address: bitcoin::Address,
|
||||
pub derivation_index: bip32::ChildNumber,
|
||||
}
|
||||
|
||||
@ -203,15 +205,21 @@ impl TryFrom<&rusqlite::Row<'_>> for DbAddress {
|
||||
type Error = rusqlite::Error;
|
||||
|
||||
fn try_from(row: &rusqlite::Row) -> Result<Self, Self::Error> {
|
||||
let address: String = row.get(0)?;
|
||||
let address = bitcoin::Address::from_str(&address).expect("We only store valid addresses");
|
||||
let receive_address: String = row.get(0)?;
|
||||
let receive_address =
|
||||
bitcoin::Address::from_str(&receive_address).expect("We only store valid addresses");
|
||||
|
||||
let derivation_index: u32 = row.get(1)?;
|
||||
let change_address: String = row.get(1)?;
|
||||
let change_address =
|
||||
bitcoin::Address::from_str(&change_address).expect("We only store valid addresses");
|
||||
|
||||
let derivation_index: u32 = row.get(2)?;
|
||||
let derivation_index = bip32::ChildNumber::from(derivation_index);
|
||||
assert!(derivation_index.is_normal());
|
||||
|
||||
Ok(DbAddress {
|
||||
address,
|
||||
receive_address,
|
||||
change_address,
|
||||
derivation_index,
|
||||
})
|
||||
}
|
||||
|
||||
@ -95,15 +95,19 @@ pub fn create_fresh_db(
|
||||
// necessarily 0.
|
||||
let mut query = String::with_capacity(100 * LOOK_AHEAD_LIMIT as usize);
|
||||
for index in 0..LOOK_AHEAD_LIMIT {
|
||||
// TODO: have this as a helper in descriptors.rs
|
||||
let address = options
|
||||
let receive_address = options
|
||||
.main_descriptor
|
||||
.receive_descriptor()
|
||||
.derive(index.into(), secp)
|
||||
.address(options.bitcoind_network);
|
||||
let change_address = options
|
||||
.main_descriptor
|
||||
.change_descriptor()
|
||||
.derive(index.into(), secp)
|
||||
.address(options.bitcoind_network);
|
||||
query += &format!(
|
||||
"INSERT INTO addresses (address, derivation_index) VALUES (\"{}\", {});\n",
|
||||
address, index
|
||||
"INSERT INTO addresses (receive_address, change_address, derivation_index) VALUES (\"{}\", \"{}\", {});\n",
|
||||
receive_address, change_address, index
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user