* Calculates the block height and previous block's median time past at * which the transaction will be considered final in the context of BIP 68. * Also removes from the vector of input heights any entries which did not * correspond to sequence locked inputs as they do not affect the calculation. */
| 75 | * correspond to sequence locked inputs as they do not affect the calculation. |
| 76 | */ |
| 77 | static std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>* prevHeights, const CBlockIndex& block) |
| 78 | { |
| 79 | assert(prevHeights->size() == tx.vin.size()); |
| 80 | |
| 81 | // Will be set to the equivalent height- and time-based nLockTime |
| 82 | // values that would be necessary to satisfy all relative lock- |
| 83 | // time constraints given our view of block chain history. |
| 84 | // The semantics of nLockTime are the last invalid height/time, so |
| 85 | // use -1 to have the effect of any height or time being valid. |
| 86 | int nMinHeight = -1; |
| 87 | int64_t nMinTime = -1; |
| 88 | |
| 89 | // tx.nVersion is signed integer so requires cast to unsigned otherwise |
| 90 | // we would be doing a signed comparison and half the range of nVersion |
| 91 | // wouldn't support BIP 68. |
| 92 | bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2 |
| 93 | && flags & LOCKTIME_VERIFY_SEQUENCE; |
| 94 | |
| 95 | // Do not enforce sequence numbers as a relative lock time |
| 96 | // unless we have been instructed to |
| 97 | if (!fEnforceBIP68) { |
| 98 | return std::make_pair(nMinHeight, nMinTime); |
| 99 | } |
| 100 | |
| 101 | for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { |
| 102 | const CTxIn& txin = tx.vin[txinIndex]; |
| 103 | |
| 104 | // Sequence numbers with the most significant bit set are not |
| 105 | // treated as relative lock-times, nor are they given any |
| 106 | // consensus-enforced meaning at this point. |
| 107 | if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) { |
| 108 | // The height of this input is not relevant for sequence locks |
| 109 | (*prevHeights)[txinIndex] = 0; |
| 110 | continue; |
| 111 | } |
| 112 | |
| 113 | int nCoinHeight = (*prevHeights)[txinIndex]; |
| 114 | |
| 115 | if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) { |
| 116 | int64_t nCoinTime = block.GetAncestor(std::max(nCoinHeight-1, 0))->GetMedianTimePast(); |
| 117 | // NOTE: Subtract 1 to maintain nLockTime semantics |
| 118 | // BIP 68 relative lock times have the semantics of calculating |
| 119 | // the first block or time at which the transaction would be |
| 120 | // valid. When calculating the effective block time or height |
| 121 | // for the entire transaction, we switch to using the |
| 122 | // semantics of nLockTime which is the last invalid block |
| 123 | // time or height. Thus we subtract 1 from the calculated |
| 124 | // time or height. |
| 125 | |
| 126 | // Time-based relative lock-times are measured from the |
| 127 | // smallest allowed timestamp of the block containing the |
| 128 | // txout being spent, which is the median time past of the |
| 129 | // block prior. |
| 130 | nMinTime = std::max(nMinTime, nCoinTime + (int64_t)((txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) << CTxIn::SEQUENCE_LOCKTIME_GRANULARITY) - 1); |
| 131 | } else { |
| 132 | nMinHeight = std::max(nMinHeight, nCoinHeight + (int)(txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_MASK) - 1); |
| 133 | } |
| 134 | } |
no test coverage detected