In order of escalating scope of amendments to OP_COSHV, I suggest
1) Peeking at surrounding data surrounding data should definitely be replaced by a pushdata-like op-code that uses the subsequent 32-bytes directly. The OP_SUCCESSx upgrade path specifically allows for this, and avoids complicating the semantics Bitcoin Script.
2) Furthermore, the number-of-input-verification and the outputhash-verification operations ought to be split into different opcodes as they are logically unrelated.
3) Better still, we should instead implement the transaction reflection operations of OP_PUSHOUTPUTHASH and OP_NUMINPUTS that puts the outputhash and number of inputs respectively onto the stack. Recursive covenants appear to be effectively impossible without either an OP_TWEEKPUBKEY or an OP_PUSHSCRIPTPUBKEY so the effort your proposal goes through to guard against placing an arbitrary outputhash onto the stack appears to be wasted effort to me.
4) If we anticipate adding OP_CHECKSIGFROMSTACKVERIFY, then we should most definitely prefer (3) instead of OP_COSHV, if we still feel the need to do anything at all. It is probably best to have both OP_CHECKSIGFROMSTACKVERIFY and transaction reflection operations of OP_PUSHOUTPUTHASH and OP_NUMINPUTS but I think I would be fine with just OP_CHECKSIGFROMSTACKVERIFY as well.
On the other hand, if we are serious about preferring less per-block bandwidth over reusable primitive opcodes for programming, then we should instead abandon the RISC-style Bitcoin Script and instead add an alternative CISC-style taproot leaf type that directly provides (a conjunction of) the various popular common policies: channel opening, channel factories, coinjoins, hashlocks, timelocks, congestion control etc. Segwit v0 already implements this CISC-style for the single most popular policy: single signature verification.
Hi Russell,
Thanks for this detailed comparison. The COSHV BIP does include a brief comparison to OP_CHECKSIGFROMSTACKVERIFY and ANYPREVOUT, but this is more detailed.
I think that the power from CHECKSIGFROMSTACKVERIFY is awesome. It's clearly one of the more flexible options available and would enable a multitude of new use cases.
When I originally presented my work on congestion control at Jan 2017 BPASE, I also discussed it as an option for covenants. Unfortunately I think it may be on the edge of too powerful -- there are a lot of use cases and implications from having a potentially recursive covenant. If you see my response to Matt in the OP_COSHV BIP thread I classify it as enabling a non-computationally enumerable set of restrictions.
I think also from a developer point of view working with OP_COSHV is much much simpler (maybe this can be abstracted) which will lead to increased adoption. OP_COSHV also uses less per-block bandwidth which also makes it preferable for a measure intended to decongest blocks. Do you know the exact byte cost for OP_CHECKSIGFROMSTACK? OP_COSHV scripts, with templating changes to taproot, can be a single byte. OP_COSHV also has less potential to have a negative interaction with future opcodes we may want like OP_PUBKEYTWEAK. While we're getting to an exact spec for the features we want in Bitcoin scripting, it's hard to sign on to OP_CHECKSIGFROMSTACK unless there's an exact specification which makes us confident we're hitting all the points.
If the main complaint about OP_COSHV is that it peeks at surrounding data, it's also possible to implement it more closely to a multi-byte pushdata opcode or do the template optimization.
Lastly, as I have previously noted, OP_LEFT is probably safer to implement than OP_CAT and should be more efficient for OP_CHECKSIGFROMSTACK scripts.