Subject: Re: [bitcoin-dev] Concrete MATT opcodes

From: Antoine Riard <[email-masked]>
Date: Mon, 14 Aug 2023 04:00:57 +0100

Hi Salvatore,

> This also allows inspection of other inputs, that was not possible with
the original opcodes.

I think cross-input inspection (not cross-input signature aggregation which
is different) is opening a pandora box in terms of "malicious" off-chain
contracts than one could design. E.g miners bribing contracts to censor the
confirmation of time-sensitive lightning channel transactions, where the
bribes are paid on the hashrate distribution of miners during the previous
difficulty period, thanks to the coinbase pubkey.

See https://blog.bitmex.com/txwithhold-smart-contracts/ and
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-February/021395.html

I wonder if we might face the dilemma of miners censorship attacks, if we
wish to have more advanced bitcoin contracts, though I think it would be
safe design practice to rule out those types of concerns thanks to smart
bitcoin contracting primitives.

I think this is a common risk to all second-layers vaults, lightning
channels and payment pools.

> A flag can disable this behavior"

More than a binary flag like a matrix could be introduced to encode subset
of introspected inputs /outputs to enable sighash_group-like semantic:
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019243.html

> There are two defined flags:
> - CCV_FLAG_CHECK_INPUT = 1: if present, <index> refers to an input;
>  otherwise, it refers to an output.
> - CCV_FLAG_IGNORE_OUTPUT_AMOUNT = 2: only defined when _CHECK_INPUT
>  is absent, it disables the deferred checks logic for amounts.

Or even beyond a matrix, it could be a set of "tags". There could be a
generalized tag for unstructured data, and another one for bitcoin
transaction / script data types (e.g scriptpubkey, amount, nsequence,
merkle branch) that could be fetched from the taproot annex.

> After the evaluation of all inputs, it is verified that each output's
> amount is greater than or equal to the total amount in the bucket
> if that output (validation of the deferred checks).

At the very least, I think for the payment pool, where you're fanning-out
satoshis value from a subset of inputs to another subset of outputs, I
think you would need more malleability here.

> It is unclear if all the special values above will be useful in
> applications; however, as each special case requires very little added
> code, I tried to make the specs as flexible as possible at this time.

I think this generic framework is interesting for joinpool / coinpool /
payment pool, as you can check that any withdrawal output can be committed
as part of the input scriptpubkey, and spend it on
blessed-with-one-participant-sig script. There is still a big open question
if it's efficient in terms of witness space consumed.

That said, I still think you would need at least ANYPREVOUT and more
malleability for the amount transfer validation as laid out above.

Looking on the `DeferredCheck` framework commit, one obvious low-level
concern is the DoS risk for full-nodes participating in transaction-relay,
and that maybe policy rules should be introduced to keep the worst-CPU
input in the ranges of current transaction spend allowed to propagate on
the network today.

Thanks for the proposal,

Best,
Antoine

Le dim. 30 juil. 2023 à 22:52, Salvatore Ingala via bitcoin-dev <
[email-masked]> a écrit :

> Hi all,
>
> I have put together a first complete proposal for the core opcodes of
> MATT [1][2].
> The changes make the opcode functionally complete, and the
> implementation is revised and improved.
>
> The code is implemented in the following fork of the
> bitcoin-inquisition repo:
>
> https://github.com/Merkleize/bitcoin/tree/checkcontractverify
>
> Therefore, it also includes OP_CHECKTEMPLATEVERIFY, as in a
> previous early demo for vaults [3].
>
> Please check out the diff [4] if you are interested in the
> implementation details. It includes some basic functional tests for
> the main cases of the opcode.
>
> ## Changes vs the previous draft
>
> These are the changes compared to the initial incomplete proposal:
> - OP_CHECK{IN,OUT}CONTRACTVERIFY are replaced by a single opcode
>   OP_CHECKCONTRACTVERIFY (CCV). An additional `flags` parameter allows
>   to specify if the opcode operates on an input or an output.
>   This also allows inspection of other inputs, that was not possible
>   with the original opcodes.
> - For outputs, the default behavior is to have the following deferred
>   checks mechanism for amounts: all the inputs that have a CCV towards
>   the same output, have their input amounts summed, and that act as a
>   lower bound for that output's amount.
>   A flag can disable this behavior. [*]
> - A number of special values of the parameters were defined in order
>   to optimize for common cases, and add some implicit introspection.
> - The order of parameters is modified (particularly, <data> is at the
>   bottom of the arguments, as so is more natural when writing Scripts).
>
> ## Semantics
>
> The new OP_CHECKCONTRACTVERIFY takes 5 parameters from the stack:
>
>   <data>, <index>, <pk>, <taptree>, <flags>
>
> The core logic of the opcode is as follows:
>
> "Check if the <index>-th input/output's scriptPubKey is a P2TR
> whose public key is obtained from <pk>, (optionally) tweaked with
> <data>, (optionally) tap-tweaked with <taptree>".
>
> The following are special values of the parameters:
>
> - if <pk> is empty, it is replaced with a fixed NUMS point. [**]
> - if <pk> is -1, it is replaced with the current input's taproot
>   internal key.
> - if <index> is -1, it is replaced with the current input's index.
> - if <data> is empty, the data tweak is skipped.
> - if <taptree> is empty, the taptweak is skipped.
> - if <taptree> is -1, it is replaced with the current input's root
>   of the taproot merkle tree.
>
> There are two defined flags:
> - CCV_FLAG_CHECK_INPUT = 1: if present, <index> refers to an input;
>   otherwise, it refers to an output.
> - CCV_FLAG_IGNORE_OUTPUT_AMOUNT = 2: only defined when _CHECK_INPUT
>   is absent, it disables the deferred checks logic for amounts.
>
> Finally, if both the flags CCV_FLAG_CHECK_INPUT and
> CCV_FLAG_IGNORE_OUTPUT_AMOUNT are absent:
>   - Add the current input's amount to the <index>-th output's bucket.
>
> After the evaluation of all inputs, it is verified that each output's
> amount is greater than or equal to the total amount in the bucket
> if that output (validation of the deferred checks).
>
> ## Comment
>
> It is unclear if all the special values above will be useful in
> applications; however, as each special case requires very little added
> code, I tried to make the specs as flexible as possible at this time.
>
> With this new opcode, the full generality of MATT (including the fraud
> proofs) can be obtained with just two opcodes: OP_CHECKCONTRACTVERIFY
> and OP_CAT.
> However, additional opcodes (and additional introspection) would
> surely benefit some applications.
>
> I look forward to your comments, and to start drafting a BIP proposal.
>
> Best,
> Salvatore Ingala
>
>
> [*] - Credits go to James O'Beirne for this approach, taken from his
>       OP_VAULT proposal. I cherry-picked the commit containing the
>       Deferred Checks framework.
> [**] - The same NUMS point suggested in BIP-0341 was used.
>
>
> References:
>
> [1] - https://merkle.fun/
> [2] -
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-November/021182.html
> [3] -
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-April/021588.html
> [4] -
> https://github.com/bitcoin-inquisition/bitcoin/compare/24.0...Merkleize:bitcoin:checkcontractverify
> _______________________________________________
> bitcoin-dev mailing list
> [email-masked]
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>