Skip to content
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

Unlock utxos when TxPublish fails #1827

Closed
wants to merge 7 commits into from
Closed

Conversation

t-bast
Copy link
Member

@t-bast t-bast commented May 27, 2021

This PR refactors the TxPublisher and adds some new features:

  • We now spawn a FSM for each tx publication: this makes the publish steps more clear and easier to extend
  • We return a TxPublishResult, that will in the future allow the parent TxPublisher to manage the list of pending txs and RBF when needed
  • We don't spend our anchor output when a commit tx is already confirmed
  • We unlock utxos when tx publishing fails (which happens when we restart eclair, which re-sends channel txs to the publisher who will try to publish them but fail because they're already in the mempool)

It can be useful to review commit by commit to see each change individually.

t-bast added 5 commits May 27, 2021 08:34
Isolate the tx publishing logic inside a dedicated actor.
One actor will be created for each tx that should be published.
Use distinct behaviors for each phase of tx publishing.
This will let us handle errors more easily and apply custom clean-up
depending on what phase we were in (e.g. unlock utxos after funding).
If our commit tx or the remote commit tx has been confirmed, there's no
need to claim our anchor output.
When we fail to publish a transaction to which we added wallet inputs, we
must unlock these utxos. This can happen for various reasons, the most
frequent one is a node restart (all txs are sent to the TxPublisher again,
but they may already be in the mempool).
@t-bast t-bast requested a review from pm47 May 27, 2021 06:49
@pm47
Copy link
Member

pm47 commented Jun 7, 2021

Regarding the first commit (9ed346e):

  • have you considered handing the delayed txs in the TxPublish actor? Just my first reaction when looking at the code
  • it seems the new asynchronous publication effectively bypasses the singleThreadExecutionContext and we lose the sequentiality guarantee

@t-bast
Copy link
Member Author

t-bast commented Jun 7, 2021

have you considered handing the delayed txs in the TxPublish actor? Just my first reaction when looking at the code

Yes, all txs will be handled by the TxPublish actor in the future, but one step at a time (I start with the ones that need fee-bumping and will later add the ones for which it's optional).

it seems the new asynchronous publication effectively bypasses the singleThreadExecutionContext and we lose the sequentiality guarantee

That's true. But I really think moving to dedicated actors is important before adding more features...
The only tx that needs to be broadcast first is the commit tx, maybe we can explicitly re-broadcast it in the first step and completely get rid of singleThreadExecutionContext?

Comment on lines +153 to +155
// We retry when the next block has been found, we may have more funds available.
val nextBlockCount = nodeParams.currentBlockHeight + 1
val cltvDelayedTxs1 = cltvDelayedTxs + (nextBlockCount -> (cltvDelayedTxs.getOrElse(nextBlockCount, Seq.empty) :+ result.cmd))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a bit hacky, the transaction isn't really cltv-delayed here. Also, there is a potential risk of creating a herd effect if our wallet balance is low. That would be a nice stress test of our ability to concurrently fund many transactions and manages locks, but I'm not sure it's a good thing.

Copy link
Member Author

@t-bast t-bast Jun 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That will be improved later, when we'll introduce deadlines (block heights at which we should republish/bump some txs), but that requires more work. In the meantime I'd rather err on the safe side and republish aggressively to ensure we don't forget to publish an important transaction because of an unknown error.

@pm47
Copy link
Member

pm47 commented Jun 7, 2021

it seems the new asynchronous publication effectively bypasses the singleThreadExecutionContext and we lose the sequentiality guarantee

That's true. But I really think moving to dedicated actors is important before adding more features...
The only tx that needs to be broadcast first is the commit tx, maybe we can explicitly re-broadcast it in the first step and completely get rid of singleThreadExecutionContext?

IIRC, the most probable scenario would be local-commit and htlc-success

@t-bast
Copy link
Member Author

t-bast commented Jun 7, 2021

The only scenario where it's an issue is the local commit tx, it must be published before its children, otherwise the rest is CSV-delayed so it's not impacted.

t-bast added 2 commits June 9, 2021 10:34
We ensure that the behavior we rely on works as expected.
We treat each transaction separately, which works fine in most cases and
improves parallelism.

But there are cases where we must ensure some sequentiality:

- for standard commitments: commit tx must be published before htlc txs
- for anchor output commitments: commit tx must be published before its anchor

We previously relied on a custom execution context, but that doesn't work
now that we create one actor per transaction.
@t-bast
Copy link
Member Author

t-bast commented Jun 9, 2021

it seems the new asynchronous publication effectively bypasses the singleThreadExecutionContext and we lose the sequentiality guarantee

This is fixed in 81a1b51
I chose to optimistically publish txs and react on failures by publishing the parent first.
The most impacted case if htlc txs in non-anchor output commitments (because they aren't csv-delayed).

@t-bast t-bast mentioned this pull request Jun 18, 2021
@t-bast
Copy link
Member Author

t-bast commented Jun 22, 2021

Closed in favor of #1844

@t-bast t-bast closed this Jun 22, 2021
@t-bast t-bast deleted the tx-publisher-unlock-utxos branch June 22, 2021 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants