1
0
mirror of https://github.com/bitcoin/bips.git synced 2025-05-12 12:03:29 +00:00

Update BIP112 reference example

This commit is contained in:
BtcDrak 2016-02-13 12:14:03 +00:00
parent 561e1b77bd
commit a712fe5e22

View File

@ -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 Refer to the reference implementation, reproduced below, for the precise
semantics and detailed rationale for those semantics. semantics and detailed rationale for those semantics.
<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 this flag set, CTxIn::nSequence is NOT interpreted as a /* If CTxIn::nSequence encodes a relative lock-time and this flag
* relative lock-time. */ * is set, the relative lock-time has units of 512 seconds,
static const uint32_t SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31); * 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 and this flag /* If CTxIn::nSequence encodes a relative lock-time, this mask is
* is set, the relative lock-time has units of 512 seconds, * applied to extract that lock-time from the sequence field. */
* otherwise it specifies blocks with a granularity of 1. */ static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
static const uint32_t SEQUENCE_LOCKTIME_TYPE_FLAG = (1 << 22);
/* If CTxIn::nSequence encodes a relative lock-time, this mask is case OP_NOP3:
* applied to extract that lock-time from the sequence field. */ {
static const uint32_t SEQUENCE_LOCKTIME_MASK = 0x0000ffff; if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
// not enabled; treat as a NOP3
case OP_NOP3: if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) {
{ return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);
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;
} }
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; break;
} }
bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const if (stack.size() < 1)
{ return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
// 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 // Note that elsewhere numeric opcodes are limited to
// enough to trigger BIP 68 rules. // operands in the range -2**31+1 to 2**31-1, however it is
if (static_cast<uint32_t>(txTo->nVersion) < 2) // legal for opcodes to produce results exceeding that
return false; // 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);
// Sequence numbers with their most significant bit set are not // In the rare event that the argument may be < 0 due to
// defined by BIP68. Testing that the transaction's sequence // some arithmetic being done first, you can always use
// number do not have this bit set prevents using this property // 0 MAX CHECKSEQUENCEVERIFY.
// to get around a CHECKSEQUENCEVERIFY check. if (nSequence < 0)
if (txToSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME);
return false;
// Mask off any bits that do not have BIP68 consensus-enforced meaning // To provide for future soft-fork extensibility, if the
// before doing the integer comparisons of ::VerifySequence. // operand has the disabled lock-time flag set,
const uint32_t nLockTimeMask = CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG // CHECKSEQUENCEVERIFY behaves as a NOP.
| CTxIn::SEQUENCE_LOCKTIME_MASK; if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != 0)
break;
if (!::VerifySequence(txToSequence & nLockTimeMask, // Compare the specified sequence number with the input.
CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG, if (!checker.CheckSequence(nSequence))
nSequence & nLockTimeMask)) return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME);
return false;
return true; break;
} }
static bool VerifySequence(int64_t txToSequence, int64_t nThreshold, const CScriptNum& nSequence) bool TransactionSignatureChecker::CheckSequence(const CScriptNum& nSequence) const
{ {
// There are two kinds of nLockTime: lock-by-blockheight // Relative lock times are supported by comparing the passed
// and lock-by-blocktime, distinguished by whether // in operand to the sequence number of the input.
// nSequence < nThreshold (CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG). const int64_t txToSequence = (int64_t)txTo->vin[nIn].nSequence;
//
// 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 // Fail if the transaction's version number is not set high
// comparison is a simple numeric one. // enough to trigger BIP 68 rules.
if (nSequence > txToSequence) if (static_cast<uint32_t>(txTo->nVersion) < 2)
return false; return false;
return true; // 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== ==Reference Implementation==