Skip to content

Commit 2e15117

Browse files
committed
Always return failure in update_monitor after funding spend
Previously, monitor updates were allowed freely even after a funding-spend transaction confirmed. This would allow a race condition where we could receive a payment (including the counterparty revoking their broadcasted state!) and accept it without recourse as long as the ChannelMonitor receives the block first, the full commitment update dance occurs after the block is connected, and before the ChannelManager receives the block. Obviously this is an incredibly contrived race given the counterparty would be risking their full channel balance for it, but its worth fixing nonetheless as it makes the potential ChannelMonitor states simpler to reason about. The test in this commit also tests the behavior changed in the previous commit.
1 parent 25ac76f commit 2e15117

File tree

2 files changed

+134
-5
lines changed

2 files changed

+134
-5
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 123 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,11 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
700700
// remote monitor out-of-order with regards to the block view.
701701
holder_tx_signed: bool,
702702

703+
// If a spend of the funding output is seen, we set this to true and reject any further
704+
// updates. This prevents any further changes in the offchain state no matter the order
705+
// of block connection between ChannelMonitors and the ChannelManager.
706+
funding_spend_seen: bool,
707+
703708
funding_spend_confirmed: Option<Txid>,
704709
/// The set of HTLCs which have been either claimed or failed on chain and have reached
705710
/// the requisite confirmations on the claim/fail transaction (either ANTI_REORG_DELAY or the
@@ -765,6 +770,7 @@ impl<Signer: Sign> PartialEq for ChannelMonitorImpl<Signer> {
765770
self.outputs_to_watch != other.outputs_to_watch ||
766771
self.lockdown_from_offchain != other.lockdown_from_offchain ||
767772
self.holder_tx_signed != other.holder_tx_signed ||
773+
self.funding_spend_seen != other.funding_spend_seen ||
768774
self.funding_spend_confirmed != other.funding_spend_confirmed ||
769775
self.htlcs_resolved_on_chain != other.htlcs_resolved_on_chain
770776
{
@@ -940,6 +946,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
940946
(1, self.funding_spend_confirmed, option),
941947
(3, self.htlcs_resolved_on_chain, vec_type),
942948
(5, self.pending_monitor_events, vec_type),
949+
(7, self.funding_spend_seen, required),
943950
});
944951

945952
Ok(())
@@ -1038,6 +1045,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
10381045

10391046
lockdown_from_offchain: false,
10401047
holder_tx_signed: false,
1048+
funding_spend_seen: false,
10411049
funding_spend_confirmed: None,
10421050
htlcs_resolved_on_chain: Vec::new(),
10431051

@@ -1847,6 +1855,10 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
18471855
}
18481856
}
18491857
self.latest_update_id = updates.update_id;
1858+
1859+
if ret.is_ok() && self.funding_spend_seen {
1860+
ret = Err(MonitorUpdateError("Counterparty attempted to update commitment after funding was spent"));
1861+
}
18501862
ret
18511863
}
18521864

@@ -2275,6 +2287,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
22752287
if prevout.txid == self.funding_info.0.txid && prevout.vout == self.funding_info.0.index as u32 {
22762288
let mut balance_spendable_csv = None;
22772289
log_info!(logger, "Channel closed by funding output spend in txid {}.", log_bytes!(tx.txid()));
2290+
self.funding_spend_seen = true;
22782291
if (tx.input[0].sequence >> 8*3) as u8 == 0x80 && (tx.lock_time >> 8*3) as u8 == 0x20 {
22792292
let (mut new_outpoints, new_outputs) = self.check_spend_counterparty_transaction(&tx, height, &logger);
22802293
if !new_outputs.1.is_empty() {
@@ -3124,10 +3137,12 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
31243137

31253138
let mut funding_spend_confirmed = None;
31263139
let mut htlcs_resolved_on_chain = Some(Vec::new());
3140+
let mut funding_spend_seen = Some(false);
31273141
read_tlv_fields!(reader, {
31283142
(1, funding_spend_confirmed, option),
31293143
(3, htlcs_resolved_on_chain, vec_type),
31303144
(5, pending_monitor_events, vec_type),
3145+
(7, funding_spend_seen, option),
31313146
});
31323147

31333148
let mut secp_ctx = Secp256k1::new();
@@ -3177,6 +3192,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
31773192

31783193
lockdown_from_offchain,
31793194
holder_tx_signed,
3195+
funding_spend_seen: funding_spend_seen.unwrap(),
31803196
funding_spend_confirmed,
31813197
htlcs_resolved_on_chain: htlcs_resolved_on_chain.unwrap(),
31823198

@@ -3190,6 +3206,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
31903206

31913207
#[cfg(test)]
31923208
mod tests {
3209+
use bitcoin::blockdata::block::BlockHeader;
31933210
use bitcoin::blockdata::script::{Script, Builder};
31943211
use bitcoin::blockdata::opcodes;
31953212
use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut, SigHashType};
@@ -3198,24 +3215,125 @@ mod tests {
31983215
use bitcoin::hashes::Hash;
31993216
use bitcoin::hashes::sha256::Hash as Sha256;
32003217
use bitcoin::hashes::hex::FromHex;
3201-
use bitcoin::hash_types::Txid;
3218+
use bitcoin::hash_types::{BlockHash, Txid};
32023219
use bitcoin::network::constants::Network;
3220+
use bitcoin::secp256k1::key::{SecretKey,PublicKey};
3221+
use bitcoin::secp256k1::Secp256k1;
3222+
32033223
use hex;
3204-
use chain::BestBlock;
3224+
3225+
use super::ChannelMonitorUpdateStep;
3226+
use ::{check_added_monitors, check_closed_broadcast, check_closed_event, check_spends, get_local_commitment_txn, get_monitor, get_route_and_payment_hash, unwrap_send_err};
3227+
use chain::{BestBlock, Confirm};
32053228
use chain::channelmonitor::ChannelMonitor;
32063229
use chain::package::{WEIGHT_OFFERED_HTLC, WEIGHT_RECEIVED_HTLC, WEIGHT_REVOKED_OFFERED_HTLC, WEIGHT_REVOKED_RECEIVED_HTLC, WEIGHT_REVOKED_OUTPUT};
32073230
use chain::transaction::OutPoint;
3231+
use chain::keysinterface::InMemorySigner;
32083232
use ln::{PaymentPreimage, PaymentHash};
32093233
use ln::chan_utils;
32103234
use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
3235+
use ln::channelmanager::PaymentSendFailure;
3236+
use ln::features::InitFeatures;
3237+
use ln::functional_test_utils::*;
32113238
use ln::script::ShutdownScript;
3239+
use util::errors::APIError;
3240+
use util::events::{ClosureReason, MessageSendEventsProvider};
32123241
use util::test_utils::{TestLogger, TestBroadcaster, TestFeeEstimator};
3213-
use bitcoin::secp256k1::key::{SecretKey,PublicKey};
3214-
use bitcoin::secp256k1::Secp256k1;
3242+
use util::ser::{ReadableArgs, Writeable};
32153243
use sync::{Arc, Mutex};
3216-
use chain::keysinterface::InMemorySigner;
3244+
use io;
32173245
use prelude::*;
32183246

3247+
fn do_test_funding_spend_refuses_updates(use_local_txn: bool) {
3248+
// Previously, monitor updates were allowed freely even after a funding-spend transaction
3249+
// confirmed. This would allow a race condition where we could receive a payment (including
3250+
// the counterparty revoking their broadcasted state!) and accept it without recourse as
3251+
// long as the ChannelMonitor receives the block first, the full commitment update dance
3252+
// occurs after the block is connected, and before the ChannelManager receives the block.
3253+
// Obviously this is an incredibly contrived race given the counterparty would be risking
3254+
// their full channel balance for it, but its worth fixing nonetheless as it makes the
3255+
// potential ChannelMonitor states simpler to reason about.
3256+
//
3257+
// This test checks said behavior, as well as ensuring a ChannelMonitorUpdate with multiple
3258+
// updates is handled correctly in such conditions.
3259+
let chanmon_cfgs = create_chanmon_cfgs(3);
3260+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
3261+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
3262+
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
3263+
let channel = create_announced_chan_between_nodes(
3264+
&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
3265+
create_announced_chan_between_nodes(
3266+
&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
3267+
3268+
// Rebalance somewhat
3269+
send_payment(&nodes[0], &[&nodes[1]], 10_000_000);
3270+
3271+
// First route two payments for testing at the end
3272+
let payment_preimage_1 = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000).0;
3273+
let payment_preimage_2 = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000).0;
3274+
3275+
let local_txn = get_local_commitment_txn!(nodes[1], channel.2);
3276+
assert_eq!(local_txn.len(), 1);
3277+
let remote_txn = get_local_commitment_txn!(nodes[0], channel.2);
3278+
assert_eq!(remote_txn.len(), 3); // Commitment and two HTLC-Timeouts
3279+
check_spends!(remote_txn[1], remote_txn[0]);
3280+
check_spends!(remote_txn[2], remote_txn[0]);
3281+
let broadcast_tx = if use_local_txn { &local_txn[0] } else { &remote_txn[0] };
3282+
3283+
// Connect a commitment transaction, but only to the ChainMonitor/ChannelMonitor. The
3284+
// channel is now closed, but the ChannelManager doesn't know that yet.
3285+
let new_header = BlockHeader {
3286+
version: 2, time: 0, bits: 0, nonce: 0,
3287+
prev_blockhash: nodes[0].best_block_info().0,
3288+
merkle_root: Default::default() };
3289+
let conf_height = nodes[0].best_block_info().1 + 1;
3290+
nodes[1].chain_monitor.chain_monitor.transactions_confirmed(&new_header,
3291+
&[(0, broadcast_tx)], conf_height);
3292+
3293+
let (_, pre_update_monitor) = <(BlockHash, ChannelMonitor<InMemorySigner>)>::read(
3294+
&mut io::Cursor::new(&get_monitor!(nodes[1], channel.2).encode()),
3295+
&nodes[1].keys_manager.backing).unwrap();
3296+
3297+
// If the ChannelManager tries to update the channel, however, the ChainMonitor will pass
3298+
// the update through to the ChannelMonitor which will refuse it (as the channel is closed).
3299+
let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 100_000);
3300+
unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)),
3301+
true, APIError::ChannelUnavailable { ref err },
3302+
assert!(err.contains("ChannelMonitor storage failure")));
3303+
check_added_monitors!(nodes[1], 2); // After the failure we generate a close-channel monitor update
3304+
check_closed_broadcast!(nodes[1], true);
3305+
check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: "ChannelMonitor storage failure".to_string() });
3306+
3307+
let monitor_updates = nodes[1].chain_monitor.monitor_updates.lock().unwrap();
3308+
let mut replay_update = monitor_updates.get(&channel.2).unwrap().iter().rev().skip(1).next().unwrap().clone();
3309+
assert_eq!(replay_update.updates.len(), 1);
3310+
if let ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } = replay_update.updates[0] {
3311+
} else { panic!(); }
3312+
replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: payment_preimage_1 });
3313+
replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: payment_preimage_2 });
3314+
3315+
let broadcaster = TestBroadcaster::new(Arc::clone(&nodes[1].blocks));
3316+
assert!(
3317+
pre_update_monitor.update_monitor(&replay_update, &&broadcaster, &&chanmon_cfgs[1].fee_estimator, &nodes[1].logger)
3318+
.is_err());
3319+
// Even though we error'd on the first update, we should still have generated an HTLC claim
3320+
// transaction
3321+
let txn_broadcasted = broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
3322+
assert!(txn_broadcasted.len() >= 2);
3323+
let htlc_txn = txn_broadcasted.iter().filter(|tx| {
3324+
assert_eq!(tx.input.len(), 1);
3325+
tx.input[0].previous_output.txid == broadcast_tx.txid()
3326+
}).collect::<Vec<_>>();
3327+
assert_eq!(htlc_txn.len(), 2);
3328+
check_spends!(htlc_txn[0], broadcast_tx);
3329+
check_spends!(htlc_txn[1], broadcast_tx);
3330+
}
3331+
#[test]
3332+
fn test_funding_spend_refuses_updates() {
3333+
do_test_funding_spend_refuses_updates(true);
3334+
do_test_funding_spend_refuses_updates(false);
3335+
}
3336+
32193337
#[test]
32203338
fn test_prune_preimages() {
32213339
let secp_ctx = Secp256k1::new();

lightning/src/util/test_utils.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
8989

9090
pub struct TestChainMonitor<'a> {
9191
pub added_monitors: Mutex<Vec<(OutPoint, channelmonitor::ChannelMonitor<EnforcingSigner>)>>,
92+
pub monitor_updates: Mutex<HashMap<[u8; 32], Vec<channelmonitor::ChannelMonitorUpdate>>>,
9293
pub latest_monitor_update_id: Mutex<HashMap<[u8; 32], (OutPoint, u64, MonitorUpdateId)>>,
9394
pub chain_monitor: chainmonitor::ChainMonitor<EnforcingSigner, &'a TestChainSource, &'a chaininterface::BroadcasterInterface, &'a TestFeeEstimator, &'a TestLogger, &'a chainmonitor::Persist<EnforcingSigner>>,
9495
pub keys_manager: &'a TestKeysInterface,
@@ -101,6 +102,7 @@ impl<'a> TestChainMonitor<'a> {
101102
pub fn new(chain_source: Option<&'a TestChainSource>, broadcaster: &'a chaininterface::BroadcasterInterface, logger: &'a TestLogger, fee_estimator: &'a TestFeeEstimator, persister: &'a chainmonitor::Persist<EnforcingSigner>, keys_manager: &'a TestKeysInterface) -> Self {
102103
Self {
103104
added_monitors: Mutex::new(Vec::new()),
105+
monitor_updates: Mutex::new(HashMap::new()),
104106
latest_monitor_update_id: Mutex::new(HashMap::new()),
105107
chain_monitor: chainmonitor::ChainMonitor::new(chain_source, broadcaster, logger, fee_estimator, persister),
106108
keys_manager,
@@ -130,6 +132,8 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
130132
assert!(channelmonitor::ChannelMonitorUpdate::read(
131133
&mut io::Cursor::new(&w.0)).unwrap() == update);
132134

135+
self.monitor_updates.lock().unwrap().entry(funding_txo.to_channel_id()).or_insert(Vec::new()).push(update.clone());
136+
133137
if let Some(exp) = self.expect_channel_force_closed.lock().unwrap().take() {
134138
assert_eq!(funding_txo.to_channel_id(), exp.0);
135139
assert_eq!(update.updates.len(), 1);
@@ -209,6 +213,13 @@ pub struct TestBroadcaster {
209213
pub txn_broadcasted: Mutex<Vec<Transaction>>,
210214
pub blocks: Arc<Mutex<Vec<(BlockHeader, u32)>>>,
211215
}
216+
217+
impl TestBroadcaster {
218+
pub fn new(blocks: Arc<Mutex<Vec<(BlockHeader, u32)>>>) -> TestBroadcaster {
219+
TestBroadcaster { txn_broadcasted: Mutex::new(Vec::new()), blocks }
220+
}
221+
}
222+
212223
impl chaininterface::BroadcasterInterface for TestBroadcaster {
213224
fn broadcast_transaction(&self, tx: &Transaction) {
214225
assert!(tx.lock_time < 1_500_000_000);

0 commit comments

Comments
 (0)