summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames O'Beirne <james.obeirne@gmail.com>2023-03-06 10:25:38 -0500
committerbitcoindev <bitcoindev@gnusha.org>2023-03-06 15:25:28 +0000
commite9c070ca6f2e75ea2b7dc837e88db1d8aabf0d9f (patch)
treefda4e4f9e37585c0126b6b9735d68ec2949934ff
parent8e0af098921f32d3f05b5bef21ba3355993034d5 (diff)
downloadpi-bitcoindev-e9c070ca6f2e75ea2b7dc837e88db1d8aabf0d9f.tar.gz
pi-bitcoindev-e9c070ca6f2e75ea2b7dc837e88db1d8aabf0d9f.zip
Re: [bitcoin-dev] BIP for OP_VAULT
-rw-r--r--f9/bd93c9694cf8d3333d877813a593c9fb15f993399
1 files changed, 399 insertions, 0 deletions
diff --git a/f9/bd93c9694cf8d3333d877813a593c9fb15f993 b/f9/bd93c9694cf8d3333d877813a593c9fb15f993
new file mode 100644
index 000000000..300d2cbd0
--- /dev/null
+++ b/f9/bd93c9694cf8d3333d877813a593c9fb15f993
@@ -0,0 +1,399 @@
+Return-Path: <james.obeirne@gmail.com>
+Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138])
+ by lists.linuxfoundation.org (Postfix) with ESMTP id ACCCCC0032
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Mon, 6 Mar 2023 15:25:28 +0000 (UTC)
+Received: from localhost (localhost [127.0.0.1])
+ by smtp1.osuosl.org (Postfix) with ESMTP id 851E981462
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Mon, 6 Mar 2023 15:25:28 +0000 (UTC)
+DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 851E981462
+Authentication-Results: smtp1.osuosl.org;
+ dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com
+ header.a=rsa-sha256 header.s=20210112 header.b=KEPCKUl9
+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
+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 b5I0JM_Mllvl
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Mon, 6 Mar 2023 15:25:27 +0000 (UTC)
+X-Greylist: whitelisted by SQLgrey-1.8.0
+DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 43E8B80E62
+Received: from mail-oa1-x32.google.com (mail-oa1-x32.google.com
+ [IPv6:2001:4860:4864:20::32])
+ by smtp1.osuosl.org (Postfix) with ESMTPS id 43E8B80E62
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Mon, 6 Mar 2023 15:25:27 +0000 (UTC)
+Received: by mail-oa1-x32.google.com with SMTP id
+ 586e51a60fabf-176b90e14a9so4119271fac.9
+ for <bitcoin-dev@lists.linuxfoundation.org>;
+ Mon, 06 Mar 2023 07:25:27 -0800 (PST)
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+ d=gmail.com; s=20210112; t=1678116326;
+ h=cc:to:subject:message-id:date:from:in-reply-to:references
+ :mime-version:from:to:cc:subject:date:message-id:reply-to;
+ bh=+hl9viP1p2Zf/uWKlPYzMlAysuCRnem2npeV1du65QM=;
+ b=KEPCKUl9Cco2GR8odlZPaIQQ8uU2tZy2OZ1QiUtOQ4B17d0q0RIrDnFi2p1EJmASGB
+ 0rxk8+nklvP2f9N1beU5dT9850kKMQgrA3I4xcDkJr2TYzcB2GLZVDbLM+1S8K8412bX
+ ikXAdC91xv2JeiQSwrQm0lfhwOxWcsQJl+0g5cmfdD1aVJYrWrHwoP02SeC9raH6jx3C
+ VAdCbe+SvNc9mZNP95yov2uzNOyDlR1o5ztlClBu+SVSIsYsdjVFOdx5uzeG/dB3ZxxA
+ OEPzr87L4ChxwjR5Gblxmm7V5oXWIRt/3QZ9TAzy4ITQB4BO41Tjs3k163h3aFuyeJhU
+ uaRg==
+X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
+ d=1e100.net; s=20210112; t=1678116326;
+ h=cc:to:subject:message-id:date:from:in-reply-to:references
+ :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id
+ :reply-to;
+ bh=+hl9viP1p2Zf/uWKlPYzMlAysuCRnem2npeV1du65QM=;
+ b=HR3QBMPJ3OcgO83fht/lCi4knXWH390DHlHFEOF7SKxznDjTH33xSYpcDgUMAWlH4C
+ BKu3sA5Se7jKLfkxfIDzkbfElIhDeZYzbPmx/iqIiwQvRzBqX1YeN8eFXd2pr4jd5bwG
+ VI4k/f9sTuhEWUUTmIc8WNri3R/jtNQRn+a5XuMRM3TFjsKs/oIvjY+t8LTm1CMBL4Zu
+ Q3/8uDVPaCMN/EXnkkl5oEES9lwOnE7JYN0gQPF3xdbontJMQnqSvJ7mqiWSUE0sLRhm
+ DYErIm0yWTH1tpr6GuE355W2BwDF2TbRLqImTys1M5RJ/UUGpVIpS0OhnfywTUPX8leg
+ bSyw==
+X-Gm-Message-State: AO0yUKWsYJ57vc6/4dXnSJb9e5vNeNL2BSjaMJDrevIkxOiYHVWtcJmQ
+ L7pJJFg9J2O+waZhrAte8dC17UUq+qSlf1lvJJt8wbq/SME=
+X-Google-Smtp-Source: AK7set/pwvCba69KSbH2NMM65FyKfTbM6y47iM34imCKmQmBc4cawaMgAT4V66M55zJ7NSNtJf5xvHBYHMR5rePGDtg=
+X-Received: by 2002:a05:6871:4495:b0:176:3e22:3f99 with SMTP id
+ ne21-20020a056871449500b001763e223f99mr7181248oab.2.1678116326028; Mon, 06
+ Mar 2023 07:25:26 -0800 (PST)
+MIME-Version: 1.0
+References: <CAPfvXfJQKb7i8GBvTEvTTz-3dU_5mH8jOv8Nm4Q8gPt=KxrqLQ@mail.gmail.com>
+ <CAB3F3DveCDz6yy-rd3ttV8+4sMufsvB+9J-qVK95yh9aLYX+Mw@mail.gmail.com>
+ <ZAAqIZZO1KK32Th9@erisian.com.au>
+ <CAB3F3DtGpVHkyT_=KLS42rvdP=dgnMvChhR1Rs0BHO5yOEabmw@mail.gmail.com>
+In-Reply-To: <CAB3F3DtGpVHkyT_=KLS42rvdP=dgnMvChhR1Rs0BHO5yOEabmw@mail.gmail.com>
+From: "James O'Beirne" <james.obeirne@gmail.com>
+Date: Mon, 6 Mar 2023 10:25:38 -0500
+Message-ID: <CAPfvXf+4iX0h-nSuyTai_VvJHkDvAyKtgSk6DsaEwE8N3wnYEg@mail.gmail.com>
+To: Greg Sanders <gsanders87@gmail.com>
+Content-Type: multipart/alternative; boundary="000000000000813aec05f63ce78f"
+Cc: Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>,
+ Anthony Towns <aj@erisian.com.au>
+Subject: Re: [bitcoin-dev] BIP for OP_VAULT
+X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
+X-Mailman-Version: 2.1.15
+Precedence: list
+List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
+List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>,
+ <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
+List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
+List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
+List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
+List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>,
+ <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
+X-List-Received-Date: Mon, 06 Mar 2023 15:25:28 -0000
+
+--000000000000813aec05f63ce78f
+Content-Type: text/plain; charset="UTF-8"
+
+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
+
+--000000000000813aec05f63ce78f
+Content-Type: text/html; charset="UTF-8"
+Content-Transfer-Encoding: quoted-printable
+
+<div dir=3D"ltr"><div dir=3D"ltr">I&#39;m glad to see that Greg and AJ are =
+forming a habit of hammering=C2=A0</div><div dir=3D"ltr">this proposal into=
+ shape. Nice work fellas.<br><br>To summarize:<br><br>What Greg is proposin=
+g above is to in essence TLUV-ify this proposal.<br><br>I.e. instead of rel=
+ying on hashed commitments and recursive script<br>execution (e.g. &lt;trig=
+ger-sPK-hash&gt; + later presentation of preimage<br>script for execution),=
+ OP_VAULT would instead move through its<br>withdrawal process by swapping =
+out tapleaf contents according to<br>specialized rules. If this is opaque (=
+as it was to me), don&#39;t fret -<br>I&#39;ll describe it below in the &qu=
+ot;mechanics&quot; section.<br><br><br>The benefits of this TLUVification a=
+re<br><br>- we can avoid any nested/recursive script execution. I know the<=
+br>=C2=A0 recursive stuff rankles some greybeards even in spite of it being=
+<br>=C2=A0 bounded to a single call. I&#39;m not sure I share the concern b=
+ut <br>=C2=A0 maintaining the status quo seems good.<br><br>- the spec is e=
+asier to reason about, more or less. The opcodes<br>=C2=A0 introduced don&#=
+39;t have variadic witness requirements, and each opcode<br>=C2=A0 is only =
+consumed in a single way.<br><br>- there&#39;s less general indirection. In=
+stead of saying &quot;okay, here&#39;s the<br>=C2=A0 hash of the script I&#=
+39;m going to use to authorize trigger<br>=C2=A0 transactions,&quot; we&#39=
+;re just outright including the trigger auth script<br>=C2=A0 in the taplea=
+f at the birth of the vault as regular &#39;ol script that is<br>=C2=A0 eva=
+luated before execution of the OP_VAULT instruction. <br><br>=C2=A0 Similar=
+ly, instead of relying on an implicit rule that an OP_VAULT can<br>=C2=A0 b=
+e claimed by a recovery flow, we&#39;re relying on a specific tapleaf that<=
+br>=C2=A0 facilitates that recovery with OP_VAULT_RECOVER, described below.=
+<br><br>Basically, OP_VAULT=C2=A0would just be implemented in a way that fe=
+els<br>more native to Taproot primitives.<br><br>Greg also introduces diffe=
+rent opcodes to facilitate consistent<br>witness structure, rather than the=
+ variable ones we have now<br>since OP_VAULT and OP_UNVAULT can each be spe=
+nt in two different<br>contexts. I&#39;ve changed those a little here; inst=
+ead of the three general<br>ones Greg gave, we whittled it down to two: OP_=
+VAULT and<br>OP_VAULT_RECOVER.<br><br><br>So I think that, barring signific=
+ant implementation complexity - which<br>I&#39;ll find out about soon and d=
+on&#39;t expect - this is a good change to the<br>proposal. As Greg noted, =
+it doesn&#39;t really change anything about the<br>usage or expressiveness.=
+.. other than the fact that, as a bonus, it<br>might allow an optional with=
+drawal authorization script (i.e. trigger<br>output =3D&gt; final target), =
+which could be useful if e.g. some kind of<br>size-limiting opcode (e.g. OP=
+_TX_MAXSIZE or something) came around in<br>the future as a kind of pinning=
+ fix.<br><br>If that last bit lost you, don&#39;t worry - that is speculati=
+ve, but the<br>point is that this rework composes well with other stuff.<br=
+><br><br># CTV use<br><br>Another thing that has dawned on us is that we mi=
+ght as well just reuse<br>OP_CHECKTEMPLATEVERIFY for withdrawal target spen=
+ds. Ben Carmen and<br>others realized early on that you can synthesize CTV-=
+like behavior by<br>spending to a 0-delay OP_UNVAULT output, so something C=
+TVish has always<br>implicitly been a part of the proposal. But CTV is bett=
+er studied and<br>basically as simple as the OP_UNVAULT spend semantics, so=
+ the thought is<br>that we might as well reuse all the existing work (and s=
+crutiny) from<br>CTV.<br><br>As a concrete example, an issue with the exist=
+ing proposal is that the<br>existing CTVish OP_UNVAULT behavior has txid ma=
+lleability, since it<br>doesn&#39;t commit to nVersion or nLockTime or the =
+input sequences. Using<br>CTV solves this issue. Otherwise we&#39;d basical=
+ly reinvent it - &quot;something<br>something convergent evolution.&quot;<b=
+r><br>I think this is a satisfying development, because there&#39;s clearly=
+ demand<br>for CTV use in other contexts (DLC efficiency, e.g.), and if it&=
+#39;s<br>required behavior for practical vaults, I think pulling in the exi=
+sting<br>BIP-119 that&#39;s been worked over for years reduces the conceptu=
+al</div><div dir=3D"ltr">surface area added by OP_VAULT.<br><br><br># New m=
+echanics of the proposal<br><br>So here I&#39;m going to describe my render=
+ing of Greg and AJ&#39;s suggestions.<br><br><br>## Required opcodes<br><br=
+>- OP_VAULT: spent to trigger withdrawal<br>- OP_VAULT_RECOVER: spent to re=
+cover<br>- OP_CHECKTEMPLATEVERIFY: spent into final withdrawal target<br><b=
+r><br>Creating an initial deposit<br>---------------------------<br><br>For=
+ each vault, vaulted coins are spent to an output with the taproot<br>struc=
+ture<br><br>=C2=A0 taproot(internal_key, {$recovery_leaf, $trigger_leaf, ..=
+.})<br><br>where<br><br>=C2=A0 internal_key =3D <br>=C2=A0 =C2=A0 unchanged=
+ from original proposal (some very safe recovery key)<br><br>=C2=A0 $recove=
+ry_leaf =3D <br>=C2=A0 =C2=A0 [&lt;opt.&gt; &lt;recovery&gt; &lt;auth&gt;] =
+&lt;recovery sPK hash&gt; OP_VAULT_RECOVER<br><br>=C2=A0 $trigger_leaf =3D =
+<br>=C2=A0 =C2=A0 &lt;trigger&gt; &lt;auth&gt; &lt;script&gt; &lt;spend-del=
+ay&gt; OP_VAULT<br><br>=C2=A0 ... =3D<br>=C2=A0 =C2=A0 other (optional) lea=
+ves in the taptree<br><br><br>Triggering a withdrawal request<br>----------=
+---------------------<br><br>To trigger the start of the withdrawal process=
+, an output of the above<br>form is spent with a witness that contains <br>=
+<br>=C2=A0 - Taproot control block pointing to $trigger_leaf.<br>=C2=A0 - &=
+lt;trigger-vout-idx&gt;, indicating the trigger output which must abide<br>=
+=C2=A0 =C2=A0 by the rules given below.<br><br><br>## Output structure<br>=
+=C2=A0 <br>=C2=A0 taproot(internal_key, {$recovery_leaf, $expr_withdraw, ..=
+.})<br><br>where<br><br>=C2=A0 $recovery_leaf is preserved exactly<br>=C2=
+=A0 $expr_withdraw =3D <br>=C2=A0 =C2=A0 &lt;spend-delay&gt; OP_CSV OP_DROP=
+ &lt;target-ctv-hash&gt; OP_CTV<br>=C2=A0 ... is preserved exactly<br><br><=
+br>(Spoiler: note here that the only thing that is changing is<br>s/expr_tr=
+igger/expr_withdrawl/ from the initial vault ouput.)<br><br>Of course $expr=
+_withdraw *could* be prefixed by an optional &quot;withdrawal<br>authorizat=
+ion&quot; script, if some sensible use for that is found.<br><br>The valida=
+tion rules are essentially unchanged from the existing<br>proposal:<br><br>=
+- The total amount of all OP_VAULT inputs with matching $recovery_leaf<br>=
+=C2=A0 values must be reflected in output &lt;trigger-vout-idx&gt;<br><br>-=
+ &lt;trigger-vout-idx&gt; must correspond to an output that is identical to=
+<br>=C2=A0 the input taptree but with the spent tapleaf (OP_VAULT) swapped =
+out<br>=C2=A0 for the timelocked CTV constructed using &lt;target-ctv-hash&=
+gt; and<br>=C2=A0 &lt;spend-delay&gt; as extracted from the spent tapleaf<b=
+r>=C2=A0 - internal_key is preserved<br>=C2=A0 - the whole rest of the tapt=
+ree is preserved<br>=C2=A0 - (this is what ensures the parameters of the va=
+ult are forwarded)<br><br>All batching, fee management characteristics are =
+the same.<br><br><br>Finalizing withdrawal<br>---------------------<br><br>=
+Happens via script-path spend to $expr_withdraw, i.e. a timelocked<br>OP_CT=
+V.<br><br><br>Recovery<br>--------<br><br>Can happen from any of the above =
+outputs using the $recovery_leaf<br>script path in a way very similar to th=
+e existing OP_VAULT proposal.<br><br><br>---<br><br>To reiterate, all aspec=
+ts of the existing OP_VAULT proposal are either<br>preserved or improved up=
+on in terms of malleability reduction,<br>composability, and flexibility. S=
+o big thanks to AJ and Greg.<br><br>I&#39;ll undertake implementing these c=
+hanges in the coming days to verify<br>that they are, as expected, workable=
+.<br><br>James</div></div>
+
+--000000000000813aec05f63ce78f--
+