2018-08-06 15:40:20 -04:00
|
|
|
#ifndef BITCOIN_CLAIMTRIE_H
|
|
|
|
#define BITCOIN_CLAIMTRIE_H
|
|
|
|
|
|
|
|
#include <amount.h>
|
2019-07-01 12:42:45 -06:00
|
|
|
#include <chain.h>
|
|
|
|
#include <chainparams.h>
|
|
|
|
#include <dbwrapper.h>
|
|
|
|
#include <prefixtrie.h>
|
|
|
|
#include <primitives/transaction.h>
|
2018-08-06 15:40:20 -04:00
|
|
|
#include <serialize.h>
|
|
|
|
#include <uint256.h>
|
|
|
|
#include <util.h>
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
#include <map>
|
2018-08-06 15:40:20 -04:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2019-07-01 12:42:45 -06:00
|
|
|
#include <unordered_map>
|
|
|
|
#include <unordered_set>
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
// leveldb keys
|
|
|
|
#define TRIE_NODE 'n'
|
|
|
|
#define CLAIM_BY_ID 'i'
|
|
|
|
#define CLAIM_QUEUE_ROW 'r'
|
|
|
|
#define CLAIM_QUEUE_NAME_ROW 'm'
|
|
|
|
#define EXP_QUEUE_ROW 'e'
|
|
|
|
#define SUPPORT 's'
|
|
|
|
#define SUPPORT_QUEUE_ROW 'u'
|
|
|
|
#define SUPPORT_QUEUE_NAME_ROW 'p'
|
|
|
|
#define SUPPORT_EXP_QUEUE_ROW 'x'
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
uint256 getValueHash(const COutPoint& outPoint, int nHeightOfLastTakeover);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
struct CClaimValue
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
COutPoint outPoint;
|
|
|
|
uint160 claimId;
|
|
|
|
CAmount nAmount;
|
|
|
|
CAmount nEffectiveAmount;
|
|
|
|
int nHeight;
|
|
|
|
int nValidAtHeight;
|
|
|
|
|
2019-07-22 15:53:17 -06:00
|
|
|
CClaimValue() = default;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CClaimValue(const COutPoint& outPoint, const uint160& claimId, CAmount nAmount, int nHeight, int nValidAtHeight)
|
|
|
|
: outPoint(outPoint), claimId(claimId), nAmount(nAmount), nEffectiveAmount(nAmount), nHeight(nHeight), nValidAtHeight(nValidAtHeight)
|
|
|
|
{
|
|
|
|
}
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
CClaimValue(CClaimValue&&) = default;
|
|
|
|
CClaimValue(const CClaimValue&) = default;
|
|
|
|
CClaimValue& operator=(CClaimValue&&) = default;
|
|
|
|
CClaimValue& operator=(const CClaimValue&) = default;
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2019-07-01 12:42:45 -06:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
|
|
{
|
2018-08-06 15:40:20 -04:00
|
|
|
READWRITE(outPoint);
|
|
|
|
READWRITE(claimId);
|
|
|
|
READWRITE(nAmount);
|
|
|
|
READWRITE(nHeight);
|
|
|
|
READWRITE(nValidAtHeight);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator<(const CClaimValue& other) const
|
|
|
|
{
|
|
|
|
if (nEffectiveAmount < other.nEffectiveAmount)
|
|
|
|
return true;
|
2019-07-01 12:42:45 -06:00
|
|
|
if (nEffectiveAmount != other.nEffectiveAmount)
|
|
|
|
return false;
|
|
|
|
if (nHeight > other.nHeight)
|
|
|
|
return true;
|
|
|
|
if (nHeight != other.nHeight)
|
|
|
|
return false;
|
|
|
|
return outPoint != other.outPoint && !(outPoint < other.outPoint);
|
2018-08-06 15:40:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const CClaimValue& other) const
|
|
|
|
{
|
|
|
|
return outPoint == other.outPoint && claimId == other.claimId && nAmount == other.nAmount && nHeight == other.nHeight && nValidAtHeight == other.nValidAtHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const CClaimValue& other) const
|
|
|
|
{
|
|
|
|
return !(*this == other);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
struct CSupportValue
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
COutPoint outPoint;
|
|
|
|
uint160 supportedClaimId;
|
|
|
|
CAmount nAmount;
|
|
|
|
int nHeight;
|
|
|
|
int nValidAtHeight;
|
|
|
|
|
2019-07-22 15:53:17 -06:00
|
|
|
CSupportValue() = default;
|
2019-07-01 12:42:45 -06:00
|
|
|
|
|
|
|
CSupportValue(const COutPoint& outPoint, const uint160& supportedClaimId, CAmount nAmount, int nHeight, int nValidAtHeight)
|
|
|
|
: outPoint(outPoint), supportedClaimId(supportedClaimId), nAmount(nAmount), nHeight(nHeight), nValidAtHeight(nValidAtHeight)
|
|
|
|
{
|
|
|
|
}
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
CSupportValue(CSupportValue&&) = default;
|
|
|
|
CSupportValue(const CSupportValue&) = default;
|
|
|
|
CSupportValue& operator=(CSupportValue&&) = default;
|
|
|
|
CSupportValue& operator=(const CSupportValue&) = default;
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2019-07-01 12:42:45 -06:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
|
|
{
|
2018-08-06 15:40:20 -04:00
|
|
|
READWRITE(outPoint);
|
|
|
|
READWRITE(supportedClaimId);
|
|
|
|
READWRITE(nAmount);
|
|
|
|
READWRITE(nHeight);
|
|
|
|
READWRITE(nValidAtHeight);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const CSupportValue& other) const
|
|
|
|
{
|
|
|
|
return outPoint == other.outPoint && supportedClaimId == other.supportedClaimId && nAmount == other.nAmount && nHeight == other.nHeight && nValidAtHeight == other.nValidAtHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const CSupportValue& other) const
|
|
|
|
{
|
|
|
|
return !(*this == other);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
typedef std::vector<CClaimValue> claimEntryType;
|
|
|
|
typedef std::vector<CSupportValue> supportEntryType;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
struct CClaimTrieData
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
uint256 hash;
|
2019-07-01 12:42:45 -06:00
|
|
|
claimEntryType claims;
|
|
|
|
int nHeightOfLastTakeover = 0;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CClaimTrieData() = default;
|
|
|
|
CClaimTrieData(CClaimTrieData&&) = default;
|
|
|
|
CClaimTrieData(const CClaimTrieData&) = default;
|
|
|
|
CClaimTrieData& operator=(CClaimTrieData&&) = default;
|
|
|
|
CClaimTrieData& operator=(const CClaimTrieData& d) = default;
|
|
|
|
|
|
|
|
bool insertClaim(const CClaimValue& claim);
|
2018-08-06 15:40:20 -04:00
|
|
|
bool removeClaim(const COutPoint& outPoint, CClaimValue& claim);
|
|
|
|
bool getBestClaim(CClaimValue& claim) const;
|
|
|
|
bool haveClaim(const COutPoint& outPoint) const;
|
2019-07-01 12:42:45 -06:00
|
|
|
void reorderClaims(const supportEntryType& support);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2019-07-01 12:42:45 -06:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
|
|
{
|
2018-08-06 15:40:20 -04:00
|
|
|
READWRITE(hash);
|
2019-07-01 12:42:45 -06:00
|
|
|
|
|
|
|
if (ser_action.ForRead()) {
|
|
|
|
if (s.eof()) {
|
|
|
|
claims.clear();
|
|
|
|
nHeightOfLastTakeover = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (claims.empty())
|
|
|
|
return;
|
|
|
|
|
2018-08-06 15:40:20 -04:00
|
|
|
READWRITE(claims);
|
|
|
|
READWRITE(nHeightOfLastTakeover);
|
|
|
|
}
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool operator==(const CClaimTrieData& other) const
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
2019-07-01 12:42:45 -06:00
|
|
|
return hash == other.hash && nHeightOfLastTakeover == other.nHeightOfLastTakeover && claims == other.claims;
|
2018-08-06 15:40:20 -04:00
|
|
|
}
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool operator!=(const CClaimTrieData& other) const
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
return !(*this == other);
|
|
|
|
}
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool empty() const
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
2019-07-01 12:42:45 -06:00
|
|
|
return claims.empty();
|
2018-08-06 15:40:20 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
struct COutPointHeightType
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
COutPoint outPoint;
|
|
|
|
int nHeight;
|
|
|
|
|
2019-07-22 15:53:17 -06:00
|
|
|
COutPointHeightType() = default;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
COutPointHeightType(const COutPoint& outPoint, int nHeight)
|
|
|
|
: outPoint(outPoint), nHeight(nHeight)
|
|
|
|
{
|
|
|
|
}
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
|
|
{
|
|
|
|
READWRITE(outPoint);
|
|
|
|
READWRITE(nHeight);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
struct CNameOutPointHeightType
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
std::string name;
|
|
|
|
COutPoint outPoint;
|
|
|
|
int nHeight;
|
|
|
|
|
2019-07-22 15:53:17 -06:00
|
|
|
CNameOutPointHeightType() = default;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CNameOutPointHeightType(std::string name, const COutPoint& outPoint, int nHeight)
|
|
|
|
: name(std::move(name)), outPoint(outPoint), nHeight(nHeight)
|
|
|
|
{
|
|
|
|
}
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
|
|
{
|
|
|
|
READWRITE(name);
|
|
|
|
READWRITE(outPoint);
|
|
|
|
READWRITE(nHeight);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
struct CNameOutPointType
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
std::string name;
|
|
|
|
COutPoint outPoint;
|
|
|
|
|
2019-07-22 15:53:17 -06:00
|
|
|
CNameOutPointType() = default;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CNameOutPointType(std::string name, const COutPoint& outPoint)
|
|
|
|
: name(std::move(name)), outPoint(outPoint)
|
|
|
|
{
|
|
|
|
}
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-15 08:48:24 +03:00
|
|
|
bool operator==(const CNameOutPointType& other) const
|
|
|
|
{
|
|
|
|
return name == other.name && outPoint == other.outPoint;
|
|
|
|
}
|
|
|
|
|
2018-08-06 15:40:20 -04:00
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
|
|
{
|
|
|
|
READWRITE(name);
|
|
|
|
READWRITE(outPoint);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
struct CClaimIndexElement
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
2019-07-22 15:53:17 -06:00
|
|
|
CClaimIndexElement() = default;
|
2019-07-02 18:49:02 +03:00
|
|
|
|
2019-07-22 15:53:17 -06:00
|
|
|
CClaimIndexElement(std::string name, CClaimValue claim)
|
|
|
|
: name(std::move(name)), claim(std::move(claim))
|
2019-07-02 18:49:02 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-08-06 15:40:20 -04:00
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
2019-07-01 12:42:45 -06:00
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
|
|
{
|
2018-08-06 15:40:20 -04:00
|
|
|
READWRITE(name);
|
|
|
|
READWRITE(claim);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string name;
|
|
|
|
CClaimValue claim;
|
|
|
|
};
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
struct CClaimsForNameType
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
2019-07-01 12:42:45 -06:00
|
|
|
claimEntryType claims;
|
|
|
|
supportEntryType supports;
|
2018-08-06 15:40:20 -04:00
|
|
|
int nLastTakeoverHeight;
|
|
|
|
std::string name;
|
|
|
|
|
2019-07-22 15:53:17 -06:00
|
|
|
CClaimsForNameType(claimEntryType claims, supportEntryType supports, int nLastTakeoverHeight, std::string name)
|
|
|
|
: claims(std::move(claims)), supports(std::move(supports)), nLastTakeoverHeight(nLastTakeoverHeight), name(std::move(name))
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CClaimsForNameType(CClaimsForNameType&&) = default;
|
|
|
|
CClaimsForNameType(const CClaimsForNameType&) = default;
|
|
|
|
CClaimsForNameType& operator=(CClaimsForNameType&&) = default;
|
|
|
|
CClaimsForNameType& operator=(const CClaimsForNameType&) = default;
|
2018-08-06 15:40:20 -04:00
|
|
|
};
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
class CClaimTrie : public CPrefixTrie<std::string, CClaimTrieData>
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
2019-07-01 12:42:45 -06:00
|
|
|
int nNextHeight = 0;
|
|
|
|
int nProportionalDelayFactor = 0;
|
|
|
|
std::unique_ptr<CDBWrapper> db;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
public:
|
|
|
|
CClaimTrie() = default;
|
|
|
|
CClaimTrie(CClaimTrie&&) = delete;
|
|
|
|
CClaimTrie(const CClaimTrie&) = delete;
|
|
|
|
CClaimTrie(bool fMemory, bool fWipe, int proportionalDelayFactor = 32);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CClaimTrie& operator=(CClaimTrie&&) = delete;
|
|
|
|
CClaimTrie& operator=(const CClaimTrie&) = delete;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool SyncToDisk();
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
friend class CClaimTrieCacheBase;
|
2019-07-18 14:35:18 -06:00
|
|
|
friend struct ClaimTrieChainFixture;
|
2018-08-06 15:40:20 -04:00
|
|
|
friend class CClaimTrieCacheExpirationFork;
|
2019-07-01 12:42:45 -06:00
|
|
|
friend class CClaimTrieCacheNormalizationFork;
|
2018-08-06 15:40:20 -04:00
|
|
|
};
|
|
|
|
|
2019-07-02 18:49:02 +03:00
|
|
|
struct CClaimTrieProofNode
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
2019-07-01 12:42:45 -06:00
|
|
|
CClaimTrieProofNode(std::vector<std::pair<unsigned char, uint256>> children, bool hasValue, const uint256& valHash)
|
|
|
|
: children(std::move(children)), hasValue(hasValue), valHash(valHash)
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
}
|
2019-07-01 12:42:45 -06:00
|
|
|
|
|
|
|
CClaimTrieProofNode(CClaimTrieProofNode&&) = default;
|
|
|
|
CClaimTrieProofNode(const CClaimTrieProofNode&) = default;
|
|
|
|
CClaimTrieProofNode& operator=(CClaimTrieProofNode&&) = default;
|
2018-08-06 15:40:20 -04:00
|
|
|
CClaimTrieProofNode& operator=(const CClaimTrieProofNode&) = default;
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
std::vector<std::pair<unsigned char, uint256>> children;
|
2018-08-06 15:40:20 -04:00
|
|
|
bool hasValue;
|
|
|
|
uint256 valHash;
|
|
|
|
};
|
|
|
|
|
2019-07-02 18:49:02 +03:00
|
|
|
struct CClaimTrieProof
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
2019-07-22 15:53:17 -06:00
|
|
|
CClaimTrieProof() = default;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CClaimTrieProof(std::vector<CClaimTrieProofNode> nodes, bool hasValue, const COutPoint& outPoint, int nHeightOfLastTakeover)
|
|
|
|
: nodes(std::move(nodes)), hasValue(hasValue), outPoint(outPoint), nHeightOfLastTakeover(nHeightOfLastTakeover)
|
2018-08-06 15:40:20 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CClaimTrieProof(CClaimTrieProof&&) = default;
|
|
|
|
CClaimTrieProof(const CClaimTrieProof&) = default;
|
|
|
|
CClaimTrieProof& operator=(CClaimTrieProof&&) = default;
|
|
|
|
CClaimTrieProof& operator=(const CClaimTrieProof&) = default;
|
|
|
|
|
2018-08-06 15:40:20 -04:00
|
|
|
std::vector<CClaimTrieProofNode> nodes;
|
|
|
|
bool hasValue;
|
|
|
|
COutPoint outPoint;
|
|
|
|
int nHeightOfLastTakeover;
|
|
|
|
};
|
|
|
|
|
2019-07-02 18:49:02 +03:00
|
|
|
template <typename T>
|
|
|
|
using queueEntryType = std::pair<std::string, T>;
|
|
|
|
|
|
|
|
typedef std::vector<queueEntryType<CClaimValue>> claimQueueRowType;
|
2019-07-01 12:42:45 -06:00
|
|
|
typedef std::map<int, claimQueueRowType> claimQueueType;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-02 18:49:02 +03:00
|
|
|
typedef std::vector<queueEntryType<CSupportValue>> supportQueueRowType;
|
2019-07-01 12:42:45 -06:00
|
|
|
typedef std::map<int, supportQueueRowType> supportQueueType;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
typedef std::vector<COutPointHeightType> queueNameRowType;
|
|
|
|
typedef std::map<std::string, queueNameRowType> queueNameType;
|
|
|
|
|
|
|
|
typedef std::vector<CNameOutPointHeightType> insertUndoType;
|
|
|
|
|
|
|
|
typedef std::vector<CNameOutPointType> expirationQueueRowType;
|
|
|
|
typedef std::map<int, expirationQueueRowType> expirationQueueType;
|
|
|
|
|
|
|
|
typedef std::set<CClaimValue> claimIndexClaimListType;
|
|
|
|
typedef std::vector<CClaimIndexElement> claimIndexElementListType;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
class CClaimTrieCacheBase
|
|
|
|
{
|
|
|
|
public:
|
2019-07-29 10:25:41 -06:00
|
|
|
explicit CClaimTrieCacheBase(CClaimTrie* base);
|
2019-07-01 12:42:45 -06:00
|
|
|
virtual ~CClaimTrieCacheBase() = default;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
uint256 getMerkleHash();
|
2019-07-02 18:49:02 +03:00
|
|
|
bool checkConsistency() const;
|
2019-07-01 12:42:45 -06:00
|
|
|
|
|
|
|
bool getClaimById(const uint160& claimId, std::string& name, CClaimValue& claim) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
bool flush();
|
2019-07-01 12:42:45 -06:00
|
|
|
bool empty() const;
|
|
|
|
bool ReadFromDisk(const CBlockIndex* tip);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool haveClaim(const std::string& name, const COutPoint& outPoint) const;
|
|
|
|
bool haveClaimInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool haveSupport(const std::string& name, const COutPoint& outPoint) const;
|
|
|
|
bool haveSupportInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
std::size_t getTotalNamesInTrie() const;
|
|
|
|
std::size_t getTotalClaimsInTrie() const;
|
|
|
|
CAmount getTotalValueOfClaimsInTrie(bool fControllingOnly) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId, CAmount nAmount, int nHeight);
|
|
|
|
bool undoAddClaim(const std::string& name, const COutPoint& outPoint, int nHeight);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool spendClaim(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight);
|
|
|
|
bool undoSpendClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId, CAmount nAmount, int nHeight, int nValidAtHeight);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool addSupport(const std::string& name, const COutPoint& outPoint, CAmount nAmount, const uint160& supportedClaimId, int nHeight);
|
|
|
|
bool undoAddSupport(const std::string& name, const COutPoint& outPoint, int nHeight);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool spendSupport(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight);
|
|
|
|
bool undoSpendSupport(const std::string& name, const COutPoint& outPoint, const uint160& supportedClaimId, CAmount nAmount, int nHeight, int nValidAtHeight);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
virtual bool incrementBlock(insertUndoType& insertUndo,
|
|
|
|
claimQueueRowType& expireUndo,
|
|
|
|
insertUndoType& insertSupportUndo,
|
|
|
|
supportQueueRowType& expireSupportUndo,
|
|
|
|
std::vector<std::pair<std::string, int>>& takeoverHeightUndo);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
virtual bool decrementBlock(insertUndoType& insertUndo,
|
|
|
|
claimQueueRowType& expireUndo,
|
|
|
|
insertUndoType& insertSupportUndo,
|
|
|
|
supportQueueRowType& expireSupportUndo);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
virtual bool getProofForName(const std::string& name, CClaimTrieProof& proof);
|
|
|
|
virtual bool getInfoForName(const std::string& name, CClaimValue& claim) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-09 18:02:54 +03:00
|
|
|
virtual int expirationTime() const;
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool finalizeDecrement(std::vector<std::pair<std::string, int>>& takeoverHeightUndo);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
virtual CClaimsForNameType getClaimsForName(const std::string& name) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CAmount getEffectiveAmountForClaim(const std::string& name, const uint160& claimId, std::vector<CSupportValue>* supports = nullptr) const;
|
|
|
|
CAmount getEffectiveAmountForClaim(const CClaimsForNameType& claims, const uint160& claimId, std::vector<CSupportValue>* supports = nullptr) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CClaimTrie::const_iterator begin() const;
|
|
|
|
CClaimTrie::const_iterator end() const;
|
|
|
|
CClaimTrie::const_iterator find(const std::string& name) const;
|
|
|
|
|
|
|
|
void dumpToLog(CClaimTrie::const_iterator it, bool diffFromBase = true) const;
|
|
|
|
|
|
|
|
protected:
|
2018-08-06 15:40:20 -04:00
|
|
|
CClaimTrie* base;
|
2019-07-22 15:53:17 -06:00
|
|
|
CClaimTrie nodesToAddOrUpdate; // nodes pulled in from base (and possibly modified thereafter), written to base on flush
|
|
|
|
std::unordered_set<std::string> namesToCheckForTakeover; // takeover numbers are updated on increment
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
uint256 recursiveComputeMerkleHash(CClaimTrie::iterator& it);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
virtual bool insertClaimIntoTrie(const std::string& name, const CClaimValue& claim, bool fCheckTakeover);
|
|
|
|
virtual bool removeClaimFromTrie(const std::string& name, const COutPoint& outPoint, CClaimValue& claim, bool fCheckTakeover);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
virtual bool insertSupportIntoMap(const std::string& name, const CSupportValue& support, bool fCheckTakeover);
|
|
|
|
virtual bool removeSupportFromMap(const std::string& name, const COutPoint& outPoint, CSupportValue& support, bool fCheckTakeover);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
supportEntryType getSupportsForName(const std::string& name) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-02 18:49:02 +03:00
|
|
|
int getDelayForName(const std::string& name) const;
|
|
|
|
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
CClaimTrie::iterator cacheData(const std::string& name, bool create = true);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool getLastTakeoverForName(const std::string& name, uint160& claimId, int& takeoverHeight) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-02 18:49:02 +03:00
|
|
|
int getNumBlocksOfContinuousOwnership(const std::string& name) const;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-15 08:48:24 +03:00
|
|
|
void reactivateClaim(const expirationQueueRowType& row, int height, bool increment);
|
|
|
|
void reactivateSupport(const expirationQueueRowType& row, int height, bool increment);
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
expirationQueueType expirationQueueCache;
|
|
|
|
expirationQueueType supportExpirationQueueCache;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
int nNextHeight; // Height of the block that is being worked on, which is
|
|
|
|
// one greater than the height of the chain's tip
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
private:
|
|
|
|
uint256 hashBlock;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
std::unordered_map<std::string, std::pair<uint160, int>> takeoverCache;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-22 15:53:17 -06:00
|
|
|
claimQueueType claimQueueCache; // claims not active yet: to be written to disk on flush
|
2019-07-01 12:42:45 -06:00
|
|
|
queueNameType claimQueueNameCache;
|
2019-07-22 15:53:17 -06:00
|
|
|
supportQueueType supportQueueCache; // supports not active yet: to be written to disk on flush
|
2019-07-01 12:42:45 -06:00
|
|
|
queueNameType supportQueueNameCache;
|
2019-07-22 15:53:17 -06:00
|
|
|
claimIndexElementListType claimsToAddToByIdIndex; // written to index on flush
|
|
|
|
claimIndexClaimListType claimsToDeleteFromByIdIndex;
|
2019-07-01 12:42:45 -06:00
|
|
|
|
2019-07-22 15:53:17 -06:00
|
|
|
std::unordered_map<std::string, supportEntryType> supportCache; // to be added/updated to base (and disk) on flush
|
|
|
|
std::unordered_set<std::string> nodesToDelete; // to be removed from base (and disk) on flush
|
|
|
|
std::unordered_set<std::string> nodesAlreadyCached; // set of nodes already pulled into cache from base
|
2019-07-01 12:42:45 -06:00
|
|
|
std::unordered_map<std::string, bool> takeoverWorkaround;
|
|
|
|
std::unordered_set<std::string> removalWorkaround;
|
|
|
|
|
|
|
|
bool shouldUseTakeoverWorkaround(const std::string& key) const;
|
|
|
|
void addTakeoverWorkaroundPotential(const std::string& key);
|
|
|
|
void confirmTakeoverWorkaroundNeeded(const std::string& key);
|
|
|
|
|
|
|
|
bool clear();
|
|
|
|
|
|
|
|
void markAsDirty(const std::string& name, bool fCheckTakeover);
|
|
|
|
bool removeSupport(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight, bool fCheckTakeover);
|
|
|
|
bool removeClaim(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight, bool fCheckTakeover);
|
|
|
|
|
2019-07-02 18:49:02 +03:00
|
|
|
template <typename T>
|
|
|
|
std::pair<const int, std::vector<queueEntryType<T>>>* getQueueCacheRow(int nHeight, bool createIfNotExists = false);
|
|
|
|
|
|
|
|
template <typename T>
|
2019-07-01 12:42:45 -06:00
|
|
|
typename queueNameType::value_type* getQueueCacheNameRow(const std::string& name, bool createIfNotExists = false);
|
2019-07-02 18:49:02 +03:00
|
|
|
|
|
|
|
template <typename T>
|
2019-07-01 12:42:45 -06:00
|
|
|
typename expirationQueueType::value_type* getExpirationQueueCacheRow(int nHeight, bool createIfNotExists = false);
|
2019-07-02 18:49:02 +03:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool haveInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T add(const std::string& name, const COutPoint& outPoint, const uint160& claimId, CAmount nAmount, int nHeight);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool remove(T& value, const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight, bool fCheckTakeover = false);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool addToQueue(const std::string& name, const T& value);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool removeFromQueue(const std::string& name, const COutPoint& outPoint, T& value);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool addToCache(const std::string& name, const T& value, bool fCheckTakeover = false);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool removeFromCache(const std::string& name, const COutPoint& outPoint, T& value, bool fCheckTakeover = false);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
bool undoSpend(const std::string& name, const T& value, int nValidAtHeight);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void undoIncrement(insertUndoType& insertUndo, std::vector<queueEntryType<T>>& expireUndo, std::set<T>* deleted = nullptr);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void undoDecrement(insertUndoType& insertUndo, std::vector<queueEntryType<T>>& expireUndo, std::vector<CClaimIndexElement>* added = nullptr, std::set<T>* deleted = nullptr);
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void undoIncrement(const std::string& name, insertUndoType& insertUndo, std::vector<queueEntryType<T>>& expireUndo);
|
2019-07-01 12:42:45 -06:00
|
|
|
|
2019-07-15 08:48:24 +03:00
|
|
|
template <typename T>
|
|
|
|
void reactivate(const expirationQueueRowType& row, int height, bool increment);
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
// for unit test
|
2019-07-18 14:35:18 -06:00
|
|
|
friend struct ClaimTrieChainFixture;
|
2019-07-01 12:42:45 -06:00
|
|
|
friend class CClaimTrieCacheTest;
|
|
|
|
};
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
class CClaimTrieCacheExpirationFork : public CClaimTrieCacheBase
|
|
|
|
{
|
|
|
|
public:
|
2019-07-29 10:25:41 -06:00
|
|
|
explicit CClaimTrieCacheExpirationFork(CClaimTrie* base);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-09 18:02:54 +03:00
|
|
|
void setExpirationTime(int time);
|
|
|
|
int expirationTime() const override;
|
|
|
|
|
|
|
|
void expirationForkActive(int height, bool increment);
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-09 18:02:54 +03:00
|
|
|
bool incrementBlock(insertUndoType& insertUndo,
|
|
|
|
claimQueueRowType& expireUndo,
|
|
|
|
insertUndoType& insertSupportUndo,
|
|
|
|
supportQueueRowType& expireSupportUndo,
|
|
|
|
std::vector<std::pair<std::string, int>>& takeoverHeightUndo) override;
|
|
|
|
|
|
|
|
bool decrementBlock(insertUndoType& insertUndo,
|
|
|
|
claimQueueRowType& expireUndo,
|
|
|
|
insertUndoType& insertSupportUndo,
|
|
|
|
supportQueueRowType& expireSupportUndo) override;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
private:
|
2019-07-09 18:02:54 +03:00
|
|
|
int nExpirationTime;
|
|
|
|
bool forkForExpirationChange(bool increment);
|
2018-08-06 15:40:20 -04:00
|
|
|
};
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
class CClaimTrieCacheNormalizationFork : public CClaimTrieCacheExpirationFork
|
|
|
|
{
|
|
|
|
public:
|
2019-07-29 10:25:41 -06:00
|
|
|
explicit CClaimTrieCacheNormalizationFork(CClaimTrie* base)
|
|
|
|
: CClaimTrieCacheExpirationFork(base), overrideInsertNormalization(false), overrideRemoveNormalization(false)
|
2019-07-01 12:42:45 -06:00
|
|
|
{
|
|
|
|
}
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
bool shouldNormalize() const;
|
|
|
|
|
|
|
|
// lower-case and normalize any input string name
|
|
|
|
// see: https://unicode.org/reports/tr15/#Norm_Forms
|
|
|
|
std::string normalizeClaimName(const std::string& name, bool force = false) const; // public only for validating name field on update op
|
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool incrementBlock(insertUndoType& insertUndo,
|
|
|
|
claimQueueRowType& expireUndo,
|
|
|
|
insertUndoType& insertSupportUndo,
|
|
|
|
supportQueueRowType& expireSupportUndo,
|
|
|
|
std::vector<std::pair<std::string, int>>& takeoverHeightUndo) override;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool decrementBlock(insertUndoType& insertUndo,
|
|
|
|
claimQueueRowType& expireUndo,
|
|
|
|
insertUndoType& insertSupportUndo,
|
|
|
|
supportQueueRowType& expireSupportUndo) override;
|
|
|
|
|
|
|
|
bool getProofForName(const std::string& name, CClaimTrieProof& proof) override;
|
|
|
|
bool getInfoForName(const std::string& name, CClaimValue& claim) const override;
|
|
|
|
CClaimsForNameType getClaimsForName(const std::string& name) const override;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
protected:
|
2019-07-22 15:53:17 -06:00
|
|
|
bool insertClaimIntoTrie(const std::string& name, const CClaimValue& claim, bool fCheckTakeover) override;
|
|
|
|
bool removeClaimFromTrie(const std::string& name, const COutPoint& outPoint, CClaimValue& claim, bool fCheckTakeover) override;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-01 12:42:45 -06:00
|
|
|
bool insertSupportIntoMap(const std::string& name, const CSupportValue& support, bool fCheckTakeover) override;
|
|
|
|
bool removeSupportFromMap(const std::string& name, const COutPoint& outPoint, CSupportValue& support, bool fCheckTakeover) override;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
2019-07-02 18:49:02 +03:00
|
|
|
int getDelayForName(const std::string& name, const uint160& claimId) const override;
|
2019-07-01 12:42:45 -06:00
|
|
|
|
|
|
|
std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
|
2018-08-06 15:40:20 -04:00
|
|
|
|
|
|
|
private:
|
2019-07-01 12:42:45 -06:00
|
|
|
bool overrideInsertNormalization;
|
|
|
|
bool overrideRemoveNormalization;
|
|
|
|
|
|
|
|
bool normalizeAllNamesInTrieIfNecessary(insertUndoType& insertUndo,
|
|
|
|
claimQueueRowType& removeUndo,
|
|
|
|
insertUndoType& insertSupportUndo,
|
|
|
|
supportQueueRowType& expireSupportUndo,
|
|
|
|
std::vector<std::pair<std::string, int>>& takeoverHeightUndo);
|
2018-08-06 15:40:20 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef CClaimTrieCacheNormalizationFork CClaimTrieCache;
|
|
|
|
|
|
|
|
#endif // BITCOIN_CLAIMTRIE_H
|