-
Notifications
You must be signed in to change notification settings - Fork 407
Remove signing from Channel #420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove signing from Channel #420
Conversation
5657cb2
to
c13a6bf
Compare
Codecov Report
@@ Coverage Diff @@
## master #420 +/- ##
========================================
Coverage ? 87.7%
========================================
Files ? 30
Lines ? 16794
Branches ? 0
========================================
Hits ? 14730
Misses ? 2064
Partials ? 0
Continue to review full report at Codecov.
|
c13a6bf
to
9aadb7f
Compare
lightning/src/chain/keysinterface.rs
Outdated
@@ -178,9 +184,9 @@ impl ChannelKeys for InMemoryChannelKeys { | |||
fn htlc_base_key(&self) -> &SecretKey { &self.htlc_base_key } | |||
fn commitment_seed(&self) -> &[u8; 32] { &self.commitment_seed } | |||
|
|||
fn sign_remote_commitment<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, channel_funding_script: &Script, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> { | |||
fn sign_remote_commitment<T: secp256k1::Signing>(&self, channel_value_satoshis: u64, channel_funding_redeemscript: &Script, feerate_per_kw: u64, commitment_tx: &Transaction, keys: &TxCreationKeys, htlcs: &[&HTLCOutputInCommitment], to_self_delay: u16, secp_ctx: &Secp256k1<T>) -> Result<(Signature, Vec<Signature>), ()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented with parameter as feerate_per_kw
instead of asbolute_fee
. I think we also conclude verbally than fee passed by caller can't be trusted by signer and should be recomputed locally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, no? Indeed, the parameter name in the trait is wrong, its per_kw, not absolute, but we can't not provide it - its required to generate the commitment transaction itself. Indeed, we can't trust it, and either our peer or our own fee estimator can make us attach an absurd fee and spend all our money on fee, but until the protocol doesn't have an update_fee message, we can't do anything about this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah you're right, thought it was there for transaction digest algo but in fact that's for second-stage htlc transactions fees, so yes right now we have to trust it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excited by this move! Some comments and checks can be a bit improved I think
@@ -2232,10 +2229,21 @@ impl ChannelMonitor { | |||
// HTLCs set may differ between last and previous local commitment txn, in case of one them hitting chain, ensure we cancel all HTLCs backward | |||
let mut is_local_tx = false; | |||
|
|||
if let &mut Some(ref mut local_tx) = &mut self.current_local_signed_commitment_tx { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why sign current and prev local commitment txn in check_spend_local_transaction
? One of them has been already signed and broadcast onchain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We dont sign both - both sign calls are in a if local_tx.txid == commitment_txid check. We probably dont need to sign them at all, but there's a number of such cases in channelmonitor that we can discuss cleaning up later, so this is more in line with existing behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I understand we sign either one of them, it was more about the new code branches in themselves. Okay let's talk about them in channelmonitor cleanup (even if it's likely we remove them long-term)
} | ||
|
||
pub fn new_from_unsigned(mut tx: Transaction, their_sig: &Signature, our_funding_key: &PublicKey, their_funding_key: &PublicKey) -> LocalCommitmentTransaction { | ||
if tx.input.len() != 1 { panic!("Tried to store a commitment transaction that had input count != 1!"); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we extend the number of non contextual commitment transaction format checks ? Like checking locktime and nSequence by passing the obscured commitment number or verifying then every output is either P2WSH or P2WPKH ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean this is still an internal function, so these are more to prevent invalid usage of the struct that indicates we've confused ourselves over where the state machine is. Being able to do more is something we should add to EnforcingChannelKeys, but that can come over time once we move the add_local_sig to that.
@@ -63,7 +63,9 @@ pub(super) fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, | |||
base_point.combine(&hashkey) | |||
} | |||
|
|||
/// Derives a revocation key from its constituent parts | |||
/// Derives a revocation key from its constituent parts. | |||
/// Note that this is infallible iff we trust that at least one of the two input keys are randomly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is obscure, is this a mention to the case that you were speaking about with a revocation pubkey without a private key ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Its a key assumption in being able to not derive the private key at commitment-check-time and instead do it at broadcast time.
assert!(preimage.is_none()); | ||
} else { | ||
tx.input[0].witness.push(preimage.unwrap().0.to_vec()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can add assert!(tx.locktime == htlc.cltv_expiry)
for !htlc.offered
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this appears to fail in 15 tests. I'll leave it for adding later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah it's also used to build remote htlc transaction so we can't rely on offered flag. All tests passed with preimage.is_none { assert!(tx.lock_time == htlc.ctlv_expiry)
We now have current-local-tx broadcast ability in channel monitors directly (for ChannelManager deserialization), so we can just use that instead of always having the Channel store signed ready-to-go copies of the latest local commitment transaction. This is further kinda nice since ChannelMonitor is live and can, eg broadcast HTLC-Success transactions immediately as they will be generated at broadcast time instead of in advance. Finally, this lets us clean up a tiny bit in Channel.
9aadb7f
to
e2e1628
Compare
ACK e2e1628, comments can be addressed in further refactoring. |
Based on #419, this takes a few big leaps forward, removing all actual signing from Channel, and dumping it all on ChannelMonitor.