2013-11-05 02:47:07 +01:00
|
|
|
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
2016-12-31 19:01:21 +01:00
|
|
|
// Copyright (c) 2009-2016 The Bitcoin Core developers
|
2014-10-31 01:43:19 +01:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
2013-11-05 02:47:07 +01:00
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2014-08-28 22:21:03 +02:00
|
|
|
|
2013-11-05 02:47:07 +01:00
|
|
|
#ifndef BITCOIN_COINS_H
|
|
|
|
#define BITCOIN_COINS_H
|
|
|
|
|
2017-04-07 04:04:19 +02:00
|
|
|
#include "primitives/transaction.h"
|
2014-10-19 04:28:43 +02:00
|
|
|
#include "compressor.h"
|
2015-07-17 19:46:18 +02:00
|
|
|
#include "core_memusage.h"
|
2016-05-06 20:47:12 +02:00
|
|
|
#include "hash.h"
|
2015-05-04 01:31:11 +02:00
|
|
|
#include "memusage.h"
|
2013-11-05 02:47:07 +01:00
|
|
|
#include "serialize.h"
|
|
|
|
#include "uint256.h"
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include <boost/foreach.hpp>
|
2017-04-21 14:26:40 +02:00
|
|
|
#include <unordered_map>
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2017-04-25 20:29:23 +02:00
|
|
|
/**
|
|
|
|
* A UTXO entry.
|
|
|
|
*
|
|
|
|
* Serialized format:
|
|
|
|
* - VARINT((coinbase ? 1 : 0) | (height << 1))
|
|
|
|
* - the non-spent CTxOut (via CTxOutCompressor)
|
|
|
|
*/
|
|
|
|
class Coin
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
//! whether the containing transaction was a coinbase
|
|
|
|
bool fCoinBase;
|
|
|
|
|
|
|
|
//! unspent transaction output
|
|
|
|
CTxOut out;
|
|
|
|
|
|
|
|
//! at which height the containing transaction was included in the active block chain
|
|
|
|
uint32_t nHeight;
|
|
|
|
|
|
|
|
//! construct a Coin from a CTxOut and height/coinbase properties.
|
|
|
|
Coin(CTxOut&& outIn, int nHeightIn, bool fCoinBaseIn) : fCoinBase(fCoinBaseIn), out(std::move(outIn)), nHeight(nHeightIn) {}
|
|
|
|
Coin(const CTxOut& outIn, int nHeightIn, bool fCoinBaseIn) : fCoinBase(fCoinBaseIn), out(outIn), nHeight(nHeightIn) {}
|
|
|
|
|
|
|
|
void Clear() {
|
|
|
|
out.SetNull();
|
|
|
|
fCoinBase = false;
|
|
|
|
nHeight = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! empty constructor
|
|
|
|
Coin() : fCoinBase(false), nHeight(0) { }
|
|
|
|
|
|
|
|
bool IsCoinBase() const {
|
|
|
|
return fCoinBase;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Stream>
|
|
|
|
void Serialize(Stream &s) const {
|
|
|
|
assert(!IsPruned());
|
|
|
|
uint32_t code = nHeight * 2 + fCoinBase;
|
|
|
|
::Serialize(s, VARINT(code));
|
|
|
|
::Serialize(s, CTxOutCompressor(REF(out)));
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename Stream>
|
|
|
|
void Unserialize(Stream &s) {
|
|
|
|
uint32_t code = 0;
|
|
|
|
::Unserialize(s, VARINT(code));
|
|
|
|
nHeight = code >> 1;
|
|
|
|
fCoinBase = code & 1;
|
|
|
|
::Unserialize(s, REF(CTxOutCompressor(out)));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsPruned() const {
|
|
|
|
return out.IsNull();
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t DynamicMemoryUsage() const {
|
|
|
|
return memusage::DynamicUsage(out.scriptPubKey);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-11-05 02:47:07 +01:00
|
|
|
class CCoins
|
|
|
|
{
|
|
|
|
public:
|
2014-10-31 01:43:19 +01:00
|
|
|
//! whether transaction is a coinbase
|
2013-11-05 02:47:07 +01:00
|
|
|
bool fCoinBase;
|
|
|
|
|
2014-10-31 01:43:19 +01:00
|
|
|
//! unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped
|
2013-11-05 02:47:07 +01:00
|
|
|
std::vector<CTxOut> vout;
|
|
|
|
|
2014-10-31 01:43:19 +01:00
|
|
|
//! at which height this transaction was included in the active block chain
|
2013-11-05 02:47:07 +01:00
|
|
|
int nHeight;
|
|
|
|
|
2014-10-31 01:43:19 +01:00
|
|
|
//! empty constructor
|
2017-04-25 20:29:18 +02:00
|
|
|
CCoins() : fCoinBase(false), vout(0), nHeight(0) { }
|
2013-11-05 02:47:07 +01:00
|
|
|
|
|
|
|
template<typename Stream>
|
2016-10-29 01:29:17 +02:00
|
|
|
void Unserialize(Stream &s) {
|
2013-11-05 02:47:07 +01:00
|
|
|
unsigned int nCode = 0;
|
|
|
|
// version
|
2017-04-25 20:29:18 +02:00
|
|
|
int nVersionDummy;
|
|
|
|
::Unserialize(s, VARINT(nVersionDummy));
|
2013-11-05 02:47:07 +01:00
|
|
|
// header code
|
2016-10-29 01:29:17 +02:00
|
|
|
::Unserialize(s, VARINT(nCode));
|
2013-11-05 02:47:07 +01:00
|
|
|
fCoinBase = nCode & 1;
|
|
|
|
std::vector<bool> vAvail(2, false);
|
2014-09-06 21:59:59 +02:00
|
|
|
vAvail[0] = (nCode & 2) != 0;
|
|
|
|
vAvail[1] = (nCode & 4) != 0;
|
2013-11-05 02:47:07 +01:00
|
|
|
unsigned int nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1);
|
|
|
|
// spentness bitmask
|
|
|
|
while (nMaskCode > 0) {
|
|
|
|
unsigned char chAvail = 0;
|
2016-10-29 01:29:17 +02:00
|
|
|
::Unserialize(s, chAvail);
|
2013-11-05 02:47:07 +01:00
|
|
|
for (unsigned int p = 0; p < 8; p++) {
|
|
|
|
bool f = (chAvail & (1 << p)) != 0;
|
|
|
|
vAvail.push_back(f);
|
|
|
|
}
|
|
|
|
if (chAvail != 0)
|
|
|
|
nMaskCode--;
|
|
|
|
}
|
|
|
|
// txouts themself
|
|
|
|
vout.assign(vAvail.size(), CTxOut());
|
|
|
|
for (unsigned int i = 0; i < vAvail.size(); i++) {
|
|
|
|
if (vAvail[i])
|
2016-10-29 01:29:17 +02:00
|
|
|
::Unserialize(s, REF(CTxOutCompressor(vout[i])));
|
2013-11-05 02:47:07 +01:00
|
|
|
}
|
|
|
|
// coinbase height
|
2016-10-29 01:29:17 +02:00
|
|
|
::Unserialize(s, VARINT(nHeight));
|
2015-05-04 01:31:11 +02:00
|
|
|
}
|
2013-11-05 02:47:07 +01:00
|
|
|
};
|
|
|
|
|
2017-04-25 20:29:39 +02:00
|
|
|
class SaltedOutpointHasher
|
2014-07-09 17:25:09 +02:00
|
|
|
{
|
|
|
|
private:
|
2016-05-06 20:47:12 +02:00
|
|
|
/** Salt */
|
2016-06-07 16:29:03 +02:00
|
|
|
const uint64_t k0, k1;
|
2014-07-09 17:25:09 +02:00
|
|
|
|
|
|
|
public:
|
2017-04-25 20:29:39 +02:00
|
|
|
SaltedOutpointHasher();
|
2014-10-31 01:43:19 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This *must* return size_t. With Boost 1.46 on 32-bit systems the
|
|
|
|
* unordered_map will behave unpredictably if the custom hasher returns a
|
|
|
|
* uint64_t, resulting in failures when syncing the chain (#4634).
|
|
|
|
*/
|
2017-04-25 20:29:39 +02:00
|
|
|
size_t operator()(const COutPoint& id) const {
|
|
|
|
return SipHashUint256Extra(k0, k1, id.hash, id.n);
|
2014-07-09 17:25:09 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-09-03 09:37:47 +02:00
|
|
|
struct CCoinsCacheEntry
|
|
|
|
{
|
2017-04-25 20:29:39 +02:00
|
|
|
Coin coins; // The actual cached data.
|
2014-09-03 09:37:47 +02:00
|
|
|
unsigned char flags;
|
|
|
|
|
|
|
|
enum Flags {
|
|
|
|
DIRTY = (1 << 0), // This cache entry is potentially different from the version in the parent view.
|
|
|
|
FRESH = (1 << 1), // The parent view does not have this entry (or it is pruned).
|
2016-11-07 21:30:41 +01:00
|
|
|
/* Note that FRESH is a performance optimization with which we can
|
|
|
|
* erase coins that are fully spent if we know we do not need to
|
|
|
|
* flush the changes to the parent cache. It is always safe to
|
|
|
|
* not mark FRESH if that condition is not guaranteed.
|
|
|
|
*/
|
2014-09-03 09:37:47 +02:00
|
|
|
};
|
|
|
|
|
2017-04-25 20:29:39 +02:00
|
|
|
CCoinsCacheEntry() : flags(0) {}
|
|
|
|
explicit CCoinsCacheEntry(Coin&& coin_) : coins(std::move(coin_)), flags(0) {}
|
2014-09-03 09:37:47 +02:00
|
|
|
};
|
|
|
|
|
2017-04-25 20:29:39 +02:00
|
|
|
typedef std::unordered_map<COutPoint, CCoinsCacheEntry, SaltedOutpointHasher> CCoinsMap;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2016-03-28 18:18:30 +02:00
|
|
|
/** Cursor for iterating over CoinsView state */
|
|
|
|
class CCoinsViewCursor
|
2013-11-05 02:47:07 +01:00
|
|
|
{
|
2016-03-28 18:18:30 +02:00
|
|
|
public:
|
|
|
|
CCoinsViewCursor(const uint256 &hashBlockIn): hashBlock(hashBlockIn) {}
|
2017-04-25 20:29:39 +02:00
|
|
|
virtual ~CCoinsViewCursor() {}
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2017-04-25 20:29:39 +02:00
|
|
|
virtual bool GetKey(COutPoint &key) const = 0;
|
|
|
|
virtual bool GetValue(Coin &coin) const = 0;
|
2016-03-28 18:18:30 +02:00
|
|
|
virtual unsigned int GetValueSize() const = 0;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2016-03-28 18:18:30 +02:00
|
|
|
virtual bool Valid() const = 0;
|
|
|
|
virtual void Next() = 0;
|
|
|
|
|
|
|
|
//! Get best block at the time this cursor was created
|
|
|
|
const uint256 &GetBestBlock() const { return hashBlock; }
|
|
|
|
private:
|
|
|
|
uint256 hashBlock;
|
|
|
|
};
|
2013-11-05 02:47:07 +01:00
|
|
|
|
|
|
|
/** Abstract view on the open txout dataset. */
|
|
|
|
class CCoinsView
|
|
|
|
{
|
|
|
|
public:
|
2017-04-25 20:29:39 +02:00
|
|
|
//! Retrieve the Coin (unspent transaction output) for a given outpoint.
|
|
|
|
virtual bool GetCoins(const COutPoint &outpoint, Coin &coin) const;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2017-04-25 20:29:39 +02:00
|
|
|
//! Just check whether we have data for a given outpoint.
|
|
|
|
//! This may (but cannot always) return true for spent outputs.
|
|
|
|
virtual bool HaveCoins(const COutPoint &outpoint) const;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2014-10-31 01:43:19 +01:00
|
|
|
//! Retrieve the block hash whose state this CCoinsView currently represents
|
2014-07-19 16:42:48 +02:00
|
|
|
virtual uint256 GetBestBlock() const;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2017-04-25 20:29:39 +02:00
|
|
|
//! Do a bulk modification (multiple Coin changes + BestBlock change).
|
2014-10-31 01:43:19 +01:00
|
|
|
//! The passed mapCoins can be modified.
|
2014-08-24 02:08:05 +02:00
|
|
|
virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2016-03-28 18:18:30 +02:00
|
|
|
//! Get a cursor to iterate over the whole state
|
|
|
|
virtual CCoinsViewCursor *Cursor() const;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2014-10-31 01:43:19 +01:00
|
|
|
//! As we use CCoinsViews polymorphically, have a virtual destructor
|
2013-11-05 02:47:07 +01:00
|
|
|
virtual ~CCoinsView() {}
|
2017-05-13 00:19:19 +02:00
|
|
|
|
|
|
|
//! Estimate database size (0 if not implemented)
|
|
|
|
virtual size_t EstimateSize() const { return 0; }
|
2013-11-05 02:47:07 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** CCoinsView backed by another CCoinsView */
|
|
|
|
class CCoinsViewBacked : public CCoinsView
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
CCoinsView *base;
|
|
|
|
|
|
|
|
public:
|
2014-09-24 03:19:04 +02:00
|
|
|
CCoinsViewBacked(CCoinsView *viewIn);
|
2017-04-25 20:29:39 +02:00
|
|
|
bool GetCoins(const COutPoint &outpoint, Coin &coin) const override;
|
|
|
|
bool HaveCoins(const COutPoint &outpoint) const override;
|
|
|
|
uint256 GetBestBlock() const override;
|
2013-11-05 02:47:07 +01:00
|
|
|
void SetBackend(CCoinsView &viewIn);
|
2017-04-25 20:29:39 +02:00
|
|
|
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override;
|
|
|
|
CCoinsViewCursor *Cursor() const override;
|
2017-05-13 00:19:19 +02:00
|
|
|
size_t EstimateSize() const override;
|
2013-11-05 02:47:07 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/** CCoinsView that adds a memory cache for transactions to another CCoinsView */
|
|
|
|
class CCoinsViewCache : public CCoinsViewBacked
|
|
|
|
{
|
|
|
|
protected:
|
2014-10-31 01:43:19 +01:00
|
|
|
/**
|
|
|
|
* Make mutable so that we can "fill the cache" even from Get-methods
|
|
|
|
* declared as "const".
|
|
|
|
*/
|
2014-07-19 16:42:48 +02:00
|
|
|
mutable uint256 hashBlock;
|
|
|
|
mutable CCoinsMap cacheCoins;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2017-04-25 20:29:39 +02:00
|
|
|
/* Cached dynamic memory usage for the inner Coin objects. */
|
2015-05-04 01:31:11 +02:00
|
|
|
mutable size_t cachedCoinsUsage;
|
|
|
|
|
2013-11-05 02:47:07 +01:00
|
|
|
public:
|
2014-09-24 03:19:04 +02:00
|
|
|
CCoinsViewCache(CCoinsView *baseIn);
|
2013-11-05 02:47:07 +01:00
|
|
|
|
|
|
|
// Standard CCoinsView methods
|
2017-04-25 20:29:39 +02:00
|
|
|
bool GetCoins(const COutPoint &outpoint, Coin &coin) const;
|
2017-04-25 20:29:29 +02:00
|
|
|
bool HaveCoins(const COutPoint &outpoint) const;
|
2014-07-19 16:42:48 +02:00
|
|
|
uint256 GetBestBlock() const;
|
2014-09-03 09:25:32 +02:00
|
|
|
void SetBestBlock(const uint256 &hashBlock);
|
2014-08-24 02:08:05 +02:00
|
|
|
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock);
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2015-10-23 00:49:53 +02:00
|
|
|
/**
|
2017-04-25 20:29:39 +02:00
|
|
|
* Check if we have the given utxo already loaded in this cache.
|
2015-10-23 00:49:53 +02:00
|
|
|
* The semantics are the same as HaveCoins(), but no calls to
|
|
|
|
* the backing CCoinsView are made.
|
|
|
|
*/
|
2017-04-25 20:29:39 +02:00
|
|
|
bool HaveCoinsInCache(const COutPoint &outpoint) const;
|
2014-09-02 21:21:15 +02:00
|
|
|
|
2017-04-25 20:29:29 +02:00
|
|
|
/**
|
2017-04-25 20:29:39 +02:00
|
|
|
* Return a reference to Coin in the cache, or a pruned one if not found. This is
|
2017-04-25 20:29:29 +02:00
|
|
|
* more efficient than GetCoins. Modifications to other cache entries are
|
|
|
|
* allowed while accessing the returned pointer.
|
|
|
|
*/
|
2017-04-25 20:29:39 +02:00
|
|
|
const Coin& AccessCoin(const COutPoint &output) const;
|
2017-04-25 20:29:29 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a coin. Set potential_overwrite to true if a non-pruned version may
|
|
|
|
* already exist.
|
|
|
|
*/
|
|
|
|
void AddCoin(const COutPoint& outpoint, Coin&& coin, bool potential_overwrite);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Spend a coin. Pass moveto in order to get the deleted data.
|
|
|
|
* If no unspent output exists for the passed outpoint, this call
|
|
|
|
* has no effect.
|
|
|
|
*/
|
|
|
|
void SpendCoin(const COutPoint &outpoint, Coin* moveto = nullptr);
|
|
|
|
|
2014-10-31 01:43:19 +01:00
|
|
|
/**
|
|
|
|
* Push the modifications applied to this cache to its base.
|
|
|
|
* Failure to call this method before destruction will cause the changes to be forgotten.
|
|
|
|
* If false is returned, the state of this cache (and its backing view) will be undefined.
|
|
|
|
*/
|
2013-11-05 02:47:07 +01:00
|
|
|
bool Flush();
|
|
|
|
|
2015-10-22 02:41:40 +02:00
|
|
|
/**
|
2017-04-25 20:29:39 +02:00
|
|
|
* Removes the UTXO with the given outpoint from the cache, if it is
|
2015-10-22 02:41:40 +02:00
|
|
|
* not modified.
|
|
|
|
*/
|
2017-04-25 20:29:39 +02:00
|
|
|
void Uncache(const COutPoint &outpoint);
|
2015-10-22 02:41:40 +02:00
|
|
|
|
2017-04-25 20:29:39 +02:00
|
|
|
//! Calculate the size of the cache (in number of transaction outputs)
|
2014-07-19 16:42:48 +02:00
|
|
|
unsigned int GetCacheSize() const;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2015-05-04 01:31:11 +02:00
|
|
|
//! Calculate the size of the cache (in bytes)
|
|
|
|
size_t DynamicMemoryUsage() const;
|
|
|
|
|
2014-10-31 01:43:19 +01:00
|
|
|
/**
|
|
|
|
* Amount of bitcoins coming in to a transaction
|
|
|
|
* Note that lightweight clients may not know anything besides the hash of previous transactions,
|
|
|
|
* so may not be able to calculate this.
|
|
|
|
*
|
|
|
|
* @param[in] tx transaction for which we are checking input total
|
|
|
|
* @return Sum of value of all inputs (scriptSigs)
|
2013-11-05 02:47:07 +01:00
|
|
|
*/
|
2014-04-23 00:46:19 +02:00
|
|
|
CAmount GetValueIn(const CTransaction& tx) const;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2014-10-31 01:43:19 +01:00
|
|
|
//! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
|
2014-07-19 16:42:48 +02:00
|
|
|
bool HaveInputs(const CTransaction& tx) const;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
2014-07-19 16:42:48 +02:00
|
|
|
const CTxOut &GetOutputFor(const CTxIn& input) const;
|
2013-11-05 02:47:07 +01:00
|
|
|
|
|
|
|
private:
|
2017-04-25 20:29:39 +02:00
|
|
|
CCoinsMap::iterator FetchCoins(const COutPoint &outpoint) const;
|
2014-12-31 04:19:24 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* By making the copy constructor private, we prevent accidentally using it when one intends to create a cache on top of a base cache.
|
|
|
|
*/
|
|
|
|
CCoinsViewCache(const CCoinsViewCache &);
|
2013-11-05 02:47:07 +01:00
|
|
|
};
|
|
|
|
|
2017-04-25 20:29:29 +02:00
|
|
|
//! Utility function to add all of a transaction's outputs to a cache.
|
|
|
|
// It assumes that overwrites are only possible for coinbase transactions,
|
|
|
|
// TODO: pass in a boolean to limit these possible overwrites to known
|
|
|
|
// (pre-BIP34) cases.
|
|
|
|
void AddCoins(CCoinsViewCache& cache, const CTransaction& tx, int nHeight);
|
|
|
|
|
|
|
|
//! Utility function to find any unspent output with a given txid.
|
2017-04-25 20:29:39 +02:00
|
|
|
const Coin& AccessByTxid(const CCoinsViewCache& cache, const uint256& txid);
|
2017-04-25 20:29:29 +02:00
|
|
|
|
2014-08-28 22:21:03 +02:00
|
|
|
#endif // BITCOIN_COINS_H
|