diff options
Diffstat (limited to 'bip-0112.mediawiki')
-rw-r--r-- | bip-0112.mediawiki | 204 |
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== |