Skip to content

Commit 632a7c2

Browse files
committed
Add more interpreter tests and refactor
1 parent 630f4aa commit 632a7c2

File tree

3 files changed

+859
-159
lines changed

3 files changed

+859
-159
lines changed

src/lib/utils/bitcoin/script/interpreter.ts

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import {
1616
isXOnlyKey,
1717
} from '$lib/utils/bitcoin/pubkey'
1818
import {
19-
OP_0,
2019
OP_0NOTEQUAL,
2120
OP_1,
2221
OP_10,
@@ -383,8 +382,8 @@ export const evalScript = (
383382
if (pubkey.length > 0 && !isXOnlyKey(pubkey)) {
384383
warnings.add(`${bytesToHex(pubkey)} is not a valid x-only public key`)
385384
}
386-
return
387385
}
386+
388387
if (tapscript === false) {
389388
if (sig.length > 0 && !isValidDERSignature(sig)) {
390389
warnings.add(`${bytesToHex(sig)} is not a valid DER signature`)
@@ -396,14 +395,20 @@ export const evalScript = (
396395
}
397396
return
398397
}
399-
if (sig.length > 0 && !isAnyKnownSignature(sig)) {
400-
warnings.add(`${bytesToHex(sig)} is not a valid signature`)
401-
}
402-
if (pubkey.length > 0 && !isAnyKnownPublicKey(pubkey)) {
403-
warnings.add(`${bytesToHex(pubkey)} is not a valid public key`)
398+
399+
if (tapscript === undefined) {
400+
if (sig.length > 0 && !isAnyKnownSignature(sig)) {
401+
warnings.add(`${bytesToHex(sig)} is not a valid signature`)
402+
}
403+
if (pubkey.length > 0 && !isAnyKnownPublicKey(pubkey)) {
404+
warnings.add(`${bytesToHex(pubkey)} is not a valid public key`)
405+
}
404406
}
405-
if (isHybridKey(pubkey)) {
406-
warnings.add('hybrid public keys are non-standard')
407+
408+
if (tapscript !== true) {
409+
if (isHybridKey(pubkey)) {
410+
warnings.add('hybrid public keys are non-standard')
411+
}
407412
}
408413
}
409414

@@ -443,7 +448,7 @@ export const evalScript = (
443448
warnings.add(ScriptWarning.cat)
444449
}
445450

446-
if (opcode >= 1 && opcode <= OP_PUSHDATA4) {
451+
if (opcode <= OP_PUSHDATA4) {
447452
let pushBytes: number
448453

449454
if (opcode <= 75) {
@@ -488,11 +493,6 @@ export const evalScript = (
488493
}
489494

490495
switch (opcode) {
491-
case OP_0:
492-
stack.push(new Uint8Array())
493-
loopHighlight = { count: 1, color: 'stack' }
494-
break
495-
496496
case OP_1NEGATE:
497497
case OP_1:
498498
case OP_2:
@@ -618,6 +618,9 @@ export const evalScript = (
618618
case OP_RETURN:
619619
return setError(SCRIPT_ERR_OP_RETURN)
620620

621+
//
622+
// Stack ops
623+
//
621624
case OP_TOALTSTACK:
622625
if (stack.length === 0) {
623626
return setStackSizeError(1)
@@ -931,7 +934,7 @@ export const evalScript = (
931934
bn = -bn
932935
break
933936
case OP_ABS:
934-
if (bn < 0) bn = -bn
937+
bn = Math.max(bn, -bn)
935938
break
936939
case OP_NOT:
937940
bn = Number(bn === 0)
@@ -990,8 +993,6 @@ export const evalScript = (
990993
bn = bn1 !== 0 || bn2 !== 0
991994
break
992995
case OP_NUMEQUAL:
993-
bn = bn1 === bn2
994-
break
995996
case OP_NUMEQUALVERIFY:
996997
bn = bn1 === bn2
997998
break
@@ -1011,10 +1012,10 @@ export const evalScript = (
10111012
bn = bn1 >= bn2
10121013
break
10131014
case OP_MIN:
1014-
bn = bn1 < bn2 ? bn1 : bn2
1015+
bn = Math.min(bn1, bn2)
10151016
break
10161017
case OP_MAX:
1017-
bn = bn1 > bn2 ? bn1 : bn2
1018+
bn = Math.max(bn1, bn2)
10181019
break
10191020
}
10201021
if (opcode === OP_NUMEQUALVERIFY && !bn) {
@@ -1170,10 +1171,10 @@ export const evalScript = (
11701171
: `number of public keys cannot be higher than ${MAX_PUBKEYS_PER_MULTISIG}`
11711172
return setError(SCRIPT_ERR_PUBKEY_COUNT, message)
11721173
}
1173-
let ikey = ++i
1174+
const ikey = ++i
11741175
// ikey2 is the position of last non-signature item in the stack. Top stack item = 1.
11751176
// With SCRIPT_VERIFY_NULLFAIL, this is used for cleanup if operation fails.
1176-
let ikey2 = nKeysCount + 2
1177+
const ikey2 = nKeysCount + 2
11771178
i += nKeysCount
11781179
if (stack.length < i) {
11791180
return setStackSizeError(i)
@@ -1188,7 +1189,7 @@ export const evalScript = (
11881189
: `number of signatures cannot be higher than number of public keys`
11891190
return setError(SCRIPT_ERR_SIG_COUNT, message)
11901191
}
1191-
let isig = ++i
1192+
const isig = ++i
11921193
i += nSigsCount
11931194
if (stack.length < i) {
11941195
return setStackSizeError(i)
@@ -1204,10 +1205,8 @@ export const evalScript = (
12041205
checkSignaturePubkeyWarnings(vchSig, vchPubKey, false)
12051206

12061207
if (fOk) {
1207-
isig++
12081208
nSigsCount--
12091209
}
1210-
ikey++
12111210
nKeysCount--
12121211

12131212
// If there are more signatures left than keys left,
@@ -1223,7 +1222,6 @@ export const evalScript = (
12231222

12241223
// Clean up stack of actual arguments
12251224
while (i-- > 1) {
1226-
if (ikey2 > 0) ikey2--
12271225
popstack()
12281226
}
12291227

@@ -1233,12 +1231,6 @@ export const evalScript = (
12331231
// Unfortunately this is a potential source of mutability,
12341232
// so optionally verify it is exactly equal to zero prior
12351233
// to removing it from the stack.
1236-
if (stack.length === 0) {
1237-
return setError(
1238-
SCRIPT_ERR_INVALID_STACK_OPERATION,
1239-
'OP_CHECKMULTISIG requires a dummy stack item',
1240-
)
1241-
}
12421234
if (stacktop(-1)!.length > 0) {
12431235
loopHighlight = { count: 1, color: 'error' }
12441236
return setError(SCRIPT_ERR_SIG_NULLDUMMY)

0 commit comments

Comments
 (0)