| 38 | } |
| 39 | |
| 40 | std::pair<int, int64_t> CalculateSequenceLocks(const CTransaction &tx, int flags, std::vector<int>& prevHeights, const CBlockIndex& block) |
| 41 | { |
| 42 | assert(prevHeights.size() == tx.vin.size()); |
| 43 | |
| 44 | // Will be set to the equivalent height- and time-based nLockTime |
| 45 | // values that would be necessary to satisfy all relative lock- |
| 46 | // time constraints given our view of block chain history. |
| 47 | // The semantics of nLockTime are the last invalid height/time, so |
| 48 | // use -1 to have the effect of any height or time being valid. |
| 49 | int nMinHeight = -1; |
| 50 | int64_t nMinTime = -1; |
| 51 | |
| 52 | // tx.nVersion is signed integer so requires cast to unsigned otherwise |
| 53 | // we would be doing a signed comparison and half the range of nVersion |
| 54 | // wouldn't support BIP 68. |
| 55 | bool fEnforceBIP68 = static_cast<uint32_t>(tx.nVersion) >= 2 |
| 56 | && flags & LOCKTIME_VERIFY_SEQUENCE; |
| 57 | |
| 58 | // Do not enforce sequence numbers as a relative lock time |
| 59 | // unless we have been instructed to |
| 60 | if (!fEnforceBIP68) { |
| 61 | return std::make_pair(nMinHeight, nMinTime); |
| 62 | } |
| 63 | |
| 64 | for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) { |
| 65 | const CTxIn& txin = tx.vin[txinIndex]; |
| 66 | |
| 67 | // Peg-ins have no output height |
| 68 | if (txin.m_is_pegin) { |
| 69 | continue; |
| 70 | } |
| 71 | |
| 72 | // Sequence numbers with the most significant bit set are not |
| 73 | // treated as relative lock-times, nor are they given any |
| 74 | // consensus-enforced meaning at this point. |
| 75 | if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) { |
| 76 | // The height of this input is not relevant for sequence locks |
| 77 | prevHeights[txinIndex] = 0; |
| 78 | continue; |
| 79 | } |
| 80 | |
| 81 | int nCoinHeight = prevHeights[txinIndex]; |
| 82 | |
| 83 | if (txin.nSequence & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) { |
| 84 | int64_t nCoinTime = block.GetAncestor(std::max(nCoinHeight-1, 0))->GetMedianTimePast(); |
| 85 | // NOTE: Subtract 1 to maintain nLockTime semantics |
| 86 | // BIP 68 relative lock times have the semantics of calculating |
| 87 | // the first block or time at which the transaction would be |
| 88 | // valid. When calculating the effective block time or height |
| 89 | // for the entire transaction, we switch to using the |
| 90 | // semantics of nLockTime which is the last invalid block |
| 91 | // time or height. Thus we subtract 1 from the calculated |
| 92 | // time or height. |
| 93 | |
| 94 | // Time-based relative lock-times are measured from the |
| 95 | // smallest allowed timestamp of the block containing the |
| 96 | // txout being spent, which is the median time past of the |
| 97 | // block prior. |
no test coverage detected