1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
|
Return-Path: <jeremy.l.rubin@gmail.com>
Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133])
by lists.linuxfoundation.org (Postfix) with ESMTP id 6AA94C000B
for <bitcoin-dev@lists.linuxfoundation.org>;
Fri, 4 Mar 2022 23:21:57 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
by smtp2.osuosl.org (Postfix) with ESMTP id 417E44010E
for <bitcoin-dev@lists.linuxfoundation.org>;
Fri, 4 Mar 2022 23:21:57 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
X-Spam-Flag: NO
X-Spam-Score: -2.098
X-Spam-Level:
X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5
tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,
HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,
SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: smtp2.osuosl.org (amavisd-new);
dkim=pass (2048-bit key) header.d=gmail.com
Received: from smtp2.osuosl.org ([127.0.0.1])
by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
with ESMTP id saexSjTB7Map
for <bitcoin-dev@lists.linuxfoundation.org>;
Fri, 4 Mar 2022 23:21:55 +0000 (UTC)
X-Greylist: whitelisted by SQLgrey-1.8.0
Received: from mail-lj1-x235.google.com (mail-lj1-x235.google.com
[IPv6:2a00:1450:4864:20::235])
by smtp2.osuosl.org (Postfix) with ESMTPS id C86B1400E9
for <bitcoin-dev@lists.linuxfoundation.org>;
Fri, 4 Mar 2022 23:21:54 +0000 (UTC)
Received: by mail-lj1-x235.google.com with SMTP id p20so13013345ljo.0
for <bitcoin-dev@lists.linuxfoundation.org>;
Fri, 04 Mar 2022 15:21:54 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
h=mime-version:from:date:message-id:subject:to;
bh=rRRAB3OFBb80kbLRW1tlSu2Yvb56ZdJ2GnKoZ4LFiyE=;
b=QNZkZzWg8/CCJkmkuJ1ogEEbEjCfxn7kuqXMg0V5vBh573NGesfbcetM4E1h4chF2l
heE4QO8fO2FcU4lJdiIyj1jxjEQ8f9mtqqj8RZnUIyHQTxkUH6oiKCeqc4sGJN69Yoe5
UprXSJrgntPxp6pWoOK3br/C2jGR3JvuBte9PsEYMoxxmtpzM+YW6u99SblpjlWzXIDd
LQHb6UNtJ+cjxKDULAMSxZc+dYFskWrF6G2tIN2C7C1M63KE6ChytDHYmAeKSlXe5DDz
Z7/hFGX/lPNK/w/anOCW6ZHmnapiMtyDhM84uGSCi8EzLBIEeLOsPk8Gs0j3sobgWVW7
0kTg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20210112;
h=x-gm-message-state:mime-version:from:date:message-id:subject:to;
bh=rRRAB3OFBb80kbLRW1tlSu2Yvb56ZdJ2GnKoZ4LFiyE=;
b=BTDxQhHvMeSTWeG5+530E5JXzKglxZ1mXc2hd/Sbq4JVlmdrmV6kbzHs/dFQLrHRmd
H2Wr8XRAbxjYZrCAM3eYGo2Xyc46irD2TB4SWih+uwcpPkyXLdFRQq48XftEU7GxmVa+
AscFQggFq5RDEndWn+5WXfHdR6BdbWOF+XmpgAIcHuaHy1KjLZsdQn2qMHxwS5k2DyD9
znUxo45YXK0XS5L5u1t/WXojQANK+Lvf+VLRMiYTTCuDucq0eswjCyvnQaSmNX8eDciR
JASlDWGv3cAKHnCHcBhcRNq075za71syKH04ndBlDgcW0qR1bfKDRZG9YACCGQdVRvwH
0OAg==
X-Gm-Message-State: AOAM533wisBdCf+b21yWHBfROq4WES87BApvJn9hPBtH+KuDDSXnJjcE
23kaQOye+VZjzQj4hHa+PMKESAjF+mmasq2DL81ZTp5vpN8=
X-Google-Smtp-Source: ABdhPJw9tNZVMdkhi2+q24NDim548SREAAbIZGZ6UwbGduQIwLs2t4fL4kAqU+BxCQQSUhelatuRL7bVWWYGfoaWxTU=
X-Received: by 2002:a2e:6804:0:b0:245:f269:618 with SMTP id
c4-20020a2e6804000000b00245f2690618mr580282lja.198.1646436112167; Fri, 04 Mar
2022 15:21:52 -0800 (PST)
MIME-Version: 1.0
From: Jeremy Rubin <jeremy.l.rubin@gmail.com>
Date: Fri, 4 Mar 2022 23:21:41 +0000
Message-ID: <CAD5xwhgXE9sB-hdzz_Bgz6iEA-M5-Yu2VOn1qRzkaq+DdVsgmw@mail.gmail.com>
To: Bitcoin development mailing list <bitcoin-dev@lists.linuxfoundation.org>
Content-Type: multipart/alternative; boundary="0000000000009c76d605d96cc722"
Subject: [bitcoin-dev] Annex Purpose Discussion: OP_ANNEX,
Turing Completeness, and other considerations
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>,
<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>,
<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Fri, 04 Mar 2022 23:21:57 -0000
--0000000000009c76d605d96cc722
Content-Type: text/plain; charset="UTF-8"
I've seen some discussion of what the Annex can be used for in Bitcoin. For
example, some people have discussed using the annex as a data field for
something like CHECKSIGFROMSTACK type stuff (additional authenticated data)
or for something like delegation (the delegation is to the annex). I think
before devs get too excited, we should have an open discussion about what
this is actually for, and figure out if there are any constraints to using
it however we may please.
The BIP is tight lipped about it's purpose, saying mostly only:
*What is the purpose of the annex? The annex is a reserved space for future
extensions, such as indicating the validation costs of computationally
expensive new opcodes in a way that is recognizable without knowing the
scriptPubKey of the output being spent. Until the meaning of this field is
defined by another softfork, users SHOULD NOT include annex in
transactions, or it may lead to PERMANENT FUND LOSS.*
*The annex (or the lack of thereof) is always covered by the signature and
contributes to transaction weight, but is otherwise ignored during taproot
validation.*
*Execute the script, according to the applicable script rules[11], using
the witness stack elements excluding the script s, the control block c, and
the annex a if present, as initial stack.*
Essentially, I read this as saying: The annex is the ability to pad a
transaction with an additional string of 0's that contribute to the virtual
weight of a transaction, but has no validation cost itself. Therefore,
somehow, if you needed to validate more signatures than 1 per 50 virtual
weight units, you could add padding to buy extra gas. Or, we might somehow
make the witness a small language (e.g., run length encoded zeros) such
that we can very quickly compute an equivalent number of zeros to 'charge'
without actually consuming the space but still consuming a linearizable
resource... or something like that. We might also e.g. want to use the
annex to reserve something else, like the amount of memory. In general, we
are using the annex to express a resource constraint efficiently. This
might be useful for e.g. simplicity one day.
Generating an Annex: One should write a tracing executor for a script, run
it, measure the resource costs, and then generate an annex that captures
any externalized costs.
-------------------
Introducing OP_ANNEX: Suppose there were some sort of annex pushing opcode,
OP_ANNEX which puts the annex on the stack as well as a 0 or 1 (to
differentiate annex is 0 from no annex, e.g. 0 1 means annex was 0 and 0 0
means no annex). This would be equivalent to something based on <annex
flag> OP_TXHASH <has annex flag> OP_TXHASH.
Now suppose that I have a computation that I am running in a script as
follows:
OP_ANNEX
OP_IF
`some operation that requires annex to be <1>`
OP_ELSE
OP_SIZE
`some operation that requires annex to be len(annex) + 1 or does a
checksig`
OP_ENDIF
Now every time you run this, it requires one more resource unit than the
last time you ran it, which makes your satisfier use the annex as some sort
of "scratch space" for a looping construct, where you compute a new annex,
loop with that value, and see if that annex is now accepted by the program.
In short, it kinda seems like being able to read the annex off of the stack
makes witness construction somehow turing complete, because we can use it
as a register/tape for some sort of computational model.
-------------------
This seems at odds with using the annex as something that just helps you
heuristically guess computation costs, now it's somehow something that
acts to make script satisfiers recursive.
Because the Annex is signed, and must be the same, this can also be
inconvenient:
Suppose that you have a Miniscript that is something like: and(or(PK(A),
PK(A')), X, or(PK(B), PK(B'))).
A or A' should sign with B or B'. X is some sort of fragment that might
require a value that is unknown (and maybe recursively defined?) so
therefore if we send the PSBT to A first, which commits to the annex, and
then X reads the annex and say it must be something else, A must sign
again. So you might say, run X first, and then sign with A and C or B.
However, what if the script somehow detects the bitstring WHICH_A WHICH_B
and has a different Annex per selection (e.g., interpret the bitstring as a
int and annex must == that int). Now, given and(or(K1, K1'),... or(Kn,
Kn')) we end up with needing to pre-sign 2**n annex values somehow... this
seems problematic theoretically.
Of course this wouldn't be miniscript then. Because miniscript is just for
the well behaved subset of script, and this seems ill behaved. So maybe
we're OK?
But I think the issue still arises where suppose I have a simple thing
like: and(COLD_LOGIC, HOT_LOGIC) where both contains a signature, if
COLD_LOGIC and HOT_LOGIC can both have different costs, I need to decide
what logic each satisfier for the branch is going to use in advance, or
sign all possible sums of both our annex costs? This could come up if
cold/hot e.g. use different numbers of signatures / use checksigCISAadd
which maybe requires an annex argument.
------------
It seems like one good option is if we just go on and banish the OP_ANNEX.
Maybe that solves some of this? I sort of think so. It definitely seems
like we're not supposed to access it via script, given the quote from above:
*Execute the script, according to the applicable script rules[11], using
the witness stack elements excluding the script s, the control block c, and
the annex a if present, as initial stack.*
If we were meant to have it, we would have not nixed it from the stack, no?
Or would have made the opcode for it as a part of taproot...
But recall that the annex is committed to by the signature.
So it's only a matter of time till we see some sort of Cat and Schnorr
Tricks III the Annex Edition that lets you use G cleverly to get the annex
onto the stack again, and then it's like we had OP_ANNEX all along, or
without CAT, at least something that we can detect that the value has
changed and cause this satisfier looping issue somehow.
Not to mention if we just got OP_TXHASH
-----------
Is the annex bad? After writing this I sort of think so?
One solution would be to... just soft-fork it out. Always must be 0. When
we come up with a use case for something like an annex, we can find a way
to add it back. Maybe this means somehow pushing multiple annexes and
having an annex stack, where only sub-segments are signed for the last
executed signature? That would solve looping... but would it break some
aggregation thing? Maybe.
Another solution would be to make it so the annex is never committed to and
unobservable from the script, but that the annex is always something that
you can run get_annex(stack) to generate the annex. Thus it is a hint for
validation rules, but not directly readable, and if it is modified you
figure out the txn was cheaper sometime after you execute the scripts and
can decrease the value when you relay. But this sounds like something that
needs to be a p2p only annex, because consensus we may not care (unless
it's something like preallocating memory for validation?).
-----------------------
Overall my preference is -- perhaps sadly -- looking like we should
soft-fork it out of our current Checksig (making the policy that it must 0
a consensus rule) and redesign the annex technique later when we actually
know what it is for with a new checksig or other mechanism. But It's not a
hard opinion! It just seems like you can't practically use the annex for
this worklimit type thing *and* observe it from the stack meaningfully.
Thanks for coming to my ted-talk,
Jeremy
--
@JeremyRubin <https://twitter.com/JeremyRubin>
--0000000000009c76d605d96cc722
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_default" style=3D"font-family:arial,he=
lvetica,sans-serif;font-size:small;color:#000000">I've seen some discus=
sion of what the Annex can be used for in Bitcoin. For example, some people=
have discussed using the annex as a data field for something like CHECKSIG=
FROMSTACK type stuff (additional authenticated data) or for something like =
delegation (the delegation is to the annex). I think before devs get too ex=
cited, we should have an open discussion about what this is actually for, a=
nd figure out if there are any constraints to using it however we may pleas=
e.</div><div class=3D"gmail_default" style=3D"font-family:arial,helvetica,s=
ans-serif;font-size:small;color:#000000"><br></div><div class=3D"gmail_defa=
ult" style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:=
#000000">The BIP is tight lipped about it's purpose, saying mostly only=
:</div><div class=3D"gmail_default"><br><i>What is the purpose of the annex=
? The annex is a reserved space for future extensions, such as indicating t=
he validation costs of computationally expensive new opcodes in a way that =
is recognizable without knowing the scriptPubKey of the output being spent.=
Until the meaning of this field is defined by another softfork, users SHOU=
LD NOT include annex in transactions, or it may lead to PERMANENT FUND LOSS=
.</i></div><div class=3D"gmail_default"><i><br></i></div><div class=3D"gmai=
l_default"><i>The annex (or the lack of thereof) is always covered by the s=
ignature and contributes to transaction weight, but is otherwise ignored du=
ring taproot validation.</i></div><div class=3D"gmail_default"><i><br></i><=
/div><div class=3D"gmail_default"><i>Execute the script, according to the a=
pplicable script rules[11], using the witness stack elements excluding the =
script s, the control block c, and the annex a if present, as initial stack=
.</i></div><div class=3D"gmail_default"><font color=3D"#000000" face=3D"ari=
al, helvetica, sans-serif"><br></font></div><div class=3D"gmail_default"><f=
ont color=3D"#000000" face=3D"arial, helvetica, sans-serif">Essentially, I =
read this as saying: The annex is the ability to pad a transaction with an =
additional string of 0's that contribute to the virtual weight of a tra=
nsaction, but has no validation cost itself. Therefore, somehow, if you nee=
ded to validate more signatures than 1 per 50 virtual weight units, you cou=
ld add padding to buy extra gas. Or, we might somehow make the witness a sm=
all language (e.g., run length encoded zeros) such that we can very quickly=
compute an equivalent number of zeros to 'charge' without actually=
consuming the space but still consuming a linearizable resource... or some=
thing like that. We might also e.g. want to use the annex to reserve someth=
ing else, like the amount of memory. In general, we are using the annex to =
express a resource constraint efficiently. This might be useful for e.g. si=
mplicity one day.</font></div><div class=3D"gmail_default"><font color=3D"#=
000000" face=3D"arial, helvetica, sans-serif"><br></font></div><div class=
=3D"gmail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-s=
erif">Generating an Annex: One should write a tracing executor for a script=
, run it, measure the resource costs, and then generate an annex that captu=
res any externalized costs.</font></div><div class=3D"gmail_default"><font =
color=3D"#000000" face=3D"arial, helvetica, sans-serif"><br></font></div><d=
iv class=3D"gmail_default"><font color=3D"#000000" face=3D"arial, helvetica=
, sans-serif"><span>-------------------</span></font></div><div class=3D"gm=
ail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif">=
<span><br></span></font></div><div class=3D"gmail_default"><font color=3D"#=
000000" face=3D"arial, helvetica, sans-serif">Introducing OP_ANNEX: Suppose=
there were some sort of annex pushing opcode, OP_ANNEX which puts the anne=
x on the stack as well as a 0 or 1 (to differentiate annex is 0 from no ann=
ex, e.g. 0 1 means annex was 0 and 0 0 means no annex). This would be equiv=
alent to something based on <annex flag> OP_TXHASH <has annex flag=
> OP_TXHASH.</font></div><div class=3D"gmail_default"><font color=3D"#00=
0000" face=3D"arial, helvetica, sans-serif"><br></font></div><div class=3D"=
gmail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif=
">Now suppose that I have a computation that I am running in a script as fo=
llows:</font></div><div class=3D"gmail_default"><br></div><div class=3D"gma=
il_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif">O=
P_ANNEX</font></div><div class=3D"gmail_default"><font color=3D"#000000" fa=
ce=3D"arial, helvetica, sans-serif">OP_IF</font></div><div class=3D"gmail_d=
efault"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif">=C2=
=A0 =C2=A0 `some operation that requires annex to be <1>`</font></div=
><div class=3D"gmail_default"><font color=3D"#000000" face=3D"arial, helvet=
ica, sans-serif">OP_ELSE</font></div><div class=3D"gmail_default"><font col=
or=3D"#000000" face=3D"arial, helvetica, sans-serif">=C2=A0 =C2=A0 OP_SIZE<=
/font></div><div class=3D"gmail_default"><font color=3D"#000000" face=3D"ar=
ial, helvetica, sans-serif">=C2=A0 =C2=A0 `some operation that requires ann=
ex to be len(annex)=C2=A0+ 1 or does a checksig`</font></div><div class=3D"=
gmail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif=
">OP_ENDIF</font></div><div class=3D"gmail_default"><font color=3D"#000000"=
face=3D"arial, helvetica, sans-serif"><br></font></div><div class=3D"gmail=
_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif">Now=
every time you run this, it requires one more resource unit than the last =
time you ran it, which makes your satisfier use the annex as some sort of &=
quot;scratch space" for a looping construct, where you compute a new a=
nnex, loop with that value, and see if that annex is now accepted by the pr=
ogram.</font></div><div class=3D"gmail_default"><font color=3D"#000000" fac=
e=3D"arial, helvetica, sans-serif"><br></font></div><div class=3D"gmail_def=
ault"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif">In shor=
t, it kinda seems like being able to read the annex off of the stack makes =
witness construction somehow turing complete, because we can use it as a re=
gister/tape for some sort of computational model.</font></div><div class=3D=
"gmail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-seri=
f"><br></font></div><div class=3D"gmail_default"><div class=3D"gmail_defaul=
t"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif">----------=
---------</font></div></div><div class=3D"gmail_default"><font color=3D"#00=
0000" face=3D"arial, helvetica, sans-serif"><br></font></div><div class=3D"=
gmail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif=
">This seems at odds with using the annex as something that just helps you =
heuristically guess =C2=A0computation costs, now it's somehow something=
that acts to make script satisfiers recursive.</font></div><div class=3D"g=
mail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif"=
><br></font></div><div class=3D"gmail_default"><font color=3D"#000000" face=
=3D"arial, helvetica, sans-serif">Because the Annex is signed, and must be =
the same, this can also be inconvenient:</font></div><div class=3D"gmail_de=
fault"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif"><br></=
font></div><div class=3D"gmail_default"><font color=3D"#000000" face=3D"ari=
al, helvetica, sans-serif">Suppose that you have a Miniscript that is somet=
hing like: and(or(PK(A), PK(A')), X, or(PK(B), PK(B'))).</font></di=
v><div class=3D"gmail_default"><font color=3D"#000000" face=3D"arial, helve=
tica, sans-serif"><br></font></div><div class=3D"gmail_default"><font color=
=3D"#000000" face=3D"arial, helvetica, sans-serif">A or A' should sign =
with B or B'. X is some sort of fragment that might require a value tha=
t is unknown (and maybe recursively defined?) so therefore if we send the P=
SBT to A first, which commits to the annex, and then X reads the annex and =
say it must be something else, A must sign again. So you might say, run X f=
irst, and then sign with A and C or B. However, what if the script somehow =
detects the bitstring WHICH_A WHICH_B and has a different Annex per selecti=
on (e.g., interpret the bitstring as a int and annex must =3D=3D that int).=
Now, given and(or(K1, K1'),... or(Kn, Kn')) we end up with needing=
to pre-sign 2**n annex values somehow... this seems problematic theoretica=
lly.</font></div><div class=3D"gmail_default"><font color=3D"#000000" face=
=3D"arial, helvetica, sans-serif"><br></font></div><div class=3D"gmail_defa=
ult"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif">Of cours=
e this wouldn't be miniscript then. Because miniscript is just for the =
well behaved subset of script, and this seems ill behaved. So maybe we'=
re OK?</font></div><div class=3D"gmail_default"><font color=3D"#000000" fac=
e=3D"arial, helvetica, sans-serif"><br></font></div><div class=3D"gmail_def=
ault"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif">But I t=
hink the issue still arises where suppose I have a simple thing like: and(C=
OLD_LOGIC, HOT_LOGIC) where both contains a signature, if COLD_LOGIC and HO=
T_LOGIC can both have different costs, I need to decide what logic each sat=
isfier for the branch is going to use in advance, or sign all possible sums=
of both our annex costs? This could come up if cold/hot e.g. use different=
numbers of signatures / use checksigCISAadd which maybe requires an annex =
argument.</font></div><div class=3D"gmail_default"><font color=3D"#000000" =
face=3D"arial, helvetica, sans-serif"><br></font></div><div class=3D"gmail_=
default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif"><br>=
</font></div><div class=3D"gmail_default"><font color=3D"#000000" face=3D"a=
rial, helvetica, sans-serif"><br></font></div><div class=3D"gmail_default">=
<font color=3D"#000000" face=3D"arial, helvetica, sans-serif">------------<=
/font></div><div class=3D"gmail_default"><font color=3D"#000000" face=3D"ar=
ial, helvetica, sans-serif"><br></font></div><div class=3D"gmail_default"><=
font color=3D"#000000" face=3D"arial, helvetica, sans-serif">It seems like =
one good option is if we just go on and banish the OP_ANNEX. Maybe that sol=
ves some of this? I sort of think so. It definitely seems like we're no=
t supposed to access it via script, given the quote from above:</font></div=
><div class=3D"gmail_default"><font color=3D"#000000" face=3D"arial, helvet=
ica, sans-serif"><br></font></div><div class=3D"gmail_default"><div class=
=3D"gmail_default"><i>Execute the script, according to the applicable scrip=
t rules[11], using the witness stack elements excluding the script s, the c=
ontrol block c, and the annex a if present, as initial stack.</i></div><br>=
</div><div class=3D"gmail_default">If we were meant to have it, we would ha=
ve not nixed it from the stack, no? Or would have made the opcode for it as=
a part of taproot...</div><div class=3D"gmail_default"><font color=3D"#000=
000" face=3D"arial, helvetica, sans-serif"><br></font></div><div class=3D"g=
mail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif"=
>But recall that the annex is committed=C2=A0to by=C2=A0the signature.</fon=
t></div><div class=3D"gmail_default"><font color=3D"#000000" face=3D"arial,=
helvetica, sans-serif"><br></font></div><div class=3D"gmail_default"><font=
color=3D"#000000" face=3D"arial, helvetica, sans-serif">So it's only a=
matter of time till we see some sort of Cat and Schnorr Tricks III the Ann=
ex Edition that lets you use G cleverly to get the annex onto the stack aga=
in, and then it's like we had OP_ANNEX all along, or without CAT, at le=
ast something that we can detect that the value has changed and cause this =
satisfier looping issue somehow.</font></div><div class=3D"gmail_default"><=
font color=3D"#000000" face=3D"arial, helvetica, sans-serif"><br></font></d=
iv><div class=3D"gmail_default"><font color=3D"#000000" face=3D"arial, helv=
etica, sans-serif">Not to mention if we just got OP_TXHASH</font></div><div=
class=3D"gmail_default"><font color=3D"#000000" face=3D"arial, helvetica, =
sans-serif"><br></font></div><div class=3D"gmail_default"><font color=3D"#0=
00000" face=3D"arial, helvetica, sans-serif"><br></font></div><div class=3D=
"gmail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-seri=
f"><br></font></div><div class=3D"gmail_default"><font color=3D"#000000" fa=
ce=3D"arial, helvetica, sans-serif">-----------</font></div><div class=3D"g=
mail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-serif"=
><br></font></div><div class=3D"gmail_default"><font color=3D"#000000" face=
=3D"arial, helvetica, sans-serif"><span>Is the annex bad? After writing thi=
s I sort of think so?</span></font></div><div class=3D"gmail_default"><br><=
/div><div class=3D"gmail_default"><font color=3D"#000000" face=3D"arial, he=
lvetica, sans-serif"><span>One solution would be to... just soft-fork it ou=
t. Always must be 0. When we come up with a use case for something like an =
annex, we can find a way to add it back.=C2=A0 Maybe this means somehow pus=
hing multiple annexes and having an annex stack, where only sub-segments ar=
e signed for the last executed signature? That would solve looping... but w=
ould it break some aggregation thing? Maybe.</span></font></div><div class=
=3D"gmail_default"><font color=3D"#000000" face=3D"arial, helvetica, sans-s=
erif"><br></font></div><div class=3D"gmail_default"><br></div><div class=3D=
"gmail_default">Another solution would be to make it so the annex is never =
committed=C2=A0to and unobservable from the script, but that the annex is a=
lways something that you can run get_annex(stack) to generate the annex. Th=
us it is a hint for validation rules, but not directly readable, and if it =
is modified you figure out the txn was cheaper sometime after you execute t=
he scripts and can decrease the value when you relay. But this sounds like =
something that needs to be a p2p only annex, because consensus we may not c=
are (unless it's something like preallocating memory for validation?).<=
/div><div class=3D"gmail_default"><br></div><div class=3D"gmail_default">--=
---------------------</div><div class=3D"gmail_default"><br></div><div clas=
s=3D"gmail_default">Overall my preference is -- perhaps sadly -- looking li=
ke we should soft-fork it out of our current Checksig (making the policy th=
at it must 0 a consensus rule) and redesign the annex technique later when =
we actually know what it is for with a new checksig or other mechanism. But=
It's not a hard opinion! It just seems like you can't practically =
use the annex for this worklimit type thing *and* observe it from the stack=
meaningfully.</div><div class=3D"gmail_default"><br></div><div class=3D"gm=
ail_default"><br></div><div class=3D"gmail_default"><br></div><div class=3D=
"gmail_default">Thanks for coming to my ted-talk,</div><div class=3D"gmail_=
default"><br></div><div class=3D"gmail_default">Jeremy</div><div class=3D"g=
mail_default"><br></div><div class=3D"gmail_default"><br></div><div><div di=
r=3D"ltr" data-smartmail=3D"gmail_signature"><div dir=3D"ltr">--<br><a href=
=3D"https://twitter.com/JeremyRubin" target=3D"_blank">@JeremyRubin</a><br>=
</div></div></div></div>
--0000000000009c76d605d96cc722--
|