<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 26, 2018 at 11:34 PM, Anthony Towns <span dir="ltr">&lt;<a href="mailto:aj@erisian.com.au" target="_blank">aj@erisian.com.au</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Mar 21, 2018 at 05:47:01PM -0700, Bram Cohen via bitcoin-dev wrote:<br>
&gt; [...] Most unused opcodes should be reclaimed as RETURN_VALID,<br>
<span class="">&gt; but there should still be one OP_NOP and there should be a &#39;real&#39; RETURN_VALID,<br>
&gt; which (a) is guaranteed to not be soft forked into something else in the<br>
&gt; future, and (b) doesn&#39;t have any parsing weirdness.<br>
<br>
</span>What&#39;s the reason for those? I could see an argument for RETURN_VALID, I guess:<br>
<br>
  confA IF condB IF condC IF [pathA] RETURN_VALID ENDIF ENDIF ENDIF [pathB]<br>
<br>
is probably simpler and saves 3 bytes compared to:<br>
<br>
  1 condA IF condB IF condC IF [pathA] NOT ENDIF ENDIF ENDIF IF [pathB] ENDIF<br>
<br>
but that doesn&#39;t seem crazy compelling?</blockquote><div><br></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">Mostly yes it&#39;s for that case and a</span>lso for: </div><div><br></div><div>   condA IF RETURN_VALID ENDIF condb IF RETURN_VALID ENDIF condc</div><div><br></div><div>Technically that can be done with fewer opcodes using OP_BOOLOR but maybe in the future there will be some incentive for short circuit evaluation</div><div><br></div><div>But there&#39;s also the general principle that it&#39;s only one opcode and if there are a lot of things which look like RETURN_VALID there should be one thing which actually is RETURN_VALID</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> I don&#39;t see a reason to just keep one OP_NOP though.<br></blockquote><div><br></div><div>Mostly based on momentum because there are several of them there right now. If noone else wants to defend it I won&#39;t either.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">&gt; By far the most expedient option is (e) cause a RETURN_VALID at parse time.<br>
&gt; There&#39;s even precedent for this sort of behavior in the other direction with<br>
&gt; disabled opcodes causing failure at parse time even if they aren&#39;t being<br>
&gt; executed.<br>
<br>
</span>You&#39;re probably right. That still doesn&#39;t let you implement intercal&#39;s<br>
COMEFROM statement as a new opcode, of course. :)<br></blockquote><div><br></div><div>That can be in the hardfork wishlist :-)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">&gt; A lot can be said about all the options, but one thing I feel like snarking<br>
&gt; about is that if you get rid of IFs using MAST, then it&#39;s highly unclear<br>
&gt; whether OP_DEPTH should be nuked as well. My feeling is that it should and that<br>
&gt; strict parsing should require that the bottom thing in the witness gets<br>
&gt; referenced at some point.<br>
<br>
</span>I guess when passing the script you could perhaps check if each witness<br>
item could have been replaced with OP_FALSE or OP_1 and still get the<br>
same result, and consider the transaction non-standard if so?<br></blockquote><div><br></div><div>Essentially all opcodes including OP_PICK make clear at runtime how deep they go and anything below the max depth can be safely eliminated (or used as grounds for rejecting in strict mode). The big exception is OP_DEPTH which totally mangles the assumptions. It&#39;s trivial to make scripts which use OP_DEPTH which become invalid with things added below the stack then go back to being valid again with more things added even though the individual items are never even accessed.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
&gt; Hacking in a multisig opcode isn&#39;t a horrible idea, but it is very stuck<br>
&gt; specifically on m-of-n and doesn&#39;t support more complex formulas for how<br>
&gt; signatures can be combined, which makes it feel hacky and weird.<br>
<br>
</span>Hmm? The opcode I suggested works just as easily with arbitrary formulas,<br>
eg, &quot;There must be at least 1 signer from pka{1,2,3}, and 3 signers all<br>
up, except each of pkb{1,2,3,4,5,6} only counts for half&quot;:<br>
<br>
  0 pkb6 pkb5 pkb4 pkb3 pkb2 pkb1 pka3 pka2 pka1 9 CHECK_AGGSIG_VERIFY<br>
    (declare pubkeys)<br>
  0b111 CHECK_AGG_SIGNERS VERIFY<br>
    (one of pka{1,2,3} must sign)<br>
  0b001 CHECK_AGG_SIGNERS<br>
  0b010 CHECK_AGG_SIGNERS ADD<br>
  0b100 CHECK_AGG_SIGNERS ADD<br>
  DUP ADD<br>
    (pka{1,2,3} count double)<br>
  0b000001000 CHECK_AGG_SIGNERS ADD<br>
  0b000010000 CHECK_AGG_SIGNERS ADD<br>
  0b000100000 CHECK_AGG_SIGNERS ADD<br>
  0b001000000 CHECK_AGG_SIGNERS ADD<br>
  0b010000000 CHECK_AGG_SIGNERS ADD<br>
  0b100000000 CHECK_AGG_SIGNERS ADD<br>
    (pkb{1..6} count single)<br>
  6 EQUAL<br>
    (summing to a total of 3 doubled)<br>
<br>
Not sure that saves it from being &quot;hacky and weird&quot; though...<br></blockquote><div><br></div><div>That is very hacky and weird. Doing MAST on lots of possibilities is always reasonably elegant, and it only gets problematic when the number of possibilities is truly massive.</div><div><br></div><div>It&#39;s also the case that BLS can support complex key agreement schemes without even giving away that it isn&#39;t a simple single signature. Just saying.</div></div></div></div>