Skip to content

Commit 6919cd3

Browse files
authored
Merge pull request #98 from TheBlueMatt/2018-07-invalid-funding
Handle invalid funding tx in channelmanager
2 parents cf6532e + 7e255b5 commit 6919cd3

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

src/ln/channel.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crypto::digest::Digest;
1414
use crypto::hkdf::{hkdf_extract,hkdf_expand};
1515

1616
use ln::msgs;
17-
use ln::msgs::{HandleError, MsgEncodable};
17+
use ln::msgs::{ErrorAction, HandleError, MsgEncodable};
1818
use ln::channelmonitor::ChannelMonitor;
1919
use ln::channelmanager::{PendingForwardHTLCInfo, HTLCFailReason};
2020
use ln::chan_utils::{TxCreationKeys,HTLCOutputInCommitment,HTLC_SUCCESS_TX_WEIGHT,HTLC_TIMEOUT_TX_WEIGHT};
@@ -1916,7 +1916,10 @@ impl Channel {
19161916
/// Called by channelmanager based on chain blocks being connected.
19171917
/// Note that we only need to use this to detect funding_signed, anything else is handled by
19181918
/// the channel_monitor.
1919-
pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Option<msgs::FundingLocked> {
1919+
/// In case of Err, the channel may have been closed, at which point the standard requirements
1920+
/// apply - no calls may be made except those explicitly stated to be allowed post-shutdown.
1921+
/// Only returns an ErrorAction of DisconnectPeer, if Err.
1922+
pub fn block_connected(&mut self, header: &BlockHeader, height: u32, txn_matched: &[&Transaction], indexes_of_txn_matched: &[u32]) -> Result<Option<msgs::FundingLocked>, HandleError> {
19201923
let non_shutdown_state = self.channel_state & (!BOTH_SIDES_SHUTDOWN_MASK);
19211924
if self.funding_tx_confirmations > 0 {
19221925
if header.bitcoin_hash() != self.last_block_connected {
@@ -1940,10 +1943,10 @@ impl Channel {
19401943
//a protocol oversight, but I assume I'm just missing something.
19411944
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
19421945
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret).unwrap();
1943-
return Some(msgs::FundingLocked {
1946+
return Ok(Some(msgs::FundingLocked {
19441947
channel_id: self.channel_id,
19451948
next_per_commitment_point: next_per_commitment_point,
1946-
});
1949+
}));
19471950
}
19481951
}
19491952
}
@@ -1955,6 +1958,7 @@ impl Channel {
19551958
tx.output[txo_idx].value != self.channel_value_satoshis {
19561959
self.channel_state = ChannelState::ShutdownComplete as u32;
19571960
self.channel_update_count += 1;
1961+
return Err(HandleError{err: "funding tx had wrong script/value", action: Some(ErrorAction::DisconnectPeer{msg: None})});
19581962
} else {
19591963
self.funding_tx_confirmations = 1;
19601964
self.short_channel_id = Some(((height as u64) << (5*8)) |
@@ -1964,7 +1968,7 @@ impl Channel {
19641968
}
19651969
}
19661970
}
1967-
None
1971+
Ok(None)
19681972
}
19691973

19701974
/// Called by channelmanager based on chain blocks being disconnected.

src/ln/channelmanager.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,8 @@ impl ChainListener for ChannelManager {
11411141
let channel_state = channel_lock.borrow_parts();
11421142
let short_to_id = channel_state.short_to_id;
11431143
channel_state.by_id.retain(|_, channel| {
1144-
if let Some(funding_locked) = channel.block_connected(header, height, txn_matched, indexes_of_txn_matched) {
1144+
let chan_res = channel.block_connected(header, height, txn_matched, indexes_of_txn_matched);
1145+
if let Ok(Some(funding_locked)) = chan_res {
11451146
let announcement_sigs = match self.get_announcement_sigs(channel) {
11461147
Ok(res) => res,
11471148
Err(_e) => {
@@ -1155,6 +1156,16 @@ impl ChainListener for ChannelManager {
11551156
announcement_sigs: announcement_sigs
11561157
});
11571158
short_to_id.insert(channel.get_short_channel_id().unwrap(), channel.channel_id());
1159+
} else if let Err(e) = chan_res {
1160+
if let Some(msgs::ErrorAction::DisconnectPeer { msg }) = e.action {
1161+
new_events.push(events::Event::DisconnectPeer {
1162+
node_id: channel.get_their_node_id(),
1163+
msg: msg
1164+
});
1165+
} else { unreachable!(); }
1166+
if channel.is_shutdown() {
1167+
return false;
1168+
}
11581169
}
11591170
if let Some(funding_txo) = channel.get_funding_txo() {
11601171
for tx in txn_matched {

0 commit comments

Comments
 (0)