Skip to content

Commit f67e880

Browse files
committed
Add a method to fetch all possible remote-closure script_pubkeys
In the previous commit we (finally) allowed users to opt into a static `remote_key` derivation scheme, enabling them to scan the chain for funds on counterparty commitment transactions without any state at all. This is only possible, however, of course, if they have the full list of scripts to scan the chain for, which we expose here.
1 parent a2614c8 commit f67e880

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

lightning/src/sign/mod.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,6 +2072,35 @@ impl KeysManager {
20722072
self.node_secret
20732073
}
20742074

2075+
/// Gets the set of possible `script_pubkey`s which can appear on chain for our
2076+
/// non-HTLC-encumbered balance if our counterparty force-closes the channel.
2077+
///
2078+
/// Only channels opened or spliced when using a [`KeysManager`] with the
2079+
/// `v2_remote_key_derivation` argument to [`KeysManager::new`] will close to such scripts,
2080+
/// other channels will close to a randomly-generated `script_pubkey`.
2081+
pub fn possible_v2_counterparty_closed_balance_spks<C: Signing>(
2082+
&self, secp_ctx: &Secp256k1<C>,
2083+
) -> Vec<ScriptBuf> {
2084+
let mut res = Vec::with_capacity(usize::from(STATIC_PAYMENT_KEY_COUNT) * 2);
2085+
let static_remote_key_features = ChannelTypeFeatures::only_static_remote_key();
2086+
let mut zero_fee_htlc_features = ChannelTypeFeatures::only_static_remote_key();
2087+
zero_fee_htlc_features.set_anchors_zero_fee_htlc_tx_required();
2088+
for idx in 0..STATIC_PAYMENT_KEY_COUNT {
2089+
let key = self
2090+
.static_payment_key
2091+
.derive_priv(
2092+
&self.secp_ctx,
2093+
&ChildNumber::from_hardened_idx(u32::from(idx)).expect("key space exhausted"),
2094+
)
2095+
.expect("Your RNG is busted")
2096+
.private_key;
2097+
let pubkey = PublicKey::from_secret_key(secp_ctx, &key);
2098+
res.push(get_counterparty_payment_script(&static_remote_key_features, &pubkey));
2099+
res.push(get_counterparty_payment_script(&zero_fee_htlc_features, &pubkey));
2100+
}
2101+
res
2102+
}
2103+
20752104
fn derive_payment_key_v2(&self, key_idx: u64) -> SecretKey {
20762105
let idx = key_idx % u64::from(STATIC_PAYMENT_KEY_COUNT);
20772106
self.static_payment_key
@@ -2174,6 +2203,15 @@ impl KeysManager {
21742203
let signer = self.derive_channel_keys(&descriptor.channel_keys_id);
21752204
keys_cache = Some((signer, descriptor.channel_keys_id));
21762205
}
2206+
#[cfg(test)]
2207+
if self.v2_remote_key_derivation {
2208+
// In tests, we don't have to deal with upgrades from V1 sighers with
2209+
// `v2_remote_key_derivation` set, so use this opportunity to test
2210+
// `possible_v2_counterparty_closed_balance_spks`.
2211+
let possible_spks =
2212+
self.possible_v2_counterparty_closed_balance_spks(secp_ctx);
2213+
assert!(possible_spks.contains(&descriptor.output.script_pubkey));
2214+
}
21772215
let witness = keys_cache.as_ref().unwrap().0.sign_counterparty_payment_input(
21782216
&psbt.unsigned_tx,
21792217
input_idx,

0 commit comments

Comments
 (0)