You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Properly handle funding key rotation during splices
When splicing, we're required by protocol to retain all the
existing keys material except the funding key which we're allowed
to rotate. In the original implementation we acknowledged that but
figured we'd stick with a single `pubkey` method in the
`ChannelSigner` anyway cause adding a specific method for it is
annoying.
Sadly, this was ultimately broken - in `FundingScope::for_splice`,
we called the signer's `new_pubkeys` method (renamed from `pubkeys`
after splicing initially landed), replacing all of the public keys
the `Channel` would use rather than just the funding key. This can
result in commitment signature mismatches if the signer changes any
keys aside from the funding one.
`InMemorySigner` did not do so, however, so we didn't notice the
bug. Luckily-ish, in 189b8ac we
started generating a fresh `remote_key` when splicing (at least
when upgrading from 0.1 to 0.2 or when setting `KeysManager` to use
v1 `remote_key` derivation). This breaks splicing cause we can't
communicate the new `remote_key` to the counterparty during the
splicing handshake.
Ultimately this bug is because the API we had didn't communicate to
the signer that we weren't allowed to change anything except the
funding key, and allowed returning a `ChannelPublicKeys` which
would break the channel.
Here we fix this by renaming `new_pubkeys` `pubkeys` again
(partially reverting 9d291e0 but
keeping the changed requirements that `pubkeys` only be called
once) and adding a new `ChannelSigner:new_funding_pubkey` method
specifically for splicing.
We also update `channel.rs` to correctly fetch the new funding
pubkey before sending `splice_init`, storing it in the
`PendingFunding` untl we build a `FundingScope`.
Backport of e95ebf8
/// This channel's type, as negotiated during channel open. For old objects where this field
1068
1068
/// wasn't serialized, it will default to static_remote_key at deserialization.
@@ -2285,8 +2285,8 @@ mod tests {
2285
2285
let counterparty_signer = keys_provider.derive_channel_signer(keys_provider.generate_channel_keys_id(true,1));
2286
2286
let per_commitment_secret = SecretKey::from_slice(&<Vec<u8>>::from_hex("1f1e1d1c1b1a191817161514131211100f0e0d0c0b0a09080706050403020100").unwrap()[..]).unwrap();
2287
2287
let per_commitment_point = PublicKey::from_secret_key(&secp_ctx,&per_commitment_secret);
2288
-
let holder_pubkeys = signer.new_pubkeys(None,&secp_ctx);
2289
-
let counterparty_pubkeys = counterparty_signer.new_pubkeys(None,&secp_ctx).clone();
2288
+
let holder_pubkeys = signer.pubkeys(&secp_ctx);
2289
+
let counterparty_pubkeys = counterparty_signer.pubkeys(&secp_ctx).clone();
2290
2290
let channel_parameters = ChannelTransactionParameters{
0 commit comments