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

proof of concept: implement cancel_tx #1764

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

ValuedMammal
Copy link
Contributor

@ValuedMammal ValuedMammal commented Dec 8, 2024

Description

This is not a merge candidate. The goal of this PR is implement cancel_tx, as doing so has the potential to fix a long-standing TODO in the library saying "make this free up reserved utxos when that's implemented". This was initiated in response to user feedback claiming that the method has no effect.

issue #1743

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Copy link

@ErikDeSmedt ErikDeSmedt left a comment

Choose a reason for hiding this comment

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

Thanks for looking into this.

I'm not very familiar with the BDK-codebase but I am happy to see where this is going

Canceled,
/// new details added. note, when applied this will overwrite existing
Details(Details),
}

Choose a reason for hiding this comment

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

I don't really understand the design of this enum.

What is the difference between Record::Canceled and Record::Details { canceled: true}.
Why are both structs required?

@@ -44,6 +44,95 @@ const P2WPKH_FAKE_WITNESS_SIZE: usize = 106;

const DB_MAGIC: &[u8] = &[0x21, 0x24, 0x48];

#[test]
fn cancel_tx_frees_spent_inputs() -> anyhow::Result<()> {

Choose a reason for hiding this comment

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

Nice, this test behaves exactly as I would expect

@evanlinjin
Copy link
Member

@ValuedMammal could you further elaborate on the goals of this PR? Thanks!

@ValuedMammal ValuedMammal changed the title proof of concept: cancel_tx + tx details proof of concept: implement cancel_tx Dec 11, 2024
@buffrr
Copy link

buffrr commented Dec 18, 2024

Even after PR #1765, I think cancel_tx would still be needed for different reasons. If a transaction gets dropped from the mempool but persisted in the wallet as unconfirmed, we need a way to handle it - otherwise it would stay as unconfirmed in the wallet db forever, right? Users would have no choice but to rescan their wallet (I guess they could try to rebroadcast or bump the fee)

@evanlinjin
Copy link
Member

evanlinjin commented Dec 24, 2024

@buffrr The only way we can confidently say "a transaction is dropped" is if a conflicting transaction gets confirmed. Therefore, having cancel_tx is not the correct fix here. Instead, we should somehow introduce the conflicting tx into our TxGraph.

@buffrr
Copy link

buffrr commented Dec 24, 2024

It's possible for a transaction to be dropped from the mempool without a conflicting tx - such as when it has a low fee and stays in the mempool too long. While we can have some level of confidence after seeing a conflicting tx, we also can't be certain that it will be mined over the original. Waiting for a confirmation of a foreign/irrelevant tx might not be desirable as it locks the users funds during that period which could be hours or days.

It would be helpful to give developers the option to explicitly mark a tx as 'ok to double spend' and I guess that's what would cancel_tx enable. I'm grateful for #1765 so this is more of a nice to have!

@evanlinjin
Copy link
Member

Imagine this from a UX perspective. The user creates a tx because they have intent to spend their Bitcoin. Then because feerate too low, it gets dropped from mempool and the tx just disappears from the wallet. I would say this is unexpected behavior. I expect the user would want to RBF the tx?

What if the feerate is acceptable after some time, and someone, all this time, has a mempool that didn't drop txs and this tx gets rebroadcasted? So now do we need a method to uncancel the tx?

There are other ways to explicitly mark a tx as "okay to double spend".

@buffrr
Copy link

buffrr commented Dec 26, 2024

Then because feerate too low, it gets dropped from mempool and the tx just disappears from the wallet. I would say this is unexpected behavior. I expect the user would want to RBF the tx?

While I agree in that specific case for typical transactions, it really depends on the use case and how developers would want to tailor the UX for end users.

What if the feerate is acceptable after some time, and someone, all this time, has a mempool that didn't drop txs and this tx gets rebroadcasted? So now do we need a method to uncancel the tx?

There's no need for such a method as that wouldn't result in locking up funds. The worst that could happen is they end up replacing it, or it gets confirmed, which, depending on the use case, might be ok.

There are other ways to explicitly mark a tx as "okay to double spend".

I’m not sure that’s easily achievable. Perhaps only by attempting to manually find and double-spend the locked-up funds?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

4 participants