use secp256k1::{Secp256k1,Signature};
use secp256k1;
+use ln::features::{ChannelFeatures, InitFeatures};
use ln::msgs;
-use ln::msgs::{DecodeError, OptionalField, LocalFeatures, DataLossProtect};
+use ln::msgs::{DecodeError, OptionalField, DataLossProtect};
use ln::channelmonitor::ChannelMonitor;
use ln::channelmanager::{PendingHTLCStatus, HTLCSource, HTLCFailReason, HTLCFailureMsg, PendingForwardHTLCInfo, RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT, MAX_LOCAL_BREAKDOWN_TIMEOUT};
use ln::chan_utils::{LocalCommitmentTransaction,TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
/// Creates a new channel from a remote sides' request for one.
/// Assumes chain_hash has already been checked and corresponds with what we expect!
- pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface<ChanKeySigner = ChanSigner>>, their_node_id: PublicKey, their_local_features: LocalFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel<ChanSigner>, ChannelError> {
+ pub fn new_from_req(fee_estimator: &FeeEstimator, keys_provider: &Arc<KeysInterface<ChanKeySigner = ChanSigner>>, their_node_id: PublicKey, their_features: InitFeatures, msg: &msgs::OpenChannel, user_id: u64, logger: Arc<Logger>, config: &UserConfig) -> Result<Channel<ChanSigner>, ChannelError> {
let chan_keys = keys_provider.get_channel_keys(true);
let mut local_config = (*config).channel_options.clone();
chan_keys.htlc_base_key(), chan_keys.payment_base_key(), &keys_provider.get_shutdown_pubkey(), config.own_channel_config.our_to_self_delay,
keys_provider.get_destination_script(), logger.clone());
- let their_shutdown_scriptpubkey = if their_local_features.supports_upfront_shutdown_script() {
+ let their_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
match &msg.shutdown_scriptpubkey {
&OptionalField::Present(ref script) => {
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. We enforce it while receiving shutdown msg
chan_utils::build_htlc_transaction(prev_hash, feerate_per_kw, if local { self.their_to_self_delay } else { self.our_to_self_delay }, htlc, &keys.a_delayed_payment_key, &keys.revocation_key)
}
- fn create_htlc_tx_signature(&self, tx: &Transaction, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result<(Script, Signature, bool), ChannelError> {
- if tx.input.len() != 1 {
- panic!("Tried to sign HTLC transaction that had input count != 1!");
- }
-
- let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
-
- let our_htlc_key = secp_check!(chan_utils::derive_private_key(&self.secp_ctx, &keys.per_commitment_point, self.local_keys.htlc_base_key()), "Derived invalid key, peer is maliciously selecting parameters");
- let sighash = hash_to_message!(&bip143::SighashComponents::new(&tx).sighash_all(&tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]);
- let is_local_tx = PublicKey::from_secret_key(&self.secp_ctx, &our_htlc_key) == keys.a_htlc_key;
- Ok((htlc_redeemscript, self.secp_ctx.sign(&sighash, &our_htlc_key), is_local_tx))
- }
-
- #[cfg(test)]
- /// Signs a transaction created by build_htlc_transaction. If the transaction is an
- /// HTLC-Success transaction (ie htlc.offered is false), preimage must be set!
- /// TODO: Make this a chan_utils, use it in channelmonitor and tests, cause its unused now
- fn sign_htlc_transaction(&self, tx: &mut Transaction, their_sig: &Signature, preimage: &Option<PaymentPreimage>, htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Result<Signature, ChannelError> {
- if tx.input.len() != 1 {
- panic!("Tried to sign HTLC transaction that had input count != 1!");
- }
- if tx.input[0].witness.len() != 0 {
- panic!("Tried to re-sign HTLC transaction");
- }
-
- let (htlc_redeemscript, our_sig, local_tx) = self.create_htlc_tx_signature(tx, htlc, keys)?;
-
- tx.input[0].witness.push(Vec::new()); // First is the multisig dummy
-
- if local_tx { // b, then a
- tx.input[0].witness.push(their_sig.serialize_der().to_vec());
- tx.input[0].witness.push(our_sig.serialize_der().to_vec());
- } else {
- tx.input[0].witness.push(our_sig.serialize_der().to_vec());
- tx.input[0].witness.push(their_sig.serialize_der().to_vec());
- }
- tx.input[0].witness[1].push(SigHashType::All as u8);
- tx.input[0].witness[2].push(SigHashType::All as u8);
-
- if htlc.offered {
- tx.input[0].witness.push(Vec::new());
- } else {
- tx.input[0].witness.push(preimage.unwrap().0.to_vec());
- }
-
- tx.input[0].witness.push(htlc_redeemscript.into_bytes());
-
- Ok(our_sig)
- }
-
/// Per HTLC, only one get_update_fail_htlc or get_update_fulfill_htlc call may be made.
/// In such cases we debug_assert!(false) and return an IgnoreError. Thus, will always return
/// Ok(_) if debug assertions are turned on and preconditions are met.
// Message handlers:
- pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config: &UserConfig, their_local_features: LocalFeatures) -> Result<(), ChannelError> {
+ pub fn accept_channel(&mut self, msg: &msgs::AcceptChannel, config: &UserConfig, their_features: InitFeatures) -> Result<(), ChannelError> {
// Check sanity of message fields:
if !self.channel_outbound {
return Err(ChannelError::Close("Got an accept_channel message from an inbound peer"));
return Err(ChannelError::Close("We consider the minimum depth to be unreasonably large"));
}
- let their_shutdown_scriptpubkey = if their_local_features.supports_upfront_shutdown_script() {
+ let their_shutdown_scriptpubkey = if their_features.supports_upfront_shutdown_script() {
match &msg.shutdown_scriptpubkey {
&OptionalField::Present(ref script) => {
// Peer is signaling upfront_shutdown and has provided a non-accepted scriptpubkey format. We enforce it while receiving shutdown msg
log_trace!(self, "Checking HTLC tx signature {} by key {} against tx {} with redeemscript {}", log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), log_bytes!(local_keys.b_htlc_key.serialize()), encode::serialize_hex(&htlc_tx), encode::serialize_hex(&htlc_redeemscript));
let htlc_sighash = hash_to_message!(&bip143::SighashComponents::new(&htlc_tx).sighash_all(&htlc_tx.input[0], &htlc_redeemscript, htlc.amount_msat / 1000)[..]);
secp_check!(self.secp_ctx.verify(&htlc_sighash, &msg.htlc_signatures[idx], &local_keys.b_htlc_key), "Invalid HTLC tx signature from peer");
- let htlc_sig = self.create_htlc_tx_signature(&htlc_tx, &htlc, &local_keys)?.1;
- htlcs_and_sigs.push((htlc, Some((msg.htlc_signatures[idx], htlc_sig)), source));
+ htlcs_and_sigs.push((htlc, Some(msg.htlc_signatures[idx]), source));
} else {
htlcs_and_sigs.push((htlc, None, source));
}
let our_bitcoin_key = PublicKey::from_secret_key(&self.secp_ctx, self.local_keys.funding_key());
let msg = msgs::UnsignedChannelAnnouncement {
- features: msgs::GlobalFeatures::new(),
+ features: ChannelFeatures::supported(),
chain_hash: chain_hash,
short_channel_id: self.get_short_channel_id().unwrap(),
node_id_1: if were_node_one { our_node_id } else { self.get_their_node_id() },
assert!(preimage.is_some());
}
- chan.sign_htlc_transaction(&mut htlc_tx, &remote_signature, &preimage, &htlc, &keys).unwrap();
+ chan_utils::sign_htlc_transaction(&mut htlc_tx, &remote_signature, &preimage, &htlc, &keys.a_htlc_key, &keys.b_htlc_key, &keys.revocation_key, &keys.per_commitment_point, chan.local_keys.htlc_base_key(), &chan.secp_ctx).unwrap();
assert_eq!(serialize(&htlc_tx)[..],
hex::decode($tx_hex).unwrap()[..]);
};