Skip to content

Commit 2b78957

Browse files
authored
Merge pull request #1176 from lightning-signer/2021-11-htlc-anchors
Add anchors support for HTLCs
2 parents ba50dd5 + 530abc5 commit 2b78957

File tree

7 files changed

+157
-58
lines changed

7 files changed

+157
-58
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3381,6 +3381,7 @@ mod tests {
33813381
selected_contest_delay: 67,
33823382
}),
33833383
funding_outpoint: Some(funding_outpoint),
3384+
opt_anchors: None,
33843385
};
33853386
// Prune with one old state and a holder commitment tx holding a few overlaps with the
33863387
// old state.
@@ -3446,15 +3447,15 @@ mod tests {
34463447
let mut sum_actual_sigs = 0;
34473448

34483449
macro_rules! sign_input {
3449-
($sighash_parts: expr, $idx: expr, $amount: expr, $weight: expr, $sum_actual_sigs: expr) => {
3450+
($sighash_parts: expr, $idx: expr, $amount: expr, $weight: expr, $sum_actual_sigs: expr, $opt_anchors: expr) => {
34503451
let htlc = HTLCOutputInCommitment {
34513452
offered: if *$weight == WEIGHT_REVOKED_OFFERED_HTLC || *$weight == WEIGHT_OFFERED_HTLC { true } else { false },
34523453
amount_msat: 0,
34533454
cltv_expiry: 2 << 16,
34543455
payment_hash: PaymentHash([1; 32]),
34553456
transaction_output_index: Some($idx as u32),
34563457
};
3457-
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) };
3458+
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) };
34583459
let sighash = hash_to_message!(&$sighash_parts.signature_hash($idx, &redeem_script, $amount, SigHashType::All)[..]);
34593460
let sig = secp_ctx.sign(&sighash, &privkey);
34603461
$sighash_parts.access_witness($idx).push(sig.serialize_der().to_vec());
@@ -3502,7 +3503,7 @@ mod tests {
35023503
{
35033504
let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
35043505
for (idx, inp) in inputs_weight.iter().enumerate() {
3505-
sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
3506+
sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, false);
35063507
inputs_total_weight += inp;
35073508
}
35083509
}
@@ -3528,7 +3529,7 @@ mod tests {
35283529
{
35293530
let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
35303531
for (idx, inp) in inputs_weight.iter().enumerate() {
3531-
sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
3532+
sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, false);
35323533
inputs_total_weight += inp;
35333534
}
35343535
}
@@ -3552,7 +3553,7 @@ mod tests {
35523553
{
35533554
let mut sighash_parts = bip143::SigHashCache::new(&mut claim_tx);
35543555
for (idx, inp) in inputs_weight.iter().enumerate() {
3555-
sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs);
3556+
sign_input!(sighash_parts, idx, 0, inp, sum_actual_sigs, false);
35563557
inputs_total_weight += inp;
35573558
}
35583559
}

lightning/src/chain/keysinterface.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,12 @@ impl InMemorySigner {
505505
self.channel_parameters.as_ref().unwrap()
506506
}
507507

508+
/// Whether anchors should be used.
509+
/// Will panic if ready_channel wasn't called.
510+
pub fn opt_anchors(&self) -> bool {
511+
self.get_channel_parameters().opt_anchors.is_some()
512+
}
513+
508514
/// Sign the single input of spend_tx at index `input_idx` which spends the output
509515
/// described by descriptor, returning the witness stack for the input.
510516
///
@@ -593,8 +599,8 @@ impl BaseSign for InMemorySigner {
593599

594600
let mut htlc_sigs = Vec::with_capacity(commitment_tx.htlcs().len());
595601
for htlc in commitment_tx.htlcs() {
596-
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);
597-
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, &keys);
602+
let htlc_tx = chan_utils::build_htlc_transaction(&commitment_txid, commitment_tx.feerate_per_kw(), self.holder_selected_contest_delay(), htlc, self.opt_anchors(), &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
603+
let htlc_redeemscript = chan_utils::get_htlc_redeemscript(&htlc, self.opt_anchors(), &keys);
598604
let htlc_sighash = hash_to_message!(&bip143::SigHashCache::new(&htlc_tx).signature_hash(0, &htlc_redeemscript, htlc.amount_msat / 1000, SigHashType::All)[..]);
599605
let holder_htlc_key = chan_utils::derive_private_key(&secp_ctx, &keys.per_commitment_point, &self.htlc_base_key).map_err(|_| ())?;
600606
htlc_sigs.push(secp_ctx.sign(&htlc_sighash, &holder_htlc_key));
@@ -648,7 +654,7 @@ impl BaseSign for InMemorySigner {
648654
let witness_script = {
649655
let counterparty_htlcpubkey = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.counterparty_pubkeys().htlc_basepoint).map_err(|_| ())?;
650656
let holder_htlcpubkey = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.pubkeys().htlc_basepoint).map_err(|_| ())?;
651-
chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &counterparty_htlcpubkey, &holder_htlcpubkey, &revocation_pubkey)
657+
chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, self.opt_anchors(), &counterparty_htlcpubkey, &holder_htlcpubkey, &revocation_pubkey)
652658
};
653659
let mut sighash_parts = bip143::SigHashCache::new(justice_tx);
654660
let sighash = hash_to_message!(&sighash_parts.signature_hash(input, &witness_script, amount, SigHashType::All)[..]);
@@ -660,7 +666,7 @@ impl BaseSign for InMemorySigner {
660666
let witness_script = if let Ok(revocation_pubkey) = chan_utils::derive_public_revocation_key(&secp_ctx, &per_commitment_point, &self.pubkeys().revocation_basepoint) {
661667
if let Ok(counterparty_htlcpubkey) = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.counterparty_pubkeys().htlc_basepoint) {
662668
if let Ok(htlcpubkey) = chan_utils::derive_public_key(&secp_ctx, &per_commitment_point, &self.pubkeys().htlc_basepoint) {
663-
chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, &counterparty_htlcpubkey, &htlcpubkey, &revocation_pubkey)
669+
chan_utils::get_htlc_redeemscript_with_explicit_keys(&htlc, self.opt_anchors(), &counterparty_htlcpubkey, &htlcpubkey, &revocation_pubkey)
664670
} else { return Err(()) }
665671
} else { return Err(()) }
666672
} else { return Err(()) };

lightning/src/chain/onchaintx.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,10 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
786786
htlc_tx
787787
}
788788

789+
pub(crate) fn opt_anchors(&self) -> bool {
790+
self.channel_transaction_parameters.opt_anchors.is_some()
791+
}
792+
789793
#[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
790794
pub(crate) fn unsafe_get_fully_signed_htlc_tx(&mut self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>) -> Option<Transaction> {
791795
let latest_had_sigs = self.holder_htlc_sigs.is_some();

lightning/src/chain/package.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ impl PackageSolvingData {
341341
},
342342
PackageSolvingData::RevokedHTLCOutput(ref outp) => {
343343
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) {
344-
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);
344+
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);
345345
//TODO: should we panic on signer failure ?
346346
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) {
347347
bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
@@ -353,7 +353,7 @@ impl PackageSolvingData {
353353
},
354354
PackageSolvingData::CounterpartyOfferedHTLCOutput(ref outp) => {
355355
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) {
356-
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);
356+
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);
357357

358358
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) {
359359
bumped_tx.input[i].witness.push(sig.serialize_der().to_vec());
@@ -365,7 +365,7 @@ impl PackageSolvingData {
365365
},
366366
PackageSolvingData::CounterpartyReceivedHTLCOutput(ref outp) => {
367367
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) {
368-
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);
368+
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);
369369

370370
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
371371
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) {

0 commit comments

Comments
 (0)