public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Anthony Towns <aj@erisian.com.au>
To: Antoine Riard <antoine.riard@gmail.com>
Cc: Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
Subject: Re: [bitcoin-dev] TAPLEAF_UPDATE_VERIFY covenant opcode
Date: Sat, 11 Sep 2021 13:26:44 +1000	[thread overview]
Message-ID: <20210911032644.GB23578@erisian.com.au> (raw)
In-Reply-To: <CALZpt+FnnbGJC4=KO_OPiKxt0Ey9Bzh1gxP1dQSDz2aBi9WyOA@mail.gmail.com>

On Fri, Sep 10, 2021 at 12:12:24AM -0400, Antoine Riard wrote:
> "Talk is cheap. Show me the code" :p
>     case OP_MERKLESUB:

I'm not entirely clear on what your opcode there is trying to do. I
think it's taking

   <N> <P> MERKLESUB

and checking that output N has the same scripts as the current input
except with the current script removed, and with its internal pubkey as
the current input's internal pubkey plus P.

>         txTo->vout[out_pos].scriptPubKey.IsWitnessProgram(witnessversion,
> witnessprogram);
>         //! The committed to output must be a witness v1 program at least

That would mean anyone who could do a valid spend of the tx could
violate the covenant by spending to an unencumbered witness v2 output
and (by collaborating with a miner) steal the funds. I don't think
there's a reasonable way to have existing covenants be forward
compatible with future destination addresses (beyond something like CTV
that strictly hardcodes them).

> One could also imagine a list of output positions to force the taproot update
> on multiple outputs ("OP_MULTIMERKLESUB").

Having the output position parameter might be an interesting way to
merge/split a vault/pool, but it's not clear to me how much sense it
makes sense to optimise for that, rather than just doing that via the key
path. For pools, you want the key path to be common anyway (for privacy
and efficiency), so it shouldn't be a problem; but even for vaults,
you want the cold wallet accessible enough to be useful for the case
where theft is attempted, and maybe that's also accessible enough for
the ocassional merge/split to keep your utxo count/sizes reasonable.

> For the merkle branches extension, I was thinking of introducing a separate
> OP_MERKLEADD, maybe to *add* a point to the internal pubkey group signer. If
> you're only interested in leaf pruning, using OP_MERKLESUB only should save you
> one byte of empty vector ?

Saving a byte of witness data at the cost of specifying additional
opcodes seems like optimising the wrong thing to me.

> One solution I was thinking about was introducing a new tapscript version
> (`TAPROOT_INTERNAL_TAPSCRIPT`) signaling that VerifyTaprootCommitment must
> compute the TapTweak with a new TapTweak=(internal_pubkey || merkle_root ||
> parity_bit). A malicious participant wouldn't be able to interfere with the
> updated internal key as it would break its own spending taproot commitment
> verification ?

I don't think that works, because different scripts in the same merkle
tree can have different script versions, which would here indicate
different parities for the same internal pub key.

> > That's useless without some way of verifying that the new utxo retains
> > the bitcoin that was in the old utxo, so also include a new opcode
> > IN_OUT_AMOUNT that pushes two items onto the stack: the amount from this
> > input's utxo, and the amount in the corresponding output, and then expect
> > anyone using TLUV to use maths operators to verify that funds are being
> > appropriately retained in the updated scriptPubKey.
> Credit to you for the SIGHASH_GROUP design, here the code, with
> SIGHASH_ANYPUBKEY/ANYAMOUNT extensions.
> 
> I think it's achieving the same effect as IN_OUT_AMOUNT, at least for CoinPool
> use-case.

The IN_OUT_AMOUNT opcode lets you do maths on the values, so you can
specify "hot wallets can withdraw up to X" rather than "hot wallets
must withdraw exactly X". I don't think there's a way of doing that with
SIGHASH_GROUP, even with a modifier like ANYPUBKEY?

> (I think I could come with some use-case from lex mercatoria where if you play
> out a hardship provision you want to tweak all the other provisions by a CSV
> delay while conserving the rest of their policy)

If you want to tweak all the scripts, I think you should be using the
key path.

One way you could do somthing like that without changing the scripts
though, is have the timelock on most of the scripts be something like
"[3 months] CSV", and have a "delay" script that doesn't require a CSV,
does require a signature from someone able to authorise the delay,
and requires the output to have the same scriptPubKey and amount. Then
you can use that path to delay resolution by 3 months however often,
even if you can't coordinate a key path spend.

> > And second, it doesn't provide a way for utxos to "interact", which is
> > something that is interesting for automated market makers [5], but perhaps
> > only interesting for chains aiming to support multiple asset types,
> > and not bitcoin directly. On the other hand, perhaps combining it with
> > CTV might be enough to solve that, particularly if the hash passed to
> > CTV is constructed via script/CAT/etc.
> That's where SIGHASH_GROUP might be more interesting as you could generate
> transaction "puzzles".
> IIUC, the problem is how to have a set of ratios between x/f(x).

Normal way to do it is specify a formula, eg

   outBTC * outUSDT >= inBTC * inUSDT

that's a constant product market maker without a profit margin. There's
lots of research in the ethereum world about doing these things, and
bitmatrix is trying to do it on liquid. It's not clear to me if there's
anywhere in bitcoin per se that it would make sense.

Then your relative balances of each token imply a price, and traders will
rebalance anytime that price is out of whack with the rest of the market.

You can tweak the formula so that you make a profit, which also ends up
meaning the fund pool becomes more liquid overtime. But that means that
you want to cope with 100 BTC and 5M USDT at $50k, but also 200 BTC and
10M USDT at $50k, and many values in between. So I don't think:

> The maker generates a Taproot tree where each leaf is committing to a different
> "strike price".

really works that well.

One irritating thing I realised while reading Jeremy's mail is that

  CAT "TapBranch" SHA256 DUP CAT SWAP CAT SHA256

doesn't actually work -- the first CAT needs to sort the two branches
first, and "LESSTHAN" etc want to compare values numerically rather
than lexically. So maybe it would make more sense to introduce an opcode
that builds a merkle root from tagged hashes directly, rather than one
that lets you compare to 32B strings so that you can do the TapBranch
logic manually.

Cheers,
aj



  reply	other threads:[~2021-09-11  3:26 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-09  6:41 [bitcoin-dev] TAPLEAF_UPDATE_VERIFY covenant opcode Anthony Towns
2021-09-09  6:53 ` Anthony Towns
2021-09-09 12:56   ` darosior
2021-09-09 15:54   ` Jeremy
2021-09-09 19:26   ` Jeremy
2021-09-10  7:42     ` Anthony Towns
2022-07-08 19:52   ` Tim Ruffing
2021-09-09  9:16 ` Matt Corallo
2021-09-10  4:12 ` Antoine Riard
2021-09-11  3:26   ` Anthony Towns [this message]
2021-09-12 23:37     ` Antoine Riard
2021-09-15  6:50       ` Anthony Towns
2021-09-18 14:11         ` Antoine Riard
2021-09-20 14:52           ` Anthony Towns
2021-09-22  1:40             ` Antoine Riard
2021-09-23  0:29 ` Olaoluwa Osuntokun
2021-10-29 15:47   ` Billy Tetrud

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210911032644.GB23578@erisian.com.au \
    --to=aj@erisian.com.au \
    --cc=antoine.riard@gmail.com \
    --cc=bitcoin-dev@lists.linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox