Skip to content

Commit 2e0a0f7

Browse files
author
Antoine Riard
committed
Add RBF-bumping of preimage/timeout txn on remote HTLC outputs
Given they are only signed by us we can RBF at wish Fix tests broken by introduction of more txn broadcast
1 parent 3f8df98 commit 2e0a0f7

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

src/ln/channelmonitor.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,8 +2439,25 @@ impl ChannelMonitor {
24392439
return Some((new_timer, bumped_tx, new_feerate));
24402440
}
24412441
},
2442-
TxMaterial::RemoteHTLC { .. } => {
2443-
return None;
2442+
TxMaterial::RemoteHTLC { ref script, ref key, ref preimage, ref amount } => {
2443+
let predicted_weight = bumped_tx.get_weight() + Self::get_witnesses_weight(if preimage.is_some() { &[InputDescriptors::OfferedHTLC] } else { &[InputDescriptors::ReceivedHTLC] });
2444+
if let Some((new_fee, new_feerate)) = RBF_bump!(*amount, old_feerate, fee_estimator, predicted_weight, claimed_outpoint, "remote htlc") {
2445+
bumped_tx.output[0].value = amount - new_fee;
2446+
let sighash_parts = bip143::SighashComponents::new(&bumped_tx);
2447+
let sighash = hash_to_message!(&sighash_parts.sighash_all(&bumped_tx.input[0], &script, *amount)[..]);
2448+
let sig = self.secp_ctx.sign(&sighash, &key);
2449+
bumped_tx.input[0].witness.push(sig.serialize_der().to_vec());
2450+
bumped_tx.input[0].witness[0].push(SigHashType::All as u8);
2451+
if let &Some(preimage) = preimage {
2452+
bumped_tx.input[0].witness.push(preimage.clone().0.to_vec());
2453+
} else {
2454+
bumped_tx.input[0].witness.push(vec![0]);
2455+
}
2456+
bumped_tx.input[0].witness.push(script.clone().into_bytes());
2457+
assert!(predicted_weight >= bumped_tx.get_weight());
2458+
log_info!(self, "Going to broadcast bumped Claim Transaction {} claiming remote htlc output {} from {} with new feerate {}", bumped_tx.txid(), claimed_outpoint.vout, claimed_outpoint.txid, new_feerate);
2459+
return Some((new_timer, bumped_tx, new_feerate));
2460+
}
24442461
},
24452462
TxMaterial::LocalHTLC { .. } => {
24462463
//TODO : Given that Local Commitment Transaction and HTLC-Timeout/HTLC-Success are counter-signed by peer, we can't

src/ln/functional_tests.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,14 +1695,19 @@ fn channel_monitor_network_test() {
16951695
let payment_preimage_2 = route_payment(&nodes[3], &vec!(&nodes[4])[..], 3000000).0;
16961696
// CLTV expires at TEST_FINAL_CLTV + 1 (current height) + 1 (added in send_payment for
16971697
// buffer space).
1698-
16991698
{
17001699
let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
17011700
nodes[3].chain_monitor.block_connected_checked(&header, 7, &Vec::new()[..], &[0; 0]);
17021701
for i in 8..TEST_FINAL_CLTV + 2 + HTLC_FAIL_TIMEOUT_BLOCKS + 6 {
17031702
header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
17041703
nodes[3].chain_monitor.block_connected_checked(&header, i, &Vec::new()[..], &[0; 0]);
17051704
}
1705+
{
1706+
let mut node_txn = nodes[3].tx_broadcaster.txn_broadcasted.lock().unwrap();
1707+
node_txn.swap_remove(0);
1708+
node_txn.swap_remove(1);
1709+
node_txn.truncate(2);
1710+
}
17061711

17071712
let node_txn = test_txn_broadcast(&nodes[3], &chan_4, None, HTLCType::TIMEOUT);
17081713

@@ -2151,16 +2156,16 @@ fn test_htlc_on_chain_success() {
21512156
connect_blocks(&nodes[1].chain_monitor, HTLC_FAIL_ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
21522157
check_closed_broadcast!(nodes[1]);
21532158
let node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap().clone(); // ChannelManager : 1 (commitment tx), ChannelMonitor : 1 (HTLC-Success) * 2 (block-rescan)
2154-
assert_eq!(node_txn.len(), 3);
2159+
assert_eq!(node_txn.len(), 5);
21552160
assert_eq!(node_txn[0], node_txn[1]);
21562161
check_spends!(node_txn[0], commitment_tx[0].clone());
21572162
assert_eq!(node_txn[0].input.len(), 2);
21582163
assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
21592164
assert_eq!(node_txn[0].input[1].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
21602165
assert_eq!(node_txn[0].lock_time, 0);
21612166
assert!(node_txn[0].output[0].script_pubkey.is_v0_p2wpkh()); // direct payment
2162-
check_spends!(node_txn[2], chan_1.3.clone());
2163-
assert_eq!(node_txn[2].input[0].witness.clone().last().unwrap().len(), 71);
2167+
check_spends!(node_txn[4], chan_1.3.clone());
2168+
assert_eq!(node_txn[4].input[0].witness.clone().last().unwrap().len(), 71);
21642169
// We don't bother to check that B can claim the HTLC output on its commitment tx here as
21652170
// we already checked the same situation with A.
21662171

@@ -3643,7 +3648,7 @@ fn test_static_spendable_outputs_preimage_tx() {
36433648
check_spends!(node_txn[0], commitment_tx[0].clone());
36443649
assert_eq!(node_txn[0], node_txn[1]);
36453650
assert_eq!(node_txn[0].input[0].witness.last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);
3646-
check_spends!(node_txn[2], chan_1.3.clone());
3651+
check_spends!(node_txn[3], chan_1.3.clone());
36473652

36483653
let spend_txn = check_spendable_outputs!(nodes[1], 1); // , 0, 0, 1, 1);
36493654
assert_eq!(spend_txn.len(), 2);
@@ -3861,8 +3866,8 @@ fn test_onchain_to_onchain_claim() {
38613866
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![commitment_tx[0].clone()]}, 1);
38623867
connect_blocks(&nodes[1].chain_monitor, HTLC_FAIL_ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
38633868
let b_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
3864-
assert_eq!(b_txn.len(), 3);
3865-
check_spends!(b_txn[2], chan_1.3); // Local commitment tx, issued by ChannelManager
3869+
assert_eq!(b_txn.len(), 4);
3870+
check_spends!(b_txn[3], chan_1.3); // Local commitment tx, issued by ChannelManager
38663871
assert_eq!(b_txn[0], b_txn[1]); // HTLC-Success tx, issued by ChannelMonitor, * 2 due to block rescan
38673872
check_spends!(b_txn[0], commitment_tx[0].clone());
38683873
assert_eq!(b_txn[0].input[0].witness.clone().last().unwrap().len(), OFFERED_HTLC_SCRIPT_WEIGHT);

0 commit comments

Comments
 (0)