From ce1e31f09ff3bccb5f51ac03c4c8c4708bbaf546 Mon Sep 17 00:00:00 2001 From: Nicolas Pouillard Date: Wed, 19 Nov 2014 22:35:26 +0100 Subject: [PATCH] [script parsing] allows the OP_ prefix --- ParseScript.hs | 195 +++++++++--------- tests/sx-tuto-rawscript-stdin-OP.t/TESTRECIPE | 42 ++++ tests/sx-tuto-rawscript-stdin-OP.t/stdin | 1 + tests/sx-tuto-rawscript-stdin-OP.t/stdout | 1 + 4 files changed, 145 insertions(+), 94 deletions(-) create mode 100644 tests/sx-tuto-rawscript-stdin-OP.t/TESTRECIPE create mode 100644 tests/sx-tuto-rawscript-stdin-OP.t/stdin create mode 100644 tests/sx-tuto-rawscript-stdin-OP.t/stdout diff --git a/ParseScript.hs b/ParseScript.hs index 77219b5..2e9815a 100644 --- a/ParseScript.hs +++ b/ParseScript.hs @@ -21,8 +21,11 @@ wordBoundary = do (c:_) | isAlphaNum c -> pfail _ -> return () +tokP :: Parser a -> Parser () +tokP p = p *> wordBoundary *> skipSpaces + tok :: String -> Parser () -tok s = (string s <|> string (map toUpper s)) *> wordBoundary *> skipSpaces +tok = tokP . string bracket :: Parser a -> Parser a bracket p = tok "[" *> p <* tok "]" @@ -39,13 +42,17 @@ hex = fst . B16.decode . pack <$> some hexDigit <* skipSpaces word8 :: Parser Word8 word8 = read <$> some (satisfy isDigit) <* skipSpaces +op :: String -> Parser () +op s = tokP (foldr1 (<|>) . map string $ [s, up s, "op_" ++ s, "OP_" ++ up s]) + where up = map toUpper + parseOp :: Parser ScriptOp parseOp = opPushData <$> bracket hex -- Constants <|> OP_0 <$ int 0 <|> OP_1NEGATE <$ int (-1) - <|> OP_RESERVED <$ tok "reserved" + <|> OP_RESERVED <$ op "reserved" <|> OP_1 <$ int 1 <|> OP_2 <$ int 2 <|> OP_3 <$ int 3 @@ -64,114 +71,114 @@ parseOp <|> OP_16 <$ int 16 -- Crypto Constants - <|> OP_PUBKEY <$ tok "pubkey" - <|> OP_PUBKEYHASH <$ tok "pubkeyhash" + <|> OP_PUBKEY <$ op "pubkey" + <|> OP_PUBKEYHASH <$ op "pubkeyhash" -- Invalid Opcodes - <|> OP_INVALIDOPCODE <$ tok "invalidopcode" <*> word8 + <|> OP_INVALIDOPCODE <$ op "invalidopcode" <*> word8 -- Flow Control - <|> OP_NOP <$ tok "nop" - <|> OP_VER <$ tok "ver" - <|> OP_IF <$ tok "if" - <|> OP_NOTIF <$ tok "notif" - <|> OP_VERIF <$ tok "verif" - <|> OP_VERNOTIF <$ tok "vernotif" - <|> OP_ELSE <$ tok "else" - <|> OP_ENDIF <$ tok "endif" - <|> OP_VERIFY <$ tok "verify" - <|> OP_RETURN <$ tok "return" + <|> OP_NOP <$ op "nop" + <|> OP_VER <$ op "ver" + <|> OP_IF <$ op "if" + <|> OP_NOTIF <$ op "notif" + <|> OP_VERIF <$ op "verif" + <|> OP_VERNOTIF <$ op "vernotif" + <|> OP_ELSE <$ op "else" + <|> OP_ENDIF <$ op "endif" + <|> OP_VERIFY <$ op "verify" + <|> OP_RETURN <$ op "return" -- Stack Operations - <|> OP_TOALTSTACK <$ tok "toaltstack" - <|> OP_FROMALTSTACK <$ tok "fromaltstack" - <|> OP_2DROP <$ tok "2drop" - <|> OP_2DUP <$ tok "2dup" - <|> OP_3DUP <$ tok "3dup" - <|> OP_2OVER <$ tok "2over" - <|> OP_2ROT <$ tok "2rot" - <|> OP_2SWAP <$ tok "2swap" - <|> OP_IFDUP <$ tok "ifdup" - <|> OP_DEPTH <$ tok "depth" - <|> OP_DROP <$ tok "drop" - <|> OP_DUP <$ tok "dup" - <|> OP_NIP <$ tok "nip" - <|> OP_OVER <$ tok "over" - <|> OP_PICK <$ tok "pick" - <|> OP_ROLL <$ tok "roll" - <|> OP_ROT <$ tok "rot" - <|> OP_SWAP <$ tok "swap" - <|> OP_TUCK <$ tok "tuck" + <|> OP_TOALTSTACK <$ op "toaltstack" + <|> OP_FROMALTSTACK <$ op "fromaltstack" + <|> OP_2DROP <$ op "2drop" + <|> OP_2DUP <$ op "2dup" + <|> OP_3DUP <$ op "3dup" + <|> OP_2OVER <$ op "2over" + <|> OP_2ROT <$ op "2rot" + <|> OP_2SWAP <$ op "2swap" + <|> OP_IFDUP <$ op "ifdup" + <|> OP_DEPTH <$ op "depth" + <|> OP_DROP <$ op "drop" + <|> OP_DUP <$ op "dup" + <|> OP_NIP <$ op "nip" + <|> OP_OVER <$ op "over" + <|> OP_PICK <$ op "pick" + <|> OP_ROLL <$ op "roll" + <|> OP_ROT <$ op "rot" + <|> OP_SWAP <$ op "swap" + <|> OP_TUCK <$ op "tuck" -- Splice - <|> OP_CAT <$ tok "cat" - <|> OP_SUBSTR <$ tok "substr" - <|> OP_LEFT <$ tok "left" - <|> OP_RIGHT <$ tok "right" - <|> OP_SIZE <$ tok "size" + <|> OP_CAT <$ op "cat" + <|> OP_SUBSTR <$ op "substr" + <|> OP_LEFT <$ op "left" + <|> OP_RIGHT <$ op "right" + <|> OP_SIZE <$ op "size" -- Bitwise Logic - <|> OP_INVERT <$ tok "invert" - <|> OP_AND <$ tok "and" - <|> OP_OR <$ tok "or" - <|> OP_XOR <$ tok "xor" - <|> OP_EQUAL <$ tok "equal" - <|> OP_EQUALVERIFY <$ tok "equalverify" - <|> OP_RESERVED1 <$ tok "reserved1" - <|> OP_RESERVED2 <$ tok "reserved2" + <|> OP_INVERT <$ op "invert" + <|> OP_AND <$ op "and" + <|> OP_OR <$ op "or" + <|> OP_XOR <$ op "xor" + <|> OP_EQUAL <$ op "equal" + <|> OP_EQUALVERIFY <$ op "equalverify" + <|> OP_RESERVED1 <$ op "reserved1" + <|> OP_RESERVED2 <$ op "reserved2" -- Arithmetic - <|> OP_1ADD <$ tok "1add" - <|> OP_1SUB <$ tok "1sub" - <|> OP_2MUL <$ tok "2mul" - <|> OP_2DIV <$ tok "2div" - <|> OP_NEGATE <$ tok "negate" - <|> OP_ABS <$ tok "abs" - <|> OP_NOT <$ tok "not" - <|> OP_0NOTEQUAL <$ tok "0notequal" - <|> OP_ADD <$ tok "add" - <|> OP_SUB <$ tok "sub" - <|> OP_MUL <$ tok "mul" - <|> OP_DIV <$ tok "div" - <|> OP_MOD <$ tok "mod" - <|> OP_LSHIFT <$ tok "lshift" - <|> OP_RSHIFT <$ tok "rshift" - <|> OP_BOOLAND <$ tok "booland" - <|> OP_BOOLOR <$ tok "boolor" - <|> OP_NUMEQUAL <$ tok "numequal" - <|> OP_NUMEQUALVERIFY <$ tok "numequalverify" - <|> OP_NUMNOTEQUAL <$ tok "numnotequal" - <|> OP_LESSTHAN <$ tok "lessthan" - <|> OP_GREATERTHAN <$ tok "greaterthan" - <|> OP_LESSTHANOREQUAL <$ tok "lessthanorequal" - <|> OP_GREATERTHANOREQUAL <$ tok "greaterthanorequal" - <|> OP_MIN <$ tok "min" - <|> OP_MAX <$ tok "max" - <|> OP_WITHIN <$ tok "within" + <|> OP_1ADD <$ op "1add" + <|> OP_1SUB <$ op "1sub" + <|> OP_2MUL <$ op "2mul" + <|> OP_2DIV <$ op "2div" + <|> OP_NEGATE <$ op "negate" + <|> OP_ABS <$ op "abs" + <|> OP_NOT <$ op "not" + <|> OP_0NOTEQUAL <$ op "0notequal" + <|> OP_ADD <$ op "add" + <|> OP_SUB <$ op "sub" + <|> OP_MUL <$ op "mul" + <|> OP_DIV <$ op "div" + <|> OP_MOD <$ op "mod" + <|> OP_LSHIFT <$ op "lshift" + <|> OP_RSHIFT <$ op "rshift" + <|> OP_BOOLAND <$ op "booland" + <|> OP_BOOLOR <$ op "boolor" + <|> OP_NUMEQUAL <$ op "numequal" + <|> OP_NUMEQUALVERIFY <$ op "numequalverify" + <|> OP_NUMNOTEQUAL <$ op "numnotequal" + <|> OP_LESSTHAN <$ op "lessthan" + <|> OP_GREATERTHAN <$ op "greaterthan" + <|> OP_LESSTHANOREQUAL <$ op "lessthanorequal" + <|> OP_GREATERTHANOREQUAL <$ op "greaterthanorequal" + <|> OP_MIN <$ op "min" + <|> OP_MAX <$ op "max" + <|> OP_WITHIN <$ op "within" -- Crypto - <|> OP_RIPEMD160 <$ tok "ripemd160" - <|> OP_SHA1 <$ tok "sha1" - <|> OP_SHA256 <$ tok "sha256" - <|> OP_HASH160 <$ tok "hash160" - <|> OP_HASH256 <$ tok "hash256" - <|> OP_CODESEPARATOR <$ tok "codeseparator" - <|> OP_CHECKSIG <$ tok "checksig" - <|> OP_CHECKSIGVERIFY <$ tok "checksigverify" - <|> OP_CHECKMULTISIG <$ tok "checkmultisig" - <|> OP_CHECKMULTISIGVERIFY<$ tok "checkmultisigverify" + <|> OP_RIPEMD160 <$ op "ripemd160" + <|> OP_SHA1 <$ op "sha1" + <|> OP_SHA256 <$ op "sha256" + <|> OP_HASH160 <$ op "hash160" + <|> OP_HASH256 <$ op "hash256" + <|> OP_CODESEPARATOR <$ op "codeseparator" + <|> OP_CHECKSIG <$ op "checksig" + <|> OP_CHECKSIGVERIFY <$ op "checksigverify" + <|> OP_CHECKMULTISIG <$ op "checkmultisig" + <|> OP_CHECKMULTISIGVERIFY<$ op "checkmultisigverify" -- More NOPs - <|> OP_NOP1 <$ tok "nop1" - <|> OP_NOP2 <$ tok "nop2" - <|> OP_NOP3 <$ tok "nop3" - <|> OP_NOP4 <$ tok "nop4" - <|> OP_NOP5 <$ tok "nop5" - <|> OP_NOP6 <$ tok "nop6" - <|> OP_NOP7 <$ tok "nop7" - <|> OP_NOP8 <$ tok "nop8" - <|> OP_NOP9 <$ tok "nop9" - <|> OP_NOP10 <$ tok "nop10" + <|> OP_NOP1 <$ op "nop1" + <|> OP_NOP2 <$ op "nop2" + <|> OP_NOP3 <$ op "nop3" + <|> OP_NOP4 <$ op "nop4" + <|> OP_NOP5 <$ op "nop5" + <|> OP_NOP6 <$ op "nop6" + <|> OP_NOP7 <$ op "nop7" + <|> OP_NOP8 <$ op "nop8" + <|> OP_NOP9 <$ op "nop9" + <|> OP_NOP10 <$ op "nop10" parseScript :: Parser Script parseScript = Script <$> many parseOp diff --git a/tests/sx-tuto-rawscript-stdin-OP.t/TESTRECIPE b/tests/sx-tuto-rawscript-stdin-OP.t/TESTRECIPE new file mode 100644 index 0000000..83c75b8 --- /dev/null +++ b/tests/sx-tuto-rawscript-stdin-OP.t/TESTRECIPE @@ -0,0 +1,42 @@ +#!/bin/bash + +testname=sx-tuto-rawscript-stdin-OP.t +command=hx +args=( rawscript op_dup OP_HASH160 \[ - \] equalverify OP_CHECKSIG ) +exit_code=0 +stdin_file=stdin +stdout_file=stdout +stderr_file=/dev/null +sources=( ) +products=( ) + +# Environment variables: +env_vars=( ) + +setup(){ + : Perform here actions to be run before the tested program +} + +munge(){ + : Munge here the results of the tested program to ease the check +} + +check(){ + check_exit_code && + check_stderr && + check_stdout && + check_products && + : Perform here extra checks on the tested program +} + +explain(){ + explain_exit_code + explain_stdout + explain_stderr + explain_products + : Explain here more potential differences +} + +teardown(){ + : Undo here the actions of setup +} diff --git a/tests/sx-tuto-rawscript-stdin-OP.t/stdin b/tests/sx-tuto-rawscript-stdin-OP.t/stdin new file mode 100644 index 0000000..fe8f376 --- /dev/null +++ b/tests/sx-tuto-rawscript-stdin-OP.t/stdin @@ -0,0 +1 @@ +e60921dbfe1e066113f1c6e0ea15517234187d47 diff --git a/tests/sx-tuto-rawscript-stdin-OP.t/stdout b/tests/sx-tuto-rawscript-stdin-OP.t/stdout new file mode 100644 index 0000000..de974e7 --- /dev/null +++ b/tests/sx-tuto-rawscript-stdin-OP.t/stdout @@ -0,0 +1 @@ +76a914e60921dbfe1e066113f1c6e0ea15517234187d4788ac