-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
neutrino remove sweeptx #7800
neutrino remove sweeptx #7800
Conversation
9f32082
to
0e0c49f
Compare
A switch from neutrino to normal backends could solve the problem too, so maybe that's the reason why it comes up so late? While analysing the bug I realised that we also do not save the "ForceClosing" transactions ( |
0e0c49f
to
7dd93dc
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.
Thanks a lot for catching this and providing a fix!
I think this makes sense, but would like to get at least another review from someone who is a bit more familiar with the internals of the sweeper.
7dd93dc
to
9ff2d40
Compare
Isn't this equivalent to just removing the |
Good idea but our use case is a bit different here. So when we launch our CPFP anchor sweeps we do that in the worst case for 3 different commitment txids, (local,remote,remote_dangling) in your function only the inputs are checked which are spent in the transaction, however we must trigger the removal also when sweeps of the same exclusive group are confirmed, because only one commitment tx can make it into the blockchain. Maybe there is a way to include this removal in this code, instead of introducing another function. Ok so the interesting part happens here, where all pendingsweeps with the same exclusive group are evaluated and exactly there we have to hook in for the removal of those lingering unminded transaction: So I think it's the safest way to include the call in the |
Regarding our solution in #7879 we should also make sure that we remove invalid transactions when our sweeper exhausts for specific outputs. This would make sure in a case of the anchorsweeps or any other sweep also gets removed from the unminded bucket of the wallet and the Rebroadcaster as well. Basically calling the new The removal of transactions in the same exclusive group could also be fixed in another way. So we could add an |
The question here which is still open: How do we remove transactions resulting from this behaviour prior to this fix? Where the channel is already resolved and no more sweeps are registered but the transaction is still stuck in the |
Rescanning the wallet works here 🙌 user will need to trigger a rescan. However we can maybe add an rpc endpoint nonetheless, facilitating the process in case the user knows what he is missing ? |
@ziggie1984 I think that's a good idea. Having to add that flag, then also resume with a special unlock flag is kinda annoying. Should be a small change. |
@yyforyongyu: review reminder |
!lightninglabs-deploy mute |
9ff2d40
to
8b85c0c
Compare
Added a new walletrpc endpoint Only relevant for neutrino backends imo, prior to that people could just use |
0c80433
to
93ed71b
Compare
713bf28
to
def84d2
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.
Nice addition of the RemoveTransaction
! My main question is whether we should combine removeLastSweepDescendants
and removeConflictingSweepTx
.
a0d5cf8
to
bcae6bf
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.
Looking good🏖 Just a few nits. Meanwhile do you think the following case is fixed here?
Lines 523 to 551 in d9b88fb
// Send another UTXO if this is a neutrino backend. When sweeping | |
// anchors, there are two transactions created, `local_sweep_tx` for | |
// sweeping Alice's anchor on the local commitment, `remote_sweep_tx` | |
// for sweeping her anchor on the remote commitment. Whenever the force | |
// close transaction is published, Alice will always create these two | |
// transactions to sweep her anchor. | |
// On the other hand, when creating the sweep txes, the anchor itself | |
// is not able to cover the fee, so another wallet UTXO is needed. In | |
// our test case, there's a change output that can be used from the | |
// above funding process. And it's used by both sweep txes - when `lnd` | |
// happens to create the `remote_sweep_tx` first, it will receive an | |
// error since its parent tx, the remote commitment, is not known, | |
// hence freeing the change output to be used by `local_sweep_tx`. | |
// For neutrino client, however, it will consider the transaction which | |
// sweeps the remote anchor as an orphan tx, and it will neither send | |
// it to the mempool nor return an error to free the change output. | |
// Thus, if the change output is already used in `remote_sweep_tx`, we | |
// won't have UTXO to create `local_sweep_tx`. | |
// | |
// NOTE: the order of the sweep requests for the two anchors cannot be | |
// guaranteed. If the sweeper happens to sweep the remote anchor first, | |
// then the test won't pass without the extra UTXO, which is the source | |
// of the flakeness. | |
// | |
// TODO(yy): make a RPC server for sweeper so we can explicitly check | |
// and control its state. | |
if ht.IsNeutrinoBackend() { | |
ht.FundCoins(anchorFeeBuffer, alice) | |
} |
Was thinking how we can test this new behavior for neutrino backend, and this the above case won't be fixed becase these conflicting transactions are only removed AFTER the sweeping tx is confirmed?
I agree it's not fixed because this only removes them if the commitment is confirmed. But the flakiness is fixed when adding this additional input correct ? |
bcae6bf
to
74dbee7
Compare
74dbee7
to
d13aff1
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🙏
But the flakiness is fixed when adding this additional input correct ?
Correct.
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.
Did a first pass. Very nice, definitely very useful to have!
Main ask is to change the RPC/CLI a bit to allow only specifying the TXID. Other than that it's mostly nits.
9ec90ee
to
f6f1c03
Compare
f7556b9
to
8123112
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.
Great work, we're almost there.
Just one more ask (simplification because of new wallet method we have) and a couple of nits.
lnrpc/walletrpc/walletkit_server.go
Outdated
// `ListTransactionDetails` function so we provide an empty string. | ||
// -1 equals the mempool height so only unconfirmed transactions are | ||
// returned. | ||
transactions, err := w.cfg.Wallet.ListTransactionDetails(-1, -1, "") |
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.
We can now fetch a transaction directly from the wallet, see #7654.
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 wonder if we also should allow to remove confirmed transactions to shortcircuit the wallet rescan, but I guess for this we would also need to introduce a addTx
cmd, so that that we can manually add some utxos if we know for sure that they are ours?
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.
see for example issue #8251, where they kind of know what they are missing ?
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, not sure if that's a good idea... You could really mess up your wallet state with that. At the very least it shouldn't be part of this PR anyway so we can properly discuss the feature (and its consequences) in a standalone PR.
For anchor channels and neutrino backends we need to make sure that sweeps of the same exclusive group are removed when one of them is confirmed. Otherwise for neutrino backends those sweep transaction are always rebroadcasted and are blocking funds in the worst case scenario.
The RemoveTransaction endpoint removes the transaction with the provided txid including all its descendants from the internal wallet. We still keep watching for the address of the transation in case the transcation is confirmed nonetheless. This command is particular useful for neutrino backends because new bitcoind versions do not reply with an invalid transaction error code when the tx published fails to be included into the mempool (fullnodes do).
This new command calls the new rpc endpoint RemoveTransaction.
8123112
to
043153f
Compare
// as a transaction is confirmed it will be evaluated by the wallet | ||
// again and the wallet state would be updated in case the user had | ||
// removed the transaction accidentally. | ||
if res.NumConfirmations > 0 { |
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.
We might think of a --i_know_what_i_am_doing
flag and also allow the removal of confirmed txids ?
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.
See my comment above about doing it in a separate PR (if even...). Also, when it comes to naming, I think we'd want something more along the lines of --danger-allow-confirmed
since apparently the "I know what I'm doing" approach doesn't seem to work for some users. Psychologically it seems people are more inclined to think they know what they're doing while if something is labelled as "dangerous" they might be more careful (even if they happen to actually know what they are doing).
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.
well said, I observed the same behavior :)
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 🎉
Fixes #7790
Change Description
Up until now we were only removing pending sweep inputs when a transaction was confirmed spending an input of the same exclusive group. For neutrino backends this is not enough, we need to make sure that the whole unconfirmed transaction is purged as well. This refers especially to anchor force closes where up to 3 sweep inputs are broadcasted within the same exclusive group. In the worst case scenario 2 additional inputs will be blocked because they are used to sweep anchor outputs which will never confirm because their parent will never make it into the blockchain as soon as one of them is confirmed.
This change does not restrict the removing soley for neutrino backends because it is most likely a NOOP for other backends. Nonetheless I think it does no harm and prevents us from surfacing the backend-structure into the Sweeper package. Open for suggestions here if there is a better way.
Restarting the node will not fix this behaviour because the transaction is still in the unminded bucket which means it will be rebroadcasted and bitcoind nodes will not fail this transaction because they will consider it as orphan.
Enhanced an itest to easily verify this:
make itest icase=multi_hop_local_force_close_on-chain_htlc_timeout/zeroconf=false/committype=ANCHORS backend=neutrino
Steps to Test
Steps for reviewers to follow to test the change.
Pull Request Checklist
Testing
Code Style and Documentation
[skip ci]
in the commit message for small changes.📝 Please see our Contribution Guidelines for further guidance.