-
Notifications
You must be signed in to change notification settings - Fork 366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add flag to disable broadcasting when it's dangerous due to information loss #1593
Changes from all commits
9445382
f7c2023
dff01e1
7342d8c
0da0f93
f0f8c83
140152b
2971adc
214c222
616e69b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -783,6 +783,10 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> { | |
counterparty_node_id: Option<PublicKey>, | ||
|
||
secp_ctx: Secp256k1<secp256k1::All>, //TODO: dedup this a bit... | ||
|
||
// Used to track that the channel was updated with ChannelForceClosed {should_broadcast: false} | ||
// implying that it's unsafe to broadcast the latest holder commitment transaction. | ||
allow_automated_broadcast: bool, | ||
} | ||
|
||
/// Transaction outputs to watch for on-chain spends. | ||
|
@@ -1017,6 +1021,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> { | |
(7, self.funding_spend_seen, required), | ||
(9, self.counterparty_node_id, option), | ||
(11, self.confirmed_commitment_tx_counterparty_output, option), | ||
(13, self.allow_automated_broadcast, required), | ||
}); | ||
|
||
Ok(()) | ||
|
@@ -1130,6 +1135,8 @@ impl<Signer: Sign> ChannelMonitor<Signer> { | |
counterparty_node_id: Some(counterparty_node_id), | ||
|
||
secp_ctx, | ||
|
||
allow_automated_broadcast: true, | ||
}) | ||
} | ||
|
||
|
@@ -1180,15 +1187,29 @@ impl<Signer: Sign> ChannelMonitor<Signer> { | |
payment_hash, payment_preimage, broadcaster, fee_estimator, logger) | ||
} | ||
|
||
pub(crate) fn broadcast_latest_holder_commitment_txn<B: Deref, L: Deref>( | ||
/// Broadcasts the latest commitment transaction only if it's safe to do so. | ||
pub(crate) fn maybe_broadcast_latest_holder_commitment_txn<B: Deref, L: Deref>( | ||
&self, | ||
broadcaster: &B, | ||
logger: &L, | ||
) where | ||
B::Target: BroadcasterInterface, | ||
L::Target: Logger, | ||
{ | ||
self.inner.lock().unwrap().maybe_broadcast_latest_holder_commitment_txn(broadcaster, logger) | ||
} | ||
|
||
/// Broadcasts the latest commitment transaction, even if we can't ensure it's safe to do so | ||
/// due to missing information. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should just list the reasons why we force-closed without broadcast here, which I think are just -
|
||
pub fn force_broadcast_latest_holder_commitment_txn_unsafe<B: Deref, L: Deref>( | ||
TheBlueMatt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
&self, | ||
broadcaster: &B, | ||
logger: &L, | ||
) where | ||
B::Target: BroadcasterInterface, | ||
L::Target: Logger, | ||
{ | ||
self.inner.lock().unwrap().broadcast_latest_holder_commitment_txn(broadcaster, logger) | ||
self.inner.lock().unwrap().force_broadcast_latest_holder_commitment_txn_unsafe(broadcaster, logger) | ||
} | ||
|
||
/// Updates a ChannelMonitor on the basis of some new information provided by the Channel | ||
|
@@ -2148,7 +2169,25 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> { | |
} | ||
} | ||
|
||
pub(crate) fn broadcast_latest_holder_commitment_txn<B: Deref, L: Deref>(&mut self, broadcaster: &B, logger: &L) | ||
/// Broadcasts the latest commitment transaction only if it's safe to do so. | ||
pub fn maybe_broadcast_latest_holder_commitment_txn<B: Deref, L: Deref>(&mut self, broadcaster: &B, logger: &L) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The entire type is private, so there's no reason to make these pub. If anything its a bit confusing because it looks like users/other things can call this (and the next function) but they cant. |
||
where B::Target: BroadcasterInterface, | ||
L::Target: Logger, | ||
{ | ||
if self.allow_automated_broadcast { | ||
for tx in self.get_latest_holder_commitment_txn(logger).iter() { | ||
log_info!(logger, "Broadcasting local {}", log_tx!(tx)); | ||
broadcaster.broadcast_transaction(tx); | ||
} | ||
self.pending_monitor_events.push(MonitorEvent::CommitmentTxConfirmed(self.funding_info.0)); | ||
} else { | ||
log_info!(logger, "Not broadcasting local commitment txn. Automated broadcasting is disabled."); | ||
} | ||
} | ||
|
||
/// Broadcasts the latest commitment transaction, even if we can't ensure it's safe to do so | ||
/// due to missing information. | ||
pub fn force_broadcast_latest_holder_commitment_txn_unsafe<B: Deref, L: Deref>(&mut self, broadcaster: &B, logger: &L) | ||
where B::Target: BroadcasterInterface, | ||
L::Target: Logger, | ||
{ | ||
|
@@ -2214,16 +2253,11 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> { | |
ChannelMonitorUpdateStep::ChannelForceClosed { should_broadcast } => { | ||
log_trace!(logger, "Updating ChannelMonitor: channel force closed, should broadcast: {}", should_broadcast); | ||
self.lockdown_from_offchain = true; | ||
if *should_broadcast { | ||
self.broadcast_latest_holder_commitment_txn(broadcaster, logger); | ||
} else if !self.holder_tx_signed { | ||
log_error!(logger, "You have a toxic holder commitment transaction avaible in channel monitor, read comment in ChannelMonitor::get_latest_holder_commitment_txn to be informed of manual action to take"); | ||
} else { | ||
// If we generated a MonitorEvent::CommitmentTxConfirmed, the ChannelManager | ||
// will still give us a ChannelForceClosed event with !should_broadcast, but we | ||
// shouldn't print the scary warning above. | ||
self.allow_automated_broadcast = *should_broadcast; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If its already set to false we should probably leave it at false and not update it. I dont know that it actually matters, but it seems safer. |
||
if !*should_broadcast && self.holder_tx_signed { | ||
log_info!(logger, "Channel off-chain state closed after we broadcasted our latest commitment transaction."); | ||
} | ||
self.maybe_broadcast_latest_holder_commitment_txn(broadcaster, logger); | ||
}, | ||
ChannelMonitorUpdateStep::ShutdownScript { scriptpubkey } => { | ||
log_trace!(logger, "Updating ChannelMonitor with shutdown script"); | ||
|
@@ -3628,13 +3662,15 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K> | |
let mut funding_spend_seen = Some(false); | ||
let mut counterparty_node_id = None; | ||
let mut confirmed_commitment_tx_counterparty_output = None; | ||
let mut allow_automated_broadcast = None; | ||
read_tlv_fields!(reader, { | ||
(1, funding_spend_confirmed, option), | ||
(3, htlcs_resolved_on_chain, vec_type), | ||
(5, pending_monitor_events, vec_type), | ||
(7, funding_spend_seen, option), | ||
(9, counterparty_node_id, option), | ||
(11, confirmed_commitment_tx_counterparty_output, option), | ||
(13, allow_automated_broadcast, option), | ||
}); | ||
|
||
let mut secp_ctx = Secp256k1::new(); | ||
|
@@ -3692,6 +3728,8 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K> | |
counterparty_node_id, | ||
|
||
secp_ctx, | ||
|
||
allow_automated_broadcast: allow_automated_broadcast.unwrap(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be |
||
}))) | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't matter so much for internal fields, but good to make this a doc comment with three "/"s rather than two.