Subject: Re: [bitcoindev] Difficulty in emulating "weaker" OP_SUCCESS and why it should be a real opcode

From: Brandon Black <[email-masked]>
Date: Wed, 11 Dec 2024 21:49:48 -0800

On 2024-12-10 (Tue) at 10:51:38 +1030, Rusty Russell wrote:
> Brandon Black <[email-masked]> writes:
> > It occurred to me today when thinking about Weikeng's post that we can
> > slightly weaken the existing OP_SUCCESS behavior while retaining
> > essentially all of its benefits in practice without introducing
> > OP_SEGMENT by leveraging OP_CODESEPARATOR. Redefine OP_SUCCESS with a
> > soft fork from "make the script unconditionally valid" to "make the
> > script segment unconditionally valid", and define a script segment as
> > "each lexicographic section of the script containing no
> > OP_CODESEPARATOR".
> >
> > The script interpreter can perform SUCCESS checking as it currently does
> > until it encounters an OP_CODESEPARATOR. Each OP_CODESEPARATOR gets a
> > "SUCCESS" flag defaulted to false and SUCCESS checking now sets that
> > flag to true on the most recently encountered OP_CODESEPARATOR.
> >
> > During script execution, whenever an OP_CODESEPARATOR is popped (not
> > executed) its "SUCCESS" flag value is copied to the interpreter state.
> > After this state setting conditional, if the interpreter "SUCCESS" flag
> > is true, and fExec is true, the script immediately succeeds.
> 
> Beware success inside branches?  This is why I preferred to segment the
> script and scan for OP_SUCCESS and evaluate each part in order (if you
> have part of an if statement inside one segment, you fail as expected).
> This is actually not that different inside Bitcoin's script.cpp.

I believe my description of CODESEPARATOR segments has a predictable but
different handling of SUCCESS with conditionals. As long as interpreter
state change are handled in order:

* update success mode if opcode is CODESEPARATOR
* if execution enabled by flow control and success mode is true, succeed
* execute operation if enabled or operation is flow control

That said, I've just reread [BIP342] and realized that the designers of
tapscript had greater things in mind for SUCCESS than I had remembered
(e.g. the existence of an SUCCESS can be used to change the behavior of
other opcodes or even stack limits) which would not work at all well
with segmented SUCCESS.

Some of these be possible with segmented execution, but not all.

Based on this, I'm now in favor of Weikeng's idea for a runtime success
operator possibly akin to the original RETURN. If it were equivalent to
the original RETURN, it would be a useful alternative to VERIFY in
certain cases.

> (Also: CODESEPARATOR is cursed, so I chose a different name :)

Isn't tapscript CODESEPARATOR uncursed? :)

Aside: Because SUCCESS allows for changing resource limits and more,
restored script can mostly be implemented in tapscript 0xc0. If any of
the new opcodes are present, 1NEGATE is redefined to TX (or something),
numbers are bigwholes, limits are varops, etc. Gets a little weird if
someone wants to write a restored script without any of the new ops, so
maybe you also provide an RESTORE that does nothing other than trigger
the mode change.

All the best,

--Brandon

[BIP342]: https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email-masked].
To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/Z1p5fA6-ZcMtPLOq%40console.