From bb176dab4d067752e7fb283f5c1fb5c47f589e2c Mon Sep 17 00:00:00 2001 From: Nicola Atzei Date: Tue, 4 Jul 2017 01:07:47 +0200 Subject: [PATCH] Implement the CHECKSEQUENCEVERIFY script operator. This also adds CSV-related tests from Bitcoin Core into script_tests.json, tx_valid.json and tx_invalid.json. --- .../java/org/bitcoinj/core/Transaction.java | 14 +++ .../main/java/org/bitcoinj/script/Script.java | 97 +++++++++++++++++-- .../org/bitcoinj/script/ScriptOpCodes.java | 8 +- .../java/org/bitcoinj/script/ScriptTest.java | 2 +- .../org/bitcoinj/script/script_tests.json | 22 +++-- .../org/bitcoinj/script/tx_invalid.json | 54 +++++++++++ .../org/bitcoinj/script/tx_valid.json | 84 ++++++++++++++++ 7 files changed, 265 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/Transaction.java b/core/src/main/java/org/bitcoinj/core/Transaction.java index da947ae8..14ab317c 100644 --- a/core/src/main/java/org/bitcoinj/core/Transaction.java +++ b/core/src/main/java/org/bitcoinj/core/Transaction.java @@ -192,6 +192,20 @@ public class Transaction extends ChildMessage { @Nullable private String memo; + /* Below flags apply in the context of BIP 68 */ + /* If this flag set, CTxIn::nSequence is NOT interpreted as a + * relative lock-time. */ + public static final long SEQUENCE_LOCKTIME_DISABLE_FLAG = 1L << 31; + + /* If CTxIn::nSequence encodes a relative lock-time and this flag + * is set, the relative lock-time has units of 512 seconds, + * otherwise it specifies blocks with a granularity of 1. */ + public static final long SEQUENCE_LOCKTIME_TYPE_FLAG = 1L << 22; + + /* If CTxIn::nSequence encodes a relative lock-time, this mask is + * applied to extract that lock-time from the sequence field. */ + public static final long SEQUENCE_LOCKTIME_MASK = 0x0000ffff; + public Transaction(NetworkParameters params) { super(params); version = 1; diff --git a/core/src/main/java/org/bitcoinj/script/Script.java b/core/src/main/java/org/bitcoinj/script/Script.java index 915540fc..83aef3db 100644 --- a/core/src/main/java/org/bitcoinj/script/Script.java +++ b/core/src/main/java/org/bitcoinj/script/Script.java @@ -75,7 +75,8 @@ public class Script { MINIMALDATA, // Require minimal encodings for all push operations DISCOURAGE_UPGRADABLE_NOPS, // Discourage use of NOPs reserved for upgrades (NOP1-10) CLEANSTACK, // Require that only a single stack element remains after evaluation. - CHECKLOCKTIMEVERIFY // Enable CHECKLOCKTIMEVERIFY operation + CHECKLOCKTIMEVERIFY, // Enable CHECKLOCKTIMEVERIFY operation + CHECKSEQUENCEVERIFY // Enable CHECKSEQUENCEVERIFY operation } public static final EnumSet ALL_VERIFY_FLAGS = EnumSet.allOf(VerifyFlag.class); @@ -816,7 +817,7 @@ public class Script { /** * Cast a script chunk to a BigInteger. Normally you would want * {@link #castToBigInteger(byte[])} instead, this is only for cases where - * the normal maximum length does not apply (i.e. CHECKLOCKTIMEVERIFY). + * the normal maximum length does not apply (i.e. CHECKLOCKTIMEVERIFY, CHECKSEQUENCEVERIFY). * * @param maxLength the maximum length in bytes. * @throws ScriptException if the chunk is longer than the specified maximum. @@ -1353,10 +1354,19 @@ public class Script { } break; } - executeCheckLockTimeVerify(txContainingThis, (int) index, script, stack, lastCodeSepLocation, opcode, verifyFlags); + executeCheckLockTimeVerify(txContainingThis, (int) index, stack); + break; + case OP_CHECKSEQUENCEVERIFY: + if (!verifyFlags.contains(VerifyFlag.CHECKSEQUENCEVERIFY)) { + // not enabled; treat as a NOP3 + if (verifyFlags.contains(VerifyFlag.DISCOURAGE_UPGRADABLE_NOPS)) { + throw new ScriptException("Script used a reserved opcode " + opcode); + } + break; + } + executeCheckSequenceVerify(txContainingThis, (int) index, stack); break; case OP_NOP1: - case OP_NOP3: case OP_NOP4: case OP_NOP5: case OP_NOP6: @@ -1383,9 +1393,7 @@ public class Script { } // This is more or less a direct translation of the code in Bitcoin Core - private static void executeCheckLockTimeVerify(Transaction txContainingThis, int index, Script script, LinkedList stack, - int lastCodeSepLocation, int opcode, - Set verifyFlags) throws ScriptException { + private static void executeCheckLockTimeVerify(Transaction txContainingThis, int index, LinkedList stack) throws ScriptException { if (stack.size() < 1) throw new ScriptException("Attempted OP_CHECKLOCKTIMEVERIFY on a stack with size < 1"); @@ -1422,6 +1430,81 @@ public class Script { throw new ScriptException("Transaction contains a final transaction input for a CHECKLOCKTIMEVERIFY script."); } + private static void executeCheckSequenceVerify(Transaction txContainingThis, int index, LinkedList stack) throws ScriptException { + if (stack.size() < 1) + throw new ScriptException("Attempted OP_CHECKLOCKTIMEVERIFY on a stack with size < 1"); + + // Note that elsewhere numeric opcodes are limited to + // operands in the range -2**31+1 to 2**31-1, however it is + // legal for opcodes to produce results exceeding that + // range. This limitation is implemented by CScriptNum's + // default 4-byte limit. + // + // Thus as a special case we tell CScriptNum to accept up + // to 5-byte bignums, which are good until 2**39-1, well + // beyond the 2**32-1 limit of the nSequence field itself. + final long nSequence = castToBigInteger(stack.getLast(), 5).longValue(); + + // In the rare event that the argument may be < 0 due to + // some arithmetic being done first, you can always use + // 0 MAX CHECKSEQUENCEVERIFY. + if (nSequence < 0) + throw new ScriptException("Negative sequence"); + + // To provide for future soft-fork extensibility, if the + // operand has the disabled lock-time flag set, + // CHECKSEQUENCEVERIFY behaves as a NOP. + if ((nSequence & Transaction.SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) + return; + + // Compare the specified sequence number with the input. + if (!checkSequence(nSequence, txContainingThis, index)) + throw new ScriptException("Unsatisfied CHECKLOCKTIMEVERIFY lock time"); + } + + private static boolean checkSequence(long nSequence, Transaction txContainingThis, int index) { + // Relative lock times are supported by comparing the passed + // in operand to the sequence number of the input. + long txToSequence = txContainingThis.getInput(index).getSequenceNumber(); + + // Fail if the transaction's version number is not set high + // enough to trigger BIP 68 rules. + if (txContainingThis.getVersion() < 2) + return false; + + // Sequence numbers with their most significant bit set are not + // consensus constrained. Testing that the transaction's sequence + // number do not have this bit set prevents using this property + // to get around a CHECKSEQUENCEVERIFY check. + if ((txToSequence & Transaction.SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0) + return false; + + // Mask off any bits that do not have consensus-enforced meaning + // before doing the integer comparisons + long nLockTimeMask = Transaction.SEQUENCE_LOCKTIME_TYPE_FLAG | Transaction.SEQUENCE_LOCKTIME_MASK; + long txToSequenceMasked = txToSequence & nLockTimeMask; + long nSequenceMasked = nSequence & nLockTimeMask; + + // There are two kinds of nSequence: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // nSequenceMasked < CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG. + // + // We want to compare apples to apples, so fail the script + // unless the type of nSequenceMasked being tested is the same as + // the nSequenceMasked in the transaction. + if (!((txToSequenceMasked < Transaction.SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked < Transaction.SEQUENCE_LOCKTIME_TYPE_FLAG) || + (txToSequenceMasked >= Transaction.SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= Transaction.SEQUENCE_LOCKTIME_TYPE_FLAG))) { + return false; + } + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nSequenceMasked > txToSequenceMasked) + return false; + + return true; + } + private static void executeCheckSig(Transaction txContainingThis, int index, Script script, LinkedList stack, int lastCodeSepLocation, int opcode, Set verifyFlags) throws ScriptException { diff --git a/core/src/main/java/org/bitcoinj/script/ScriptOpCodes.java b/core/src/main/java/org/bitcoinj/script/ScriptOpCodes.java index 7a50eea0..3a25b24c 100644 --- a/core/src/main/java/org/bitcoinj/script/ScriptOpCodes.java +++ b/core/src/main/java/org/bitcoinj/script/ScriptOpCodes.java @@ -145,13 +145,16 @@ public class ScriptOpCodes { // block state /** Check lock time of the block. Introduced in BIP 65, replacing OP_NOP2 */ public static final int OP_CHECKLOCKTIMEVERIFY = 0xb1; + public static final int OP_CHECKSEQUENCEVERIFY = 0xb2; // expansion public static final int OP_NOP1 = 0xb0; /** Deprecated by BIP 65 */ @Deprecated public static final int OP_NOP2 = OP_CHECKLOCKTIMEVERIFY; - public static final int OP_NOP3 = 0xb2; + /** Deprecated by BIP 112 */ + @Deprecated + public static final int OP_NOP3 = OP_CHECKSEQUENCEVERIFY; public static final int OP_NOP4 = 0xb3; public static final int OP_NOP5 = 0xb4; public static final int OP_NOP6 = 0xb5; @@ -265,7 +268,7 @@ public class ScriptOpCodes { .put(OP_CHECKMULTISIGVERIFY, "CHECKMULTISIGVERIFY") .put(OP_NOP1, "NOP1") .put(OP_CHECKLOCKTIMEVERIFY, "CHECKLOCKTIMEVERIFY") - .put(OP_NOP3, "NOP3") + .put(OP_CHECKSEQUENCEVERIFY, "CHECKSEQUENCEVERIFY") .put(OP_NOP4, "NOP4") .put(OP_NOP5, "NOP5") .put(OP_NOP6, "NOP6") @@ -378,6 +381,7 @@ public class ScriptOpCodes { .put("CHECKMULTISIGVERIFY", OP_CHECKMULTISIGVERIFY) .put("NOP1", OP_NOP1) .put("CHECKLOCKTIMEVERIFY", OP_CHECKLOCKTIMEVERIFY) + .put("CHECKSEQUENCEVERIFY", OP_CHECKSEQUENCEVERIFY) .put("NOP2", OP_NOP2) .put("NOP3", OP_NOP3) .put("NOP4", OP_NOP4) diff --git a/core/src/test/java/org/bitcoinj/script/ScriptTest.java b/core/src/test/java/org/bitcoinj/script/ScriptTest.java index 07d9b482..00c862b2 100644 --- a/core/src/test/java/org/bitcoinj/script/ScriptTest.java +++ b/core/src/test/java/org/bitcoinj/script/ScriptTest.java @@ -300,7 +300,7 @@ public class ScriptTest { Transaction txSpend = buildSpendingTransaction(txCredit, scriptSig); scriptSig.correctlySpends(txSpend, 0, scriptPubKey, verifyFlags); if (!expectedError.equals("OK")) - fail(); + fail(test + " is expected to fail"); } catch (ScriptException e) { if (expectedError.equals("OK")) { // TODO check for specific error diff --git a/core/src/test/resources/org/bitcoinj/script/script_tests.json b/core/src/test/resources/org/bitcoinj/script/script_tests.json index 8f720c1e..ffae5ed4 100644 --- a/core/src/test/resources/org/bitcoinj/script/script_tests.json +++ b/core/src/test/resources/org/bitcoinj/script/script_tests.json @@ -232,8 +232,8 @@ ["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC", "OK"], -["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], +["1","NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC", "OK"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC", "OK"], ["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "OK", "Discourage NOPx flag allows OP_NOP"], @@ -443,7 +443,7 @@ ["NOP", "NOP1 1", "P2SH,STRICTENC", "OK"], ["NOP", "CHECKLOCKTIMEVERIFY 1", "P2SH,STRICTENC", "OK"], -["NOP", "NOP3 1", "P2SH,STRICTENC", "OK"], +["NOP", "CHECKSEQUENCEVERIFY 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP4 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP5 1", "P2SH,STRICTENC", "OK"], ["NOP", "NOP6 1", "P2SH,STRICTENC", "OK"], @@ -700,6 +700,8 @@ ["0x17 0x3014020002107777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Zero-length R is correctly encoded"], ["0x17 0x3014021077777777777777777777777777777777020001", "0 CHECKSIG NOT", "", "OK", "Zero-length S is correctly encoded for DERSIG"], ["0x27 0x302402107777777777777777777777777777777702108777777777777777777777777777777701", "0 CHECKSIG NOT", "", "OK", "Negative S is correctly encoded"], + +["2147483648", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "OK", "CSV passes if stack top bit 1 << 31 is set"], ["", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "Test the test: we should have an empty stack after scriptSig evaluation"], [" ", "DEPTH", "P2SH,STRICTENC", "EVAL_FALSE", "and multiple spaces should not change that."], @@ -855,13 +857,13 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "DISABLED_OPCODE", "disabled"], -["1","NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], -["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["1", "NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], +["'NOP_1_to_10' NOP1 CHECKLOCKTIMEVERIFY CHECKSEQUENCEVERIFY NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE"], ["Ensure 100% coverage of discouraged NOPS"], ["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "CHECKLOCKTIMEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], -["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], +["1", "CHECKSEQUENCEVERIFY", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "DISCOURAGE_UPGRADABLE_NOPS"], @@ -1119,5 +1121,13 @@ ["0x00", "'00' EQUAL", "P2SH,STRICTENC", "EVAL_FALSE", "Basic OP_0 execution"], +["CHECKSEQUENCEVERIFY tests"], +["", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "INVALID_STACK_OPERATION", "CSV automatically fails on an empty stack"], +["-1", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "NEGATIVE_LOCKTIME", "CSV automatically fails if stack top is negative"], +["0x0100", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY,MINIMALDATA", "UNKNOWN_ERROR", "CSV fails if stack top is not minimally encoded"], +["0", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", "CSV fails if stack top bit 1 << 31 is set and the tx version < 2"], +["4294967296", "CHECKSEQUENCEVERIFY", "CHECKSEQUENCEVERIFY", "UNSATISFIED_LOCKTIME", + "CSV fails if stack top bit 1 << 31 is not set, and tx version < 2"], + ["The End"] ] diff --git a/core/src/test/resources/org/bitcoinj/script/tx_invalid.json b/core/src/test/resources/org/bitcoinj/script/tx_invalid.json index 13e83a38..50220364 100644 --- a/core/src/test/resources/org/bitcoinj/script/tx_invalid.json +++ b/core/src/test/resources/org/bitcoinj/script/tx_invalid.json @@ -182,5 +182,59 @@ [[["a54b3bff74c910adff4f81b641587440c9f3b02a67c69b06d4eea36c0d199bac", 0, "DUP HASH160 0x14 0x33b9fe6942f268ae728136046e638c8863bed91f EQUALVERIFY CHECKSIG"]], "0100000001ac9b190d6ca3eed4069bc6672ab0f3c940745841b6814fffad10c974ff3b4ba5000000006c493046022100c16257354c7ec7fedda7ce724abfc6a8f26fd433d08b1a11bd01a8f0f157b1fb0221009069419fa4454cd52f1d3219c395b96c3dc0404257196f96d819d71e4f95b8290121039770779101a01dbbf6c25466df8869e648dc75a51d64ebf5136c824c32fcc9c8ffffffff0100000000000000001976a914aaf0529f46a86271255621ed566e79e67345916d88ac00000000", "P2SH,LOW_S"], +["CHECKSEQUENCEVERIFY tests"], + +["By-height locks, with argument just beyond txin.nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["By-time locks, with argument just beyond txin.nSequence (but within numerical boundries)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194305 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument missing"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument negative with by-blockheight txin.nSequence=0"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument negative with by-blocktime txin.nSequence=CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "-1 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument/tx height/time mismatch, both versions"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["6 byte non-minimally-encoded arguments are invalid even if their contents are valid"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x06 0x000000000000 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Failure due to failing CHECKSEQUENCEVERIFY in scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"02000000010001000000000000000000000000000000000000000000000000000000000000000000000251b2000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Failure due to failing CHECKSEQUENCEVERIFY in redeemScript"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]], +"0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Failure due to insufficient tx.nVersion (<2)"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKSEQUENCEVERIFY 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]], +"010000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/core/src/test/resources/org/bitcoinj/script/tx_valid.json b/core/src/test/resources/org/bitcoinj/script/tx_valid.json index 47700aec..f021da8b 100644 --- a/core/src/test/resources/org/bitcoinj/script/tx_valid.json +++ b/core/src/test/resources/org/bitcoinj/script/tx_valid.json @@ -232,5 +232,89 @@ [[["a54b3bff74c910adff4f81b641587440c9f3b02a67c69b06d4eea36c0d199bac", 0, "DUP HASH160 0x14 0x33b9fe6942f268ae728136046e638c8863bed91f EQUALVERIFY CHECKSIG"]], "0100000001ac9b190d6ca3eed4069bc6672ab0f3c940745841b6814fffad10c974ff3b4ba5000000006c493046022100c16257354c7ec7fedda7ce724abfc6a8f26fd433d08b1a11bd01a8f0f157b1fb0221009069419fa4454cd52f1d3219c395b96c3dc0404257196f96d819d71e4f95b8290121039770779101a01dbbf6c25466df8869e648dc75a51d64ebf5136c824c32fcc9c8ffffffff0100000000000000001976a914aaf0529f46a86271255621ed566e79e67345916d88ac00000000", "P2SH"], +["CHECKSEQUENCEVERIFY tests"], + +["By-height locks, with argument == 0 and == txin.nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "65535 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["By-time locks, with argument == 0 and == txin.nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff40000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4259839 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Upper sequence with upper sequence is fine"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000800100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000800100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000feffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument 2^31 with various nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483648 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument 2^32-1 with various nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4294967295 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Argument 3<<31 with various nSequence"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffbf7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffff7f0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "6442450944 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff0100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["5 byte non-minimally-encoded operandss are valid"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x05 0x0000000000 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["The argument can be calculated rather than created directly by a PUSHDATA"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194303 1ADD CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "4194304 1SUB CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000ffff00000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["An ADD producing a 5-byte result that sets CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 65536 CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "2147483647 4259840 ADD CHECKSEQUENCEVERIFY 1"]], +"020000000100010000000000000000000000000000000000000000000000000000000000000000000000000040000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Valid CHECKSEQUENCEVERIFY in scriptSig"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "1"]], +"02000000010001000000000000000000000000000000000000000000000000000000000000000000000251b2010000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + +["Valid CHECKSEQUENCEVERIFY in redeemScript"], +[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7c17aff532f22beb54069942f9bf567a66133eaf EQUAL"]], +"0200000001000100000000000000000000000000000000000000000000000000000000000000000000030251b2010000000100000000000000000000000000", "P2SH,CHECKSEQUENCEVERIFY"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ]