V3 transactions were an answer to pinning that predates the practical idea of a totally ordered mempool. Being unable to answer simple questions about allowable transactional topologies on the local mempool makes reasoning about safety of simple operations like transaction entry impossible. By restricting topologies of these kinds of transactions, it made it easier to reason about. In a post-cluster mempool world, with our ability to reason about things, it is worth a re-examination.
As a semi-sequel to priority transactions, this post explores possibilities for v3 and v3-like policies in a post-cluster mempool world. It tries to answer questions:
- How much can we remove the topology restrictions? Given the general resistance of people to concept ACK a specific transaction topology like V3, I was thinking it would be useful to think ahead and see what policy relaxations or restrictions we could enact in the future to make things more flexible, incentive compatible, and overall more useful, in a backwards compatible manner.
- What other rules can we add to express the intention of v3? If we think of this as a way for smart contracts to opt in to a set of policies where âIâm only going to {add, replace} transactions if itâs a fee-bump,â can we implement rules that are closer to that?
- After cluster mempool, how useful is v3? Will we regret having deployed v3 and its features, seeing it as a future maintenence burden?
TL;DR: V3 is useful and likely upgradeable to something more post-cluster mempool world in a backwards compatible way.
Definitions
âtop blockâ refers to whatever level we want. Using a cluster mempool we can check properties of incoming transactions such as: âchunk would enter the first or second block even if we estimate 10 minutes of additional inflowâ, or whatever statistical massaging we want to reduce pins, while not unduly impeding the ability for miners to have a backlog of transactions from which to mine in the short term.
âgoldfinger++â is the concept where an adversary either knows transactional load is incoming or induces a transaction load in the mempool, such that all the top-block-using transactions become buried on each other, and may be unable to reorder effectively due to incremental fee pinning induced by the attacker. Goldfinger attacks are not a new concept, and outside the scope of mempools to solve. The â++â is to indicate the additional pin vector which allows the attacker to possibly choose the order of the defendersâ time-sensitive transactions in the mempool, which may allow additional value extraction on top of a classical goldfinger attack where the defenders are at least able to reorder transactions respectful to the total funds at risk. I have no data or simulations on how much worse this is, but itâs worth noting as a possibility.
Ideas
All deployment ideas below are suggested paths that could be taken, with their benefits and drawbacks hopegully enumerated.
The future labels and version numbers came to me in a dream.
V3
- One parent, up to one <=1kvB child.
Pros:
- Trivially optimal sibling eviction due to reduced topology
- Itâs coded. Relatively simple. Doesnât require cluster mempool.
- Reduces max pinning ~100x, and package limit pinning for this topology.
- Requires fewer relay changes to fully use, like 1-parent-1-child(1p1c) relay
Cons:
- Not clearly incentive compatible: If weâre asking wallets to make structural changes beyond flipping a bit, is that too much?
- 1kvB is a guess on what size is required for a CPFP, so it leaves pinning potential along with the potential that itâs not even big enough for larger value bumps.
- Does not support batched CPFP.
- Does not fix ANYONCANPAY usage and other useful single tx RBF fee cases.
- Does not support chains of larger than two, such as 0-conf channel funding chains, or chains from presigned/CTV trees, two CPFPs of an anchor, etc.
As we can see, V3 leaves a lot to be desired, but can be done today with known pinning bounds.
V3.0.5
- Deploy V3.
- Deploy Cluster Mempool.
- Require âtop blockâ for V3 child (parent can still just hit minfee)
- Relax child size
Pros:
- Small leap from V3
- Allows wallets to not always shoot for top block, unless they need a CPFP
- Less/no more guesswork on CPFP size
- Maintains trivial sibling eviction
Cons:
- Same topologically based cons as V3.
- Additional size may allow for additional âgoldfinger attack++â damage.
This is both a tightening and relaxation of policy, which is arguably more incentive compatible, and blunts a lot of pinning attacks. Single transactions are allowed to relay at any feerate about minfee.
V3.1
- Deploy V3.
- Deploy Cluster Mempool.
- Require âtop blockâ for any cluster size of 2 or more
Pros:
- Relaxed topology allows anything normally representable, allowing for easier migration for wallet systems, provided they can be aggressive about fees when making size 2+ clusters.
- Multi-tx pin-resistant constructs possible.
- Still allows for less-fee-aggressive size 1 clusters that can be later bumped or batched in more fee-aggressive way in less adversarial settings.
- If the parent is 0-fee(and SIGHASH_ALL), itâs relatively pin resistant since getting CPFP into mempool requires top-block. Smart contracts can do less introspection of other peopleâs scripts.
Cons:
- Need to rethink V3 sibling eviction. With top block do we need it?
- Both endogenous and exogenous fee single transaction RBF transactions are not pin resistant in general. Parent contract can be inflated with 0-fee junk then put into the mempool just above minfee.
V4(a)
- To enter mempool the tx must be entering âtop blockâ.
- Cluster can only be <= X kvB
Pros:
- No topological restrictions, aside from lower bound in vbytes.
- ANYONECANPAY support. Endogenous and exogenous single tx RBF are pin resistant.
- Maybe less pinning potential from golfinger++ and fee spikes than default cluster size
- Limit could be expanded later with more research/reasoning (i.e. V4(b))
Cons:
- Need to rethink V3 sibling eviction. With top block do we need it?
- Limited vsize makes it cheaper to hit cluster size limits. Might want to think more about this.
- Size restriction may stop usage like LN commitment tx, ln-symmetry settlement tx, unless HTLC number restricted (though it looks like 10kvB would support almost 230 HTLCsâŚ)
- ânormalâ transactions wonât propagate unless theyâre top block.
- It might not be useful enough to get widespread usage from non-time sensitive usecases?
V4(b)
- To enter mempool the tx must be entering âtop blockâ.
Pros:
- Same as V4(a)
- Not much to bikeshed about.
- Easy to reason about under same cluster limits as mempool default.
Cons:
- ânormalâ transactions wonât propagate unless theyâre top block.
- It might not be useful enough to get widespread usage from non-time sensitive usecases?
V4(c)
Can we somehow unify the benefits of V3.1 and V4?
- V4(b), with two possible relaxations:
- if single tx and <= X vbytes, allow non-top block, or
- if chunk being added is <= X vbytes out of top block, allow
You can imagine X being something quite small, since rather than disallowing the transaction entirely, breaching the limit âmerelyâ requires the transaction to pay much more aggressive fees to be relayed.
Pros:
- V4(b), but allows more natural non-top block usage
- Allows more backlog to build. One opt-in policy to rule them all?
Cons:
- Reintroduces a less important bikeshed, and additional pin vector.
These are related ideas, with subtle differences, but fundamentally these are about allowing ânon-pinâ transactions to propagate without being top block, introducing minimal pinning risk alongside it.
This may allow more users to opt into this regime, build up more backlog, reducing the UX pain and incentive compatibility question of dropping low-feerate but small transactions.
The remaining use-cases for V3.1 style policy would essentially be consolidation transactions.
Some Possible Deployments
Here are some ideas on what path we could take. Aside from cluster mempool, there are no hard constraints on what has to be shipped in what order, almost any steps can be completely skipped. The most logical ordering will involve simple relaxations to relay rules.
flowchart TD
V3([V3]) -->|cpfp carveout maybe dead| C
C([Cluster mempool]):::required
C -.->|V3, but child top\nblock| V3.0.5([V3.0.5])
V3.0.5 -->|any topo,\nnon-single tx\ntop block| V3.1([V3.1])
C -->|small cluster,\ntop block\nonly| V4a([V4a])
V4a:::genvict -->|any vsize cluster| V4b([V4b]):::genvict
V3.1:::genvict -.->|topblockify single tx| V4b
V4b -->|<= X vbytes\nnon-top block| V4c([V4c]):::genvict
Tx([No V3 style sibling eviction]):::genvict
classDef required fill:#aaaaaa
classDef genvict fill:#FF7F50