Skip to content

Commit 2b4ca9e

Browse files
authored
Merge pull request #1083 from TheBlueMatt/2021-09-funding-timeout
Automatically close channels that go unfunded for 2016 blocks
2 parents 77948db + 3582921 commit 2b4ca9e

File tree

7 files changed

+147
-53
lines changed

7 files changed

+147
-53
lines changed

lightning/src/ln/channel.rs

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use chain::chaininterface::{FeeEstimator,ConfirmationTarget};
3535
use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateStep, LATENCY_GRACE_PERIOD_BLOCKS};
3636
use chain::transaction::{OutPoint, TransactionData};
3737
use chain::keysinterface::{Sign, KeysInterface};
38+
use util::events::ClosureReason;
3839
use util::ser::{Readable, ReadableArgs, Writeable, Writer, VecWriter};
3940
use util::logger::Logger;
4041
use util::errors::APIError;
@@ -378,6 +379,11 @@ pub const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2;
378379
#[cfg(not(fuzzing))]
379380
const FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE: u64 = 2;
380381

382+
/// If we fail to see a funding transaction confirmed on-chain within this many blocks after the
383+
/// channel creation on an inbound channel, we simply force-close and move on.
384+
/// This constant is the one suggested in BOLT 2.
385+
pub(crate) const FUNDING_CONF_DEADLINE_BLOCKS: u32 = 2016;
386+
381387
// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
382388
// has been completed, and then turn into a Channel to get compiler-time enforcement of things like
383389
// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
@@ -475,6 +481,10 @@ pub(super) struct Channel<Signer: Sign> {
475481
funding_tx_confirmed_in: Option<BlockHash>,
476482
funding_tx_confirmation_height: u32,
477483
short_channel_id: Option<u64>,
484+
/// Either the height at which this channel was created or the height at which it was last
485+
/// serialized if it was serialized by versions prior to 0.0.103.
486+
/// We use this to close if funding is never broadcasted.
487+
channel_creation_height: u32,
478488

479489
counterparty_dust_limit_satoshis: u64,
480490
#[cfg(test)]
@@ -646,7 +656,10 @@ impl<Signer: Sign> Channel<Signer> {
646656
}
647657

648658
// Constructors:
649-
pub fn new_outbound<K: Deref, F: Deref>(fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures, channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig) -> Result<Channel<Signer>, APIError>
659+
pub fn new_outbound<K: Deref, F: Deref>(
660+
fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
661+
channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig, current_chain_height: u32
662+
) -> Result<Channel<Signer>, APIError>
650663
where K::Target: KeysInterface<Signer = Signer>,
651664
F::Target: FeeEstimator,
652665
{
@@ -734,6 +747,7 @@ impl<Signer: Sign> Channel<Signer> {
734747
funding_tx_confirmed_in: None,
735748
funding_tx_confirmation_height: 0,
736749
short_channel_id: None,
750+
channel_creation_height: current_chain_height,
737751

738752
feerate_per_kw: feerate,
739753
counterparty_dust_limit_satoshis: 0,
@@ -807,7 +821,10 @@ impl<Signer: Sign> Channel<Signer> {
807821

808822
/// Creates a new channel from a remote sides' request for one.
809823
/// Assumes chain_hash has already been checked and corresponds with what we expect!
810-
pub fn new_from_req<K: Deref, F: Deref>(fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures, msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig) -> Result<Channel<Signer>, ChannelError>
824+
pub fn new_from_req<K: Deref, F: Deref>(
825+
fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
826+
msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig, current_chain_height: u32
827+
) -> Result<Channel<Signer>, ChannelError>
811828
where K::Target: KeysInterface<Signer = Signer>,
812829
F::Target: FeeEstimator
813830
{
@@ -1020,6 +1037,7 @@ impl<Signer: Sign> Channel<Signer> {
10201037
funding_tx_confirmed_in: None,
10211038
funding_tx_confirmation_height: 0,
10221039
short_channel_id: None,
1040+
channel_creation_height: current_chain_height,
10231041

10241042
feerate_per_kw: msg.feerate_per_kw,
10251043
channel_value_satoshis: msg.funding_satoshis,
@@ -4117,7 +4135,7 @@ impl<Signer: Sign> Channel<Signer> {
41174135
/// In the first case, we store the confirmation height and calculating the short channel id.
41184136
/// In the second, we simply return an Err indicating we need to be force-closed now.
41194137
pub fn transactions_confirmed<L: Deref>(&mut self, block_hash: &BlockHash, height: u32, txdata: &TransactionData, logger: &L)
4120-
-> Result<Option<msgs::FundingLocked>, msgs::ErrorMessage> where L::Target: Logger {
4138+
-> Result<Option<msgs::FundingLocked>, ClosureReason> where L::Target: Logger {
41214139
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
41224140
for &(index_in_block, tx) in txdata.iter() {
41234141
if let Some(funding_txo) = self.get_funding_txo() {
@@ -4138,10 +4156,8 @@ impl<Signer: Sign> Channel<Signer> {
41384156
panic!("Client called ChannelManager::funding_transaction_generated with bogus transaction!");
41394157
}
41404158
self.update_time_counter += 1;
4141-
return Err(msgs::ErrorMessage {
4142-
channel_id: self.channel_id(),
4143-
data: "funding tx had wrong script/value or output index".to_owned()
4144-
});
4159+
let err_reason = "funding tx had wrong script/value or output index";
4160+
return Err(ClosureReason::ProcessingError { err: err_reason.to_owned() });
41454161
} else {
41464162
if self.is_outbound() {
41474163
for input in tx.input.iter() {
@@ -4172,10 +4188,7 @@ impl<Signer: Sign> Channel<Signer> {
41724188
for inp in tx.input.iter() {
41734189
if inp.previous_output == funding_txo.into_bitcoin_outpoint() {
41744190
log_info!(logger, "Detected channel-closing tx {} spending {}:{}, closing channel {}", tx.txid(), inp.previous_output.txid, inp.previous_output.vout, log_bytes!(self.channel_id()));
4175-
return Err(msgs::ErrorMessage {
4176-
channel_id: self.channel_id(),
4177-
data: "Commitment or closing transaction was confirmed on chain.".to_owned()
4178-
});
4191+
return Err(ClosureReason::CommitmentTxConfirmed);
41794192
}
41804193
}
41814194
}
@@ -4195,7 +4208,7 @@ impl<Signer: Sign> Channel<Signer> {
41954208
/// May return some HTLCs (and their payment_hash) which have timed out and should be failed
41964209
/// back.
41974210
pub fn best_block_updated<L: Deref>(&mut self, height: u32, highest_header_time: u32, logger: &L)
4198-
-> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>), msgs::ErrorMessage> where L::Target: Logger {
4211+
-> Result<(Option<msgs::FundingLocked>, Vec<(HTLCSource, PaymentHash)>), ClosureReason> where L::Target: Logger {
41994212
let mut timed_out_htlcs = Vec::new();
42004213
// This mirrors the check in ChannelManager::decode_update_add_htlc_onion, refusing to
42014214
// forward an HTLC when our counterparty should almost certainly just fail it for expiring
@@ -4236,11 +4249,17 @@ impl<Signer: Sign> Channel<Signer> {
42364249
// close the channel and hope we can get the latest state on chain (because presumably
42374250
// the funding transaction is at least still in the mempool of most nodes).
42384251
if funding_tx_confirmations < self.minimum_depth.unwrap() as i64 / 2 {
4239-
return Err(msgs::ErrorMessage {
4240-
channel_id: self.channel_id(),
4241-
data: format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.", self.minimum_depth.unwrap(), funding_tx_confirmations),
4242-
});
4252+
let err_reason = format!("Funding transaction was un-confirmed. Locked at {} confs, now have {} confs.",
4253+
self.minimum_depth.unwrap(), funding_tx_confirmations);
4254+
return Err(ClosureReason::ProcessingError { err: err_reason });
42434255
}
4256+
} else if !self.is_outbound() && self.funding_tx_confirmed_in.is_none() &&
4257+
height >= self.channel_creation_height + FUNDING_CONF_DEADLINE_BLOCKS {
4258+
log_info!(logger, "Closing channel {} due to funding timeout", log_bytes!(self.channel_id));
4259+
// If funding_tx_confirmed_in is unset, the channel must not be active
4260+
assert!(non_shutdown_state <= ChannelState::ChannelFunded as u32);
4261+
assert_eq!(non_shutdown_state & ChannelState::OurFundingLocked as u32, 0);
4262+
return Err(ClosureReason::FundingTimedOut);
42444263
}
42454264

42464265
Ok((None, timed_out_htlcs))
@@ -4249,7 +4268,7 @@ impl<Signer: Sign> Channel<Signer> {
42494268
/// Indicates the funding transaction is no longer confirmed in the main chain. This may
42504269
/// force-close the channel, but may also indicate a harmless reorganization of a block or two
42514270
/// before the channel has reached funding_locked and we can just wait for more blocks.
4252-
pub fn funding_transaction_unconfirmed<L: Deref>(&mut self, logger: &L) -> Result<(), msgs::ErrorMessage> where L::Target: Logger {
4271+
pub fn funding_transaction_unconfirmed<L: Deref>(&mut self, logger: &L) -> Result<(), ClosureReason> where L::Target: Logger {
42534272
if self.funding_tx_confirmation_height != 0 {
42544273
// We handle the funding disconnection by calling best_block_updated with a height one
42554274
// below where our funding was connected, implying a reorg back to conf_height - 1.
@@ -5279,16 +5298,18 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
52795298
(7, self.shutdown_scriptpubkey, option),
52805299
(9, self.target_closing_feerate_sats_per_kw, option),
52815300
(11, self.monitor_pending_finalized_fulfills, vec_type),
5301+
(13, self.channel_creation_height, required),
52825302
});
52835303

52845304
Ok(())
52855305
}
52865306
}
52875307

52885308
const MAX_ALLOC_SIZE: usize = 64*1024;
5289-
impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
5309+
impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
52905310
where K::Target: KeysInterface<Signer = Signer> {
5291-
fn read<R : io::Read>(reader: &mut R, keys_source: &'a K) -> Result<Self, DecodeError> {
5311+
fn read<R : io::Read>(reader: &mut R, args: (&'a K, u32)) -> Result<Self, DecodeError> {
5312+
let (keys_source, serialized_height) = args;
52925313
let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
52935314

52945315
let user_id = Readable::read(reader)?;
@@ -5516,6 +5537,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
55165537
// Prior to supporting channel type negotiation, all of our channels were static_remotekey
55175538
// only, so we default to that if none was written.
55185539
let mut channel_type = Some(ChannelTypeFeatures::only_static_remote_key());
5540+
let mut channel_creation_height = Some(serialized_height);
55195541
read_tlv_fields!(reader, {
55205542
(0, announcement_sigs, option),
55215543
(1, minimum_depth, option),
@@ -5525,6 +5547,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
55255547
(7, shutdown_scriptpubkey, option),
55265548
(9, target_closing_feerate_sats_per_kw, option),
55275549
(11, monitor_pending_finalized_fulfills, vec_type),
5550+
(13, channel_creation_height, option),
55285551
});
55295552

55305553
let chan_features = channel_type.as_ref().unwrap();
@@ -5589,6 +5612,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
55895612
funding_tx_confirmed_in,
55905613
funding_tx_confirmation_height,
55915614
short_channel_id,
5615+
channel_creation_height: channel_creation_height.unwrap(),
55925616

55935617
counterparty_dust_limit_satoshis,
55945618
holder_dust_limit_satoshis,
@@ -5737,7 +5761,7 @@ mod tests {
57375761
let secp_ctx = Secp256k1::new();
57385762
let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
57395763
let config = UserConfig::default();
5740-
match Channel::<EnforcingSigner>::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config) {
5764+
match Channel::<EnforcingSigner>::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0) {
57415765
Err(APIError::IncompatibleShutdownScript { script }) => {
57425766
assert_eq!(script.into_inner(), non_v0_segwit_shutdown_script.into_inner());
57435767
},
@@ -5759,7 +5783,7 @@ mod tests {
57595783

57605784
let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
57615785
let config = UserConfig::default();
5762-
let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap();
5786+
let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
57635787

57645788
// Now change the fee so we can check that the fee in the open_channel message is the
57655789
// same as the old fee.
@@ -5784,13 +5808,13 @@ mod tests {
57845808
// Create Node A's channel pointing to Node B's pubkey
57855809
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
57865810
let config = UserConfig::default();
5787-
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap();
5811+
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
57885812

57895813
// Create Node B's channel by receiving Node A's open_channel message
57905814
// Make sure A's dust limit is as we expect.
57915815
let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
57925816
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
5793-
let node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config).unwrap();
5817+
let node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0).unwrap();
57945818

57955819
// Node B --> Node A: accept channel, explicitly setting B's dust limit.
57965820
let mut accept_channel_msg = node_b_chan.get_accept_channel();
@@ -5854,7 +5878,7 @@ mod tests {
58545878

58555879
let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
58565880
let config = UserConfig::default();
5857-
let mut chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap();
5881+
let mut chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
58585882

58595883
let commitment_tx_fee_0_htlcs = chan.commit_tx_fee_msat(0);
58605884
let commitment_tx_fee_1_htlc = chan.commit_tx_fee_msat(1);
@@ -5903,12 +5927,12 @@ mod tests {
59035927
// Create Node A's channel pointing to Node B's pubkey
59045928
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
59055929
let config = UserConfig::default();
5906-
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap();
5930+
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
59075931

59085932
// Create Node B's channel by receiving Node A's open_channel message
59095933
let open_channel_msg = node_a_chan.get_open_channel(chain_hash);
59105934
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
5911-
let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config).unwrap();
5935+
let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0).unwrap();
59125936

59135937
// Node B --> Node A: accept channel
59145938
let accept_channel_msg = node_b_chan.get_accept_channel();
@@ -5965,7 +5989,7 @@ mod tests {
59655989
// Create a channel.
59665990
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
59675991
let config = UserConfig::default();
5968-
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config).unwrap();
5992+
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
59695993
assert!(node_a_chan.counterparty_forwarding_info.is_none());
59705994
assert_eq!(node_a_chan.holder_htlc_minimum_msat, 1); // the default
59715995
assert!(node_a_chan.counterparty_forwarding_info().is_none());
@@ -6029,7 +6053,7 @@ mod tests {
60296053
let counterparty_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
60306054
let mut config = UserConfig::default();
60316055
config.channel_options.announced_channel = false;
6032-
let mut chan = Channel::<InMemorySigner>::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, &InitFeatures::known(), 10_000_000, 100000, 42, &config).unwrap(); // Nothing uses their network key in this test
6056+
let mut chan = Channel::<InMemorySigner>::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, &InitFeatures::known(), 10_000_000, 100000, 42, &config, 0).unwrap(); // Nothing uses their network key in this test
60336057
chan.holder_dust_limit_satoshis = 546;
60346058
chan.counterparty_selected_channel_reserve_satoshis = Some(0); // Filled in in accept_channel
60356059

0 commit comments

Comments
 (0)