Re: [bitcoin-dev] TAPLEAF_UPDATE_VERIFY covenant opcode
Hi AJ, Happy to see that this proposal has finally seen the light of day! I've been hearing about it in hinted background convos over the past few months, so happy I can finally dig into the specifics of its operation. > So the idea is to do just that via a new opcode "TAPLEAF_UPDATE_VERIFY" > (TLUV) that takes three inputs: one that specifies how to update the > internal public key (X), one that specifies a new step for the merkle path > (F), and one that specifies whether to remove the current script and/or > how many merkle path steps to remove What if instead, it obtained the script from the _annex_? I think this small modification would make the op code even _more_ powerful. Consider that this allows a new script to be passed _dynamically_ after the output has been created, possibly by a threshold of parties that control the output, or them all (mu sig, etc, etc). This serves to create a generic "upgrade" mechanism for any tapscript output (covenant or not). Functionally, this is similar to the existence of "admin keys" or voted DAO upgrades that exists in chains that utilize an account based systems. This is really useful as it allows a script any given output to optional add in graftroot like behavior (leaf in tree that accepts script updates), and also allows contract developers to progressively upgrade or fix issues in prior versions of their deployed contracts. This little trick is secure since unlike the witness itself, the annex is actually _signed_ within the sighash like everything else. Incorporating this proposal would require the addition of an OP_PUSH_ANNEX op code, which by itself seems expertly useful. If one views the annex as a sort of authenticated associated data that can be passed into the script execution context, then this actually serves to absorb _some_ uses cases of a hypothetical OP_CHECKSIG_FROM_STACK opcode. A push annex op code also makes doing things like output delegation to a given key passed into the witness secure since the prior "owner" of the output commits to the key within the sighash. Even assuming a more powerful type of covenant that allows partial application of binding logic, something like this is still super useful since the action of re-creating a new tapscript tree based in dynamic input data would generate a rather large witness if only something like OP_CAT was available. The unique "update" nature of this appears to augment any other type of covenant, which is pretty cool. Consider that it would allow you (with the annex addition above), take something like a CTV congestion tree, and add in _new_ users at the tree is already being unrolled (just a toy example). It would also allow an individual to _join_ the payment pool construct described earlier which makes it 1000x more useful (vs just supporting unrolling). I haven't written it all down yet, but I think this along with something like CTV or CSFS makes it possible to implement a Plasma Cash [4] like Commit Chain [5], which is super exciting (assume a counter is embedded in the main script that tracks the next free leaf slot(s). With this model an "operator" is able to include a single transaction in the chain that stamps a batch of updates in the payment tree. Users then get a contestation period where they can refute a modification to the tree in order to withdraw their funds. > And second, it doesn't provide a way for utxos to "interact", This is due to the fact that the op code doesn't allow any sort of late binding or pattern matching then constraining _where_ (or whence?) the coins can Be sent to. There's a group of developers that are attempting to make an AMM-like system on Liquid [1] using more generic stack based covenants [2] (see the `OP_INSPECTINPUT` op code, which seems very much inspired by jl2012's old proposal). However one challenge that still need to be tackled in the UTXO model is allowing multiple participants to easily interact w/ the contract in a single block w/o a coordination layer to synchronize the access. One solution to this concurrency issue, that I believe is already employed by Chia is to allow "contracts" to be identified via a fixed ID (as long as their active in the chain) [3]. This lets transactions spend/interact with a contract, without always needing to know the set of active UTXOs where that contract lives. Transactions then specify their contract and "regular" inputs, with the requirement that every transaction spends at least a single regular input. The trade-off here is that nodes need to maintain this extra index into the UTXO set. However, this can be alleviated by applying a utreexo like solution: nodes maintain some merklized data structure over the index and require that spending transactions provide an _inclusion_ proof of the active contract. Nodes then only need to maintain root hashes of the UTXO and contract set. I'm super happy w.r.t how the covenant space has been processing over the past few years. IMO its the single most
Re: [bitcoin-dev] Proposal: Package Mempool Accept and Package RBF
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 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 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 >> 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 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
Re: [bitcoin-dev] Proposal: Package Mempool Accept and Package RBF
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 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 > 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 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 >>> wrote: >>> Hi Gloria, Thanks for this detailed
Re: [bitcoin-dev] TAPLEAF_UPDATE_VERIFY covenant opcode
> Hmm, I'm reading C5 as "If an oracle says X, and Alice and Carol agree, > they can distribute all the remaining funds as they see fit". Should be read as an OR: IF 2 2 CHECKMULTISIG ELSE 2 2 CHECKMULTISIG ENDIF <> 2 IN_OUT_AMOUNT The empty vector is a wildcard on the spent amount, as this tapscript may be executed before/ after the split or any withdraw option. > (Relative timelocks would probably be annoying for everyone who wasn't > the first to exit the pool) And I think unsafe, if you're wrapping a time-sensitive output in your withdraw scriptPubkey. > I think the above fixes that -- when AB is spent it deletes itself and > the (A,B) pair; when A is spent, it deletes (A, B and AB) and replaces > them with B'; when B' is spent it just deletes itself. Right, here the subtlety in reading the scripts is about the B' substitution tapscript in the A one. And it sounds correct to me that AB exercise deletes the withdraw pair (A, B). Le lun. 20 sept. 2021 à 10:52, Anthony Towns a écrit : > On Sat, Sep 18, 2021 at 10:11:10AM -0400, Antoine Riard wrote: > > I think one design advantage of combining scope-minimal opcodes like > MERKLESUB > > with sighash malleability is the ability to update a subset of the > off-chain > > contract transactions fields after the funding phase. > > Note that it's not "update" so much as "add to"; and I mostly think > graftroot (and friends), or just updating the utxo onchain, are a better > general purpose way of doing that. It's definitely a tradeoff though. > > > Yes this is a different contract policy that I would like to set up. > > Let's say you would like to express the following set of capabilities. > > C0="Split the 4 BTC funds between Alice/Bob and Caroll/Dave" > > C1="Alice can withdraw 1 BTC after 2 weeks" > > C2="Bob can withdraw 1 BTC after 2 weeks" > > C3="Caroll can withdraw 1 BTC after 2 weeks" > > C4="Dave can withdraw 1 BTC after 2 weeks" > > C5="If USDT price=X, Alice can withdraw 2 BTC or Caroll can withdraw 2 > BTC" > > Hmm, I'm reading C5 as "If an oracle says X, and Alice and Carol agree, > they can distribute all the remaining funds as they see fit". > > > If C4 is exercised, to avoid trust in the remaining counterparty, both > Alice or > > Caroll should be able to conserve the C5 option, without relying on the > updated > > key path. > > > As you're saying, as we know the group in advance, one way to setup the > tree > > could be: > >(A, (B, C), BC), D), BCD), E, F), EF), G), EFG))) > > Make it: > > (((AB, (A,B)), (CD, (C,D))), ACO) > > AB = DROP DUP 0 6 TLUV CHECKSIGVERIFY IN_OUT_AMOUNT SUB 2BTC > LESSTHAN > CD = same but for carol+dave > A = DUP 10 TLUV CHECKSIGVERIFY IN_OUT_AMOUNT SUB 1BTC LESSTHAN > B' = DUP 0 2 TLUV CHECKSIGVERIFY IN_OUT_AMOUNT SUB 1BTC LESSTHAN > B,C,D = same as A but for bob, etc > A',C',D' = same as B' but for alice, etc > ACO = CHECKSIGVERIFY CHECKSIG > > Probably AB, CD, A..D, A'..D' all want a CLTV delay in there as well. > (Relative timelocks would probably be annoying for everyone who wasn't > the first to exit the pool) > > > Note, this solution isn't really satisfying as the G path isn't > neutralized on > > the Caroll/Dave fork and could be replayed by Alice or Bob... > > I think the above fixes that -- when AB is spent it deletes itself and > the (A,B) pair; when A is spent, it deletes (A, B and AB) and replaces > them with B'; when B' is spent it just deletes itself. > > Cheers, > aj > ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev