Merge pull request #1055 from lightning-signer/2021-08-anchor-tx
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Thu, 2 Sep 2021 21:54:11 +0000 (21:54 +0000)
committerGitHub <noreply@github.com>
Thu, 2 Sep 2021 21:54:11 +0000 (21:54 +0000)
1  2 
lightning/src/ln/channel.rs
lightning/src/ln/functional_tests.rs

index e2a19618be52c4eaace19472cbdbf1a72d6800ef,b44a642b7f265226f9a83fd8ca7f0f7e21cd0029..0481a93fcd97e6fc566436dbbad9fad95f3d871c
@@@ -567,7 -567,9 +567,9 @@@ const COMMITMENT_TX_WEIGHT_PER_HTLC: u6
  #[cfg(test)]
  pub const COMMITMENT_TX_WEIGHT_PER_HTLC: u64 = 172;
  
- /// Maximmum `funding_satoshis` value, according to the BOLT #2 specification
+ pub const ANCHOR_OUTPUT_VALUE_SATOSHI: u64 = 330;
+ /// Maximum `funding_satoshis` value, according to the BOLT #2 specification
  /// it's 2^24.
  pub const MAX_FUNDING_SATOSHIS: u64 = 1 << 24;
  
@@@ -1206,6 -1208,11 +1208,11 @@@ impl<Signer: Sign> Channel<Signer> 
  
                let mut value_to_a = if local { value_to_self } else { value_to_remote };
                let mut value_to_b = if local { value_to_remote } else { value_to_self };
+               let (funding_pubkey_a, funding_pubkey_b) = if local {
+                       (self.get_holder_pubkeys().funding_pubkey, self.get_counterparty_pubkeys().funding_pubkey)
+               } else {
+                       (self.get_counterparty_pubkeys().funding_pubkey, self.get_holder_pubkeys().funding_pubkey)
+               };
  
                if value_to_a >= (broadcaster_dust_limit_satoshis as i64) {
                        log_trace!(logger, "   ...including {} output with value {}", if local { "to_local" } else { "to_remote" }, value_to_a);
                let tx = CommitmentTransaction::new_with_auxiliary_htlc_data(commitment_number,
                                                                             value_to_a as u64,
                                                                             value_to_b as u64,
+                                                                            false,
+                                                                            funding_pubkey_a,
+                                                                            funding_pubkey_b,
                                                                             keys.clone(),
                                                                             feerate_per_kw,
                                                                             &mut included_non_dust_htlcs,
                        self.counterparty_funding_pubkey()
                );
  
 +              self.holder_signer.validate_holder_commitment(&holder_commitment_tx)
 +                      .map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;
 +
                // Now that we're past error-generating stuff, update our local state:
  
                let funding_redeemscript = self.get_funding_redeemscript();
                        self.counterparty_funding_pubkey()
                );
  
 +              self.holder_signer.validate_holder_commitment(&holder_commitment_tx)
 +                      .map_err(|_| ChannelError::Close("Failed to validate our commitment".to_owned()))?;
 +
  
                let funding_redeemscript = self.get_funding_redeemscript();
                let funding_txo = self.get_funding_txo().unwrap();
                );
  
                let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number - 1, &self.secp_ctx);
 +              self.holder_signer.validate_holder_commitment(&holder_commitment_tx)
 +                      .map_err(|_| (None, ChannelError::Close("Failed to validate our commitment".to_owned())))?;
                let per_commitment_secret = self.holder_signer.release_commitment_secret(self.cur_holder_commitment_transaction_number + 1);
  
                // Update state now that we've passed all the can-fail calls...
                        return Err(ChannelError::Close("Peer sent revoke_and_ack after we'd started exchanging closing_signeds".to_owned()));
                }
  
 +              let secret = secp_check!(SecretKey::from_slice(&msg.per_commitment_secret), "Peer provided an invalid per_commitment_secret".to_owned());
 +
                if let Some(counterparty_prev_commitment_point) = self.counterparty_prev_commitment_point {
 -                      if PublicKey::from_secret_key(&self.secp_ctx, &secp_check!(SecretKey::from_slice(&msg.per_commitment_secret), "Peer provided an invalid per_commitment_secret".to_owned())) != counterparty_prev_commitment_point {
 +                      if PublicKey::from_secret_key(&self.secp_ctx, &secret) != counterparty_prev_commitment_point {
                                return Err(ChannelError::Close("Got a revoke commitment secret which didn't correspond to their current pubkey".to_owned()));
                        }
                }
                        *self.next_remote_commitment_tx_fee_info_cached.lock().unwrap() = None;
                }
  
 +              self.holder_signer.validate_counterparty_revocation(
 +                      self.cur_counterparty_commitment_transaction_number + 1,
 +                      &secret
 +              ).map_err(|_| ChannelError::Close("Failed to validate revocation from peer".to_owned()))?;
 +
                self.commitment_secrets.provide_secret(self.cur_counterparty_commitment_transaction_number + 1, msg.per_commitment_secret)
                        .map_err(|_| ChannelError::Close("Previous secrets did not match new one".to_owned()))?;
                self.latest_monitor_update_id += 1;
index 7391523485d533ba306f06c0a14176e661b2351f,b7eb6c006f4baddbdc0b71c18d3f19704cc0c457..06cc80cc18b0a5b770be83ce25cbb82535d932ba
@@@ -1297,25 -1297,24 +1297,27 @@@ fn test_fee_spike_violation_fails_htlc(
  
        // Get the EnforcingSigner for each channel, which will be used to (1) get the keys
        // needed to sign the new commitment tx and (2) sign the new commitment tx.
-       let (local_revocation_basepoint, local_htlc_basepoint, local_secret, next_local_point) = {
+       let (local_revocation_basepoint, local_htlc_basepoint, local_secret, next_local_point, local_funding) = {
                let chan_lock = nodes[0].node.channel_state.lock().unwrap();
                let local_chan = chan_lock.by_id.get(&chan.2).unwrap();
                let chan_signer = local_chan.get_signer();
 +              // Make the signer believe we validated another commitment, so we can release the secret
 +              chan_signer.get_enforcement_state().last_holder_commitment -= 1;
 +
                let pubkeys = chan_signer.pubkeys();
                (pubkeys.revocation_basepoint, pubkeys.htlc_basepoint,
                 chan_signer.release_commitment_secret(INITIAL_COMMITMENT_NUMBER),
-                chan_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 2, &secp_ctx))
+                chan_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 2, &secp_ctx),
+                chan_signer.pubkeys().funding_pubkey)
        };
-       let (remote_delayed_payment_basepoint, remote_htlc_basepoint,remote_point) = {
+       let (remote_delayed_payment_basepoint, remote_htlc_basepoint, remote_point, remote_funding) = {
                let chan_lock = nodes[1].node.channel_state.lock().unwrap();
                let remote_chan = chan_lock.by_id.get(&chan.2).unwrap();
                let chan_signer = remote_chan.get_signer();
                let pubkeys = chan_signer.pubkeys();
                (pubkeys.delayed_payment_basepoint, pubkeys.htlc_basepoint,
-                chan_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &secp_ctx))
+                chan_signer.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &secp_ctx),
+                chan_signer.pubkeys().funding_pubkey)
        };
  
        // Assemble the set of keys we can use for signatures for our commitment_signed message.
                        commitment_number,
                        95000,
                        local_chan_balance,
+                       false, local_funding, remote_funding,
                        commit_tx_keys.clone(),
                        feerate_per_kw,
                        &mut vec![(accepted_htlc_info, ())],
@@@ -7984,7 -7984,7 +7987,7 @@@ fn test_counterparty_raa_skip_no_crash(
        // commitment transaction, we would have happily carried on and provided them the next
        // commitment transaction based on one RAA forward. This would probably eventually have led to
        // channel closure, but it would not have resulted in funds loss. Still, our
 -      // EnforcingSigner would have paniced as it doesn't like jumps into the future. Here, we
 +      // EnforcingSigner would have panicked as it doesn't like jumps into the future. Here, we
        // check simply that the channel is closed in response to such an RAA, but don't check whether
        // we decide to punish our counterparty for revoking their funds (as we don't currently
        // implement that).
        let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2;
  
        let mut guard = nodes[0].node.channel_state.lock().unwrap();
 -      let keys = &guard.by_id.get_mut(&channel_id).unwrap().get_signer();
 +      let keys = guard.by_id.get_mut(&channel_id).unwrap().get_signer();
 +
        const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
 +
 +      // Make signer believe we got a counterparty signature, so that it allows the revocation
 +      keys.get_enforcement_state().last_holder_commitment -= 1;
        let per_commitment_secret = keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER);
 +
        // Must revoke without gaps
 +      keys.get_enforcement_state().last_holder_commitment -= 1;
        keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 1);
 +
 +      keys.get_enforcement_state().last_holder_commitment -= 1;
        let next_per_commitment_point = PublicKey::from_secret_key(&Secp256k1::new(),
                &SecretKey::from_slice(&keys.release_commitment_secret(INITIAL_COMMITMENT_NUMBER - 2)).unwrap());