Skip to content

Commit 3b5f00b

Browse files
committed
Add comments and debug assertions for list_unspent_utxos
We previously erroneously included the version byte trying to construct a `WitnessProgram`, which was was recently fixed. Here we add some more comments to the code explaining what went wrong, and also add a debug assertion checking `list_unspent_utxos` retrieves at least one `Utxo` when we see any confirmed balances.
1 parent bcea1c2 commit 3b5f00b

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

src/wallet/mod.rs

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,16 @@ where
205205
) -> Result<(u64, u64), Error> {
206206
let balance = self.inner.lock().unwrap().balance();
207207

208+
// Make sure `list_confirmed_utxos` returns at least one `Utxo` we could use to spend/bump
209+
// Anchors if we have any confirmed amounts.
210+
#[cfg(debug_assertions)]
211+
if balance.confirmed != Amount::ZERO {
212+
debug_assert!(
213+
self.list_confirmed_utxos().map_or(false, |v| !v.is_empty()),
214+
"Confirmed amounts should always be available for Anchor spending"
215+
);
216+
}
217+
208218
let (total, spendable) = (
209219
balance.total().to_sat(),
210220
balance.trusted_spendable().to_sat().saturating_sub(total_anchor_channels_reserve_sats),
@@ -387,12 +397,23 @@ where
387397
let script_pubkey = u.txout.script_pubkey;
388398
match script_pubkey.witness_version() {
389399
Some(version @ WitnessVersion::V0) => {
400+
// According to the SegWit rules of [BIP 141] a witness program is defined as:
401+
// > A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of
402+
// > a 1-byte push opcode (one of OP_0,OP_1,OP_2,.. .,OP_16) followed by a direct
403+
// > data push between 2 and 40 bytes gets a new special meaning. The value of
404+
// > the first push is called the "version byte". The following byte vector
405+
// > pushed is called the "witness program"."
406+
//
407+
// We therefore skip the first byte we just read via `witness_version` and use
408+
// the rest (i.e., the data push) as the raw bytes to construct the
409+
// `WitnessProgram` below.
410+
//
411+
// [BIP 141]: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program
412+
let witness_bytes = &script_pubkey.as_bytes()[2..];
390413
let witness_program =
391-
WitnessProgram::new(version, &script_pubkey.as_bytes()[2..]).map_err(
392-
|e| {
393-
log_error!(self.logger, "Failed to retrieve script payload: {}", e);
394-
},
395-
)?;
414+
WitnessProgram::new(version, witness_bytes).map_err(|e| {
415+
log_error!(self.logger, "Failed to retrieve script payload: {}", e);
416+
})?;
396417

397418
let wpkh = WPubkeyHash::from_slice(&witness_program.program().as_bytes())
398419
.map_err(|e| {
@@ -402,12 +423,23 @@ where
402423
utxos.push(utxo);
403424
},
404425
Some(version @ WitnessVersion::V1) => {
426+
// According to the SegWit rules of [BIP 141] a witness program is defined as:
427+
// > A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of
428+
// > a 1-byte push opcode (one of OP_0,OP_1,OP_2,.. .,OP_16) followed by a direct
429+
// > data push between 2 and 40 bytes gets a new special meaning. The value of
430+
// > the first push is called the "version byte". The following byte vector
431+
// > pushed is called the "witness program"."
432+
//
433+
// We therefore skip the first byte we just read via `witness_version` and use
434+
// the rest (i.e., the data push) as the raw bytes to construct the
435+
// `WitnessProgram` below.
436+
//
437+
// [BIP 141]: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program
438+
let witness_bytes = &script_pubkey.as_bytes()[2..];
405439
let witness_program =
406-
WitnessProgram::new(version, &script_pubkey.as_bytes()[2..]).map_err(
407-
|e| {
408-
log_error!(self.logger, "Failed to retrieve script payload: {}", e);
409-
},
410-
)?;
440+
WitnessProgram::new(version, witness_bytes).map_err(|e| {
441+
log_error!(self.logger, "Failed to retrieve script payload: {}", e);
442+
})?;
411443

412444
XOnlyPublicKey::from_slice(&witness_program.program().as_bytes()).map_err(
413445
|e| {

0 commit comments

Comments
 (0)