Skip to content

Commit 4ab80dd

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 62c1bd5 commit 4ab80dd

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
@@ -695,6 +695,11 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
695695
// remote monitor out-of-order with regards to the block view.
696696
holder_tx_signed: bool,
697697

698+
// If a spend of the funding output is seen, we set this to true and reject any further
699+
// updates. This prevents any further changes in the offchain state no matter the order
700+
// of block connection between ChannelMonitors and the ChannelManager.
701+
funding_spend_seen: bool,
702+
698703
funding_spend_confirmed: Option<Txid>,
699704
/// The set of HTLCs which have been either claimed or failed on chain and have reached
700705
/// the requisite confirmations on the claim/fail transaction (either ANTI_REORG_DELAY or the
@@ -760,6 +765,7 @@ impl<Signer: Sign> PartialEq for ChannelMonitorImpl<Signer> {
760765
self.outputs_to_watch != other.outputs_to_watch ||
761766
self.lockdown_from_offchain != other.lockdown_from_offchain ||
762767
self.holder_tx_signed != other.holder_tx_signed ||
768+
self.funding_spend_seen != other.funding_spend_seen ||
763769
self.funding_spend_confirmed != other.funding_spend_confirmed ||
764770
self.htlcs_resolved_on_chain != other.htlcs_resolved_on_chain
765771
{
@@ -935,6 +941,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
935941
(1, self.funding_spend_confirmed, option),
936942
(3, self.htlcs_resolved_on_chain, vec_type),
937943
(5, self.pending_monitor_events, vec_type),
944+
(7, self.funding_spend_seen, required),
938945
});
939946

940947
Ok(())
@@ -1033,6 +1040,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
10331040

10341041
lockdown_from_offchain: false,
10351042
holder_tx_signed: false,
1043+
funding_spend_seen: false,
10361044
funding_spend_confirmed: None,
10371045
htlcs_resolved_on_chain: Vec::new(),
10381046

@@ -1937,6 +1945,10 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
19371945
}
19381946
}
19391947
self.latest_update_id = updates.update_id;
1948+
1949+
if ret.is_ok() && self.funding_spend_seen {
1950+
ret = Err(MonitorUpdateError("Counterparty attempted to update commitment after funding was spent"));
1951+
}
19401952
ret
19411953
}
19421954

@@ -2366,6 +2378,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23662378
let mut balance_spendable_csv = None;
23672379
log_info!(logger, "Channel {} closed by funding output spend in txid {}.",
23682380
log_bytes!(self.funding_info.0.to_channel_id()), tx.txid());
2381+
self.funding_spend_seen = true;
23692382
if (tx.input[0].sequence >> 8*3) as u8 == 0x80 && (tx.lock_time >> 8*3) as u8 == 0x20 {
23702383
let (mut new_outpoints, new_outputs) = self.check_spend_counterparty_transaction(&tx, height, &logger);
23712384
if !new_outputs.1.is_empty() {
@@ -3215,10 +3228,12 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
32153228

32163229
let mut funding_spend_confirmed = None;
32173230
let mut htlcs_resolved_on_chain = Some(Vec::new());
3231+
let mut funding_spend_seen = Some(false);
32183232
read_tlv_fields!(reader, {
32193233
(1, funding_spend_confirmed, option),
32203234
(3, htlcs_resolved_on_chain, vec_type),
32213235
(5, pending_monitor_events, vec_type),
3236+
(7, funding_spend_seen, option),
32223237
});
32233238

32243239
let mut secp_ctx = Secp256k1::new();
@@ -3268,6 +3283,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
32683283

32693284
lockdown_from_offchain,
32703285
holder_tx_signed,
3286+
funding_spend_seen: funding_spend_seen.unwrap(),
32713287
funding_spend_confirmed,
32723288
htlcs_resolved_on_chain: htlcs_resolved_on_chain.unwrap(),
32733289

@@ -3281,6 +3297,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
32813297

32823298
#[cfg(test)]
32833299
mod tests {
3300+
use bitcoin::blockdata::block::BlockHeader;
32843301
use bitcoin::blockdata::script::{Script, Builder};
32853302
use bitcoin::blockdata::opcodes;
32863303
use bitcoin::blockdata::transaction::{Transaction, TxIn, TxOut, SigHashType};
@@ -3289,24 +3306,125 @@ mod tests {
32893306
use bitcoin::hashes::Hash;
32903307
use bitcoin::hashes::sha256::Hash as Sha256;
32913308
use bitcoin::hashes::hex::FromHex;
3292-
use bitcoin::hash_types::Txid;
3309+
use bitcoin::hash_types::{BlockHash, Txid};
32933310
use bitcoin::network::constants::Network;
3311+
use bitcoin::secp256k1::key::{SecretKey,PublicKey};
3312+
use bitcoin::secp256k1::Secp256k1;
3313+
32943314
use hex;
3295-
use chain::BestBlock;
3315+
3316+
use super::ChannelMonitorUpdateStep;
3317+
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};
3318+
use chain::{BestBlock, Confirm};
32963319
use chain::channelmonitor::ChannelMonitor;
32973320
use chain::package::{WEIGHT_OFFERED_HTLC, WEIGHT_RECEIVED_HTLC, WEIGHT_REVOKED_OFFERED_HTLC, WEIGHT_REVOKED_RECEIVED_HTLC, WEIGHT_REVOKED_OUTPUT};
32983321
use chain::transaction::OutPoint;
3322+
use chain::keysinterface::InMemorySigner;
32993323
use ln::{PaymentPreimage, PaymentHash};
33003324
use ln::chan_utils;
33013325
use ln::chan_utils::{HTLCOutputInCommitment, ChannelPublicKeys, ChannelTransactionParameters, HolderCommitmentTransaction, CounterpartyChannelTransactionParameters};
3326+
use ln::channelmanager::PaymentSendFailure;
3327+
use ln::features::InitFeatures;
3328+
use ln::functional_test_utils::*;
33023329
use ln::script::ShutdownScript;
3330+
use util::errors::APIError;
3331+
use util::events::{ClosureReason, MessageSendEventsProvider};
33033332
use util::test_utils::{TestLogger, TestBroadcaster, TestFeeEstimator};
3304-
use bitcoin::secp256k1::key::{SecretKey,PublicKey};
3305-
use bitcoin::secp256k1::Secp256k1;
3333+
use util::ser::{ReadableArgs, Writeable};
33063334
use sync::{Arc, Mutex};
3307-
use chain::keysinterface::InMemorySigner;
3335+
use io;
33083336
use prelude::*;
33093337

3338+
fn do_test_funding_spend_refuses_updates(use_local_txn: bool) {
3339+
// Previously, monitor updates were allowed freely even after a funding-spend transaction
3340+
// confirmed. This would allow a race condition where we could receive a payment (including
3341+
// the counterparty revoking their broadcasted state!) and accept it without recourse as
3342+
// long as the ChannelMonitor receives the block first, the full commitment update dance
3343+
// occurs after the block is connected, and before the ChannelManager receives the block.
3344+
// Obviously this is an incredibly contrived race given the counterparty would be risking
3345+
// their full channel balance for it, but its worth fixing nonetheless as it makes the
3346+
// potential ChannelMonitor states simpler to reason about.
3347+
//
3348+
// This test checks said behavior, as well as ensuring a ChannelMonitorUpdate with multiple
3349+
// updates is handled correctly in such conditions.
3350+
let chanmon_cfgs = create_chanmon_cfgs(3);
3351+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
3352+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
3353+
let nodes = create_network(3, &node_cfgs, &node_chanmgrs);
3354+
let channel = create_announced_chan_between_nodes(
3355+
&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
3356+
create_announced_chan_between_nodes(
3357+
&nodes, 1, 2, InitFeatures::known(), InitFeatures::known());
3358+
3359+
// Rebalance somewhat
3360+
send_payment(&nodes[0], &[&nodes[1]], 10_000_000);
3361+
3362+
// First route two payments for testing at the end
3363+
let payment_preimage_1 = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000).0;
3364+
let payment_preimage_2 = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000).0;
3365+
3366+
let local_txn = get_local_commitment_txn!(nodes[1], channel.2);
3367+
assert_eq!(local_txn.len(), 1);
3368+
let remote_txn = get_local_commitment_txn!(nodes[0], channel.2);
3369+
assert_eq!(remote_txn.len(), 3); // Commitment and two HTLC-Timeouts
3370+
check_spends!(remote_txn[1], remote_txn[0]);
3371+
check_spends!(remote_txn[2], remote_txn[0]);
3372+
let broadcast_tx = if use_local_txn { &local_txn[0] } else { &remote_txn[0] };
3373+
3374+
// Connect a commitment transaction, but only to the ChainMonitor/ChannelMonitor. The
3375+
// channel is now closed, but the ChannelManager doesn't know that yet.
3376+
let new_header = BlockHeader {
3377+
version: 2, time: 0, bits: 0, nonce: 0,
3378+
prev_blockhash: nodes[0].best_block_info().0,
3379+
merkle_root: Default::default() };
3380+
let conf_height = nodes[0].best_block_info().1 + 1;
3381+
nodes[1].chain_monitor.chain_monitor.transactions_confirmed(&new_header,
3382+
&[(0, broadcast_tx)], conf_height);
3383+
3384+
let (_, pre_update_monitor) = <(BlockHash, ChannelMonitor<InMemorySigner>)>::read(
3385+
&mut io::Cursor::new(&get_monitor!(nodes[1], channel.2).encode()),
3386+
&nodes[1].keys_manager.backing).unwrap();
3387+
3388+
// If the ChannelManager tries to update the channel, however, the ChainMonitor will pass
3389+
// the update through to the ChannelMonitor which will refuse it (as the channel is closed).
3390+
let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 100_000);
3391+
unwrap_send_err!(nodes[1].node.send_payment(&route, payment_hash, &Some(payment_secret)),
3392+
true, APIError::ChannelUnavailable { ref err },
3393+
assert!(err.contains("ChannelMonitor storage failure")));
3394+
check_added_monitors!(nodes[1], 2); // After the failure we generate a close-channel monitor update
3395+
check_closed_broadcast!(nodes[1], true);
3396+
check_closed_event!(nodes[1], 1, ClosureReason::ProcessingError { err: "ChannelMonitor storage failure".to_string() });
3397+
3398+
let monitor_updates = nodes[1].chain_monitor.monitor_updates.lock().unwrap();
3399+
let mut replay_update = monitor_updates.get(&channel.2).unwrap().iter().rev().skip(1).next().unwrap().clone();
3400+
assert_eq!(replay_update.updates.len(), 1);
3401+
if let ChannelMonitorUpdateStep::LatestCounterpartyCommitmentTXInfo { .. } = replay_update.updates[0] {
3402+
} else { panic!(); }
3403+
replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: payment_preimage_1 });
3404+
replay_update.updates.push(ChannelMonitorUpdateStep::PaymentPreimage { payment_preimage: payment_preimage_2 });
3405+
3406+
let broadcaster = TestBroadcaster::new(Arc::clone(&nodes[1].blocks));
3407+
assert!(
3408+
pre_update_monitor.update_monitor(&replay_update, &&broadcaster, &&chanmon_cfgs[1].fee_estimator, &nodes[1].logger)
3409+
.is_err());
3410+
// Even though we error'd on the first update, we should still have generated an HTLC claim
3411+
// transaction
3412+
let txn_broadcasted = broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
3413+
assert!(txn_broadcasted.len() >= 2);
3414+
let htlc_txn = txn_broadcasted.iter().filter(|tx| {
3415+
assert_eq!(tx.input.len(), 1);
3416+
tx.input[0].previous_output.txid == broadcast_tx.txid()
3417+
}).collect::<Vec<_>>();
3418+
assert_eq!(htlc_txn.len(), 2);
3419+
check_spends!(htlc_txn[0], broadcast_tx);
3420+
check_spends!(htlc_txn[1], broadcast_tx);
3421+
}
3422+
#[test]
3423+
fn test_funding_spend_refuses_updates() {
3424+
do_test_funding_spend_refuses_updates(true);
3425+
do_test_funding_spend_refuses_updates(false);
3426+
}
3427+
33103428
#[test]
33113429
fn test_prune_preimages() {
33123430
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
@@ -91,6 +91,7 @@ impl keysinterface::KeysInterface for OnlyReadsKeysInterface {
9191

9292
pub struct TestChainMonitor<'a> {
9393
pub added_monitors: Mutex<Vec<(OutPoint, channelmonitor::ChannelMonitor<EnforcingSigner>)>>,
94+
pub monitor_updates: Mutex<HashMap<[u8; 32], Vec<channelmonitor::ChannelMonitorUpdate>>>,
9495
pub latest_monitor_update_id: Mutex<HashMap<[u8; 32], (OutPoint, u64, MonitorUpdateId)>>,
9596
pub chain_monitor: chainmonitor::ChainMonitor<EnforcingSigner, &'a TestChainSource, &'a chaininterface::BroadcasterInterface, &'a TestFeeEstimator, &'a TestLogger, &'a chainmonitor::Persist<EnforcingSigner>>,
9697
pub keys_manager: &'a TestKeysInterface,
@@ -103,6 +104,7 @@ impl<'a> TestChainMonitor<'a> {
103104
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 {
104105
Self {
105106
added_monitors: Mutex::new(Vec::new()),
107+
monitor_updates: Mutex::new(HashMap::new()),
106108
latest_monitor_update_id: Mutex::new(HashMap::new()),
107109
chain_monitor: chainmonitor::ChainMonitor::new(chain_source, broadcaster, logger, fee_estimator, persister),
108110
keys_manager,
@@ -132,6 +134,8 @@ impl<'a> chain::Watch<EnforcingSigner> for TestChainMonitor<'a> {
132134
assert!(channelmonitor::ChannelMonitorUpdate::read(
133135
&mut io::Cursor::new(&w.0)).unwrap() == update);
134136

137+
self.monitor_updates.lock().unwrap().entry(funding_txo.to_channel_id()).or_insert(Vec::new()).push(update.clone());
138+
135139
if let Some(exp) = self.expect_channel_force_closed.lock().unwrap().take() {
136140
assert_eq!(funding_txo.to_channel_id(), exp.0);
137141
assert_eq!(update.updates.len(), 1);
@@ -211,6 +215,13 @@ pub struct TestBroadcaster {
211215
pub txn_broadcasted: Mutex<Vec<Transaction>>,
212216
pub blocks: Arc<Mutex<Vec<(BlockHeader, u32)>>>,
213217
}
218+
219+
impl TestBroadcaster {
220+
pub fn new(blocks: Arc<Mutex<Vec<(BlockHeader, u32)>>>) -> TestBroadcaster {
221+
TestBroadcaster { txn_broadcasted: Mutex::new(Vec::new()), blocks }
222+
}
223+
}
224+
214225
impl chaininterface::BroadcasterInterface for TestBroadcaster {
215226
fn broadcast_transaction(&self, tx: &Transaction) {
216227
assert!(tx.lock_time < 1_500_000_000);

0 commit comments

Comments
 (0)