summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bip-0112.mediawiki204
1 files 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;
+<pre>
+/* 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<uint32_t>(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<uint32_t>(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;
+}
+</pre>
==Reference Implementation==