Skip to content

Commit b0d3ee6

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 9d46c4f commit b0d3ee6

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, params: &[u8; 32]) -> SecretKey {
20762105
let mut eight_bytes = [0; 8];
20772106
eight_bytes.copy_from_slice(&params[0..8]);
@@ -2173,6 +2202,15 @@ impl KeysManager {
21732202
let signer = self.derive_channel_keys(&descriptor.channel_keys_id);
21742203
keys_cache = Some((signer, descriptor.channel_keys_id));
21752204
}
2205+
#[cfg(test)]
2206+
if self.v2_remote_key_derivation {
2207+
// In tests, we don't have to deal with upgrades from V1 sighers with
2208+
// `v2_remote_key_derivation` set, so use this opportunity to test
2209+
// `possible_v2_counterparty_closed_balance_spks`.
2210+
let possible_spks =
2211+
self.possible_v2_counterparty_closed_balance_spks(secp_ctx);
2212+
assert!(possible_spks.contains(&descriptor.output.script_pubkey));
2213+
}
21762214
let witness = keys_cache.as_ref().unwrap().0.sign_counterparty_payment_input(
21772215
&psbt.unsigned_tx,
21782216
input_idx,

0 commit comments

Comments
 (0)