Skip to content

Commit 4b99549

Browse files
committed
Merge #16: WIP: Update bdk_wallet to 3.0.0
51f8b14 chore: Add `.github/pull_request_template.md` (valued mammal) 15d60f2 feat(wallet): Update wallet to read/write locked outpoints (valued mammal) 8dd9ac5 schema: Add migration `0003_schema.up.sql` (valued mammal) 1344f47 Bump dependencies (valued mammal) Pull request description: ### Description Updates `bdk_wallet` from 2.3.0 to 3.0.0, along with companion bumps to `bdk_chain` (0.23.2 → 0.23.3) and `bdk_esplora` dev dependency (0.22.1 → 0.22.2). `bdk_wallet` 3.0.0 adds a `locked_outpoints` field to `ChangeSet`, representing the persisted state of UTXO locks. This PR adds support for reading and writing that state: - Adds migration `0003_schema.up.sql` which creates the `locked_outpoint(txid, vout)` table - Adds `write_locked_outpoints` / `read_locked_outpoints` on `Store`, wired into the existing `write_changeset` / `read_changeset` methods ### Notes to the reviewers The `write_locked_outpoints` implementation uses the `locked_outpoints::ChangeSet` semantics directly: a `true` value inserts the row (`INSERT OR IGNORE`), and a `false` value deletes it. On read, all rows in the table are returned as locked (`true`) (an absent row means unlocked). ### Changelog notice ### Added - Migration `0003_schema.up.sql`: add `locked_outpoint` table for persisting UTXO lock state ### Changed - Bump `bdk_chain` 0.23.2 → 0.23.3 - Bump `bdk_wallet` 2.3.0 → 3.0.0 - Bump `bdk_esplora` (dev) 0.22.1 → 0.22.2 Top commit has no ACKs. Tree-SHA512: cc5beed27cbfb07c60d75f5ecea3144a5ca0f32c1231f921a4d60fb9d4d9e4268a3c923754c5121f2d3e5bcc4c38bf69ff8a75d4bb8c12b052a26d12d6199f19
2 parents f6f8d64 + 51f8b14 commit 4b99549

4 files changed

Lines changed: 72 additions & 4 deletions

File tree

.github/pull_request_template.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### Description
2+
3+
<!-- Describe the purpose of this PR, what's being adding and/or fixed -->
4+
5+
### Notes to the reviewers
6+
7+
<!-- In this section you can include notes directed to the reviewers, like explaining why some parts
8+
of the PR were done in a specific way -->
9+
10+
### Changelog notice
11+
12+
<!-- Notice the release manager should include in the release tag message changelog -->
13+
<!-- See https://keepachangelog.com/en/1.0.0/ for examples -->

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ license = "MIT OR Apache-2.0"
1212
readme = "README.md"
1313

1414
[dependencies]
15-
bdk_chain = { version = "0.23.2", features = ["miniscript"] }
16-
bdk_wallet = { version = "2.3.0", optional = true }
15+
bdk_chain = { version = "0.23.3", features = ["miniscript"] }
16+
bdk_wallet = { version = "3.0.0", optional = true }
1717
sqlx = { version = "0.8.6", features = ["sqlite", "runtime-tokio"] }
1818

1919
[dev-dependencies]
2020
anyhow = "1"
21-
bdk_esplora = { version = "0.22.1", features = ["tokio"] }
21+
bdk_esplora = { version = "0.22.2", features = ["tokio"] }
2222
tokio = { version = "1", default-features = false, features = ["full"] }
2323

2424
[dev-dependencies.bdk_sqlite]

migrations/0003_schema.up.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- Add locked outpoints table
2+
3+
CREATE TABLE IF NOT EXISTS locked_outpoint(
4+
txid TEXT NOT NULL,
5+
vout INTEGER NOT NULL,
6+
PRIMARY KEY(txid, vout)
7+
);

src/wallet.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ use std::{collections::BTreeMap, pin::Pin, str::FromStr};
44

55
use bdk_chain::bitcoin;
66
use bdk_chain::miniscript;
7-
use bdk_wallet::{AsyncWalletPersister, ChangeSet, KeychainKind};
7+
use bdk_wallet::{AsyncWalletPersister, ChangeSet, KeychainKind, locked_outpoints};
88
use bitcoin::Network;
9+
use bitcoin::OutPoint;
910
use miniscript::descriptor::{Descriptor, DescriptorPublicKey};
1011
use sqlx::Row;
1112

@@ -31,6 +32,8 @@ impl Store {
3132
self.write_local_chain(&changeset.local_chain).await?;
3233
self.write_tx_graph(&changeset.tx_graph).await?;
3334
self.write_keychain_txout(&changeset.indexer).await?;
35+
self.write_locked_outpoints(&changeset.locked_outpoints)
36+
.await?;
3437

3538
Ok(())
3639
}
@@ -76,6 +79,7 @@ impl Store {
7679
let tx_graph = self.read_tx_graph().await?;
7780
let local_chain = self.read_local_chain().await?;
7881
let indexer = self.read_keychain_txout().await?;
82+
let locked_outpoints = self.read_locked_outpoints().await?;
7983

8084
Ok(ChangeSet {
8185
network,
@@ -84,6 +88,7 @@ impl Store {
8488
tx_graph,
8589
local_chain,
8690
indexer,
91+
locked_outpoints,
8792
})
8893
}
8994

@@ -126,6 +131,49 @@ impl Store {
126131

127132
Ok(descriptors)
128133
}
134+
135+
/// Write locked outpoints.
136+
pub async fn write_locked_outpoints(
137+
&self,
138+
locked_outpoints: &locked_outpoints::ChangeSet,
139+
) -> Result<(), Error> {
140+
for (&outpoint, &is_locked) in &locked_outpoints.outpoints {
141+
let OutPoint { txid, vout } = outpoint;
142+
if is_locked {
143+
sqlx::query("INSERT OR IGNORE INTO locked_outpoint(txid, vout) VALUES($1, $2)")
144+
.bind(txid.to_string())
145+
.bind(vout)
146+
.execute(&self.pool)
147+
.await?;
148+
} else {
149+
sqlx::query("DELETE FROM locked_outpoint WHERE txid = $1 AND vout = $2")
150+
.bind(txid.to_string())
151+
.bind(vout)
152+
.execute(&self.pool)
153+
.await?;
154+
}
155+
}
156+
157+
Ok(())
158+
}
159+
160+
/// Read locked outpoints.
161+
pub async fn read_locked_outpoints(&self) -> Result<locked_outpoints::ChangeSet, Error> {
162+
let mut changeset = locked_outpoints::ChangeSet::default();
163+
164+
let rows = sqlx::query("SELECT txid, vout FROM locked_outpoint")
165+
.fetch_all(&self.pool)
166+
.await?;
167+
for row in rows {
168+
let txid: String = row.get("txid");
169+
let txid: bitcoin::Txid = txid.parse()?;
170+
let vout: u32 = row.get("vout");
171+
let outpoint = OutPoint { txid, vout };
172+
changeset.outpoints.insert(outpoint, true);
173+
}
174+
175+
Ok(changeset)
176+
}
129177
}
130178

131179
type FutureResult<'a, T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'a + Send>>;

0 commit comments

Comments
 (0)