Hello devs, I've had this thought rattling around and thought it was worth putting to a wider audience since I haven't really seen it in other contexts. I've been working on eltoo designs for Elements and eventual inclusion into Bitcoin. With that in mind there's been a reasonable amount of discussion on the remaining unknowns on how well eltoo could work. To me the biggest issue is BIP125 rule#3. To quote:"The replacement transaction pays an absolute fee of at least the sum paid by the original transactions." In the ANYONECANPAY-like scenarios like eltoo that require "bring your own fees", this essentially means the counterparty(or anyone, if you don't include chaperone sigs[0]) can post a series of low feerate update transactions, or the final update, with bloated inputs/outputs(depending on flags), and this results in illicit HTLC timeouts as the channel is unable to be settled in time, unless you fork over quite a few sats. This is a problem in both "vanilla" eltoo[1] from the original paper, as well as the "layered commitments" style of eltoo[2]. This problem is highly reminiscent of the ANYONECANPAY pinning that others have discussed for vaults and other usecases, in that anyone can include new inputs(and sometimes outputs) to make the overall feerate lower. To promptly get the final transactions settled, you are forced to over-pay, and essentially refund your griefing counterparty by knocking their inputs out of the mempool. Fixing BIP125 rule#3 would be great. It's also a while out at a minimum. There are thoughts on how to mitigate some cases[3] of this pinning using policy, and could be extended to cover this particular pinning case(restrict both transaction weight AND the weight of the descendant package, or maybe just include the txns weight in the original idea?). This might be the simplest idea, if it ends up being deemed incentive compatible and deployed. In case the above is not incentive compatible, we can use more drastic measures. Another tactic would be to use transaction introspection opcodes to smooth around these policy issues. Elements has its own set of transaction introspection codes[4], but fairly standard introspection codes seem to be sufficient. This example is using Rusty's quite recent OP_TX proposal[5] with a single extension but as mentioned before it's all fairly standard. The actual eltoo-enabling opcode implementation is basically orthogonal to this problem, so I'm simply focusing on restricting the size of the transaction package being submitted to mempools. For simplicity of a working example, we'll assume a set of "state" outputs that are continuously being spent off-chain and sent to a committed set of outputs. In vanilla eltoo case this corresponds to the first input and output you typically see in diagrams. The state transitions include no fees themselves, sending inputs of sum value N to outputs that sum to the value of N. Vanilla eltoo uses SIGHASH_SINGLE to bind just the first input/ouput pair. To post on-chain, we will need to include at least one input, and likely an output for change. We add OPTX_SELECT_WEIGHT(pushes tx weight to stack, my addition to the proposal) to the "state" input's script. This is used in the update transaction to set the upper bound on the final transaction weight. In this same input, for each contract participant, we also conditionally commit to the change output's scriptpubkey via OPTX_SELECT_OUTPUT_SCRIPTPUBKEY and OPTX_SELECT_OUTPUTCOUNT==2. This means any participant can send change back to themselves, but with a catch. Each change output script possibility in that state input also includes a 1 block CSV to avoid mempool spending to reintroduce pinning. This allows the change value to be anything, contra to what SIGHASH_ALL would give you instead. With this setup, you can't CPFP-spend the fee change outputs you create, but you can RBF as much as you'd like by RBFing at higher feerates, using any number of inputs you'd like provided the total tx weight doesn't exceed the OPTX_SELECT_WEIGHT argument. With more engineering we can re-enable CPFP of this change output as well. Handwaves here, but we could encumber change outputs to either the aformentioned 1 block CSV encumbered outputs or one to another OPTX_SELECT_WEIGHT, recursively. This would allow each counterparty to CPFP N times, each transaction a maximum weight, and use the 1 block CSV as an "escape hatch" to get their fee output back out from the covenant structure. We could mix and match strategies here as well allowing bigger transactions at each step, or more steps. I suspect you'd want a single weight-bound CPFP that can later be RBF'd any number of times under this same weight limit. TL;DR: Mempool is hard, let's use transaction weight, output count, and output scriptpubkey, and ??? introspection to avoid solving life's hard problems. 0: https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-May/001994.html 1: https://blockstream.com/eltoo.pdf 2: https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-January/002448.html 3: https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff?permalink_comment_id=4058140#gistcomment-4058140 4: https://github.com/ElementsProject/elements/blob/master/doc/tapscript_opcodes.md 5: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-May/020450.html