Fix getchangesinblock and unit test
getTotalValueOfClaimsInTrie query is not well performance balanced Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
This commit is contained in:
parent
f47826232f
commit
0dad6a7c10
6 changed files with 113 additions and 48 deletions
|
@ -144,6 +144,7 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary(takeov
|
|||
// make the new nodes
|
||||
db << "INSERT INTO nodes(name) SELECT NORMALIZED(name) AS nn FROM claims WHERE nn != nodeName "
|
||||
"AND validHeight <= ?1 AND expirationHeight > ?1 ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight;
|
||||
|
||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||
"(SELECT NORMALIZED(name) AS nn FROM supports WHERE nn != nodeName "
|
||||
"AND validHeight <= ?1 AND expirationHeight > ?1)" << nNextHeight;
|
||||
|
@ -181,6 +182,7 @@ bool CClaimTrieCacheNormalizationFork::unnormalizeAllNamesInTrieIfNecessary()
|
|||
|
||||
db << "INSERT INTO nodes(name) SELECT name FROM claims WHERE name != nodeName "
|
||||
"AND validHeight < ?1 AND expirationHeight > ?1 ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight;
|
||||
|
||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||
"(SELECT name FROM supports WHERE name != nodeName UNION "
|
||||
"SELECT nodeName FROM supports WHERE name != nodeName UNION "
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
void CLogPrint::setLogger(ClogBase* log)
|
||||
{
|
||||
ss.str({});
|
||||
logger = log;
|
||||
}
|
||||
|
||||
|
@ -14,10 +15,16 @@ CLogPrint& CLogPrint::global()
|
|||
|
||||
CLogPrint& CLogPrint::operator<<(const Clog& cl)
|
||||
{
|
||||
if (logger && cl == Clog::endl) {
|
||||
ss << '\n';
|
||||
logger->LogPrintStr(ss.str());
|
||||
ss.str({});
|
||||
if (logger) {
|
||||
switch(cl) {
|
||||
case Clog::endl:
|
||||
ss << '\n';
|
||||
// fallthrough
|
||||
case Clog::flush:
|
||||
logger->LogPrintStr(ss.str());
|
||||
ss.str({});
|
||||
break;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ struct ClogBase
|
|||
enum struct Clog
|
||||
{
|
||||
endl = 0,
|
||||
flush = 1,
|
||||
};
|
||||
|
||||
struct CLogPrint
|
||||
|
|
|
@ -61,6 +61,7 @@ CClaimTrie::CClaimTrie(bool fWipe, int height,
|
|||
{
|
||||
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)";
|
||||
db << "CREATE INDEX IF NOT EXISTS nodes_parent ON nodes (parent)";
|
||||
|
||||
|
@ -69,6 +70,7 @@ CClaimTrie::CClaimTrie(bool fWipe, int height,
|
|||
"txID BLOB NOT NULL COLLATE BINARY, txN INTEGER NOT NULL, blockHeight INTEGER NOT NULL, "
|
||||
"validHeight INTEGER NOT NULL, expirationHeight INTEGER NOT NULL, "
|
||||
"amount INTEGER NOT NULL, metadata BLOB COLLATE BINARY);";
|
||||
|
||||
db << "CREATE INDEX IF NOT EXISTS claims_validHeight ON claims (validHeight)";
|
||||
db << "CREATE INDEX IF NOT EXISTS claims_expirationHeight ON claims (expirationHeight)";
|
||||
db << "CREATE INDEX IF NOT EXISTS claims_nodeName ON claims (nodeName)";
|
||||
|
@ -77,6 +79,7 @@ CClaimTrie::CClaimTrie(bool fWipe, int height,
|
|||
"supportedClaimID BLOB NOT NULL COLLATE BINARY, name TEXT NOT NULL, nodeName TEXT NOT NULL, "
|
||||
"blockHeight INTEGER NOT NULL, validHeight INTEGER NOT NULL, expirationHeight INTEGER NOT NULL, "
|
||||
"amount INTEGER NOT NULL, metadata BLOB COLLATE BINARY, PRIMARY KEY(txID, txN));";
|
||||
|
||||
db << "CREATE INDEX IF NOT EXISTS supports_supportedClaimID ON supports (supportedClaimID)";
|
||||
db << "CREATE INDEX IF NOT EXISTS supports_validHeight ON supports (validHeight)";
|
||||
db << "CREATE INDEX IF NOT EXISTS supports_expirationHeight ON supports (expirationHeight)";
|
||||
|
@ -321,11 +324,17 @@ std::size_t CClaimTrieCacheBase::getTotalClaimsInTrie() const
|
|||
int64_t CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly) const
|
||||
{
|
||||
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");
|
||||
if (fControllingOnly)
|
||||
throw std::runtime_error("not implemented yet"); // TODO: finish this
|
||||
const std::string query = fControllingOnly ?
|
||||
"SELECT SUM(amount) FROM (SELECT c.amount as amount, "
|
||||
"(SELECT(SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s "
|
||||
"WHERE s.supportedClaimID = c.claimID AND c.nodeName = s.nodeName "
|
||||
"AND s.validHeight < ?1 AND s.expirationHeight >= ?1) as effective "
|
||||
"ORDER BY effective DESC LIMIT 1) as winner FROM claims c "
|
||||
"WHERE c.validHeight < ?1 AND c.expirationHeight >= ?1 GROUP BY c.nodeName)"
|
||||
:
|
||||
"SELECT SUM(amount) FROM (SELECT c.amount as amount "
|
||||
"FROM claims c WHERE c.validHeight < ?1 AND s.expirationHeight >= ?1)";
|
||||
|
||||
db << query << nNextHeight >> ret;
|
||||
return ret;
|
||||
}
|
||||
|
@ -448,7 +457,7 @@ bool CClaimTrieCacheBase::checkConsistency()
|
|||
|
||||
bool CClaimTrieCacheBase::validateDb(const CUint256& rootHash)
|
||||
{
|
||||
logPrint << "Checking claim trie consistency... ";
|
||||
logPrint << "Checking claim trie consistency... " << Clog::flush;
|
||||
if (checkConsistency()) {
|
||||
logPrint << "consistent" << Clog::endl;
|
||||
if (rootHash != getMerkleHash()) {
|
||||
|
@ -569,6 +578,7 @@ bool CClaimTrieCacheBase::addClaim(const std::string& name, const CTxOutPoint& o
|
|||
|
||||
if (nValidHeight < 0)
|
||||
nValidHeight = nHeight + getDelayForName(name, claimId); // sets nValidHeight to the old value
|
||||
|
||||
auto nodeName = adjustNameForValidHeight(name, nValidHeight);
|
||||
auto expires = expirationTime() + nHeight;
|
||||
|
||||
|
@ -589,6 +599,7 @@ bool CClaimTrieCacheBase::addSupport(const std::string& name, const CTxOutPoint&
|
|||
|
||||
if (nValidHeight < 0)
|
||||
nValidHeight = nHeight + getDelayForName(name, supportedClaimId);
|
||||
|
||||
auto nodeName = adjustNameForValidHeight(name, nValidHeight);
|
||||
auto expires = expirationTime() + nHeight;
|
||||
|
||||
|
@ -1113,6 +1124,7 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
|||
db << "INSERT INTO nodes(name) SELECT nodeName FROM claims "
|
||||
"WHERE validHeight = ?1 AND expirationHeight > ?1 "
|
||||
"ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight;
|
||||
|
||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||
"(SELECT nodeName FROM supports WHERE validHeight = ?1 AND expirationHeight > ?1)" << nNextHeight;
|
||||
|
||||
|
@ -1269,6 +1281,7 @@ bool CClaimTrieCacheBase::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
|||
{
|
||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||
"(SELECT nodeName FROM claims WHERE validHeight = ?1 AND expirationHeight > ?1)" << nNextHeight;
|
||||
|
||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||
"(SELECT nodeName FROM supports WHERE validHeight = ?1 AND expirationHeight > ?1)" << nNextHeight;
|
||||
|
||||
|
|
|
@ -742,47 +742,92 @@ UniValue getclaimproofbyseq(const JSONRPCRequest& request)
|
|||
return proofToJSON(proof);
|
||||
}
|
||||
|
||||
extern bool UndoReadFromDisk(CBlockUndo&, const CBlockIndex*);
|
||||
|
||||
template <typename T>
|
||||
UniValue removedToJSON(const std::vector<queueEntryType<T>>& undo)
|
||||
{
|
||||
UniValue ret(UniValue::VARR);
|
||||
for (auto& u : undo) {
|
||||
auto outPoint = COutPoint(u.second.outPoint);
|
||||
ret.push_back(ClaimIdHash(outPoint.hash, outPoint.n).ToString());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
UniValue getchangesinblock(const JSONRPCRequest& request)
|
||||
{
|
||||
validateRequest(request, GETCHANGESINBLOCK, 0, 1);
|
||||
|
||||
CBlockUndo undo;
|
||||
CBlock block;
|
||||
LOCK(cs_main);
|
||||
bool allowSupportMetadata;
|
||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
||||
{
|
||||
LOCK(cs_main);
|
||||
auto index = chainActive.Tip();
|
||||
if (request.params.size() > 0)
|
||||
index = BlockHashIndex(ParseHashV(request.params[0], T_BLOCKHASH " (optional parameter)"));
|
||||
|
||||
if (!UndoReadFromDisk(undo, index))
|
||||
if (!ReadBlockFromDisk(block, index, Params().GetConsensus()))
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR,
|
||||
"Unable to read the undo block for height " + std::to_string(index->nHeight));
|
||||
|
||||
allowSupportMetadata = index->nHeight >= Params().GetConsensus().nAllClaimsInMerkleForkHeight;
|
||||
}
|
||||
|
||||
auto addedUpdated = [](const insertUndoType& insertUndo) {
|
||||
UniValue added(UniValue::VARR);
|
||||
for (auto& a : insertUndo)
|
||||
added.push_back(ClaimIdHash(uint256(a.outPoint.hash), a.outPoint.n).ToString());
|
||||
return added;
|
||||
UniValue claimsAddUp(UniValue::VARR),
|
||||
claimsRm(UniValue::VARR),
|
||||
supportsAddUp(UniValue::VARR),
|
||||
supportsRm(UniValue::VARR);
|
||||
|
||||
int op;
|
||||
std::vector<std::vector<unsigned char> > vvchParams;
|
||||
|
||||
auto findScriptKey = [&block](const COutPoint& point) -> CScript {
|
||||
for (auto& tx : block.vtx)
|
||||
if (tx->GetHash() == point.hash && point.n < tx->vout.size())
|
||||
return tx->vout[point.n].scriptPubKey;
|
||||
return CScript{};
|
||||
};
|
||||
|
||||
for (auto& tx : block.vtx) {
|
||||
if (tx->IsCoinBase())
|
||||
continue;
|
||||
|
||||
for (auto& txin : tx->vin) {
|
||||
const Coin& coin = coinsCache.AccessCoin(txin.prevout);
|
||||
CScript scriptPubKey = coin.out.IsNull() ?
|
||||
findScriptKey(txin.prevout) : coin.out.scriptPubKey;
|
||||
|
||||
if (scriptPubKey.empty())
|
||||
continue;
|
||||
|
||||
if (!DecodeClaimScript(scriptPubKey, op, vvchParams, allowSupportMetadata))
|
||||
continue;
|
||||
|
||||
switch (op) {
|
||||
case OP_CLAIM_NAME:
|
||||
claimsRm.push_back(ClaimIdHash(txin.prevout.hash, txin.prevout.n).ToString());
|
||||
break;
|
||||
case OP_UPDATE_CLAIM:
|
||||
claimsRm.push_back(uint160(vvchParams[1]).ToString());
|
||||
break;
|
||||
case OP_SUPPORT_CLAIM:
|
||||
supportsRm.push_back(uint160(vvchParams[1]).ToString());
|
||||
}
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < tx->vout.size(); ++i) {
|
||||
auto& txout = tx->vout[i];
|
||||
if (txout.scriptPubKey.empty())
|
||||
continue;
|
||||
|
||||
if (!DecodeClaimScript(txout.scriptPubKey, op, vvchParams, allowSupportMetadata))
|
||||
continue;
|
||||
|
||||
switch (op) {
|
||||
case OP_CLAIM_NAME:
|
||||
case OP_UPDATE_CLAIM:
|
||||
claimsAddUp.push_back(ClaimIdHash(tx->GetHash(), i).ToString());
|
||||
break;
|
||||
case OP_SUPPORT_CLAIM:
|
||||
supportsAddUp.push_back(ClaimIdHash(tx->GetHash(), i).ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV(T_CLAIMSADDEDORUPDATED, addedUpdated(undo.insertUndo));
|
||||
result.pushKV(T_CLAIMSREMOVED, removedToJSON(undo.expireUndo));
|
||||
result.pushKV(T_SUPPORTSADDEDORUPDATED, addedUpdated(undo.insertSupportUndo));
|
||||
result.pushKV(T_SUPPORTSREMOVED, removedToJSON(undo.expireSupportUndo));
|
||||
result.pushKV(T_CLAIMSADDEDORUPDATED, claimsAddUp);
|
||||
result.pushKV(T_CLAIMSREMOVED, claimsRm);
|
||||
result.pushKV(T_SUPPORTSADDEDORUPDATED, supportsAddUp);
|
||||
result.pushKV(T_SUPPORTSREMOVED, supportsRm);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -353,19 +353,16 @@ BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
|||
claimHash = getValueHash(COutPoint(tx3.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
||||
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
||||
|
||||
// TODO: repair this or ditch it
|
||||
// auto getchangesinblock = tableRPC["getchangesinblock"]->actor;
|
||||
// req.params = UniValue(UniValue::VARR);
|
||||
// req.params.push_back(UniValue(blockhash.GetHex()));
|
||||
//
|
||||
// result = getchangesinblock(req);
|
||||
// BOOST_REQUIRE_EQUAL(result[T_CLAIMSADDEDORUPDATED].size(), 3);
|
||||
// BOOST_CHECK_EQUAL(result[T_CLAIMSADDEDORUPDATED][0].get_str(), claimId2.GetHex());
|
||||
// BOOST_CHECK_EQUAL(result[T_CLAIMSADDEDORUPDATED][1].get_str(), claimId3.GetHex());
|
||||
// BOOST_CHECK_EQUAL(result[T_CLAIMSADDEDORUPDATED][2].get_str(), claimId4.GetHex());
|
||||
// BOOST_CHECK_EQUAL(result[T_CLAIMSREMOVED].size(), 0);
|
||||
// BOOST_CHECK_EQUAL(result[T_SUPPORTSADDEDORUPDATED].size(), 0);
|
||||
// BOOST_CHECK_EQUAL(result[T_SUPPORTSREMOVED].size(), 0);
|
||||
auto getchangesinblock = tableRPC["getchangesinblock"]->actor;
|
||||
req.params = UniValue(UniValue::VARR);
|
||||
req.params.push_back(UniValue(blockhash.GetHex()));
|
||||
|
||||
result = getchangesinblock(req);
|
||||
BOOST_CHECK_EQUAL(result[T_CLAIMSADDEDORUPDATED].size(), 1);
|
||||
BOOST_CHECK_EQUAL(result[T_CLAIMSADDEDORUPDATED][0].get_str(), claimId4.GetHex());
|
||||
BOOST_CHECK_EQUAL(result[T_CLAIMSREMOVED].size(), 0);
|
||||
BOOST_CHECK_EQUAL(result[T_SUPPORTSADDEDORUPDATED].size(), 0);
|
||||
BOOST_CHECK_EQUAL(result[T_SUPPORTSREMOVED].size(), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(claim_rpc_pending_amount_test)
|
||||
|
|
Loading…
Reference in a new issue