Don't call lsn_reset at periodic time #360
2 changed files with 50 additions and 35 deletions
|
@ -223,6 +223,7 @@ libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h
|
||||||
# server: shared between lbrycrdd and lbrycrd-qt
|
# 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_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS)
|
||||||
libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||||
|
libbitcoin_server_a_CFLAGS = $(PIE_FLAGS)
|
||||||
libbitcoin_server_a_SOURCES = \
|
libbitcoin_server_a_SOURCES = \
|
||||||
addrdb.cpp \
|
addrdb.cpp \
|
||||||
addrman.cpp \
|
addrman.cpp \
|
||||||
|
|
|
@ -171,22 +171,14 @@ bool CClaimTrieCacheBase::haveSupportInQueue(const std::string& name, const COut
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Target, typename... AttrTypes>
|
|
||||||
struct vector_builder : public std::vector<Target> {
|
|
||||||
using std::vector<Target>::vector; // use constructors
|
|
||||||
|
|
||||||
void operator()(AttrTypes... args) {
|
|
||||||
this->emplace_back(std::forward<AttrTypes&&>(args)...);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::string& parent, std::vector<std::string>& claims) {
|
bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::string& parent, std::vector<std::string>& claims) {
|
||||||
if (name.empty()) return false;
|
if (name.empty()) return false;
|
||||||
// to remove a node it must have one or less children and no claims
|
// to remove a node it must have one or less children and no claims
|
||||||
vector_builder<std::string, std::string> claimsBuilder;
|
claims.clear();
|
||||||
db << "SELECT name FROM claims WHERE nodeName = ?1 AND validHeight < ?2 AND expirationHeight >= ?2 "
|
db << "SELECT name FROM claims WHERE nodeName = ?1 AND validHeight < ?2 AND expirationHeight >= ?2 "
|
||||||
<< name << nNextHeight >> claimsBuilder;
|
<< name << nNextHeight >> [&claims](std::string name) {
|
||||||
claims = std::move(claimsBuilder);
|
claims.push_back(std::move(name));
|
||||||
|
};
|
||||||
if (!claims.empty()) return false; // still has claims
|
if (!claims.empty()) return false; // still has claims
|
||||||
// we now know it has no claims, but we need to check its children
|
// we now know it has no claims, but we need to check its children
|
||||||
int64_t count;
|
int64_t count;
|
||||||
|
@ -212,6 +204,19 @@ bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::str
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
std::string bin2hex(const std::string& bin)
|
||||||
|
{
|
||||||
|
std::stringstream s;
|
||||||
|
s << std::hex;
|
||||||
|
for (uint8_t i : bin) {
|
||||||
|
if (i < 16) s << '0';
|
||||||
|
s << uint32_t(i);
|
||||||
|
}
|
||||||
|
return s.str();
|
||||||
|
}
|
||||||
|
|
||||||
void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
if (!transacting) return;
|
if (!transacting) return;
|
||||||
|
|
||||||
|
@ -224,8 +229,11 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
|
|
||||||
|
|
||||||
// the plan: update all the claim hashes first
|
// the plan: update all the claim hashes first
|
||||||
vector_builder<std::string, std::string> names;
|
std::vector<std::string> names;
|
||||||
db << "SELECT name FROM nodes WHERE hash IS NULL ORDER BY LENGTH(name) DESC, name DESC" >> names;
|
db << "SELECT name FROM nodes WHERE hash IS NULL ORDER BY LENGTH(name), name"
|
||||||
|
>> [&names](std::string name) {
|
||||||
|
names.push_back(std::move(name));
|
||||||
|
};
|
||||||
if (names.empty()) return; // nothing to do
|
if (names.empty()) return; // nothing to do
|
||||||
|
|
||||||
// there's an assumption that all nodes with claims are here; we do that as claims are inserted
|
// there's an assumption that all nodes with claims are here; we do that as claims are inserted
|
||||||
|
@ -244,13 +252,10 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
|
|
||||||
for (auto& name: names) {
|
for (auto& name: names) {
|
||||||
std::vector<std::string> claims;
|
std::vector<std::string> claims;
|
||||||
std::string parent;
|
std::string parent, node;
|
||||||
if (deleteNodeIfPossible(name, parent, claims)) {
|
for (node = name; deleteNodeIfPossible(node, parent, claims);)
|
||||||
std::string grandparent;
|
node = parent;
|
||||||
deleteNodeIfPossible(parent, grandparent, claims);
|
if (node != name || name.empty() || claims.empty())
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (name.empty() || claims.empty())
|
|
||||||
continue; // if you have no claims but we couldn't delete you, you must have legitimate children
|
continue; // if you have no claims but we couldn't delete you, you must have legitimate children
|
||||||
|
|
||||||
parentQuery << name.substr(0, name.size() - 1);
|
parentQuery << name.substr(0, name.size() - 1);
|
||||||
|
@ -263,12 +268,16 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
|
|
||||||
// we know now that we need to insert it,
|
// we know now that we need to insert it,
|
||||||
// but we may need to insert a parent node for it first (also called a split)
|
// but we may need to insert a parent node for it first (also called a split)
|
||||||
vector_builder<std::string, std::string> siblings;
|
std::vector<std::string> siblings;
|
||||||
db << "SELECT name FROM nodes WHERE parent = ?" << parent >> siblings;
|
db << "SELECT name FROM nodes WHERE parent = ? ORDER BY name" << parent
|
||||||
|
>> [&siblings](std::string name) {
|
||||||
|
siblings.push_back(std::move(name));
|
||||||
|
};
|
||||||
std::size_t splitPos = 0;
|
std::size_t splitPos = 0;
|
||||||
|
auto psize = parent.size() + 1;
|
||||||
for (auto& sibling: siblings) {
|
for (auto& sibling: siblings) {
|
||||||
if (sibling[parent.size()] == name[parent.size()]) {
|
if (sibling.compare(0, psize, name, 0, psize) == 0) {
|
||||||
splitPos = parent.size() + 1;
|
splitPos = psize;
|
||||||
while(splitPos < sibling.size() && splitPos < name.size() && sibling[splitPos] == name[splitPos])
|
while(splitPos < sibling.size() && splitPos < name.size() && sibling[splitPos] == name[splitPos])
|
||||||
++splitPos;
|
++splitPos;
|
||||||
auto newNodeName = name.substr(0, splitPos);
|
auto newNodeName = name.substr(0, splitPos);
|
||||||
|
@ -299,7 +308,7 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint(BCLog::CLAIMS, "Inserting or updating node %s, parent %s\n", name, parent);
|
LogPrint(BCLog::CLAIMS, "Inserting or updating node %s(%s), parent %s\n", name, bin2hex(name), parent);
|
||||||
insertQuery << name << parent;
|
insertQuery << name << parent;
|
||||||
insertQuery++;
|
insertQuery++;
|
||||||
if (splitPos == 0)
|
if (splitPos == 0)
|
||||||
|
@ -312,6 +321,9 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
else
|
else
|
||||||
db << "UPDATE nodes SET parent = ?1 WHERE SUBSTR(name, 1, ?2) = ?1 AND LENGTH(parent) < ?2 AND name != ?1"
|
db << "UPDATE nodes SET parent = ?1 WHERE SUBSTR(name, 1, ?2) = ?1 AND LENGTH(parent) < ?2 AND name != ?1"
|
||||||
<< name << name.size();
|
<< name << name.size();
|
||||||
|
|
||||||
|
if (name.size() == 1 && name[0] == 0)
|
||||||
|
db << "UPDATE nodes SET parent = '' WHERE name = ?" << name;
|
||||||
}
|
}
|
||||||
|
|
||||||
parentQuery.used(true);
|
parentQuery.used(true);
|
||||||
|
@ -345,7 +357,7 @@ std::size_t CClaimTrieCacheBase::getTotalClaimsInTrie() const
|
||||||
CAmount CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly) const
|
CAmount CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly) const
|
||||||
{
|
{
|
||||||
CAmount ret = 0;
|
CAmount ret = 0;
|
||||||
std::string query("SELECT TOTAL(SELECT TOTAL(s.amount)+c.amount FROM supports s "
|
std::string query("SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s "
|
||||||
"WHERE s.supportedClaimID = c.claimID AND s.validHeight < ?1 AND s.expirationHeight >= ?1) "
|
"WHERE s.supportedClaimID = c.claimID AND s.validHeight < ?1 AND s.expirationHeight >= ?1) "
|
||||||
"FROM claims c WHERE c.validHeight < ?1 AND s.expirationHeight >= ?1");
|
"FROM claims c WHERE c.validHeight < ?1 AND s.expirationHeight >= ?1");
|
||||||
if (fControllingOnly)
|
if (fControllingOnly)
|
||||||
|
@ -442,7 +454,7 @@ uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name,
|
||||||
if (child.hash->IsNull()) {
|
if (child.hash->IsNull()) {
|
||||||
*child.hash = recursiveComputeMerkleHash(child.name, child.takeoverHeight, checkOnly);
|
*child.hash = recursiveComputeMerkleHash(child.name, child.takeoverHeight, checkOnly);
|
||||||
}
|
}
|
||||||
LogPrint(BCLog::CLAIMS, "Hash of %s: %s, takeover: %d\n", child.name, (*child.hash).GetHex(), child.takeoverHeight);
|
LogPrint(BCLog::CLAIMS, "Hash of %s(%s): %s, takeover: %d\n", child.name, bin2hex(child.name), (*child.hash).GetHex(), child.takeoverHeight);
|
||||||
completeHash(*child.hash, child.name, pos);
|
completeHash(*child.hash, child.name, pos);
|
||||||
vchToHash.push_back(child.name[pos]);
|
vchToHash.push_back(child.name[pos]);
|
||||||
vchToHash.insert(vchToHash.end(), child.hash->begin(), child.hash->end());
|
vchToHash.insert(vchToHash.end(), child.hash->begin(), child.hash->end());
|
||||||
|
@ -526,8 +538,8 @@ CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base)
|
||||||
: base(base), db(base->dbPath, sharedConfig), transacting(false),
|
: base(base), db(base->dbPath, sharedConfig), transacting(false),
|
||||||
childHashQuery(db << "SELECT name, hash, IFNULL(takeoverHeight, 0) FROM nodes WHERE parent = ? ORDER BY name"),
|
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, "
|
claimHashQuery(db << "SELECT c.txID, c.txN, c.claimID, c.blockHeight, c.validHeight, c.amount, "
|
||||||
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
"(SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
||||||
"AND s.validHeight < ?1 AND s.expirationHeight >= ?1) as effectiveAmount "
|
"AND s.nodeName = c.nodeName AND s.validHeight < ?1 AND s.expirationHeight >= ?1) as effectiveAmount "
|
||||||
"FROM claims c WHERE c.nodeName = ?2 AND c.validHeight < ?1 AND c.expirationHeight >= ?1 "
|
"FROM claims c WHERE c.nodeName = ?2 AND c.validHeight < ?1 AND c.expirationHeight >= ?1 "
|
||||||
"ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN")
|
"ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN")
|
||||||
{
|
{
|
||||||
|
@ -595,7 +607,6 @@ bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& out
|
||||||
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" << claimId << name << nodeName
|
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" << claimId << name << nodeName
|
||||||
<< outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << expires << metadata;
|
<< outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << expires << metadata;
|
||||||
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << nodeName;
|
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << nodeName;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -986,8 +997,11 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
||||||
<< nNextHeight;
|
<< nNextHeight;
|
||||||
|
|
||||||
// takeover handling:
|
// takeover handling:
|
||||||
vector_builder<std::string, std::string> takeovers;
|
std::vector<std::string> takeovers;
|
||||||
db << "SELECT name FROM nodes WHERE hash IS NULL" >> takeovers;
|
db << "SELECT name FROM nodes WHERE hash IS NULL"
|
||||||
|
>> [&takeovers](std::string name) {
|
||||||
|
takeovers.push_back(std::move(name));
|
||||||
|
};
|
||||||
auto getTakeoverQuery = db << "SELECT IFNULL(takeoverHeight, 0), takeoverID FROM nodes WHERE name = ?";
|
auto getTakeoverQuery = db << "SELECT IFNULL(takeoverHeight, 0), takeoverID FROM nodes WHERE name = ?";
|
||||||
auto hasCandidateQuery = db << "UPDATE nodes SET takeoverHeight = ?, takeoverID = ? 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 noCandidateQuery = db << "UPDATE nodes SET takeoverHeight = NULL, takeoverID = NULL WHERE name = ?";
|
||||||
|
@ -1013,7 +1027,7 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
||||||
if (takeoverHappening && activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover))
|
if (takeoverHappening && activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover))
|
||||||
hasCandidate = getInfoForName(nameWithTakeover, candidateValue, 1);
|
hasCandidate = getInfoForName(nameWithTakeover, candidateValue, 1);
|
||||||
|
|
||||||
LogPrint(BCLog::CLAIMS, "Takeover on %s at %d, happening: %d, set before: %d\n", nameWithTakeover, nNextHeight, takeoverHappening, hasBeenSetBefore);
|
LogPrint(BCLog::CLAIMS, "Takeover on %s(%s) at %d, happening: %d, set before: %d\n", nameWithTakeover, bin2hex(nameWithTakeover), nNextHeight, takeoverHappening, hasBeenSetBefore);
|
||||||
|
|
||||||
if (takeoverHappening || !hasBeenSetBefore) {
|
if (takeoverHappening || !hasBeenSetBefore) {
|
||||||
takeoverUndo.emplace_back(nameWithTakeover, std::make_pair(existingHeight, hasBeenSetBefore ? *existingID : uint160()));
|
takeoverUndo.emplace_back(nameWithTakeover, std::make_pair(existingHeight, hasBeenSetBefore ? *existingID : uint160()));
|
||||||
|
|
Loading…
Reference in a new issue