-
Notifications
You must be signed in to change notification settings - Fork 407
Add ChannelPending
event emitted upon funding_signed
#2098
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
Changes from all commits
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 |
---|---|---|
|
@@ -32,7 +32,9 @@ use crate::util::ser::{BigSize, FixedLengthReader, Writeable, Writer, MaybeReada | |
use crate::util::string::UntrustedString; | ||
use crate::routing::router::{RouteHop, RouteParameters}; | ||
|
||
use bitcoin::{PackedLockTime, Transaction}; | ||
use bitcoin::{PackedLockTime, Transaction, OutPoint}; | ||
#[cfg(anchors)] | ||
use bitcoin::{Txid, TxIn, TxOut, Witness}; | ||
use bitcoin::blockdata::script::Script; | ||
use bitcoin::hashes::Hash; | ||
use bitcoin::hashes::sha256::Hash as Sha256; | ||
|
@@ -608,12 +610,39 @@ pub enum Event { | |
/// The caveat described above the `fee_earned_msat` field applies here as well. | ||
outbound_amount_forwarded_msat: Option<u64>, | ||
}, | ||
/// Used to indicate that a channel with the given `channel_id` is being opened and pending | ||
/// confirmation on-chain. | ||
/// | ||
/// This event is emitted when the funding transaction has been signed and is broadcast to the | ||
/// network. For 0conf channels it will be immediately followed by the corresponding | ||
/// [`Event::ChannelReady`] event. | ||
ChannelPending { | ||
/// The `channel_id` of the channel that is pending confirmation. | ||
channel_id: [u8; 32], | ||
/// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound | ||
/// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if | ||
/// [`UserConfig::manually_accept_inbound_channels`] config flag is set to true. Otherwise | ||
/// `user_channel_id` will be randomized for an inbound channel. | ||
/// | ||
/// [`ChannelManager::create_channel`]: crate::ln::channelmanager::ChannelManager::create_channel | ||
/// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel | ||
/// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels | ||
user_channel_id: u128, | ||
/// The `temporary_channel_id` this channel used to be known by during channel establishment. | ||
/// | ||
/// Will be `None` for channels created prior to LDK version 0.0.115. | ||
former_temporary_channel_id: Option<[u8; 32]>, | ||
/// The `node_id` of the channel counterparty. | ||
counterparty_node_id: PublicKey, | ||
/// The outpoint of the channel's funding transaction. | ||
funding_txo: OutPoint, | ||
}, | ||
/// Used to indicate that a channel with the given `channel_id` is ready to | ||
/// be used. This event is emitted either when the funding transaction has been confirmed | ||
/// on-chain, or, in case of a 0conf channel, when both parties have confirmed the channel | ||
/// establishment. | ||
ChannelReady { | ||
/// The channel_id of the channel that is ready. | ||
/// The `channel_id` of the channel that is ready. | ||
channel_id: [u8; 32], | ||
/// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound | ||
/// channels, or to [`ChannelManager::accept_inbound_channel`] for inbound channels if | ||
|
@@ -624,15 +653,15 @@ pub enum Event { | |
/// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel | ||
/// [`UserConfig::manually_accept_inbound_channels`]: crate::util::config::UserConfig::manually_accept_inbound_channels | ||
user_channel_id: u128, | ||
/// The node_id of the channel counterparty. | ||
/// The `node_id` of the channel counterparty. | ||
counterparty_node_id: PublicKey, | ||
/// The features that this channel will operate with. | ||
channel_type: ChannelTypeFeatures, | ||
}, | ||
/// Used to indicate that a previously opened channel with the given `channel_id` is in the | ||
/// process of closure. | ||
ChannelClosed { | ||
/// The channel_id of the channel which has been closed. Note that on-chain transactions | ||
/// The `channel_id` of the channel which has been closed. Note that on-chain transactions | ||
/// resolving the channel are likely still awaiting confirmation. | ||
channel_id: [u8; 32], | ||
/// The `user_channel_id` value passed in to [`ChannelManager::create_channel`] for outbound | ||
|
@@ -931,6 +960,16 @@ impl Writeable for Event { | |
(6, channel_type, required), | ||
}); | ||
}, | ||
&Event::ChannelPending { ref channel_id, ref user_channel_id, ref former_temporary_channel_id, ref counterparty_node_id, ref funding_txo } => { | ||
31u8.write(writer)?; | ||
write_tlv_fields!(writer, { | ||
(0, channel_id, required), | ||
(2, user_channel_id, required), | ||
(4, former_temporary_channel_id, required), | ||
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. nit: 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. Yes, it's a tiny bit more efficient but to be honest I don't liking mixing implementation type and serialization type semantics if it can be avoided. In my mind |
||
(6, counterparty_node_id, required), | ||
(8, funding_txo, required), | ||
}); | ||
}, | ||
// Note that, going forward, all new events must only write data inside of | ||
// `write_tlv_fields`. Versions 0.0.101+ will ignore odd-numbered events that write | ||
// data via `write_tlv_fields`. | ||
|
@@ -1271,6 +1310,31 @@ impl MaybeReadable for Event { | |
}; | ||
f() | ||
}, | ||
31u8 => { | ||
let f = || { | ||
let mut channel_id = [0; 32]; | ||
let mut user_channel_id: u128 = 0; | ||
let mut former_temporary_channel_id = None; | ||
let mut counterparty_node_id = RequiredWrapper(None); | ||
let mut funding_txo = RequiredWrapper(None); | ||
read_tlv_fields!(reader, { | ||
(0, channel_id, required), | ||
(2, user_channel_id, required), | ||
(4, former_temporary_channel_id, required), | ||
(6, counterparty_node_id, required), | ||
(8, funding_txo, required), | ||
}); | ||
|
||
Ok(Some(Event::ChannelPending { | ||
channel_id, | ||
user_channel_id, | ||
former_temporary_channel_id, | ||
counterparty_node_id: counterparty_node_id.0.unwrap(), | ||
funding_txo: funding_txo.0.unwrap() | ||
})) | ||
}; | ||
f() | ||
}, | ||
// Versions prior to 0.0.100 did not ignore odd types, instead returning InvalidValue. | ||
// Version 0.0.100 failed to properly ignore odd types, possibly resulting in corrupt | ||
// reads. | ||
|
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.
Should we have a note that, in rare cases, this event may be missed if a channel is ultimately confirmed quickly prior to the event being processed and then we restart? Its a stupid rare case but its possible I think?
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.
I'm confused, which scenario are you describing exactly? Wouldn't rather be an edge case that we emit the event twice when we decide to rebroadcast on restart?
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.
I think we can: (a) fund the channel, with an async monitor update, (b) not have that complete, but persist the manager, then (c) complete the monitor update and broadcast the funding tx (d) then restart, replay the chain and see the funding tx confirm, then (e) re-complete the monitor update completed in c, then we wont get the event again but the user will never have used it.
I think with "full" async monitor updates this becomes more realistic.
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.
Since we plan to leverage it for #2137, seems we should always regenerate it in cases like this? The channel will actually be ready, but as long as it's queued before the
ChannelReady
event, it should be fine.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.
Yea, that's my biggest concern here.
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.
Ugh., I see. In that scenario it would persist the event queue when the event hasn't been emitted yet and wouldn't re-emit it after restart. Mh, instead of leaving a note I went ahead and am now tracking the emission of
ChannelPending
in the same way asChannelReady
and removed it frominternal_funding_created
entirely.This means that we're now only emitting it after CMU completion or reestablish, i.e., would re-emit it if the "emitted" state wasn't persisted before.