Separate disk related functions in CClaimTrieDb
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
This commit is contained in:
parent
7930840005
commit
7d321ec0ea
14 changed files with 802 additions and 579 deletions
|
@ -2,8 +2,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
|
||||||
AC_PREREQ([2.60])
|
AC_PREREQ([2.60])
|
||||||
define(_CLIENT_VERSION_MAJOR, 0)
|
define(_CLIENT_VERSION_MAJOR, 0)
|
||||||
define(_CLIENT_VERSION_MINOR, 12)
|
define(_CLIENT_VERSION_MINOR, 12)
|
||||||
define(_CLIENT_VERSION_REVISION, 1)
|
define(_CLIENT_VERSION_REVISION, 2)
|
||||||
define(_CLIENT_VERSION_BUILD, 2)
|
define(_CLIENT_VERSION_BUILD, 0)
|
||||||
define(_CLIENT_VERSION_IS_RELEASE, true)
|
define(_CLIENT_VERSION_IS_RELEASE, true)
|
||||||
define(_COPYRIGHT_YEAR, 2016)
|
define(_COPYRIGHT_YEAR, 2016)
|
||||||
define(_COPYRIGHT_HOLDERS,[The %s developers])
|
define(_COPYRIGHT_HOLDERS,[The %s developers])
|
||||||
|
|
|
@ -232,7 +232,7 @@ function build_dependencies() {
|
||||||
else
|
else
|
||||||
install_apt_packages
|
install_apt_packages
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$CLEAN" = true ]; then
|
if [ "$CLEAN" = true ]; then
|
||||||
rm -rf "${LBRYCRD_DEPENDENCIES}"
|
rm -rf "${LBRYCRD_DEPENDENCIES}"
|
||||||
rm -rf "${OUTPUT_DIR}"
|
rm -rf "${OUTPUT_DIR}"
|
||||||
|
@ -246,7 +246,7 @@ function build_dependencies() {
|
||||||
|
|
||||||
build_dependency "${BDB_PREFIX}" "${LOG_DIR}/bdb_build.log" build_bdb
|
build_dependency "${BDB_PREFIX}" "${LOG_DIR}/bdb_build.log" build_bdb
|
||||||
build_dependency "${OPENSSL_PREFIX}" "${LOG_DIR}/openssl_build.log" build_openssl
|
build_dependency "${OPENSSL_PREFIX}" "${LOG_DIR}/openssl_build.log" build_openssl
|
||||||
|
|
||||||
set +u
|
set +u
|
||||||
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${OPENSSL_PREFIX}/lib/pkgconfig/"
|
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${OPENSSL_PREFIX}/lib/pkgconfig/"
|
||||||
set -u
|
set -u
|
||||||
|
@ -277,8 +277,9 @@ function build_openssl() {
|
||||||
-fPIC darwin64-x86_64-cc \
|
-fPIC darwin64-x86_64-cc \
|
||||||
no-shared no-dso no-engines > "${OPENSSL_LOG}"
|
no-shared no-dso no-engines > "${OPENSSL_LOG}"
|
||||||
else
|
else
|
||||||
|
[[ $(uname -m) = 'i686' ]] && OS_ARCH="linux-generic32" || OS_ARCH="linux-x86_64"
|
||||||
./Configure --prefix="${OPENSSL_PREFIX}" --openssldir="${OPENSSL_PREFIX}/ssl" \
|
./Configure --prefix="${OPENSSL_PREFIX}" --openssldir="${OPENSSL_PREFIX}/ssl" \
|
||||||
linux-x86_64 -fPIC -static no-shared no-dso > "${OPENSSL_LOG}"
|
${OS_ARCH} -fPIC -static no-shared no-dso > "${OPENSSL_LOG}"
|
||||||
fi
|
fi
|
||||||
background make "${OPENSSL_LOG}" "Waiting for openssl to finish building"
|
background make "${OPENSSL_LOG}" "Waiting for openssl to finish building"
|
||||||
make install >> "${OPENSSL_LOG}" 2>&1
|
make install >> "${OPENSSL_LOG}" 2>&1
|
||||||
|
|
|
@ -119,6 +119,7 @@ BITCOIN_CORE_H = \
|
||||||
miner.h \
|
miner.h \
|
||||||
nameclaim.h \
|
nameclaim.h \
|
||||||
claimtrie.h \
|
claimtrie.h \
|
||||||
|
claimtriedb.h \
|
||||||
lbry.h \
|
lbry.h \
|
||||||
net.h \
|
net.h \
|
||||||
netbase.h \
|
netbase.h \
|
||||||
|
@ -191,6 +192,7 @@ libbitcoin_server_a_SOURCES = \
|
||||||
merkleblock.cpp \
|
merkleblock.cpp \
|
||||||
miner.cpp \
|
miner.cpp \
|
||||||
claimtrie.cpp \
|
claimtrie.cpp \
|
||||||
|
claimtriedb.cpp \
|
||||||
net.cpp \
|
net.cpp \
|
||||||
noui.cpp \
|
noui.cpp \
|
||||||
policy/fees.cpp \
|
policy/fees.cpp \
|
||||||
|
|
|
@ -131,6 +131,9 @@ public:
|
||||||
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||||
consensus.nPowTargetTimespan = 150; //retarget every block
|
consensus.nPowTargetTimespan = 150; //retarget every block
|
||||||
consensus.nPowTargetSpacing = 150;
|
consensus.nPowTargetSpacing = 150;
|
||||||
|
consensus.nOriginalClaimExpirationTime = 262974;
|
||||||
|
consensus.nExtendedClaimExpirationTime = 2102400;
|
||||||
|
consensus.nExtendedClaimExpirationForkHeight = 400155;
|
||||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||||
consensus.fPowNoRetargeting = false;
|
consensus.fPowNoRetargeting = false;
|
||||||
consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
|
consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
|
||||||
|
@ -215,6 +218,9 @@ public:
|
||||||
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
consensus.powLimit = uint256S("0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||||
consensus.nPowTargetTimespan = 150;
|
consensus.nPowTargetTimespan = 150;
|
||||||
consensus.nPowTargetSpacing = 150;
|
consensus.nPowTargetSpacing = 150;
|
||||||
|
consensus.nOriginalClaimExpirationTime = 262974;
|
||||||
|
consensus.nExtendedClaimExpirationTime = 2102400;
|
||||||
|
consensus.nExtendedClaimExpirationForkHeight = 278160;
|
||||||
consensus.fPowAllowMinDifficultyBlocks = true;
|
consensus.fPowAllowMinDifficultyBlocks = true;
|
||||||
consensus.fPowNoRetargeting = false;
|
consensus.fPowNoRetargeting = false;
|
||||||
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
|
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
|
||||||
|
@ -292,6 +298,9 @@ public:
|
||||||
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||||
consensus.nPowTargetTimespan = 1;//14 * 24 * 60 * 60; // two weeks
|
consensus.nPowTargetTimespan = 1;//14 * 24 * 60 * 60; // two weeks
|
||||||
consensus.nPowTargetSpacing = 1;
|
consensus.nPowTargetSpacing = 1;
|
||||||
|
consensus.nOriginalClaimExpirationTime = 500;
|
||||||
|
consensus.nExtendedClaimExpirationTime = 600;
|
||||||
|
consensus.nExtendedClaimExpirationForkHeight = 800;
|
||||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||||
consensus.fPowNoRetargeting = false;
|
consensus.fPowNoRetargeting = false;
|
||||||
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
|
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
|
||||||
|
|
File diff suppressed because it is too large
Load diff
148
src/claimtrie.h
148
src/claimtrie.h
|
@ -5,25 +5,12 @@
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
#include "uint256.h"
|
#include "uint256.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "dbwrapper.h"
|
#include "claimtriedb.h"
|
||||||
|
#include "chainparams.h"
|
||||||
#include "primitives/transaction.h"
|
#include "primitives/transaction.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
|
||||||
|
|
||||||
// leveldb keys
|
|
||||||
#define HASH_BLOCK 'h'
|
|
||||||
#define CURRENT_HEIGHT 't'
|
|
||||||
#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'
|
|
||||||
|
|
||||||
uint256 getValueHash(COutPoint outPoint, int nHeightOfLastTakeover);
|
uint256 getValueHash(COutPoint outPoint, int nHeightOfLastTakeover);
|
||||||
|
|
||||||
|
@ -211,7 +198,7 @@ struct nameOutPointHeightType
|
||||||
|
|
||||||
nameOutPointHeightType(std::string name, COutPoint outPoint, int nHeight)
|
nameOutPointHeightType(std::string name, COutPoint outPoint, int nHeight)
|
||||||
: name(name), outPoint(outPoint), nHeight(nHeight) {}
|
: name(name), outPoint(outPoint), nHeight(nHeight) {}
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
template <typename Stream, typename Operation>
|
||||||
|
@ -254,24 +241,75 @@ class CClaimIndexElement
|
||||||
READWRITE(claim);
|
READWRITE(claim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return name.empty() && claim.claimId.IsNull();
|
||||||
|
}
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
CClaimValue claim;
|
CClaimValue claim;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<std::string, CClaimValue> claimQueueEntryType;
|
struct claimQueueEntryHelper;
|
||||||
|
struct supportQueueEntryHelper;
|
||||||
|
|
||||||
typedef std::pair<std::string, CSupportValue> supportQueueEntryType;
|
struct queueNameRowHelper;
|
||||||
|
struct supportQueueNameRowHelper;
|
||||||
|
|
||||||
|
struct expirationQueueRowHelper;
|
||||||
|
struct supportExpirationQueueRowHelper;
|
||||||
|
|
||||||
|
template <typename Base, typename Form>
|
||||||
|
struct Generic : public Base
|
||||||
|
{
|
||||||
|
Generic() : Base() {}
|
||||||
|
Generic(const Base &base) : Base(base) {}
|
||||||
|
Generic(const Generic &generic) : Base(generic) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Base, typename Form> inline
|
||||||
|
void swap(Generic<Base, Form> &generic, Base &base)
|
||||||
|
{
|
||||||
|
Base base1 = generic;
|
||||||
|
generic = base;
|
||||||
|
base = base1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Base, typename Form> inline
|
||||||
|
void swap(Base &base, Generic<Base, Form> &generic)
|
||||||
|
{
|
||||||
|
swap(generic, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Generic<CClaimValue, claimQueueEntryHelper> claimQueueValueType;
|
||||||
|
typedef Generic<CSupportValue, supportQueueEntryHelper> supportQueueValueType;
|
||||||
|
|
||||||
|
typedef Generic<outPointHeightType, queueNameRowHelper> queueNameRowValueType;
|
||||||
|
typedef Generic<outPointHeightType, supportQueueNameRowHelper> supportQueueNameRowValueType;
|
||||||
|
|
||||||
|
typedef Generic<nameOutPointType, expirationQueueRowHelper> expirationQueueRowValueType;
|
||||||
|
typedef Generic<nameOutPointType, supportExpirationQueueRowHelper> supportExpirationQueueRowValueType;
|
||||||
|
|
||||||
|
typedef std::pair<std::string, claimQueueValueType> claimQueueEntryType;
|
||||||
|
|
||||||
|
typedef std::pair<std::string, supportQueueValueType> supportQueueEntryType;
|
||||||
|
|
||||||
typedef std::map<std::string, supportMapEntryType> supportMapType;
|
typedef std::map<std::string, supportMapEntryType> supportMapType;
|
||||||
|
|
||||||
typedef std::vector<outPointHeightType> queueNameRowType;
|
typedef std::vector<queueNameRowValueType> queueNameRowType;
|
||||||
typedef std::map<std::string, queueNameRowType> queueNameType;
|
typedef std::map<std::string, queueNameRowType> queueNameType;
|
||||||
|
|
||||||
|
typedef std::vector<supportQueueNameRowValueType> supportQueueNameRowType;
|
||||||
|
typedef std::map<std::string, supportQueueNameRowType> supportQueueNameType;
|
||||||
|
|
||||||
typedef std::vector<nameOutPointHeightType> insertUndoType;
|
typedef std::vector<nameOutPointHeightType> insertUndoType;
|
||||||
|
|
||||||
typedef std::vector<nameOutPointType> expirationQueueRowType;
|
typedef std::vector<expirationQueueRowValueType> expirationQueueRowType;
|
||||||
typedef std::map<int, expirationQueueRowType> expirationQueueType;
|
typedef std::map<int, expirationQueueRowType> expirationQueueType;
|
||||||
|
|
||||||
|
typedef std::vector<supportExpirationQueueRowValueType> supportExpirationQueueRowType;
|
||||||
|
typedef std::map<int, supportExpirationQueueRowType> supportExpirationQueueType;
|
||||||
|
|
||||||
typedef std::vector<claimQueueEntryType> claimQueueRowType;
|
typedef std::vector<claimQueueEntryType> claimQueueRowType;
|
||||||
typedef std::map<int, claimQueueRowType> claimQueueType;
|
typedef std::map<int, claimQueueRowType> claimQueueType;
|
||||||
|
|
||||||
|
@ -298,9 +336,9 @@ class CClaimTrie
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CClaimTrie(bool fMemory = false, bool fWipe = false, int nProportionalDelayFactor = 32)
|
CClaimTrie(bool fMemory = false, bool fWipe = false, int nProportionalDelayFactor = 32)
|
||||||
: db(GetDataDir() / "claimtrie", 100, fMemory, fWipe, false)
|
: nCurrentHeight(0), nExpirationTime(Params().GetConsensus().nOriginalClaimExpirationTime)
|
||||||
, nCurrentHeight(0), nExpirationTime(262974)
|
|
||||||
, nProportionalDelayFactor(nProportionalDelayFactor)
|
, nProportionalDelayFactor(nProportionalDelayFactor)
|
||||||
|
, db(fMemory, fWipe)
|
||||||
, root(uint256S("0000000000000000000000000000000000000000000000000000000000000001"))
|
, root(uint256S("0000000000000000000000000000000000000000000000000000000000000001"))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -319,7 +357,7 @@ public:
|
||||||
bool getLastTakeoverForName(const std::string& name, int& lastTakeoverHeight) const;
|
bool getLastTakeoverForName(const std::string& name, int& lastTakeoverHeight) const;
|
||||||
|
|
||||||
claimsForNameType getClaimsForName(const std::string& name) const;
|
claimsForNameType getClaimsForName(const std::string& name) const;
|
||||||
CAmount getEffectiveAmountForClaim(const std::string& name, uint160 claimId) const;
|
CAmount getEffectiveAmountForClaim(const std::string& name, uint160 claimId) const;
|
||||||
|
|
||||||
bool queueEmpty() const;
|
bool queueEmpty() const;
|
||||||
bool supportEmpty() const;
|
bool supportEmpty() const;
|
||||||
|
@ -333,13 +371,6 @@ public:
|
||||||
void removeFromClaimIndex(const CClaimValue& claim);
|
void removeFromClaimIndex(const CClaimValue& claim);
|
||||||
|
|
||||||
bool getClaimById(const uint160 claimId, std::string& name, CClaimValue& claim) const;
|
bool getClaimById(const uint160 claimId, std::string& name, CClaimValue& claim) const;
|
||||||
bool getQueueRow(int nHeight, claimQueueRowType& row) const;
|
|
||||||
bool getQueueNameRow(const std::string& name, queueNameRowType& row) const;
|
|
||||||
bool getExpirationQueueRow(int nHeight, expirationQueueRowType& row) const;
|
|
||||||
bool getSupportNode(std::string name, supportMapEntryType& node) const;
|
|
||||||
bool getSupportQueueRow(int nHeight, supportQueueRowType& row) const;
|
|
||||||
bool getSupportQueueNameRow(const std::string& name, queueNameRowType& row) const;
|
|
||||||
bool getSupportExpirationQueueRow(int nHeight, expirationQueueRowType& row) const;
|
|
||||||
|
|
||||||
|
|
||||||
bool haveClaim(const std::string& name, const COutPoint& outPoint) const;
|
bool haveClaim(const std::string& name, const COutPoint& outPoint) const;
|
||||||
|
@ -356,11 +387,11 @@ public:
|
||||||
|
|
||||||
friend class CClaimTrieCache;
|
friend class CClaimTrieCache;
|
||||||
|
|
||||||
CDBWrapper db;
|
|
||||||
int nCurrentHeight;
|
int nCurrentHeight;
|
||||||
int nExpirationTime;
|
int nExpirationTime;
|
||||||
int nProportionalDelayFactor;
|
int nProportionalDelayFactor;
|
||||||
private:
|
private:
|
||||||
|
CClaimTrieDb db;
|
||||||
void clear(CClaimTrieNode* current);
|
void clear(CClaimTrieNode* current);
|
||||||
|
|
||||||
const CClaimTrieNode* getNodeForName(const std::string& name) const;
|
const CClaimTrieNode* getNodeForName(const std::string& name) const;
|
||||||
|
@ -372,8 +403,8 @@ private:
|
||||||
expirationQueueType& expirationQueueCache, int nNewHeight,
|
expirationQueueType& expirationQueueCache, int nNewHeight,
|
||||||
supportMapType& supportCache,
|
supportMapType& supportCache,
|
||||||
supportQueueType& supportQueueCache,
|
supportQueueType& supportQueueCache,
|
||||||
queueNameType& supportQueueNameCache,
|
supportQueueNameType& supportQueueNameCache,
|
||||||
expirationQueueType& supportExpirationQueueCache);
|
supportExpirationQueueType& supportExpirationQueueCache);
|
||||||
bool updateName(const std::string& name, CClaimTrieNode* updatedNode);
|
bool updateName(const std::string& name, CClaimTrieNode* updatedNode);
|
||||||
bool updateHash(const std::string& name, uint256& hash);
|
bool updateHash(const std::string& name, uint256& hash);
|
||||||
bool updateTakeoverHeight(const std::string& name, int nTakeoverHeight);
|
bool updateTakeoverHeight(const std::string& name, int nTakeoverHeight);
|
||||||
|
@ -392,42 +423,11 @@ private:
|
||||||
std::vector<namedNodeType>& nodes) const;
|
std::vector<namedNodeType>& nodes) const;
|
||||||
|
|
||||||
void markNodeDirty(const std::string& name, CClaimTrieNode* node);
|
void markNodeDirty(const std::string& name, CClaimTrieNode* node);
|
||||||
void updateQueueRow(int nHeight, claimQueueRowType& row);
|
|
||||||
void updateQueueNameRow(const std::string& name,
|
|
||||||
queueNameRowType& row);
|
|
||||||
void updateExpirationRow(int nHeight, expirationQueueRowType& row);
|
|
||||||
void updateSupportMap(const std::string& name, supportMapEntryType& node);
|
|
||||||
void updateSupportQueue(int nHeight, supportQueueRowType& row);
|
|
||||||
void updateSupportNameQueue(const std::string& name,
|
|
||||||
queueNameRowType& row);
|
|
||||||
void updateSupportExpirationQueue(int nHeight, expirationQueueRowType& row);
|
|
||||||
|
|
||||||
void BatchWriteNode(CDBBatch& batch, const std::string& name,
|
|
||||||
const CClaimTrieNode* pNode) const;
|
|
||||||
void BatchEraseNode(CDBBatch& batch, const std::string& nome) const;
|
|
||||||
void BatchWriteClaimIndex(CDBBatch& batch) const;
|
|
||||||
void BatchWriteQueueRows(CDBBatch& batch);
|
|
||||||
void BatchWriteQueueNameRows(CDBBatch& batch);
|
|
||||||
void BatchWriteExpirationQueueRows(CDBBatch& batch);
|
|
||||||
void BatchWriteSupportNodes(CDBBatch& batch);
|
|
||||||
void BatchWriteSupportQueueRows(CDBBatch& batch);
|
|
||||||
void BatchWriteSupportQueueNameRows(CDBBatch& batch);
|
|
||||||
void BatchWriteSupportExpirationQueueRows(CDBBatch& batch);
|
|
||||||
template<typename K> bool keyTypeEmpty(char key, K& dummy) const;
|
|
||||||
|
|
||||||
CClaimTrieNode root;
|
CClaimTrieNode root;
|
||||||
uint256 hashBlock;
|
uint256 hashBlock;
|
||||||
|
|
||||||
claimQueueType dirtyQueueRows;
|
|
||||||
queueNameType dirtyQueueNameRows;
|
|
||||||
expirationQueueType dirtyExpirationQueueRows;
|
|
||||||
|
|
||||||
supportQueueType dirtySupportQueueRows;
|
|
||||||
queueNameType dirtySupportQueueNameRows;
|
|
||||||
expirationQueueType dirtySupportExpirationQueueRows;
|
|
||||||
|
|
||||||
nodeCacheType dirtyNodes;
|
nodeCacheType dirtyNodes;
|
||||||
supportMapType dirtySupportNodes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CClaimTrieProofNode
|
class CClaimTrieProofNode
|
||||||
|
@ -516,6 +516,12 @@ public:
|
||||||
CClaimTrieProof getProofForName(const std::string& name) const;
|
CClaimTrieProof getProofForName(const std::string& name) const;
|
||||||
|
|
||||||
bool finalizeDecrement() const;
|
bool finalizeDecrement() const;
|
||||||
|
|
||||||
|
void removeAndAddSupportToExpirationQueue(supportExpirationQueueRowType &row, int height, bool increment) const;
|
||||||
|
void removeAndAddToExpirationQueue(expirationQueueRowType &row, int height, bool increment) const;
|
||||||
|
|
||||||
|
bool forkForExpirationChange(bool increment) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CClaimTrie* base;
|
CClaimTrie* base;
|
||||||
|
|
||||||
|
@ -530,10 +536,10 @@ protected:
|
||||||
mutable expirationQueueType expirationQueueCache;
|
mutable expirationQueueType expirationQueueCache;
|
||||||
mutable supportMapType supportCache;
|
mutable supportMapType supportCache;
|
||||||
mutable supportQueueType supportQueueCache;
|
mutable supportQueueType supportQueueCache;
|
||||||
mutable queueNameType supportQueueNameCache;
|
mutable supportQueueNameType supportQueueNameCache;
|
||||||
mutable expirationQueueType supportExpirationQueueCache;
|
mutable supportExpirationQueueType supportExpirationQueueCache;
|
||||||
mutable std::set<std::string> namesToCheckForTakeover;
|
mutable std::set<std::string> namesToCheckForTakeover;
|
||||||
mutable std::map<std::string, int> cacheTakeoverHeights;
|
mutable std::map<std::string, int> cacheTakeoverHeights;
|
||||||
mutable int nCurrentHeight; // Height of the block that is being worked on, which is
|
mutable int nCurrentHeight; // Height of the block that is being worked on, which is
|
||||||
// one greater than the height of the chain's tip
|
// one greater than the height of the chain's tip
|
||||||
|
|
||||||
|
@ -580,10 +586,10 @@ protected:
|
||||||
|
|
||||||
supportQueueType::iterator getSupportQueueCacheRow(int nHeight,
|
supportQueueType::iterator getSupportQueueCacheRow(int nHeight,
|
||||||
bool createIfNotExists) const;
|
bool createIfNotExists) const;
|
||||||
queueNameType::iterator getSupportQueueCacheNameRow(const std::string& name,
|
supportQueueNameType::iterator getSupportQueueCacheNameRow(const std::string& name,
|
||||||
bool createIfNotExists) const;
|
bool createIfNotExists) const;
|
||||||
expirationQueueType::iterator getSupportExpirationQueueCacheRow(int nHeight,
|
supportExpirationQueueType::iterator getSupportExpirationQueueCacheRow(int nHeight,
|
||||||
bool createIfNotExists) const;
|
bool createIfNotExists) const;
|
||||||
|
|
||||||
bool addSupportToQueues(const std::string& name, CSupportValue& support) const;
|
bool addSupportToQueues(const std::string& name, CSupportValue& support) const;
|
||||||
bool removeSupportFromQueue(const std::string& name, const COutPoint& outPoint,
|
bool removeSupportFromQueue(const std::string& name, const COutPoint& outPoint,
|
||||||
|
|
188
src/claimtriedb.cpp
Normal file
188
src/claimtriedb.cpp
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
|
||||||
|
#include "claimtriedb.h"
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
class CCMap : public CCBase
|
||||||
|
{
|
||||||
|
std::map<K, V> data;
|
||||||
|
public:
|
||||||
|
CCMap() : data() {}
|
||||||
|
std::map<K, V>& data_map() { return data; }
|
||||||
|
void write(size_t key, CClaimTrieDb *db)
|
||||||
|
{
|
||||||
|
for (auto &it : data)
|
||||||
|
{
|
||||||
|
if (it.second.empty())
|
||||||
|
{
|
||||||
|
db->Erase(std::make_pair(key, it.first));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
db->Write(std::make_pair(key, it.first), it.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CClaimTrieDb::CClaimTrieDb(bool fMemory, bool fWipe)
|
||||||
|
: CDBWrapper(GetDataDir() / "claimtrie", 100, fMemory, fWipe, false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CClaimTrieDb::~CClaimTrieDb()
|
||||||
|
{
|
||||||
|
for (std::map<size_t, CCBase*>::iterator itQueue = queues.begin(); itQueue != queues.end(); ++itQueue)
|
||||||
|
{
|
||||||
|
delete itQueue->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CClaimTrieDb::writeQueues()
|
||||||
|
{
|
||||||
|
for (std::map<size_t, CCBase*>::iterator itQueue = queues.begin(); itQueue != queues.end(); ++itQueue)
|
||||||
|
{
|
||||||
|
itQueue->second->write(itQueue->first, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V> bool CClaimTrieDb::getQueueRow(const K &key, V &row) const
|
||||||
|
{
|
||||||
|
const size_t hash = boost::typeindex::type_id<std::map<K, V> >().hash_code();
|
||||||
|
std::map<size_t, CCBase*>::const_iterator itQueue = queues.find(hash);
|
||||||
|
if (itQueue != queues.end())
|
||||||
|
{
|
||||||
|
std::map<K, V> &map = (static_cast<CCMap<K, V>*>(itQueue->second))->data_map();
|
||||||
|
typename std::map<K, V>::iterator itMap = map.find(key);
|
||||||
|
if (itMap != map.end())
|
||||||
|
{
|
||||||
|
row = itMap->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Read(std::make_pair(hash, key), row);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V> void CClaimTrieDb::updateQueueRow(const K &key, V &row)
|
||||||
|
{
|
||||||
|
const size_t hash = boost::typeindex::type_id<std::map<K, V> >().hash_code();
|
||||||
|
std::map<size_t, CCBase*>::iterator itQueue = queues.find(hash);
|
||||||
|
if (itQueue == queues.end())
|
||||||
|
{
|
||||||
|
itQueue = queues.insert(itQueue, std::pair<size_t, CCBase*>(hash, new CCMap<K, V>));
|
||||||
|
}
|
||||||
|
std::map<K, V> &map = (static_cast<CCMap<K, V>*>(itQueue->second))->data_map();
|
||||||
|
typename std::map<K, V>::iterator itMap = map.find(key);
|
||||||
|
if (itMap == map.end())
|
||||||
|
{
|
||||||
|
itMap = map.insert(itMap, std::make_pair(key, row));
|
||||||
|
}
|
||||||
|
std::swap(itMap->second, row);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V> bool CClaimTrieDb::keyTypeEmpty() const
|
||||||
|
{
|
||||||
|
const size_t hash = boost::typeindex::type_id<std::map<K, V> >().hash_code();
|
||||||
|
std::map<size_t, CCBase*>::const_iterator itQueue = queues.find(hash);
|
||||||
|
if (itQueue != queues.end())
|
||||||
|
{
|
||||||
|
std::map<K, V> &map = (static_cast<CCMap<K, V>*>(itQueue->second))->data_map();
|
||||||
|
for (typename std::map<K, V>::iterator itMap = map.begin(); itMap != map.end(); ++itMap)
|
||||||
|
{
|
||||||
|
if (!itMap->second.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::scoped_ptr<CDBIterator> pcursor(const_cast<CClaimTrieDb*>(this)->NewIterator());
|
||||||
|
pcursor->SeekToFirst();
|
||||||
|
|
||||||
|
while (pcursor->Valid())
|
||||||
|
{
|
||||||
|
std::pair<size_t, K> key;
|
||||||
|
if (pcursor->GetKey(key))
|
||||||
|
{
|
||||||
|
if (key.first == hash)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pcursor->Next();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V> bool CClaimTrieDb::SeekFirstKey(K &keyOut, V &value) const
|
||||||
|
{
|
||||||
|
const size_t hash = boost::typeindex::type_id<std::map<K, V> >().hash_code();
|
||||||
|
boost::scoped_ptr<CDBIterator> pcursor(const_cast<CClaimTrieDb*>(this)->NewIterator());
|
||||||
|
pcursor->SeekToFirst();
|
||||||
|
|
||||||
|
while (pcursor->Valid())
|
||||||
|
{
|
||||||
|
std::pair<size_t, K> key;
|
||||||
|
if (pcursor->GetKey(key))
|
||||||
|
{
|
||||||
|
if (key.first == hash)
|
||||||
|
{
|
||||||
|
if (pcursor->GetValue(value))
|
||||||
|
{
|
||||||
|
keyOut = key.second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pcursor->Next();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename K, typename V> bool CClaimTrieDb::getQueueMap(std::map<K,V> &map) const
|
||||||
|
{
|
||||||
|
const size_t hash = boost::typeindex::type_id<std::map<K, V> >().hash_code();
|
||||||
|
std::map<size_t, CCBase*>::const_iterator itQueue = queues.find(hash);
|
||||||
|
if (itQueue != queues.end())
|
||||||
|
{
|
||||||
|
map = (static_cast<CCMap<K, V>*>(itQueue->second))->data_map();
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::scoped_ptr<CDBIterator> pcursor(const_cast<CClaimTrieDb*>(this)->NewIterator());
|
||||||
|
pcursor->SeekToFirst();
|
||||||
|
|
||||||
|
while (pcursor->Valid())
|
||||||
|
{
|
||||||
|
std::pair<size_t, K> key;
|
||||||
|
if (pcursor->GetKey(key))
|
||||||
|
{
|
||||||
|
if (key.first == hash)
|
||||||
|
{
|
||||||
|
typename std::map<K, V>::iterator itMap = map.find(key.second);
|
||||||
|
if (itMap != map.end())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
V value;
|
||||||
|
if (pcursor->GetValue(value))
|
||||||
|
{
|
||||||
|
map.insert(itMap, std::make_pair(key.second, value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pcursor->Next();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
40
src/claimtriedb.h
Normal file
40
src/claimtriedb.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef BITCOIN_CLAIMTRIE_DB_H
|
||||||
|
#define BITCOIN_CLAIMTRIE_DB_H
|
||||||
|
|
||||||
|
#include "dbwrapper.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <boost/type_index.hpp>
|
||||||
|
|
||||||
|
class CClaimTrieDb;
|
||||||
|
|
||||||
|
class CCBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~CCBase() {}
|
||||||
|
virtual void write(size_t key, CClaimTrieDb *db) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CClaimTrieDb : public CDBWrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CClaimTrieDb(bool fMemory = false, bool fWipe = false);
|
||||||
|
~CClaimTrieDb();
|
||||||
|
|
||||||
|
void writeQueues();
|
||||||
|
|
||||||
|
template <typename K, typename V> bool getQueueMap(std::map<K,V> &map) const;
|
||||||
|
|
||||||
|
template <typename K, typename V> bool getQueueRow(const K &key, V &row) const;
|
||||||
|
template <typename K, typename V> void updateQueueRow(const K &key, V &row);
|
||||||
|
|
||||||
|
template <typename K, typename V> bool keyTypeEmpty() const;
|
||||||
|
template <typename K, typename V> bool SeekFirstKey(K &key, V &value) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<size_t, CCBase*> queues;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BITCOIN_CLAIMTRIE_DB_H
|
|
@ -16,8 +16,8 @@
|
||||||
//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
|
//! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it
|
||||||
#define CLIENT_VERSION_MAJOR 0
|
#define CLIENT_VERSION_MAJOR 0
|
||||||
#define CLIENT_VERSION_MINOR 12
|
#define CLIENT_VERSION_MINOR 12
|
||||||
#define CLIENT_VERSION_REVISION 1
|
#define CLIENT_VERSION_REVISION 2
|
||||||
#define CLIENT_VERSION_BUILD 2
|
#define CLIENT_VERSION_BUILD 0
|
||||||
|
|
||||||
//! Set to true for release, false for prerelease or test build
|
//! Set to true for release, false for prerelease or test build
|
||||||
#define CLIENT_VERSION_IS_RELEASE true
|
#define CLIENT_VERSION_IS_RELEASE true
|
||||||
|
|
|
@ -58,6 +58,14 @@ struct Params {
|
||||||
bool fPowNoRetargeting;
|
bool fPowNoRetargeting;
|
||||||
int64_t nPowTargetSpacing;
|
int64_t nPowTargetSpacing;
|
||||||
int64_t nPowTargetTimespan;
|
int64_t nPowTargetTimespan;
|
||||||
|
int64_t nOriginalClaimExpirationTime;
|
||||||
|
int64_t nExtendedClaimExpirationTime;
|
||||||
|
int64_t nExtendedClaimExpirationForkHeight;
|
||||||
|
int64_t GetExpirationTime(int64_t nHeight) const {
|
||||||
|
return nHeight < nExtendedClaimExpirationForkHeight ?
|
||||||
|
nOriginalClaimExpirationTime :
|
||||||
|
nExtendedClaimExpirationTime;
|
||||||
|
}
|
||||||
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
|
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
|
||||||
};
|
};
|
||||||
} // namespace Consensus
|
} // namespace Consensus
|
||||||
|
|
|
@ -1229,6 +1229,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024));
|
LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024));
|
||||||
LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024));
|
LogPrintf("* Using %.1fMiB for in-memory UTXO set\n", nCoinCacheUsage * (1.0 / 1024 / 1024));
|
||||||
|
|
||||||
|
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||||
|
|
||||||
bool fLoaded = false;
|
bool fLoaded = false;
|
||||||
while (!fLoaded) {
|
while (!fLoaded) {
|
||||||
bool fReset = fReindex;
|
bool fReset = fReindex;
|
||||||
|
@ -1266,7 +1268,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
|
|
||||||
// If the loaded chain has a wrong genesis, bail out immediately
|
// If the loaded chain has a wrong genesis, bail out immediately
|
||||||
// (we're likely using a testnet datadir, or the other way around).
|
// (we're likely using a testnet datadir, or the other way around).
|
||||||
if (!mapBlockIndex.empty() && mapBlockIndex.count(chainparams.GetConsensus().hashGenesisBlock) == 0)
|
if (!mapBlockIndex.empty() && mapBlockIndex.count(consensusParams.hashGenesisBlock) == 0)
|
||||||
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
|
return InitError(_("Incorrect or no genesis block found. Wrong datadir for network?"));
|
||||||
|
|
||||||
// Initialize the block index (no-op if non-empty database was already loaded)
|
// Initialize the block index (no-op if non-empty database was already loaded)
|
||||||
|
@ -1422,6 +1424,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
|
|
||||||
RandAddSeedPerfmon();
|
RandAddSeedPerfmon();
|
||||||
|
|
||||||
|
pclaimTrie->setExpirationTime(consensusParams.GetExpirationTime(chainActive.Height()));
|
||||||
|
|
||||||
//// debug print
|
//// debug print
|
||||||
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
|
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
|
||||||
LogPrintf("nBestHeight = %d\n", chainActive.Height());
|
LogPrintf("nBestHeight = %d\n", chainActive.Height());
|
||||||
|
@ -1437,7 +1441,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||||
StartNode(threadGroup, scheduler);
|
StartNode(threadGroup, scheduler);
|
||||||
|
|
||||||
// Monitor the chain, and alert if we get blocks much quicker or slower than expected
|
// Monitor the chain, and alert if we get blocks much quicker or slower than expected
|
||||||
int64_t nPowTargetSpacing = Params().GetConsensus().nPowTargetSpacing;
|
int64_t nPowTargetSpacing = consensusParams.nPowTargetSpacing;
|
||||||
CScheduler::Function f = boost::bind(&PartitionCheck, &IsInitialBlockDownload,
|
CScheduler::Function f = boost::bind(&PartitionCheck, &IsInitialBlockDownload,
|
||||||
boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
|
boost::ref(cs_main), boost::cref(pindexBestHeader), nPowTargetSpacing);
|
||||||
scheduler.scheduleEvery(f, nPowTargetSpacing);
|
scheduler.scheduleEvery(f, nPowTargetSpacing);
|
||||||
|
|
41
src/main.cpp
41
src/main.cpp
|
@ -2171,12 +2171,22 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
||||||
if (op == OP_CLAIM_NAME)
|
if (op == OP_CLAIM_NAME)
|
||||||
{
|
{
|
||||||
assert(vvchParams.size() == 2);
|
assert(vvchParams.size() == 2);
|
||||||
|
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||||
|
std::string value(vvchParams[1].begin(), vvchParams[1].end());
|
||||||
claimId = ClaimIdHash(hash, i);
|
claimId = ClaimIdHash(hash, i);
|
||||||
|
LogPrintf("--- %s[%lu]: OP_CLAIM_NAME \"%s\" = \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||||
|
__func__, pindex->nHeight, name, SanitizeString(value),
|
||||||
|
claimId.GetHex(), hash.ToString(), i);
|
||||||
}
|
}
|
||||||
else if (op == OP_UPDATE_CLAIM)
|
else if (op == OP_UPDATE_CLAIM)
|
||||||
{
|
{
|
||||||
assert(vvchParams.size() == 3);
|
assert(vvchParams.size() == 3);
|
||||||
|
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||||
|
std::string value(vvchParams[1].begin(), vvchParams[1].end());
|
||||||
claimId = uint160(vvchParams[1]);
|
claimId = uint160(vvchParams[1]);
|
||||||
|
LogPrintf("--- %s[%lu]: OP_UPDATE_CLAIM \"%s\" = \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||||
|
__func__, pindex->nHeight, name, SanitizeString(value),
|
||||||
|
claimId.GetHex(), hash.ToString(), i);
|
||||||
}
|
}
|
||||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||||
LogPrintf("%s: (txid: %s, nOut: %d) Trying to remove %s from the claim trie due to its block being disconnected\n", __func__, hash.ToString(), i, name.c_str());
|
LogPrintf("%s: (txid: %s, nOut: %d) Trying to remove %s from the claim trie due to its block being disconnected\n", __func__, hash.ToString(), i, name.c_str());
|
||||||
|
@ -2190,6 +2200,8 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
||||||
assert(vvchParams.size() == 2);
|
assert(vvchParams.size() == 2);
|
||||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||||
uint160 supportedClaimId(vvchParams[1]);
|
uint160 supportedClaimId(vvchParams[1]);
|
||||||
|
LogPrintf("--- %s[%lu]: OP_SUPPORT_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||||
|
__func__, pindex->nHeight, name, supportedClaimId.GetHex(), hash.ToString(), i);
|
||||||
LogPrintf("%s: (txid: %s, nOut: %d) Removing support for claim id %s on %s due to its block being disconnected\n", __func__, hash.ToString(), i, supportedClaimId.ToString(), name.c_str());
|
LogPrintf("%s: (txid: %s, nOut: %d) Removing support for claim id %s on %s due to its block being disconnected\n", __func__, hash.ToString(), i, supportedClaimId.ToString(), name.c_str());
|
||||||
if (!trieCache.undoAddSupport(name, COutPoint(hash, i), pindex->nHeight))
|
if (!trieCache.undoAddSupport(name, COutPoint(hash, i), pindex->nHeight))
|
||||||
LogPrintf("%s: Something went wrong removing support for name %s in hash %s\n", __func__, name.c_str(), hash.ToString());
|
LogPrintf("%s: Something went wrong removing support for name %s in hash %s\n", __func__, name.c_str(), hash.ToString());
|
||||||
|
@ -2220,6 +2232,13 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
||||||
assert(trieCache.finalizeDecrement());
|
assert(trieCache.finalizeDecrement());
|
||||||
trieCache.setBestBlock(pindex->pprev->GetBlockHash());
|
trieCache.setBestBlock(pindex->pprev->GetBlockHash());
|
||||||
assert(trieCache.getMerkleHash() == pindex->pprev->hashClaimTrie);
|
assert(trieCache.getMerkleHash() == pindex->pprev->hashClaimTrie);
|
||||||
|
if (pindex->nHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
||||||
|
{
|
||||||
|
LogPrintf("Decremented past the extended claim expiration hard fork height");
|
||||||
|
pclaimTrie->setExpirationTime(Params().GetConsensus().GetExpirationTime(pindex->nHeight-1));
|
||||||
|
trieCache.forkForExpirationChange(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pfClean) {
|
if (pfClean) {
|
||||||
*pfClean = fClean;
|
*pfClean = fClean;
|
||||||
|
@ -2480,6 +2499,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
|
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
|
||||||
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
|
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// v 13 LBRYcrd hard fork to extend expiration time
|
||||||
|
if (pindex->nHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
||||||
|
{
|
||||||
|
LogPrintf("Incremented past the extended claim expiration hard fork height");
|
||||||
|
pclaimTrie->setExpirationTime(chainparams.GetConsensus().GetExpirationTime(pindex->nHeight));
|
||||||
|
trieCache.forkForExpirationChange(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
|
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
|
||||||
LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001);
|
LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001);
|
||||||
|
@ -2573,12 +2601,22 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
if (op == OP_CLAIM_NAME)
|
if (op == OP_CLAIM_NAME)
|
||||||
{
|
{
|
||||||
assert(vvchParams.size() == 2);
|
assert(vvchParams.size() == 2);
|
||||||
|
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||||
|
std::string value(vvchParams[1].begin(), vvchParams[1].end());
|
||||||
claimId = ClaimIdHash(txin.prevout.hash, txin.prevout.n);
|
claimId = ClaimIdHash(txin.prevout.hash, txin.prevout.n);
|
||||||
|
LogPrintf("+++ %s[%lu]: OP_CLAIM_NAME \"%s\" = \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||||
|
__func__, pindex->nHeight, name, SanitizeString(value),
|
||||||
|
claimId.GetHex(), txin.prevout.hash.GetHex(), txin.prevout.n);
|
||||||
}
|
}
|
||||||
else if (op == OP_UPDATE_CLAIM)
|
else if (op == OP_UPDATE_CLAIM)
|
||||||
{
|
{
|
||||||
assert(vvchParams.size() == 3);
|
assert(vvchParams.size() == 3);
|
||||||
|
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||||
|
std::string value(vvchParams[1].begin(), vvchParams[1].end());
|
||||||
claimId = uint160(vvchParams[1]);
|
claimId = uint160(vvchParams[1]);
|
||||||
|
LogPrintf("+++ %s[%lu]: OP_UPDATE_CLAIM \"%s\" = \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||||
|
__func__, pindex->nHeight, name, SanitizeString(value),
|
||||||
|
claimId.GetHex(), txin.prevout.hash.GetHex(), txin.prevout.n);
|
||||||
}
|
}
|
||||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||||
int nValidAtHeight;
|
int nValidAtHeight;
|
||||||
|
@ -2595,6 +2633,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
assert(vvchParams.size() == 2);
|
assert(vvchParams.size() == 2);
|
||||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||||
uint160 supportedClaimId(vvchParams[1]);
|
uint160 supportedClaimId(vvchParams[1]);
|
||||||
|
LogPrintf("+++ %s[%lu]: OP_SUPPORT_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||||
|
__func__, pindex->nHeight, name,
|
||||||
|
supportedClaimId.GetHex(), txin.prevout.hash.GetHex(), txin.prevout.n);
|
||||||
int nValidAtHeight;
|
int nValidAtHeight;
|
||||||
LogPrintf("%s: Removing support for %s in %s. Tx: %s, nOut: %d, removed txid: %s\n", __func__, supportedClaimId.ToString(), name, txin.prevout.hash.ToString(), txin.prevout.n,tx.GetHash().ToString());
|
LogPrintf("%s: Removing support for %s in %s. Tx: %s, nOut: %d, removed txid: %s\n", __func__, supportedClaimId.ToString(), name, txin.prevout.hash.ToString(), txin.prevout.n,tx.GetHash().ToString());
|
||||||
if (trieCache.spendSupport(name, COutPoint(txin.prevout.hash, txin.prevout.n), coins->nHeight, nValidAtHeight))
|
if (trieCache.spendSupport(name, COutPoint(txin.prevout.hash, txin.prevout.n), coins->nHeight, nValidAtHeight))
|
||||||
|
|
28
src/pow.cpp
28
src/pow.cpp
|
@ -14,31 +14,21 @@
|
||||||
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
|
||||||
{
|
{
|
||||||
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
|
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
|
||||||
|
|
||||||
// Genesis block
|
// Genesis block
|
||||||
if (pindexLast == NULL)
|
if (pindexLast == NULL)
|
||||||
return nProofOfWorkLimit;
|
return nProofOfWorkLimit;
|
||||||
|
|
||||||
// Only change once per difficulty adjustment interval
|
if (params.fPowAllowMinDifficultyBlocks && pindexLast->nHeight >= 277299)
|
||||||
if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
|
|
||||||
{
|
{
|
||||||
if (params.fPowAllowMinDifficultyBlocks)
|
// Special difficulty rule for testnet:
|
||||||
{
|
// If the new block's timestamp is twice the target block time
|
||||||
// Special difficulty rule for testnet:
|
// then allow mining of a min-difficulty block.
|
||||||
// If the new block's timestamp is more than 2* 10 minutes
|
// This is to prevent the testnet from gettig stuck when a large amount
|
||||||
// then allow mining of a min-difficulty block.
|
// of hashrate drops off the network.
|
||||||
if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
|
// This rule was not implemented properly until testnet block 277299.
|
||||||
return nProofOfWorkLimit;
|
if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2){
|
||||||
else
|
return nProofOfWorkLimit;
|
||||||
{
|
|
||||||
// Return the last non-special-min-difficulty-rules-block
|
|
||||||
const CBlockIndex* pindex = pindexLast;
|
|
||||||
while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
|
|
||||||
pindex = pindex->pprev;
|
|
||||||
return pindex->nBits;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return pindexLast->nBits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go back the full period unless it's the first retarget after genesis.
|
// Go back the full period unless it's the first retarget after genesis.
|
||||||
|
|
|
@ -23,7 +23,6 @@ using namespace std;
|
||||||
|
|
||||||
BOOST_FIXTURE_TEST_SUITE(claimtriebranching_tests, RegTestingSetup)
|
BOOST_FIXTURE_TEST_SUITE(claimtriebranching_tests, RegTestingSetup)
|
||||||
|
|
||||||
|
|
||||||
//is a claim in queue
|
//is a claim in queue
|
||||||
boost::test_tools::predicate_result
|
boost::test_tools::predicate_result
|
||||||
is_claim_in_queue(std::string name, const CTransaction &tx)
|
is_claim_in_queue(std::string name, const CTransaction &tx)
|
||||||
|
@ -164,7 +163,16 @@ struct ClaimTrieChainFixture{
|
||||||
unsigned int num_txs;
|
unsigned int num_txs;
|
||||||
unsigned int num_txs_for_next_block;
|
unsigned int num_txs_for_next_block;
|
||||||
|
|
||||||
ClaimTrieChainFixture()
|
// these will take on regtest parameters
|
||||||
|
const int expirationForkHeight;
|
||||||
|
const int originalExpiration;
|
||||||
|
const int extendedExpiration;
|
||||||
|
|
||||||
|
|
||||||
|
ClaimTrieChainFixture():
|
||||||
|
expirationForkHeight(Params(CBaseChainParams::REGTEST).GetConsensus().nExtendedClaimExpirationForkHeight),
|
||||||
|
originalExpiration(Params(CBaseChainParams::REGTEST).GetConsensus().nOriginalClaimExpirationTime),
|
||||||
|
extendedExpiration(Params(CBaseChainParams::REGTEST).GetConsensus().nExtendedClaimExpirationTime)
|
||||||
{
|
{
|
||||||
fRequireStandard = false;
|
fRequireStandard = false;
|
||||||
BOOST_CHECK(pclaimTrie->nCurrentHeight == chainActive.Height() + 1);
|
BOOST_CHECK(pclaimTrie->nCurrentHeight == chainActive.Height() + 1);
|
||||||
|
@ -300,6 +308,17 @@ struct ClaimTrieChainFixture{
|
||||||
num_txs_for_next_block = 0;
|
num_txs_for_next_block = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WriteClearReadClaimTrie()
|
||||||
|
{
|
||||||
|
// this will simulate restart of lbrycrdd by writing the claimtrie to disk,
|
||||||
|
// clearing the-in memory claimtrie, and then reading the saved claimtrie
|
||||||
|
// from disk
|
||||||
|
pclaimTrie->WriteToDisk();
|
||||||
|
pclaimTrie->clear();
|
||||||
|
pclaimTrie->ReadFromDisk(true);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -683,6 +702,7 @@ BOOST_AUTO_TEST_CASE(claimtriebranching_update)
|
||||||
fixture.DecrementBlocks(11);
|
fixture.DecrementBlocks(11);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
expiration
|
expiration
|
||||||
check claims expire and loses claim
|
check claims expire and loses claim
|
||||||
|
@ -844,4 +864,204 @@ BOOST_AUTO_TEST_CASE(claimtriebranching_get_claim_by_id)
|
||||||
BOOST_CHECK(claimValue2.claimId != claimId);
|
BOOST_CHECK(claimValue2.claimId != claimId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
claim expiration for hard fork
|
||||||
|
check claims do not expire post ExpirationForkHeight
|
||||||
|
check supports work post ExpirationForkHeight
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE(claimtriebranching_hardfork_claim)
|
||||||
|
{
|
||||||
|
ClaimTrieChainFixture fixture;
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(pclaimTrie->nExpirationTime, fixture.originalExpiration);
|
||||||
|
// First create a claim and make sure it expires pre-fork
|
||||||
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",3);
|
||||||
|
fixture.IncrementBlocks(fixture.originalExpiration+1);
|
||||||
|
BOOST_CHECK(!is_best_claim("test",tx1));
|
||||||
|
fixture.DecrementBlocks(fixture.originalExpiration);
|
||||||
|
BOOST_CHECK(is_best_claim("test",tx1));
|
||||||
|
fixture.IncrementBlocks(fixture.originalExpiration);
|
||||||
|
BOOST_CHECK(!is_best_claim("test",tx1));
|
||||||
|
|
||||||
|
// Create a claim 1 block before the fork height that will expire after the fork height
|
||||||
|
fixture.IncrementBlocks(fixture.expirationForkHeight - chainActive.Height() -2);
|
||||||
|
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(),"test2","one",3);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
BOOST_CHECK_EQUAL(chainActive.Height(), fixture.expirationForkHeight -1);
|
||||||
|
|
||||||
|
// Disable future expirations and fast-forward past the fork height
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
BOOST_CHECK_EQUAL(chainActive.Height(), fixture.expirationForkHeight);
|
||||||
|
BOOST_CHECK_EQUAL(pclaimTrie->nExpirationTime, fixture.extendedExpiration);
|
||||||
|
// make sure decrementing to before the fork height will apppropriately set back the
|
||||||
|
// expiration time to the original expiraiton time
|
||||||
|
fixture.DecrementBlocks(1);
|
||||||
|
BOOST_CHECK_EQUAL(pclaimTrie->nExpirationTime, fixture.originalExpiration);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
|
// make sure that claim created 1 block before the fork expires as expected
|
||||||
|
// at the extended expiration times
|
||||||
|
BOOST_CHECK(is_best_claim("test2", tx2));
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration-1);
|
||||||
|
BOOST_CHECK(!is_best_claim("test2", tx2));
|
||||||
|
fixture.DecrementBlocks(fixture.extendedExpiration-1);
|
||||||
|
|
||||||
|
// This first claim is still expired since it's pre-fork, even
|
||||||
|
// after fork activation
|
||||||
|
BOOST_CHECK(!is_best_claim("test",tx1));
|
||||||
|
|
||||||
|
// This new claim created at the fork height cannot expire at original expiration
|
||||||
|
BOOST_CHECK_EQUAL(chainActive.Height(), fixture.expirationForkHeight);
|
||||||
|
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
fixture.IncrementBlocks(fixture.originalExpiration);
|
||||||
|
BOOST_CHECK(is_best_claim("test",tx3));
|
||||||
|
BOOST_CHECK(!is_best_claim("test",tx1));
|
||||||
|
fixture.DecrementBlocks(fixture.originalExpiration);
|
||||||
|
|
||||||
|
// but it expires at the extended expiration, and not a single block below
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration);
|
||||||
|
BOOST_CHECK(!is_best_claim("test",tx3));
|
||||||
|
fixture.DecrementBlocks(fixture.extendedExpiration);
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration-1);
|
||||||
|
BOOST_CHECK(is_best_claim("test",tx3));
|
||||||
|
fixture.DecrementBlocks(fixture.extendedExpiration-1);
|
||||||
|
|
||||||
|
|
||||||
|
// Ensure that we cannot update the original pre-fork expired claim
|
||||||
|
CMutableTransaction u1 = fixture.MakeUpdate(tx1,"test","two",ClaimIdHash(tx1.GetHash(),0), 3);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
BOOST_CHECK(!is_best_claim("test",u1));
|
||||||
|
|
||||||
|
// Ensure that supports for the expired claim don't support it
|
||||||
|
CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(),u1,"test",10);
|
||||||
|
BOOST_CHECK(!is_best_claim("test",u1));
|
||||||
|
|
||||||
|
// Ensure that we can update the new post-fork claim
|
||||||
|
CMutableTransaction u2 = fixture.MakeUpdate(tx3,"test","two",ClaimIdHash(tx3.GetHash(),0), 1);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
BOOST_CHECK(is_best_claim("test",u2));
|
||||||
|
|
||||||
|
// Ensure that supports for the new post-fork claim
|
||||||
|
CMutableTransaction s2 = fixture.MakeSupport(fixture.GetCoinbase(),u2,"test",3);
|
||||||
|
BOOST_CHECK(is_best_claim("test",u2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
support expiration for hard fork
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE(claimtriebranching_hardfork_support)
|
||||||
|
{
|
||||||
|
ClaimTrieChainFixture fixture;
|
||||||
|
|
||||||
|
int blocks_before_fork = 10;
|
||||||
|
fixture.IncrementBlocks(fixture.expirationForkHeight - chainActive.Height() - blocks_before_fork-1);
|
||||||
|
// Create claim and support it before the fork height
|
||||||
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1);
|
||||||
|
CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(),tx1,"test",2);
|
||||||
|
// this claim will win without the support
|
||||||
|
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
fixture.IncrementBlocks(blocks_before_fork);
|
||||||
|
|
||||||
|
// check that the claim expires as expected at the extended time, as does the support
|
||||||
|
fixture.IncrementBlocks(fixture.originalExpiration - blocks_before_fork);
|
||||||
|
BOOST_CHECK(is_best_claim("test",tx1));
|
||||||
|
BOOST_CHECK(best_claim_effective_amount_equals("test",3));
|
||||||
|
fixture.DecrementBlocks(fixture.originalExpiration - blocks_before_fork);
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration - blocks_before_fork);
|
||||||
|
BOOST_CHECK(!is_best_claim("test",tx1));
|
||||||
|
fixture.DecrementBlocks(fixture.extendedExpiration - blocks_before_fork);
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration - blocks_before_fork - 1);
|
||||||
|
BOOST_CHECK(is_best_claim("test",tx1));
|
||||||
|
BOOST_CHECK(best_claim_effective_amount_equals("test",3));
|
||||||
|
fixture.DecrementBlocks(fixture.extendedExpiration - blocks_before_fork - 1);
|
||||||
|
|
||||||
|
// update the claims at fork
|
||||||
|
fixture.DecrementBlocks(1);
|
||||||
|
CMutableTransaction u1 = fixture.MakeUpdate(tx1,"test","two",ClaimIdHash(tx1.GetHash(),0),1);
|
||||||
|
CMutableTransaction u2 = fixture.MakeUpdate(tx2,"test","two",ClaimIdHash(tx2.GetHash(),0),2);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
BOOST_CHECK_EQUAL(fixture.expirationForkHeight, chainActive.Height());
|
||||||
|
|
||||||
|
BOOST_CHECK(is_best_claim("test", u1));
|
||||||
|
BOOST_CHECK(best_claim_effective_amount_equals("test",3));
|
||||||
|
BOOST_CHECK(!is_claim_in_queue("test",tx1));
|
||||||
|
BOOST_CHECK(!is_claim_in_queue("test",tx2));
|
||||||
|
|
||||||
|
// check that the support expires as expected
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration - blocks_before_fork);
|
||||||
|
BOOST_CHECK(is_best_claim("test",u2));
|
||||||
|
fixture.DecrementBlocks(fixture.extendedExpiration - blocks_before_fork);
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration - blocks_before_fork - 1);
|
||||||
|
BOOST_CHECK(is_best_claim("test",u1));
|
||||||
|
BOOST_CHECK(best_claim_effective_amount_equals("test",3));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
claim/support expiration for hard fork, but with checks for disk procedures
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE(claimtriebranching_hardfork_disktest)
|
||||||
|
{
|
||||||
|
ClaimTrieChainFixture fixture;
|
||||||
|
|
||||||
|
// Check that incrementing to fork height, reseting to disk will get proper expiration time
|
||||||
|
BOOST_CHECK_EQUAL(pclaimTrie->nExpirationTime, fixture.originalExpiration);
|
||||||
|
fixture.IncrementBlocks(fixture.expirationForkHeight - chainActive.Height());
|
||||||
|
BOOST_CHECK_EQUAL(chainActive.Height(), fixture.expirationForkHeight);
|
||||||
|
BOOST_CHECK_EQUAL(pclaimTrie->nExpirationTime, fixture.extendedExpiration);
|
||||||
|
fixture.WriteClearReadClaimTrie();
|
||||||
|
BOOST_CHECK_EQUAL(pclaimTrie->nExpirationTime, fixture.extendedExpiration);
|
||||||
|
|
||||||
|
// Create a claim and support 1 block before the fork height that will expire after the fork height.
|
||||||
|
// Reset to disk, increment past the fork height and make sure we get
|
||||||
|
// proper behavior
|
||||||
|
fixture.DecrementBlocks(2);
|
||||||
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1);
|
||||||
|
CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(),tx1,"test",1);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
BOOST_CHECK_EQUAL(chainActive.Height(), fixture.expirationForkHeight -1);
|
||||||
|
|
||||||
|
fixture.WriteClearReadClaimTrie();
|
||||||
|
BOOST_CHECK_EQUAL(chainActive.Height(), fixture.expirationForkHeight-1);
|
||||||
|
BOOST_CHECK_EQUAL(pclaimTrie->nExpirationTime, fixture.originalExpiration);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
BOOST_CHECK_EQUAL(pclaimTrie->nExpirationTime, fixture.extendedExpiration);
|
||||||
|
BOOST_CHECK(is_best_claim("test", tx1));
|
||||||
|
BOOST_CHECK(best_claim_effective_amount_equals("test",2));
|
||||||
|
fixture.IncrementBlocks(fixture.originalExpiration-1);
|
||||||
|
BOOST_CHECK(is_best_claim("test", tx1));
|
||||||
|
BOOST_CHECK(best_claim_effective_amount_equals("test",2));
|
||||||
|
fixture.DecrementBlocks(fixture.originalExpiration-1);
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration-1);
|
||||||
|
BOOST_CHECK(!is_best_claim("test", tx1));
|
||||||
|
|
||||||
|
// Create a claim and support before the fork height, reset to disk, update the claim
|
||||||
|
// increment past the fork height and make sure we get proper behavior
|
||||||
|
int height_of_update_before_expiration = 50;
|
||||||
|
fixture.DecrementBlocks(chainActive.Height() - fixture.expirationForkHeight + height_of_update_before_expiration+2);
|
||||||
|
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(),"test2","one",1);
|
||||||
|
CMutableTransaction s2 = fixture.MakeSupport(fixture.GetCoinbase(),tx2,"test2",1);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
fixture.WriteClearReadClaimTrie();
|
||||||
|
CMutableTransaction u2 = fixture.MakeUpdate(tx2,"test2","two",ClaimIdHash(tx2.GetHash(),0),1);
|
||||||
|
// increment to fork
|
||||||
|
fixture.IncrementBlocks(fixture.expirationForkHeight - chainActive.Height());
|
||||||
|
BOOST_CHECK(is_best_claim("test2", u2));
|
||||||
|
BOOST_CHECK(best_claim_effective_amount_equals("test2",2));
|
||||||
|
// increment to original expiration, should not be expired
|
||||||
|
fixture.IncrementBlocks(fixture.originalExpiration - height_of_update_before_expiration);
|
||||||
|
BOOST_CHECK(is_best_claim("test2", u2));
|
||||||
|
BOOST_CHECK(best_claim_effective_amount_equals("test2",2));
|
||||||
|
fixture.DecrementBlocks(fixture.originalExpiration - height_of_update_before_expiration);
|
||||||
|
// increment to extended expiration, should be expired and not one block before
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration - height_of_update_before_expiration);
|
||||||
|
BOOST_CHECK(!is_best_claim("test2", u2));
|
||||||
|
fixture.DecrementBlocks(fixture.extendedExpiration - height_of_update_before_expiration);
|
||||||
|
fixture.IncrementBlocks(fixture.extendedExpiration - height_of_update_before_expiration-1);
|
||||||
|
BOOST_CHECK(is_best_claim("test2", u2));
|
||||||
|
BOOST_CHECK(best_claim_effective_amount_equals("test2",1)); // the support expires one block before
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Reference in a new issue