Logic fixes, unit test
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
This commit is contained in:
parent
4ab46e4972
commit
32e6a99ee6
3 changed files with 254 additions and 81 deletions
|
@ -100,7 +100,7 @@ S3(" ", T_AMOUNT, " (numeric) the amount of the support") \
|
||||||
S1(" ]") \
|
S1(" ]") \
|
||||||
S3(" ", T_LASTTAKEOVERHEIGHT, " (numeric) the last height at which ownership of the name changed") \
|
S3(" ", T_LASTTAKEOVERHEIGHT, " (numeric) the last height at which ownership of the name changed") \
|
||||||
S3(" ", T_BID, " (numeric) lower value means a higher bid rate, ordered by effective amount") \
|
S3(" ", T_BID, " (numeric) lower value means a higher bid rate, ordered by effective amount") \
|
||||||
S3(" ", T_SEQUENCE, " (numeric) lower value means latest in sequence, ordered by height of insertion")
|
S3(" ", T_SEQUENCE, " (numeric) lower value means an older one in sequence, ordered by height of insertion")
|
||||||
|
|
||||||
#define PROOF_OUTPUT \
|
#define PROOF_OUTPUT \
|
||||||
S3(" ", T_NODES, ": [ (array of object, pre-fork) full nodes\n" \
|
S3(" ", T_NODES, ": [ (array of object, pre-fork) full nodes\n" \
|
||||||
|
@ -194,7 +194,7 @@ S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the support
|
||||||
S3(" ", T_AMOUNT, " (numeric) the amount of the support")
|
S3(" ", T_AMOUNT, " (numeric) the amount of the support")
|
||||||
S1(" ]")
|
S1(" ]")
|
||||||
S3(" ", T_BID, " (numeric) lower value means a higher bid rate, ordered by effective amount")
|
S3(" ", T_BID, " (numeric) lower value means a higher bid rate, ordered by effective amount")
|
||||||
S3(" ", T_SEQUENCE, " (numeric) lower value means latest in sequence, ordered by height of insertion")
|
S3(" ", T_SEQUENCE, " (numeric) lower value means an older one in sequence, ordered by height of insertion")
|
||||||
S1(" ]")
|
S1(" ]")
|
||||||
S3(" ", T_LASTTAKEOVERHEIGHT, " (numeric) the last height at which ownership of the name changed")
|
S3(" ", T_LASTTAKEOVERHEIGHT, " (numeric) the last height at which ownership of the name changed")
|
||||||
S3(" ", T_SUPPORTSWITHOUTCLAIM, ": [")
|
S3(" ", T_SUPPORTSWITHOUTCLAIM, ": [")
|
||||||
|
|
|
@ -19,21 +19,22 @@
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
void ParseClaimtrieId(const UniValue& v, std::string& partialId, uint160& claimId, const std::string& strName)
|
|
||||||
{
|
|
||||||
static constexpr size_t claimIdHexLength = 40;
|
static constexpr size_t claimIdHexLength = 40;
|
||||||
|
|
||||||
std::string strHex;
|
uint160 uint160S(const std::string& str)
|
||||||
if (v.isStr())
|
{
|
||||||
strHex = v.get_str();
|
uint160 s;
|
||||||
if (!IsHex(strHex))
|
s.SetHex(str);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseClaimtrieId(const UniValue& v, std::string& claimId, const std::string& strName)
|
||||||
|
{
|
||||||
|
// use IsHexNumber which verify odd strings size
|
||||||
|
if (!v.isStr() || !IsHexNumber(claimId = v.get_str()))
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strName + " must be a hexadecimal string");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strName + " must be a hexadecimal string");
|
||||||
if (strHex.length() > claimIdHexLength)
|
if (claimId.length() > claimIdHexLength)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strName + " must be max 20-character hexadecimal string");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strName + " must be max 20-character hexadecimal string");
|
||||||
if (strHex.length() == claimIdHexLength)
|
|
||||||
claimId.SetHex(strHex);
|
|
||||||
else
|
|
||||||
partialId = strHex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CBlockIndex* BlockHashIndex(const uint256& blockHash)
|
static CBlockIndex* BlockHashIndex(const uint256& blockHash)
|
||||||
|
@ -107,7 +108,7 @@ std::string escapeNonUtf8(const std::string& name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool getValueForOutPoint(const CScript& scriptPubKey, std::string& sValue)
|
static bool extractValue(const CScript& scriptPubKey, std::string& sValue)
|
||||||
{
|
{
|
||||||
int op;
|
int op;
|
||||||
std::vector<std::vector<unsigned char> > vvchParams;
|
std::vector<std::vector<unsigned char> > vvchParams;
|
||||||
|
@ -174,11 +175,9 @@ std::vector<CClaimNsupports> seqSort(const std::vector<CClaimNsupports>& source)
|
||||||
auto claimsNsupports = source;
|
auto claimsNsupports = source;
|
||||||
|
|
||||||
std::sort(claimsNsupports.begin(), claimsNsupports.end(), [](const CClaimNsupports& lhs, const CClaimNsupports& rhs) {
|
std::sort(claimsNsupports.begin(), claimsNsupports.end(), [](const CClaimNsupports& lhs, const CClaimNsupports& rhs) {
|
||||||
if (lhs.claim.nHeight > rhs.claim.nHeight)
|
auto& lc = lhs.claim;
|
||||||
return true;
|
auto& rc = rhs.claim;
|
||||||
if (lhs.claim.nHeight != rhs.claim.nHeight)
|
return lc.nHeight < rc.nHeight || (lc.nHeight == rc.nHeight && lc.outPoint.n < rc.outPoint.n);
|
||||||
return false;
|
|
||||||
return lhs.claim.outPoint.n > rhs.claim.outPoint.n;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return claimsNsupports;
|
return claimsNsupports;
|
||||||
|
@ -204,7 +203,7 @@ UniValue claimToJSON(const CCoinsViewCache& coinsCache, const CClaimValue& claim
|
||||||
auto& coin = coinsCache.AccessCoin(claim.outPoint);
|
auto& coin = coinsCache.AccessCoin(claim.outPoint);
|
||||||
if (!coin.IsSpent()) {
|
if (!coin.IsSpent()) {
|
||||||
std::string value;
|
std::string value;
|
||||||
if (getValueForOutPoint(coin.out.scriptPubKey, value))
|
if (extractValue(coin.out.scriptPubKey, value))
|
||||||
result.pushKV(T_VALUE, value);
|
result.pushKV(T_VALUE, value);
|
||||||
|
|
||||||
CTxDestination address;
|
CTxDestination address;
|
||||||
|
@ -229,7 +228,7 @@ UniValue supportToJSON(const CCoinsViewCache& coinsCache, const CSupportValue& s
|
||||||
auto& coin = coinsCache.AccessCoin(support.outPoint);
|
auto& coin = coinsCache.AccessCoin(support.outPoint);
|
||||||
if (!coin.IsSpent()) {
|
if (!coin.IsSpent()) {
|
||||||
std::string value;
|
std::string value;
|
||||||
if (getValueForOutPoint(coin.out.scriptPubKey, value))
|
if (extractValue(coin.out.scriptPubKey, value))
|
||||||
ret.pushKV(T_VALUE, value);
|
ret.pushKV(T_VALUE, value);
|
||||||
|
|
||||||
CTxDestination address;
|
CTxDestination address;
|
||||||
|
@ -286,7 +285,6 @@ static UniValue getclaimsintrie(const JSONRPCRequest& request)
|
||||||
throw JSONRPCError(RPC_METHOD_DEPRECATED, msg);
|
throw JSONRPCError(RPC_METHOD_DEPRECATED, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue ret(UniValue::VARR);
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
CCoinsViewCache coinsCache(pcoinsTip.get());
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
|
@ -296,6 +294,7 @@ static UniValue getclaimsintrie(const JSONRPCRequest& request)
|
||||||
RollBackTo(blockIndex, coinsCache, trieCache);
|
RollBackTo(blockIndex, coinsCache, trieCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UniValue ret(UniValue::VARR);
|
||||||
trieCache.recurseNodes({}, [&ret, &trieCache, &coinsCache] (const std::string& name, const CClaimTrieData& data) {
|
trieCache.recurseNodes({}, [&ret, &trieCache, &coinsCache] (const std::string& name, const CClaimTrieData& data) {
|
||||||
if (ShutdownRequested())
|
if (ShutdownRequested())
|
||||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Shutdown requested");
|
throw JSONRPCError(RPC_INTERNAL_ERROR, "Shutdown requested");
|
||||||
|
@ -335,8 +334,8 @@ static UniValue getnamesintrie(const JSONRPCRequest& request)
|
||||||
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[0], T_BLOCKHASH " (optional parameter 1)"));
|
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[0], T_BLOCKHASH " (optional parameter 1)"));
|
||||||
RollBackTo(blockIndex, coinsCache, trieCache);
|
RollBackTo(blockIndex, coinsCache, trieCache);
|
||||||
}
|
}
|
||||||
UniValue ret(UniValue::VARR);
|
|
||||||
|
|
||||||
|
UniValue ret(UniValue::VARR);
|
||||||
trieCache.recurseNodes({}, [&ret](const std::string &name, const CClaimTrieData &data) {
|
trieCache.recurseNodes({}, [&ret](const std::string &name, const CClaimTrieData &data) {
|
||||||
if (!data.empty())
|
if (!data.empty())
|
||||||
ret.push_back(escapeNonUtf8(name));
|
ret.push_back(escapeNonUtf8(name));
|
||||||
|
@ -362,10 +361,9 @@ static UniValue getvalueforname(const JSONRPCRequest& request)
|
||||||
RollBackTo(blockIndex, coinsCache, trieCache);
|
RollBackTo(blockIndex, coinsCache, trieCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint160 claimId;
|
std::string claimId;
|
||||||
std::string partialId;
|
|
||||||
if (request.params.size() > 2)
|
if (request.params.size() > 2)
|
||||||
ParseClaimtrieId(request.params[2], partialId, claimId, T_CLAIMID " (optional parameter 3)");
|
ParseClaimtrieId(request.params[2], claimId, T_CLAIMID " (optional parameter 3)");
|
||||||
|
|
||||||
const auto name = request.params[0].get_str();
|
const auto name = request.params[0].get_str();
|
||||||
UniValue ret(UniValue::VOBJ);
|
UniValue ret(UniValue::VOBJ);
|
||||||
|
@ -375,8 +373,8 @@ static UniValue getvalueforname(const JSONRPCRequest& request)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
auto& claimNsupports =
|
auto& claimNsupports =
|
||||||
!claimId.IsNull() ? csToName.find(claimId) :
|
claimId.length() == claimIdHexLength ? csToName.find(uint160S(claimId)) :
|
||||||
!partialId.empty() ? csToName.find(partialId) : csToName.claimsNsupports[0];
|
!claimId.empty() ? csToName.find(claimId) : csToName.claimsNsupports[0];
|
||||||
|
|
||||||
if (claimNsupports.IsNull())
|
if (claimNsupports.IsNull())
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -451,7 +449,7 @@ UniValue getclaimbybid(const JSONRPCRequest& request)
|
||||||
bid = request.params[1].get_int();
|
bid = request.params[1].get_int();
|
||||||
|
|
||||||
if (bid < 0)
|
if (bid < 0)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, T_BID " (parameter 2) should be greater than 0");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, T_BID " (parameter 2) should not be a negative value");
|
||||||
|
|
||||||
if (request.params.size() > 2) {
|
if (request.params.size() > 2) {
|
||||||
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3)"));
|
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3)"));
|
||||||
|
@ -494,7 +492,7 @@ UniValue getclaimbyseq(const JSONRPCRequest& request)
|
||||||
seq = request.params[1].get_int();
|
seq = request.params[1].get_int();
|
||||||
|
|
||||||
if (seq < 0)
|
if (seq < 0)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, T_SEQUENCE " (parameter 2) should be greater than 0");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, T_SEQUENCE " (parameter 2) should not be a negative value");
|
||||||
|
|
||||||
if (request.params.size() > 2) {
|
if (request.params.size() > 2) {
|
||||||
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3)"));
|
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3)"));
|
||||||
|
@ -534,34 +532,34 @@ UniValue getclaimbyid(const JSONRPCRequest& request)
|
||||||
CClaimTrieCache trieCache(pclaimTrie);
|
CClaimTrieCache trieCache(pclaimTrie);
|
||||||
CCoinsViewCache coinsCache(pcoinsTip.get());
|
CCoinsViewCache coinsCache(pcoinsTip.get());
|
||||||
|
|
||||||
uint160 claimId;
|
std::string claimId;
|
||||||
std::string partialId;
|
ParseClaimtrieId(request.params[0], claimId, T_CLAIMID " (parameter 1)");
|
||||||
ParseClaimtrieId(request.params[0], partialId, claimId, T_CLAIMID " (parameter 1)");
|
|
||||||
|
|
||||||
if (claimId.IsNull() && partialId.length() < 3)
|
if (claimId.length() < 3)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, T_CLAIMID " (parameter 1) should be at least 3 chars");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, T_CLAIMID " (parameter 1) should be at least 3 chars");
|
||||||
|
|
||||||
UniValue claim(UniValue::VOBJ);
|
|
||||||
std::string name;
|
std::string name;
|
||||||
CClaimValue claimValue;
|
CClaimValue claim;
|
||||||
if (getClaimById(claimId, name, &claimValue) || getClaimById(partialId, name, &claimValue)) {
|
UniValue ret(UniValue::VOBJ);
|
||||||
|
bool found = claimId.length() == claimIdHexLength && getClaimById(uint160S(claimId), name, &claim);
|
||||||
|
if (found || getClaimById(claimId, name, &claim)) {
|
||||||
auto csToName = trieCache.getClaimsForName(name);
|
auto csToName = trieCache.getClaimsForName(name);
|
||||||
auto& claimNsupports = !claimId.IsNull() ? csToName.find(claimId) : csToName.find(partialId);
|
auto& claimNsupports = csToName.find(claim.claimId);
|
||||||
if (!claimNsupports.IsNull()) {
|
if (!claimNsupports.IsNull()) {
|
||||||
std::size_t seq = 0, bid = 0;
|
std::size_t seq = 0, bid = 0;
|
||||||
if (csToName.claimsNsupports.size() > 1) {
|
if (csToName.claimsNsupports.size() > 1) {
|
||||||
auto seqOrder = seqSort(csToName.claimsNsupports);
|
auto seqOrder = seqSort(csToName.claimsNsupports);
|
||||||
seq = indexOf(seqOrder, claimNsupports.claim.claimId);
|
seq = indexOf(seqOrder, claim.claimId);
|
||||||
bid = indexOf(csToName.claimsNsupports, claimNsupports.claim.claimId);
|
bid = indexOf(csToName.claimsNsupports, claim.claimId);
|
||||||
}
|
}
|
||||||
claim.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(csToName.name));
|
ret.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(csToName.name));
|
||||||
claim.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports));
|
ret.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports));
|
||||||
claim.pushKV(T_LASTTAKEOVERHEIGHT, csToName.nLastTakeoverHeight);
|
ret.pushKV(T_LASTTAKEOVERHEIGHT, csToName.nLastTakeoverHeight);
|
||||||
claim.pushKV(T_BID, (int)bid);
|
ret.pushKV(T_BID, (int)bid);
|
||||||
claim.pushKV(T_SEQUENCE, (int)seq);
|
ret.pushKV(T_SEQUENCE, (int)seq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return claim;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue gettotalclaimednames(const JSONRPCRequest& request)
|
UniValue gettotalclaimednames(const JSONRPCRequest& request)
|
||||||
|
@ -734,20 +732,21 @@ UniValue getnameproof(const JSONRPCRequest& request)
|
||||||
RollBackTo(pblockIndex, coinsCache, trieCache);
|
RollBackTo(pblockIndex, coinsCache, trieCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint160 claimId;
|
std::string claimId;
|
||||||
std::string partialId;
|
|
||||||
if (request.params.size() > 2)
|
if (request.params.size() > 2)
|
||||||
ParseClaimtrieId(request.params[2], partialId, claimId, T_CLAIMID " (optional parameter 3)");
|
ParseClaimtrieId(request.params[2], claimId, T_CLAIMID " (optional parameter 3)");
|
||||||
|
|
||||||
std::function<bool(const CClaimValue&)> comp;
|
std::function<bool(const CClaimValue&)> comp;
|
||||||
if (!claimId.IsNull())
|
if (claimId.length() == claimIdHexLength) {
|
||||||
|
auto claimIdx = uint160S(claimId);
|
||||||
|
comp = [claimIdx](const CClaimValue& claim) {
|
||||||
|
return claim.claimId == claimIdx;
|
||||||
|
};
|
||||||
|
} else if (!claimId.empty()) {
|
||||||
comp = [&claimId](const CClaimValue& claim) {
|
comp = [&claimId](const CClaimValue& claim) {
|
||||||
return claim.claimId == claimId;
|
return claim.claimId.GetHex().find(claimId) == 0;
|
||||||
};
|
|
||||||
else
|
|
||||||
comp = [&partialId](const CClaimValue& claim) {
|
|
||||||
return claim.claimId.GetHex().find(partialId) == 0;
|
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
CClaimTrieProof proof;
|
CClaimTrieProof proof;
|
||||||
std::string name = request.params[0].get_str();
|
std::string name = request.params[0].get_str();
|
||||||
|
@ -770,7 +769,7 @@ UniValue getclaimproofbybid(const JSONRPCRequest& request)
|
||||||
bid = request.params[1].get_int();
|
bid = request.params[1].get_int();
|
||||||
|
|
||||||
if (bid < 0)
|
if (bid < 0)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, T_BID " (parameter 2) should be greater than 0");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, T_BID " (parameter 2) should not be a negative value");
|
||||||
|
|
||||||
if (request.params.size() > 2) {
|
if (request.params.size() > 2) {
|
||||||
CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3)"));
|
CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3)"));
|
||||||
|
@ -810,7 +809,7 @@ UniValue getclaimproofbyseq(const JSONRPCRequest& request)
|
||||||
seq = request.params[1].get_int();
|
seq = request.params[1].get_int();
|
||||||
|
|
||||||
if (seq < 0)
|
if (seq < 0)
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, T_SEQUENCE " (parameter 2) should be greater than 0");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, T_SEQUENCE " (parameter 2) should not be a negative value");
|
||||||
|
|
||||||
if (request.params.size() > 2) {
|
if (request.params.size() > 2) {
|
||||||
CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3"));
|
CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3"));
|
||||||
|
@ -838,9 +837,20 @@ UniValue getclaimproofbyseq(const JSONRPCRequest& request)
|
||||||
|
|
||||||
extern bool UndoReadFromDisk(CBlockUndo&, const CBlockIndex*);
|
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 = u.second.outPoint;
|
||||||
|
ret.push_back(ClaimIdHash(outPoint.hash, outPoint.n).ToString());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
UniValue getchangesinblock(const JSONRPCRequest& request)
|
UniValue getchangesinblock(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
validateRequest(request, GETCHANGESINBLOCK, 1, 0);
|
validateRequest(request, GETCHANGESINBLOCK, 0, 1);
|
||||||
|
|
||||||
CBlockUndo undo;
|
CBlockUndo undo;
|
||||||
{
|
{
|
||||||
|
@ -861,25 +871,11 @@ UniValue getchangesinblock(const JSONRPCRequest& request)
|
||||||
return added;
|
return added;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto removedClaims = [](const claimQueueRowType& expireUndo) {
|
|
||||||
UniValue removed(UniValue::VARR);
|
|
||||||
for (auto& r : expireUndo)
|
|
||||||
removed.push_back(r.second.claimId.ToString());
|
|
||||||
return removed;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto removedSupports = [](const supportQueueRowType& expireUndo) {
|
|
||||||
UniValue removed(UniValue::VARR);
|
|
||||||
for (auto& r : expireUndo)
|
|
||||||
removed.push_back(r.second.supportedClaimId.ToString());
|
|
||||||
return removed;
|
|
||||||
};
|
|
||||||
|
|
||||||
UniValue result(UniValue::VOBJ);
|
UniValue result(UniValue::VOBJ);
|
||||||
result.pushKV(T_CLAIMSADDEDORUPDATED, addedUpdated(undo.insertUndo));
|
result.pushKV(T_CLAIMSADDEDORUPDATED, addedUpdated(undo.insertUndo));
|
||||||
result.pushKV(T_CLAIMSREMOVED, removedClaims(undo.expireUndo));
|
result.pushKV(T_CLAIMSREMOVED, removedToJSON(undo.expireUndo));
|
||||||
result.pushKV(T_SUPPORTSADDEDORUPDATED, addedUpdated(undo.insertSupportUndo));
|
result.pushKV(T_SUPPORTSADDEDORUPDATED, addedUpdated(undo.insertSupportUndo));
|
||||||
result.pushKV(T_SUPPORTSREMOVED, removedSupports(undo.expireSupportUndo));
|
result.pushKV(T_SUPPORTSREMOVED, removedToJSON(undo.expireSupportUndo));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4135,9 +4135,9 @@ BOOST_AUTO_TEST_CASE(update_on_support2_test)
|
||||||
BOOST_CHECK_EQUAL(node.nHeightOfLastTakeover, height + 1);
|
BOOST_CHECK_EQUAL(node.nHeightOfLastTakeover, height + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ValidatePairs(CClaimTrieCache& cache, const CClaimTrieProof& proof, uint256 claimHash)
|
void ValidatePairs(CClaimTrieCache& cache, const std::vector<std::pair<bool, uint256>>& pairs, uint256 claimHash)
|
||||||
{
|
{
|
||||||
for (auto& pair : proof.pairs)
|
for (auto& pair : pairs)
|
||||||
if (pair.first) // we're on the right because we were an odd index number
|
if (pair.first) // we're on the right because we were an odd index number
|
||||||
claimHash = Hash(pair.second.begin(), pair.second.end(), claimHash.begin(), claimHash.end());
|
claimHash = Hash(pair.second.begin(), pair.second.end(), claimHash.begin(), claimHash.end());
|
||||||
else
|
else
|
||||||
|
@ -4182,7 +4182,7 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_single_test)
|
||||||
BOOST_CHECK(proof.hasValue);
|
BOOST_CHECK(proof.hasValue);
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, outPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, outPoint);
|
||||||
auto claimHash = getValueHash(outPoint, proof.nHeightOfLastTakeover);
|
auto claimHash = getValueHash(outPoint, proof.nHeightOfLastTakeover);
|
||||||
ValidatePairs(fixture, proof, claimHash);
|
ValidatePairs(fixture, proof.pairs, claimHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(hash_includes_all_claims_triple_test)
|
BOOST_AUTO_TEST_CASE(hash_includes_all_claims_triple_test)
|
||||||
|
@ -4212,7 +4212,7 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_triple_test)
|
||||||
BOOST_CHECK(proof.hasValue);
|
BOOST_CHECK(proof.hasValue);
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
|
||||||
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
||||||
ValidatePairs(fixture, proof, claimHash);
|
ValidatePairs(fixture, proof.pairs, claimHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4243,7 +4243,7 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_branched_test)
|
||||||
BOOST_CHECK(proof.hasValue);
|
BOOST_CHECK(proof.hasValue);
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
|
||||||
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
||||||
ValidatePairs(fixture, proof, claimHash);
|
ValidatePairs(fixture, proof.pairs, claimHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4278,9 +4278,186 @@ BOOST_AUTO_TEST_CASE(hash_claims_children_fuzzer_test)
|
||||||
BOOST_CHECK(proof.hasValue);
|
BOOST_CHECK(proof.hasValue);
|
||||||
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
|
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
|
||||||
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
|
||||||
ValidatePairs(fixture, proof, claimHash);
|
ValidatePairs(fixture, proof.pairs, claimHash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<bool, uint256>> jsonToPairs(const UniValue& jsonPair)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<bool, uint256>> 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()));
|
||||||
|
}
|
||||||
|
return pairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(hash_bid_seq_claim_changes_test)
|
||||||
|
{
|
||||||
|
ClaimTrieChainFixture fixture;
|
||||||
|
fixture.setHashForkHeight(2);
|
||||||
|
fixture.IncrementBlocks(4);
|
||||||
|
|
||||||
|
std::string name = "toa";
|
||||||
|
std::string value1 = "one", value2 = "two", value3 = "tre", value4 = "for";
|
||||||
|
|
||||||
|
auto tx1 = fixture.MakeClaim(fixture.GetCoinbase(), name, value1, 1);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
|
CMutableTransaction tx2 = BuildTransaction(fixture.GetCoinbase(), 0, 2);
|
||||||
|
tx2.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME
|
||||||
|
<< std::vector<unsigned char>(name.begin(), name.end())
|
||||||
|
<< std::vector<unsigned char>(value2.begin(), value2.end()) << OP_2DROP << OP_DROP << OP_TRUE;
|
||||||
|
tx2.vout[0].nValue = 3;
|
||||||
|
tx2.vout[1].scriptPubKey = CScript() << OP_CLAIM_NAME
|
||||||
|
<< std::vector<unsigned char>(name.begin(), name.end())
|
||||||
|
<< std::vector<unsigned char>(value3.begin(), value3.end()) << OP_2DROP << OP_DROP << OP_TRUE;
|
||||||
|
tx2.vout[1].nValue = 2;
|
||||||
|
|
||||||
|
fixture.CommitTx(tx2);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
|
auto tx3 = fixture.MakeClaim(fixture.GetCoinbase(), name, value4, 4);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
|
||||||
|
int height = chainActive.Height();
|
||||||
|
|
||||||
|
auto claimId1 = ClaimIdHash(tx1.GetHash(), 0);
|
||||||
|
auto claimId2 = ClaimIdHash(tx2.GetHash(), 0);
|
||||||
|
auto claimId3 = ClaimIdHash(tx2.GetHash(), 1);
|
||||||
|
auto claimId4 = ClaimIdHash(tx3.GetHash(), 0);
|
||||||
|
|
||||||
|
int claim1bid = 3, claim1seq = 0;
|
||||||
|
int claim2bid = 1, claim2seq = 1;
|
||||||
|
int claim3bid = 2, claim3seq = 2;
|
||||||
|
int claim4bid = 0, claim4seq = 3;
|
||||||
|
|
||||||
|
auto getclaimsforname = tableRPC["getclaimsforname"]->actor;
|
||||||
|
|
||||||
|
JSONRPCRequest req;
|
||||||
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
req.params.push_back(UniValue(name));
|
||||||
|
|
||||||
|
auto result = getclaimsforname(req);
|
||||||
|
auto claims = result[T_CLAIMS];
|
||||||
|
BOOST_CHECK_EQUAL(claims.size(), 4U);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_LASTTAKEOVERHEIGHT].get_int(), height);
|
||||||
|
BOOST_CHECK_EQUAL(claims[0][T_EFFECTIVEAMOUNT].get_int(), 4);
|
||||||
|
BOOST_CHECK_EQUAL(claims[0][T_BID].get_int(), claim4bid);
|
||||||
|
BOOST_CHECK_EQUAL(claims[0][T_SEQUENCE].get_int(), claim4seq);
|
||||||
|
BOOST_CHECK_EQUAL(claims[0][T_CLAIMID].get_str(), claimId4.GetHex());
|
||||||
|
BOOST_CHECK_EQUAL(claims[1][T_EFFECTIVEAMOUNT].get_int(), 3);
|
||||||
|
BOOST_CHECK_EQUAL(claims[1][T_BID].get_int(), claim2bid);
|
||||||
|
BOOST_CHECK_EQUAL(claims[1][T_SEQUENCE].get_int(), claim2seq);
|
||||||
|
BOOST_CHECK_EQUAL(claims[1][T_CLAIMID].get_str(), claimId2.GetHex());
|
||||||
|
BOOST_CHECK_EQUAL(claims[2][T_EFFECTIVEAMOUNT].get_int(), 2);
|
||||||
|
BOOST_CHECK_EQUAL(claims[2][T_BID].get_int(), claim3bid);
|
||||||
|
BOOST_CHECK_EQUAL(claims[2][T_SEQUENCE].get_int(), claim3seq);
|
||||||
|
BOOST_CHECK_EQUAL(claims[2][T_CLAIMID].get_str(), claimId3.GetHex());
|
||||||
|
BOOST_CHECK_EQUAL(claims[3][T_EFFECTIVEAMOUNT].get_int(), 1);
|
||||||
|
BOOST_CHECK_EQUAL(claims[3][T_BID].get_int(), claim1bid);
|
||||||
|
BOOST_CHECK_EQUAL(claims[3][T_SEQUENCE].get_int(), claim1seq);
|
||||||
|
BOOST_CHECK_EQUAL(claims[3][T_CLAIMID].get_str(), claimId1.GetHex());
|
||||||
|
|
||||||
|
auto getclaimbybid = tableRPC["getclaimbybid"]->actor;
|
||||||
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
req.params.push_back(UniValue(name));
|
||||||
|
req.params.push_back(UniValue(claim3bid));
|
||||||
|
|
||||||
|
result = getclaimbybid(req);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_LASTTAKEOVERHEIGHT].get_int(), height);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_EFFECTIVEAMOUNT].get_int(), 2);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_BID].get_int(), claim3bid);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim3seq);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId3.GetHex());
|
||||||
|
|
||||||
|
auto getclaimbyseq = tableRPC["getclaimbyseq"]->actor;
|
||||||
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
req.params.push_back(UniValue(name));
|
||||||
|
req.params.push_back(UniValue(claim2seq));
|
||||||
|
|
||||||
|
result = getclaimbyseq(req);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_LASTTAKEOVERHEIGHT].get_int(), height);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_EFFECTIVEAMOUNT].get_int(), 3);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_BID].get_int(), claim2bid);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim2seq);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId2.GetHex());
|
||||||
|
|
||||||
|
auto getclaimbyid = tableRPC["getclaimbyid"]->actor;
|
||||||
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
req.params.push_back(UniValue(claimId1.GetHex()));
|
||||||
|
|
||||||
|
result = getclaimbyid(req);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_LASTTAKEOVERHEIGHT].get_int(), height);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_EFFECTIVEAMOUNT].get_int(), 1);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_BID].get_int(), claim1bid);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim1seq);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId1.GetHex());
|
||||||
|
|
||||||
|
// check by partial id (at least 3 chars)
|
||||||
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
req.params.push_back(UniValue(claimId3.GetHex().substr(0, 3)));
|
||||||
|
|
||||||
|
result = getclaimbyid(req);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_LASTTAKEOVERHEIGHT].get_int(), height);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_EFFECTIVEAMOUNT].get_int(), 2);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_BID].get_int(), claim3bid);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_SEQUENCE].get_int(), claim3seq);
|
||||||
|
BOOST_CHECK_EQUAL(result[T_CLAIMID].get_str(), claimId3.GetHex());
|
||||||
|
|
||||||
|
auto blockhash = chainActive.Tip()->GetBlockHash();
|
||||||
|
|
||||||
|
auto getnameproof = tableRPC["getnameproof"]->actor;
|
||||||
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
req.params.push_back(UniValue(name));
|
||||||
|
req.params.push_back(UniValue(blockhash.GetHex()));
|
||||||
|
req.params.push_back(UniValue(claimId3.GetHex()));
|
||||||
|
|
||||||
|
result = getnameproof(req);
|
||||||
|
auto claimHash = getValueHash(COutPoint(tx2.GetHash(), 1), result[T_LASTTAKEOVERHEIGHT].get_int());
|
||||||
|
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
||||||
|
|
||||||
|
// check by partial id (can be even 1 char)
|
||||||
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
req.params.push_back(UniValue(name));
|
||||||
|
req.params.push_back(UniValue(blockhash.GetHex()));
|
||||||
|
req.params.push_back(UniValue(claimId2.GetHex().substr(0, 2)));
|
||||||
|
|
||||||
|
result = getnameproof(req);
|
||||||
|
claimHash = getValueHash(COutPoint(tx2.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
||||||
|
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
||||||
|
|
||||||
|
auto getclaimproofbybid = tableRPC["getclaimproofbybid"]->actor;
|
||||||
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
req.params.push_back(UniValue(name));
|
||||||
|
req.params.push_back(UniValue(claim1bid));
|
||||||
|
|
||||||
|
result = getclaimproofbybid(req);
|
||||||
|
claimHash = getValueHash(COutPoint(tx1.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
||||||
|
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
||||||
|
|
||||||
|
auto getclaimproofbyseq = tableRPC["getclaimproofbyseq"]->actor;
|
||||||
|
req.params = UniValue(UniValue::VARR);
|
||||||
|
req.params.push_back(UniValue(name));
|
||||||
|
req.params.push_back(UniValue(claim4seq));
|
||||||
|
|
||||||
|
result = getclaimproofbyseq(req);
|
||||||
|
claimHash = getValueHash(COutPoint(tx3.GetHash(), 0), result[T_LASTTAKEOVERHEIGHT].get_int());
|
||||||
|
ValidatePairs(fixture, jsonToPairs(result[T_PAIRS]), claimHash);
|
||||||
|
|
||||||
|
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(), 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);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Reference in a new issue