Don't call lsn_reset at periodic time #360
9 changed files with 254 additions and 220 deletions
|
@ -1,12 +1,9 @@
|
||||||
|
|
||||||
#include <data.h>
|
#include <data.h>
|
||||||
#include <log.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#define logPrint CLogPrint::global()
|
|
||||||
|
|
||||||
CClaimValue::CClaimValue(CTxOutPoint outPoint, CUint160 claimId, int64_t nAmount, int nHeight, int nValidAtHeight)
|
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)
|
: outPoint(std::move(outPoint)), claimId(std::move(claimId)), nAmount(nAmount), nEffectiveAmount(nAmount), nHeight(nHeight), nValidAtHeight(nValidAtHeight)
|
||||||
{
|
{
|
||||||
|
@ -77,3 +74,50 @@ CNameOutPointHeightType::CNameOutPointHeightType(std::string name, CTxOutPoint o
|
||||||
: name(std::move(name)), outPoint(std::move(outPoint)), nValidHeight(nValidHeight)
|
: name(std::move(name)), outPoint(std::move(outPoint)), nValidHeight(nValidHeight)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
#ifndef CLAIMTRIE_DATA_H
|
#ifndef CLAIMTRIE_DATA_H
|
||||||
#define CLAIMTRIE_DATA_H
|
#define CLAIMTRIE_DATA_H
|
||||||
|
|
||||||
#include <sqlite/sqlite3.h>
|
|
||||||
#include <txoutpoint.h>
|
#include <txoutpoint.h>
|
||||||
#include <uints.h>
|
#include <uints.h>
|
||||||
|
|
||||||
|
@ -10,56 +9,6 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#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 <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
|
struct CClaimValue
|
||||||
{
|
{
|
||||||
CTxOutPoint outPoint;
|
CTxOutPoint outPoint;
|
||||||
|
@ -119,4 +68,66 @@ struct CNameOutPointHeightType
|
||||||
CNameOutPointHeightType(std::string name, CTxOutPoint outPoint, int nValidHeight);
|
CNameOutPointHeightType(std::string name, CTxOutPoint outPoint, int nValidHeight);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CClaimTrieProofNode
|
||||||
|
{
|
||||||
|
CClaimTrieProofNode(std::vector<std::pair<unsigned char, CUint256>> children, bool hasValue, CUint256 valHash);
|
||||||
|
|
||||||
|
CClaimTrieProofNode() = default;
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // CLAIMTRIE_DATA_H
|
#endif // CLAIMTRIE_DATA_H
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <trie.h>
|
#include <trie.h>
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
#include <boost/locale.hpp>
|
#include <boost/locale.hpp>
|
||||||
#include <boost/locale/conversion.hpp>
|
#include <boost/locale/conversion.hpp>
|
||||||
#include <boost/locale/localization_backend.hpp>
|
#include <boost/locale/localization_backend.hpp>
|
||||||
|
@ -270,22 +272,19 @@ CUint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string&
|
||||||
return CClaimTrieCacheNormalizationFork::recursiveComputeMerkleHash(name, takeoverHeight, checkOnly);
|
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
|
// 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<CUint256> hash; int takeoverHeight; };
|
std::vector<std::tuple<std::string, std::unique_ptr<CUint256>, int>> children;
|
||||||
std::vector<Triple> children;
|
childHashQuery << name >> [&children](std::string name, std::unique_ptr<CUint256> hash, int takeoverHeight) {
|
||||||
for (auto&& row : childHashQuery << name) {
|
children.push_back(std::make_tuple(std::move(name), std::move(hash), takeoverHeight));
|
||||||
children.emplace_back();
|
};
|
||||||
auto& b = children.back();
|
|
||||||
row >> b.name >> b.hash >> b.takeoverHeight;
|
|
||||||
}
|
|
||||||
childHashQuery++;
|
childHashQuery++;
|
||||||
|
|
||||||
std::vector<CUint256> childHashes;
|
std::vector<CUint256> childHashes;
|
||||||
for (auto& child: children) {
|
for (auto& child: children) {
|
||||||
if (child.hash == nullptr) child.hash = std::make_unique<CUint256>();
|
auto& name = std::get<0>(child);
|
||||||
if (child.hash->IsNull()) {
|
auto& hash = std::get<1>(child);
|
||||||
*child.hash = recursiveComputeMerkleHash(child.name, child.takeoverHeight, checkOnly);
|
if (!hash || hash->IsNull())
|
||||||
}
|
childHashes.push_back(recursiveComputeMerkleHash(name, std::get<2>(child), checkOnly));
|
||||||
childHashes.push_back(*child.hash);
|
else
|
||||||
|
childHashes.push_back(*hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<CUint256> claimHashes;
|
std::vector<CUint256> claimHashes;
|
||||||
|
@ -299,8 +298,8 @@ CUint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string&
|
||||||
claimHashQuery++;
|
claimHashQuery++;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
auto left = childHashes.empty() ? leafHash : ComputeMerkleRoot(childHashes);
|
auto left = childHashes.empty() ? leafHash : ComputeMerkleRoot(std::move(childHashes));
|
||||||
auto right = claimHashes.empty() ? emptyHash : ComputeMerkleRoot(claimHashes);
|
auto right = claimHashes.empty() ? emptyHash : ComputeMerkleRoot(std::move(claimHashes));
|
||||||
|
|
||||||
auto computedHash = Hash(left.begin(), left.end(), right.begin(), right.end());
|
auto computedHash = Hash(left.begin(), left.end(), right.begin(), right.end());
|
||||||
if (!checkOnly)
|
if (!checkOnly)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
%module libclaimtrie
|
%module(directors="1") libclaimtrie
|
||||||
%{
|
%{
|
||||||
#include "uints.h"
|
#include "uints.h"
|
||||||
#include "txoutpoint.h"
|
#include "txoutpoint.h"
|
||||||
|
@ -8,15 +8,16 @@
|
||||||
#include "forks.h"
|
#include "forks.h"
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%feature("directors", 1);
|
|
||||||
%feature("flatnested", 1);
|
%feature("flatnested", 1);
|
||||||
|
%feature("director") CIterateCallback;
|
||||||
|
|
||||||
%include stl.i
|
%include stl.i
|
||||||
%include stdint.i
|
%include stdint.i
|
||||||
%include std_pair.i
|
%include std_pair.i
|
||||||
|
|
||||||
|
%apply int& OUTPUT { int& nValidAtHeight };
|
||||||
|
|
||||||
%ignore CBaseBlob(CBaseBlob &&);
|
%ignore CBaseBlob(CBaseBlob &&);
|
||||||
%ignore CClaimIndexElement(CClaimIndexElement &&);
|
|
||||||
%ignore CClaimNsupports(CClaimNsupports &&);
|
%ignore CClaimNsupports(CClaimNsupports &&);
|
||||||
%ignore CClaimTrieProof(CClaimTrieProof &&);
|
%ignore CClaimTrieProof(CClaimTrieProof &&);
|
||||||
%ignore CClaimTrieProofNode(CClaimTrieProofNode &&);
|
%ignore CClaimTrieProofNode(CClaimTrieProofNode &&);
|
||||||
|
@ -29,6 +30,9 @@
|
||||||
%include "uints.h"
|
%include "uints.h"
|
||||||
%include "txoutpoint.h"
|
%include "txoutpoint.h"
|
||||||
%include "data.h"
|
%include "data.h"
|
||||||
|
|
||||||
|
%rename(CClaimTrieCache) CClaimTrieCacheHashFork;
|
||||||
|
|
||||||
%include "trie.h"
|
%include "trie.h"
|
||||||
%include "forks.h"
|
%include "forks.h"
|
||||||
|
|
||||||
|
@ -41,10 +45,11 @@
|
||||||
%template(claimsNsupports) std::vector<CClaimNsupports>;
|
%template(claimsNsupports) std::vector<CClaimNsupports>;
|
||||||
|
|
||||||
%template(proofPair) std::pair<bool, CUint256>;
|
%template(proofPair) std::pair<bool, CUint256>;
|
||||||
|
%template(intClaimPair) std::pair<int, CUint160>;
|
||||||
%template(proofNodePair) std::pair<unsigned char, CUint256>;
|
%template(proofNodePair) std::pair<unsigned char, CUint256>;
|
||||||
%template(claimUndoPair) std::pair<std::string, CClaimValue>;
|
%template(claimUndoPair) std::pair<std::string, CClaimValue>;
|
||||||
%template(supportUndoPair) std::pair<std::string, CSupportValue>;
|
%template(supportUndoPair) std::pair<std::string, CSupportValue>;
|
||||||
%template(takeoverUndoPair) std::pair<std::string, <std::pair<int, CUint160>>;
|
%template(takeoverUndoPair) std::pair<std::string, std::pair<int, CUint160>>;
|
||||||
|
|
||||||
%template(proofNodes) std::vector<CClaimTrieProofNode>;
|
%template(proofNodes) std::vector<CClaimTrieProofNode>;
|
||||||
%template(proofPairs) std::vector<std::pair<bool, CUint256>>;
|
%template(proofPairs) std::vector<std::pair<bool, CUint256>>;
|
||||||
|
@ -54,4 +59,21 @@
|
||||||
%template(insertUndoType) std::vector<CNameOutPointHeightType>;
|
%template(insertUndoType) std::vector<CNameOutPointHeightType>;
|
||||||
%template(takeoverUndoType) std::vector<takeoverUndoPair>;
|
%template(takeoverUndoType) std::vector<takeoverUndoPair>;
|
||||||
|
|
||||||
%rename(CClaimTrieCache) CClaimTrieCacheHashFork;
|
%inline %{
|
||||||
|
struct CIterateCallback {
|
||||||
|
CIterateCallback() = default;
|
||||||
|
virtual ~CIterateCallback() = default;
|
||||||
|
virtual void apply(const std::string&) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void getNamesInTrie(const CClaimTrieCache& cache, CIterateCallback* cb)
|
||||||
|
{
|
||||||
|
cache.getNamesInTrie([cb](const std::string& name) {
|
||||||
|
cb->apply(name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
%typemap(in,numinputs=0) CClaimValue&, CClaimTrieProof&, insertUndoType&, claimUndoType&, supportUndoType&, takeoverUndoType& %{
|
||||||
|
$1 = &$input;
|
||||||
|
%}
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
from libclaimtrie import *
|
from libclaimtrie import *
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
class CacheIterateCallback(CIterateCallback):
|
||||||
|
def __init__(self, names):
|
||||||
|
CIterateCallback.__init__(self)
|
||||||
|
self.names = names
|
||||||
|
|
||||||
|
def apply(self, name):
|
||||||
|
assert(name in self.names), "Incorrect trie names"
|
||||||
|
|
||||||
class TestClaimTrieTypes(unittest.TestCase):
|
class TestClaimTrieTypes(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.uint256s = "1234567890987654321012345678909876543210123456789098765432101234"
|
self.uint256s = "1234567890987654321012345678909876543210123456789098765432101234"
|
||||||
|
@ -67,17 +75,26 @@ class TestClaimTrieTypes(unittest.TestCase):
|
||||||
def test_claimtrie(self):
|
def test_claimtrie(self):
|
||||||
txp = self.txp
|
txp = self.txp
|
||||||
uint160 = self.uint160
|
uint160 = self.uint160
|
||||||
claim = CClaimValue(txp, uint160, 20, 1, 10)
|
claim = CClaimValue(txp, uint160, 20, 1, 1)
|
||||||
data = CClaimTrieData()
|
wipe = True; height = 1; data_dir = "."
|
||||||
data.insertClaim(claim)
|
|
||||||
wipe = True; height = 0; data_dir = "."
|
|
||||||
trie = CClaimTrie(wipe, height, data_dir)
|
trie = CClaimTrie(wipe, height, data_dir)
|
||||||
cache = CClaimTrieCacheBase(trie)
|
cache = CClaimTrieCache(trie)
|
||||||
self.assertTrue(cache.empty(), "incorrect CClaimtrieCache::empty")
|
self.assertTrue(cache.empty(), "incorrect CClaimtrieCache::empty")
|
||||||
self.assertFalse(cache.haveClaim("test", txp), "incorrect CClaimtrieCache::haveClaim")
|
self.assertTrue(cache.addClaim("test", txp, uint160, 20, 1), "incorrect CClaimtrieCache::addClaim")
|
||||||
self.assertTrue(cache.addClaim("tes", txp, uint160, 20, 0), "incorrect CClaimtrieCache::addClaim")
|
self.assertTrue(cache.haveClaim("test", txp), "incorrect CClaimtrieCache::haveClaim")
|
||||||
self.assertEqual(cache.getTotalNamesInTrie(), 1, "incorrect CClaimtrieCache::getTotalNamesInTrie")
|
self.assertEqual(cache.getTotalNamesInTrie(), 1, "incorrect CClaimtrieCache::getTotalNamesInTrie")
|
||||||
self.assertEqual(cache.getTotalClaimsInTrie(), 1, "incorrect CClaimtrieCache::getTotalClaimsInTrie")
|
self.assertEqual(cache.getTotalClaimsInTrie(), 1, "incorrect CClaimtrieCache::getTotalClaimsInTrie")
|
||||||
|
getNamesInTrie(cache, CacheIterateCallback(["test"]))
|
||||||
|
nValidAtHeight = -1
|
||||||
|
result, nValidAtHeight = cache.haveClaimInQueue("test", txp)
|
||||||
|
self.assertTrue(result, "incorrect CClaimTrieCache::haveClaimInQueue")
|
||||||
|
self.assertEqual(nValidAtHeight, 0, "incorrect CClaimTrieCache::haveClaimInQueue, nValidAtHeight")
|
||||||
|
claim1 = CClaimValue()
|
||||||
|
self.assertTrue(cache.getInfoForName("test", claim1), "incorrect CClaimTrieCache::getInfoForName")
|
||||||
|
self.assertEqual(claim, claim1, "incorrect CClaimtrieCache::getInfoForName")
|
||||||
|
proof = CClaimTrieProof()
|
||||||
|
self.assertTrue(cache.getProofForName(cache, "test", proof), "incorrect CacheProofCallback")
|
||||||
|
self.assertTrue(proof.hasValue, "incorrect CClaimTrieCache::getProofForName")
|
||||||
claimsToName = cache.getClaimsForName("test")
|
claimsToName = cache.getClaimsForName("test")
|
||||||
claims = claimsToName.claimsNsupports
|
claims = claimsToName.claimsNsupports
|
||||||
self.assertEqual(claims.size(), 1, "incorrect CClaimTrieCache::getClaimsForName")
|
self.assertEqual(claims.size(), 1, "incorrect CClaimTrieCache::getClaimsForName")
|
||||||
|
|
58
src/claimtrie/sqlite.h
Normal file
58
src/claimtrie/sqlite.h
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
|
||||||
|
#ifndef SQLITE_H
|
||||||
|
#define SQLITE_H
|
||||||
|
|
||||||
|
#include <sqlite/sqlite3.h>
|
||||||
|
#include <uints.h>
|
||||||
|
|
||||||
|
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 <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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SQLITE_H
|
|
@ -10,7 +10,6 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include <boost/container/flat_map.hpp>
|
#include <boost/container/flat_map.hpp>
|
||||||
#include <boost/container/flat_set.hpp>
|
|
||||||
|
|
||||||
#define logPrint CLogPrint::global()
|
#define logPrint CLogPrint::global()
|
||||||
|
|
||||||
|
@ -36,53 +35,6 @@ CUint256 getValueHash(const CTxOutPoint& outPoint, int nHeightOfLastTakeover)
|
||||||
return Hash(hash1.begin(), hash1.end(), hash2.begin(), hash2.end(), hash3.begin(), hash3.end());
|
return Hash(hash1.begin(), hash1.end(), hash2.begin(), hash2.end(), hash3.begin(), hash3.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
static const sqlite::sqlite_config sharedConfig {
|
||||||
sqlite::OpenFlags::READWRITE | sqlite::OpenFlags::CREATE, // TODO: test with this: | sqlite::OpenFlags::SHAREDCACHE,
|
sqlite::OpenFlags::READWRITE | sqlite::OpenFlags::CREATE, // TODO: test with this: | sqlite::OpenFlags::SHAREDCACHE,
|
||||||
nullptr, sqlite::Encoding::UTF8
|
nullptr, sqlite::Encoding::UTF8
|
||||||
|
@ -1410,7 +1362,7 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, const CUint16
|
||||||
return true;
|
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) const
|
||||||
{
|
{
|
||||||
std::reverse(claim.begin(), claim.end());
|
std::reverse(claim.begin(), claim.end());
|
||||||
auto query = db << "SELECT nodeName, claimId, txID, txN, amount, validHeight, blockHeight "
|
auto query = db << "SELECT nodeName, claimId, txID, txN, amount, validHeight, blockHeight "
|
||||||
|
@ -1426,7 +1378,7 @@ bool CClaimTrieCacheBase::findNameForClaim(std::vector<unsigned char> claim, CCl
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CClaimTrieCacheBase::getNamesInTrie(std::function<void(const std::string&)> callback)
|
void CClaimTrieCacheBase::getNamesInTrie(std::function<void(const std::string&)> callback) const
|
||||||
{
|
{
|
||||||
auto query = db << "SELECT DISTINCT nodeName FROM claims WHERE validHeight < ? AND expirationHeight >= ?"
|
auto query = db << "SELECT DISTINCT nodeName FROM claims WHERE validHeight < ? AND expirationHeight >= ?"
|
||||||
<< nNextHeight << nNextHeight;
|
<< nNextHeight << nNextHeight;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CLAIMTRIE_TRIE_H
|
#define CLAIMTRIE_TRIE_H
|
||||||
|
|
||||||
#include <data.h>
|
#include <data.h>
|
||||||
|
#include <sqlite.h>
|
||||||
#include <txoutpoint.h>
|
#include <txoutpoint.h>
|
||||||
#include <uints.h>
|
#include <uints.h>
|
||||||
|
|
||||||
|
@ -10,44 +11,11 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
CUint256 getValueHash(const CTxOutPoint& outPoint, int nHeightOfLastTakeover);
|
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
|
class CClaimTrie
|
||||||
{
|
{
|
||||||
friend class CClaimTrieCacheBase;
|
friend class CClaimTrieCacheBase;
|
||||||
|
@ -57,16 +25,16 @@ class CClaimTrie
|
||||||
friend class CClaimTrieCacheNormalizationFork;
|
friend class CClaimTrieCacheNormalizationFork;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CClaimTrie() = default;
|
CClaimTrie() = delete;
|
||||||
CClaimTrie(CClaimTrie&&) = delete;
|
CClaimTrie(CClaimTrie&&) = delete;
|
||||||
CClaimTrie(const CClaimTrie&) = delete;
|
CClaimTrie(const CClaimTrie&) = delete;
|
||||||
CClaimTrie(bool fWipe, int height,
|
CClaimTrie(bool fWipe, int height = 0,
|
||||||
const std::string& dataDir,
|
const std::string& dataDir = ".",
|
||||||
int nNormalizedNameForkHeight = -1,
|
int nNormalizedNameForkHeight = 1,
|
||||||
int64_t nOriginalClaimExpirationTime = -1,
|
int64_t nOriginalClaimExpirationTime = 1,
|
||||||
int64_t nExtendedClaimExpirationTime = -1,
|
int64_t nExtendedClaimExpirationTime = 1,
|
||||||
int64_t nExtendedClaimExpirationForkHeight = -1,
|
int64_t nExtendedClaimExpirationForkHeight = 1,
|
||||||
int64_t nAllClaimsInMerkleForkHeight = -1,
|
int64_t nAllClaimsInMerkleForkHeight = 1,
|
||||||
int proportionalDelayFactor = 32);
|
int proportionalDelayFactor = 32);
|
||||||
|
|
||||||
CClaimTrie& operator=(CClaimTrie&&) = delete;
|
CClaimTrie& operator=(CClaimTrie&&) = delete;
|
||||||
|
@ -76,45 +44,15 @@ public:
|
||||||
bool SyncToDisk();
|
bool SyncToDisk();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int nNextHeight = 0;
|
int nNextHeight;
|
||||||
sqlite::database db;
|
sqlite::database db;
|
||||||
const int nProportionalDelayFactor = 1;
|
const int nProportionalDelayFactor;
|
||||||
|
|
||||||
const int nNormalizedNameForkHeight = -1;
|
const int nNormalizedNameForkHeight;
|
||||||
const int64_t nOriginalClaimExpirationTime = -1;
|
const int64_t nOriginalClaimExpirationTime;
|
||||||
const int64_t nExtendedClaimExpirationTime = -1;
|
const int64_t nExtendedClaimExpirationTime;
|
||||||
const int64_t nExtendedClaimExpirationForkHeight = -1;
|
const int64_t nExtendedClaimExpirationForkHeight;
|
||||||
const int64_t nAllClaimsInMerkleForkHeight = -1;
|
const int64_t nAllClaimsInMerkleForkHeight;
|
||||||
};
|
|
||||||
|
|
||||||
struct CClaimTrieProofNode
|
|
||||||
{
|
|
||||||
CClaimTrieProofNode(std::vector<std::pair<unsigned char, CUint256>> children, bool hasValue, CUint256 valHash);
|
|
||||||
|
|
||||||
CClaimTrieProofNode() = default;
|
|
||||||
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>
|
template <typename T>
|
||||||
|
@ -123,7 +61,7 @@ using queueEntryType = std::pair<std::string, T>;
|
||||||
#ifdef SWIG_INTERFACE // swig has a problem with using in typedef
|
#ifdef SWIG_INTERFACE // swig has a problem with using in typedef
|
||||||
using claimUndoPair = std::pair<std::string, CClaimValue>;
|
using claimUndoPair = std::pair<std::string, CClaimValue>;
|
||||||
using supportUndoPair = std::pair<std::string, CSupportValue>;
|
using supportUndoPair = std::pair<std::string, CSupportValue>;
|
||||||
using takeoverUndoPair = std::pair<std::string, <std::pair<int, CUint160>>;
|
using takeoverUndoPair = std::pair<std::string, std::pair<int, CUint160>>;
|
||||||
#else
|
#else
|
||||||
using claimUndoPair = queueEntryType<CClaimValue>;
|
using claimUndoPair = queueEntryType<CClaimValue>;
|
||||||
using supportUndoPair = queueEntryType<CSupportValue>;
|
using supportUndoPair = queueEntryType<CSupportValue>;
|
||||||
|
@ -141,11 +79,9 @@ public:
|
||||||
explicit CClaimTrieCacheBase(CClaimTrie* base);
|
explicit CClaimTrieCacheBase(CClaimTrie* base);
|
||||||
virtual ~CClaimTrieCacheBase();
|
virtual ~CClaimTrieCacheBase();
|
||||||
|
|
||||||
CUint256 getMerkleHash();
|
|
||||||
|
|
||||||
bool flush();
|
bool flush();
|
||||||
bool empty() const;
|
|
||||||
bool checkConsistency();
|
bool checkConsistency();
|
||||||
|
CUint256 getMerkleHash();
|
||||||
bool validateDb(const CUint256& rootHash);
|
bool validateDb(const CUint256& rootHash);
|
||||||
|
|
||||||
std::size_t getTotalNamesInTrie() const;
|
std::size_t getTotalNamesInTrie() const;
|
||||||
|
@ -188,9 +124,9 @@ public:
|
||||||
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
|
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
|
||||||
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) 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) const;
|
||||||
void getNamesInTrie(std::function<void(const std::string&)> callback);
|
|
||||||
bool getLastTakeoverForName(const std::string& name, CUint160& claimId, int& takeoverHeight) const;
|
bool getLastTakeoverForName(const std::string& name, CUint160& claimId, int& takeoverHeight) const;
|
||||||
|
bool findNameForClaim(std::vector<unsigned char> claim, CClaimValue& value, std::string& name) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CClaimTrie* base;
|
CClaimTrie* base;
|
||||||
|
@ -210,7 +146,6 @@ protected:
|
||||||
void ensureTreeStructureIsUpToDate();
|
void ensureTreeStructureIsUpToDate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, std::pair<CUint160, int>> takeoverCache;
|
|
||||||
// for unit test
|
// for unit test
|
||||||
friend struct ClaimTrieChainFixture;
|
friend struct ClaimTrieChainFixture;
|
||||||
friend class CClaimTrieCacheTest;
|
friend class CClaimTrieCacheTest;
|
||||||
|
|
|
@ -35,8 +35,4 @@ public:
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef SWIG_INTERFACE
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SWIG_INTERFACE
|
|
||||||
#endif // CLAIMTRIE_TXOUTPUT_H
|
#endif // CLAIMTRIE_TXOUTPUT_H
|
||||||
|
|
Loading…
Reference in a new issue