From a712fe5e22eb05968a5862fe4efebed9fb0c5ce7 Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Sat, 13 Feb 2016 12:14:03 +0000 Subject: Update BIP112 reference example --- bip-0112.mediawiki | 204 +++++++++++++++++++++++++---------------------------- 1 file changed, 98 insertions(+), 106 deletions(-) diff --git a/bip-0112.mediawiki b/bip-0112.mediawiki index cb9f206..336f9fc 100644 --- a/bip-0112.mediawiki +++ b/bip-0112.mediawiki @@ -229,117 +229,109 @@ The 2-way pegged sidechain requires a new REORGPROOFVERIFY opcode, the semantics Refer to the reference implementation, reproduced below, for the precise semantics and detailed rationale for those semantics. - - /* If this flag set, CTxIn::nSequence is NOT interpreted as a - * relative lock-time. */ - static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 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. */ - static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22); - - /* If CTxIn::nSequence encodes a relative lock-time, this mask is - * applied to extract that lock-time from the sequence field. */ - static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff; +
+/* Below flags apply in the context of BIP 68 */
+/* If this flag set, CTxIn::nSequence is NOT interpreted as a
+ * relative lock-time. */
+static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 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. */
+static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
+
+/* If CTxIn::nSequence encodes a relative lock-time, this mask is
+ * applied to extract that lock-time from the sequence field. */
+static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
    
-    case OP_NOP3:
-    {
-        if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
-            // not enabled; treat as a NOP3
-            if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
-                return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
-            }
-            break;
+case OP_NOP3:
+{
+    if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
+        // not enabled; treat as a NOP3
+        if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
+            return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
         }
-    
-        if (stack.size() < 1)
-            return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
-     
-        // 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.
-        const CScriptNum nSequence(stacktop(-1), fRequireMinimal, 5);
-    
-        // 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)
-            return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME);
-    
-        // To provide for future soft-fork extensibility, if the
-        // operand has the disabled lock-time flag set,
-        // CHECKSEQUENCEVERIFY behaves as a NOP.
-        if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0)
-            break;
-    
-        // Compare the specified sequence number with the input.
-        if (!checker.CheckSequence(nSequence))
-            return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME);
-    
         break;
     }
-    
-    bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const
-    {
-        // Relative lock times are supported by comparing the passed
-        // in operand to the sequence number of the input.
-        const int64_t txToSequence = (int64_t)txTo->vin[nIn].nSequence;
-    
-        // Fail if the transaction's version number is not set high
-        // enough to trigger BIP 68 rules.
-        if (static_cast(txTo->nVersion) < 2)
-            return false;
-    
-        // Sequence numbers with their most significant bit set are not
-        // defined by BIP68. 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 & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG)
-            return false;
-    
-        // Mask off any bits that do not have BIP68 consensus-enforced meaning
-        // before doing the integer comparisons of ::VerifySequence.
-        const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG
-                                     | CTxIn::SEQUENCE_LOCKTIME_MASK;
-        
-        if (!::VerifySequence(txToSequence & nLockTimeMask,
-                              CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG,
-                              nSequence & nLockTimeMask))
-            return false;
-    
-        return true;
-    }
-    
-    static bool VerifySequence(int64_t txToSequence, int64_t nThreshold, const CScriptNum& nSequence)
-    {
-        // There are two kinds of nLockTime: lock-by-blockheight
-        // and lock-by-blocktime, distinguished by whether
-        // nSequence < nThreshold (CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG).
-        //
-        // We want to compare apples to apples, so fail the script
-        // unless the type of nSequence being tested is the same as
-        // the nSequence in the transaction.
-        if (!(
-            (txToSequence <  nThreshold && nSequence <  nThreshold) ||
-            (txToSequence >= nThreshold && nSequence >= nThreshold)
-        ))
-            return false;
-    
-        // Now that we know we're comparing apples-to-apples, the
-        // comparison is a simple numeric one.
-        if (nSequence > txToSequence)
-            return false;
-    
-        return true;
-    }
 
+    if (stack.size() < 1)
+       return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
+
+    // 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.
+    const CScriptNum nSequence(stacktop(-1), fRequireMinimal, 5);
+
+    // 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)
+        return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME);
+
+    // To provide for future soft-fork extensibility, if the
+    // operand has the disabled lock-time flag set,
+    // CHECKSEQUENCEVERIFY behaves as a NOP.
+    if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0)
+        break;
+
+    // Compare the specified sequence number with the input.
+    if (!checker.CheckSequence(nSequence))
+        return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME);
+
+    break;
+}
+    
+bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const
+{
+    // Relative lock times are supported by comparing the passed
+    // in operand to the sequence number of the input.
+    const int64_t txToSequence = (int64_t)txTo->vin[nIn].nSequence;
+
+    // Fail if the transaction's version number is not set high
+    // enough to trigger BIP 68 rules.
+    if (static_cast(txTo->nVersion) < 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 & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG)
+        return false;
+
+    // Mask off any bits that do not have consensus-enforced meaning
+    // before doing the integer comparisons
+    const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG | CTxIn::SEQUENCE_LOCKTIME_MASK;
+    const int64_t txToSequenceMasked = txToSequence & nLockTimeMask;
+    const CScriptNum 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 <  CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked <  CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) ||
+        (txToSequenceMasked >= CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG && nSequenceMasked >= CTxIn::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;
+}
+
==Reference Implementation== -- cgit v1.2.3