mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-01 00:34:01 +02:00
coins: pack Coin height/coinbase consistently
Serialize `Coin` metadata using the canonical (height << 1) | coinbase packing across `Coin` serialization, undo records, and coinstats hashing. Cast the 31-bit `nHeight` bitfield to `uint32_t` before shifting to avoid signed promotion undefined behaviour.
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
* A UTXO entry.
|
||||
*
|
||||
* Serialized format:
|
||||
* - VARINT((coinbase ? 1 : 0) | (height << 1))
|
||||
* - VARINT((height << 1) | (coinbase ? 1 : 0))
|
||||
* - the non-spent CTxOut (via TxOutCompression)
|
||||
*/
|
||||
class Coin
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
template<typename Stream>
|
||||
void Serialize(Stream &s) const {
|
||||
assert(!IsSpent());
|
||||
uint32_t code = nHeight * uint32_t{2} + fCoinBase;
|
||||
uint32_t code{(uint32_t{nHeight} << 1) | uint32_t{fCoinBase}};
|
||||
::Serialize(s, VARINT(code));
|
||||
::Serialize(s, Using<TxOutCompression>(out));
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ template <typename T>
|
||||
static void TxOutSer(T& ss, const COutPoint& outpoint, const Coin& coin)
|
||||
{
|
||||
ss << outpoint;
|
||||
ss << static_cast<uint32_t>((coin.nHeight << 1) + coin.fCoinBase);
|
||||
ss << ((uint32_t{coin.nHeight} << 1) | uint32_t{coin.fCoinBase});
|
||||
ss << coin.out;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@ struct TxInUndoFormatter
|
||||
{
|
||||
template<typename Stream>
|
||||
void Ser(Stream &s, const Coin& txout) {
|
||||
::Serialize(s, VARINT(txout.nHeight * uint32_t{2} + txout.fCoinBase ));
|
||||
uint32_t nCode{(uint32_t{txout.nHeight} << 1) | uint32_t{txout.fCoinBase}};
|
||||
::Serialize(s, VARINT(nCode));
|
||||
if (txout.nHeight > 0) {
|
||||
// Required to maintain compatibility with older undo format.
|
||||
::Serialize(s, (unsigned char)0);
|
||||
|
||||
Reference in New Issue
Block a user