let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id);
let remote_txn = get_local_commitment_txn!(nodes[1], chan_id);
+ let sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC {
+ claimable_amount_satoshis: 3_000,
+ claimable_height: htlc_cltv_timeout,
+ };
+ let sent_htlc_timeout_balance = Balance::MaybeTimeoutClaimableHTLC {
+ claimable_amount_satoshis: 4_000,
+ claimable_height: htlc_cltv_timeout,
+ };
+ let received_htlc_balance = Balance::MaybePreimageClaimableHTLC {
+ claimable_amount_satoshis: 3_000,
+ expiry_height: htlc_cltv_timeout,
+ };
+ let received_htlc_timeout_balance = Balance::MaybePreimageClaimableHTLC {
+ claimable_amount_satoshis: 4_000,
+ expiry_height: htlc_cltv_timeout,
+ };
+ let received_htlc_claiming_balance = Balance::ContentiousClaimable {
+ claimable_amount_satoshis: 3_000,
+ timeout_height: htlc_cltv_timeout,
+ };
+ let received_htlc_timeout_claiming_balance = Balance::ContentiousClaimable {
+ claimable_amount_satoshis: 4_000,
+ timeout_height: htlc_cltv_timeout,
+ };
+
// Before B receives the payment preimage, it only suggests the push_msat value of 1_000 sats
// as claimable. A lists both its to-self balance and the (possibly-claimable) HTLCs.
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
claimable_amount_satoshis: 1_000_000 - 3_000 - 4_000 - 1_000 - 3 - chan_feerate *
(channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 3_000,
- claimable_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 4_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ }, sent_htlc_balance.clone(), sent_htlc_timeout_balance.clone()]),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
claimable_amount_satoshis: 1_000,
- }, Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 3_000,
- expiry_height: htlc_cltv_timeout,
- }, Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 4_000,
- expiry_height: htlc_cltv_timeout,
- }]),
+ }, received_htlc_balance.clone(), received_htlc_timeout_balance.clone()]),
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
nodes[1].node.claim_funds(payment_preimage);
chan_feerate * (channel::commitment_tx_base_weight(opt_anchors) +
if prev_commitment_tx { 1 } else { 2 } *
channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 4_000,
- claimable_height: htlc_cltv_timeout,
- }];
+ }, sent_htlc_timeout_balance.clone()];
if !prev_commitment_tx {
- a_expected_balances.push(Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 3_000,
- claimable_height: htlc_cltv_timeout,
- });
+ a_expected_balances.push(sent_htlc_balance.clone());
}
assert_eq!(sorted_vec(a_expected_balances),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
claimable_amount_satoshis: 1_000_000 - 3_000 - 4_000 - 1_000 - 3 - chan_feerate *
(channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
confirmation_height: nodes[0].best_block_info().1 + ANTI_REORG_DELAY - 1,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 3_000,
- claimable_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 4_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ }, sent_htlc_balance.clone(), sent_htlc_timeout_balance.clone()]),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
// The main non-HTLC balance is just awaiting confirmations, but the claimable height is the
// CSV delay, not ANTI_REORG_DELAY.
},
// Both HTLC balances are "contentious" as our counterparty could claim them if we wait too
// long.
- Balance::ContentiousClaimable {
- claimable_amount_satoshis: 3_000,
- timeout_height: htlc_cltv_timeout,
- }, Balance::ContentiousClaimable {
- claimable_amount_satoshis: 4_000,
- timeout_height: htlc_cltv_timeout,
- }]),
+ received_htlc_claiming_balance.clone(), received_htlc_timeout_claiming_balance.clone()]),
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
// After ANTI_REORG_DELAY, A will consider its balance fully spendable and generate a
// `SpendableOutputs` event. However, B still has to wait for the CSV delay.
- assert_eq!(sorted_vec(vec![Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 3_000,
- claimable_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 4_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ assert_eq!(sorted_vec(vec![sent_htlc_balance.clone(), sent_htlc_timeout_balance.clone()]),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
assert_eq!(sorted_vec(vec![Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 1_000,
confirmation_height: node_b_commitment_claimable,
- }, Balance::ContentiousClaimable {
- claimable_amount_satoshis: 3_000,
- timeout_height: htlc_cltv_timeout,
- }, Balance::ContentiousClaimable {
- claimable_amount_satoshis: 4_000,
- timeout_height: htlc_cltv_timeout,
- }]),
+ }, received_htlc_claiming_balance.clone(), received_htlc_timeout_claiming_balance.clone()]),
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
test_spendable_output(&nodes[0], &remote_txn[0]);
} else {
expect_payment_sent!(nodes[0], payment_preimage);
}
- assert_eq!(sorted_vec(vec![Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 3_000,
- claimable_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 4_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ assert_eq!(sorted_vec(vec![sent_htlc_balance.clone(), sent_htlc_timeout_balance.clone()]),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
- assert_eq!(vec![Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 4_000,
- claimable_height: htlc_cltv_timeout,
- }],
+ assert_eq!(vec![sent_htlc_timeout_balance.clone()],
nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances());
// When the HTLC timeout output is spendable in the next block, A should broadcast it
}, Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 3_000,
confirmation_height: node_b_htlc_claimable,
- }, Balance::ContentiousClaimable {
- claimable_amount_satoshis: 4_000,
- timeout_height: htlc_cltv_timeout,
- }]),
+ }, received_htlc_timeout_claiming_balance.clone()]),
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
// After reaching the commitment output CSV, we'll get a SpendableOutputs event for it and have
assert_eq!(sorted_vec(vec![Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 3_000,
confirmation_height: node_b_htlc_claimable,
- }, Balance::ContentiousClaimable {
- claimable_amount_satoshis: 4_000,
- timeout_height: htlc_cltv_timeout,
- }]),
+ }, received_htlc_timeout_claiming_balance.clone()]),
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
// After reaching the claimed HTLC output CSV, we'll get a SpendableOutptus event for it and
connect_blocks(&nodes[1], node_b_htlc_claimable - nodes[1].best_block_info().1);
test_spendable_output(&nodes[1], &b_broadcast_txn[0]);
- assert_eq!(vec![Balance::ContentiousClaimable {
- claimable_amount_satoshis: 4_000,
- timeout_height: htlc_cltv_timeout,
- }],
+ assert_eq!(vec![received_htlc_timeout_claiming_balance.clone()],
nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances());
// Finally, mine the HTLC timeout transaction that A broadcasted (even though B should be able
// to claim this HTLC with the preimage it knows!). It will remain listed as a claimable HTLC
// until ANTI_REORG_DELAY confirmations on the spend.
mine_transaction(&nodes[1], &a_broadcast_txn[1]);
- assert_eq!(vec![Balance::ContentiousClaimable {
- claimable_amount_satoshis: 4_000,
- timeout_height: htlc_cltv_timeout,
- }],
+ assert_eq!(vec![received_htlc_timeout_claiming_balance.clone()],
nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances());
connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1);
assert_eq!(Vec::<Balance>::new(),
check_closed_broadcast!(nodes[0], true);
check_closed_event!(nodes[0], 1, ClosureReason::CommitmentTxConfirmed);
+ let htlc_balance_known_preimage = Balance::MaybeTimeoutClaimableHTLC {
+ claimable_amount_satoshis: 10_000,
+ claimable_height: htlc_cltv_timeout,
+ };
+ let htlc_balance_unknown_preimage = Balance::MaybeTimeoutClaimableHTLC {
+ claimable_amount_satoshis: 20_000,
+ claimable_height: htlc_cltv_timeout,
+ };
+
assert_eq!(sorted_vec(vec![Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 1_000_000 - 10_000 - 20_000 - chan_feerate *
(channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
confirmation_height: node_a_commitment_claimable,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 10_000,
- claimable_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ }, htlc_balance_known_preimage.clone(), htlc_balance_unknown_preimage.clone()]),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
// Get nodes[1]'s HTLC claim tx for the second HTLC
claimable_amount_satoshis: 1_000_000 - 10_000 - 20_000 - chan_feerate *
(channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
confirmation_height: node_a_commitment_claimable,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 10_000,
- claimable_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ }, htlc_balance_known_preimage.clone(), htlc_balance_unknown_preimage.clone()]),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
assert_eq!(as_txn[1].lock_time.0, nodes[0].best_block_info().1 + 1); // as_txn[1] can be included in the next block
}, Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 10_000,
confirmation_height: node_a_htlc_claimable,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ }, htlc_balance_unknown_preimage.clone()]),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
// Now confirm nodes[1]'s HTLC claim, giving nodes[0] the preimage. Note that the "maybe
}, Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 10_000,
confirmation_height: node_a_htlc_claimable,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ }, htlc_balance_unknown_preimage.clone()]),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
// Finally make the HTLC transactions have ANTI_REORG_DELAY blocks. This call previously
let chan_feerate = get_feerate!(nodes[0], nodes[1], chan_id) as u64;
let opt_anchors = get_opt_anchors!(nodes[0], nodes[1], chan_id);
+ let a_sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC {
+ claimable_amount_satoshis: 10_000,
+ claimable_height: htlc_cltv_timeout,
+ };
+ let a_received_htlc_balance = Balance::MaybePreimageClaimableHTLC {
+ claimable_amount_satoshis: 20_000,
+ expiry_height: htlc_cltv_timeout,
+ };
+ let b_received_htlc_balance = Balance::MaybePreimageClaimableHTLC {
+ claimable_amount_satoshis: 10_000,
+ expiry_height: htlc_cltv_timeout,
+ };
+ let b_sent_htlc_balance = Balance::MaybeTimeoutClaimableHTLC {
+ claimable_amount_satoshis: 20_000,
+ claimable_height: htlc_cltv_timeout,
+ };
+
// Both A and B will have an HTLC that's claimable on timeout and one that's claimable if they
// receive the preimage. These will remain the same through the channel closure and until the
// HTLC output is spent.
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate *
(channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
- }, Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- expiry_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 10_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ }, a_received_htlc_balance.clone(), a_sent_htlc_balance.clone()]),
sorted_vec(nodes[0].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
assert_eq!(sorted_vec(vec![Balance::ClaimableOnChannelClose {
claimable_amount_satoshis: 500_000 - 20_000,
- }, Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 10_000,
- expiry_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- claimable_height: htlc_cltv_timeout,
- }]),
+ }, b_received_htlc_balance.clone(), b_sent_htlc_balance.clone()]),
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
// Get nodes[0]'s commitment transaction and HTLC-Timeout transaction
claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate *
(channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
confirmation_height: node_a_commitment_claimable,
- }, Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- expiry_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 10_000,
- claimable_height: htlc_cltv_timeout,
- }]);
+ }, a_received_htlc_balance.clone(), a_sent_htlc_balance.clone()]);
mine_transaction(&nodes[0], &as_txn[0]);
nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().clear();
let mut bs_pre_spend_claims = sorted_vec(vec![Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 500_000 - 20_000,
confirmation_height: node_b_commitment_claimable,
- }, Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 10_000,
- expiry_height: htlc_cltv_timeout,
- }, Balance::MaybeTimeoutClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- claimable_height: htlc_cltv_timeout,
- }]);
+ }, b_received_htlc_balance.clone(), b_sent_htlc_balance.clone()]);
assert_eq!(bs_pre_spend_claims,
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate *
(channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
confirmation_height: node_a_commitment_claimable,
- }, Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- expiry_height: htlc_cltv_timeout,
- }, Balance::ClaimableAwaitingConfirmations {
+ }, a_received_htlc_balance.clone(), Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 10_000,
confirmation_height: as_timeout_claimable_height,
}]),
claimable_amount_satoshis: 1_000_000 - 500_000 - 10_000 - chan_feerate *
(channel::commitment_tx_base_weight(opt_anchors) + 2 * channel::COMMITMENT_TX_WEIGHT_PER_HTLC) / 1000,
confirmation_height: node_a_commitment_claimable,
- }, Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 20_000,
- expiry_height: htlc_cltv_timeout,
- }, Balance::ClaimableAwaitingConfirmations {
+ }, a_received_htlc_balance.clone(), Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 10_000,
confirmation_height: as_timeout_claimable_height,
}]),
// was already claimed.
mine_transaction(&nodes[1], &bs_htlc_timeout_claim[0]);
let bs_timeout_claimable_height = nodes[1].best_block_info().1 + ANTI_REORG_DELAY - 1;
- assert_eq!(sorted_vec(vec![Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 10_000,
- expiry_height: htlc_cltv_timeout,
- }, Balance::ClaimableAwaitingConfirmations {
+ assert_eq!(sorted_vec(vec![b_received_htlc_balance.clone(), Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 20_000,
confirmation_height: bs_timeout_claimable_height,
}]),
sorted_vec(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()));
mine_transaction(&nodes[1], &as_htlc_timeout_claim[0]);
- assert_eq!(sorted_vec(vec![Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 10_000,
- expiry_height: htlc_cltv_timeout,
- }, Balance::ClaimableAwaitingConfirmations {
+ assert_eq!(sorted_vec(vec![b_received_htlc_balance.clone(), Balance::ClaimableAwaitingConfirmations {
claimable_amount_satoshis: 20_000,
confirmation_height: bs_timeout_claimable_height,
}]),
connect_blocks(&nodes[1], ANTI_REORG_DELAY - 2);
expect_payment_failed!(nodes[1], to_a_failed_payment_hash, false);
- assert_eq!(vec![Balance::MaybePreimageClaimableHTLC {
- claimable_amount_satoshis: 10_000,
- expiry_height: htlc_cltv_timeout,
- }],
+ assert_eq!(vec![b_received_htlc_balance.clone()],
nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances());
test_spendable_output(&nodes[1], &bs_htlc_timeout_claim[0]);