Return-Path: Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 7B86AC0001 for ; Fri, 28 May 2021 04:14:01 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 626C6843D3 for ; Fri, 28 May 2021 04:14:01 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org X-Spam-Flag: NO X-Spam-Score: -2.098 X-Spam-Level: X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no Authentication-Results: smtp1.osuosl.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xTUF9DdYKn3K for ; Fri, 28 May 2021 04:14:00 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by smtp1.osuosl.org (Postfix) with ESMTPS id C7C18843D0 for ; Fri, 28 May 2021 04:13:59 +0000 (UTC) Received: by mail-wr1-x42a.google.com with SMTP id m18so1902793wrv.2 for ; Thu, 27 May 2021 21:13:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=k//nGKHid7ETyUubvKYhrw0yANTIdHD5NN9YAVvr2rc=; b=lrNBEwmebKhD2oFj40Wa1cY0Hk/caTzv3lEdRpCHaNcPuUNrYpgrgy8tIpMBcDRWGR gB6953m7ntGZ8XB2azcQnGQo1cM79rge2gzjl2kQV75ikZpQ/+ePTbr0tk5ptU3J4p3K RN78h4H9so9R7FoTzCn8DBb04JJYSeV9tVAzwC2HqywZx02vQXylEA3lcfrx1zoWNCqy 1wawvrS2jjbHTwz1+Hz+FkAvOn0Y3v4WIgE9KESMIQcdZ/maFoVQlOcEa5iGMOMS7qYN iH2OEIocfHjdPcLhTcMemqSgaafbdyucBS7D9jbFXjKkNqS2vPixyojZcomowuwrFjUr bAqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=k//nGKHid7ETyUubvKYhrw0yANTIdHD5NN9YAVvr2rc=; b=OBKV/0UKS2TH2Tayvy873jS/pxkCgb1KvFcGPazIWordrkYgNsN1Q+3amfSaIhrmZy kGjOiNmFBZ/8pL19eTGwkmEhnV6PIwRirogapGiE0GySGDpPiQQaxOHrghVRuj3Y5qP0 x6O1M4ExKRowBTQpYlGRm6hYTiJCr7ZZmx3gsQVGl/2HRltrYNpNsAIQ8GU/7W2EUmG7 kudASv5iI/8RrqY7K1y6Vfv5/nigqYgnzyuc1zQfyTCu0Od5scZm3IhMOtFe5KyD+hs5 O7Sm8H6gvfwVJwhnagaU3axPCK+G6ehS21augPYjKI1TgS57yxUfYae3YlDdbArdLOYX Rkdw== X-Gm-Message-State: AOAM533PuYeziGK5aBu+L1Fx2ZVBq9TH0E/bcm/UpLij/M2VSk53bcyK W6juTBZntF/G0t4kE473774W2plCV9hvbvgybKo= X-Google-Smtp-Source: ABdhPJw9FiNUOvuCOj8coXf2u8yS6xYKtPepnA4IQTzKa1Xtm39LfVgzm6TY/fiDntMbX/X/AXjgdbQJwPb8VP12BEE= X-Received: by 2002:a05:6000:154c:: with SMTP id 12mr6673056wry.14.1622175237702; Thu, 27 May 2021 21:13:57 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Antoine Riard Date: Fri, 28 May 2021 00:13:44 -0400 Message-ID: To: darosior Content-Type: multipart/alternative; boundary="000000000000ce8a9505c35c1aa5" X-Mailman-Approved-At: Fri, 28 May 2021 14:35:38 +0000 Cc: Bitcoin Protocol Discussion Subject: Re: [bitcoin-dev] A Stroll through Fee-Bumping Techniques : Input-Based vs Child-Pay-For-Parent X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Bitcoin Protocol Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 May 2021 04:14:01 -0000 --000000000000ce8a9505c35c1aa5 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable > Unfortunately, ACP | SINGLE is trivially pinable [0] (TL;DR: i can just attach an output paying immediately to me, and construct a tx chain spending it). We are using ACP | ALL for Revault, > which is the reason why we need a well laid-out pool of fee-bumping UTXOs (as you need to consume them entirely). Oh yes, I should have mentioned this pinning vector. The witnessScript I've in mind to make secure that type of chain of transactions would be one MuSig key for all contract participants, where signature are committed with SIGHASH_ANYPREVOUT | SIGHASH_IOMAP, one pubkey per participant to lockdown the transaction with SIGHASH_ALL. I think it works and prevents malicious in-flight attachment of input/output to a multi-party transaction ? > I believe that it's better to broadcast a single fan-out transaction creating your entire UTXO pool in advance. You could create one coin per contract you are watching which value would be > used to bump your transaction feerate from the presigned one to -say- the average feerate over the past month, and then have smaller coins that you could attach to any transaction to bump > by a certain threshold (say, 10sat/vbyte). You would create as many small coin as your reserve algorithm tells you (which could be "i need to be able, worst case, to close all my contracts > with the worst historical feerate." or (fractional reserve version) "i need to be able, worst case, to close 10% of my contracts at the average feerate of the past year, the remaining ones sorry > for my loss"). [1] > This method is both much more optimal (though you need to sometimes incur the cost of many small additional inputs) and also makes sure that your feebump does not depend on the confirmation of a first stage transaction (as you can only RBF with new inputs if they are confirmed). I see, so you spread your bumping UTXO pool in two ranges : at least one bumping utxo per contract, and a subpool of emergency smaller coins, ready to be attached on any contract. I think this strategy makes sense for vaults as you can afford a bunch of small coins at different feerates, spending the ones not used afterwards. And higher cells of feerate reserve as the worst historical feerate are relatively not that much compared to locked-in vaults value. That said, I'm more dubious about LN, where node operators might not keep the worst-case fee-bumping reserve, as the time value of the coins aren't worth the channel liquidity at stake. > Why not just attaching it at the tail of the chain? Bumping the last child with additional input would effectively be a CPFP for the entire chain in this case. Yes, input-based bumping targeting the tail of the chain works at the transaction level. But if you assume bounded visibility of network mempools, one of your counterparties might have broadcast a concurrent state, thus making your CPFP irrelevant for propagation. Though smarter tx-relay techniques such as "attach-on-contract-utxo-root" CPFP (or also known as "blinded CPFP") might solve this issue. Le jeu. 27 mai 2021 =C3=A0 17:45, darosior a =C3= =A9crit : > Hi, > > ## Input-Based > > I think input-based fee-bumping has been less studied as fee-bumping > primitive for L2s [1]. One variant of input-based fee-bumping usable toda= y > is the leverage of the SIGHASH_ANYONECANPAY/SIGHASH_SINGLE malleability > flags. If the transaction is the latest stage of the contract, a bumping > input can be attached just-in-time, thus increasing the feerate of the > whole package. > > > Unfortunately, ACP | SINGLE is trivially pinable [0] (TL;DR: i can just > attach an output paying immediately to me, and construct a tx chain > spending it). We are using ACP | ALL for Revault, > which is the reason why we need a well laid-out pool of fee-bumping UTXOs > (as you need to consume them entirely). > > Input-based (today): If the bumping utxo is offering an adequate feerate > point in function of network mempools congestion at time of broadcast, on= ly > 1 input. If a preliminary fan-out transaction to adjust feerate point mus= t > be broadcasted first, 1 input and 2 outputs more must be accounted for. > Onchain footprint: 2 inputs + 3 outputs. > > > I believe that it's better to broadcast a single fan-out transaction > creating your entire UTXO pool in advance. You could create one coin per > contract you are watching which value would be > used to bump your transaction feerate from the presigned one to -say- the > average feerate over the past month, and then have smaller coins that you > could attach to any transaction to bump > by a certain threshold (say, 10sat/vbyte). You would create as many small > coin as your reserve algorithm tells you (which could be "i need to be > able, worst case, to close all my contracts > with the worst historical feerate." or (fractional reserve version) "i > need to be able, worst case, to close 10% of my contracts at the average > feerate of the past year, the remaining ones sorry > for my loss"). [1] > > This method is both much more optimal (though you need to sometimes incur > the cost of many small additional inputs) and also makes sure that your > feebump does not depend on the confirmation > of a first stage transaction (as you can only RBF with new inputs if they > are confirmed). > > Input-based (today): In case of rebroadcast, the fee-bumping input is > attached to the root of the chain of transactions and as such breaks the > chain validity in itself. Beyond the rebroadcast of the updated root unde= r > replacement policy, the remaining transactions must be updated and > rebroadcast. Rebroadcast footprint: the whole chain of transactions. > > > Why not just attaching it at the tail of the chain? Bumping the last chil= d > with additional input would effectively be a CPFP for the entire chain in > this case. > > > Thanks for starting this discussion :) > Antoine > > [0] > https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-May/017835.h= tml > [1] Credits to Jacob Swambo, who came up with the single fan-out > transaction and with whom i'm discussing how to practically apply these > ideas to Revault. > --000000000000ce8a9505c35c1aa5 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
> Unfortunately, ACP | SINGLE is trivially pinable [0] = (TL;DR: i can just attach an output paying immediately to me, and construct= a tx chain spending it). We are using ACP | ALL for Revault,
> which= is the reason why we need a well laid-out pool of fee-bumping UTXOs (as yo= u need to consume them entirely).

Oh yes, I should have mentioned th= is pinning vector. The witnessScript I've in mind to make secure that t= ype of chain of transactions would be one MuSig key for all contract partic= ipants, where signature are committed with SIGHASH_ANYPREVOUT | SIGHASH_IOM= AP, one pubkey per participant to lockdown the transaction with SIGHASH_ALL= . I think it works and prevents malicious in-flight attachment of input/out= put to a multi-party transaction ?

> I believe that it's bett= er to broadcast a single fan-out transaction creating your entire UTXO pool= in advance. You could create one coin per contract you are watching which = value would be
> used to bump your transaction feerate from the presi= gned one to -say- the average feerate over the past month, and then have sm= aller coins that you could attach to any transaction to bump
> by a c= ertain threshold (say, 10sat/vbyte). You would create as many small coin as= your reserve algorithm tells you (which could be "i need to be able, = worst case, to close all my contracts
> with the worst historical fee= rate." or (fractional reserve version) "i need to be able, worst = case, to close 10% of my contracts at the average feerate of the past year,= the remaining ones sorry
> for my loss"). [1]

> This = method is both much more optimal (though you need to sometimes incur the co= st of many small additional inputs) and also makes sure that your feebump d= oes not depend on the confirmation of a first stage transaction (as you can= only RBF with new inputs if they are confirmed).

I see, so you spre= ad your bumping UTXO pool in two ranges : at least one bumping utxo per con= tract, and a subpool of emergency smaller coins, ready to be attached on an= y contract. I think this strategy makes sense for vaults as you can afford = a bunch of small coins at different feerates, spending the ones not used af= terwards. And higher cells of feerate reserve as the worst historical feera= te are relatively not that much compared to locked-in vaults value. That sa= id, I'm more dubious about LN, where node operators might not keep the = worst-case fee-bumping reserve, as the time value of the coins aren't w= orth the channel liquidity at stake.
=C2=A0
> Why not just attachi= ng it at the tail of the chain? Bumping the last child with additional inpu= t would effectively be a CPFP for the entire chain in this case.

Yes= , input-based bumping targeting the tail of the chain works at the transact= ion level. But if you assume bounded visibility of network mempools, one of= your counterparties might have broadcast a concurrent state, thus making y= our CPFP irrelevant for propagation. Though smarter tx-relay techniques suc= h as "attach-on-contract-utxo-root" CPFP (or also known as "= blinded CPFP") might solve this issue.

Le=C2=A0jeu. 27 mai 2021 =C3= =A0=C2=A017:45, darosior <dar= osior@protonmail.com> a =C3=A9crit=C2=A0:
Hi,

## Input-Based

I think input-based fee-bumping has been less studied as fee-bumpin= g primitive for L2s [1]. One variant of input-based fee-bumping usable toda= y is the leverage of the SIGHASH_ANYONECANPAY/SIGHASH_SINGLE malleability f= lags. If the transaction is the latest stage of the contract, a bumping inp= ut can be attached just-in-time, thus increasing the feerate of the whole p= ackage.

Unfortunately,= ACP | SINGLE is trivially pinable [0] (TL;DR: i can just attach an output = paying immediately to me, and construct a tx chain spending it). We are usi= ng ACP | ALL for Revault,
which is the reason why we need a well laid-ou= t pool of fee-bumping UTXOs (as you need to consume them entirely).

Inpu= t-based (today): If the bumping utxo is offering an adequate feerate point = in function of network mempools congestion at time of broadcast, only 1 inp= ut. If a preliminary fan-out transaction to adjust feerate point must be br= oadcasted first, 1 input and 2 outputs more must be accounted for. Onchain = footprint: 2 inputs + 3 outputs.

I believe that it's better to broadcast a single fan-out transact= ion creating your entire UTXO pool in advance. You could create one coin pe= r contract you are watching which value would be
used to bump your trans= action feerate from the presigned one to -say- the average feerate over the= past month, and then have smaller coins that you could attach to any trans= action to bump
by a certain threshold (say, 10sat/vbyte). You would crea= te as many small coin as your reserve algorithm tells you (which could be &= quot;i need to be able, worst case, to close all my contracts
with the w= orst historical feerate." or (fractional reserve version) "i need= to be able, worst case, to close 10% of my contracts at the average feerat= e of the past year, the remaining ones sorry
for my loss"). [1]
=

This method is both much more optimal (though you= need to sometimes incur the cost of many small additional inputs) and also= makes sure that your feebump does not depend on the confirmation
of a f= irst stage transaction (as you can only RBF with new inputs if they are con= firmed).

Input-based (today): In case of rebroadcast, the fee-bumping input is= attached to the root of the chain of transactions and as such breaks the c= hain validity in itself. Beyond the rebroadcast of the updated root under r= eplacement policy, the remaining transactions must be updated and rebroadca= st. Rebroadcast footprint: the whole chain of transactions.
=

Why not just attaching it at the tail of t= he chain? Bumping the last child with additional input would effectively be= a CPFP for the entire chain in this case.

Thanks for starting this discussion :)
Antoine

[1] Credits to Jacob Swambo, who came up with the single= fan-out transaction and with whom i'm discussing how to practically ap= ply these ideas to Revault.
--000000000000ce8a9505c35c1aa5--