public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Gloria Zhao <gloriajzhao@gmail•com>
To: Bastien TEINTURIER <bastien@acinq•fr>
Cc: Bitcoin Protocol Discussion <bitcoin-dev@lists•linuxfoundation.org>
Subject: Re: [bitcoin-dev] Proposal: Package Mempool Accept and Package RBF
Date: Wed, 22 Sep 2021 14:26:14 +0100	[thread overview]
Message-ID: <CAFXO6=KYYEB9gYMYsHPyxNLbzGB12+XHrX_NbfNoUuFtJjpXgw@mail.gmail.com> (raw)
In-Reply-To: <CACdvm3Ou_o31m1bbn6wkpxvfCiOUDYLF-4s5MVK9Z3i6=w=LzA@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 32046 bytes --]

Hi Bastien,

> A package A + C will be able to replace A' + B regardless of
> the weight of A' + B?

Correct, the weight of A' + B will not prevent A+C from replacing it (as
long as A+C pays enough fees). In example 2C, we would be able to replace A
with a package.

Best,
Gloria

On Wed, Sep 22, 2021 at 8:10 AM Bastien TEINTURIER <bastien@acinq•fr> wrote:

> Great, thanks for this clarification!
>
> Can you confirm that this won't be an issue either with your
> example 2C (in your first set of diagrams)? If I understand it
> correctly it shouldn't, but I'd rather be 100% sure.
>
> A package A + C will be able to replace A' + B regardless of
> the weight of A' + B?
>
> Thanks,
> Bastien
>
> Le mar. 21 sept. 2021 à 18:42, Gloria Zhao <gloriajzhao@gmail•com> a
> écrit :
>
>> Hi Bastien,
>>
>> Excellent diagram :D
>>
>> > Here the issue is that a revoked commitment tx A' is pinned in other
>> > mempools, with a long chain of descendants (or descendants that reach
>> > the maximum replaceable size).
>> > We would really like A + C to be able to replace this pinned A'.
>> > We can't submit individually because A on its own won't replace A'...
>>
>> Right, this is a key motivation for having Package RBF. In this case, A+C
>> can replace A' + B1...B24.
>>
>> Due to the descendant limit (each node operator can increase it on their
>> own node, but the default is 25), A' should have no more than 25
>> descendants, even including CPFP carve out. As long as A only conflicts
>> with A', it won't be trying to replace more than 100 transactions. The
>> proposed package RBF will allow C to pay for A's conflicts, since their
>> package feerate is used in the fee comparisons. A is not a descendant of
>> A', so the existence of B1...B24 does not prevent the replacement.
>>
>> Best,
>> Gloria
>>
>> On Tue, Sep 21, 2021 at 4:18 PM Bastien TEINTURIER <bastien@acinq•fr>
>> wrote:
>>
>>> Hi Gloria,
>>>
>>> > I believe this attack is mitigated as long as we attempt to submit
>>> transactions individually
>>>
>>> Unfortunately not, as there exists a pinning scenario in LN where a
>>> different commit tx is pinned, but you actually can't know which one.
>>>
>>> Since I really like your diagrams, I made one as well to illustrate:
>>>
>>> https://user-images.githubusercontent.com/31281497/134198114-5e9c6857-e8fc-405a-be57-18181d5e54cb.jpg
>>>
>>> Here the issue is that a revoked commitment tx A' is pinned in other
>>> mempools, with a long chain of descendants (or descendants that reach
>>> the maximum replaceable size).
>>>
>>> We would really like A + C to be able to replace this pinned A'.
>>> We can't submit individually because A on its own won't replace A'...
>>>
>>> > I would note that this proposal doesn't accommodate something like
>>> diagram B, where C is getting CPFP carve out and wants to bring a +1
>>>
>>> No worries, that case shouldn't be a concern.
>>> I believe any L2 protocol can always ensure it confirms such tx trees
>>> "one depth after the other" without impacting funds safety, so it
>>> only needs to ensure A + C can get into mempools.
>>>
>>> Thanks,
>>> Bastien
>>>
>>> Le mar. 21 sept. 2021 à 13:18, Gloria Zhao <gloriajzhao@gmail•com> a
>>> écrit :
>>>
>>>> Hi Bastien,
>>>>
>>>> Thank you for your feedback!
>>>>
>>>> > In your example we have a parent transaction A already in the mempool
>>>> > and an unrelated child B. We submit a package C + D where C spends
>>>> > another of A's inputs. You're highlighting that this package may be
>>>> > rejected because of the unrelated transaction(s) B.
>>>>
>>>> > The way I see this, an attacker can abuse this rule to ensure
>>>> > transaction A stays pinned in the mempool without confirming by
>>>> > broadcasting a set of child transactions that reach these limits
>>>> > and pay low fees (where A would be a commit tx in LN).
>>>>
>>>> I believe you are describing a pinning attack in which your adversarial
>>>> counterparty attempts to monopolize the mempool descendant limit of the
>>>> shared  transaction A in order to prevent you from submitting a fee-bumping
>>>> child C; I've tried to illustrate this as diagram A here:
>>>> https://user-images.githubusercontent.com/25183001/134159860-068080d0-bbb6-4356-ae74-00df00644c74.png
>>>> (please let me know if I'm misunderstanding).
>>>>
>>>> I believe this attack is mitigated as long as we attempt to submit
>>>> transactions individually (and thus take advantage of CPFP carve out)
>>>> before attempting package validation. So, in scenario A2, even if the
>>>> mempool receives a package with A+C, it would deduplicate A, submit C as an
>>>> individual transaction, and allow it due to the CPFP carve out exemption. A
>>>> more general goal is: if a transaction would propagate successfully on its
>>>> own now, it should still propagate regardless of whether it is included in
>>>> a package. The best way to ensure this, as far as I can tell, is to always
>>>> try to submit them individually first.
>>>>
>>>> I would note that this proposal doesn't accommodate something like
>>>> diagram B, where C is getting CPFP carve out and wants to bring a +1 (e.g.
>>>> C has very low fees and is bumped by D). I don't think this is a use case
>>>> since C should be the one fee-bumping A, but since we're talking about
>>>> limitations around the CPFP carve out, this is it.
>>>>
>>>> Let me know if this addresses your concerns?
>>>>
>>>> Thanks,
>>>> Gloria
>>>>
>>>> On Mon, Sep 20, 2021 at 10:19 AM Bastien TEINTURIER <bastien@acinq•fr>
>>>> wrote:
>>>>
>>>>> Hi Gloria,
>>>>>
>>>>> Thanks for this detailed post!
>>>>>
>>>>> The illustrations you provided are very useful for this kind of graph
>>>>> topology problems.
>>>>>
>>>>> The rules you lay out for package RBF look good to me at first glance
>>>>> as there are some subtle improvements compared to BIP 125.
>>>>>
>>>>> > 1. A package cannot exceed `MAX_PACKAGE_COUNT=25` count and
>>>>> > `MAX_PACKAGE_SIZE=101KvB` total size [8]
>>>>>
>>>>> I have a question regarding this rule, as your example 2C could be
>>>>> concerning for LN (unless I didn't understand it correctly).
>>>>>
>>>>> This also touches on the package RBF rule 5 ("The package cannot
>>>>> replace more than 100 mempool transactions.")
>>>>>
>>>>> In your example we have a parent transaction A already in the mempool
>>>>> and an unrelated child B. We submit a package C + D where C spends
>>>>> another of A's inputs. You're highlighting that this package may be
>>>>> rejected because of the unrelated transaction(s) B.
>>>>>
>>>>> The way I see this, an attacker can abuse this rule to ensure
>>>>> transaction A stays pinned in the mempool without confirming by
>>>>> broadcasting a set of child transactions that reach these limits
>>>>> and pay low fees (where A would be a commit tx in LN).
>>>>>
>>>>> We had to create the CPFP carve-out rule explicitly to work around
>>>>> this limitation, and I think it would be necessary for package RBF
>>>>> as well, because in such cases we do want to be able to submit a
>>>>> package A + C where C pays high fees to speed up A's confirmation,
>>>>> regardless of unrelated unconfirmed children of A...
>>>>>
>>>>> We could submit only C to benefit from the existing CPFP carve-out
>>>>> rule, but that wouldn't work if our local mempool doesn't have A yet,
>>>>> but other remote mempools do.
>>>>>
>>>>> Is my concern justified? Is this something that we should dig into a
>>>>> bit deeper?
>>>>>
>>>>> Thanks,
>>>>> Bastien
>>>>>
>>>>> Le jeu. 16 sept. 2021 à 09:55, Gloria Zhao via bitcoin-dev <
>>>>> bitcoin-dev@lists•linuxfoundation.org> a écrit :
>>>>>
>>>>>> Hi there,
>>>>>>
>>>>>> I'm writing to propose a set of mempool policy changes to enable
>>>>>> package
>>>>>> validation (in preparation for package relay) in Bitcoin Core. These
>>>>>> would not
>>>>>> be consensus or P2P protocol changes. However, since mempool policy
>>>>>> significantly affects transaction propagation, I believe this is
>>>>>> relevant for
>>>>>> the mailing list.
>>>>>>
>>>>>> My proposal enables packages consisting of multiple parents and 1
>>>>>> child. If you
>>>>>> develop software that relies on specific transaction relay
>>>>>> assumptions and/or
>>>>>> are interested in using package relay in the future, I'm very
>>>>>> interested to hear
>>>>>> your feedback on the utility or restrictiveness of these package
>>>>>> policies for
>>>>>> your use cases.
>>>>>>
>>>>>> A draft implementation of this proposal can be found in [Bitcoin Core
>>>>>> PR#22290][1].
>>>>>>
>>>>>> An illustrated version of this post can be found at
>>>>>> https://gist.github.com/glozow/dc4e9d5c5b14ade7cdfac40f43adb18a.
>>>>>> I have also linked the images below.
>>>>>>
>>>>>> ## Background
>>>>>>
>>>>>> Feel free to skip this section if you are already familiar with
>>>>>> mempool policy
>>>>>> and package relay terminology.
>>>>>>
>>>>>> ### Terminology Clarifications
>>>>>>
>>>>>> * Package = an ordered list of related transactions, representable by
>>>>>> a Directed
>>>>>>   Acyclic Graph.
>>>>>> * Package Feerate = the total modified fees divided by the total
>>>>>> virtual size of
>>>>>>   all transactions in the package.
>>>>>>     - Modified fees = a transaction's base fees + fee delta applied
>>>>>> by the user
>>>>>>       with `prioritisetransaction`. As such, we expect this to vary
>>>>>> across
>>>>>> mempools.
>>>>>>     - Virtual Size = the maximum of virtual sizes calculated using
>>>>>> [BIP141
>>>>>>       virtual size][2] and sigop weight. [Implemented here in Bitcoin
>>>>>> Core][3].
>>>>>>     - Note that feerate is not necessarily based on the base fees and
>>>>>> serialized
>>>>>>       size.
>>>>>>
>>>>>> * Fee-Bumping = user/wallet actions that take advantage of miner
>>>>>> incentives to
>>>>>>   boost a transaction's candidacy for inclusion in a block, including
>>>>>> Child Pays
>>>>>> for Parent (CPFP) and [BIP125][12] Replace-by-Fee (RBF). Our
>>>>>> intention in
>>>>>> mempool policy is to recognize when the new transaction is more
>>>>>> economical to
>>>>>> mine than the original one(s) but not open DoS vectors, so there are
>>>>>> some
>>>>>> limitations.
>>>>>>
>>>>>> ### Policy
>>>>>>
>>>>>> The purpose of the mempool is to store the best (to be most
>>>>>> incentive-compatible
>>>>>> with miners, highest feerate) candidates for inclusion in a block.
>>>>>> Miners use
>>>>>> the mempool to build block templates. The mempool is also useful as a
>>>>>> cache for
>>>>>> boosting block relay and validation performance, aiding transaction
>>>>>> relay, and
>>>>>> generating feerate estimations.
>>>>>>
>>>>>> Ideally, all consensus-valid transactions paying reasonable fees
>>>>>> should make it
>>>>>> to miners through normal transaction relay, without any special
>>>>>> connectivity or
>>>>>> relationships with miners. On the other hand, nodes do not have
>>>>>> unlimited
>>>>>> resources, and a P2P network designed to let any honest node
>>>>>> broadcast their
>>>>>> transactions also exposes the transaction validation engine to DoS
>>>>>> attacks from
>>>>>> malicious peers.
>>>>>>
>>>>>> As such, for unconfirmed transactions we are considering for our
>>>>>> mempool, we
>>>>>> apply a set of validation rules in addition to consensus, primarily
>>>>>> to protect
>>>>>> us from resource exhaustion and aid our efforts to keep the highest
>>>>>> fee
>>>>>> transactions. We call this mempool _policy_: a set of (configurable,
>>>>>> node-specific) rules that transactions must abide by in order to be
>>>>>> accepted
>>>>>> into our mempool. Transaction "Standardness" rules and mempool
>>>>>> restrictions such
>>>>>> as "too-long-mempool-chain" are both examples of policy.
>>>>>>
>>>>>> ### Package Relay and Package Mempool Accept
>>>>>>
>>>>>> In transaction relay, we currently consider transactions one at a
>>>>>> time for
>>>>>> submission to the mempool. This creates a limitation in the node's
>>>>>> ability to
>>>>>> determine which transactions have the highest feerates, since we
>>>>>> cannot take
>>>>>> into account descendants (i.e. cannot use CPFP) until all the
>>>>>> transactions are
>>>>>> in the mempool. Similarly, we cannot use a transaction's descendants
>>>>>> when
>>>>>> considering it for RBF. When an individual transaction does not meet
>>>>>> the mempool
>>>>>> minimum feerate and the user isn't able to create a replacement
>>>>>> transaction
>>>>>> directly, it will not be accepted by mempools.
>>>>>>
>>>>>> This limitation presents a security issue for applications and users
>>>>>> relying on
>>>>>> time-sensitive transactions. For example, Lightning and other
>>>>>> protocols create
>>>>>> UTXOs with multiple spending paths, where one counterparty's spending
>>>>>> path opens
>>>>>> up after a timelock, and users are protected from cheating scenarios
>>>>>> as long as
>>>>>> they redeem on-chain in time. A key security assumption is that all
>>>>>> parties'
>>>>>> transactions will propagate and confirm in a timely manner. This
>>>>>> assumption can
>>>>>> be broken if fee-bumping does not work as intended.
>>>>>>
>>>>>> The end goal for Package Relay is to consider multiple transactions
>>>>>> at the same
>>>>>> time, e.g. a transaction with its high-fee child. This may help us
>>>>>> better
>>>>>> determine whether transactions should be accepted to our mempool,
>>>>>> especially if
>>>>>> they don't meet fee requirements individually or are better RBF
>>>>>> candidates as a
>>>>>> package. A combination of changes to mempool validation logic,
>>>>>> policy, and
>>>>>> transaction relay allows us to better propagate the transactions with
>>>>>> the
>>>>>> highest package feerates to miners, and makes fee-bumping tools more
>>>>>> powerful
>>>>>> for users.
>>>>>>
>>>>>> The "relay" part of Package Relay suggests P2P messaging changes, but
>>>>>> a large
>>>>>> part of the changes are in the mempool's package validation logic. We
>>>>>> call this
>>>>>> *Package Mempool Accept*.
>>>>>>
>>>>>> ### Previous Work
>>>>>>
>>>>>> * Given that mempool validation is DoS-sensitive and complex, it
>>>>>> would be
>>>>>>   dangerous to haphazardly tack on package validation logic. Many
>>>>>> efforts have
>>>>>> been made to make mempool validation less opaque (see [#16400][4],
>>>>>> [#21062][5],
>>>>>> [#22675][6], [#22796][7]).
>>>>>> * [#20833][8] Added basic capabilities for package validation, test
>>>>>> accepts only
>>>>>>   (no submission to mempool).
>>>>>> * [#21800][9] Implemented package ancestor/descendant limit checks
>>>>>> for arbitrary
>>>>>>   packages. Still test accepts only.
>>>>>> * Previous package relay proposals (see [#16401][10], [#19621][11]).
>>>>>>
>>>>>> ### Existing Package Rules
>>>>>>
>>>>>> These are in master as introduced in [#20833][8] and [#21800][9].
>>>>>> I'll consider
>>>>>> them as "given" in the rest of this document, though they can be
>>>>>> changed, since
>>>>>> package validation is test-accept only right now.
>>>>>>
>>>>>> 1. A package cannot exceed `MAX_PACKAGE_COUNT=25` count and
>>>>>> `MAX_PACKAGE_SIZE=101KvB` total size [8]
>>>>>>
>>>>>>    *Rationale*: This is already enforced as mempool
>>>>>> ancestor/descendant limits.
>>>>>> Presumably, transactions in a package are all related, so exceeding
>>>>>> this limit
>>>>>> would mean that the package can either be split up or it wouldn't
>>>>>> pass this
>>>>>> mempool policy.
>>>>>>
>>>>>> 2. Packages must be topologically sorted: if any dependencies exist
>>>>>> between
>>>>>> transactions, parents must appear somewhere before children. [8]
>>>>>>
>>>>>> 3. A package cannot have conflicting transactions, i.e. none of them
>>>>>> can spend
>>>>>> the same inputs. This also means there cannot be duplicate
>>>>>> transactions. [8]
>>>>>>
>>>>>> 4. When packages are evaluated against ancestor/descendant limits in
>>>>>> a test
>>>>>> accept, the union of all of their descendants and ancestors is
>>>>>> considered. This
>>>>>> is essentially a "worst case" heuristic where every transaction in
>>>>>> the package
>>>>>> is treated as each other's ancestor and descendant. [8]
>>>>>> Packages for which ancestor/descendant limits are accurately captured
>>>>>> by this
>>>>>> heuristic: [19]
>>>>>>
>>>>>> There are also limitations such as the fact that CPFP carve out is
>>>>>> not applied
>>>>>> to package transactions. #20833 also disables RBF in package
>>>>>> validation; this
>>>>>> proposal overrides that to allow packages to use RBF.
>>>>>>
>>>>>> ## Proposed Changes
>>>>>>
>>>>>> The next step in the Package Mempool Accept project is to implement
>>>>>> submission
>>>>>> to mempool, initially through RPC only. This allows us to test the
>>>>>> submission
>>>>>> logic before exposing it on P2P.
>>>>>>
>>>>>> ### Summary
>>>>>>
>>>>>> - Packages may contain already-in-mempool transactions.
>>>>>> - Packages are 2 generations, Multi-Parent-1-Child.
>>>>>> - Fee-related checks use the package feerate. This means that wallets
>>>>>> can
>>>>>> create a package that utilizes CPFP.
>>>>>> - Parents are allowed to RBF mempool transactions with a set of rules
>>>>>> similar
>>>>>>   to BIP125. This enables a combination of CPFP and RBF, where a
>>>>>> transaction's descendant fees pay for replacing mempool conflicts.
>>>>>>
>>>>>> There is a draft implementation in [#22290][1]. It is WIP, but
>>>>>> feedback is
>>>>>> always welcome.
>>>>>>
>>>>>> ### Details
>>>>>>
>>>>>> #### Packages May Contain Already-in-Mempool Transactions
>>>>>>
>>>>>> A package may contain transactions that are already in the mempool.
>>>>>> We remove
>>>>>> ("deduplicate") those transactions from the package for the purposes
>>>>>> of package
>>>>>> mempool acceptance. If a package is empty after deduplication, we do
>>>>>> nothing.
>>>>>>
>>>>>> *Rationale*: Mempools vary across the network. It's possible for a
>>>>>> parent to be
>>>>>> accepted to the mempool of a peer on its own due to differences in
>>>>>> policy and
>>>>>> fee market fluctuations. We should not reject or penalize the entire
>>>>>> package for
>>>>>> an individual transaction as that could be a censorship vector.
>>>>>>
>>>>>> #### Packages Are Multi-Parent-1-Child
>>>>>>
>>>>>> Only packages of a specific topology are permitted. Namely, a package
>>>>>> is exactly
>>>>>> 1 child with all of its unconfirmed parents. After deduplication, the
>>>>>> package
>>>>>> may be exactly the same, empty, 1 child, 1 child with just some of its
>>>>>> unconfirmed parents, etc. Note that it's possible for the parents to
>>>>>> be indirect
>>>>>> descendants/ancestors of one another, or for parent and child to
>>>>>> share a parent,
>>>>>> so we cannot make any other topology assumptions.
>>>>>>
>>>>>> *Rationale*: This allows for fee-bumping by CPFP. Allowing multiple
>>>>>> parents
>>>>>> makes it possible to fee-bump a batch of transactions. Restricting
>>>>>> packages to a
>>>>>> defined topology is also easier to reason about and simplifies the
>>>>>> validation
>>>>>> logic greatly. Multi-parent-1-child allows us to think of the package
>>>>>> as one big
>>>>>> transaction, where:
>>>>>>
>>>>>> - Inputs = all the inputs of parents + inputs of the child that come
>>>>>> from
>>>>>>   confirmed UTXOs
>>>>>> - Outputs = all the outputs of the child + all outputs of the parents
>>>>>> that
>>>>>>   aren't spent by other transactions in the package
>>>>>>
>>>>>> Examples of packages that follow this rule (variations of example A
>>>>>> show some
>>>>>> possibilities after deduplication): ![image][15]
>>>>>>
>>>>>> #### Fee-Related Checks Use Package Feerate
>>>>>>
>>>>>> Package Feerate = the total modified fees divided by the total
>>>>>> virtual size of
>>>>>> all transactions in the package.
>>>>>>
>>>>>> To meet the two feerate requirements of a mempool, i.e., the
>>>>>> pre-configured
>>>>>> minimum relay feerate (`minRelayTxFee`) and dynamic mempool minimum
>>>>>> feerate, the
>>>>>> total package feerate is used instead of the individual feerate. The
>>>>>> individual
>>>>>> transactions are allowed to be below feerate requirements if the
>>>>>> package meets
>>>>>> the feerate requirements. For example, the parent(s) in the package
>>>>>> can have 0
>>>>>> fees but be paid for by the child.
>>>>>>
>>>>>> *Rationale*: This can be thought of as "CPFP within a package,"
>>>>>> solving the
>>>>>> issue of a parent not meeting minimum fees on its own. This allows L2
>>>>>> applications to adjust their fees at broadcast time instead of
>>>>>> overshooting or
>>>>>> risking getting stuck/pinned.
>>>>>>
>>>>>> We use the package feerate of the package *after deduplication*.
>>>>>>
>>>>>> *Rationale*:  It would be incorrect to use the fees of transactions
>>>>>> that are
>>>>>> already in the mempool, as we do not want a transaction's fees to be
>>>>>> double-counted for both its individual RBF and package RBF.
>>>>>>
>>>>>> Examples F and G [14] show the same package, but P1 is submitted
>>>>>> individually before
>>>>>> the package in example G. In example F, we can see that the 300vB
>>>>>> package pays
>>>>>> an additional 200sat in fees, which is not enough to pay for its own
>>>>>> bandwidth
>>>>>> (BIP125#4). In example G, we can see that P1 pays enough to replace
>>>>>> M1, but
>>>>>> using P1's fees again during package submission would make it look
>>>>>> like a 300sat
>>>>>> increase for a 200vB package. Even including its fees and size would
>>>>>> not be
>>>>>> sufficient in this example, since the 300sat looks like enough for
>>>>>> the 300vB
>>>>>> package. The calculcation after deduplication is 100sat increase for
>>>>>> a package
>>>>>> of size 200vB, which correctly fails BIP125#4. Assume all
>>>>>> transactions have a
>>>>>> size of 100vB.
>>>>>>
>>>>>> #### Package RBF
>>>>>>
>>>>>> If a package meets feerate requirements as a package, the parents in
>>>>>> the
>>>>>> transaction are allowed to replace-by-fee mempool transactions. The
>>>>>> child cannot
>>>>>> replace mempool transactions. Multiple transactions can replace the
>>>>>> same
>>>>>> transaction, but in order to be valid, none of the transactions can
>>>>>> try to
>>>>>> replace an ancestor of another transaction in the same package (which
>>>>>> would thus
>>>>>> make its inputs unavailable).
>>>>>>
>>>>>> *Rationale*: Even if we are using package feerate, a package will not
>>>>>> propagate
>>>>>> as intended if RBF still requires each individual transaction to meet
>>>>>> the
>>>>>> feerate requirements.
>>>>>>
>>>>>> We use a set of rules slightly modified from BIP125 as follows:
>>>>>>
>>>>>> ##### Signaling (Rule #1)
>>>>>>
>>>>>> All mempool transactions to be replaced must signal replaceability.
>>>>>>
>>>>>> *Rationale*: Package RBF signaling logic should be the same for
>>>>>> package RBF and
>>>>>> single transaction acceptance. This would be updated if single
>>>>>> transaction
>>>>>> validation moves to full RBF.
>>>>>>
>>>>>> ##### New Unconfirmed Inputs (Rule #2)
>>>>>>
>>>>>> A package may include new unconfirmed inputs, but the ancestor
>>>>>> feerate of the
>>>>>> child must be at least as high as the ancestor feerates of every
>>>>>> transaction
>>>>>> being replaced. This is contrary to BIP125#2, which states "The
>>>>>> replacement
>>>>>> transaction may only include an unconfirmed input if that input was
>>>>>> included in
>>>>>> one of the original transactions. (An unconfirmed input spends an
>>>>>> output from a
>>>>>> currently-unconfirmed transaction.)"
>>>>>>
>>>>>> *Rationale*: The purpose of BIP125#2 is to ensure that the replacement
>>>>>> transaction has a higher ancestor score than the original
>>>>>> transaction(s) (see
>>>>>> [comment][13]). Example H [16] shows how adding a new unconfirmed
>>>>>> input can lower the
>>>>>> ancestor score of the replacement transaction. P1 is trying to
>>>>>> replace M1, and
>>>>>> spends an unconfirmed output of M2. P1 pays 800sat, M1 pays 600sat,
>>>>>> and M2 pays
>>>>>> 100sat. Assume all transactions have a size of 100vB. While, in
>>>>>> isolation, P1
>>>>>> looks like a better mining candidate than M1, it must be mined with
>>>>>> M2, so its
>>>>>> ancestor feerate is actually 4.5sat/vB.  This is lower than M1's
>>>>>> ancestor
>>>>>> feerate, which is 6sat/vB.
>>>>>>
>>>>>> In package RBF, the rule analogous to BIP125#2 would be "none of the
>>>>>> transactions in the package can spend new unconfirmed inputs."
>>>>>> Example J [17] shows
>>>>>> why, if any of the package transactions have ancestors, package
>>>>>> feerate is no
>>>>>> longer accurate. Even though M2 and M3 are not ancestors of P1 (which
>>>>>> is the
>>>>>> replacement transaction in an RBF), we're actually interested in the
>>>>>> entire
>>>>>> package. A miner should mine M1 which is 5sat/vB instead of M2, M3,
>>>>>> P1, P2, and
>>>>>> P3, which is only 4sat/vB. The Package RBF rule cannot be loosened to
>>>>>> only allow
>>>>>> the child to have new unconfirmed inputs, either, because it can
>>>>>> still cause us
>>>>>> to overestimate the package's ancestor score.
>>>>>>
>>>>>> However, enforcing a rule analogous to BIP125#2 would not only make
>>>>>> Package RBF
>>>>>> less useful, but would also break Package RBF for packages with
>>>>>> parents already
>>>>>> in the mempool: if a package parent has already been submitted, it
>>>>>> would look
>>>>>> like the child is spending a "new" unconfirmed input. In example K
>>>>>> [18], we're
>>>>>> looking to replace M1 with the entire package including P1, P2, and
>>>>>> P3. We must
>>>>>> consider the case where one of the parents is already in the mempool
>>>>>> (in this
>>>>>> case, P2), which means we must allow P3 to have new unconfirmed
>>>>>> inputs. However,
>>>>>> M2 lowers the ancestor score of P3 to 4.3sat/vB, so we should not
>>>>>> replace M1
>>>>>> with this package.
>>>>>>
>>>>>> Thus, the package RBF rule regarding new unconfirmed inputs is less
>>>>>> strict than
>>>>>> BIP125#2. However, we still achieve the same goal of requiring the
>>>>>> replacement
>>>>>> transactions to have a ancestor score at least as high as the
>>>>>> original ones. As
>>>>>> a result, the entire package is required to be a higher feerate
>>>>>> mining candidate
>>>>>> than each of the replaced transactions.
>>>>>>
>>>>>> Another note: the [comment][13] above the BIP125#2 code in the
>>>>>> original RBF
>>>>>> implementation suggests that the rule was intended to be temporary.
>>>>>>
>>>>>> ##### Absolute Fee (Rule #3)
>>>>>>
>>>>>> The package must increase the absolute fee of the mempool, i.e. the
>>>>>> total fees
>>>>>> of the package must be higher than the absolute fees of the mempool
>>>>>> transactions
>>>>>> it replaces. Combined with the CPFP rule above, this differs from
>>>>>> BIP125 Rule #3
>>>>>> - an individual transaction in the package may have lower fees than
>>>>>> the
>>>>>>   transaction(s) it is replacing. In fact, it may have 0 fees, and
>>>>>> the child
>>>>>> pays for RBF.
>>>>>>
>>>>>> ##### Feerate (Rule #4)
>>>>>>
>>>>>> The package must pay for its own bandwidth; the package feerate must
>>>>>> be higher
>>>>>> than the replaced transactions by at least minimum relay feerate
>>>>>> (`incrementalRelayFee`). Combined with the CPFP rule above, this
>>>>>> differs from
>>>>>> BIP125 Rule #4 - an individual transaction in the package can have a
>>>>>> lower
>>>>>> feerate than the transaction(s) it is replacing. In fact, it may have
>>>>>> 0 fees,
>>>>>> and the child pays for RBF.
>>>>>>
>>>>>> ##### Total Number of Replaced Transactions (Rule #5)
>>>>>>
>>>>>> The package cannot replace more than 100 mempool transactions. This
>>>>>> is identical
>>>>>> to BIP125 Rule #5.
>>>>>>
>>>>>> ### Expected FAQs
>>>>>>
>>>>>> 1. Is it possible for only some of the package to make it into the
>>>>>> mempool?
>>>>>>
>>>>>>    Yes, it is. However, since we evict transactions from the mempool
>>>>>> by
>>>>>> descendant score and the package child is supposed to be sponsoring
>>>>>> the fees of
>>>>>> its parents, the most common scenario would be all-or-nothing. This is
>>>>>> incentive-compatible. In fact, to be conservative, package validation
>>>>>> should
>>>>>> begin by trying to submit all of the transactions individually, and
>>>>>> only use the
>>>>>> package mempool acceptance logic if the parents fail due to low
>>>>>> feerate.
>>>>>>
>>>>>> 2. Should we allow packages to contain already-confirmed transactions?
>>>>>>
>>>>>>     No, for practical reasons. In mempool validation, we actually
>>>>>> aren't able to
>>>>>> tell with 100% confidence if we are looking at a transaction that has
>>>>>> already
>>>>>> confirmed, because we look up inputs using a UTXO set. If we have
>>>>>> historical
>>>>>> block data, it's possible to look for it, but this is inefficient,
>>>>>> not always
>>>>>> possible for pruning nodes, and unnecessary because we're not going
>>>>>> to do
>>>>>> anything with the transaction anyway. As such, we already have the
>>>>>> expectation
>>>>>> that transaction relay is somewhat "stateful" i.e. nobody should be
>>>>>> relaying
>>>>>> transactions that have already been confirmed. Similarly, we
>>>>>> shouldn't be
>>>>>> relaying packages that contain already-confirmed transactions.
>>>>>>
>>>>>> [1]: https://github.com/bitcoin/bitcoin/pull/22290
>>>>>> [2]:
>>>>>> https://github.com/bitcoin/bips/blob/1f0b563738199ca60d32b4ba779797fc97d040fe/bip-0141.mediawiki#transaction-size-calculations
>>>>>> [3]:
>>>>>> https://github.com/bitcoin/bitcoin/blob/94f83534e4b771944af7d9ed0f40746f392eb75e/src/policy/policy.cpp#L282
>>>>>> [4]: https://github.com/bitcoin/bitcoin/pull/16400
>>>>>> [5]: https://github.com/bitcoin/bitcoin/pull/21062
>>>>>> [6]: https://github.com/bitcoin/bitcoin/pull/22675
>>>>>> [7]: https://github.com/bitcoin/bitcoin/pull/22796
>>>>>> [8]: https://github.com/bitcoin/bitcoin/pull/20833
>>>>>> [9]: https://github.com/bitcoin/bitcoin/pull/21800
>>>>>> [10]: https://github.com/bitcoin/bitcoin/pull/16401
>>>>>> [11]: https://github.com/bitcoin/bitcoin/pull/19621
>>>>>> [12]: https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki
>>>>>> [13]:
>>>>>> https://github.com/bitcoin/bitcoin/pull/6871/files#diff-34d21af3c614ea3cee120df276c9c4ae95053830d7f1d3deaf009a4625409ad2R1101-R1104
>>>>>> [14]:
>>>>>> https://user-images.githubusercontent.com/25183001/133567078-075a971c-0619-4339-9168-b41fd2b90c28.png
>>>>>> [15]:
>>>>>> https://user-images.githubusercontent.com/25183001/132856734-fc17da75-f875-44bb-b954-cb7a1725cc0d.png
>>>>>> [16]:
>>>>>> https://user-images.githubusercontent.com/25183001/133567347-a3e2e4a8-ae9c-49f8-abb9-81e8e0aba224.png
>>>>>> [17]:
>>>>>> https://user-images.githubusercontent.com/25183001/133567370-21566d0e-36c8-4831-b1a8-706634540af3.png
>>>>>> [18]:
>>>>>> https://user-images.githubusercontent.com/25183001/133567444-bfff1142-439f-4547-800a-2ba2b0242bcb.png
>>>>>> [19]:
>>>>>> https://user-images.githubusercontent.com/25183001/133456219-0bb447cb-dcb4-4a31-b9c1-7d86205b68bc.png
>>>>>> [20]:
>>>>>> https://user-images.githubusercontent.com/25183001/132857787-7b7c6f56-af96-44c8-8d78-983719888c19.png
>>>>>> _______________________________________________
>>>>>> bitcoin-dev mailing list
>>>>>> bitcoin-dev@lists•linuxfoundation.org
>>>>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>>>>>
>>>>>

[-- Attachment #2: Type: text/html, Size: 33705 bytes --]

      reply	other threads:[~2021-09-22 13:26 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-16  7:51 Gloria Zhao
2021-09-19 23:16 ` Antoine Riard
2021-09-20 15:10   ` Gloria Zhao
2021-09-23  4:29     ` Antoine Riard
2021-09-23 15:36       ` Gloria Zhao
2021-09-26 21:10         ` Antoine Riard
2021-09-27  7:15           ` Bastien TEINTURIER
2021-09-28 22:59             ` Antoine Riard
2021-09-29 11:56               ` Gloria Zhao
2021-10-14 10:48         ` darosior
2021-09-20  9:19 ` Bastien TEINTURIER
2021-09-21 11:18   ` Gloria Zhao
2021-09-21 15:18     ` Bastien TEINTURIER
2021-09-21 16:42       ` Gloria Zhao
2021-09-22  7:10         ` Bastien TEINTURIER
2021-09-22 13:26           ` Gloria Zhao [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFXO6=KYYEB9gYMYsHPyxNLbzGB12+XHrX_NbfNoUuFtJjpXgw@mail.gmail.com' \
    --to=gloriajzhao@gmail$(echo .)com \
    --cc=bastien@acinq$(echo .)fr \
    --cc=bitcoin-dev@lists$(echo .)linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox