Introduce libclaimtrie
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
This commit is contained in:
parent
61625c0eef
commit
53a61258e1
61 changed files with 1461 additions and 905 deletions
|
@ -29,6 +29,7 @@ LIBBITCOIN_COMMON=libbitcoin_common.a
|
|||
LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a
|
||||
LIBBITCOIN_CLI=libbitcoin_cli.a
|
||||
LIBBITCOIN_UTIL=libbitcoin_util.a
|
||||
LIBCLAIMTRIE=claimtrie/libclaimtrie.a
|
||||
LIBBITCOIN_CRYPTO_BASE=crypto/libbitcoin_crypto_base.a
|
||||
LIBBITCOINQT=qt/libbitcoinqt.a
|
||||
LIBSECP256K1=secp256k1/libsecp256k1.la
|
||||
|
@ -63,6 +64,7 @@ $(LIBSECP256K1): $(wildcard secp256k1/src/*.h) $(wildcard secp256k1/src/*.c) $(w
|
|||
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
|
||||
# But to build the less dependent modules first, we manually select their order here:
|
||||
EXTRA_LIBRARIES += \
|
||||
$(LIBCLAIMTRIE) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
|
@ -103,7 +105,7 @@ BITCOIN_CORE_H = \
|
|||
checkpoints.h \
|
||||
checkqueue.h \
|
||||
claimscriptop.h \
|
||||
claimtrie.h \
|
||||
claimtrie_serial.h \
|
||||
clientversion.h \
|
||||
coins.h \
|
||||
compat.h \
|
||||
|
@ -170,8 +172,6 @@ BITCOIN_CORE_H = \
|
|||
script/standard.h \
|
||||
shutdown.h \
|
||||
streams.h \
|
||||
sqlite/sqlite3.h \
|
||||
sqlite/hdr/sqlite_modern_cpp.h \
|
||||
support/allocators/secure.h \
|
||||
support/allocators/zeroafterfree.h \
|
||||
support/cleanse.h \
|
||||
|
@ -223,7 +223,6 @@ libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
|
|||
# server: shared between lbrycrdd and lbrycrd-qt
|
||||
libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS)
|
||||
libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libbitcoin_server_a_CFLAGS = $(PIE_FLAGS)
|
||||
libbitcoin_server_a_SOURCES = \
|
||||
addrdb.cpp \
|
||||
addrman.cpp \
|
||||
|
@ -232,8 +231,6 @@ libbitcoin_server_a_SOURCES = \
|
|||
chain.cpp \
|
||||
checkpoints.cpp \
|
||||
claimscriptop.cpp \
|
||||
claimtrie.cpp \
|
||||
claimtrieforks.cpp \
|
||||
consensus/tx_verify.cpp \
|
||||
httprpc.cpp \
|
||||
httpserver.cpp \
|
||||
|
@ -263,7 +260,6 @@ libbitcoin_server_a_SOURCES = \
|
|||
rpc/server.cpp \
|
||||
rpc/util.cpp \
|
||||
script/sigcache.cpp \
|
||||
sqlite/sqlite3.c \
|
||||
shutdown.cpp \
|
||||
timedata.cpp \
|
||||
torcontrol.cpp \
|
||||
|
@ -415,6 +411,20 @@ libbitcoin_common_a_SOURCES = \
|
|||
warnings.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
# claimtrie: shared between all executables.
|
||||
claimtrie_libclaimtrie_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
claimtrie_libclaimtrie_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
claimtrie_libclaimtrie_a_CFLAGS = $(PIE_FLAGS)
|
||||
claimtrie_libclaimtrie_a_SOURCES = \
|
||||
claimtrie/sqlite/sqlite3.c \
|
||||
claimtrie/data.cpp \
|
||||
claimtrie/forks.cpp \
|
||||
claimtrie/hash.cpp \
|
||||
claimtrie/log.cpp \
|
||||
claimtrie/trie.cpp \
|
||||
claimtrie/txoutpoint.cpp \
|
||||
claimtrie/uints.cpp
|
||||
|
||||
# util: shared between all executables.
|
||||
# This library *must* be included to make sure that the glibc
|
||||
# backward-compatibility objects and their sanity checks are linked.
|
||||
|
@ -482,7 +492,7 @@ lbrycrdd_LDADD = \
|
|||
$(LIBMEMENV) \
|
||||
$(LIBSECP256K1)
|
||||
|
||||
lbrycrdd_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
|
||||
lbrycrdd_LDADD += $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(BDB_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
|
||||
|
||||
# lbrycrd-cli binary #
|
||||
lbrycrd_cli_SOURCES = bitcoin-cli.cpp
|
||||
|
@ -500,7 +510,7 @@ lbrycrd_cli_LDADD = \
|
|||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_CRYPTO)
|
||||
|
||||
lbrycrd_cli_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(EVENT_LIBS)
|
||||
lbrycrd_cli_LDADD += $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(CRYPTO_LIBS) $(ICU_LIBS) $(EVENT_LIBS)
|
||||
#
|
||||
|
||||
# bitcoin-tx binary #
|
||||
|
@ -521,7 +531,7 @@ lbrycrd_tx_LDADD = \
|
|||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBSECP256K1)
|
||||
|
||||
lbrycrd_tx_LDADD += $(BOOST_LIBS) $(ICU_LIBS) $(CRYPTO_LIBS)
|
||||
lbrycrd_tx_LDADD += $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(ICU_LIBS) $(CRYPTO_LIBS)
|
||||
#
|
||||
|
||||
# bitcoinconsensus library #
|
||||
|
|
|
@ -55,7 +55,7 @@ if ENABLE_WALLET
|
|||
bench_bench_bitcoin_SOURCES += bench/coin_selection.cpp
|
||||
endif
|
||||
|
||||
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(BDB_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
bench_bench_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
||||
CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_BENCH_FILES)
|
||||
|
|
|
@ -409,7 +409,7 @@ if ENABLE_ZMQ
|
|||
qt_lbrycrd_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||
endif
|
||||
qt_lbrycrd_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \
|
||||
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(ICU_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
||||
$(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(ICU_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
||||
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
qt_lbrycrd_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
qt_lbrycrd_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX
|
||||
|
|
|
@ -63,7 +63,7 @@ if ENABLE_ZMQ
|
|||
qt_test_test_lbrycrd_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
|
||||
endif
|
||||
qt_test_test_lbrycrd_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \
|
||||
$(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
|
||||
$(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
|
||||
$(QR_LIBS) $(PROTOBUF_LIBS) $(ICU_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
||||
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
qt_test_test_lbrycrd_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
|
|
@ -126,7 +126,7 @@ test_test_lbrycrd_LDADD += $(LIBBITCOIN_WALLET)
|
|||
endif
|
||||
|
||||
test_test_lbrycrd_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \
|
||||
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
|
||||
$(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
|
||||
test_test_lbrycrd_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
|
||||
test_test_lbrycrd_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS) $(MINIUPNPC_LIBS)
|
||||
|
@ -155,7 +155,7 @@ test_test_lbrycrd_fuzzy_LDADD = \
|
|||
$(LIBBITCOIN_CRYPTO_SHANI) \
|
||||
$(LIBSECP256K1)
|
||||
|
||||
test_test_lbrycrd_fuzzy_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) $(ICU_LIBS)
|
||||
test_test_lbrycrd_fuzzy_LDADD += $(BOOST_LIBS) $(LIBCLAIMTRIE) $(BOOST_LOCALE_LIB) $(CRYPTO_LIBS) $(ICU_LIBS)
|
||||
|
||||
nodist_test_test_lbrycrd_SOURCES = $(GENERATED_TEST_FILES)
|
||||
|
||||
|
|
|
@ -143,8 +143,6 @@ public:
|
|||
consensus.nAllowMinDiffMinHeight = -1;
|
||||
consensus.nAllowMinDiffMaxHeight = -1;
|
||||
consensus.nNormalizedNameForkHeight = 539940; // targeting 21 March 2019
|
||||
consensus.nMinTakeoverWorkaroundHeight = 496850;
|
||||
consensus.nMaxTakeoverWorkaroundHeight = 658300; // targeting 30 Oct 2019
|
||||
consensus.nWitnessForkHeight = 680770; // targeting 11 Dec 2019
|
||||
consensus.nAllClaimsInMerkleForkHeight = 658310; // targeting 30 Oct 2019
|
||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||
|
@ -261,8 +259,6 @@ public:
|
|||
consensus.nAllowMinDiffMinHeight = 277299;
|
||||
consensus.nAllowMinDiffMaxHeight = 1100000;
|
||||
consensus.nNormalizedNameForkHeight = 993380; // targeting, 21 Feb 2019
|
||||
consensus.nMinTakeoverWorkaroundHeight = 99;
|
||||
consensus.nMaxTakeoverWorkaroundHeight = 1198550; // targeting 30 Sep 2019
|
||||
consensus.nWitnessForkHeight = 1198600;
|
||||
consensus.nAllClaimsInMerkleForkHeight = 1198560; // targeting 30 Sep 2019
|
||||
consensus.fPowAllowMinDifficultyBlocks = true;
|
||||
|
@ -368,8 +364,6 @@ public:
|
|||
consensus.nAllowMinDiffMinHeight = -1;
|
||||
consensus.nAllowMinDiffMaxHeight = -1;
|
||||
consensus.nNormalizedNameForkHeight = 250; // SDK depends upon this number
|
||||
consensus.nMinTakeoverWorkaroundHeight = -1;
|
||||
consensus.nMaxTakeoverWorkaroundHeight = -1;
|
||||
consensus.nWitnessForkHeight = 150;
|
||||
consensus.nAllClaimsInMerkleForkHeight = 350;
|
||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||
|
|
|
@ -39,7 +39,7 @@ bool CClaimScriptAddOp::supportClaim(CClaimTrieCache& trieCache, const std::stri
|
|||
{
|
||||
LogPrint(BCLog::CLAIMS, "+++ Support added: %s, c: %.6s, t: %.6s:%d, h: %.6d, a: %d\n",
|
||||
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValue);
|
||||
return trieCache.addSupport(name, point, nValue, claimId, nHeight, -1, metadata);
|
||||
return trieCache.addSupport(name, point, claimId, nValue, nHeight, -1, metadata);
|
||||
}
|
||||
|
||||
CClaimScriptUndoAddOp::CClaimScriptUndoAddOp(const COutPoint& point, int nHeight) : point(point), nHeight(nHeight)
|
||||
|
@ -164,7 +164,7 @@ bool CClaimScriptUndoSpendOp::supportClaim(CClaimTrieCache& trieCache, const std
|
|||
{
|
||||
LogPrint(BCLog::CLAIMS, "+++ Undoing support spend: %s, c: %.6s, t: %.6s:%d, h: %.6d, vh: %d\n",
|
||||
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValidHeight);
|
||||
return trieCache.addSupport(name, point, nValue, claimId, nHeight, nValidHeight, metadata);
|
||||
return trieCache.addSupport(name, point, claimId, nValue, nHeight, nValidHeight, metadata);
|
||||
}
|
||||
|
||||
static std::string vchToString(const std::vector<unsigned char>& name)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#define CLAIMSCRIPTOP_H
|
||||
|
||||
#include "amount.h"
|
||||
#include "claimtrie.h"
|
||||
#include "claimtrie/forks.h"
|
||||
#include "hash.h"
|
||||
#include "primitives/transaction.h"
|
||||
#include "script/script.h"
|
||||
|
|
491
src/claimtrie.h
491
src/claimtrie.h
|
@ -1,491 +0,0 @@
|
|||
#ifndef BITCOIN_CLAIMTRIE_H
|
||||
#define BITCOIN_CLAIMTRIE_H
|
||||
|
||||
#include <amount.h>
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
|
||||
#include <primitives/transaction.h>
|
||||
#include <serialize.h>
|
||||
#include <uint256.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <sqlite/sqlite3.h>
|
||||
|
||||
namespace sqlite
|
||||
{
|
||||
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint160& val) {
|
||||
return sqlite3_bind_blob(stmt, inx, val.begin(), int(val.size()), SQLITE_STATIC);
|
||||
}
|
||||
|
||||
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint256& val) {
|
||||
return sqlite3_bind_blob(stmt, inx, val.begin(), int(val.size()), SQLITE_STATIC);
|
||||
}
|
||||
|
||||
inline void store_result_in_db(sqlite3_context* db, const uint160& val) {
|
||||
sqlite3_result_blob(db, val.begin(), int(val.size()), SQLITE_TRANSIENT); // I think we need transient here but I'm not 100% sure
|
||||
}
|
||||
|
||||
inline void store_result_in_db(sqlite3_context* db, const uint256& val) {
|
||||
sqlite3_result_blob(db, val.begin(), int(val.size()), SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
|
||||
#include <sqlite/hdr/sqlite_modern_cpp.h>
|
||||
|
||||
namespace sqlite {
|
||||
template<>
|
||||
struct has_sqlite_type<uint256, SQLITE_BLOB, void> : std::true_type {};
|
||||
|
||||
template<>
|
||||
struct has_sqlite_type<uint160, SQLITE_BLOB, void> : std::true_type {};
|
||||
|
||||
inline uint160 get_col_from_db(sqlite3_stmt* stmt, int inx, result_type<uint160>) {
|
||||
uint160 ret;
|
||||
auto ptr = sqlite3_column_blob(stmt, inx);
|
||||
if (!ptr) return ret;
|
||||
int bytes = sqlite3_column_bytes(stmt, inx);
|
||||
assert(bytes == ret.size());
|
||||
std::memcpy(ret.begin(), ptr, bytes);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline uint256 get_col_from_db(sqlite3_stmt* stmt, int inx, result_type<uint256>) {
|
||||
uint256 ret;
|
||||
auto ptr = sqlite3_column_blob(stmt, inx);
|
||||
if (!ptr) return ret;
|
||||
int bytes = sqlite3_column_bytes(stmt, inx);
|
||||
assert(bytes == ret.size());
|
||||
std::memcpy(ret.begin(), ptr, bytes);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint256 getValueHash(const COutPoint& outPoint, int nHeightOfLastTakeover);
|
||||
|
||||
struct CClaimValue
|
||||
{
|
||||
COutPoint outPoint;
|
||||
uint160 claimId;
|
||||
CAmount nAmount = 0;
|
||||
CAmount nEffectiveAmount = 0;
|
||||
int nHeight = 0;
|
||||
int nValidAtHeight = 0;
|
||||
|
||||
CClaimValue() = default;
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
CClaimValue(CClaimValue&&) = default;
|
||||
CClaimValue(const CClaimValue&) = default;
|
||||
CClaimValue& operator=(CClaimValue&&) = default;
|
||||
CClaimValue& operator=(const CClaimValue&) = default;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||
{
|
||||
READWRITE(outPoint);
|
||||
READWRITE(claimId);
|
||||
READWRITE(nAmount);
|
||||
READWRITE(nHeight);
|
||||
READWRITE(nValidAtHeight);
|
||||
}
|
||||
|
||||
bool operator<(const CClaimValue& other) const
|
||||
{
|
||||
if (nEffectiveAmount < other.nEffectiveAmount)
|
||||
return true;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
struct CSupportValue
|
||||
{
|
||||
COutPoint outPoint;
|
||||
uint160 supportedClaimId;
|
||||
CAmount nAmount = 0;
|
||||
int nHeight = 0;
|
||||
int nValidAtHeight = 0;
|
||||
|
||||
CSupportValue() = default;
|
||||
|
||||
CSupportValue(const COutPoint& outPoint, const uint160& supportedClaimId, CAmount nAmount, int nHeight, int nValidAtHeight)
|
||||
: outPoint(outPoint), supportedClaimId(supportedClaimId), nAmount(nAmount), nHeight(nHeight), nValidAtHeight(nValidAtHeight)
|
||||
{
|
||||
}
|
||||
|
||||
CSupportValue(CSupportValue&&) = default;
|
||||
CSupportValue(const CSupportValue&) = default;
|
||||
CSupportValue& operator=(CSupportValue&&) = default;
|
||||
CSupportValue& operator=(const CSupportValue&) = default;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||
{
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<CClaimValue> claimEntryType;
|
||||
typedef std::vector<CSupportValue> supportEntryType;
|
||||
|
||||
struct CNameOutPointHeightType
|
||||
{
|
||||
std::string name;
|
||||
COutPoint outPoint;
|
||||
int nValidHeight = 0;
|
||||
|
||||
CNameOutPointHeightType() = default;
|
||||
|
||||
CNameOutPointHeightType(std::string name, const COutPoint& outPoint, int nValidHeight)
|
||||
: name(std::move(name)), outPoint(outPoint), nValidHeight(nValidHeight)
|
||||
{
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||
{
|
||||
READWRITE(name);
|
||||
READWRITE(outPoint);
|
||||
READWRITE(nValidHeight);
|
||||
}
|
||||
};
|
||||
|
||||
struct CClaimNsupports
|
||||
{
|
||||
CClaimNsupports() = default;
|
||||
CClaimNsupports(CClaimNsupports&&) = default;
|
||||
CClaimNsupports(const CClaimNsupports&) = default;
|
||||
|
||||
CClaimNsupports& operator=(CClaimNsupports&&) = default;
|
||||
CClaimNsupports& operator=(const CClaimNsupports&) = default;
|
||||
|
||||
CClaimNsupports(const CClaimValue& claim, CAmount effectiveAmount, const std::vector<CSupportValue>& supports = {})
|
||||
: claim(claim), effectiveAmount(effectiveAmount), supports(supports)
|
||||
{
|
||||
}
|
||||
|
||||
bool IsNull() const
|
||||
{
|
||||
return claim.claimId.IsNull();
|
||||
}
|
||||
|
||||
bool operator<(const CClaimNsupports& other) const {
|
||||
return claim < other.claim;
|
||||
}
|
||||
|
||||
CClaimValue claim;
|
||||
CAmount effectiveAmount = 0;
|
||||
std::vector<CSupportValue> supports;
|
||||
};
|
||||
|
||||
static const CClaimNsupports invalid;
|
||||
|
||||
struct CClaimSupportToName
|
||||
{
|
||||
CClaimSupportToName(const std::string& name, int nLastTakeoverHeight, std::vector<CClaimNsupports> claimsNsupports, std::vector<CSupportValue> unmatchedSupports)
|
||||
: name(name), nLastTakeoverHeight(nLastTakeoverHeight), claimsNsupports(std::move(claimsNsupports)), unmatchedSupports(std::move(unmatchedSupports))
|
||||
{
|
||||
}
|
||||
|
||||
const CClaimNsupports& find(const uint160& claimId) const
|
||||
{
|
||||
auto it = std::find_if(claimsNsupports.begin(), claimsNsupports.end(), [&claimId](const CClaimNsupports& value) {
|
||||
return claimId == value.claim.claimId;
|
||||
});
|
||||
return it != claimsNsupports.end() ? *it : invalid;
|
||||
}
|
||||
|
||||
const CClaimNsupports& find(const std::string& partialId) const
|
||||
{
|
||||
std::string lowered(partialId);
|
||||
for (auto& c: lowered)
|
||||
c = std::tolower(c);
|
||||
|
||||
auto it = std::find_if(claimsNsupports.begin(), claimsNsupports.end(), [&lowered](const CClaimNsupports& value) {
|
||||
return value.claim.claimId.GetHex().find(lowered) == 0;
|
||||
});
|
||||
return it != claimsNsupports.end() ? *it : invalid;
|
||||
}
|
||||
|
||||
const std::string name;
|
||||
const int nLastTakeoverHeight;
|
||||
const std::vector<CClaimNsupports> claimsNsupports;
|
||||
const std::vector<CSupportValue> unmatchedSupports;
|
||||
};
|
||||
|
||||
class CClaimTrieCacheBase;
|
||||
class CClaimTrie
|
||||
{
|
||||
friend CClaimTrieCacheBase;
|
||||
std::string dbPath;
|
||||
int nNextHeight;
|
||||
sqlite::database db; // keep below dbPath
|
||||
|
||||
public:
|
||||
const int nProportionalDelayFactor;
|
||||
|
||||
CClaimTrie() = delete;
|
||||
CClaimTrie(CClaimTrie&&) = delete;
|
||||
CClaimTrie(const CClaimTrie&) = delete;
|
||||
CClaimTrie(bool fWipe, int height, int proportionalDelayFactor = 32);
|
||||
|
||||
CClaimTrie& operator=(CClaimTrie&&) = delete;
|
||||
CClaimTrie& operator=(const CClaimTrie&) = delete;
|
||||
|
||||
bool SyncToDisk();
|
||||
bool empty(); // for tests
|
||||
};
|
||||
|
||||
struct CClaimTrieProofNode
|
||||
{
|
||||
CClaimTrieProofNode(std::vector<std::pair<unsigned char, uint256>> children, bool hasValue, const uint256& valHash)
|
||||
: children(std::move(children)), hasValue(hasValue), valHash(valHash)
|
||||
{
|
||||
}
|
||||
|
||||
CClaimTrieProofNode(CClaimTrieProofNode&&) = default;
|
||||
CClaimTrieProofNode(const CClaimTrieProofNode&) = default;
|
||||
CClaimTrieProofNode& operator=(CClaimTrieProofNode&&) = default;
|
||||
CClaimTrieProofNode& operator=(const CClaimTrieProofNode&) = default;
|
||||
|
||||
std::vector<std::pair<unsigned char, uint256>> children;
|
||||
bool hasValue;
|
||||
uint256 valHash;
|
||||
};
|
||||
|
||||
struct CClaimTrieProof
|
||||
{
|
||||
CClaimTrieProof() = default;
|
||||
CClaimTrieProof(CClaimTrieProof&&) = default;
|
||||
CClaimTrieProof(const CClaimTrieProof&) = default;
|
||||
CClaimTrieProof& operator=(CClaimTrieProof&&) = default;
|
||||
CClaimTrieProof& operator=(const CClaimTrieProof&) = default;
|
||||
|
||||
std::vector<std::pair<bool, uint256>> pairs;
|
||||
std::vector<CClaimTrieProofNode> nodes;
|
||||
int nHeightOfLastTakeover = 0;
|
||||
bool hasValue = false;
|
||||
COutPoint outPoint;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using queueEntryType = std::pair<std::string, T>;
|
||||
|
||||
typedef std::vector<queueEntryType<CClaimValue>> claimUndoType;
|
||||
typedef std::vector<queueEntryType<CSupportValue>> supportUndoType;
|
||||
typedef std::vector<CNameOutPointHeightType> insertUndoType;
|
||||
typedef std::vector<queueEntryType<std::pair<int, uint160>>> takeoverUndoType;
|
||||
|
||||
class CClaimTrieCacheBase
|
||||
{
|
||||
public:
|
||||
explicit CClaimTrieCacheBase(CClaimTrie* base);
|
||||
virtual ~CClaimTrieCacheBase();
|
||||
|
||||
uint256 getMerkleHash();
|
||||
|
||||
bool flush();
|
||||
bool checkConsistency();
|
||||
bool ValidateTipMatches(const CBlockIndex* tip);
|
||||
|
||||
bool haveClaim(const std::string& name, const COutPoint& outPoint) const;
|
||||
bool haveClaimInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const;
|
||||
|
||||
bool haveSupport(const std::string& name, const COutPoint& outPoint) const;
|
||||
bool haveSupportInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const;
|
||||
|
||||
bool addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId, CAmount nAmount,
|
||||
int nHeight, int nValidHeight = -1, const std::vector<unsigned char>& metadata = {});
|
||||
bool addSupport(const std::string& name, const COutPoint& outPoint, CAmount nAmount,
|
||||
const uint160& supportedClaimId, int nHeight, int nValidHeight = -1, const std::vector<unsigned char>& metadata = {});
|
||||
|
||||
bool removeSupport(const COutPoint& outPoint, std::string& nodeName, int& validHeight);
|
||||
bool removeClaim(const uint160& claimId, const COutPoint& outPoint, std::string& nodeName, int& validHeight);
|
||||
|
||||
virtual bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeovers);
|
||||
|
||||
virtual bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo);
|
||||
|
||||
virtual bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const;
|
||||
virtual bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof);
|
||||
|
||||
virtual int expirationTime() const;
|
||||
|
||||
virtual bool finalizeDecrement(takeoverUndoType& takeovers);
|
||||
|
||||
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
|
||||
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
||||
|
||||
std::size_t getTotalNamesInTrie() const;
|
||||
std::size_t getTotalClaimsInTrie() const;
|
||||
CAmount getTotalValueOfClaimsInTrie(bool fControllingOnly) const;
|
||||
|
||||
bool findNameForClaim(std::vector<unsigned char> claim, CClaimValue& value, std::string& name);
|
||||
void getNamesInTrie(std::function<void(const std::string&)> callback);
|
||||
bool getLastTakeoverForName(const std::string& name, uint160& claimId, int& takeoverHeight) const;
|
||||
|
||||
protected:
|
||||
CClaimTrie* base;
|
||||
mutable sqlite::database db;
|
||||
int nNextHeight; // Height of the block that is being worked on, which is
|
||||
bool transacting;
|
||||
mutable std::unordered_set<std::string> removalWorkaround;
|
||||
|
||||
// one greater than the height of the chain's tip
|
||||
|
||||
mutable sqlite::database_binder claimHashQuery, childHashQuery;
|
||||
|
||||
virtual uint256 recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly);
|
||||
supportEntryType getSupportsForName(const std::string& name) const;
|
||||
|
||||
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
|
||||
|
||||
bool deleteNodeIfPossible(const std::string& name, std::string& parent, int64_t& claims);
|
||||
void ensureTreeStructureIsUpToDate();
|
||||
|
||||
private:
|
||||
// for unit test
|
||||
friend struct ClaimTrieChainFixture;
|
||||
friend class CClaimTrieCacheTest;
|
||||
|
||||
bool activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo,
|
||||
const std::string& takeover);
|
||||
};
|
||||
|
||||
class CClaimTrieCacheExpirationFork : public CClaimTrieCacheBase
|
||||
{
|
||||
public:
|
||||
explicit CClaimTrieCacheExpirationFork(CClaimTrie* base);
|
||||
|
||||
void setExpirationTime(int time);
|
||||
int expirationTime() const override;
|
||||
|
||||
virtual void initializeIncrement();
|
||||
bool finalizeDecrement(takeoverUndoType& takeovers) override;
|
||||
|
||||
bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeovers) override;
|
||||
|
||||
bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo) override;
|
||||
|
||||
private:
|
||||
int nExpirationTime;
|
||||
bool forkForExpirationChange(bool increment);
|
||||
};
|
||||
|
||||
class CClaimTrieCacheNormalizationFork : public CClaimTrieCacheExpirationFork
|
||||
{
|
||||
public:
|
||||
explicit CClaimTrieCacheNormalizationFork(CClaimTrie* base)
|
||||
: CClaimTrieCacheExpirationFork(base)
|
||||
{
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeovers) override;
|
||||
|
||||
bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo) override;
|
||||
|
||||
bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof) override;
|
||||
bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const override;
|
||||
CClaimSupportToName getClaimsForName(const std::string& name) const override;
|
||||
std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
|
||||
|
||||
protected:
|
||||
int getDelayForName(const std::string& name, const uint160& claimId) const override;
|
||||
|
||||
private:
|
||||
bool normalizeAllNamesInTrieIfNecessary(takeoverUndoType& takeovers);
|
||||
bool unnormalizeAllNamesInTrieIfNecessary();
|
||||
};
|
||||
|
||||
class CClaimTrieCacheHashFork : public CClaimTrieCacheNormalizationFork
|
||||
{
|
||||
public:
|
||||
explicit CClaimTrieCacheHashFork(CClaimTrie* base);
|
||||
|
||||
bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof) override;
|
||||
void initializeIncrement() override;
|
||||
bool finalizeDecrement(takeoverUndoType& takeovers) override;
|
||||
|
||||
bool allowSupportMetadata() const;
|
||||
|
||||
protected:
|
||||
uint256 recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly) override;
|
||||
};
|
||||
|
||||
typedef CClaimTrieCacheHashFork CClaimTrieCache;
|
||||
|
||||
#endif // BITCOIN_CLAIMTRIE_H
|
84
src/claimtrie/data.cpp
Normal file
84
src/claimtrie/data.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
|
||||
#include <claimtrie/data.h>
|
||||
#include <claimtrie/log.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
#define logPrint CLogPrint::global()
|
||||
|
||||
CClaimValue::CClaimValue(CTxOutPoint outPoint, CUint160 claimId, int64_t nAmount, int nHeight, int nValidAtHeight)
|
||||
: outPoint(std::move(outPoint)), claimId(std::move(claimId)), nAmount(nAmount), nEffectiveAmount(nAmount), nHeight(nHeight), nValidAtHeight(nValidAtHeight)
|
||||
{
|
||||
}
|
||||
|
||||
bool CClaimValue::operator<(const CClaimValue& other) const
|
||||
{
|
||||
if (nEffectiveAmount < other.nEffectiveAmount)
|
||||
return true;
|
||||
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);
|
||||
}
|
||||
|
||||
bool CClaimValue::operator==(const CClaimValue& other) const
|
||||
{
|
||||
return outPoint == other.outPoint && claimId == other.claimId && nAmount == other.nAmount && nHeight == other.nHeight && nValidAtHeight == other.nValidAtHeight;
|
||||
}
|
||||
|
||||
bool CClaimValue::operator!=(const CClaimValue& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
std::string CClaimValue::ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "CClaimValue(" << outPoint.ToString()
|
||||
<< ", " << claimId.ToString()
|
||||
<< ", " << nAmount
|
||||
<< ", " << nEffectiveAmount
|
||||
<< ", " << nHeight
|
||||
<< ", " << nValidAtHeight << ')';
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
CSupportValue::CSupportValue(CTxOutPoint outPoint, CUint160 supportedClaimId, int64_t nAmount, int nHeight, int nValidAtHeight)
|
||||
: outPoint(std::move(outPoint)), supportedClaimId(std::move(supportedClaimId)), nAmount(nAmount), nHeight(nHeight), nValidAtHeight(nValidAtHeight)
|
||||
{
|
||||
}
|
||||
|
||||
bool CSupportValue::operator==(const CSupportValue& other) const
|
||||
{
|
||||
return outPoint == other.outPoint && supportedClaimId == other.supportedClaimId && nAmount == other.nAmount && nHeight == other.nHeight && nValidAtHeight == other.nValidAtHeight;
|
||||
}
|
||||
|
||||
bool CSupportValue::operator!=(const CSupportValue& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
std::string CSupportValue::ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "CSupportValue(" << outPoint.ToString()
|
||||
<< ", " << supportedClaimId.ToString()
|
||||
<< ", " << nAmount
|
||||
<< ", " << nHeight
|
||||
<< ", " << nValidAtHeight << ')';
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
CNameOutPointHeightType::CNameOutPointHeightType(std::string name, CTxOutPoint outPoint, int nValidHeight)
|
||||
: name(std::move(name)), outPoint(std::move(outPoint)), nValidHeight(nValidHeight)
|
||||
{
|
||||
}
|
||||
|
||||
CClaimIndexElement::CClaimIndexElement(std::string name, CClaimValue claim)
|
||||
: name(std::move(name)), claim(std::move(claim))
|
||||
{
|
||||
}
|
131
src/claimtrie/data.h
Normal file
131
src/claimtrie/data.h
Normal file
|
@ -0,0 +1,131 @@
|
|||
|
||||
#ifndef CLAIMTRIE_DATA_H
|
||||
#define CLAIMTRIE_DATA_H
|
||||
|
||||
#include <claimtrie/sqlite/sqlite3.h>
|
||||
#include <claimtrie/txoutpoint.h>
|
||||
#include <claimtrie/uints.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace sqlite
|
||||
{
|
||||
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const CUint160& val) {
|
||||
return sqlite3_bind_blob(stmt, inx, val.begin(), int(val.size()), SQLITE_STATIC);
|
||||
}
|
||||
|
||||
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const CUint256& val) {
|
||||
return sqlite3_bind_blob(stmt, inx, val.begin(), int(val.size()), SQLITE_STATIC);
|
||||
}
|
||||
|
||||
inline void store_result_in_db(sqlite3_context* db, const CUint160& val) {
|
||||
sqlite3_result_blob(db, val.begin(), int(val.size()), SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
inline void store_result_in_db(sqlite3_context* db, const CUint256& val) {
|
||||
sqlite3_result_blob(db, val.begin(), int(val.size()), SQLITE_TRANSIENT);
|
||||
}
|
||||
}
|
||||
|
||||
#include <claimtrie/sqlite/hdr/sqlite_modern_cpp.h>
|
||||
|
||||
namespace sqlite
|
||||
{
|
||||
template<>
|
||||
struct has_sqlite_type<CUint256, SQLITE_BLOB, void> : std::true_type {};
|
||||
|
||||
template<>
|
||||
struct has_sqlite_type<CUint160, SQLITE_BLOB, void> : std::true_type {};
|
||||
|
||||
inline CUint160 get_col_from_db(sqlite3_stmt* stmt, int inx, result_type<CUint160>) {
|
||||
CUint160 ret;
|
||||
auto ptr = sqlite3_column_blob(stmt, inx);
|
||||
if (!ptr) return ret;
|
||||
int bytes = sqlite3_column_bytes(stmt, inx);
|
||||
assert(bytes == ret.size());
|
||||
std::memcpy(ret.begin(), ptr, bytes);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline CUint256 get_col_from_db(sqlite3_stmt* stmt, int inx, result_type<CUint256>) {
|
||||
CUint256 ret;
|
||||
auto ptr = sqlite3_column_blob(stmt, inx);
|
||||
if (!ptr) return ret;
|
||||
int bytes = sqlite3_column_bytes(stmt, inx);
|
||||
assert(bytes == ret.size());
|
||||
std::memcpy(ret.begin(), ptr, bytes);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
struct CClaimValue
|
||||
{
|
||||
CTxOutPoint outPoint;
|
||||
CUint160 claimId;
|
||||
int64_t nAmount = 0;
|
||||
int64_t nEffectiveAmount = 0;
|
||||
int nHeight = 0;
|
||||
int nValidAtHeight = 0;
|
||||
|
||||
CClaimValue() = default;
|
||||
CClaimValue(CTxOutPoint outPoint, CUint160 claimId, int64_t nAmount, int nHeight, int nValidAtHeight);
|
||||
|
||||
CClaimValue(CClaimValue&&) = default;
|
||||
CClaimValue(const CClaimValue&) = default;
|
||||
CClaimValue& operator=(CClaimValue&&) = default;
|
||||
CClaimValue& operator=(const CClaimValue&) = default;
|
||||
|
||||
bool operator<(const CClaimValue& other) const;
|
||||
bool operator==(const CClaimValue& other) const;
|
||||
bool operator!=(const CClaimValue& other) const;
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
struct CSupportValue
|
||||
{
|
||||
CTxOutPoint outPoint;
|
||||
CUint160 supportedClaimId;
|
||||
int64_t nAmount = 0;
|
||||
int nHeight = 0;
|
||||
int nValidAtHeight = 0;
|
||||
|
||||
CSupportValue() = default;
|
||||
CSupportValue(CTxOutPoint outPoint, CUint160 supportedClaimId, int64_t nAmount, int nHeight, int nValidAtHeight);
|
||||
|
||||
CSupportValue(CSupportValue&&) = default;
|
||||
CSupportValue(const CSupportValue&) = default;
|
||||
CSupportValue& operator=(CSupportValue&&) = default;
|
||||
CSupportValue& operator=(const CSupportValue&) = default;
|
||||
|
||||
bool operator==(const CSupportValue& other) const;
|
||||
bool operator!=(const CSupportValue& other) const;
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
typedef std::vector<CClaimValue> claimEntryType;
|
||||
typedef std::vector<CSupportValue> supportEntryType;
|
||||
|
||||
struct CNameOutPointHeightType
|
||||
{
|
||||
std::string name;
|
||||
CTxOutPoint outPoint;
|
||||
int nValidHeight = 0;
|
||||
|
||||
CNameOutPointHeightType() = default;
|
||||
CNameOutPointHeightType(std::string name, CTxOutPoint outPoint, int nValidHeight);
|
||||
};
|
||||
|
||||
struct CClaimIndexElement
|
||||
{
|
||||
std::string name;
|
||||
CClaimValue claim;
|
||||
|
||||
CClaimIndexElement() = default;
|
||||
CClaimIndexElement(std::string name, CClaimValue claim);
|
||||
};
|
||||
|
||||
#endif // CLAIMTRIE_DATA_H
|
|
@ -1,35 +1,33 @@
|
|||
|
||||
#include <consensus/merkle.h>
|
||||
#include <chainparams.h>
|
||||
#include <claimtrie.h>
|
||||
#include <hash.h>
|
||||
#include <claimtrie/forks.h>
|
||||
#include <claimtrie/hash.h>
|
||||
#include <claimtrie/log.h>
|
||||
#include <claimtrie/trie.h>
|
||||
|
||||
#include <boost/locale.hpp>
|
||||
#include <boost/locale/conversion.hpp>
|
||||
#include <boost/locale/localization_backend.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
CClaimTrieCacheExpirationFork::CClaimTrieCacheExpirationFork(CClaimTrie* base)
|
||||
: CClaimTrieCacheBase(base)
|
||||
{
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||
}
|
||||
#define logPrint CLogPrint::global()
|
||||
|
||||
void CClaimTrieCacheExpirationFork::setExpirationTime(int time)
|
||||
CClaimTrieCacheExpirationFork::CClaimTrieCacheExpirationFork(CClaimTrie* base) : CClaimTrieCacheBase(base)
|
||||
{
|
||||
nExpirationTime = time;
|
||||
expirationHeight = nNextHeight;
|
||||
}
|
||||
|
||||
int CClaimTrieCacheExpirationFork::expirationTime() const
|
||||
{
|
||||
return nExpirationTime;
|
||||
if (expirationHeight < base->nExtendedClaimExpirationForkHeight)
|
||||
return CClaimTrieCacheBase::expirationTime();
|
||||
return base->nExtendedClaimExpirationTime;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheExpirationFork::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo, takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
if (CClaimTrieCacheBase::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo)) {
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||
expirationHeight = nNextHeight;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -38,7 +36,7 @@ bool CClaimTrieCacheExpirationFork::incrementBlock(insertUndoType& insertUndo, c
|
|||
bool CClaimTrieCacheExpirationFork::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo)
|
||||
{
|
||||
if (CClaimTrieCacheBase::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo)) {
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||
expirationHeight = nNextHeight;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -47,7 +45,7 @@ bool CClaimTrieCacheExpirationFork::decrementBlock(insertUndoType& insertUndo, c
|
|||
void CClaimTrieCacheExpirationFork::initializeIncrement()
|
||||
{
|
||||
// we could do this in the constructor, but that would not allow for multiple increments in a row (as done in unit tests)
|
||||
if (nNextHeight != Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
||||
if (nNextHeight != base->nExtendedClaimExpirationForkHeight)
|
||||
return;
|
||||
|
||||
forkForExpirationChange(true);
|
||||
|
@ -56,7 +54,7 @@ void CClaimTrieCacheExpirationFork::initializeIncrement()
|
|||
bool CClaimTrieCacheExpirationFork::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
auto ret = CClaimTrieCacheBase::finalizeDecrement(takeoverUndo);
|
||||
if (ret && nNextHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
||||
if (ret && nNextHeight == base->nExtendedClaimExpirationForkHeight)
|
||||
forkForExpirationChange(false);
|
||||
return ret;
|
||||
}
|
||||
|
@ -73,7 +71,7 @@ bool CClaimTrieCacheExpirationFork::forkForExpirationChange(bool increment)
|
|||
will have their expiration extension removed.
|
||||
*/
|
||||
|
||||
auto extension = Params().GetConsensus().nExtendedClaimExpirationTime - Params().GetConsensus().nOriginalClaimExpirationTime;
|
||||
auto extension = base->nExtendedClaimExpirationTime - base->nOriginalClaimExpirationTime;
|
||||
if (increment) {
|
||||
db << "UPDATE claims SET expirationHeight = expirationHeight + ? WHERE expirationHeight >= ?"
|
||||
<< extension << nNextHeight;
|
||||
|
@ -89,9 +87,13 @@ bool CClaimTrieCacheExpirationFork::forkForExpirationChange(bool increment)
|
|||
return true;
|
||||
}
|
||||
|
||||
CClaimTrieCacheNormalizationFork::CClaimTrieCacheNormalizationFork(CClaimTrie* base) : CClaimTrieCacheExpirationFork(base)
|
||||
{
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::shouldNormalize() const
|
||||
{
|
||||
return nNextHeight > Params().GetConsensus().nNormalizedNameForkHeight;
|
||||
return nNextHeight > base->nNormalizedNameForkHeight;
|
||||
}
|
||||
|
||||
std::string CClaimTrieCacheNormalizationFork::normalizeClaimName(const std::string& name, bool force) const
|
||||
|
@ -125,10 +127,10 @@ std::string CClaimTrieCacheNormalizationFork::normalizeClaimName(const std::stri
|
|||
} catch (const boost::locale::conv::conversion_error& e) {
|
||||
return name;
|
||||
} catch (const std::bad_cast& e) {
|
||||
LogPrintf("%s() is invalid or dependencies are missing: %s\n", __func__, e.what());
|
||||
logPrint << "CClaimTrieCacheNormalizationFork::" << __func__ << "() is invalid or dependencies are missing: " << e.what() << Clog::endl;
|
||||
throw;
|
||||
} catch (const std::exception& e) { // TODO: change to use ... with current_exception() in c++11
|
||||
LogPrintf("%s() had an unexpected exception: %s\n", __func__, e.what());
|
||||
logPrint << "CClaimTrieCacheNormalizationFork::" << __func__ << "() had an unexpected exception: " << e.what() << Clog::endl;
|
||||
return name;
|
||||
}
|
||||
|
||||
|
@ -159,11 +161,11 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary(takeov
|
|||
for (auto&& row: query) {
|
||||
std::string name;
|
||||
int takeoverHeight;
|
||||
std::unique_ptr<uint160> takeoverID;
|
||||
std::unique_ptr<CUint160> takeoverID;
|
||||
row >> name >> takeoverHeight >> takeoverID;
|
||||
if (name.empty()) continue; // preserve our root node
|
||||
if (takeoverHeight > 0)
|
||||
takeoverUndo.emplace_back(name, std::make_pair(takeoverHeight, takeoverID ? *takeoverID : uint160()));
|
||||
takeoverUndo.emplace_back(name, std::make_pair(takeoverHeight, takeoverID ? *takeoverID : CUint160()));
|
||||
// we need to let the tree structure method do the actual node delete:
|
||||
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << name;
|
||||
}
|
||||
|
@ -202,57 +204,22 @@ bool CClaimTrieCacheNormalizationFork::unnormalizeAllNamesInTrieIfNecessary()
|
|||
bool CClaimTrieCacheNormalizationFork::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo, takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
if (nNextHeight == Params().GetConsensus().nNormalizedNameForkHeight)
|
||||
if (nNextHeight == base->nNormalizedNameForkHeight)
|
||||
normalizeAllNamesInTrieIfNecessary(takeoverUndo);
|
||||
auto ret = CClaimTrieCacheExpirationFork::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo);
|
||||
// if (nNextHeight == 588319) {
|
||||
// getMerkleHash();
|
||||
// auto q2 = db << "SELECT name, nodeName FROM claims WHERE nodeName NOT IN (SELECT name FROM nodes) "
|
||||
// "AND validHeight < ?1 AND expirationHeight >= ?1" << nNextHeight;
|
||||
// for (auto&& row: q2) {
|
||||
// std::string name, nn;
|
||||
// row >> name >> nn;
|
||||
// LogPrintf("BAD NAME 2: %s, %s\n", name, nn);
|
||||
// }
|
||||
// std::ifstream input("dump588318.txt");
|
||||
// std::string line;
|
||||
// std::vector<std::string> lines;
|
||||
// while (std::getline(input, line)) {
|
||||
// lines.push_back(line);
|
||||
// }
|
||||
// std::sort(lines.begin(), lines.end());
|
||||
// auto q3 = db << "SELECT n.name, n.hash, IFNULL(n.takeoverHeight, 0), "
|
||||
// "(SELECT COUNT(*) FROM claims c WHERE c.nodeName = n.name "
|
||||
// "AND validHeight < ?1 AND expirationHeight >= ?1) as cc FROM nodes n ORDER BY n.name" << nNextHeight;
|
||||
// for (auto&& row: q3) {
|
||||
// std::string name; int takeover, childs; uint256 hash;
|
||||
// row >> name >> hash >> takeover >> childs;
|
||||
// std::string m = name + ", " + std::to_string(name.size()) + ", " + hash.GetHex() + ", " + std::to_string(takeover) + ", " + std::to_string(childs);
|
||||
// if (!std::binary_search(lines.begin(), lines.end(), m)) {
|
||||
// LogPrintf("BAD BAD: %s\n", m);
|
||||
// }
|
||||
// }
|
||||
// auto q4 = db << "SELECT n.name, n.parent FROM nodes n LEFT JOIN claims c ON n.name = c.nodeName LEFT JOIN nodes n2 ON n.name = n2.parent WHERE c.nodeName IS NULL AND n2.parent IS NULL";
|
||||
// for (auto&& row: q4) {
|
||||
// std::string name, nn;
|
||||
// row >> name >> nn;
|
||||
// LogPrintf("BAD NAME 3: %s, %s\n", name, nn);
|
||||
// }
|
||||
// }
|
||||
return ret;
|
||||
return CClaimTrieCacheExpirationFork::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo)
|
||||
{
|
||||
auto ret = CClaimTrieCacheExpirationFork::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo);
|
||||
if (ret && nNextHeight == Params().GetConsensus().nNormalizedNameForkHeight)
|
||||
if (ret && nNextHeight == base->nNormalizedNameForkHeight)
|
||||
unnormalizeAllNamesInTrieIfNecessary();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof)
|
||||
bool CClaimTrieCacheNormalizationFork::getProofForName(const std::string& name, const CUint160& claim, CClaimTrieProof& proof)
|
||||
{
|
||||
return CClaimTrieCacheExpirationFork::getProofForName(normalizeClaimName(name), finalClaim, proof);
|
||||
return CClaimTrieCacheExpirationFork::getProofForName(normalizeClaimName(name), claim, proof);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, CClaimValue& claim, int offsetHeight) const
|
||||
|
@ -265,30 +232,45 @@ CClaimSupportToName CClaimTrieCacheNormalizationFork::getClaimsForName(const std
|
|||
return CClaimTrieCacheExpirationFork::getClaimsForName(normalizeClaimName(name));
|
||||
}
|
||||
|
||||
int CClaimTrieCacheNormalizationFork::getDelayForName(const std::string& name, const uint160& claimId) const
|
||||
int CClaimTrieCacheNormalizationFork::getDelayForName(const std::string& name, const CUint160& claimId) const
|
||||
{
|
||||
return CClaimTrieCacheExpirationFork::getDelayForName(normalizeClaimName(name), claimId);
|
||||
}
|
||||
|
||||
std::string CClaimTrieCacheNormalizationFork::adjustNameForValidHeight(const std::string& name, int validHeight) const
|
||||
{
|
||||
return normalizeClaimName(name, validHeight > Params().GetConsensus().nNormalizedNameForkHeight);
|
||||
return normalizeClaimName(name, validHeight > base->nNormalizedNameForkHeight);
|
||||
}
|
||||
|
||||
CClaimTrieCacheHashFork::CClaimTrieCacheHashFork(CClaimTrie* base) : CClaimTrieCacheNormalizationFork(base)
|
||||
{
|
||||
}
|
||||
|
||||
static const uint256 leafHash = uint256S("0000000000000000000000000000000000000000000000000000000000000002");
|
||||
static const uint256 emptyHash = uint256S("0000000000000000000000000000000000000000000000000000000000000003");
|
||||
static const auto leafHash = CUint256S("0000000000000000000000000000000000000000000000000000000000000002");
|
||||
static const auto emptyHash = CUint256S("0000000000000000000000000000000000000000000000000000000000000003");
|
||||
|
||||
uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly)
|
||||
CUint256 ComputeMerkleRoot(std::vector<CUint256> hashes)
|
||||
{
|
||||
if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
|
||||
while (hashes.size() > 1) {
|
||||
if (hashes.size() & 1)
|
||||
hashes.push_back(hashes.back());
|
||||
|
||||
for (std::size_t i = 0, j = 0; i < hashes.size(); i += 2)
|
||||
hashes[j++] = Hash(hashes[i].begin(), hashes[i].end(),
|
||||
hashes[i+1].begin(), hashes[i+1].end());
|
||||
|
||||
hashes.resize(hashes.size() / 2);
|
||||
}
|
||||
return hashes.empty() ? CUint256{} : hashes[0];
|
||||
}
|
||||
|
||||
CUint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly)
|
||||
{
|
||||
if (nNextHeight < base->nAllClaimsInMerkleForkHeight)
|
||||
return CClaimTrieCacheNormalizationFork::recursiveComputeMerkleHash(name, takeoverHeight, checkOnly);
|
||||
|
||||
// it may be that using RAM for this is more expensive than preparing a new query statement in each recursive call
|
||||
struct Triple { std::string name; std::unique_ptr<uint256> hash; int takeoverHeight; };
|
||||
struct Triple { std::string name; std::unique_ptr<CUint256> hash; int takeoverHeight; };
|
||||
std::vector<Triple> children;
|
||||
for (auto&& row : childHashQuery << name) {
|
||||
children.emplace_back();
|
||||
|
@ -297,19 +279,19 @@ uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& n
|
|||
}
|
||||
childHashQuery++;
|
||||
|
||||
std::vector<uint256> childHashes;
|
||||
std::vector<CUint256> childHashes;
|
||||
for (auto& child: children) {
|
||||
if (child.hash == nullptr) child.hash = std::make_unique<uint256>();
|
||||
if (child.hash == nullptr) child.hash = std::make_unique<CUint256>();
|
||||
if (child.hash->IsNull()) {
|
||||
*child.hash = recursiveComputeMerkleHash(child.name, child.takeoverHeight, checkOnly);
|
||||
}
|
||||
childHashes.push_back(*child.hash);
|
||||
}
|
||||
|
||||
std::vector<uint256> claimHashes;
|
||||
std::vector<CUint256> claimHashes;
|
||||
//if (takeoverHeight > 0) {
|
||||
for (auto &&row: claimHashQuery << nNextHeight << name) {
|
||||
COutPoint p;
|
||||
CTxOutPoint p;
|
||||
row >> p.hash >> p.n;
|
||||
auto claimHash = getValueHash(p, takeoverHeight);
|
||||
claimHashes.push_back(claimHash);
|
||||
|
@ -326,14 +308,14 @@ uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& n
|
|||
return computedHash;
|
||||
}
|
||||
|
||||
std::vector<uint256> ComputeMerklePath(const std::vector<uint256>& hashes, uint32_t idx)
|
||||
std::vector<CUint256> ComputeMerklePath(const std::vector<CUint256>& hashes, uint32_t idx)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
int matchlevel = -1;
|
||||
bool matchh = false;
|
||||
uint256 inner[32], h;
|
||||
CUint256 inner[32], h;
|
||||
const uint32_t one = 1;
|
||||
std::vector<uint256> res;
|
||||
std::vector<CUint256> res;
|
||||
|
||||
const auto iterateInner = [&](int& level) {
|
||||
for (; !(count & (one << level)); level++) {
|
||||
|
@ -381,12 +363,12 @@ std::vector<uint256> ComputeMerklePath(const std::vector<uint256>& hashes, uint3
|
|||
return res;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof)
|
||||
bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const CUint160& claim, CClaimTrieProof& proof)
|
||||
{
|
||||
if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
|
||||
return CClaimTrieCacheNormalizationFork::getProofForName(name, finalClaim, proof);
|
||||
if (nNextHeight < base->nAllClaimsInMerkleForkHeight)
|
||||
return CClaimTrieCacheNormalizationFork::getProofForName(name, claim, proof);
|
||||
|
||||
auto fillPairs = [&proof](const std::vector<uint256>& hashes, uint32_t idx) {
|
||||
auto fillPairs = [&proof](const std::vector<CUint256>& hashes, uint32_t idx) {
|
||||
auto partials = ComputeMerklePath(hashes, idx);
|
||||
for (int i = partials.size() - 1; i >= 0; --i)
|
||||
proof.pairs.emplace_back((idx >> i) & 1, partials[i]);
|
||||
|
@ -400,14 +382,14 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin
|
|||
"SELECT POPS(p) FROM prefix WHERE p != '') SELECT p FROM prefix) "
|
||||
"ORDER BY name" << name;
|
||||
for (auto&& row: nodeQuery) {
|
||||
std::string key;;
|
||||
std::string key;
|
||||
int takeoverHeight;
|
||||
row >> key >> takeoverHeight;
|
||||
std::vector<uint256> childHashes;
|
||||
uint32_t nextCurrentIdx = 0;
|
||||
std::vector<CUint256> childHashes;
|
||||
for (auto&& child : childHashQuery << key) {
|
||||
std::string childKey;
|
||||
uint256 childHash;
|
||||
CUint256 childHash;
|
||||
child >> childKey >> childHash;
|
||||
if (name.find(childKey) == 0)
|
||||
nextCurrentIdx = uint32_t(childHashes.size());
|
||||
|
@ -415,14 +397,14 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin
|
|||
}
|
||||
childHashQuery++;
|
||||
|
||||
std::vector<uint256> claimHashes;
|
||||
uint32_t finalClaimIdx = 0;
|
||||
std::vector<CUint256> claimHashes;
|
||||
uint32_t claimIdx = 0;
|
||||
for (auto&& child: claimHashQuery << nNextHeight << key) {
|
||||
COutPoint childOutPoint;
|
||||
uint160 childClaimID;
|
||||
CTxOutPoint childOutPoint;
|
||||
CUint160 childClaimID;
|
||||
child >> childOutPoint.hash >> childOutPoint.n >> childClaimID;
|
||||
if (childClaimID == finalClaim && key == name) {
|
||||
finalClaimIdx = uint32_t(claimHashes.size());
|
||||
if (childClaimID == claim && key == name) {
|
||||
claimIdx = uint32_t(claimHashes.size());
|
||||
proof.outPoint = childOutPoint;
|
||||
proof.hasValue = true;
|
||||
}
|
||||
|
@ -438,7 +420,7 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin
|
|||
auto hash = childHashes.empty() ? leafHash : ComputeMerkleRoot(childHashes);
|
||||
proof.pairs.emplace_back(true, hash);
|
||||
if (!claimHashes.empty())
|
||||
fillPairs(claimHashes, finalClaimIdx);
|
||||
fillPairs(claimHashes, claimIdx);
|
||||
} else {
|
||||
auto hash = claimHashes.empty() ? emptyHash : ComputeMerkleRoot(claimHashes);
|
||||
proof.pairs.emplace_back(false, hash);
|
||||
|
@ -454,7 +436,7 @@ void CClaimTrieCacheHashFork::initializeIncrement()
|
|||
{
|
||||
CClaimTrieCacheNormalizationFork::initializeIncrement();
|
||||
// we could do this in the constructor, but that would not allow for multiple increments in a row (as done in unit tests)
|
||||
if (nNextHeight == Params().GetConsensus().nAllClaimsInMerkleForkHeight - 1) {
|
||||
if (nNextHeight == base->nAllClaimsInMerkleForkHeight - 1) {
|
||||
if (!transacting) { transacting = true; db << "begin"; }
|
||||
db << "UPDATE nodes SET hash = NULL";
|
||||
}
|
||||
|
@ -463,7 +445,7 @@ void CClaimTrieCacheHashFork::initializeIncrement()
|
|||
bool CClaimTrieCacheHashFork::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
auto ret = CClaimTrieCacheNormalizationFork::finalizeDecrement(takeoverUndo);
|
||||
if (ret && nNextHeight == Params().GetConsensus().nAllClaimsInMerkleForkHeight - 1) {
|
||||
if (ret && nNextHeight == base->nAllClaimsInMerkleForkHeight - 1) {
|
||||
if (!transacting) { transacting = true; db << "begin"; }
|
||||
db << "UPDATE nodes SET hash = NULL";
|
||||
}
|
||||
|
@ -472,5 +454,5 @@ bool CClaimTrieCacheHashFork::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
|||
|
||||
bool CClaimTrieCacheHashFork::allowSupportMetadata() const
|
||||
{
|
||||
return nNextHeight >= Params().GetConsensus().nAllClaimsInMerkleForkHeight;
|
||||
return nNextHeight >= base->nAllClaimsInMerkleForkHeight;
|
||||
}
|
87
src/claimtrie/forks.h
Normal file
87
src/claimtrie/forks.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
|
||||
#ifndef CLAIMTRIE_FORKS_H
|
||||
#define CLAIMTRIE_FORKS_H
|
||||
|
||||
#include <claimtrie/trie.h>
|
||||
|
||||
class CClaimTrieCacheExpirationFork : public CClaimTrieCacheBase
|
||||
{
|
||||
public:
|
||||
explicit CClaimTrieCacheExpirationFork(CClaimTrie* base);
|
||||
|
||||
int expirationTime() const override;
|
||||
|
||||
virtual void initializeIncrement();
|
||||
bool finalizeDecrement(takeoverUndoType& takeoverHeightUndo) override;
|
||||
|
||||
bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeoverHeightUndo) override;
|
||||
|
||||
bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo) override;
|
||||
|
||||
protected:
|
||||
int expirationHeight;
|
||||
|
||||
private:
|
||||
bool forkForExpirationChange(bool increment);
|
||||
};
|
||||
|
||||
class CClaimTrieCacheNormalizationFork : public CClaimTrieCacheExpirationFork
|
||||
{
|
||||
public:
|
||||
explicit CClaimTrieCacheNormalizationFork(CClaimTrie* base);
|
||||
|
||||
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
|
||||
|
||||
bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeoverHeightUndo) override;
|
||||
|
||||
bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo) override;
|
||||
|
||||
bool getProofForName(const std::string& name, const CUint160& claim, CClaimTrieProof& proof) override;
|
||||
bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const override;
|
||||
CClaimSupportToName getClaimsForName(const std::string& name) const override;
|
||||
std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
|
||||
|
||||
protected:
|
||||
int getDelayForName(const std::string& name, const CUint160& claimId) const override;
|
||||
|
||||
private:
|
||||
bool normalizeAllNamesInTrieIfNecessary(takeoverUndoType& takeovers);
|
||||
bool unnormalizeAllNamesInTrieIfNecessary();
|
||||
};
|
||||
|
||||
class CClaimTrieCacheHashFork : public CClaimTrieCacheNormalizationFork
|
||||
{
|
||||
public:
|
||||
explicit CClaimTrieCacheHashFork(CClaimTrie* base);
|
||||
|
||||
bool getProofForName(const std::string& name, const CUint160& claim, CClaimTrieProof& proof) override;
|
||||
void initializeIncrement() override;
|
||||
bool finalizeDecrement(takeoverUndoType& takeoverHeightUndo) override;
|
||||
|
||||
bool allowSupportMetadata() const;
|
||||
|
||||
protected:
|
||||
CUint256 recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly) override;
|
||||
};
|
||||
|
||||
typedef CClaimTrieCacheHashFork CClaimTrieCache;
|
||||
|
||||
#endif // CLAIMTRIE_FORKS_H
|
12
src/claimtrie/hash.cpp
Normal file
12
src/claimtrie/hash.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
#include <claimtrie/hash.h>
|
||||
|
||||
CUint256 CalcHash(SHA256_CTX* sha)
|
||||
{
|
||||
CUint256 result;
|
||||
SHA256_Final(result.begin(), sha);
|
||||
SHA256_Init(sha);
|
||||
SHA256_Update(sha, result.begin(), result.size());
|
||||
SHA256_Final(result.begin(), sha);
|
||||
return result;
|
||||
}
|
29
src/claimtrie/hash.h
Normal file
29
src/claimtrie/hash.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
#ifndef CLAIMTRIE_HASH_H
|
||||
#define CLAIMTRIE_HASH_H
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include <claimtrie/uints.h>
|
||||
|
||||
// Bitcoin doubles hashes
|
||||
CUint256 CalcHash(SHA256_CTX* sha);
|
||||
|
||||
template<typename TIterator, typename... Args>
|
||||
CUint256 CalcHash(SHA256_CTX* sha, TIterator begin, TIterator end, Args... args)
|
||||
{
|
||||
static uint8_t blank;
|
||||
SHA256_Update(sha, begin == end ? &blank : (uint8_t*)&begin[0], std::distance(begin, end) * sizeof(begin[0]));
|
||||
return CalcHash(sha, args...);
|
||||
}
|
||||
|
||||
template<typename TIterator, typename... Args>
|
||||
CUint256 Hash(TIterator begin, TIterator end, Args... args)
|
||||
{
|
||||
static_assert((sizeof...(args) & 1) != 1, "Parameters should be even number");
|
||||
SHA256_CTX sha;
|
||||
SHA256_Init(&sha);
|
||||
return CalcHash(&sha, begin, end, args...);
|
||||
}
|
||||
|
||||
#endif // CLAIMTRIE_HASH_H
|
23
src/claimtrie/log.cpp
Normal file
23
src/claimtrie/log.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
#include <claimtrie/log.h>
|
||||
|
||||
void CLogPrint::setLogger(ClogBase* log)
|
||||
{
|
||||
logger = log;
|
||||
}
|
||||
|
||||
CLogPrint& CLogPrint::global()
|
||||
{
|
||||
static CLogPrint logger;
|
||||
return logger;
|
||||
}
|
||||
|
||||
CLogPrint& CLogPrint::operator<<(const Clog& cl)
|
||||
{
|
||||
if (logger && cl == Clog::endl) {
|
||||
ss << '\n';
|
||||
logger->LogPrintStr(ss.str());
|
||||
ss.str({});
|
||||
}
|
||||
return *this;
|
||||
}
|
41
src/claimtrie/log.h
Normal file
41
src/claimtrie/log.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
|
||||
#ifndef CLAIMTRIE_LOG_H
|
||||
#define CLAIMTRIE_LOG_H
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
struct ClogBase
|
||||
{
|
||||
ClogBase() = default;
|
||||
virtual ~ClogBase() = default;
|
||||
virtual void LogPrintStr(const std::string&) = 0;
|
||||
};
|
||||
|
||||
enum struct Clog
|
||||
{
|
||||
endl = 0,
|
||||
};
|
||||
|
||||
struct CLogPrint
|
||||
{
|
||||
template <typename T>
|
||||
CLogPrint& operator<<(const T& a)
|
||||
{
|
||||
if (logger)
|
||||
ss << a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CLogPrint& operator<<(const Clog& cl);
|
||||
|
||||
void setLogger(ClogBase* log);
|
||||
static CLogPrint& global();
|
||||
|
||||
private:
|
||||
CLogPrint() = default;
|
||||
std::stringstream ss;
|
||||
ClogBase* logger = nullptr;
|
||||
};
|
||||
|
||||
#endif // CLAIMTRIE_LOG_H
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#define MODERN_SQLITE_VERSION 3002008
|
||||
|
||||
#include <sqlite/sqlite3.h>
|
||||
#include "../sqlite3.h"
|
||||
|
||||
#include "sqlite_modern_cpp/type_wrapper.h"
|
||||
#include "sqlite_modern_cpp/errors.h"
|
|
@ -3,7 +3,7 @@
|
|||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <sqlite/sqlite3.h>
|
||||
#include "../../sqlite3.h"
|
||||
|
||||
namespace sqlite {
|
||||
|
|
@ -49,7 +49,7 @@ namespace sqlite
|
|||
typedef const std::u16string& u16str_ref;
|
||||
}
|
||||
#endif
|
||||
#include <sqlite/sqlite3.h>
|
||||
#include "../../sqlite3.h"
|
||||
#include "errors.h"
|
||||
|
||||
namespace sqlite {
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include<type_traits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace sqlite {
|
||||
namespace utility {
|
|
@ -1,21 +1,22 @@
|
|||
#include <claimtrie.h>
|
||||
#include <hash.h>
|
||||
#include <logging.h>
|
||||
#include <util.h>
|
||||
#include <utilstrencodings.h>
|
||||
|
||||
#include <claimtrie/hash.h>
|
||||
#include <claimtrie/log.h>
|
||||
#include <claimtrie/trie.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <consensus/merkle.h>
|
||||
#include <iomanip>
|
||||
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <boost/container/flat_set.hpp>
|
||||
|
||||
extern const uint256 one = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
|
||||
#define logPrint CLogPrint::global()
|
||||
|
||||
static const auto one = CUint256S("0000000000000000000000000000000000000000000000000000000000000001");
|
||||
|
||||
std::vector<unsigned char> heightToVch(int n)
|
||||
{
|
||||
std::vector<unsigned char> vchHeight(8, 0);
|
||||
std::vector<uint8_t> vchHeight(8, 0);
|
||||
vchHeight[4] = n >> 24;
|
||||
vchHeight[5] = n >> 16;
|
||||
vchHeight[6] = n >> 8;
|
||||
|
@ -23,40 +24,84 @@ std::vector<unsigned char> heightToVch(int n)
|
|||
return vchHeight;
|
||||
}
|
||||
|
||||
uint256 getValueHash(const COutPoint& outPoint, int nHeightOfLastTakeover)
|
||||
CUint256 getValueHash(const CTxOutPoint& outPoint, int nHeightOfLastTakeover)
|
||||
{
|
||||
CHash256 hasher;
|
||||
auto hash = Hash(outPoint.hash.begin(), outPoint.hash.end());
|
||||
hasher.Write(hash.begin(), hash.size());
|
||||
|
||||
auto hash1 = Hash(outPoint.hash.begin(), outPoint.hash.end());
|
||||
auto snOut = std::to_string(outPoint.n);
|
||||
hash = Hash(snOut.begin(), snOut.end());
|
||||
hasher.Write(hash.begin(), hash.size());
|
||||
|
||||
auto hash2 = Hash(snOut.begin(), snOut.end());
|
||||
auto vchHash = heightToVch(nHeightOfLastTakeover);
|
||||
hash = Hash(vchHash.begin(), vchHash.end());
|
||||
hasher.Write(hash.begin(), hash.size());
|
||||
|
||||
uint256 result;
|
||||
hasher.Finalize(result.begin());
|
||||
return result;
|
||||
auto hash3 = Hash(vchHash.begin(), vchHash.end());
|
||||
return Hash(hash1.begin(), hash1.end(), hash2.begin(), hash2.end(), hash3.begin(), hash3.end());
|
||||
}
|
||||
|
||||
static const sqlite::sqlite_config sharedConfig{
|
||||
CClaimNsupports::CClaimNsupports(CClaimValue claim, int64_t effectiveAmount, std::vector<CSupportValue> supports)
|
||||
: claim(std::move(claim)), effectiveAmount(effectiveAmount), supports(std::move(supports))
|
||||
{
|
||||
}
|
||||
|
||||
bool CClaimNsupports::IsNull() const
|
||||
{
|
||||
return claim.claimId.IsNull();
|
||||
}
|
||||
|
||||
CClaimSupportToName::CClaimSupportToName(std::string name, int nLastTakeoverHeight, std::vector<CClaimNsupports> claimsNsupports, std::vector<CSupportValue> unmatchedSupports)
|
||||
: name(std::move(name)), nLastTakeoverHeight(nLastTakeoverHeight), claimsNsupports(std::move(claimsNsupports)), unmatchedSupports(std::move(unmatchedSupports))
|
||||
{
|
||||
}
|
||||
|
||||
static const CClaimNsupports invalid;
|
||||
|
||||
const CClaimNsupports& CClaimSupportToName::find(const CUint160& claimId) const
|
||||
{
|
||||
auto it = std::find_if(claimsNsupports.begin(), claimsNsupports.end(), [&claimId](const CClaimNsupports& value) {
|
||||
return claimId == value.claim.claimId;
|
||||
});
|
||||
return it != claimsNsupports.end() ? *it : invalid;
|
||||
}
|
||||
|
||||
const CClaimNsupports& CClaimSupportToName::find(const std::string& partialId) const
|
||||
{
|
||||
std::string lowered(partialId);
|
||||
for (auto& c: lowered)
|
||||
c = std::tolower(c);
|
||||
|
||||
auto it = std::find_if(claimsNsupports.begin(), claimsNsupports.end(), [&lowered](const CClaimNsupports& value) {
|
||||
return value.claim.claimId.GetHex().find(lowered) == 0;
|
||||
});
|
||||
return it != claimsNsupports.end() ? *it : invalid;
|
||||
}
|
||||
|
||||
bool CClaimNsupports::operator<(const CClaimNsupports& other) const
|
||||
{
|
||||
return claim < other.claim;
|
||||
}
|
||||
|
||||
CClaimTrieProofNode::CClaimTrieProofNode(std::vector<std::pair<unsigned char, CUint256>> children, bool hasValue, CUint256 valHash)
|
||||
: children(std::move(children)), hasValue(hasValue), valHash(std::move(valHash))
|
||||
{
|
||||
}
|
||||
|
||||
static const sqlite::sqlite_config sharedConfig {
|
||||
sqlite::OpenFlags::READWRITE | sqlite::OpenFlags::CREATE, // TODO: test with this: | sqlite::OpenFlags::SHAREDCACHE,
|
||||
nullptr, sqlite::Encoding::UTF8
|
||||
};
|
||||
|
||||
CClaimTrie::CClaimTrie(bool fWipe, int height, int proportionalDelayFactor)
|
||||
: dbPath((GetDataDir() / "claims.sqlite").string()), db(dbPath, sharedConfig),
|
||||
nNextHeight(height), nProportionalDelayFactor(proportionalDelayFactor)
|
||||
CClaimTrie::CClaimTrie(bool fWipe, int height,
|
||||
int nNormalizedNameForkHeight,
|
||||
int64_t nOriginalClaimExpirationTime,
|
||||
int64_t nExtendedClaimExpirationTime,
|
||||
int64_t nExtendedClaimExpirationForkHeight,
|
||||
int64_t nAllClaimsInMerkleForkHeight,
|
||||
int proportionalDelayFactor) :
|
||||
nNextHeight(height),
|
||||
db("claims.sqlite", sharedConfig),
|
||||
nProportionalDelayFactor(proportionalDelayFactor),
|
||||
nNormalizedNameForkHeight(nNormalizedNameForkHeight),
|
||||
nOriginalClaimExpirationTime(nOriginalClaimExpirationTime),
|
||||
nExtendedClaimExpirationTime(nExtendedClaimExpirationTime),
|
||||
nExtendedClaimExpirationForkHeight(nExtendedClaimExpirationForkHeight),
|
||||
nAllClaimsInMerkleForkHeight(nAllClaimsInMerkleForkHeight)
|
||||
{
|
||||
// db.define("MERKLE_ROOT", [](std::vector<uint256>& hashes, const std::vector<unsigned char>& blob) { hashes.emplace_back(uint256(blob)); },
|
||||
// [](const std::vector<uint256>& hashes) { return ComputeMerkleRoot(hashes); });
|
||||
//
|
||||
// db.define("MERKLE_PAIR", [](const std::vector<unsigned char>& blob1, const std::vector<unsigned char>& blob2) { return Hash(blob1.begin(), blob1.end(), blob2.begin(), blob2.end()); });
|
||||
// db.define("MERKLE", [](const std::vector<unsigned char>& blob1) { return Hash(blob1.begin(), blob1.end()); });
|
||||
|
||||
db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT REFERENCES nodes(name) DEFERRABLE INITIALLY DEFERRED, "
|
||||
"hash BLOB COLLATE BINARY, takeoverHeight INTEGER, takeoverID BLOB COLLATE BINARY)";
|
||||
db << "CREATE INDEX IF NOT EXISTS nodes_hash ON nodes (hash)";
|
||||
|
@ -95,7 +140,8 @@ CClaimTrie::CClaimTrie(bool fWipe, int height, int proportionalDelayFactor)
|
|||
db << "INSERT OR IGNORE INTO nodes(name, hash) VALUES('', ?)" << one; // ensure that we always have our root node
|
||||
}
|
||||
|
||||
CClaimTrieCacheBase::~CClaimTrieCacheBase() {
|
||||
CClaimTrieCacheBase::~CClaimTrieCacheBase()
|
||||
{
|
||||
if (transacting) {
|
||||
db << "rollback";
|
||||
transacting = false;
|
||||
|
@ -111,13 +157,14 @@ bool CClaimTrie::SyncToDisk()
|
|||
return rc == SQLITE_OK;
|
||||
}
|
||||
|
||||
bool CClaimTrie::empty() {
|
||||
bool CClaimTrie::empty()
|
||||
{
|
||||
int64_t count;
|
||||
db << "SELECT COUNT(*) FROM claims WHERE validHeight < ?1 AND expirationHeight >= ?1" << nNextHeight >> count;
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::haveClaim(const std::string& name, const COutPoint& outPoint) const
|
||||
bool CClaimTrieCacheBase::haveClaim(const std::string& name, const CTxOutPoint& outPoint) const
|
||||
{
|
||||
auto query = db << "SELECT 1 FROM claims WHERE nodeName = ?1 AND txID = ?2 AND txN = ?3 "
|
||||
"AND validHeight < ?4 AND expirationHeight >= ?4 LIMIT 1"
|
||||
|
@ -125,7 +172,7 @@ bool CClaimTrieCacheBase::haveClaim(const std::string& name, const COutPoint& ou
|
|||
return query.begin() != query.end();
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::haveSupport(const std::string& name, const COutPoint& outPoint) const
|
||||
bool CClaimTrieCacheBase::haveSupport(const std::string& name, const CTxOutPoint& outPoint) const
|
||||
{
|
||||
auto query = db << "SELECT 1 FROM supports WHERE nodeName = ?1 AND txID = ?2 AND txN = ?3 "
|
||||
"AND validHeight < ?4 AND expirationHeight >= ?4 LIMIT 1"
|
||||
|
@ -148,7 +195,7 @@ supportEntryType CClaimTrieCacheBase::getSupportsForName(const std::string& name
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::haveClaimInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const
|
||||
bool CClaimTrieCacheBase::haveClaimInQueue(const std::string& name, const CTxOutPoint& outPoint, int& nValidAtHeight) const
|
||||
{
|
||||
auto query = db << "SELECT validHeight FROM claims WHERE nodeName = ? AND txID = ? AND txN = ? "
|
||||
"AND validHeight >= ? AND expirationHeight > validHeight LIMIT 1"
|
||||
|
@ -160,7 +207,7 @@ bool CClaimTrieCacheBase::haveClaimInQueue(const std::string& name, const COutPo
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::haveSupportInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const
|
||||
bool CClaimTrieCacheBase::haveSupportInQueue(const std::string& name, const CTxOutPoint& outPoint, int& nValidAtHeight) const
|
||||
{
|
||||
auto query = db << "SELECT validHeight FROM supports WHERE nodeName = ? AND txID = ? AND txN = ? "
|
||||
"AND validHeight >= ? AND expirationHeight > validHeight LIMIT 1"
|
||||
|
@ -172,7 +219,8 @@ bool CClaimTrieCacheBase::haveSupportInQueue(const std::string& name, const COut
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::string& parent, int64_t& claims) {
|
||||
bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::string& parent, int64_t& claims)
|
||||
{
|
||||
if (name.empty()) return false;
|
||||
// to remove a node it must have one or less children and no claims
|
||||
db << "SELECT COUNT(*) FROM claims WHERE nodeName = ?1 AND validHeight < ?2 AND expirationHeight >= ?2 "
|
||||
|
@ -186,7 +234,7 @@ bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::str
|
|||
// alternately: SELECT COUNT(DISTINCT nodeName) FROM claims WHERE SUBSTR(nodeName, 1, len(?)) == ? AND LENGTH(nodeName) > len(?)
|
||||
db << "SELECT COUNT(*),MAX(name) FROM nodes WHERE parent = ?" << name >> std::tie(count, childName);
|
||||
if (count > 1) return false; // still has multiple children
|
||||
LogPrint(BCLog::CLAIMS, "Removing node %s with %d children\n", name, count);
|
||||
logPrint << "Removing node " << name << " with " << count << " children" << Clog::endl;
|
||||
// okay. it's going away
|
||||
auto query = db << "SELECT parent FROM nodes WHERE name = ?" << name;
|
||||
auto it = query.begin();
|
||||
|
@ -202,7 +250,8 @@ bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::str
|
|||
return ret;
|
||||
}
|
||||
|
||||
void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||
void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate()
|
||||
{
|
||||
if (!transacting) return;
|
||||
|
||||
// your children are your nodes that match your key but go at least one longer,
|
||||
|
@ -272,7 +321,7 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
|||
break;
|
||||
}
|
||||
// insert the split node:
|
||||
LogPrint(BCLog::CLAIMS, "Inserting split node %s near %s, parent %s\n", newNodeName, sibling, parent);
|
||||
logPrint << "Inserting split node " << newNodeName << " near " << sibling << ", parent " << parent << Clog::endl;
|
||||
insertQuery << newNodeName << parent;
|
||||
insertQuery++;
|
||||
|
||||
|
@ -281,7 +330,7 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
|||
}
|
||||
}
|
||||
|
||||
LogPrint(BCLog::CLAIMS, "Inserting or updating node %s (%s), parent %s\n", name, HexStr(name), parent);
|
||||
logPrint << "Inserting or updating node " << name << ", parent " << parent << Clog::endl;
|
||||
insertQuery << name << parent;
|
||||
insertQuery++;
|
||||
}
|
||||
|
@ -313,9 +362,9 @@ std::size_t CClaimTrieCacheBase::getTotalClaimsInTrie() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
CAmount CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly) const
|
||||
int64_t CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly) const
|
||||
{
|
||||
CAmount ret = 0;
|
||||
int64_t ret = 0;
|
||||
std::string query("SELECT SUM(SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s "
|
||||
"WHERE s.supportedClaimID = c.claimID AND s.validHeight < ?1 AND s.expirationHeight >= ?1) "
|
||||
"FROM claims c WHERE c.validHeight < ?1 AND s.expirationHeight >= ?1");
|
||||
|
@ -348,9 +397,9 @@ CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& nam
|
|||
if (it != query.end())
|
||||
*it >> nLastTakeoverHeight;
|
||||
}
|
||||
auto supports = getSupportsForName(name);
|
||||
|
||||
claimEntryType claims;
|
||||
auto supports = getSupportsForName(name);
|
||||
{
|
||||
auto query = db << "SELECT claimID, txID, txN, blockHeight, validHeight, amount "
|
||||
"FROM claims WHERE nodeName = ? AND expirationHeight >= ?"
|
||||
|
@ -362,6 +411,7 @@ CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& nam
|
|||
claims.push_back(claim);
|
||||
}
|
||||
}
|
||||
|
||||
auto find = [&supports](decltype(supports)::iterator& it, const CClaimValue& claim) {
|
||||
it = std::find_if(it, supports.end(), [&claim](const CSupportValue& support) {
|
||||
return claim.claimId == support.supportedClaimId;
|
||||
|
@ -372,7 +422,7 @@ CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& nam
|
|||
// match support to claim
|
||||
std::vector<CClaimNsupports> claimsNsupports;
|
||||
for (const auto& claim : claims) {
|
||||
CAmount nAmount = claim.nValidAtHeight < nNextHeight ? claim.nAmount : 0;
|
||||
int64_t nAmount = claim.nValidAtHeight < nNextHeight ? claim.nAmount : 0;
|
||||
auto ic = claimsNsupports.emplace(claimsNsupports.end(), claim, nAmount);
|
||||
for (auto it = supports.begin(); find(it, claim); it = supports.erase(it)) {
|
||||
if (it->nValidAtHeight < nNextHeight)
|
||||
|
@ -385,22 +435,18 @@ CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& nam
|
|||
return {name, nLastTakeoverHeight, std::move(claimsNsupports), std::move(supports)};
|
||||
}
|
||||
|
||||
void completeHash(uint256& partialHash, const std::string& key, std::size_t to)
|
||||
void completeHash(CUint256& partialHash, const std::string& key, int to)
|
||||
{
|
||||
CHash256 hasher;
|
||||
for (auto i = key.size(); i > to + 1; --i, hasher.Reset())
|
||||
hasher
|
||||
.Write((uint8_t*)&key[i - 1], 1)
|
||||
.Write(partialHash.begin(), partialHash.size())
|
||||
.Finalize(partialHash.begin());
|
||||
for (auto it = key.rbegin(); std::distance(it, key.rend()) > to + 1; ++it)
|
||||
partialHash = Hash(it, it + 1, partialHash.begin(), partialHash.end());
|
||||
}
|
||||
|
||||
uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly)
|
||||
CUint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly)
|
||||
{
|
||||
std::vector<uint8_t> vchToHash;
|
||||
const auto pos = name.size();
|
||||
// we have to free up the hash query so it can be reused by a child
|
||||
struct Triple { std::string name; std::unique_ptr<uint256> hash; int takeoverHeight; };
|
||||
struct Triple { std::string name; std::unique_ptr<CUint256> hash; int takeoverHeight; };
|
||||
std::vector<Triple> children;
|
||||
for (auto&& row : childHashQuery << name) {
|
||||
children.emplace_back();
|
||||
|
@ -410,12 +456,10 @@ uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name,
|
|||
childHashQuery++;
|
||||
|
||||
for (auto& child: children) {
|
||||
if (child.hash == nullptr) child.hash = std::make_unique<uint256>();
|
||||
if (child.hash == nullptr) child.hash = std::make_unique<CUint256>();
|
||||
if (child.hash->IsNull()) {
|
||||
*child.hash = recursiveComputeMerkleHash(child.name, child.takeoverHeight, checkOnly);
|
||||
}
|
||||
if (!checkOnly)
|
||||
LogPrint(BCLog::CLAIMS, "Using hash of %s (%s): %s, takeover: %d\n", child.name, HexStr(child.name), (*child.hash).GetHex(), child.takeoverHeight);
|
||||
completeHash(*child.hash, child.name, pos);
|
||||
vchToHash.push_back(child.name[pos]);
|
||||
vchToHash.insert(vchToHash.end(), child.hash->begin(), child.hash->end());
|
||||
|
@ -423,7 +467,7 @@ uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name,
|
|||
|
||||
CClaimValue claim;
|
||||
if (getInfoForName(name, claim)) {
|
||||
uint256 valueHash = getValueHash(claim.outPoint, takeoverHeight);
|
||||
CUint256 valueHash = getValueHash(claim.outPoint, takeoverHeight);
|
||||
vchToHash.insert(vchToHash.end(), valueHash.begin(), valueHash.end());
|
||||
}
|
||||
|
||||
|
@ -440,7 +484,7 @@ bool CClaimTrieCacheBase::checkConsistency()
|
|||
auto query = db << "SELECT name, hash, IFNULL(takeoverHeight, 0) FROM nodes";
|
||||
for (auto&& row: query) {
|
||||
std::string name;
|
||||
uint256 hash;
|
||||
CUint256 hash;
|
||||
int takeoverHeight;
|
||||
row >> name >> hash >> takeoverHeight;
|
||||
auto computedHash = recursiveComputeMerkleHash(name, takeoverHeight, true);
|
||||
|
@ -459,7 +503,7 @@ bool CClaimTrieCacheBase::flush()
|
|||
db << "commit";
|
||||
}
|
||||
catch (const sqlite::sqlite_exception& e) {
|
||||
LogPrintf("ERROR in ClaimTrieCache flush: %s\n", e.what());
|
||||
logPrint << "ERROR in ClaimTrieCache flush: " << e.what() << Clog::endl;
|
||||
auto code = e.get_code();
|
||||
if (code == SQLITE_LOCKED || code == SQLITE_BUSY) {
|
||||
LogPrintf("Retrying the commit in one second.\n", e.what());
|
||||
|
@ -475,36 +519,25 @@ bool CClaimTrieCacheBase::flush()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::ValidateTipMatches(const CBlockIndex* tip)
|
||||
bool CClaimTrieCacheBase::ReadFromDisk(int nHeight, const CUint256& rootHash)
|
||||
{
|
||||
base->nNextHeight = nNextHeight = tip ? tip->nHeight + 1 : 0;
|
||||
base->nNextHeight = nNextHeight = nHeight + 1;
|
||||
|
||||
LogPrintf("Checking claim trie consistency... ");
|
||||
logPrint << "Checking claim trie consistency... " << Clog::endl;
|
||||
if (checkConsistency()) {
|
||||
LogPrintf("consistent\n");
|
||||
if (tip && tip->hashClaimTrie != getMerkleHash()) {
|
||||
// suppose we leave the old LevelDB data there: any harm done? It's ~10GB
|
||||
// eh, we better blow it away; it's their job to back up the folder first
|
||||
// well, only do it if we're empty on the sqlite side -- aka, we haven't trie to sync first
|
||||
std::size_t count;
|
||||
db << "SELECT COUNT(*) FROM nodes" >> count;
|
||||
if (count <= 1) {
|
||||
auto oldDataPath = GetDataDir() / "claimtrie";
|
||||
boost::system::error_code ec;
|
||||
boost::filesystem::remove_all(oldDataPath, ec);
|
||||
}
|
||||
|
||||
return error("%s(): the block's root claim hash doesn't match the persisted claim root hash.", __func__);
|
||||
logPrint << "consistent" << Clog::endl;
|
||||
if (rootHash != getMerkleHash()) {
|
||||
logPrint << "Merkle hash does not match root hash" << Clog::endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
LogPrintf("inconsistent!\n");
|
||||
|
||||
logPrint << "inconsistent!" << Clog::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base)
|
||||
: base(base), db(base->dbPath, sharedConfig), transacting(false),
|
||||
: base(base), db(base->db), transacting(false),
|
||||
childHashQuery(db << "SELECT name, hash, IFNULL(takeoverHeight, 0) FROM nodes WHERE parent = ? ORDER BY name"),
|
||||
claimHashQuery(db << "SELECT c.txID, c.txN, c.claimID, c.blockHeight, c.validHeight, c.amount, "
|
||||
"(SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
||||
|
@ -526,13 +559,13 @@ CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base)
|
|||
|
||||
int CClaimTrieCacheBase::expirationTime() const
|
||||
{
|
||||
return Params().GetConsensus().nOriginalClaimExpirationTime;
|
||||
return base->nOriginalClaimExpirationTime;
|
||||
}
|
||||
|
||||
uint256 CClaimTrieCacheBase::getMerkleHash()
|
||||
CUint256 CClaimTrieCacheBase::getMerkleHash()
|
||||
{
|
||||
ensureTreeStructureIsUpToDate();
|
||||
std::unique_ptr<uint256> hash;
|
||||
std::unique_ptr<CUint256> hash;
|
||||
int takeoverHeight;
|
||||
// can't use childHashQuery here because "IS NULL" must be used instead of parent = NULL
|
||||
db << "SELECT hash, IFNULL(takeoverHeight, 0) FROM nodes WHERE name = ''" >> std::tie(hash, takeoverHeight);
|
||||
|
@ -543,7 +576,7 @@ uint256 CClaimTrieCacheBase::getMerkleHash()
|
|||
return *hash;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, uint160& claimId, int& takeoverHeight) const
|
||||
bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, CUint160& claimId, int& takeoverHeight) const
|
||||
{
|
||||
auto query = db << "SELECT takeoverHeight, takeoverID FROM nodes WHERE name = ? AND takeoverID IS NOT NULL" << name;
|
||||
auto it = query.begin();
|
||||
|
@ -553,8 +586,8 @@ bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, uint16
|
|||
return !claimId.IsNull();
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId,
|
||||
CAmount nAmount, int nHeight, int nValidHeight, const std::vector<unsigned char>& metadata)
|
||||
bool CClaimTrieCacheBase::addClaim(const std::string& name, const CTxOutPoint& outPoint, const CUint160& claimId,
|
||||
int64_t nAmount, int nHeight, int nValidHeight, const std::vector<unsigned char>& metadata)
|
||||
{
|
||||
if (!transacting) { transacting = true; db << "begin"; }
|
||||
|
||||
|
@ -584,8 +617,8 @@ bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& out
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::addSupport(const std::string& name, const COutPoint& outPoint, CAmount nAmount,
|
||||
const uint160& supportedClaimId, int nHeight, int nValidHeight, const std::vector<unsigned char>& metadata)
|
||||
bool CClaimTrieCacheBase::addSupport(const std::string& name, const CTxOutPoint& outPoint, const CUint160& supportedClaimId,
|
||||
int64_t nAmount, int nHeight, int nValidHeight, const std::vector<unsigned char>& metadata)
|
||||
{
|
||||
if (!transacting) { transacting = true; db << "begin"; }
|
||||
|
||||
|
@ -603,7 +636,7 @@ bool CClaimTrieCacheBase::addSupport(const std::string& name, const COutPoint& o
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::removeClaim(const uint160& claimId, const COutPoint& outPoint, std::string& nodeName, int& validHeight)
|
||||
bool CClaimTrieCacheBase::removeClaim(const CUint160& claimId, const CTxOutPoint& outPoint, std::string& nodeName, int& validHeight)
|
||||
{
|
||||
if (!transacting) { transacting = true; db << "begin"; }
|
||||
|
||||
|
@ -640,11 +673,10 @@ bool CClaimTrieCacheBase::removeClaim(const uint160& claimId, const COutPoint& o
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::removeSupport(const COutPoint& outPoint, std::string& nodeName, int& validHeight)
|
||||
bool CClaimTrieCacheBase::removeSupport(const CTxOutPoint& outPoint, std::string& nodeName, int& validHeight)
|
||||
{
|
||||
if (!transacting) { transacting = true; db << "begin"; }
|
||||
|
||||
|
@ -1147,6 +1179,7 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
|||
expireSupportUndo.emplace_back(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
db << "UPDATE nodes SET hash = NULL WHERE name IN (SELECT nodeName FROM supports WHERE expirationHeight = ?)"
|
||||
<< nNextHeight;
|
||||
|
||||
|
@ -1156,10 +1189,10 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
|||
>> [&takeovers](std::string name) {
|
||||
takeovers.push_back(std::move(name));
|
||||
};
|
||||
|
||||
auto getTakeoverQuery = db << "SELECT IFNULL(takeoverHeight, 0), takeoverID FROM nodes WHERE name = ?";
|
||||
auto hasCandidateQuery = db << "UPDATE nodes SET takeoverHeight = ?, takeoverID = ? WHERE name = ?";
|
||||
auto noCandidateQuery = db << "UPDATE nodes SET takeoverHeight = NULL, takeoverID = NULL WHERE name = ?";
|
||||
auto maxWorkaround = Params().GetConsensus().nMaxTakeoverWorkaroundHeight;
|
||||
|
||||
for (const auto& nameWithTakeover : takeovers) {
|
||||
// if somebody activates on this block and they are the new best, then everybody activates on this block
|
||||
|
@ -1167,7 +1200,7 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
|||
auto hasCandidate = getInfoForName(nameWithTakeover, candidateValue, 1);
|
||||
// now that they're all in get the winner:
|
||||
int existingHeight;
|
||||
std::unique_ptr<uint160> existingID;
|
||||
std::unique_ptr<CUint160> existingID;
|
||||
getTakeoverQuery << nameWithTakeover >> std::tie(existingHeight, existingID);
|
||||
getTakeoverQuery++; // reset it
|
||||
|
||||
|
@ -1179,15 +1212,15 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
|||
// This is a super ugly hack to work around bug in old code.
|
||||
// The bug: un/support a name then update it. This will cause its takeover height to be reset to current.
|
||||
// This is because the old code with add to the cache without setting block originals when dealing in supports.
|
||||
if (nNextHeight < maxWorkaround) {
|
||||
if (nNextHeight < 658300) {
|
||||
auto wit = takeoverWorkarounds.find(std::make_pair(nNextHeight, nameWithTakeover));
|
||||
takeoverHappening |= wit != takeoverWorkarounds.end();
|
||||
}
|
||||
|
||||
LogPrint(BCLog::CLAIMS, "Takeover on %s (%s) at %d, happening: %d, set before: %d\n", nameWithTakeover, HexStr(nameWithTakeover), nNextHeight, takeoverHappening, hasBeenSetBefore);
|
||||
logPrint << "Takeover on " << nameWithTakeover << " at " << nNextHeight << ", happening: " << takeoverHappening << ", set before: " << hasBeenSetBefore << Clog::endl;
|
||||
|
||||
if (takeoverHappening || !hasBeenSetBefore) {
|
||||
takeoverUndo.emplace_back(nameWithTakeover, std::make_pair(existingHeight, hasBeenSetBefore ? *existingID : uint160()));
|
||||
takeoverUndo.emplace_back(nameWithTakeover, std::make_pair(existingHeight, hasBeenSetBefore ? *existingID : CUint160()));
|
||||
if (hasCandidate) {
|
||||
hasCandidateQuery << nNextHeight << candidateValue.claimId << nameWithTakeover;
|
||||
hasCandidateQuery++;
|
||||
|
@ -1203,25 +1236,24 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
|||
getTakeoverQuery.used(true);
|
||||
hasCandidateQuery.used(true);
|
||||
noCandidateQuery.used(true);
|
||||
|
||||
nNextHeight++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo,
|
||||
const std::string& name) {
|
||||
bool CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo, const std::string& name)
|
||||
{
|
||||
// now that we know a takeover is happening, we bring everybody in:
|
||||
auto ret = false;
|
||||
{
|
||||
auto query = db << "SELECT txID, txN, validHeight FROM claims WHERE nodeName = ?1 AND validHeight > ?2 AND expirationHeight > ?2"
|
||||
<< name << nNextHeight;
|
||||
for (auto &&row: query) {
|
||||
uint256 hash;
|
||||
CUint256 hash;
|
||||
uint32_t n;
|
||||
int oldValidHeight;
|
||||
row >> hash >> n >> oldValidHeight;
|
||||
insertUndo.emplace_back(name, COutPoint(hash, n), oldValidHeight);
|
||||
LogPrint(BCLog::CLAIMS, "Early activation of claim %s, t: %s:%d at %d\n", name, hash.GetHex().substr(0, 6), n, nNextHeight);
|
||||
insertUndo.emplace_back(name, CTxOutPoint(hash, n), oldValidHeight);
|
||||
logPrint << "Early activation of claim " << name << ", " << CTxOutPoint(hash, n).ToString() << " at " << nNextHeight << Clog::endl;
|
||||
}
|
||||
}
|
||||
// and then update them all to activate now:
|
||||
|
@ -1234,12 +1266,12 @@ bool CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoT
|
|||
auto query = db << "SELECT txID, txN, validHeight FROM supports WHERE nodeName = ?1 AND validHeight > ?2 AND expirationHeight > ?2"
|
||||
<< name << nNextHeight;
|
||||
for (auto &&row: query) {
|
||||
uint256 hash;
|
||||
CUint256 hash;
|
||||
uint32_t n;
|
||||
int oldValidHeight;
|
||||
row >> hash >> n >> oldValidHeight;
|
||||
insertSupportUndo.emplace_back(name, COutPoint(hash, n), oldValidHeight);
|
||||
LogPrint(BCLog::CLAIMS, "Early activation of support %s, t: %s:%d at %d\n", name, hash.GetHex().substr(0, 6), n, nNextHeight);
|
||||
insertSupportUndo.emplace_back(name, CTxOutPoint(hash, n), oldValidHeight);
|
||||
logPrint << "Early activation of support " << name << ", " << CTxOutPoint(hash, n).ToString() << " at " << nNextHeight << Clog::endl;
|
||||
}
|
||||
}
|
||||
// and then update them all to activate now:
|
||||
|
@ -1267,14 +1299,14 @@ bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimUndoTy
|
|||
}
|
||||
|
||||
for (auto it = insertSupportUndo.crbegin(); it != insertSupportUndo.crend(); ++it) {
|
||||
LogPrint(BCLog::CLAIMS, "Resetting support valid height to %d for %s\n", it->nValidHeight, it->name);
|
||||
logPrint << "Resetting support valid height to " << it->nValidHeight << " for " << it->name << Clog::endl;
|
||||
db << "UPDATE supports SET validHeight = ? WHERE txID = ? AND txN = ?"
|
||||
<< it->nValidHeight << it->outPoint.hash << it->outPoint.n;
|
||||
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << it->name;
|
||||
}
|
||||
|
||||
for (auto it = insertUndo.crbegin(); it != insertUndo.crend(); ++it) {
|
||||
LogPrint(BCLog::CLAIMS, "Resetting valid height to %d for %s\n", it->nValidHeight, it->name);
|
||||
logPrint << "Resetting valid height to " << it->nValidHeight << " for " << it->name << Clog::endl;
|
||||
db << "UPDATE claims SET validHeight = ? WHERE nodeName = ? AND txID = ? AND txN = ?"
|
||||
<< it->nValidHeight << it->name << it->outPoint.hash << it->outPoint.n;
|
||||
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << it->name;
|
||||
|
@ -1300,9 +1332,9 @@ bool CClaimTrieCacheBase::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
|||
return true;
|
||||
}
|
||||
|
||||
int CClaimTrieCacheBase::getDelayForName(const std::string& name, const uint160& claimId) const
|
||||
int CClaimTrieCacheBase::getDelayForName(const std::string& name, const CUint160& claimId) const
|
||||
{
|
||||
uint160 winningClaimId;
|
||||
CUint160 winningClaimId;
|
||||
int winningTakeoverHeight;
|
||||
auto found = getLastTakeoverForName(name, winningClaimId, winningTakeoverHeight);
|
||||
if (found && winningClaimId == claimId) {
|
||||
|
@ -1326,7 +1358,7 @@ std::string CClaimTrieCacheBase::adjustNameForValidHeight(const std::string& nam
|
|||
return name;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof)
|
||||
bool CClaimTrieCacheBase::getProofForName(const std::string& name, const CUint160& finalClaim, CClaimTrieProof& proof)
|
||||
{
|
||||
// cache the parent nodes
|
||||
getMerkleHash();
|
||||
|
@ -1341,25 +1373,25 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, const uint160
|
|||
int takeoverHeight;
|
||||
row >> key >> takeoverHeight;
|
||||
bool fNodeHasValue = getInfoForName(key, claim);
|
||||
uint256 valueHash;
|
||||
CUint256 valueHash;
|
||||
if (fNodeHasValue)
|
||||
valueHash = getValueHash(claim.outPoint, takeoverHeight);
|
||||
|
||||
const auto pos = key.size();
|
||||
std::vector<std::pair<unsigned char, uint256>> children;
|
||||
std::vector<std::pair<unsigned char, CUint256>> children;
|
||||
for (auto&& child : childHashQuery << key) {
|
||||
std::string childKey;
|
||||
uint256 hash;
|
||||
CUint256 hash;
|
||||
child >> childKey >> hash;
|
||||
if (name.find(childKey) == 0) {
|
||||
for (auto i = pos; i + 1 < childKey.size(); ++i) {
|
||||
children.emplace_back(childKey[i], uint256{});
|
||||
children.emplace_back(childKey[i], CUint256{});
|
||||
proof.nodes.emplace_back(children, fNodeHasValue, valueHash);
|
||||
children.clear();
|
||||
valueHash.SetNull();
|
||||
fNodeHasValue = false;
|
||||
}
|
||||
children.emplace_back(childKey.back(), uint256{});
|
||||
children.emplace_back(childKey.back(), CUint256{});
|
||||
continue;
|
||||
}
|
||||
completeHash(hash, childKey, pos);
|
||||
|
@ -1379,7 +1411,8 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, const uint160
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::findNameForClaim(std::vector<unsigned char> claim, CClaimValue& value, std::string& name) {
|
||||
bool CClaimTrieCacheBase::findNameForClaim(std::vector<unsigned char> claim, CClaimValue& value, std::string& name)
|
||||
{
|
||||
std::reverse(claim.begin(), claim.end());
|
||||
auto query = db << "SELECT nodeName, claimId, txID, txN, amount, validHeight, blockHeight "
|
||||
"FROM claims WHERE SUBSTR(claimID, ?) = ? AND validHeight < ? AND expirationHeight >= ?"
|
207
src/claimtrie/trie.h
Normal file
207
src/claimtrie/trie.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
#ifndef CLAIMTRIE_TRIE_H
|
||||
#define CLAIMTRIE_TRIE_H
|
||||
|
||||
#include <claimtrie/data.h>
|
||||
#include <claimtrie/txoutpoint.h>
|
||||
#include <claimtrie/uints.h>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
CUint256 getValueHash(const CTxOutPoint& outPoint, int nHeightOfLastTakeover);
|
||||
|
||||
struct CClaimNsupports
|
||||
{
|
||||
CClaimNsupports() = default;
|
||||
CClaimNsupports(CClaimNsupports&&) = default;
|
||||
CClaimNsupports(const CClaimNsupports&) = default;
|
||||
|
||||
bool operator<(const CClaimNsupports& other) const;
|
||||
CClaimNsupports& operator=(CClaimNsupports&&) = default;
|
||||
CClaimNsupports& operator=(const CClaimNsupports&) = default;
|
||||
|
||||
CClaimNsupports(CClaimValue claim, int64_t effectiveAmount, std::vector<CSupportValue> supports = {});
|
||||
|
||||
bool IsNull() const;
|
||||
|
||||
CClaimValue claim;
|
||||
int64_t effectiveAmount = 0;
|
||||
std::vector<CSupportValue> supports;
|
||||
};
|
||||
|
||||
struct CClaimSupportToName
|
||||
{
|
||||
CClaimSupportToName(std::string name, int nLastTakeoverHeight, std::vector<CClaimNsupports> claimsNsupports, std::vector<CSupportValue> unmatchedSupports);
|
||||
|
||||
const CClaimNsupports& find(const CUint160& claimId) const;
|
||||
const CClaimNsupports& find(const std::string& partialId) const;
|
||||
|
||||
const std::string name;
|
||||
const int nLastTakeoverHeight;
|
||||
const std::vector<CClaimNsupports> claimsNsupports;
|
||||
const std::vector<CSupportValue> unmatchedSupports;
|
||||
};
|
||||
|
||||
class CClaimTrie
|
||||
{
|
||||
friend class CClaimTrieCacheBase;
|
||||
friend class ClaimTrieChainFixture;
|
||||
friend class CClaimTrieCacheHashFork;
|
||||
friend class CClaimTrieCacheExpirationFork;
|
||||
friend class CClaimTrieCacheNormalizationFork;
|
||||
public:
|
||||
CClaimTrie() = default;
|
||||
CClaimTrie(CClaimTrie&&) = delete;
|
||||
CClaimTrie(const CClaimTrie&) = delete;
|
||||
CClaimTrie(bool fWipe, int height,
|
||||
int nNormalizedNameForkHeight,
|
||||
int64_t nOriginalClaimExpirationTime,
|
||||
int64_t nExtendedClaimExpirationTime,
|
||||
int64_t nExtendedClaimExpirationForkHeight,
|
||||
int64_t nAllClaimsInMerkleForkHeight,
|
||||
int proportionalDelayFactor = 32);
|
||||
|
||||
CClaimTrie& operator=(CClaimTrie&&) = delete;
|
||||
CClaimTrie& operator=(const CClaimTrie&) = delete;
|
||||
|
||||
bool empty();
|
||||
bool SyncToDisk();
|
||||
|
||||
protected:
|
||||
int nNextHeight = 0;
|
||||
sqlite::database db;
|
||||
const int nProportionalDelayFactor = 0;
|
||||
|
||||
const int nNormalizedNameForkHeight = -1;
|
||||
const int64_t nOriginalClaimExpirationTime = -1;
|
||||
const int64_t nExtendedClaimExpirationTime = -1;
|
||||
const int64_t nExtendedClaimExpirationForkHeight = -1;
|
||||
const int64_t nAllClaimsInMerkleForkHeight = -1;
|
||||
};
|
||||
|
||||
struct CClaimTrieProofNode
|
||||
{
|
||||
CClaimTrieProofNode(std::vector<std::pair<unsigned char, CUint256>> children, bool hasValue, CUint256 valHash);
|
||||
|
||||
CClaimTrieProofNode(CClaimTrieProofNode&&) = default;
|
||||
CClaimTrieProofNode(const CClaimTrieProofNode&) = default;
|
||||
CClaimTrieProofNode& operator=(CClaimTrieProofNode&&) = default;
|
||||
CClaimTrieProofNode& operator=(const CClaimTrieProofNode&) = default;
|
||||
|
||||
std::vector<std::pair<unsigned char, CUint256>> children;
|
||||
bool hasValue;
|
||||
CUint256 valHash;
|
||||
};
|
||||
|
||||
struct CClaimTrieProof
|
||||
{
|
||||
CClaimTrieProof() = default;
|
||||
CClaimTrieProof(CClaimTrieProof&&) = default;
|
||||
CClaimTrieProof(const CClaimTrieProof&) = default;
|
||||
CClaimTrieProof& operator=(CClaimTrieProof&&) = default;
|
||||
CClaimTrieProof& operator=(const CClaimTrieProof&) = default;
|
||||
|
||||
std::vector<std::pair<bool, CUint256>> pairs;
|
||||
std::vector<CClaimTrieProofNode> nodes;
|
||||
int nHeightOfLastTakeover = 0;
|
||||
bool hasValue = false;
|
||||
CTxOutPoint outPoint;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using queueEntryType = std::pair<std::string, T>;
|
||||
|
||||
typedef std::vector<queueEntryType<CClaimValue>> claimUndoType;
|
||||
typedef std::vector<queueEntryType<CSupportValue>> supportUndoType;
|
||||
typedef std::vector<CNameOutPointHeightType> insertUndoType;
|
||||
typedef std::vector<queueEntryType<std::pair<int, CUint160>>> takeoverUndoType;
|
||||
|
||||
class CClaimTrieCacheBase
|
||||
{
|
||||
public:
|
||||
explicit CClaimTrieCacheBase(CClaimTrie* base);
|
||||
virtual ~CClaimTrieCacheBase();
|
||||
|
||||
CUint256 getMerkleHash();
|
||||
|
||||
bool flush();
|
||||
bool empty() const;
|
||||
bool checkConsistency();
|
||||
bool ReadFromDisk(int nHeight, const CUint256& rootHash);
|
||||
|
||||
std::size_t getTotalNamesInTrie() const;
|
||||
std::size_t getTotalClaimsInTrie() const;
|
||||
int64_t getTotalValueOfClaimsInTrie(bool fControllingOnly) const;
|
||||
|
||||
bool haveClaim(const std::string& name, const CTxOutPoint& outPoint) const;
|
||||
bool haveClaimInQueue(const std::string& name, const CTxOutPoint& outPoint, int& nValidAtHeight) const;
|
||||
|
||||
bool haveSupport(const std::string& name, const CTxOutPoint& outPoint) const;
|
||||
bool haveSupportInQueue(const std::string& name, const CTxOutPoint& outPoint, int& nValidAtHeight) const;
|
||||
|
||||
bool addClaim(const std::string& name, const CTxOutPoint& outPoint, const CUint160& claimId, int64_t nAmount,
|
||||
int nHeight, int nValidHeight = -1, const std::vector<unsigned char>& metadata = {});
|
||||
|
||||
bool addSupport(const std::string& name, const CTxOutPoint& outPoint, const CUint160& supportedClaimId, int64_t nAmount,
|
||||
int nHeight, int nValidHeight = -1, const std::vector<unsigned char>& metadata = {});
|
||||
|
||||
bool removeClaim(const CUint160& claimId, const CTxOutPoint& outPoint, std::string& nodeName, int& validHeight);
|
||||
bool removeSupport(const CTxOutPoint& outPoint, std::string& nodeName, int& validHeight);
|
||||
|
||||
virtual bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeoverHeightUndo);
|
||||
|
||||
virtual bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportUndoType& expireSupportUndo);
|
||||
|
||||
virtual bool getProofForName(const std::string& name, const CUint160& claim, CClaimTrieProof& proof);
|
||||
virtual bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const;
|
||||
|
||||
virtual int expirationTime() const;
|
||||
|
||||
virtual bool finalizeDecrement(takeoverUndoType& takeoverHeightUndo);
|
||||
|
||||
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
|
||||
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
||||
|
||||
bool findNameForClaim(std::vector<unsigned char> claim, CClaimValue& value, std::string& name);
|
||||
void getNamesInTrie(std::function<void(const std::string&)> callback);
|
||||
bool getLastTakeoverForName(const std::string& name, CUint160& claimId, int& takeoverHeight) const;
|
||||
|
||||
protected:
|
||||
CClaimTrie* base;
|
||||
mutable sqlite::database db;
|
||||
int nNextHeight; // Height of the block that is being worked on, which is
|
||||
bool transacting;
|
||||
mutable std::unordered_set<std::string> removalWorkaround;
|
||||
|
||||
mutable sqlite::database_binder claimHashQuery, childHashQuery;
|
||||
|
||||
virtual CUint256 recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly);
|
||||
supportEntryType getSupportsForName(const std::string& name) const;
|
||||
|
||||
virtual int getDelayForName(const std::string& name, const CUint160& claimId) const;
|
||||
|
||||
bool deleteNodeIfPossible(const std::string& name, std::string& parent, int64_t& claims);
|
||||
void ensureTreeStructureIsUpToDate();
|
||||
|
||||
private:
|
||||
// for unit test
|
||||
friend struct ClaimTrieChainFixture;
|
||||
friend class CClaimTrieCacheTest;
|
||||
|
||||
bool activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo, const std::string& takeover);
|
||||
};
|
||||
|
||||
#endif // CLAIMTRIE_TRIE_H
|
42
src/claimtrie/txoutpoint.cpp
Normal file
42
src/claimtrie/txoutpoint.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
#include <claimtrie/txoutpoint.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
CTxOutPoint::CTxOutPoint(CUint256 hashIn, uint32_t nIn) : hash(std::move(hashIn)), n(nIn)
|
||||
{
|
||||
}
|
||||
|
||||
void CTxOutPoint::SetNull()
|
||||
{
|
||||
hash.SetNull();
|
||||
n = uint32_t(-1);
|
||||
}
|
||||
|
||||
bool CTxOutPoint::IsNull() const
|
||||
{
|
||||
return hash.IsNull() && n == uint32_t(-1);
|
||||
}
|
||||
|
||||
std::string CTxOutPoint::ToString() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "CTxOutPoint(" << hash.ToString().substr(0, 10) << ", " << n << ')';
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
bool operator<(const CTxOutPoint& a, const CTxOutPoint& b)
|
||||
{
|
||||
int cmp = a.hash.Compare(b.hash);
|
||||
return cmp < 0 || (cmp == 0 && a.n < b.n);
|
||||
}
|
||||
|
||||
bool operator==(const CTxOutPoint& a, const CTxOutPoint& b)
|
||||
{
|
||||
return (a.hash == b.hash && a.n == b.n);
|
||||
}
|
||||
|
||||
bool operator!=(const CTxOutPoint& a, const CTxOutPoint& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
37
src/claimtrie/txoutpoint.h
Normal file
37
src/claimtrie/txoutpoint.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
#ifndef CLAIMTRIE_TXOUTPUT_H
|
||||
#define CLAIMTRIE_TXOUTPUT_H
|
||||
|
||||
#include <claimtrie/uints.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
/** An outpoint - a combination of a transaction hash and an index n into its vout */
|
||||
class CTxOutPoint
|
||||
{
|
||||
public:
|
||||
CUint256 hash;
|
||||
uint32_t n = uint32_t(-1);
|
||||
|
||||
CTxOutPoint() = default;
|
||||
CTxOutPoint(CTxOutPoint&&) = default;
|
||||
CTxOutPoint(const CTxOutPoint&) = default;
|
||||
CTxOutPoint(CUint256 hashIn, uint32_t nIn);
|
||||
|
||||
CTxOutPoint& operator=(CTxOutPoint&&) = default;
|
||||
CTxOutPoint& operator=(const CTxOutPoint&) = default;
|
||||
|
||||
void SetNull();
|
||||
bool IsNull() const;
|
||||
|
||||
friend bool operator<(const CTxOutPoint& a, const CTxOutPoint& b);
|
||||
friend bool operator==(const CTxOutPoint& a, const CTxOutPoint& b);
|
||||
friend bool operator!=(const CTxOutPoint& a, const CTxOutPoint& b);
|
||||
|
||||
std::string ToString() const;
|
||||
};
|
||||
|
||||
#endif // CLAIMTRIE_TXOUTPUT_H
|
155
src/claimtrie/uints.cpp
Normal file
155
src/claimtrie/uints.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
|
||||
#include <claimtrie/uints.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
/** Template base class for fixed-sized opaque blobs. */
|
||||
template<uint32_t BITS>
|
||||
CBaseBlob<BITS>::CBaseBlob() : data(std::make_unique<uint8_t[]>(WIDTH))
|
||||
{
|
||||
SetNull();
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
CBaseBlob<BITS>::CBaseBlob(const std::vector<uint8_t>& vec) : data(std::make_unique<uint8_t[]>(WIDTH))
|
||||
{
|
||||
assert(vec.size() == size());
|
||||
std::copy(vec.begin(), vec.end(), begin());
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
CBaseBlob<BITS>::CBaseBlob(const CBaseBlob& o) : data(std::make_unique<uint8_t[]>(WIDTH))
|
||||
{
|
||||
*this = o;
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
CBaseBlob<BITS>& CBaseBlob<BITS>::operator=(const CBaseBlob& o)
|
||||
{
|
||||
if (this != &o)
|
||||
std::copy(o.begin(), o.end(), begin());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
bool CBaseBlob<BITS>::IsNull() const
|
||||
{
|
||||
return std::all_of(begin(), end(), [](uint8_t e) { return e == 0; });
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
void CBaseBlob<BITS>::SetNull()
|
||||
{
|
||||
std::memset(begin(), 0, size());
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
int CBaseBlob<BITS>::Compare(const CBaseBlob& other) const
|
||||
{
|
||||
return std::memcmp(begin(), other.begin(), size());
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
std::string CBaseBlob<BITS>::GetHex() const
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::hex;
|
||||
for (int i = WIDTH - 1; i >= 0; --i)
|
||||
ss << std::setw(2) << std::setfill('0') << uint32_t(data[i]);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
void CBaseBlob<BITS>::SetHex(const char* psz)
|
||||
{
|
||||
SetNull();
|
||||
|
||||
// skip leading spaces
|
||||
while (isspace(*psz))
|
||||
psz++;
|
||||
|
||||
// skip 0x
|
||||
if (psz[0] == '0' && tolower(psz[1]) == 'x')
|
||||
psz += 2;
|
||||
|
||||
auto b = psz;
|
||||
// advance to end
|
||||
while (isxdigit(*psz))
|
||||
psz++;
|
||||
|
||||
--psz;
|
||||
char buf[3] = {};
|
||||
auto it = begin();
|
||||
while (psz >= b && it != end()) {
|
||||
buf[1] = *psz--;
|
||||
buf[0] = psz >= b ? *psz-- : '0';
|
||||
*it++ = std::strtoul(buf, nullptr, 16);
|
||||
}
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
void CBaseBlob<BITS>::SetHex(const std::string& str)
|
||||
{
|
||||
SetHex(str.c_str());
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
std::string CBaseBlob<BITS>::ToString() const
|
||||
{
|
||||
return GetHex();
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
uint8_t* CBaseBlob<BITS>::begin()
|
||||
{
|
||||
return data.get();
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
uint8_t* CBaseBlob<BITS>::end()
|
||||
{
|
||||
return begin() + WIDTH;
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
const uint8_t* CBaseBlob<BITS>::begin() const
|
||||
{
|
||||
return data.get();
|
||||
}
|
||||
|
||||
template<uint32_t BITS>
|
||||
const uint8_t* CBaseBlob<BITS>::end() const
|
||||
{
|
||||
return begin() + WIDTH;
|
||||
}
|
||||
|
||||
CUint160 CUint160S(const char* str)
|
||||
{
|
||||
CUint160 s;
|
||||
s.SetHex(str);
|
||||
return s;
|
||||
}
|
||||
|
||||
CUint160 CUint160S(const std::string& s)
|
||||
{
|
||||
return CUint160S(s.c_str());
|
||||
}
|
||||
|
||||
CUint256 CUint256S(const char* str)
|
||||
{
|
||||
CUint256 s;
|
||||
s.SetHex(str);
|
||||
return s;
|
||||
}
|
||||
|
||||
CUint256 CUint256S(const std::string& s)
|
||||
{
|
||||
return CUint256S(s.c_str());
|
||||
}
|
||||
|
||||
template class CBaseBlob<160>;
|
||||
template class CBaseBlob<256>;
|
59
src/claimtrie/uints.h
Normal file
59
src/claimtrie/uints.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
#ifndef CLAIMTRIE_UINTS_H
|
||||
#define CLAIMTRIE_UINTS_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
/** Template base class for fixed-sized opaque blobs. */
|
||||
template<uint32_t BITS>
|
||||
class CBaseBlob
|
||||
{
|
||||
protected:
|
||||
static constexpr int WIDTH = BITS / 8;
|
||||
std::unique_ptr<uint8_t[]> data;
|
||||
public:
|
||||
CBaseBlob();
|
||||
|
||||
explicit CBaseBlob(const std::vector<uint8_t>& vec);
|
||||
|
||||
CBaseBlob(CBaseBlob&&) = default;
|
||||
CBaseBlob& operator=(CBaseBlob&&) = default;
|
||||
|
||||
CBaseBlob(const CBaseBlob& o);
|
||||
CBaseBlob& operator=(const CBaseBlob& o);
|
||||
|
||||
bool IsNull() const;
|
||||
void SetNull();
|
||||
|
||||
int Compare(const CBaseBlob& other) const;
|
||||
|
||||
friend inline bool operator==(const CBaseBlob& a, const CBaseBlob& b) { return a.Compare(b) == 0; }
|
||||
friend inline bool operator!=(const CBaseBlob& a, const CBaseBlob& b) { return a.Compare(b) != 0; }
|
||||
friend inline bool operator<(const CBaseBlob& a, const CBaseBlob& b) { return a.Compare(b) < 0; }
|
||||
|
||||
std::string GetHex() const;
|
||||
void SetHex(const char* psz);
|
||||
void SetHex(const std::string& str);
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
uint8_t* begin();
|
||||
uint8_t* end();
|
||||
|
||||
const uint8_t* begin() const;
|
||||
const uint8_t* end() const;
|
||||
|
||||
constexpr uint32_t size() const { return WIDTH; }
|
||||
};
|
||||
|
||||
typedef CBaseBlob<160> CUint160;
|
||||
typedef CBaseBlob<256> CUint256;
|
||||
|
||||
CUint160 CUint160S(const char* str);
|
||||
CUint160 CUint160S(const std::string& s);
|
||||
|
||||
CUint256 CUint256S(const char* str);
|
||||
CUint256 CUint256S(const std::string& s);
|
||||
|
||||
#endif // CLAIMTRIE_UINTS_H
|
105
src/claimtrie_serial.h
Normal file
105
src/claimtrie_serial.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
|
||||
#ifndef CLAIMTRIE_SERIAL_H
|
||||
#define CLAIMTRIE_SERIAL_H
|
||||
|
||||
#include <claimtrie/data.h>
|
||||
#include <claimtrie/txoutpoint.h>
|
||||
#include <claimtrie/uints.h>
|
||||
|
||||
template<typename Stream, uint32_t BITS>
|
||||
void Serialize(Stream& s, const CBaseBlob<BITS>& u)
|
||||
{
|
||||
s.write((const char*)u.begin(), u.size());
|
||||
}
|
||||
|
||||
template<typename Stream, uint32_t BITS>
|
||||
void Unserialize(Stream& s, CBaseBlob<BITS>& u)
|
||||
{
|
||||
s.read((char*)u.begin(), u.size());
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s, const CTxOutPoint& u)
|
||||
{
|
||||
Serialize(s, u.hash);
|
||||
Serialize(s, u.n);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s, CTxOutPoint& u)
|
||||
{
|
||||
Unserialize(s, u.hash);
|
||||
Unserialize(s, u.n);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s, const CClaimValue& u)
|
||||
{
|
||||
Serialize(s, u.outPoint);
|
||||
Serialize(s, u.claimId);
|
||||
Serialize(s, u.nAmount);
|
||||
Serialize(s, u.nHeight);
|
||||
Serialize(s, u.nValidAtHeight);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s, CClaimValue& u)
|
||||
{
|
||||
Unserialize(s, u.outPoint);
|
||||
Unserialize(s, u.claimId);
|
||||
Unserialize(s, u.nAmount);
|
||||
Unserialize(s, u.nHeight);
|
||||
Unserialize(s, u.nValidAtHeight);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s, const CSupportValue& u)
|
||||
{
|
||||
Serialize(s, u.outPoint);
|
||||
Serialize(s, u.supportedClaimId);
|
||||
Serialize(s, u.nAmount);
|
||||
Serialize(s, u.nHeight);
|
||||
Serialize(s, u.nValidAtHeight);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s, CSupportValue& u)
|
||||
{
|
||||
Unserialize(s, u.outPoint);
|
||||
Unserialize(s, u.supportedClaimId);
|
||||
Unserialize(s, u.nAmount);
|
||||
Unserialize(s, u.nHeight);
|
||||
Unserialize(s, u.nValidAtHeight);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s, const CNameOutPointHeightType& u)
|
||||
{
|
||||
Serialize(s, u.name);
|
||||
Serialize(s, u.outPoint);
|
||||
Serialize(s, u.nValidHeight);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s, CNameOutPointHeightType& u)
|
||||
{
|
||||
Unserialize(s, u.name);
|
||||
Unserialize(s, u.outPoint);
|
||||
Unserialize(s, u.nValidHeight);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s, const CClaimIndexElement& u)
|
||||
{
|
||||
Serialize(s, u.name);
|
||||
Serialize(s, u.claim);
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
void Unserialize(Stream& s, CClaimIndexElement& u)
|
||||
{
|
||||
Unserialize(s, u.name);
|
||||
Unserialize(s, u.claim);
|
||||
}
|
||||
|
||||
#endif // CLAIMTRIE_SERIAL_H
|
|
@ -78,9 +78,6 @@ struct Params {
|
|||
int nAllowMinDiffMaxHeight;
|
||||
int nNormalizedNameForkHeight;
|
||||
|
||||
int nMinTakeoverWorkaroundHeight;
|
||||
int nMaxTakeoverWorkaroundHeight;
|
||||
|
||||
int nWitnessForkHeight;
|
||||
|
||||
int64_t nPowTargetSpacing;
|
||||
|
|
25
src/init.cpp
25
src/init.cpp
|
@ -14,7 +14,7 @@
|
|||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <checkpoints.h>
|
||||
#include <claimtrie.h>
|
||||
#include <claimtrie/forks.h>
|
||||
#include <compat/sanity.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <fs.h>
|
||||
|
@ -1455,7 +1455,16 @@ bool AppInitMain()
|
|||
pblocktree.reset();
|
||||
pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, false, fReset));
|
||||
delete pclaimTrie;
|
||||
pclaimTrie = new CClaimTrie(fReindex || fReindexChainState, 0);
|
||||
auto& consensus = chainparams.GetConsensus();
|
||||
if (g_logger->Enabled() && LogAcceptCategory(BCLog::CLAIMS))
|
||||
CLogPrint::global().setLogger(g_logger);
|
||||
pclaimTrie = new CClaimTrie(fReindex || fReindexChainState, 0,
|
||||
consensus.nNormalizedNameForkHeight,
|
||||
consensus.nOriginalClaimExpirationTime,
|
||||
consensus.nExtendedClaimExpirationTime,
|
||||
consensus.nExtendedClaimExpirationForkHeight,
|
||||
consensus.nAllClaimsInMerkleForkHeight,
|
||||
32);
|
||||
|
||||
if (fReset) {
|
||||
pblocktree->WriteReindexing(true);
|
||||
|
@ -1528,12 +1537,12 @@ bool AppInitMain()
|
|||
}
|
||||
assert(chainActive.Tip() != nullptr);
|
||||
}
|
||||
{
|
||||
CClaimTrieCache trieCache(pclaimTrie);
|
||||
if (!trieCache.ValidateTipMatches(chainActive.Tip())) {
|
||||
strLoadError = _("Error loading the claim trie from disk");
|
||||
break;
|
||||
}
|
||||
auto tip = chainActive.Tip();
|
||||
assert(tip);
|
||||
CClaimTrieCache trieCache(pclaimTrie);
|
||||
if (!trieCache.ReadFromDisk(tip->nHeight, tip->hashClaimTrie)) {
|
||||
strLoadError = _("Error loading the claim trie from disk");
|
||||
break;
|
||||
}
|
||||
if (!fReset) {
|
||||
// Note that RewindBlockIndex MUST run even if we're about to -reindex-chainstate.
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include <cstdio>
|
||||
|
||||
uint32_t g_memfileSize = 0;
|
||||
|
||||
unsigned int CalculateLbryNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
|
||||
{
|
||||
if (params.fPowNoRetargeting)
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
|
||||
extern uint32_t g_memfileSize;
|
||||
unsigned int CalculateLbryNextWorkRequired(const CBlockIndex* pindexLast, int64_t nLastRetargetTime, const Consensus::Params& params);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef BITCOIN_LOGGING_H
|
||||
#define BITCOIN_LOGGING_H
|
||||
|
||||
#include <claimtrie/log.h>
|
||||
#include <fs.h>
|
||||
#include <tinyformat.h>
|
||||
|
||||
|
@ -57,7 +58,7 @@ namespace BCLog {
|
|||
ALL = ~(uint32_t)0,
|
||||
};
|
||||
|
||||
class Logger
|
||||
class Logger : public ClogBase
|
||||
{
|
||||
private:
|
||||
FILE* m_fileout = nullptr;
|
||||
|
@ -87,7 +88,7 @@ namespace BCLog {
|
|||
std::atomic<bool> m_reopen_file{false};
|
||||
|
||||
/** Send a string to the log output */
|
||||
void LogPrintStr(const std::string &str);
|
||||
void LogPrintStr(const std::string &str) override;
|
||||
|
||||
/** Returns whether logs will be written to any output */
|
||||
bool Enabled() const { return m_print_to_console || m_print_to_file; }
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <claimscriptop.h>
|
||||
#include <claimtrie/forks.h>
|
||||
#include <coins.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <consensus/tx_verify.h>
|
||||
|
@ -204,7 +205,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
|||
{
|
||||
CClaimTrieCache trieCache(pclaimTrie);
|
||||
blockToCache(pblock, trieCache, nHeight);
|
||||
pblock->hashClaimTrie = trieCache.getMerkleHash();
|
||||
pblock->hashClaimTrie = uint256(trieCache.getMerkleHash());
|
||||
}
|
||||
CValidationState state;
|
||||
if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) {
|
||||
|
|
|
@ -68,14 +68,10 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector<std::vector
|
|||
op = -1;
|
||||
opcodetype opcode;
|
||||
if (!scriptIn.GetOp(pc, opcode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opcode != OP_CLAIM_NAME && opcode != OP_SUPPORT_CLAIM && opcode != OP_UPDATE_CLAIM)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
op = opcode;
|
||||
|
||||
|
@ -90,57 +86,40 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector<std::vector
|
|||
// All others are invalid.
|
||||
|
||||
if (!scriptIn.GetOp(pc, opcode, vchParam1) || opcode < 0 || opcode > OP_PUSHDATA4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!scriptIn.GetOp(pc, opcode, vchParam2) || opcode < 0 || opcode > OP_PUSHDATA4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (op == OP_UPDATE_CLAIM || op == OP_SUPPORT_CLAIM)
|
||||
{
|
||||
static const size_t claimIdHashSize = sizeof(uint160);
|
||||
if (vchParam2.size() != claimIdHashSize) {
|
||||
if (vchParam2.size() != sizeof(uint160))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!scriptIn.GetOp(pc, opcode, vchParam3))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto last_drop = OP_DROP;
|
||||
if (opcode >= 0 && opcode <= OP_PUSHDATA4 && op != OP_CLAIM_NAME)
|
||||
{
|
||||
if (opcode >= 0 && opcode <= OP_PUSHDATA4 && op != OP_CLAIM_NAME) {
|
||||
if (!scriptIn.GetOp(pc, opcode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
last_drop = OP_2DROP;
|
||||
}
|
||||
else if (op == OP_UPDATE_CLAIM)
|
||||
{
|
||||
} else if (op == OP_UPDATE_CLAIM)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opcode != OP_2DROP)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!scriptIn.GetOp(pc, opcode) || opcode != last_drop)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (op == OP_SUPPORT_CLAIM && last_drop == OP_2DROP && !allowSupportMetadata)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
vvchParams.push_back(std::move(vchParam1));
|
||||
vvchParams.push_back(std::move(vchParam2));
|
||||
if (last_drop == OP_2DROP)
|
||||
{
|
||||
vvchParams.push_back(std::move(vchParam3));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -164,9 +143,7 @@ CScript StripClaimScriptPrefix(const CScript& scriptIn, int& op)
|
|||
CScript::const_iterator pc = scriptIn.begin();
|
||||
|
||||
if (!DecodeClaimScript(scriptIn, op, vvchParams, pc))
|
||||
{
|
||||
return scriptIn;
|
||||
}
|
||||
|
||||
return CScript(pc, scriptIn.end());
|
||||
}
|
||||
|
@ -183,31 +160,21 @@ size_t ClaimNameSize(const CScript& scriptIn)
|
|||
CScript::const_iterator pc = scriptIn.begin();
|
||||
int op;
|
||||
if (!DecodeClaimScript(scriptIn, op, vvchParams, pc))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return vvchParams[0].size();
|
||||
}
|
||||
return vvchParams[0].size();
|
||||
}
|
||||
|
||||
CAmount CalcMinClaimTrieFee(const CTransaction& tx, const CAmount &minFeePerNameClaimChar)
|
||||
{
|
||||
if (minFeePerNameClaimChar == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
CAmount min_fee = 0;
|
||||
for (const CTxOut& txout: tx.vout)
|
||||
{
|
||||
for (const CTxOut& txout: tx.vout) {
|
||||
int op;
|
||||
std::vector<std::vector<unsigned char> > vvchParams;
|
||||
if (DecodeClaimScript(txout.scriptPubKey, op, vvchParams))
|
||||
{
|
||||
if (op == OP_CLAIM_NAME)
|
||||
{
|
||||
if (DecodeClaimScript(txout.scriptPubKey, op, vvchParams)) {
|
||||
if (op == OP_CLAIM_NAME) {
|
||||
int claim_name_size = vvchParams[0].size();
|
||||
min_fee += claim_name_size*minFeePerNameClaimChar;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <amount.h>
|
||||
#include <claimtrie/txoutpoint.h>
|
||||
#include <script/script.h>
|
||||
#include <serialize.h>
|
||||
#include <uint256.h>
|
||||
|
@ -22,6 +23,7 @@ public:
|
|||
uint32_t n;
|
||||
|
||||
COutPoint(): n((uint32_t) -1) { }
|
||||
explicit COutPoint(const CTxOutPoint& c) : hash(c.hash), n(c.n) { }
|
||||
COutPoint(const uint256& hashIn, uint32_t nIn): hash(hashIn), n(nIn) { }
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
@ -52,6 +54,11 @@ public:
|
|||
}
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
operator CTxOutPoint() const
|
||||
{
|
||||
return CTxOutPoint{hash, n};
|
||||
}
|
||||
};
|
||||
|
||||
/** An input of a transaction. It contains the location of the previous
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <claimtrie.h>
|
||||
|
||||
#include <claimtrie/forks.h>
|
||||
#include <coins.h>
|
||||
#include <core_io.h>
|
||||
#include <key_io.h>
|
||||
|
@ -20,13 +21,6 @@
|
|||
|
||||
static constexpr size_t claimIdHexLength = 40;
|
||||
|
||||
uint160 uint160S(const std::string& str)
|
||||
{
|
||||
uint160 s;
|
||||
s.SetHex(str);
|
||||
return s;
|
||||
}
|
||||
|
||||
void ParseClaimtrieId(const UniValue& v, std::string& claimId, const std::string& strName)
|
||||
{
|
||||
// use IsHexNumber which verify odd strings size
|
||||
|
@ -137,7 +131,7 @@ std::vector<CClaimNsupports> seqSort(const std::vector<CClaimNsupports>& source)
|
|||
return claimsNsupports;
|
||||
}
|
||||
|
||||
std::size_t indexOf(const std::vector<CClaimNsupports>& source, const uint160& claimId)
|
||||
std::size_t indexOf(const std::vector<CClaimNsupports>& source, const CUint160& claimId)
|
||||
{
|
||||
auto it = std::find_if(source.begin(), source.end(), [&claimId](const CClaimNsupports& claimNsupports) {
|
||||
return claimNsupports.claim.claimId == claimId;
|
||||
|
@ -150,7 +144,7 @@ UniValue claimToJSON(const CCoinsViewCache& coinsCache, const CClaimValue& claim
|
|||
{
|
||||
UniValue result(UniValue::VOBJ);
|
||||
|
||||
auto& coin = coinsCache.AccessCoin(claim.outPoint);
|
||||
auto& coin = coinsCache.AccessCoin(COutPoint(claim.outPoint));
|
||||
if (!coin.IsSpent()) {
|
||||
std::string name, value;
|
||||
if (extractValue(coin.out.scriptPubKey, name, value)) {
|
||||
|
@ -177,7 +171,7 @@ UniValue supportToJSON(const CCoinsViewCache& coinsCache, const CSupportValue& s
|
|||
{
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
auto& coin = coinsCache.AccessCoin(support.outPoint);
|
||||
auto& coin = coinsCache.AccessCoin(COutPoint(support.outPoint));
|
||||
if (!coin.IsSpent()) {
|
||||
std::string name, value;
|
||||
if (extractValue(coin.out.scriptPubKey, name, value)) {
|
||||
|
@ -296,7 +290,7 @@ static UniValue getvalueforname(const JSONRPCRequest& request)
|
|||
return ret;
|
||||
|
||||
auto& claimNsupports =
|
||||
claimId.length() == claimIdHexLength ? csToName.find(uint160S(claimId)) :
|
||||
claimId.length() == claimIdHexLength ? csToName.find(CUint160S(claimId)) :
|
||||
!claimId.empty() ? csToName.find(claimId) : csToName.claimsNsupports[0];
|
||||
|
||||
if (claimNsupports.IsNull())
|
||||
|
@ -546,11 +540,11 @@ UniValue getclaimsfortx(const JSONRPCRequest& request)
|
|||
std::string sName(vvchParams[0].begin(), vvchParams[0].end());
|
||||
o.pushKV(T_NAME, escapeNonUtf8(sName));
|
||||
if (op == OP_CLAIM_NAME) {
|
||||
uint160 claimId = ClaimIdHash(hash, i);
|
||||
CUint160 claimId = ClaimIdHash(hash, i);
|
||||
o.pushKV(T_CLAIMID, claimId.GetHex());
|
||||
o.pushKV(T_VALUE, HexStr(vvchParams[1].begin(), vvchParams[1].end()));
|
||||
} else if (op == OP_UPDATE_CLAIM || op == OP_SUPPORT_CLAIM) {
|
||||
uint160 claimId(vvchParams[1]);
|
||||
CUint160 claimId(vvchParams[1]);
|
||||
o.pushKV(T_CLAIMID, claimId.GetHex());
|
||||
if (vvchParams.size() > 2)
|
||||
o.pushKV(T_VALUE, HexStr(vvchParams[2].begin(), vvchParams[2].end()));
|
||||
|
@ -755,7 +749,7 @@ UniValue removedToJSON(const std::vector<queueEntryType<T>>& undo)
|
|||
{
|
||||
UniValue ret(UniValue::VARR);
|
||||
for (auto& u : undo) {
|
||||
auto& outPoint = u.second.outPoint;
|
||||
auto outPoint = COutPoint(u.second.outPoint);
|
||||
ret.push_back(ClaimIdHash(outPoint.hash, outPoint.n).ToString());
|
||||
}
|
||||
return ret;
|
||||
|
@ -780,7 +774,7 @@ UniValue getchangesinblock(const JSONRPCRequest& request)
|
|||
auto addedUpdated = [](const insertUndoType& insertUndo) {
|
||||
UniValue added(UniValue::VARR);
|
||||
for (auto& a : insertUndo)
|
||||
added.push_back(ClaimIdHash(a.outPoint.hash, a.outPoint.n).ToString());
|
||||
added.push_back(ClaimIdHash(uint256(a.outPoint.hash), a.outPoint.n).ToString());
|
||||
return added;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <claimtrie_serial.h>
|
||||
#include <ios>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
|
|
|
@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(takeover_stability_test) {
|
|||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "@bass", "two", 2);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(fixture.is_best_claim("@bass", tx2));
|
||||
uint160 id; int takeover;
|
||||
CUint160 id; int takeover;
|
||||
BOOST_REQUIRE(fixture.getLastTakeoverForName("@bass", id, takeover));
|
||||
auto height = chainActive.Tip()->nHeight;
|
||||
BOOST_CHECK_EQUAL(takeover, height);
|
||||
|
@ -426,7 +426,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_takeover_test)
|
|||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "test", "one", 5);
|
||||
auto cid = ClaimIdHash(tx1.GetHash(), 0);
|
||||
fixture.IncrementBlocks(1);
|
||||
uint160 cid2;
|
||||
CUint160 cid2;
|
||||
int takeover;
|
||||
int height = chainActive.Tip()->nHeight;
|
||||
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||
|
@ -1148,7 +1148,7 @@ BOOST_AUTO_TEST_CASE(basic_merkle_test)
|
|||
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName, sValue, 10);
|
||||
fixture.IncrementBlocks(20);
|
||||
uint256 tx1MerkleHash = fixture.getMerkleHash();
|
||||
auto tx1MerkleHash = fixture.getMerkleHash();
|
||||
fixture.DecrementBlocks(20);
|
||||
BOOST_CHECK(tx1MerkleHash != fixture.getMerkleHash());
|
||||
fixture.CommitTx(tx1);
|
||||
|
@ -1230,7 +1230,7 @@ BOOST_AUTO_TEST_CASE(supporting_claims_test)
|
|||
BOOST_CHECK(fixture.getInfoForName(sName, val));
|
||||
BOOST_CHECK_EQUAL(val.outPoint.hash, tx1.GetHash());
|
||||
BOOST_CHECK_EQUAL(val.outPoint.n, 0);
|
||||
uint256 tx1MerkleHash = fixture.getMerkleHash();
|
||||
auto tx1MerkleHash = fixture.getMerkleHash();
|
||||
|
||||
CMutableTransaction tx4 = BuildTransaction(tx1);
|
||||
CMutableTransaction tx5 = BuildTransaction(tx2);
|
||||
|
@ -1553,7 +1553,7 @@ BOOST_AUTO_TEST_CASE(supporting_claims2_test)
|
|||
fixture.CommitTx(tx2);
|
||||
fixture.IncrementBlocks(1); // 7
|
||||
|
||||
uint256 rootMerkleHash = fixture.getMerkleHash();
|
||||
auto rootMerkleHash = fixture.getMerkleHash();
|
||||
|
||||
BOOST_CHECK(!pclaimTrie->empty());
|
||||
BOOST_CHECK(!fixture.queueEmpty());
|
||||
|
@ -1920,7 +1920,7 @@ BOOST_AUTO_TEST_CASE(update_on_support2_test)
|
|||
CMutableTransaction s2 = fixture.MakeSupport(fixture.GetCoinbase(), tx1, name, 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
uint160 claimId;
|
||||
CUint160 claimId;
|
||||
int lastTakeover;
|
||||
BOOST_CHECK(fixture.getLastTakeoverForName(name, claimId, lastTakeover));
|
||||
BOOST_CHECK_EQUAL(lastTakeover, height + 1);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <claimtrie.h>
|
||||
|
||||
#include <claimtrie/forks.h>
|
||||
#include <nameclaim.h>
|
||||
#include <uint256.h>
|
||||
#include <validation.h>
|
||||
|
@ -24,12 +25,12 @@ public:
|
|||
p.hash = Hash(key.begin(), key.end());
|
||||
auto c = value.claimId;
|
||||
if (c.IsNull())
|
||||
c = ClaimIdHash(p.hash, p.n);
|
||||
c = ClaimIdHash(uint256(p.hash), p.n);
|
||||
|
||||
return addClaim(key, p, c, value.nAmount, value.nHeight);
|
||||
}
|
||||
|
||||
bool removeClaimFromTrie(const std::string& key, const COutPoint& outPoint) {
|
||||
bool removeClaimFromTrie(const std::string& key, const CTxOutPoint& outPoint) {
|
||||
int validHeight;
|
||||
std::string nodeName;
|
||||
|
||||
|
@ -37,7 +38,7 @@ public:
|
|||
if (p.hash.IsNull())
|
||||
p.hash = Hash(key.begin(), key.end());
|
||||
|
||||
auto ret = removeClaim(ClaimIdHash(p.hash, p.n), p, nodeName, validHeight);
|
||||
auto ret = removeClaim(ClaimIdHash(uint256(p.hash), p.n), p, nodeName, validHeight);
|
||||
assert(!ret || nodeName == key);
|
||||
return ret;
|
||||
}
|
||||
|
@ -47,10 +48,10 @@ public:
|
|||
if (p.hash.IsNull())
|
||||
p.hash = Hash(key.begin(), key.end());
|
||||
|
||||
return addSupport(key, p, value.nAmount, value.supportedClaimId, value.nHeight);
|
||||
return addSupport(key, p, value.supportedClaimId, value.nAmount, value.nHeight);
|
||||
}
|
||||
|
||||
bool removeSupportFromMap(const std::string& key, const COutPoint& outPoint) {
|
||||
bool removeSupportFromMap(const std::string& key, const CTxOutPoint& outPoint) {
|
||||
int validHeight;
|
||||
std::string nodeName;
|
||||
|
||||
|
@ -69,7 +70,7 @@ BOOST_FIXTURE_TEST_SUITE(claimtriecache_tests, RegTestingSetup)
|
|||
BOOST_AUTO_TEST_CASE(merkle_hash_single_test)
|
||||
{
|
||||
// check empty trie
|
||||
uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||
auto one = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
|
||||
CClaimTrieCacheTest cc(pclaimTrie);
|
||||
BOOST_CHECK_EQUAL(one, cc.getMerkleHash());
|
||||
|
||||
|
@ -80,30 +81,31 @@ BOOST_AUTO_TEST_CASE(merkle_hash_single_test)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
|
||||
{
|
||||
uint256 hash0(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||
auto hash0 = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
|
||||
CUint160 hash160;
|
||||
CMutableTransaction tx1 = BuildTransaction(hash0);
|
||||
COutPoint tx1OutPoint(tx1.GetHash(), 0);
|
||||
CTxOutPoint tx1OutPoint(tx1.GetHash(), 0);
|
||||
CMutableTransaction tx2 = BuildTransaction(tx1.GetHash());
|
||||
COutPoint tx2OutPoint(tx2.GetHash(), 0);
|
||||
CTxOutPoint tx2OutPoint(tx2.GetHash(), 0);
|
||||
CMutableTransaction tx3 = BuildTransaction(tx2.GetHash());
|
||||
COutPoint tx3OutPoint(tx3.GetHash(), 0);
|
||||
CTxOutPoint tx3OutPoint(tx3.GetHash(), 0);
|
||||
CMutableTransaction tx4 = BuildTransaction(tx3.GetHash());
|
||||
COutPoint tx4OutPoint(tx4.GetHash(), 0);
|
||||
CTxOutPoint tx4OutPoint(tx4.GetHash(), 0);
|
||||
CMutableTransaction tx5 = BuildTransaction(tx4.GetHash());
|
||||
COutPoint tx5OutPoint(tx5.GetHash(), 0);
|
||||
CTxOutPoint tx5OutPoint(tx5.GetHash(), 0);
|
||||
CMutableTransaction tx6 = BuildTransaction(tx5.GetHash());
|
||||
COutPoint tx6OutPoint(tx6.GetHash(), 0);
|
||||
CTxOutPoint tx6OutPoint(tx6.GetHash(), 0);
|
||||
|
||||
uint256 hash1;
|
||||
CUint256 hash1;
|
||||
hash1.SetHex("71c7b8d35b9a3d7ad9a1272b68972979bbd18589f1efe6f27b0bf260a6ba78fa");
|
||||
|
||||
uint256 hash2;
|
||||
CUint256 hash2;
|
||||
hash2.SetHex("c4fc0e2ad56562a636a0a237a96a5f250ef53495c2cb5edd531f087a8de83722");
|
||||
|
||||
uint256 hash3;
|
||||
CUint256 hash3;
|
||||
hash3.SetHex("baf52472bd7da19fe1e35116cfb3bd180d8770ffbe3ae9243df1fb58a14b0975");
|
||||
|
||||
uint256 hash4;
|
||||
CUint256 hash4;
|
||||
hash4.SetHex("c73232a755bf015f22eaa611b283ff38100f2a23fb6222e86eca363452ba0c51");
|
||||
|
||||
CClaimTrie master(false, 2, 1);
|
||||
|
@ -212,10 +214,10 @@ BOOST_AUTO_TEST_CASE(basic_insertion_info_test)
|
|||
CClaimTrieCacheTest ctc(pclaimTrie);
|
||||
|
||||
// create and insert claim
|
||||
uint256 hash0(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||
auto hash0 = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
|
||||
CMutableTransaction tx1 = BuildTransaction(hash0);
|
||||
uint160 claimId = ClaimIdHash(tx1.GetHash(), 0);
|
||||
COutPoint claimOutPoint(tx1.GetHash(), 0);
|
||||
CUint160 claimId = ClaimIdHash(tx1.GetHash(), 0);
|
||||
CTxOutPoint claimOutPoint(tx1.GetHash(), 0);
|
||||
CAmount amount(10);
|
||||
int height = 0;
|
||||
int validHeight = 0;
|
||||
|
@ -236,9 +238,9 @@ BOOST_AUTO_TEST_CASE(basic_insertion_info_test)
|
|||
|
||||
// insert a support
|
||||
CAmount supportAmount(10);
|
||||
uint256 hash1(uint256S("0000000000000000000000000000000000000000000000000000000000000002"));
|
||||
auto hash1 = uint256S("0000000000000000000000000000000000000000000000000000000000000002");
|
||||
CMutableTransaction tx2 = BuildTransaction(hash1);
|
||||
COutPoint supportOutPoint(tx2.GetHash(), 0);
|
||||
CTxOutPoint supportOutPoint(tx2.GetHash(), 0);
|
||||
|
||||
CSupportValue support(supportOutPoint, claimId, supportAmount, height, validHeight);
|
||||
ctc.insertSupportIntoMap("test", support);
|
||||
|
@ -256,7 +258,7 @@ BOOST_AUTO_TEST_CASE(basic_insertion_info_test)
|
|||
// CClaimTrieCacheTest cc(pclaimTrie);
|
||||
// BOOST_CHECK_EQUAL(0, cc.getTotalClaimsInTrie());
|
||||
//
|
||||
// COutPoint outpoint;
|
||||
// CTxOutPoint outpoint;
|
||||
// uint160 claimId;
|
||||
// CAmount amount(20);
|
||||
// int height = 0;
|
||||
|
@ -302,14 +304,13 @@ BOOST_AUTO_TEST_CASE(trie_stays_consistent_test)
|
|||
"goodness", "goodnight", "goodnatured", "goods", "go", "goody", "goo"
|
||||
};
|
||||
|
||||
CClaimTrie trie(false, 0, 1);
|
||||
CClaimTrieCacheTest cache(&trie);
|
||||
CClaimTrieCacheTest cache(pclaimTrie);
|
||||
CClaimValue value;
|
||||
|
||||
for (auto& name: names) {
|
||||
value.outPoint.hash = Hash(name.begin(), name.end());
|
||||
value.outPoint.n = 0;
|
||||
value.claimId = ClaimIdHash(value.outPoint.hash, 0);
|
||||
value.claimId = ClaimIdHash(uint256(value.outPoint.hash), 0);
|
||||
BOOST_CHECK(cache.insertClaimIntoTrie(name, value));
|
||||
}
|
||||
|
||||
|
@ -318,17 +319,17 @@ BOOST_AUTO_TEST_CASE(trie_stays_consistent_test)
|
|||
|
||||
for (auto& name: names) {
|
||||
auto hash = Hash(name.begin(), name.end());
|
||||
BOOST_CHECK(cache.removeClaimFromTrie(name, COutPoint(hash, 0)));
|
||||
BOOST_CHECK(cache.removeClaimFromTrie(name, CTxOutPoint(hash, 0)));
|
||||
cache.flush();
|
||||
BOOST_CHECK(cache.checkConsistency());
|
||||
}
|
||||
BOOST_CHECK(trie.empty());
|
||||
BOOST_CHECK(pclaimTrie->empty());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(verify_basic_serialization)
|
||||
{
|
||||
CClaimValue cv;
|
||||
cv.outPoint = COutPoint(uint256S("123"), 2);
|
||||
cv.outPoint = CTxOutPoint(CUint256S("123"), 2);
|
||||
cv.nHeight = 3;
|
||||
cv.claimId.SetHex("4567");
|
||||
cv.nEffectiveAmount = 4;
|
||||
|
|
|
@ -276,7 +276,8 @@ BOOST_AUTO_TEST_CASE(hardfork_disk_test)
|
|||
BOOST_CHECK_EQUAL(fixture.expirationTime(), 3);
|
||||
fixture.IncrementBlocks(7, true);
|
||||
BOOST_CHECK_EQUAL(fixture.expirationTime(), 6);
|
||||
fixture.ValidateTipMatches(chainActive.Tip());
|
||||
auto tip = chainActive.Tip();
|
||||
fixture.ReadFromDisk(tip->nHeight, tip->hashClaimTrie);
|
||||
BOOST_CHECK_EQUAL(fixture.expirationTime(), 6);
|
||||
|
||||
// Create a claim and support 1 block before the fork height that will expire after the fork height.
|
||||
|
@ -287,7 +288,8 @@ BOOST_AUTO_TEST_CASE(hardfork_disk_test)
|
|||
CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(), tx1, "test", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
fixture.ValidateTipMatches(chainActive.Tip());
|
||||
tip = chainActive.Tip();
|
||||
fixture.ReadFromDisk(tip->nHeight, tip->hashClaimTrie);
|
||||
BOOST_CHECK_EQUAL(fixture.expirationTime(), 3);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK_EQUAL(fixture.expirationTime(), 6);
|
||||
|
@ -308,7 +310,8 @@ BOOST_AUTO_TEST_CASE(hardfork_disk_test)
|
|||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(),"test2","one",1);
|
||||
CMutableTransaction s2 = fixture.MakeSupport(fixture.GetCoinbase(),tx2,"test2",1);
|
||||
fixture.IncrementBlocks(1);
|
||||
fixture.ValidateTipMatches(chainActive.Tip());
|
||||
tip = chainActive.Tip();
|
||||
fixture.ReadFromDisk(tip->nHeight, tip->hashClaimTrie);
|
||||
CMutableTransaction u2 = fixture.MakeUpdate(tx2, "test2", "two", ClaimIdHash(tx2.GetHash(), 0), 1);
|
||||
// increment to fork
|
||||
fixture.IncrementBlocks(2);
|
||||
|
@ -503,7 +506,7 @@ BOOST_AUTO_TEST_CASE(claim_expiration_test)
|
|||
BOOST_CHECK(!fixture.expirationQueueEmpty());
|
||||
BOOST_CHECK(fixture.getInfoForName(sName, val));
|
||||
BOOST_CHECK_EQUAL(val.outPoint, tx1OutPoint);
|
||||
uint256 tx1MerkleHash = fixture.getMerkleHash();
|
||||
auto tx1MerkleHash = fixture.getMerkleHash();
|
||||
|
||||
// roll back to before tx3 is valid
|
||||
fixture.DecrementBlocks(1); // 10
|
||||
|
@ -601,7 +604,7 @@ BOOST_AUTO_TEST_CASE(expiring_supports_test)
|
|||
BOOST_CHECK(!fixture.queueEmpty());
|
||||
BOOST_CHECK(!fixture.supportEmpty());
|
||||
BOOST_CHECK(fixture.supportQueueEmpty());
|
||||
uint256 rootMerkleHash = fixture.getMerkleHash();
|
||||
auto rootMerkleHash = fixture.getMerkleHash();
|
||||
|
||||
// Advance until tx2 is valid
|
||||
fixture.IncrementBlocks(20); // 42
|
||||
|
|
|
@ -95,16 +95,22 @@ ClaimTrieChainFixture::~ClaimTrieChainFixture()
|
|||
added_unchecked = false;
|
||||
DecrementBlocks(chainActive.Height());
|
||||
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
||||
if (normalization_original >= 0)
|
||||
if (normalization_original >= 0) {
|
||||
consensus.nNormalizedNameForkHeight = normalization_original;
|
||||
|
||||
const_cast<int&>(base->nNormalizedNameForkHeight) = normalization_original;
|
||||
}
|
||||
if (expirationForkHeight >= 0) {
|
||||
consensus.nExtendedClaimExpirationForkHeight = expirationForkHeight;
|
||||
consensus.nExtendedClaimExpirationTime = extendedExpiration;
|
||||
consensus.nOriginalClaimExpirationTime = originalExpiration;
|
||||
const_cast<int64_t&>(base->nExtendedClaimExpirationForkHeight) = expirationForkHeight;
|
||||
const_cast<int64_t&>(base->nOriginalClaimExpirationTime) = originalExpiration;
|
||||
const_cast<int64_t&>(base->nExtendedClaimExpirationTime) = extendedExpiration;
|
||||
}
|
||||
if (forkhash_original >= 0)
|
||||
if (forkhash_original >= 0) {
|
||||
consensus.nAllClaimsInMerkleForkHeight = forkhash_original;
|
||||
const_cast<int64_t&>(base->nAllClaimsInMerkleForkHeight) = forkhash_original;
|
||||
}
|
||||
}
|
||||
|
||||
void ClaimTrieChainFixture::setExpirationForkHeight(int targetMinusCurrent, int64_t preForkExpirationTime, int64_t postForkExpirationTime)
|
||||
|
@ -119,7 +125,9 @@ void ClaimTrieChainFixture::setExpirationForkHeight(int targetMinusCurrent, int6
|
|||
consensus.nExtendedClaimExpirationForkHeight = target;
|
||||
consensus.nExtendedClaimExpirationTime = postForkExpirationTime;
|
||||
consensus.nOriginalClaimExpirationTime = preForkExpirationTime;
|
||||
setExpirationTime(targetMinusCurrent >= 0 ? preForkExpirationTime : postForkExpirationTime);
|
||||
const_cast<int64_t&>(base->nExtendedClaimExpirationForkHeight) = target;
|
||||
const_cast<int64_t&>(base->nOriginalClaimExpirationTime) = preForkExpirationTime;
|
||||
const_cast<int64_t&>(base->nExtendedClaimExpirationTime) = postForkExpirationTime;
|
||||
}
|
||||
|
||||
void ClaimTrieChainFixture::setNormalizationForkHeight(int targetMinusCurrent)
|
||||
|
@ -129,6 +137,7 @@ void ClaimTrieChainFixture::setNormalizationForkHeight(int targetMinusCurrent)
|
|||
if (normalization_original < 0)
|
||||
normalization_original = consensus.nNormalizedNameForkHeight;
|
||||
consensus.nNormalizedNameForkHeight = target;
|
||||
const_cast<int&>(base->nNormalizedNameForkHeight) = target;
|
||||
}
|
||||
|
||||
void ClaimTrieChainFixture::setHashForkHeight(int targetMinusCurrent)
|
||||
|
@ -138,6 +147,7 @@ void ClaimTrieChainFixture::setHashForkHeight(int targetMinusCurrent)
|
|||
if (forkhash_original < 0)
|
||||
forkhash_original = consensus.nAllClaimsInMerkleForkHeight;
|
||||
consensus.nAllClaimsInMerkleForkHeight = target;
|
||||
const_cast<int64_t&>(base->nAllClaimsInMerkleForkHeight) = target;
|
||||
}
|
||||
|
||||
bool ClaimTrieChainFixture::CreateBlock(const std::unique_ptr<CBlockTemplate>& pblocktemplate)
|
||||
|
@ -277,9 +287,9 @@ void ClaimTrieChainFixture::IncrementBlocks(int num_blocks, bool mark)
|
|||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), num_txs_for_next_block + 1);
|
||||
BOOST_REQUIRE(CreateBlock(pblocktemplate));
|
||||
num_txs_for_next_block = 0;
|
||||
expirationHeight = chainActive.Height();
|
||||
nNextHeight = chainActive.Height() + 1;
|
||||
}
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight - 1));
|
||||
}
|
||||
|
||||
// disconnect i blocks from tip
|
||||
|
@ -295,8 +305,8 @@ void ClaimTrieChainFixture::DecrementBlocks(int num_blocks)
|
|||
BOOST_CHECK_EQUAL(ActivateBestChain(state, Params()), true);
|
||||
mempool.clear();
|
||||
num_txs_for_next_block = 0;
|
||||
expirationHeight = chainActive.Height();
|
||||
nNextHeight = chainActive.Height() + 1;
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight - 1));
|
||||
}
|
||||
|
||||
// decrement back to last mark
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#define _CLAIMTRIEFIXTURE_H_
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <claimtrie.h>
|
||||
#include <claimtrie/forks.h>
|
||||
#include <coins.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/validation.h>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
void ValidatePairs(CClaimTrieCache& cache, const std::vector<std::pair<bool, uint256>>& pairs, uint256 claimHash)
|
||||
void ValidatePairs(CClaimTrieCache& cache, const std::vector<std::pair<bool, CUint256>>& pairs, CUint256 claimHash)
|
||||
{
|
||||
for (auto& pair : pairs)
|
||||
if (pair.first) // we're on the right because we were an odd index number
|
||||
|
@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_rollback_test)
|
|||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "test", "one", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
uint256 currentRoot = fixture.getMerkleHash();
|
||||
auto currentRoot = fixture.getMerkleHash();
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK_EQUAL(currentRoot, fixture.getMerkleHash());
|
||||
fixture.IncrementBlocks(3);
|
||||
|
@ -81,8 +81,7 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_triple_test)
|
|||
BOOST_CHECK(fixture.getProofForName(name, claim.claimId, proof));
|
||||
BOOST_CHECK(proof.hasValue);
|
||||
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
|
||||
BOOST_CHECK_EQUAL(proof.nHeightOfLastTakeover, cfn.nLastTakeoverHeight);
|
||||
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
||||
auto claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
||||
ValidatePairs(fixture, proof.pairs, claimHash);
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +110,7 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_branched_test)
|
|||
BOOST_CHECK(fixture.getProofForName(name, claim.claimId, proof));
|
||||
BOOST_CHECK(proof.hasValue);
|
||||
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
|
||||
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
||||
auto claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
||||
ValidatePairs(fixture, proof.pairs, claimHash);
|
||||
}
|
||||
}
|
||||
|
@ -172,15 +171,15 @@ BOOST_AUTO_TEST_CASE(hash_claims_children_fuzzer_test)
|
|||
BOOST_CHECK(fixture.getProofForName(name, claim.claimId, proof));
|
||||
BOOST_CHECK(proof.hasValue);
|
||||
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
|
||||
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
||||
auto claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
||||
ValidatePairs(fixture, proof.pairs, claimHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool verify_proof(const CClaimTrieProof proof, uint256 rootHash, const std::string& name)
|
||||
bool verify_proof(const CClaimTrieProof proof, CUint256 rootHash, const std::string& name)
|
||||
{
|
||||
uint256 previousComputedHash;
|
||||
CUint256 previousComputedHash;
|
||||
std::string computedReverseName;
|
||||
bool verifiedValue = false;
|
||||
|
||||
|
@ -189,7 +188,7 @@ bool verify_proof(const CClaimTrieProof proof, uint256 rootHash, const std::stri
|
|||
std::vector<unsigned char> vchToHash;
|
||||
for (auto itChildren = itNodes->children.begin(); itChildren != itNodes->children.end(); ++itChildren) {
|
||||
vchToHash.push_back(itChildren->first);
|
||||
uint256 childHash;
|
||||
CUint256 childHash;
|
||||
if (itChildren->second.IsNull()) {
|
||||
if (previousComputedHash.IsNull()) {
|
||||
return false;
|
||||
|
@ -209,7 +208,7 @@ bool verify_proof(const CClaimTrieProof proof, uint256 rootHash, const std::stri
|
|||
return false;
|
||||
}
|
||||
if (itNodes->hasValue) {
|
||||
uint256 valHash;
|
||||
CUint256 valHash;
|
||||
if (itNodes->valHash.IsNull()) {
|
||||
if (itNodes != proof.nodes.rbegin()) {
|
||||
return false;
|
||||
|
@ -232,7 +231,7 @@ bool verify_proof(const CClaimTrieProof proof, uint256 rootHash, const std::stri
|
|||
std::vector<unsigned char> vchHash(hasher.OUTPUT_SIZE);
|
||||
hasher.Write(vchToHash.data(), vchToHash.size());
|
||||
hasher.Finalize(&(vchHash[0]));
|
||||
uint256 calculatedHash(vchHash);
|
||||
CUint256 calculatedHash(vchHash);
|
||||
previousComputedHash = calculatedHash;
|
||||
}
|
||||
if (previousComputedHash != rootHash) {
|
||||
|
@ -324,7 +323,7 @@ BOOST_AUTO_TEST_CASE(value_proof_test)
|
|||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName6));
|
||||
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
||||
|
||||
BOOST_CHECK(fixture.getProofForName(sName7, ClaimIdHash(fixture.getMerkleHash(), 0), proof));
|
||||
BOOST_CHECK(fixture.getProofForName(sName7, ClaimIdHash(uint256(fixture.getMerkleHash()), 0), proof));
|
||||
BOOST_CHECK(verify_proof(proof, chainActive.Tip()->hashClaimTrie, sName7));
|
||||
BOOST_CHECK_EQUAL(proof.hasValue, false);
|
||||
|
||||
|
@ -363,8 +362,8 @@ BOOST_AUTO_TEST_CASE(value_proof_test)
|
|||
|
||||
// Check that blocks with bogus calimtrie hash is rejected
|
||||
BOOST_AUTO_TEST_CASE(bogus_claimtrie_hash_test)
|
||||
{
|
||||
ClaimTrieChainFixture fixture;
|
||||
{
|
||||
ClaimTrieChainFixture fixture;
|
||||
std::string sName("test");
|
||||
std::string sValue1("test");
|
||||
|
||||
|
|
|
@ -307,8 +307,8 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
|
|||
cache.addClaim("AB", COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, height);
|
||||
cache.addClaim("Ab", COutPoint(tx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 2, height);
|
||||
cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, height);
|
||||
cache.addSupport("AB", COutPoint(sx1.GetHash(), 0), 1, ClaimIdHash(tx1.GetHash(), 0), height);
|
||||
cache.addSupport("Ab", COutPoint(sx2.GetHash(), 0), 1, ClaimIdHash(tx2.GetHash(), 0), height);
|
||||
cache.addSupport("AB", COutPoint(sx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, height);
|
||||
cache.addSupport("Ab", COutPoint(sx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 1, height);
|
||||
insertUndoType insertUndo;
|
||||
claimUndoType expireUndo;
|
||||
insertUndoType insertSupportUndo;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
extern void ValidatePairs(CClaimTrieCache& cache, const std::vector<std::pair<bool, uint256>>& pairs, uint256 claimHash);
|
||||
extern void ValidatePairs(CClaimTrieCache& cache, const std::vector<std::pair<bool, CUint256>>& pairs, CUint256 claimHash);
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(claimtrierpc_tests, RegTestingSetup)
|
||||
|
||||
|
@ -190,12 +190,12 @@ BOOST_AUTO_TEST_CASE(claim_rpcs_rollback3_test)
|
|||
BOOST_CHECK_EQUAL(valueResults[T_AMOUNT].get_int(), 3);
|
||||
}
|
||||
|
||||
std::vector<std::pair<bool, uint256>> jsonToPairs(const UniValue& jsonPair)
|
||||
std::vector<std::pair<bool, CUint256>> jsonToPairs(const UniValue& jsonPair)
|
||||
{
|
||||
std::vector<std::pair<bool, uint256>> pairs;
|
||||
std::vector<std::pair<bool, CUint256>> pairs;
|
||||
for (std::size_t i = 0; i < jsonPair.size(); ++i) {
|
||||
auto& jpair = jsonPair[i];
|
||||
pairs.emplace_back(jpair[T_ODD].get_bool(), uint256S(jpair[T_HASH].get_str()));
|
||||
pairs.emplace_back(jpair[T_ODD].get_bool(), CUint256S(jpair[T_HASH].get_str()));
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <rpc/register.h>
|
||||
#include <script/sigcache.h>
|
||||
|
||||
#include "claimtrie.h"
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/unit_test_parameters.hpp>
|
||||
|
||||
|
@ -61,24 +60,33 @@ std::ostream& operator<<(std::ostream& os, const COutPoint& point)
|
|||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const CUint256& num)
|
||||
{
|
||||
os << num.ToString();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const CUint160& num)
|
||||
{
|
||||
os << num.ToString();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const CTxOutPoint& point)
|
||||
{
|
||||
os << point.ToString();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const CClaimValue& claim)
|
||||
{
|
||||
os << "claim(" << claim.outPoint.ToString()
|
||||
<< ", " << claim.claimId.ToString()
|
||||
<< ", " << claim.nAmount
|
||||
<< ", " << claim.nEffectiveAmount
|
||||
<< ", " << claim.nHeight
|
||||
<< ", " << claim.nValidAtHeight << ')';
|
||||
os << claim.ToString();
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const CSupportValue& support)
|
||||
{
|
||||
os << "support(" << support.outPoint.ToString()
|
||||
<< ", " << support.supportedClaimId.ToString()
|
||||
<< ", " << support.nAmount
|
||||
<< ", " << support.nHeight
|
||||
<< ", " << support.nValidAtHeight << ')';
|
||||
os << support.ToString();
|
||||
return os;
|
||||
}
|
||||
|
||||
|
@ -91,6 +99,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
|
|||
g_logger->m_print_to_console = true;
|
||||
g_logger->m_log_time_micros = true;
|
||||
g_logger->EnableCategory(BCLog::ALL);
|
||||
CLogPrint::global().setLogger(g_logger);
|
||||
}
|
||||
|
||||
SHA256AutoDetect();
|
||||
|
@ -138,7 +147,14 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
|||
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
|
||||
pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true));
|
||||
pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
|
||||
pclaimTrie = new CClaimTrie(true, 0, 1);
|
||||
auto& consensus = chainparams.GetConsensus();
|
||||
pclaimTrie = new CClaimTrie(true, false,
|
||||
consensus.nNormalizedNameForkHeight,
|
||||
consensus.nOriginalClaimExpirationTime,
|
||||
consensus.nExtendedClaimExpirationTime,
|
||||
consensus.nExtendedClaimExpirationForkHeight,
|
||||
consensus.nAllClaimsInMerkleForkHeight, 1);
|
||||
|
||||
if (!LoadGenesisBlock(chainparams)) {
|
||||
throw std::runtime_error("LoadGenesisBlock failed.");
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define BITCOIN_TEST_TEST_BITCOIN_H
|
||||
|
||||
#include <chainparamsbase.h>
|
||||
#include <claimtrie/forks.h>
|
||||
#include <fs.h>
|
||||
#include <key.h>
|
||||
#include <pubkey.h>
|
||||
|
@ -134,10 +135,9 @@ std::ostream& operator<<(std::ostream& os, const uint256& num);
|
|||
std::ostream& operator<<(std::ostream& os, const uint160& num);
|
||||
std::ostream& operator<<(std::ostream& os, const COutPoint& point);
|
||||
|
||||
struct CClaimValue;
|
||||
std::ostream& operator<<(std::ostream& os, const CUint256& num);
|
||||
std::ostream& operator<<(std::ostream& os, const CUint160& num);
|
||||
std::ostream& operator<<(std::ostream& os, const CTxOutPoint& point);
|
||||
std::ostream& operator<<(std::ostream& os, const CClaimValue& claim);
|
||||
|
||||
struct CSupportValue;
|
||||
std::ostream& operator<<(std::ostream& os, const CSupportValue& support);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <vector>
|
||||
#include <crypto/common.h>
|
||||
|
||||
#include <claimtrie/uints.h>
|
||||
|
||||
/** Template base class for fixed-sized opaque blobs. */
|
||||
template<unsigned int BITS>
|
||||
class base_blob
|
||||
|
@ -27,6 +29,11 @@ public:
|
|||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
explicit base_blob(const CBaseBlob<BITS>& b)
|
||||
{
|
||||
std::copy(b.begin(), b.end(), begin());
|
||||
}
|
||||
|
||||
explicit base_blob(const std::vector<unsigned char>& vch);
|
||||
|
||||
bool IsNull() const
|
||||
|
@ -102,6 +109,13 @@ public:
|
|||
{
|
||||
s.read((char*)data, sizeof(data));
|
||||
}
|
||||
|
||||
operator CBaseBlob<BITS>() const
|
||||
{
|
||||
CBaseBlob<BITS> c;
|
||||
std::copy(begin(), end(), c.begin());
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
/** 160-bit opaque blob.
|
||||
|
@ -110,8 +124,7 @@ public:
|
|||
*/
|
||||
class uint160 : public base_blob<160> {
|
||||
public:
|
||||
uint160() {}
|
||||
explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {}
|
||||
using base_blob<160>::base_blob;
|
||||
};
|
||||
|
||||
/** 256-bit opaque blob.
|
||||
|
@ -121,8 +134,7 @@ public:
|
|||
*/
|
||||
class uint256 : public base_blob<256> {
|
||||
public:
|
||||
uint256() {}
|
||||
explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {}
|
||||
using base_blob<256>::base_blob;
|
||||
|
||||
/** A cheap hash function that just returns 64 bits from the result, it can be
|
||||
* used when the contents are considered uniformly random. It is not appropriate
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define BITCOIN_UNDO_H
|
||||
|
||||
#include <compressor.h>
|
||||
#include <claimtrie.h>
|
||||
#include <claimtrie/forks.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <serialize.h>
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#endif
|
||||
|
||||
#include <amount.h>
|
||||
#include <claimtrie.h>
|
||||
#include <claimtrie/forks.h>
|
||||
#include <coins.h>
|
||||
#include <fs.h>
|
||||
#include <index/txindex.h>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <chain.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <core_io.h>
|
||||
#include <claimtrie/forks.h>
|
||||
#include <httpserver.h>
|
||||
#include <validation.h>
|
||||
#include <key_io.h>
|
||||
|
@ -952,7 +953,7 @@ UniValue supportclaim(const JSONRPCRequest& request)
|
|||
if (isTip) {
|
||||
CTransactionRef ref;
|
||||
uint256 block;
|
||||
if (!GetTransaction(claimNsupports.claim.outPoint.hash, ref, Params().GetConsensus(), block, true))
|
||||
if (!GetTransaction(uint256(claimNsupports.claim.outPoint.hash), ref, Params().GetConsensus(), block, true))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unable to locate the TX with the claim's output.");
|
||||
if (!ExtractDestination(ref->vout[claimNsupports.claim.outPoint.n].scriptPubKey, dest))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unable to extract the destination from the chosen claim.");
|
||||
|
|
Loading…
Reference in a new issue