selected_contest_delay: 67,
}),
funding_outpoint: Some(funding_outpoint),
+ opt_anchors: None,
};
// Prune with one old state and a holder commitment tx holding a few overlaps with the
// old state.
let mut sum_actual_sigs = 0;
macro_rules! sign_input {
- ($sighash_parts: expr, $idx: expr, $amount: expr, $weight: expr, $sum_actual_sigs: expr) => {
+ ($sighash_parts: expr, $idx: expr, $amount: expr, $weight: expr, $sum_actual_sigs: expr, $opt_anchors: expr) => {
let htlc = HTLCOutputInCommitment {
offered: if *$weight == WEIGHT_REVOKED_OFFERED_HTLC || *$weight == WEIGHT_OFFERED_HTLC { true } else { false },
amount_msat: 0,
payment_hash: PaymentHash([1; 32]),
transaction_output_index: Some($idx as u32),
};
- let redeem_script = if *$weight == WEIGHT_REVOKED_OUTPUT { chan_utils::get_revokeable_redeemscript(&pubkey, 256, &pubkey) } else { chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &pubkey, &pubkey, &pubkey) };
+ let redeem_script = if *$weight == WEIGHT_REVOKED_OUTPUT { chan_utils::get_revokeable_redeemscript(&pubkey, 256, &pubkey) } else { chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, $opt_anchors, &pubkey, &pubkey, &pubkey) };
let sighash = hash_to_message!(&$sighash_parts.signature_hash($idx, &redeem_script, $amount, SigHashType::All)[..]);
let sig = secp_ctx.sign(&sighash, &privkey);
$sighash_parts.access_witness($idx).push(sig.serialize_der().to_vec());
{
let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
for (idx, inp) in inputs_weight.iter().enumerate() {
- sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
+ sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, false);
inputs_total_weight += inp;
}
}
{
let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
for (idx, inp) in inputs_weight.iter().enumerate() {
- sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
+ sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, false);
inputs_total_weight += inp;
}
}
{
let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
for (idx, inp) in inputs_weight.iter().enumerate() {
- sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
+ sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, false);
inputs_total_weight += inp;
}
}
self.channel_parameters.as_ref().unwrap()
}
+ /// Whether anchors should be used.
+ /// Will panic if ready_channel wasn't called.
+ pub fn opt_anchors(&self) -> bool {
+ self.get_channel_parameters().opt_anchors.is_some()
+ }
+
/// Sign the single input of spend_tx at index `input_idx` which spends the output
/// described by descriptor, returning the witness stack for the input.
///
let mut htlc_sigs = Vec::with_capacity(commitment_tx.htlcs().len());
for htlc in commitment_tx.htlcs() {
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_tx.feerate_per_kw(), self.holder_selected_contest_delay(), htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
- let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
+ let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys);
let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]);
let holder_htlc_key = chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key).map_err(|_| ())?;
htlc_sigs.push(secp_ctx.sign(&htlc_sighash, &holder_htlc_key));
let witness_script = {
let counterparty_htlcpubkey = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.counterparty_pubkeys().htlc_basepoint).map_err(|_| ())?;
let holder_htlcpubkey = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.pubkeys().htlc_basepoint).map_err(|_| ())?;
- chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &counterparty_htlcpubkey, &holder_htlcpubkey, &revocation_pubkey)
+ chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, self.opt_anchors(), &counterparty_htlcpubkey, &holder_htlcpubkey, &revocation_pubkey)
};
let mut sighash_parts = bip143::SigHashCache::new(justice_tx);
let sighash = hash_to_message!(&sighash_parts.signature_hash(input, &witness_script, amount, SigHashType::All)[..]);
let witness_script = if let Ok(revocation_pubkey) = chan_utils::derive_public_revocation_key(&secp_ctx, &per_commitment_point, &self.pubkeys().revocation_basepoint) {
if let Ok(counterparty_htlcpubkey) = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.counterparty_pubkeys().htlc_basepoint) {
if let Ok(htlcpubkey) = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.pubkeys().htlc_basepoint) {
- chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &counterparty_htlcpubkey, &htlcpubkey, &revocation_pubkey)
+ chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, self.opt_anchors(), &counterparty_htlcpubkey, &htlcpubkey, &revocation_pubkey)
} else { return Err(()) }
} else { return Err(()) }
} else { return Err(()) };
htlc_tx
}
+ pub(crate) fn opt_anchors(&self) -> bool {
+ self.channel_transaction_parameters.opt_anchors.is_some()
+ }
+
#[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
pub(crate) fn unsafe_get_fully_signed_htlc_tx(&mut self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>) -> Option<Transaction> {
let latest_had_sigs = self.holder_htlc_sigs.is_some();
},
PackageSolvingData::RevokedHTLCOutput(ref outp) => {
if let Ok(chan_keys) = TxCreationKeys::derive_new(&onchain_handler.secp_ctx, &outp.per_commitment_point, &outp.counterparty_delayed_payment_base_key, &outp.counterparty_htlc_base_key, &onchain_handler.signer.pubkeys().revocation_basepoint, &onchain_handler.signer.pubkeys().htlc_basepoint) {
- let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
+ let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, onchain_handler.opt_anchors(), &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
//TODO: should we panic on signer failure ?
if let Ok(sig) = onchain_handler.signer.sign_justice_revoked_htlc(&bumped_tx, i, outp.amount, &outp.per_commitment_key, &outp.htlc, &onchain_handler.secp_ctx) {
bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
},
PackageSolvingData::CounterpartyOfferedHTLCOutput(ref outp) => {
if let Ok(chan_keys) = TxCreationKeys::derive_new(&onchain_handler.secp_ctx, &outp.per_commitment_point, &outp.counterparty_delayed_payment_base_key, &outp.counterparty_htlc_base_key, &onchain_handler.signer.pubkeys().revocation_basepoint, &onchain_handler.signer.pubkeys().htlc_basepoint) {
- let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
+ let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, onchain_handler.opt_anchors(), &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
if let Ok(sig) = onchain_handler.signer.sign_counterparty_htlc_transaction(&bumped_tx, i, &outp.htlc.amount_msat / 1000, &outp.per_commitment_point, &outp.htlc, &onchain_handler.secp_ctx) {
bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
},
PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => {
if let Ok(chan_keys) = TxCreationKeys::derive_new(&onchain_handler.secp_ctx, &outp.per_commitment_point, &outp.counterparty_delayed_payment_base_key, &outp.counterparty_htlc_base_key, &onchain_handler.signer.pubkeys().revocation_basepoint, &onchain_handler.signer.pubkeys().htlc_basepoint) {
- let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
+ let witness_script = chan_utils::get_htlc_redeemscript_with_explicit_keys(&outp.htlc, onchain_handler.opt_anchors(), &chan_keys.broadcaster_htlc_key, &chan_keys.countersignatory_htlc_key, &chan_keys.revocation_key);
bumped_tx.lock_time = outp.htlc.cltv_expiry; // Right now we don't aggregate time-locked transaction, if we do we should set lock_time before to avoid breaking hash computation
if let Ok(sig) = onchain_handler.signer.sign_counterparty_htlc_transaction(&bumped_tx, i, &outp.htlc.amount_msat / 1000, &outp.per_commitment_point, &outp.htlc, &onchain_handler.secp_ctx) {
});
#[inline]
-pub(crate) fn get_htlc_redeemscript_with_explicit_keys(htlc: &HTLCOutputInCommitment, broadcaster_htlc_key: &PublicKey, countersignatory_htlc_key: &PublicKey, revocation_key: &PublicKey) -> Script {
+pub(crate) fn get_htlc_redeemscript_with_explicit_keys(htlc: &HTLCOutputInCommitment, opt_anchors: bool, broadcaster_htlc_key: &PublicKey, countersignatory_htlc_key: &PublicKey, revocation_key: &PublicKey) -> Script {
let payment_hash160 = Ripemd160::hash(&htlc.payment_hash.0[..]).into_inner();
if htlc.offered {
- Builder::new().push_opcode(opcodes::all::OP_DUP)
+ let mut bldr = Builder::new().push_opcode(opcodes::all::OP_DUP)
.push_opcode(opcodes::all::OP_HASH160)
.push_slice(&PubkeyHash::hash(&revocation_key.serialize())[..])
.push_opcode(opcodes::all::OP_EQUAL)
.push_slice(&payment_hash160)
.push_opcode(opcodes::all::OP_EQUALVERIFY)
.push_opcode(opcodes::all::OP_CHECKSIG)
- .push_opcode(opcodes::all::OP_ENDIF)
- .push_opcode(opcodes::all::OP_ENDIF)
- .into_script()
+ .push_opcode(opcodes::all::OP_ENDIF);
+ if opt_anchors {
+ bldr = bldr.push_opcode(opcodes::all::OP_PUSHNUM_1)
+ .push_opcode(opcodes::all::OP_CSV)
+ .push_opcode(opcodes::all::OP_DROP);
+ }
+ bldr.push_opcode(opcodes::all::OP_ENDIF)
+ .into_script()
} else {
- Builder::new().push_opcode(opcodes::all::OP_DUP)
+ let mut bldr = Builder::new().push_opcode(opcodes::all::OP_DUP)
.push_opcode(opcodes::all::OP_HASH160)
.push_slice(&PubkeyHash::hash(&revocation_key.serialize())[..])
.push_opcode(opcodes::all::OP_EQUAL)
.push_opcode(opcodes::all::OP_CLTV)
.push_opcode(opcodes::all::OP_DROP)
.push_opcode(opcodes::all::OP_CHECKSIG)
- .push_opcode(opcodes::all::OP_ENDIF)
- .push_opcode(opcodes::all::OP_ENDIF)
- .into_script()
+ .push_opcode(opcodes::all::OP_ENDIF);
+ if opt_anchors {
+ bldr = bldr.push_opcode(opcodes::all::OP_PUSHNUM_1)
+ .push_opcode(opcodes::all::OP_CSV)
+ .push_opcode(opcodes::all::OP_DROP);
+ }
+ bldr.push_opcode(opcodes::all::OP_ENDIF)
+ .into_script()
}
}
/// Gets the witness redeemscript for an HTLC output in a commitment transaction. Note that htlc
/// does not need to have its previous_output_index filled.
#[inline]
-pub fn get_htlc_redeemscript(htlc: &HTLCOutputInCommitment, keys: &TxCreationKeys) -> Script {
- get_htlc_redeemscript_with_explicit_keys(htlc, &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key)
+pub fn get_htlc_redeemscript(htlc: &HTLCOutputInCommitment, opt_anchors: bool, keys: &TxCreationKeys) -> Script {
+ get_htlc_redeemscript_with_explicit_keys(htlc, opt_anchors, &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key)
}
/// Gets the redeemscript for a funding output from the two funding public keys.
pub counterparty_parameters: Option<CounterpartyChannelTransactionParameters>,
/// The late-bound funding outpoint
pub funding_outpoint: Option<chain::transaction::OutPoint>,
+ /// Are anchors used for this channel. Boolean is serialization backwards-compatible
+ pub opt_anchors: Option<()>
}
/// Late-bound per-channel counterparty data used to build transactions.
(4, is_outbound_from_holder, required),
(6, counterparty_parameters, option),
(8, funding_outpoint, option),
+ (10, opt_anchors, option),
});
/// Static channel fields used to build transactions given per-commitment fields, organized by
holder_selected_contest_delay: 0,
is_outbound_from_holder: false,
counterparty_parameters: Some(CounterpartyChannelTransactionParameters { pubkeys: channel_pubkeys.clone(), selected_contest_delay: 0 }),
- funding_outpoint: Some(chain::transaction::OutPoint { txid: Default::default(), index: 0 })
+ funding_outpoint: Some(chain::transaction::OutPoint { txid: Default::default(), index: 0 }),
+ opt_anchors: None
};
let mut htlcs_with_aux: Vec<(_, ())> = Vec::new();
let inner = CommitmentTransaction::new_with_auxiliary_htlc_data(0, 0, 0, false, dummy_key.clone(), dummy_key.clone(), keys, 0, &mut htlcs_with_aux, &channel_parameters.as_counterparty_broadcastable());
let mut htlcs = Vec::with_capacity(htlcs_with_aux.len());
for (htlc, _) in htlcs_with_aux {
- let script = chan_utils::get_htlc_redeemscript(&htlc, &keys);
+ let script = chan_utils::get_htlc_redeemscript(&htlc, opt_anchors, &keys);
let txout = TxOut {
script_pubkey: script.to_v0_p2wsh(),
value: htlc.amount_msat / 1000,
&self.inner.keys
}
+ /// Should anchors be used.
+ pub fn opt_anchors(&self) -> bool {
+ self.opt_anchors.is_some()
+ }
+
/// Get a signature for each HTLC which was included in the commitment transaction (ie for
/// which HTLCOutputInCommitment::transaction_output_index.is_some()).
///
assert!(this_htlc.transaction_output_index.is_some());
let htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
- let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
+ let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
let sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, this_htlc.amount_msat / 1000, SigHashType::All)[..]);
ret.push(secp_ctx.sign(&sighash, &holder_htlc_key));
let mut htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
- let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
+ let htlc_redeemscript = get_htlc_redeemscript_with_explicit_keys(&this_htlc, self.opt_anchors(), &keys.broadcaster_htlc_key, &keys.countersignatory_htlc_key, &keys.revocation_key);
// First push the multisig dummy, note that due to BIP147 (NULLDUMMY) it must be a zero-length element.
htlc_tx.input[0].witness.push(Vec::new());
use super::CounterpartyCommitmentSecrets;
use ::{hex, chain};
use prelude::*;
- use ln::chan_utils::{get_to_countersignatory_with_anchors_redeemscript, get_p2wpkh_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
+ use ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, get_p2wpkh_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
use util::test_utils;
use chain::keysinterface::{KeysInterface, BaseSign};
let holder_pubkeys = signer.pubkeys();
let counterparty_pubkeys = counterparty_signer.pubkeys();
let keys = TxCreationKeys::derive_new(&secp_ctx, &per_commitment_point, delayed_payment_base, htlc_basepoint, &counterparty_pubkeys.revocation_basepoint, &counterparty_pubkeys.htlc_basepoint).unwrap();
- let channel_parameters = ChannelTransactionParameters {
+ let mut channel_parameters = ChannelTransactionParameters {
holder_pubkeys: holder_pubkeys.clone(),
holder_selected_contest_delay: 0,
is_outbound_from_holder: false,
counterparty_parameters: Some(CounterpartyChannelTransactionParameters { pubkeys: counterparty_pubkeys.clone(), selected_contest_delay: 0 }),
- funding_outpoint: Some(chain::transaction::OutPoint { txid: Default::default(), index: 0 })
+ funding_outpoint: Some(chain::transaction::OutPoint { txid: Default::default(), index: 0 }),
+ opt_anchors: None
};
let mut htlcs_with_aux: Vec<(_, ())> = Vec::new();
);
assert_eq!(tx.built.transaction.output.len(), 2);
- // Generate broadcaster output, an HTLC output and two anchors
- let payment_hash = PaymentHash([42; 32]);
- let htlc_info = HTLCOutputInCommitment {
+ let received_htlc = HTLCOutputInCommitment {
offered: false,
- amount_msat: 1000000,
+ amount_msat: 400000,
+ cltv_expiry: 100,
+ payment_hash: PaymentHash([42; 32]),
+ transaction_output_index: None,
+ };
+
+ let offered_htlc = HTLCOutputInCommitment {
+ offered: true,
+ amount_msat: 600000,
cltv_expiry: 100,
- payment_hash,
+ payment_hash: PaymentHash([43; 32]),
transaction_output_index: None,
};
+ // Generate broadcaster output and received and offered HTLC outputs, w/o anchors
+ let tx = CommitmentTransaction::new_with_auxiliary_htlc_data(
+ 0, 3000, 0,
+ false,
+ holder_pubkeys.funding_pubkey,
+ counterparty_pubkeys.funding_pubkey,
+ keys.clone(), 1,
+ &mut vec![(received_htlc.clone(), ()), (offered_htlc.clone(), ())],
+ &channel_parameters.as_holder_broadcastable()
+ );
+ assert_eq!(tx.built.transaction.output.len(), 3);
+ assert_eq!(tx.built.transaction.output[0].script_pubkey, get_htlc_redeemscript(&received_htlc, false, &keys).to_v0_p2wsh());
+ assert_eq!(tx.built.transaction.output[1].script_pubkey, get_htlc_redeemscript(&offered_htlc, false, &keys).to_v0_p2wsh());
+
+ // Generate broadcaster output and received and offered HTLC outputs, with anchors
+ channel_parameters.opt_anchors = Some(());
let tx = CommitmentTransaction::new_with_auxiliary_htlc_data(
0, 3000, 0,
true,
holder_pubkeys.funding_pubkey,
counterparty_pubkeys.funding_pubkey,
keys.clone(), 1,
- &mut vec![(htlc_info, ())], &channel_parameters.as_holder_broadcastable()
+ &mut vec![(received_htlc.clone(), ()), (offered_htlc.clone(), ())],
+ &channel_parameters.as_holder_broadcastable()
);
- assert_eq!(tx.built.transaction.output.len(), 4);
+ assert_eq!(tx.built.transaction.output.len(), 5);
+ assert_eq!(tx.built.transaction.output[2].script_pubkey, get_htlc_redeemscript(&received_htlc, true, &keys).to_v0_p2wsh());
+ assert_eq!(tx.built.transaction.output[3].script_pubkey, get_htlc_redeemscript(&offered_htlc, true, &keys).to_v0_p2wsh());
}
#[test]
cmp::min(channel_value_satoshis, cmp::max(q, 1000)) //TODO
}
+ pub(crate) fn opt_anchors(&self) -> bool {
+ self.channel_transaction_parameters.opt_anchors.is_some()
+ }
+
// Constructors:
pub fn new_outbound<K: Deref, F: Deref>(
fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
holder_selected_contest_delay: config.own_channel_config.our_to_self_delay,
is_outbound_from_holder: true,
counterparty_parameters: None,
- funding_outpoint: None
+ funding_outpoint: None,
+ opt_anchors: None,
},
funding_transaction: None,
selected_contest_delay: msg.to_self_delay,
pubkeys: counterparty_pubkeys,
}),
- funding_outpoint: None
+ funding_outpoint: None,
+ opt_anchors: None
},
funding_transaction: None,
let tx = CommitmentTransaction::new_with_auxiliary_htlc_data(commitment_number,
value_to_a as u64,
value_to_b as u64,
- false,
+ self.channel_transaction_parameters.opt_anchors.is_some(),
funding_pubkey_a,
funding_pubkey_b,
keys.clone(),
self.get_counterparty_selected_contest_delay().unwrap(), &htlc,
&keys.broadcaster_delayed_payment_key, &keys.revocation_key);
- let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
+ let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys);
let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]);
log_trace!(logger, "Checking HTLC tx signature {} by key {} against tx {} (sighash {}) with redeemscript {} in channel {}.",
log_bytes!(msg.htlc_signatures[idx].serialize_compact()[..]), log_bytes!(keys.countersignatory_htlc_key.serialize()),
for (ref htlc_sig, ref htlc) in htlc_signatures.iter().zip(htlcs) {
log_trace!(logger, "Signed remote HTLC tx {} with redeemscript {} with pubkey {} -> {} in channel {}",
encode::serialize_hex(&chan_utils::build_htlc_transaction(&counterparty_commitment_txid, commitment_stats.feerate_per_kw, self.get_holder_selected_contest_delay(), htlc, &counterparty_keys.broadcaster_delayed_payment_key, &counterparty_keys.revocation_key)),
- encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, &counterparty_keys)),
+ encode::serialize_hex(&chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &counterparty_keys)),
log_bytes!(counterparty_keys.broadcaster_htlc_key.serialize()),
log_bytes!(htlc_sig.serialize_compact()[..]), log_bytes!(self.channel_id()));
}
return Err(DecodeError::UnknownRequiredFeature);
}
+ if channel_parameters.opt_anchors.is_some() {
+ // Relax this check when ChannelTypeFeatures supports anchors.
+ return Err(DecodeError::InvalidValue);
+ }
+
let mut secp_ctx = Secp256k1::new();
secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
let htlc_tx = chan_utils::build_htlc_transaction(&unsigned_tx.txid, chan.feerate_per_kw,
chan.get_counterparty_selected_contest_delay().unwrap(),
&htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
- let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
+ let opt_anchors = false;
+ let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, opt_anchors, &keys);
let htlc_sighash = Message::from_slice(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]).unwrap();
secp_ctx.verify(&htlc_sighash, &remote_signature, &keys.countersignatory_htlc_key).unwrap();
}
}
+ pub fn opt_anchors(&self) -> bool { self.inner.opt_anchors() }
+
#[cfg(test)]
pub fn get_enforcement_state(&self) -> MutexGuard<EnforcementState> {
self.state.lock().unwrap()
let keys = trusted_tx.keys();
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, trusted_tx.feerate_per_kw(), holder_csv, &this_htlc, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
- let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&this_htlc, &keys);
+ let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&this_htlc, self.opt_anchors(), &keys);
let sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, this_htlc.amount_msat / 1000, SigHashType::All)[..]);
secp_ctx.verify(&sighash, sig, &keys.countersignatory_htlc_key).unwrap();