Hi James, I think everything except the hinted "withdrawal authorization" is spot on.
For withdrawal authorization, I think we'll have to go deeper into the TLUV direction as AJ suggested for at least a couple reasons: 1) You need the withdrawal authorization committed at deposit time 2) You need to make sure cheeky opcodes cannot be prepended to the script at spend time OP_FORWARD_LEAF_UPDATE(OP_FLU) seems to fit the bill, at the cost of maybe adding another opcode for "refunds" as he notes. Cheers, Greg On Mon, Mar 6, 2023 at 10:25 AM James O'Beirne <james.obei...@gmail.com> wrote: > I'm glad to see that Greg and AJ are forming a habit of hammering > this proposal into shape. Nice work fellas. > > To summarize: > > What Greg is proposing above is to in essence TLUV-ify this proposal. > > I.e. instead of relying on hashed commitments and recursive script > execution (e.g. <trigger-sPK-hash> + later presentation of preimage > script for execution), OP_VAULT would instead move through its > withdrawal process by swapping out tapleaf contents according to > specialized rules. If this is opaque (as it was to me), don't fret - > I'll describe it below in the "mechanics" section. > > > The benefits of this TLUVification are > > - we can avoid any nested/recursive script execution. I know the > recursive stuff rankles some greybeards even in spite of it being > bounded to a single call. I'm not sure I share the concern but > maintaining the status quo seems good. > > - the spec is easier to reason about, more or less. The opcodes > introduced don't have variadic witness requirements, and each opcode > is only consumed in a single way. > > - there's less general indirection. Instead of saying "okay, here's the > hash of the script I'm going to use to authorize trigger > transactions," we're just outright including the trigger auth script > in the tapleaf at the birth of the vault as regular 'ol script that is > evaluated before execution of the OP_VAULT instruction. > > Similarly, instead of relying on an implicit rule that an OP_VAULT can > be claimed by a recovery flow, we're relying on a specific tapleaf that > facilitates that recovery with OP_VAULT_RECOVER, described below. > > Basically, OP_VAULT would just be implemented in a way that feels > more native to Taproot primitives. > > Greg also introduces different opcodes to facilitate consistent > witness structure, rather than the variable ones we have now > since OP_VAULT and OP_UNVAULT can each be spent in two different > contexts. I've changed those a little here; instead of the three general > ones Greg gave, we whittled it down to two: OP_VAULT and > OP_VAULT_RECOVER. > > > So I think that, barring significant implementation complexity - which > I'll find out about soon and don't expect - this is a good change to the > proposal. As Greg noted, it doesn't really change anything about the > usage or expressiveness... other than the fact that, as a bonus, it > might allow an optional withdrawal authorization script (i.e. trigger > output => final target), which could be useful if e.g. some kind of > size-limiting opcode (e.g. OP_TX_MAXSIZE or something) came around in > the future as a kind of pinning fix. > > If that last bit lost you, don't worry - that is speculative, but the > point is that this rework composes well with other stuff. > > > # CTV use > > Another thing that has dawned on us is that we might as well just reuse > OP_CHECKTEMPLATEVERIFY for withdrawal target spends. Ben Carmen and > others realized early on that you can synthesize CTV-like behavior by > spending to a 0-delay OP_UNVAULT output, so something CTVish has always > implicitly been a part of the proposal. But CTV is better studied and > basically as simple as the OP_UNVAULT spend semantics, so the thought is > that we might as well reuse all the existing work (and scrutiny) from > CTV. > > As a concrete example, an issue with the existing proposal is that the > existing CTVish OP_UNVAULT behavior has txid malleability, since it > doesn't commit to nVersion or nLockTime or the input sequences. Using > CTV solves this issue. Otherwise we'd basically reinvent it - "something > something convergent evolution." > > I think this is a satisfying development, because there's clearly demand > for CTV use in other contexts (DLC efficiency, e.g.), and if it's > required behavior for practical vaults, I think pulling in the existing > BIP-119 that's been worked over for years reduces the conceptual > surface area added by OP_VAULT. > > > # New mechanics of the proposal > > So here I'm going to describe my rendering of Greg and AJ's suggestions. > > > ## Required opcodes > > - OP_VAULT: spent to trigger withdrawal > - OP_VAULT_RECOVER: spent to recover > - OP_CHECKTEMPLATEVERIFY: spent into final withdrawal target > > > Creating an initial deposit > --------------------------- > > For each vault, vaulted coins are spent to an output with the taproot > structure > > taproot(internal_key, {$recovery_leaf, $trigger_leaf, ...}) > > where > > internal_key = > unchanged from original proposal (some very safe recovery key) > > $recovery_leaf = > [<opt.> <recovery> <auth>] <recovery sPK hash> OP_VAULT_RECOVER > > $trigger_leaf = > <trigger> <auth> <script> <spend-delay> OP_VAULT > > ... = > other (optional) leaves in the taptree > > > Triggering a withdrawal request > ------------------------------- > > To trigger the start of the withdrawal process, an output of the above > form is spent with a witness that contains > > - Taproot control block pointing to $trigger_leaf. > - <trigger-vout-idx>, indicating the trigger output which must abide > by the rules given below. > > > ## Output structure > > taproot(internal_key, {$recovery_leaf, $expr_withdraw, ...}) > > where > > $recovery_leaf is preserved exactly > $expr_withdraw = > <spend-delay> OP_CSV OP_DROP <target-ctv-hash> OP_CTV > ... is preserved exactly > > > (Spoiler: note here that the only thing that is changing is > s/expr_trigger/expr_withdrawl/ from the initial vault ouput.) > > Of course $expr_withdraw *could* be prefixed by an optional "withdrawal > authorization" script, if some sensible use for that is found. > > The validation rules are essentially unchanged from the existing > proposal: > > - The total amount of all OP_VAULT inputs with matching $recovery_leaf > values must be reflected in output <trigger-vout-idx> > > - <trigger-vout-idx> must correspond to an output that is identical to > the input taptree but with the spent tapleaf (OP_VAULT) swapped out > for the timelocked CTV constructed using <target-ctv-hash> and > <spend-delay> as extracted from the spent tapleaf > - internal_key is preserved > - the whole rest of the taptree is preserved > - (this is what ensures the parameters of the vault are forwarded) > > All batching, fee management characteristics are the same. > > > Finalizing withdrawal > --------------------- > > Happens via script-path spend to $expr_withdraw, i.e. a timelocked > OP_CTV. > > > Recovery > -------- > > Can happen from any of the above outputs using the $recovery_leaf > script path in a way very similar to the existing OP_VAULT proposal. > > > --- > > To reiterate, all aspects of the existing OP_VAULT proposal are either > preserved or improved upon in terms of malleability reduction, > composability, and flexibility. So big thanks to AJ and Greg. > > I'll undertake implementing these changes in the coming days to verify > that they are, as expected, workable. > > James >
_______________________________________________ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev