-
Notifications
You must be signed in to change notification settings - Fork 114
Insert channel funding outputs into Wallet #726
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
Conversation
|
👋 Thanks for assigning @jkczyz as a reviewer! |
091e391 to
d7f8bc9
Compare
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.
Makes sense to me. Do we think this is worth a backport for 0.7 or are we fine waiting for 0.8 with shipping this?
The different cases in the event handler could use a comment or two to explain when we'd land on which side of the if/else clauses there. Also, we really need to be careful with just replaying events in cases where we don't expect immediate resolution of the error on retry, as we'd otherwise just spin and block any other event processing. This could also use better test coverage to show why we need this change in the first place.
Besides that, also pinging @jkczyz as a second reviewer on this.
src/event.rs
Outdated
| self.logger, | ||
| "Failed to find channel info for pending channel {channel_id} with counterparty {counterparty_node_id}" | ||
| ); | ||
| return Err(ReplayEvent()); |
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.
This would induce an infinite loop in event handling, no? Rather than doing this, we probably need to just log the error for now, and abort the flow when we can with 0.3? Also, would it make sense to add a debug_assert here, given that we expect this always to be avaialble? (same below)
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.
The error below can only happen on a persistence failure, elsewhere in the event handling we replay on those errors so I think it makes sense to keep as is.
For this one, it should always be available so I will just change to a debug_assert
| }, | ||
| } | ||
| } else { | ||
| log_info!( |
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.
In what case would we end up in this else branch, and would we need to do something related to the redeemscript, too?
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.
According to the docs, the funding_txo "Will be None if the channel's funding transaction reached an acceptable depth prior to version 0.2". Since this was also added in 0.2, the redeem script would also be None so there shouldn't be anything to add. Either way, we need the funding txo to be able to insert so we can't add it.
| node_b.splice_in(&user_channel_id_b, node_a.node_id(), 4_000_000).unwrap(); | ||
|
|
||
| expect_splice_pending_event!(node_a, node_b.node_id()); | ||
| let txo = expect_splice_pending_event!(node_a, node_b.node_id()); |
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.
These test changes pass on main. Can you add coverage for the cases where the previous approach would lead to inaccurate fee estimations?
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.
The bug/issue only exists with bitcoind syncing so to do so, we'd have to change the test to sync with bitcoind rpc. Is that wanted?
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.
The bug/issue only exists with bitcoind syncing so to do so, we'd have to change the test to sync with bitcoind rpc. Is that wanted?
Sure, feel free to do so. Alternatively, you could also add a _bitcoind variant test case (ofc reusing the logic) so we have two test cases for bitcoind and esplora - that's if we think there would be more chain source specific edge cases.
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.
added
| } | ||
| } | ||
|
|
||
| impl UniffiCustomTypeConverter for ScriptBuf { |
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.
nit: While this should be fine for now, we generally try to get away from the UniffiCustomTypeConverter approach, and instead convert more and more objects to proper interfaces.
d7f8bc9 to
b2c3793
Compare
|
🔔 1st Reminder Hey @jkczyz! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @jkczyz! This PR has been waiting for your review. |
src/event.rs
Outdated
| ); | ||
| }, | ||
| Some(output) => { | ||
| if let Err(e) = self.wallet.insert_txo(funding_txo, output) { |
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.
Hmmm... I guess we didn't really need the redeem script in ChannelPending and SplicePending since we only need the previous funding output in the wallet for the next splice. Might have been better in ChannelReady. We'd be able to avoid the look-up, although it wouldn't remove the Option check.
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.
Yeah sadly I messed up here, i think we needed to add the redeem script along with the new channel size so we had the full utxo information
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.
Yeah, though if we insert the previous funding txo when initiating the splice as mentioned in the other comment, then I think we'll have all the necessary information in ChannelDetails? Essentially, we'd be lazily adding the previous funding output to the wallet when initiating the splice.
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.
Made so we add it before a splice-in. I still think this one is good to keep so if you're doing any other wallet related action, it will have a more complete set of information and you don't need to initiate a splice for it to have the channel information
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 still think this one is good to keep so if you're doing any other wallet related action, it will have a more complete set of information and you don't need to initiate a splice for it to have the channel information
Could you provide an example for what else we would use this information? If we don't need it I'd prefer to drop this change to declutter the logic here and avoid the extra persistence roundtrip.
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.
Okay yeah on further reflection, no real use case, especially with the api that ldk-node exposes to the wallet.
src/event.rs
Outdated
| let chans = | ||
| self.channel_manager.list_channels_with_counterparty(&counterparty_node_id); | ||
| let chan_output = chans | ||
| .iter() | ||
| .find(|c| c.user_channel_id == user_channel_id) | ||
| .and_then(|c| c.get_funding_output()); |
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.
Doing this in ChannelReady wouldn't work for splicing preexisting channels. Wonder if we should instead do this when initiating a splice? There we already look up the channel. It would also let us use the real shared_input when selecting UTXOs.
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.
Doing this in ChannelReady wouldn't work for splicing preexisting channels.
I dont think this is right, in the docs it says we get a ChannelReady for splices, also my test seems to confirm
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.
Correct, we do get it for spliced channels, but we need the initial funding output because that is the one being spent. And for channels existing before this change, we would have already processed the ChannelReady event for the initial funding.
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.
ah i see for backward compat sake, added!
b2c3793 to
8518f3d
Compare
src/lib.rs
Outdated
| let shared_output = bitcoin::TxOut { | ||
| value: shared_input.previous_utxo.value + Amount::from_sat(splice_amount_sats), | ||
| script_pubkey: make_funding_redeemscript(&dummy_pubkey, &dummy_pubkey).to_p2wsh(), | ||
| script_pubkey: funding_output.script_pubkey, |
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.
This should still be the dummy one or note that it is not really the shared output's script_pubkey. I guess the amount is already fake since we don't know what the counterparty will contribute.
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.
added a comment
…lices LDK gives us the actual funding output so we no longer need to create a dummy one with fake pubkeys
8518f3d to
4c3450e
Compare
tnull
left a comment
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.
Excuse the delay here
src/event.rs
Outdated
| ); | ||
| }, | ||
| Some(output) => { | ||
| if let Err(e) = self.wallet.insert_txo(funding_txo, output) { |
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 still think this one is good to keep so if you're doing any other wallet related action, it will have a more complete set of information and you don't need to initiate a splice for it to have the channel information
Could you provide an example for what else we would use this information? If we don't need it I'd prefer to drop this change to declutter the logic here and avoid the extra persistence roundtrip.
| node_b.splice_in(&user_channel_id_b, node_a.node_id(), 4_000_000).unwrap(); | ||
|
|
||
| expect_splice_pending_event!(node_a, node_b.node_id()); | ||
| let txo = expect_splice_pending_event!(node_a, node_b.node_id()); |
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.
The bug/issue only exists with bitcoind syncing so to do so, we'd have to change the test to sync with bitcoind rpc. Is that wanted?
Sure, feel free to do so. Alternatively, you could also add a _bitcoind variant test case (ofc reusing the logic) so we have two test cases for bitcoind and esplora - that's if we think there would be more chain source specific edge cases.
4c3450e to
95c0819
Compare
|
Addressed review, ended up removing it on events and just doing it before a splice. Made sure test coverage hits on both backends and for splice in and out |
We insert a channel's funding utxo into our wallet so we can later calculate the fees for the transaction, otherwise our wallet would have incomplete information. We do it before the splice as we only really need this information for splices and not for all channels.
Exposes the funding_redeem_script that LDK already exposes
95c0819 to
9b325ff
Compare
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.
LGTM, one nit. Otherwise should be ready pending @jkczyz's review.
|
|
||
| #[tokio::test(flavor = "multi_thread", worker_threads = 1)] | ||
| async fn splice_channel() { | ||
| run_splice_channel_test(false).await; |
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.
nit: Not that it matters much, but elsewhere in LDK Node / LDK tests the usual pattern would be to name the 'inner' test methods do_splice_channel. Feel free to make that rename if you touch the code again.
When doing a splice, to properly calculate fees we need the channel's funding utxo in our wallet, otherwise our wallet won't know the channel's original size. This adds the channel funding txo to the wallet before a splice as we only really need this information for splices and not for all channels.