Skip to content

Conversation

@glozow
Copy link
Member

@glozow glozow commented Jan 24, 2024

When we receive a v3 transaction that would bust a mempool transaction's descendant limit, instead of rejecting the new tx, consider replacing the other descendant if it is much higher feerate (using existing RBF criteria to assess that it's more incentive compatible and to avoid DoS).

Delving post with more background and motivation: https://delvingbitcoin.org/t/sibling-eviction-for-v3-transactions/472

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 24, 2024

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK instagibbs, sdaftuar, achow101

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #29496 (policy: bump TX_MAX_STANDARD_VERSION to 3 by glozow)
  • #29427 (Add imbued v3 based on template-matching by sdaftuar)
  • #29325 (consensus: Store transaction nVersion as uint32_t by achow101)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Copy link
Member

@instagibbs instagibbs left a comment

Choose a reason for hiding this comment

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

very compact!

alternative log lines are a bit noisy, but understandable and I have no good suggestions that reduce that much

Copy link
Member

@sdaftuar sdaftuar left a comment

Choose a reason for hiding this comment

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

I was thinking this PR is ready to leave Draft status -- is there anything you're waiting on before doing that?

I'm not sure how important it is to return the v3 error messages if sibling RBF fails. It seems to me that if we just declare that attempting sibling eviction is part of the v3 validation rules, then we should treat failure to get in due to insufficient fees as an RBF failure and not as a v3 failure. (It would also simplify the implementation, so it's possible I'm slightly blinded by aesthetics! Curious what others think.)

I haven't reviewed the test yet, so I will still do that and do some testing of my own, but my first pass read is that this looks pretty good.

@glozow glozow force-pushed the 2024-01-sibling-eviction branch from 96eadd1 to 8ee900f Compare February 19, 2024 11:57
@glozow
Copy link
Member Author

glozow commented Feb 19, 2024

alternative log lines are a bit noisy, but understandable and I have no good suggestions that reduce that much
I'm not sure how important it is to return the v3 error messages if sibling RBF fails.

I've changed it to just add "(including sibling eviction)" when that is what's happening. The diff is less invasive this way, but let me know if still too clunky. I just want to avoid confusing users ("wait, why am I getting an RBF error if I didn't try to replace anything?").

@glozow glozow marked this pull request as ready for review February 19, 2024 14:40
Copy link
Member

@instagibbs instagibbs left a comment

Choose a reason for hiding this comment

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

looking good, will do some testing

@glozow glozow force-pushed the 2024-01-sibling-eviction branch from 8ee900f to 8549fca Compare February 21, 2024 17:32
@glozow glozow force-pushed the 2024-01-sibling-eviction branch from 8549fca to ac7527f Compare February 21, 2024 18:32
@sdaftuar
Copy link
Member

ACK apart from @instagibbs' nit here: #29306 (comment)

@glozow glozow mentioned this pull request Feb 22, 2024
57 tasks
Copy link
Member

Choose a reason for hiding this comment

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

tighten checks a bit further to make sure this is incentive compatible?

Suggested change
const bool consider_sibling_eviction{parent_entry->GetCountWithDescendants() == 2};
const bool consider_sibling_eviction{parent_entry->GetCountWithDescendants() == 2 &&
children.begin()->get().GetCountWithAncestors() == 2};

Copy link
Member Author

Choose a reason for hiding this comment

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

added

Copy link
Member

Choose a reason for hiding this comment

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

I don't think this matters much either way, since this is only a case that can be arrived at via reorg, but I just wanted to note that I think it would be fine to attempt sibling eviction in the case where the other child has some other parent.

This is a scenario we want to avoid in general with v3, because that transaction could be an RBF pin, because such a transaction can pay a large fee but have a low mining score due to the other parent(s). However, there's no downside to attempting the replacement in this case, in the sense that if our RBF validation succeeds, then the topology constraint on the incoming transaction, combined with the restriction that the child we're evicting has no children of its own, should guarantee that the replacement is incentive compatible.

@glozow glozow force-pushed the 2024-01-sibling-eviction branch from ac7527f to 77b0b8c Compare February 23, 2024 17:26
@ariard
Copy link

ariard commented Feb 26, 2024

Additionally, I did extend the test_v3_sibling_eviction new test here 04fdc0a.

Sibling eviction adds a new replacement cycling vector, where you can from now on throw out of network mempools your counterparty honest medium-feerate CPFP with a “sibling-eviction” higher absolute fee / feerate, and then evict this “malicious” CPFP with a conflict on one of its spent UTXO, not related to the Lightning channel. From my understanding, this is a security regression from current carve-out mechanism, where at least the 2 anchor outputs spent are protected from concurrent spending. Only assuming ability to broadcast transactions in network mempools from the attacker, not advanced tx-relay topology trick. (To be fair, the alternative proposal I was laying out i.e 1 single PT2R with alternative branches is obviously affected by the same concern).

My reasonable recommendation is to skip “sibling eviction” directly and rather focus on package relay support. Now, if people wishes to move forward with this, then deprecate CPFP carve-out (which is downgrading theoretical LN security in a world where CPFP broadcast in implemented correctly by the majority of LN implementations), I don’t really care. My time is better allocated to break more substantial things, sibling eviction is too easy.

@glozow
Copy link
Member Author

glozow commented Feb 27, 2024

So unless my understanding is incorrect all major Lightning implementations have failed to implement CPFP carve-out

It seems your understanding is incorrect, given #29306 (comment) and #29319 (comment)

can you re-explain why this PR is needed given LN commitment transactions can achieve the same tx-relay propagation benefits without this change ?

Can you lay out why this feature is useful for a number of reasons ? AFAICT, it’s only designed to be used in Lightning context (?), where the commitment transaction types are trying to leverage CPFP carve-out.

As the delving post says, it's beneficial to accept a new high feerate child of a v3 tx - without busting the descendant limits - instead of being stuck with a less incentive-compatible descendant that we received earlier.

@t-bast
Copy link
Contributor

t-bast commented Feb 28, 2024

However in checkAnchorPreconditions you’re only checking one of them as a getmempoolentry() (IIUC RepleaceableTxPrePublisher) ?

Yes, but there are potentially 3 instances of that actor running in parallel, one for each commitment transaction. So one of them will match what is in our mempool and will correctly sweep the anchor.

@instagibbs
Copy link
Member

looks like you have a real test failure on a non-final commit

@glozow
Copy link
Member Author

glozow commented Mar 1, 2024

looks like you have a real test failure on a non-final commit

Should be fixed now

@glozow glozow force-pushed the 2024-01-sibling-eviction branch from 75788ee to 1342a31 Compare March 1, 2024 15:39
Copy link
Member

@instagibbs instagibbs left a comment

Choose a reason for hiding this comment

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

ACK 1342a31

// already calculated.
if (const auto err{SingleV3Checks(ws.m_ptx, ws.m_ancestors, ws.m_conflicts, ws.m_vsize)}) {
// Disabled within package validation.
if (err->second != nullptr && args.m_allow_replacement) {
Copy link
Member

Choose a reason for hiding this comment

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

For package RBF I'll be switching this boolean on in multi-tx setting, so I'll likely have to modify this. It's correct as-is.

@ariard
Copy link

ariard commented Mar 4, 2024

Yes, but there are potentially 3 instances of that actor running in parallel, one for each commitment transaction. So one of them will match what is in our mempool and will correctly sweep the anchor.

Do you have test coverage that if there is replacement of current N commitment transaction with N+1 commitment transaction, your parallel actor re-broadcast well the corresponding anchor transaction ? I even think the correct model should be to have a parallel actor for each version of the counterparty revoked transaction (and as such txid), as we considered in the past for pinning.

@DrahtBot DrahtBot requested a review from sdaftuar March 4, 2024 01:08
@ariard
Copy link

ariard commented Mar 4, 2024

As the delving post says, it's beneficial to accept a new high feerate child of a v3 tx - without busting the descendant limits - instead of being stuck with a less incentive-compatible descendant that we received earlier.

This does not address my concern here on the introduction of a new replacement cycling vector.

@t-bast
Copy link
Contributor

t-bast commented Mar 4, 2024

Do you have test coverage that if there is replacement of current N commitment transaction with N+1 commitment transaction, your parallel actor re-broadcast well the corresponding anchor transaction ?

Yes, as long as we see any commitment in our mempool, we'll spend it. If we don't see it in our mempool, we cannot do anything though. I think we should stop spamming this PR though, lightning implementation details aren't very useful here...

@sdaftuar
Copy link
Member

sdaftuar commented Mar 5, 2024

ACK 1342a31

@DrahtBot DrahtBot removed the request for review from sdaftuar March 5, 2024 16:17
@ariard
Copy link

ariard commented Mar 5, 2024

Yes, as long as we see any commitment in our mempool, we'll spend it. If we don't see it in our mempool, we cannot do anything though.

Better if you have test coverage. Not answering the fact that you might have to CPFP any past revoked commitment transaction which is not a new concern related to pinning (cf. scenario 2a)). Here lightning implementations details matters as sibling eviction is proposed to replace carve-out, which itself was justified for "contracting applications” (it’s already marked here: https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp#L905).

This does not address my concern #29306 (comment) on the introduction of a new replacement cycling vector.

No conceptual answer on the introduction of a new replacement cycling vector neutralizing all security benefits for time-sensitive use-cases (either timevalue or loss of funds) :(

@ariard
Copy link

ariard commented Mar 6, 2024

I’ll go to hack a tx-relay jamming toolkit and experiment under real-world conditions. Best process to prove my claim on the introduction of a new RC attack vector claim.

Feel free to move ahead with merging this, though if it’s broken "I would have told you so” :)

@DrahtBot DrahtBot mentioned this pull request Mar 8, 2024
8 tasks
@achow101
Copy link
Member

ACK 1342a31

@achow101 achow101 merged commit 12dae63 into bitcoin:master Mar 12, 2024
@glozow glozow deleted the 2024-01-sibling-eviction branch March 13, 2024 10:14
achow101 added a commit that referenced this pull request Jun 7, 2024
30a0113 [doc] update bips.md for 431 (glozow)
9dbe6a0 [test] wallet uses CURRENT_VERSION which is 2 (glozow)
539404f [policy] make v3 transactions standard (glozow)
052ede7 [refactor] use TRUC_VERSION in place of 3 (glozow)

Pull request description:

  Make `nVersion=3` (which is currently nonstandard on mainnet) standard.

  Note that we will treat these transactions as Topologically Restricted Until Confirmation (TRUC). Spec is in BIP 431 and implementation is in #28948, #29306, and #29873

  See #27463 for overall project tracking, and #29319 for information about relevance to cluster mempool.

ACKs for top commit:
  sdaftuar:
    utACK 30a0113
  achow101:
    ACK 30a0113
  instagibbs:
    utACK 30a0113
  murchandamus:
    ACK 30a0113
  ismaelsadeeq:
    ACK 30a0113 🛰️

Tree-SHA512: 2a4aec0442c860e792a061d83e36483c1f1b426f946efbdf664c8db97a596e498b535707e1d3a900218429486ea69fd4552e3d476526a6883cbd5556c6534b48
@bitcoin bitcoin locked and limited conversation to collaborators Mar 13, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants