[WIP] Unify and extend rpc methods to bid and sequence #303

Merged
bvbfan merged 8 commits from rpc_hash_hardfork into master 2019-09-06 22:03:39 +02:00
12 changed files with 1461 additions and 816 deletions

View file

@ -155,6 +155,7 @@ BITCOIN_CORE_H = \
reverse_iterator.h \
reverselock.h \
rpc/blockchain.h \
rpc/claimrpchelp.h \
rpc/client.h \
rpc/mining.h \
rpc/protocol.h \

View file

@ -391,45 +391,56 @@ bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& c
return base->find(name, claims) && claims.getBestClaim(claim);
}
CClaimsForNameType CClaimTrieCacheBase::getClaimsForName(const std::string& name) const
template <typename T>
void CClaimTrieCacheBase::insertRowsFromQueue(std::vector<T>& result, const std::string& name) const
{
supportedType<T>();
if (auto nameRows = getQueueCacheNameRow<T>(name))
for (auto& nameRow : *nameRows)
if (auto rows = getQueueCacheRow<T>(nameRow.nHeight))
for (auto& row : *rows)
if (row.first == name)
result.push_back(row.second);
}
CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& name) const
{
claimEntryType claims;
int nLastTakeoverHeight = 0;
auto supports = getSupportsForName(name);
insertRowsFromQueue(supports, name);
CClaimTrieData data;
if (auto it = nodesToAddOrUpdate.find(name)) {
claims = it->claims;
nLastTakeoverHeight = it->nHeightOfLastTakeover;
}
else if (!nodesToDelete.count(name) && base->find(name, data)) {
} else if (!nodesToDelete.count(name)) {
CClaimTrieData data;
if (base->find(name, data)) {
claims = data.claims;
nLastTakeoverHeight = data.nHeightOfLastTakeover;
}
return {std::move(claims), std::move(supports), nLastTakeoverHeight, name};
}
insertRowsFromQueue(claims, name);
CAmount CClaimTrieCacheBase::getEffectiveAmountForClaim(const std::string& name, const uint160& claimId, std::vector<CSupportValue>* supports) const
{
return getEffectiveAmountForClaim(getClaimsForName(name), claimId, supports);
}
auto find = [&supports](decltype(supports)::iterator& it, const CClaimValue& claim) {
it = std::find_if(it, supports.end(), [&claim](const CSupportValue& support) {
return claim.claimId == support.supportedClaimId;
});
return it != supports.end();
};
CAmount CClaimTrieCacheBase::getEffectiveAmountForClaim(const CClaimsForNameType& claims, const uint160& claimId, std::vector<CSupportValue>* supports) const
{
CAmount effectiveAmount = 0;
for (const auto& claim : claims.claims) {
if (claim.claimId == claimId && claim.nValidAtHeight < nNextHeight) {
effectiveAmount += claim.nAmount;
for (const auto& support : claims.supports) {
if (support.supportedClaimId == claimId && support.nValidAtHeight < nNextHeight) {
effectiveAmount += support.nAmount;
if (supports) supports->push_back(support);
// match support to claim
std::vector<CClaimNsupports> claimsNsupports;
for (const auto& claim : claims) {
CAmount nAmount = claim.nValidAtHeight < nNextHeight ? claim.nAmount : 0;
auto ic = claimsNsupports.emplace(claimsNsupports.end(), claim, nAmount);
for (auto it = supports.begin(); find(it, claim); it = supports.erase(it)) {
if (it->nValidAtHeight < nNextHeight)
ic->effectiveAmount += it->nAmount;
ic->supports.emplace_back(std::move(*it));
}
}
break;
}
}
return effectiveAmount;
return {name, nLastTakeoverHeight, std::move(claimsNsupports), std::move(supports)};
}
void completeHash(uint256& partialHash, const std::string& key, std::size_t to)
@ -532,19 +543,6 @@ bool CClaimTrie::find(const std::string& key, CClaimTrieData &data) const {
return db->Read(std::make_pair(TRIE_NODE_CLAIMS, key), data);
}
bool CClaimTrieCacheBase::getClaimById(const uint160& claimId, std::string& name, CClaimValue& claim) const
{
CClaimIndexElement element;
if (!base->db->Read(std::make_pair(CLAIM_BY_ID, claimId), element))
return false;
if (element.claim.claimId == claimId) {
name = element.name;
claim = element.claim;
return true;
}
return false;
}
template <typename K, typename T>
void BatchWrite(CDBBatch& batch, uint8_t dbkey, const K& key, const std::vector<T>& value)
{

View file

@ -36,10 +36,10 @@ struct CClaimValue
{
COutPoint outPoint;
uint160 claimId;
CAmount nAmount;
CAmount nEffectiveAmount;
int nHeight;
int nValidAtHeight;
CAmount nAmount = 0;
CAmount nEffectiveAmount = 0;
int nHeight = 0;
int nValidAtHeight = 0;
CClaimValue() = default;
@ -94,9 +94,9 @@ struct CSupportValue
{
COutPoint outPoint;
uint160 supportedClaimId;
CAmount nAmount;
int nHeight;
int nValidAtHeight;
CAmount nAmount = 0;
int nHeight = 0;
int nValidAtHeight = 0;
CSupportValue() = default;
@ -213,7 +213,7 @@ struct CClaimTrieDataNode {
struct COutPointHeightType
{
COutPoint outPoint;
int nHeight;
int nHeight = 0;
COutPointHeightType() = default;
@ -236,7 +236,7 @@ struct CNameOutPointHeightType
{
std::string name;
COutPoint outPoint;
int nHeight;
int nHeight = 0;
CNameOutPointHeightType() = default;
@ -305,22 +305,63 @@ struct CClaimIndexElement
CClaimValue claim;
};
struct CClaimsForNameType
struct CClaimNsupports
{
claimEntryType claims;
supportEntryType supports;
int nLastTakeoverHeight;
std::string name;
CClaimNsupports() = default;
CClaimNsupports(CClaimNsupports&&) = default;
CClaimNsupports(const CClaimNsupports&) = default;
CClaimsForNameType(claimEntryType claims, supportEntryType supports, int nLastTakeoverHeight, std::string name)
: claims(std::move(claims)), supports(std::move(supports)), nLastTakeoverHeight(nLastTakeoverHeight), name(std::move(name))
CClaimNsupports& operator=(CClaimNsupports&&) = default;
CClaimNsupports& operator=(const CClaimNsupports&) = default;
CClaimNsupports(const CClaimValue& claim, CAmount effectiveAmount, const std::vector<CSupportValue>& supports = {})
: claim(claim), effectiveAmount(effectiveAmount), supports(supports)
{
}
CClaimsForNameType(CClaimsForNameType&&) = default;
CClaimsForNameType(const CClaimsForNameType&) = default;
CClaimsForNameType& operator=(CClaimsForNameType&&) = default;
CClaimsForNameType& operator=(const CClaimsForNameType&) = default;
bool IsNull() const
{
return claim.claimId.IsNull();
}
CClaimValue claim;
CAmount effectiveAmount = 0;
std::vector<CSupportValue> supports;
};
static const CClaimNsupports invalid;
struct CClaimSupportToName
{
CClaimSupportToName(const std::string& name, int nLastTakeoverHeight, std::vector<CClaimNsupports> claimsNsupports, std::vector<CSupportValue> unmatchedSupports)
: name(name), nLastTakeoverHeight(nLastTakeoverHeight), claimsNsupports(std::move(claimsNsupports)), unmatchedSupports(std::move(unmatchedSupports))
{
}
const CClaimNsupports& find(const uint160& claimId) const
{
auto it = std::find_if(claimsNsupports.begin(), claimsNsupports.end(), [&claimId](const CClaimNsupports& value) {
return claimId == value.claim.claimId;
});
return it != claimsNsupports.end() ? *it : invalid;
}
const CClaimNsupports& find(const std::string& partialId) const
{
std::string lowered(partialId);
for (auto& c: lowered)
c = std::tolower(c);
auto it = std::find_if(claimsNsupports.begin(), claimsNsupports.end(), [&lowered](const CClaimNsupports& value) {
return value.claim.claimId.GetHex().find(lowered) == 0;
});
return it != claimsNsupports.end() ? *it : invalid;
}
const std::string name;
const int nLastTakeoverHeight;
const std::vector<CClaimNsupports> claimsNsupports;
const std::vector<CSupportValue> unmatchedSupports;
};
class CClaimTrie
@ -341,6 +382,8 @@ public:
friend struct ClaimTrieChainFixture;
friend class CClaimTrieCacheExpirationFork;
friend class CClaimTrieCacheNormalizationFork;
friend bool getClaimById(const uint160&, std::string&, CClaimValue*);
friend bool getClaimById(const std::string&, std::string&, CClaimValue*);
std::size_t getTotalNamesInTrie() const;
std::size_t getTotalClaimsInTrie() const;
@ -475,8 +518,6 @@ public:
uint256 getMerkleHash();
bool getClaimById(const uint160& claimId, std::string& name, CClaimValue& claim) const;
bool flush();
bool empty() const;
bool ReadFromDisk(const CBlockIndex* tip);
@ -517,10 +558,7 @@ public:
virtual bool finalizeDecrement(std::vector<std::pair<std::string, int>>& takeoverHeightUndo);
virtual CClaimsForNameType getClaimsForName(const std::string& name) const;
CAmount getEffectiveAmountForClaim(const std::string& name, const uint160& claimId, std::vector<CSupportValue>* supports = nullptr) const;
CAmount getEffectiveAmountForClaim(const CClaimsForNameType& claims, const uint160& claimId, std::vector<CSupportValue>* supports = nullptr) const;
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
CClaimPrefixTrie::const_iterator begin() const;
CClaimPrefixTrie::const_iterator end() const;
@ -594,6 +632,9 @@ private:
bool validateTrieConsistency(const CBlockIndex* tip);
template <typename T>
void insertRowsFromQueue(std::vector<T>& result, const std::string& name) const;
template <typename T>
std::vector<queueEntryType<T>>* getQueueCacheRow(int nHeight, bool createIfNotExists);
@ -704,7 +745,7 @@ public:
bool getProofForName(const std::string& name, CClaimTrieProof& proof) override;
bool getInfoForName(const std::string& name, CClaimValue& claim) const override;
CClaimsForNameType getClaimsForName(const std::string& name) const override;
CClaimSupportToName getClaimsForName(const std::string& name) const override;
std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
protected:
@ -733,7 +774,7 @@ public:
explicit CClaimTrieCacheHashFork(CClaimTrie* base);
bool getProofForName(const std::string& name, CClaimTrieProof& proof) override;
bool getProofForName(const std::string& name, CClaimTrieProof& proof, const uint160& claimId);
bool getProofForName(const std::string& name, CClaimTrieProof& proof, const std::function<bool(const CClaimValue&)>& comp);
void initializeIncrement() override;
bool finalizeDecrement(std::vector<std::pair<std::string, int>>& takeoverHeightUndo) override;

View file

@ -246,7 +246,7 @@ bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, C
return CClaimTrieCacheExpirationFork::getInfoForName(normalizeClaimName(name), claim);
}
CClaimsForNameType CClaimTrieCacheNormalizationFork::getClaimsForName(const std::string& name) const
CClaimSupportToName CClaimTrieCacheNormalizationFork::getClaimsForName(const std::string& name) const
{
return CClaimTrieCacheExpirationFork::getClaimsForName(normalizeClaimName(name));
}
@ -408,10 +408,10 @@ std::vector<uint256> ComputeMerklePath(const std::vector<uint256>& hashes, uint3
bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTrieProof& proof)
{
return getProofForName(name, proof, uint160());
return getProofForName(name, proof, nullptr);
}
bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTrieProof& proof, const uint160& claimId)
bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTrieProof& proof, const std::function<bool(const CClaimValue&)>& comp)
{
if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
return CClaimTrieCacheNormalizationFork::getProofForName(name, proof);
@ -445,10 +445,7 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTri
if (it.key() == name) {
uint32_t nClaimIndex = 0;
auto& claims = it->claims;
auto itClaim = claimId.IsNull() ? claims.begin() :
std::find_if(claims.begin(), claims.end(), [&claimId](const CClaimValue& claim) {
return claim.claimId == claimId;
});
auto itClaim = !comp ? claims.begin() : std::find_if(claims.begin(), claims.end(), comp);
if (itClaim != claims.end()) {
proof.hasValue = true;
proof.outPoint = itClaim->outPoint;

345
src/rpc/claimrpchelp.h Normal file
View file

@ -0,0 +1,345 @@
#ifndef CLAIMRPCHELP_H
#define CLAIMRPCHELP_H
// always keep defines T_ + value in upper case
#define T_NORMALIZEDNAME "normalizedName"
#define T_BLOCKHASH "blockhash"
#define T_CLAIMS "claims"
#define T_CLAIMID "claimId"
#define T_TXID "txId"
#define T_N "n"
#define T_AMOUNT "amount"
#define T_HEIGHT "height"
#define T_VALUE "value"
#define T_NAME "name"
#define T_VALIDATHEIGHT "validAtHeight"
#define T_NAMES "names"
#define T_EFFECTIVEAMOUNT "effectiveAmount"
#define T_LASTTAKEOVERHEIGHT "lastTakeoverHeight"
#define T_SUPPORTS "supports"
#define T_SUPPORTSWITHOUTCLAIM "supportsWithoutClaim"
#define T_TOTALNAMES "totalNames"
#define T_TOTALCLAIMS "totalClaims"
#define T_TOTALVALUE "totalValue"
#define T_CONTROLLINGONLY "controllingOnly"
#define T_CLAIMTYPE "claimType"
#define T_DEPTH "depth"
#define T_INCLAIMTRIE "inClaimTrie"
#define T_ISCONTROLLING "isControlling"
#define T_INSUPPORTMAP "inSupportMap"
#define T_INQUEUE "inQueue"
#define T_BLOCKSTOVALID "blocksToValid"
#define T_NODES "nodes"
#define T_CHILDREN "children"
#define T_CHARACTER "character"
#define T_NODEHASH "nodeHash"
#define T_VALUEHASH "valueHash"
#define T_PAIRS "pairs"
#define T_ODD "odd"
#define T_HASH "hash"
#define T_BID "bid"
#define T_SEQUENCE "sequence"
#define T_CLAIMSADDEDORUPDATED "claimsAddedOrUpdated"
#define T_SUPPORTSADDEDORUPDATED "supportsAddedOrUpdated"
#define T_CLAIMSREMOVED "claimsRemoved"
#define T_SUPPORTSREMOVED "supportsRemoved"
#define T_ADDRESS "address"
#define T_PENDINGAMOUNT "pendingAmount"
enum {
GETCLAIMSINTRIE = 0,
GETNAMESINTRIE,
GETVALUEFORNAME,
GETCLAIMSFORNAME,
GETCLAIMBYID,
GETTOTALCLAIMEDNAMES,
GETTOTALCLAIMS,
GETTOTALVALUEOFCLAIMS,
GETCLAIMSFORTX,
GETNAMEPROOF,
CHECKNORMALIZATION,
GETCLAIMBYBID,
GETCLAIMBYSEQ,
GETCLAIMPROOFBYBID,
GETCLAIMPROOFBYSEQ,
GETCHANGESINBLOCK,
};
#define S3_(pre, name, def) pre "\"" name "\"" def "\n"
#define S3(pre, name, def) S3_(pre, name, def)
#define S1(str) str "\n"
#define NAME_TEXT " (string) the name to look up"
#define BLOCKHASH_TEXT " (string, optional) get claims in the trie\n" \
" at the block specified\n" \
" by this block hash.\n" \
" If none is given,\n" \
" the latest active\n" \
" block will be used."
#define CLAIM_OUTPUT \
tiger5226 commented 2019-08-21 03:10:39 +02:00 (Migrated from github.com)
Review

These are less readable than before. I actually used these quite often.

These are less readable than before. I actually used these quite often.
bvbfan commented 2019-08-21 16:25:25 +02:00 (Migrated from github.com)
Review

I think is more readable now :) You see it on one place and there is no need to verify it's same or not and it's correct on every place or not.

I think is more readable now :) You see it on one place and there is no need to verify it's same or not and it's correct on every place or not.
tiger5226 commented 2019-08-23 03:50:03 +02:00 (Migrated from github.com)
Review

I was also looking at it through the PR lens. Will look at it in the code base too.

I was also looking at it through the PR lens. Will look at it in the code base too.
bvbfan commented 2019-08-23 13:23:17 +02:00 (Migrated from github.com)
Review

Overall code base is way better to me, logic and help message are separate which makes logic to be easy follow, OTOH help message are minimize.

Overall code base is way better to me, logic and help message are separate which makes logic to be easy follow, OTOH help message are minimize.
S3(" ", T_NORMALIZEDNAME, " (string) the name of the claim (after normalization)") \
S3(" ", T_NAME, " (string) the original name of this claim (before normalization)") \
S3(" ", T_VALUE, " (string) the value of this claim") \
S3(" ", T_ADDRESS, " (string) the destination address of this claim") \
S3(" ", T_CLAIMID, " (string) the claimId of the claim") \
S3(" ", T_TXID, " (string) the txid of the claim") \
S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs") \
S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located") \
S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the support became/becomes valid") \
S3(" ", T_AMOUNT, " (numeric) the amount of the claim") \
S3(" ", T_EFFECTIVEAMOUNT, " (numeric) the amount plus amount from all supports associated with the claim") \
S3(" ", T_PENDINGAMOUNT, " (numeric) expected amount when claim and its supports are all valid") \
S3(" ", T_SUPPORTS, ": [ (array of object) supports for this claim") \
S3(" ", T_VALUE, " (string) the metadata of the support if any") \
S3(" ", T_ADDRESS, " (string) the destination address of the support") \
S3(" ", T_TXID, " (string) the txid of the support") \
S3(" ", T_N, " (numeric) the index of the support in the transaction's list of outputs") \
S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located") \
S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the support became/becomes valid") \
S3(" ", T_AMOUNT, " (numeric) the amount of the support") \
S1(" ]") \
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_SEQUENCE, " (numeric) lower value means an older one in sequence, ordered by height of insertion")
#define PROOF_OUTPUT \
S3(" ", T_NODES, ": [ (array of object, pre-fork) full nodes\n" \
" (i.e. those which lead to the requested name)") \
S3(" ", T_CHILDREN, ": [ (array of object) the children of the node") \
S3(" ", T_CHARACTER, " (string) the character which leads from the parent to this child node") \
S3(" ", T_NODEHASH, " (string, if exists) the hash of the node if this is a leaf node") \
S1(" ]") \
S3(" ", T_VALUEHASH, " (string, if exists) the hash of this node's value, if" \
" it has one. If this is the requested name this\n" \
" will not exist whether the node has a value or not") \
S1(" ]") \
S3(" ", T_PAIRS, ": [ (array of pairs, post-fork) hash can be validated by" \
" hashing claim from the bottom up") \
S3(" ", T_ODD, " (boolean) this value goes on the right of hash") \
S3(" ", T_HASH, " (string) the hash to be mixed in") \
S1(" ]") \
S3(" ", T_TXID, " (string, if exists) the txid of the claim which controls" \
" this name, if there is one.") \
S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs") \
S3(" ", T_LASTTAKEOVERHEIGHT, " (numeric) the last height at which ownership of the name changed")
static const char* const rpc_help[] = {
// GETCLAIMSINTRIE
S1(R"(getclaimsintrie
Return all claims in the name trie. Deprecated
Arguments:)")
S3("1. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S1("Result: [")
S3(" ", T_NORMALIZEDNAME, " (string) the name of the claim(s) (after normalization)")
S3(" ", T_CLAIMS, ": [ (array of object) the claims for this name")
S3(" ", T_NAME, " (string) the original name of this claim (before normalization)")
S3(" ", T_VALUE, " (string) the value of this claim")
S3(" ", T_ADDRESS, " (string) the destination address of this claim")
S3(" ", T_CLAIMID, " (string) the claimId of the claim")
S3(" ", T_TXID, " (string) the txid of the claim")
S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs")
S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located")
S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the claim became/becomes valid")
S3(" ", T_AMOUNT, " (numeric) the amount of the claim")
S1(" ]")
"]",
// GETNAMESINTRIE
S1(R"(getnamesintrie
Return all claim names in the trie.
Arguments:)")
S3("1. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S1("Result: [")
S3(" ", T_NAMES, " all names in the trie that have claims")
"]",
// GETVALUEFORNAME
S1(R"(getvalueforname
Return the winning or specified by claimId value associated with a name
Arguments:)")
S3("1. ", T_NAME, NAME_TEXT)
S3("2. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S3("3. ", T_CLAIMID, " (string, optional) can be partial one")
S1("Result: [")
CLAIM_OUTPUT
"]",
// GETCLAIMSFORNAME
S1(R"(getclaimsforname
Return all claims and supports for a name
Arguments:)")
S3("1. ", T_NAME, NAME_TEXT)
S3("2. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S1("Result: [")
S3(" ", T_NORMALIZEDNAME, " (string) the name of the claim(s) (after normalization)")
S3(" ", T_CLAIMS, ": [ (array of object) the claims for this name")
S3(" ", T_NAME, " (string) the original name of this claim (before normalization)")
S3(" ", T_VALUE, " (string) the value of this claim")
S3(" ", T_ADDRESS, " (string) the destination address of this claim")
S3(" ", T_CLAIMID, " (string) the claimId of the claim")
S3(" ", T_TXID, " (string) the txid of the claim")
S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs")
S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located")
S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the claim became/becomes valid")
S3(" ", T_AMOUNT, " (numeric) the amount of the claim")
S3(" ", T_EFFECTIVEAMOUNT, " (numeric) the amount plus amount from all supports associated with the claim")
S3(" ", T_PENDINGAMOUNT, " (numeric) expected amount when claim and its support got valid")
S3(" ", T_SUPPORTS, ": [ (array of object) supports for this claim")
S3(" ", T_VALUE, " (string) the metadata of the support if any")
S3(" ", T_ADDRESS, " (string) the destination address of the support")
S3(" ", T_TXID, " (string) the txid of the support")
S3(" ", T_N, " (numeric) the index of the support in the transaction's list of outputs")
S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located")
S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the support became/becomes valid")
S3(" ", T_AMOUNT, " (numeric) the amount of the support")
S1(" ]")
S3(" ", T_BID, " (numeric) lower value means a higher bid rate, ordered by effective amount")
S3(" ", T_SEQUENCE, " (numeric) lower value means an older one in sequence, ordered by height of insertion")
S1(" ]")
S3(" ", T_LASTTAKEOVERHEIGHT, " (numeric) the last height at which ownership of the name changed")
S3(" ", T_SUPPORTSWITHOUTCLAIM, ": [")
S3(" ", T_TXID, " (string) the txid of the support")
S3(" ", T_N, " (numeric) the index of the support in the transaction's list of outputs")
S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located")
S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the support became/becomes valid")
S3(" ", T_AMOUNT, " (numeric) the amount of the support")
S1(" ]")
"]",
// GETCLAIMBYID
S1(R"(getclaimbyid
Get a claim by claim id
Arguments:)")
S3("1. ", T_CLAIMID, " (string) the claimId of this claim or patial id (at least 3 chars)")
S1("Result: [")
CLAIM_OUTPUT
"]",
// GETTOTALCLAIMEDNAMES
S1(R"(gettotalclaimednames
Return the total number of names that have been
Arguments:)")
S1("Result:")
S3(" ", T_TOTALNAMES, " (numeric) the total number of names in the trie")
,
// GETTOTALCLAIMS
S1(R"(gettotalclaims
Return the total number of active claims in the trie
Arguments:)")
S1("Result:")
S3(" ", T_TOTALCLAIMS, " (numeric) the total number of active claims")
,
// GETTOTALVALUEOFCLAIMS
S1(R"(gettotalvalueofclaims
Return the total value of the claims in the trie
Arguments:)")
S3("1. ", T_CONTROLLINGONLY, " (boolean) only include the value of controlling claims")
S1("Result:")
S3(" ", T_TOTALVALUE, " (numeric) the total value of the claims in the trie")
,
// GETCLAIMSFORTX
S1(R"(getclaimsfortx
Return any claims or supports found in a transaction
Arguments:)")
S3("1. ", T_TXID, " (string) the txid of the transaction to check for unspent claims")
S1("Result: [")
S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs")
S3(" ", T_CLAIMTYPE, " (string) claim or support")
S3(" ", T_NAME, " (string) the name claimed or supported")
S3(" ", T_CLAIMID, " (string) if a claim, its ID")
S3(" ", T_VALUE, " (string) if a claim, its value")
S3(" ", T_DEPTH, " (numeric) the depth of the transaction in the main chain")
S3(" ", T_INCLAIMTRIE, " (boolean) if a name claim, whether the claim is active, i.e. has made it into the trie")
S3(" ", T_ISCONTROLLING, " (boolean) if a name claim, whether the claim is the current controlling claim for the name")
S3(" ", T_INSUPPORTMAP, " (boolean) if a support, whether the support is active, i.e. has made it into the support map")
S3(" ", T_INQUEUE, " (boolean) whether the claim is in a queue waiting to be inserted into the trie or support map")
S3(" ", T_BLOCKSTOVALID, " (numeric) if in a queue, the number of blocks until it's inserted into the trie or support map")
"]",
// GETNAMEPROOF
S1(R"(getnameproof
Return the cryptographic proof that a name maps to a value or doesn't.
Arguments:)")
S3("1. ", T_NAME, NAME_TEXT)
S3("2. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S3("3. ", T_CLAIMID, R"( (string, optional, post-fork) for validating a specific claim
can be partial one)")
S1("Result: [")
PROOF_OUTPUT
"]",
// CHECKNORMALIZATION
S1(R"(checknormalization
Given an unnormalized name of a claim, return normalized version of it
Arguments:)")
S3("1. ", T_NAME, " (string) the name to normalize")
S1("Result:")
S3(" ", T_NORMALIZEDNAME, " (string) normalized name")
,
// GETCLAIMBYBID
S1(R"(getclaimbybid
Get a claim by bid
Arguments:)")
S3("1. ", T_NAME, NAME_TEXT)
S3("2. ", T_BID, " (numeric) bid number")
S3("3. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S1("Result: [")
CLAIM_OUTPUT
"]",
// GETCLAIMBYSEQ
S1(R"(getclaimbyseq
Get a claim by sequence
Arguments:)")
S3("1. ", T_NAME, NAME_TEXT)
S3("2. ", T_SEQUENCE, " (numeric) sequence number")
S3("3. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S1("Result: [")
CLAIM_OUTPUT
"]",
// GETCLAIMPROOFBYBID
S1(R"(getclaimproofbyid
Return the cryptographic proof that a name maps to a value or doesn't by a bid.
Arguments:)")
S3("1. ", T_NAME, NAME_TEXT)
S3("2. ", T_BID, " (numeric) bid number")
S3("3. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S1("Result: [")
PROOF_OUTPUT
"]",
// GETCLAIMPROOFBYSEQ
S1(R"(getclaimproofbyseq
Return the cryptographic proof that a name maps to a value or doesn't by a sequence.
Arguments:)")
S3("1. ", T_NAME, NAME_TEXT)
S3("2. ", T_SEQUENCE, " (numeric) sequence number")
S3("3. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S1("Result: [")
PROOF_OUTPUT
"]",
// GETCHANGESINBLOCK
S1(R"(getchangesinblock
Return the list of claims added, updated, and removed as pulled from the queued work for that block."
Use this method to determine which claims or supports went live on a given block."
Arguments:)")
S3("1. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S1("Result: [")
S3(" ", T_CLAIMSADDEDORUPDATED, " (array of string) claimIDs added or updated in the trie")
S3(" ", T_CLAIMSREMOVED, " (array of string) claimIDs that were removed from the trie")
S3(" ", T_SUPPORTSADDEDORUPDATED, " (array of string) IDs of supports added or updated")
S3(" ", T_SUPPORTSREMOVED, " (array of string) IDs that were removed from the trie")
"]",
};
#endif // CLAIMRPCHELP_H

File diff suppressed because it is too large Load diff

View file

@ -174,6 +174,11 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listnameclaims", 0, "includesupports"},
{ "listnameclaims", 1, "activeonly"},
{ "listnameclaims", 2, "minconf"},
{ "getclaimbybid", 1, "bid"},
{ "getclaimbyseq", 1, "sequence"},
{ "getclaimproofbybid", 1, "bid"},
{ "getclaimproofbyseq", 1, "sequence"},
{ "supportclaim", 4, "isTip"},
};
class CRPCConvertTable

View file

@ -13,6 +13,7 @@
#include <pow.h>
#include <primitives/transaction.h>
#include <random.h>
#include <rpc/claimrpchelp.h>
#include <rpc/server.h>
#include <streams.h>
#include <test/test_bitcoin.h>
@ -25,6 +26,7 @@
extern ::CChainState g_chainstate;
extern ::ArgsManager gArgs;
extern std::vector<std::string> random_strings(std::size_t count);
extern bool getClaimById(const uint160&, std::string&, CClaimValue*);
using namespace std;
@ -434,7 +436,7 @@ struct ClaimTrieChainFixture: public CClaimTrieCache
res.message() << "No claim found";
return res;
} else {
CAmount effective_amount = getEffectiveAmountForClaim(name, val.claimId);
CAmount effective_amount = getClaimsForName(name).find(val.claimId).effectiveAmount;
if (effective_amount != amount) {
boost::test_tools::predicate_result res(false);
res.message() << amount << " != " << effective_amount;
@ -566,12 +568,12 @@ BOOST_AUTO_TEST_CASE(claim_test)
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2);
fixture.IncrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("test",tx3));
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
fixture.DecrementBlocks(1);
BOOST_CHECK(!fixture.is_best_claim("test",tx2));
BOOST_CHECK(!fixture.is_best_claim("test",tx3));
BOOST_CHECK_EQUAL(0U, fixture.getClaimsForName("test").claims.size());
BOOST_CHECK_EQUAL(0U, fixture.getClaimsForName("test").claimsNsupports.size());
// make two claims , one older
CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1);
@ -583,7 +585,7 @@ BOOST_AUTO_TEST_CASE(claim_test)
BOOST_CHECK(fixture.is_best_claim("test", tx4));
fixture.IncrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("test",tx4));
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
fixture.DecrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("test", tx4));
@ -603,7 +605,7 @@ BOOST_AUTO_TEST_CASE(claim_test)
BOOST_CHECK(fixture.is_best_claim("test", tx6));
fixture.IncrementBlocks(10);
BOOST_CHECK(fixture.is_best_claim("test",tx7));
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
fixture.DecrementBlocks(10);
BOOST_CHECK(fixture.is_claim_in_queue("test",tx7));
@ -873,7 +875,7 @@ BOOST_AUTO_TEST_CASE(support_spend_test)
CMutableTransaction s2 = fixture.MakeSupport(fixture.GetCoinbase(),tx5,"test",2);
fixture.IncrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("test",tx5));
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
// build the spend where s2 is sppent on txin[1] and tx3 is spent on txin[0]
uint32_t prevout = 0;
@ -938,7 +940,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test)
CMutableTransaction u3 = fixture.MakeUpdate(tx3, "test", "one", ClaimIdHash(tx3.GetHash(), 0), 2);
fixture.IncrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("test",u3));
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
fixture.DecrementBlocks(11);
// losing update on winning claim happens without delay
@ -946,7 +948,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test)
CMutableTransaction tx6 = fixture.MakeClaim(fixture.GetCoinbase(), "test", "one", 2);
fixture.IncrementBlocks(10);
BOOST_CHECK(fixture.is_best_claim("test", tx5));
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claims.size());
BOOST_CHECK_EQUAL(2U, fixture.getClaimsForName("test").claimsNsupports.size());
CMutableTransaction u4 = fixture.MakeUpdate(tx5, "test", "one", ClaimIdHash(tx5.GetHash(), 0), 1);
fixture.IncrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("test",tx6));
@ -1054,7 +1056,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_expire_test)
BOOST_CHECK(fixture.is_best_claim("test", tx6));
}
/*
* tests for CClaimPrefixTrie::getEffectiveAmountForClaim
* tests for effectiveAmount
*/
BOOST_AUTO_TEST_CASE(claimtriebranching_get_effective_amount_for_claim)
{
@ -1064,42 +1066,42 @@ BOOST_AUTO_TEST_CASE(claimtriebranching_get_effective_amount_for_claim)
uint160 claimId = ClaimIdHash(claimtx.GetHash(), 0);
fixture.IncrementBlocks(1);
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 2);
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("inexistent", claimId), 0); //not found returns 0
BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 2);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("inexistent").find(claimId).effectiveAmount, 0); //not found returns 0
// one claim, one support
fixture.MakeSupport(fixture.GetCoinbase(), claimtx, "test", 40);
fixture.IncrementBlocks(1);
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 42);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 42);
// Two claims, first one with supports
CMutableTransaction claimtx2 = fixture.MakeClaim(fixture.GetCoinbase(), "test", "two", 1);
uint160 claimId2 = ClaimIdHash(claimtx2.GetHash(), 0);
fixture.IncrementBlocks(10);
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 42);
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId2), 1);
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("inexistent", claimId), 0);
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("inexistent", claimId2), 0);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 42);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId2).effectiveAmount, 1);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("inexistent").find(claimId).effectiveAmount, 0);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("inexistent").find(claimId2).effectiveAmount, 0);
// Two claims, both with supports, second claim effective amount being less than first claim
fixture.MakeSupport(fixture.GetCoinbase(), claimtx2, "test", 6);
fixture.IncrementBlocks(13); //delay
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 42);
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId2), 7);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 42);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId2).effectiveAmount, 7);
// Two claims, both with supports, second one taking over
fixture.MakeSupport(fixture.GetCoinbase(), claimtx2, "test", 1330);
fixture.IncrementBlocks(26); //delay
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId), 42);
BOOST_CHECK_EQUAL(fixture.getEffectiveAmountForClaim("test", claimId2), 1337);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId).effectiveAmount, 42);
BOOST_CHECK_EQUAL(fixture.getClaimsForName("test").find(claimId2).effectiveAmount, 1337);
}
/*
* tests for CClaimPrefixTrie::getClaimById basic consistency checks
* tests for getClaimById basic consistency checks
*/
BOOST_AUTO_TEST_CASE(get_claim_by_id_test)
{
@ -1111,7 +1113,7 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test)
CClaimValue claimValue;
std::string claimName;
fixture.getClaimById(claimId, claimName, claimValue);
BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
@ -1122,14 +1124,14 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test)
uint160 claimId2 = ClaimIdHash(tx2.GetHash(), 0);
fixture.IncrementBlocks(1);
fixture.getClaimById(claimId2, claimName, claimValue);
BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
CMutableTransaction u1 = fixture.MakeUpdate(tx1, name, "updated one", claimId, 1);
fixture.IncrementBlocks(1);
fixture.getClaimById(claimId, claimName, claimValue);
BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
BOOST_CHECK_EQUAL(claimValue.nAmount, 1);
@ -1137,24 +1139,24 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test)
fixture.Spend(u1);
fixture.IncrementBlocks(1);
BOOST_CHECK(!fixture.getClaimById(claimId, claimName, claimValue));
BOOST_CHECK(!getClaimById(claimId, claimName, &claimValue));
fixture.DecrementBlocks(3);
CClaimValue claimValue2;
claimName = "";
fixture.getClaimById(claimId2, claimName, claimValue2);
BOOST_CHECK(!getClaimById(claimId2, claimName, &claimValue2));
BOOST_CHECK(claimName != name);
BOOST_CHECK(claimValue2.claimId != claimId2);
fixture.getClaimById(claimId, claimName, claimValue);
BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
fixture.DecrementBlocks(2);
claimName = "";
fixture.getClaimById(claimId, claimName, claimValue2);
BOOST_CHECK(!getClaimById(claimId, claimName, &claimValue2));
BOOST_CHECK(claimName != name);
BOOST_CHECK(claimValue2.claimId != claimId);
}
@ -1535,7 +1537,7 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
CClaimValue lookupClaim;
std::string lookupName;
BOOST_CHECK(fixture.getClaimById(ClaimIdHash(tx2.GetHash(), 0), lookupName, lookupClaim));
BOOST_CHECK(getClaimById(ClaimIdHash(tx2.GetHash(), 0), lookupName, &lookupClaim));
CClaimValue nval1;
BOOST_CHECK(fixture.getInfoForName("amelie1", nval1));
// amélie is not found cause normalization still not appear
@ -1614,13 +1616,13 @@ BOOST_AUTO_TEST_CASE(normalized_activations_fall_through)
BOOST_CHECK(fixture.is_best_claim("AB", tx1));
fixture.IncrementBlocks(3);
BOOST_CHECK(fixture.is_best_claim("ab", tx2));
BOOST_CHECK(fixture.getClaimsForName("ab").claims.size() == 4U);
BOOST_CHECK(fixture.getClaimsForName("ab").claimsNsupports.size() == 4U);
fixture.DecrementBlocks(3);
fixture.Spend(tx1);
fixture.Spend(tx2);
fixture.IncrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("ab", tx3));
BOOST_CHECK(fixture.getClaimsForName("ab").claims.size() == 2U);
BOOST_CHECK(fixture.getClaimsForName("ab").claimsNsupports.size() == 2U);
fixture.DecrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("AB", tx1));
fixture.Spend(tx1);
@ -1666,8 +1668,10 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
supportQueueRowType expireSupportUndo;
std::vector<std::pair<std::string, int> > takeoverHeightUndo;
BOOST_CHECK(cache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverHeightUndo));
BOOST_CHECK(cache.getClaimsForName("ab").claims.size() == 3U);
BOOST_CHECK(cache.getClaimsForName("ab").supports.size() == 2U);
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports.size() == 3U);
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[0].supports.size() == 1U);
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[1].supports.size() == 0U);
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[2].supports.size() == 1U);
BOOST_CHECK(cache.decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo));
BOOST_CHECK(cache.finalizeDecrement(takeoverHeightUndo));
BOOST_CHECK(cache.undoAddSupport("AB", COutPoint(sx1.GetHash(), 0), height));
@ -1675,7 +1679,7 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
BOOST_CHECK(cache.undoAddClaim("AB", COutPoint(tx1.GetHash(), 0), height));
BOOST_CHECK(cache.undoAddClaim("Ab", COutPoint(tx2.GetHash(), 0), height));
BOOST_CHECK(cache.undoAddClaim("aB", COutPoint(tx3.GetHash(), 0), height));
BOOST_CHECK(cache.getClaimsForName("ab").claims.size() == 0U);
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports.size() == 0U);
}
BOOST_AUTO_TEST_CASE(normalization_does_not_kill_supports)
@ -1745,7 +1749,7 @@ BOOST_AUTO_TEST_CASE(normalization_does_not_kill_sort_order)
fixture.IncrementBlocks(1);
BOOST_CHECK(!fixture.is_best_claim("A", tx2));
BOOST_CHECK(fixture.is_best_claim("a", tx3));
BOOST_CHECK(fixture.getClaimsForName("a").claims.size() == 3U);
BOOST_CHECK(fixture.getClaimsForName("a").claimsNsupports.size() == 3U);
fixture.DecrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("A", tx2));
@ -3837,7 +3841,7 @@ BOOST_AUTO_TEST_CASE(bogus_claimtrie_hash_test)
}
/*
* tests for CClaimPrefixTrie::getClaimById basic consistency checks
* tests for getClaimById basic consistency checks
*/
BOOST_AUTO_TEST_CASE(get_claim_by_id_test_2)
{
@ -3852,7 +3856,7 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_2)
CClaimValue claimValue;
std::string claimName;
fixture.getClaimById(claimId, claimName, claimValue);
BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
@ -3860,16 +3864,16 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_2)
CMutableTransaction txb = fixture.Spend(txx);
fixture.IncrementBlocks(1);
BOOST_CHECK(!fixture.getClaimById(claimId, claimName, claimValue));
BOOST_CHECK(!fixture.getClaimById(claimIdx, claimName, claimValue));
BOOST_CHECK(!getClaimById(claimId, claimName, &claimValue));
BOOST_CHECK(!getClaimById(claimIdx, claimName, &claimValue));
fixture.DecrementBlocks(1);
fixture.getClaimById(claimId, claimName, claimValue);
BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
// this test fails
fixture.getClaimById(claimIdx, claimName, claimValue);
BOOST_CHECK(getClaimById(claimIdx, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimIdx);
}
@ -3886,7 +3890,7 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_3)
CClaimValue claimValue;
std::string claimName;
fixture.getClaimById(claimId, claimName, claimValue);
BOOST_CHECK(getClaimById(claimId, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId);
// make second claim with activation delay 1
@ -3896,14 +3900,14 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_3)
fixture.IncrementBlocks(1);
// second claim is not activated yet, but can still access by claim id
BOOST_CHECK(fixture.is_best_claim(name, tx1));
BOOST_CHECK(fixture.getClaimById(claimId2, claimName, claimValue));
BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
fixture.IncrementBlocks(1);
// second claim has activated
BOOST_CHECK(fixture.is_best_claim(name, tx2));
BOOST_CHECK(fixture.getClaimById(claimId2, claimName, claimValue));
BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
@ -3912,14 +3916,14 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_3)
// second claim has been deactivated via decrement
// should still be accesible via claim id
BOOST_CHECK(fixture.is_best_claim(name, tx1));
BOOST_CHECK(fixture.getClaimById(claimId2, claimName, claimValue));
BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
fixture.IncrementBlocks(1);
// second claim should have been re activated via increment
BOOST_CHECK(fixture.is_best_claim(name, tx2));
BOOST_CHECK(fixture.getClaimById(claimId2, claimName, claimValue));
BOOST_CHECK(getClaimById(claimId2, claimName, &claimValue));
BOOST_CHECK_EQUAL(claimName, name);
BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
}
@ -3968,15 +3972,15 @@ BOOST_AUTO_TEST_CASE(getvalueforname_test)
req.params.push_back(UniValue(sName1));
UniValue results = getvalueforname(req);
BOOST_CHECK_EQUAL(results["value"].get_str(), HexStr(sValue1));
BOOST_CHECK_EQUAL(results["amount"].get_int(), 2);
BOOST_CHECK_EQUAL(results["effective amount"].get_int(), 5);
BOOST_CHECK_EQUAL(results[T_VALUE].get_str(), HexStr(sValue1));
BOOST_CHECK_EQUAL(results[T_AMOUNT].get_int(), 2);
BOOST_CHECK_EQUAL(results[T_EFFECTIVEAMOUNT].get_int(), 5);
req.params.push_back(blockHash.GetHex());
results = getvalueforname(req);
BOOST_CHECK_EQUAL(results["amount"].get_int(), 2);
BOOST_CHECK_EQUAL(results["effective amount"].get_int(), 2);
BOOST_CHECK_EQUAL(results[T_AMOUNT].get_int(), 2);
BOOST_CHECK_EQUAL(results[T_EFFECTIVEAMOUNT].get_int(), 2);
}
BOOST_AUTO_TEST_CASE(getclaimsforname_test)
@ -4002,31 +4006,31 @@ BOOST_AUTO_TEST_CASE(getclaimsforname_test)
req.params.push_back(UniValue(sName1));
UniValue results = getclaimsforname(req);
UniValue claims = results["claims"];
BOOST_CHECK_EQUAL(claims.size(), 1U);
BOOST_CHECK_EQUAL(results["nLastTakeoverHeight"].get_int(), height + 1);
BOOST_CHECK_EQUAL(claims[0]["nEffectiveAmount"].get_int(), 2);
BOOST_CHECK_EQUAL(claims[0]["supports"].size(), 0U);
UniValue claims = results[T_CLAIMS];
BOOST_CHECK_EQUAL(claims.size(), 2U);
BOOST_CHECK_EQUAL(results[T_LASTTAKEOVERHEIGHT].get_int(), height + 1);
BOOST_CHECK_EQUAL(claims[0][T_EFFECTIVEAMOUNT].get_int(), 2);
BOOST_CHECK_EQUAL(claims[0][T_SUPPORTS].size(), 0U);
fixture.IncrementBlocks(1);
results = getclaimsforname(req);
claims = results["claims"];
claims = results[T_CLAIMS];
BOOST_CHECK_EQUAL(claims.size(), 2U);
BOOST_CHECK_EQUAL(results["nLastTakeoverHeight"].get_int(), height + 3);
BOOST_CHECK_EQUAL(claims[0]["nEffectiveAmount"].get_int(), 3);
BOOST_CHECK_EQUAL(claims[1]["nEffectiveAmount"].get_int(), 2);
BOOST_CHECK_EQUAL(claims[0]["supports"].size(), 0U);
BOOST_CHECK_EQUAL(claims[1]["supports"].size(), 0U);
BOOST_CHECK_EQUAL(results[T_LASTTAKEOVERHEIGHT].get_int(), height + 3);
BOOST_CHECK_EQUAL(claims[0][T_EFFECTIVEAMOUNT].get_int(), 3);
BOOST_CHECK_EQUAL(claims[1][T_EFFECTIVEAMOUNT].get_int(), 2);
BOOST_CHECK_EQUAL(claims[0][T_SUPPORTS].size(), 0U);
BOOST_CHECK_EQUAL(claims[1][T_SUPPORTS].size(), 0U);
req.params.push_back(blockHash.GetHex());
results = getclaimsforname(req);
claims = results["claims"];
claims = results[T_CLAIMS];
BOOST_CHECK_EQUAL(claims.size(), 1U);
BOOST_CHECK_EQUAL(results["nLastTakeoverHeight"].get_int(), height + 1);
BOOST_CHECK_EQUAL(claims[0]["nEffectiveAmount"].get_int(), 2);
BOOST_CHECK_EQUAL(claims[0]["supports"].size(), 0U);
BOOST_CHECK_EQUAL(results[T_LASTTAKEOVERHEIGHT].get_int(), height + 1);
BOOST_CHECK_EQUAL(claims[0][T_EFFECTIVEAMOUNT].get_int(), 2);
BOOST_CHECK_EQUAL(claims[0][T_SUPPORTS].size(), 0U);
}
BOOST_AUTO_TEST_CASE(claim_rpcs_rollback2_test)
@ -4056,13 +4060,13 @@ BOOST_AUTO_TEST_CASE(claim_rpcs_rollback2_test)
req.params.push_back(blockHash.GetHex());
UniValue claimsResults = getclaimsforname(req);
BOOST_CHECK_EQUAL(claimsResults["nLastTakeoverHeight"].get_int(), height + 5);
BOOST_CHECK_EQUAL(claimsResults["claims"][0]["supports"].size(), 0U);
BOOST_CHECK_EQUAL(claimsResults["claims"][1]["supports"].size(), 0U);
BOOST_CHECK_EQUAL(claimsResults[T_LASTTAKEOVERHEIGHT].get_int(), height + 5);
BOOST_CHECK_EQUAL(claimsResults[T_CLAIMS][0][T_SUPPORTS].size(), 0U);
BOOST_CHECK_EQUAL(claimsResults[T_CLAIMS][1][T_SUPPORTS].size(), 0U);
UniValue valueResults = getvalueforname(req);
BOOST_CHECK_EQUAL(valueResults["value"].get_str(), HexStr(sValue2));
BOOST_CHECK_EQUAL(valueResults["amount"].get_int(), 2);
BOOST_CHECK_EQUAL(valueResults[T_VALUE].get_str(), HexStr(sValue2));
BOOST_CHECK_EQUAL(valueResults[T_AMOUNT].get_int(), 2);
}
BOOST_AUTO_TEST_CASE(claim_rpcs_rollback3_test)
@ -4097,11 +4101,11 @@ BOOST_AUTO_TEST_CASE(claim_rpcs_rollback3_test)
req.params.push_back(blockHash.GetHex());
UniValue claimsResults = getclaimsforname(req);
BOOST_CHECK_EQUAL(claimsResults["nLastTakeoverHeight"].get_int(), height + 1);
BOOST_CHECK_EQUAL(claimsResults[T_LASTTAKEOVERHEIGHT].get_int(), height + 1);
UniValue valueResults = getvalueforname(req);
BOOST_CHECK_EQUAL(valueResults["value"].get_str(), HexStr(sValue1));
BOOST_CHECK_EQUAL(valueResults["amount"].get_int(), 3);
BOOST_CHECK_EQUAL(valueResults[T_VALUE].get_str(), HexStr(sValue1));
BOOST_CHECK_EQUAL(valueResults[T_AMOUNT].get_int(), 3);
}
BOOST_AUTO_TEST_CASE(update_on_support2_test)
@ -4131,9 +4135,9 @@ BOOST_AUTO_TEST_CASE(update_on_support2_test)
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
claimHash = Hash(pair.second.begin(), pair.second.end(), claimHash.begin(), claimHash.end());
else
@ -4172,11 +4176,13 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_single_test)
uint160 claimId = ClaimIdHash(tx1.GetHash(), 0);
CClaimTrieProof proof;
BOOST_CHECK(fixture.getProofForName("test", proof, claimId));
BOOST_CHECK(fixture.getProofForName("test", proof, [&claimId](const CClaimValue& claim) {
return claim.claimId == claimId;
}));
BOOST_CHECK(proof.hasValue);
BOOST_CHECK_EQUAL(proof.outPoint, outPoint);
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)
@ -4197,13 +4203,16 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_triple_test)
fixture.IncrementBlocks(1);
for (const auto& name : names) {
for (auto& claim : fixture.getClaimsForName(name).claims) {
for (auto& claimSupports : fixture.getClaimsForName(name).claimsNsupports) {
CClaimTrieProof proof;
BOOST_CHECK(fixture.getProofForName(name, proof, claim.claimId));
auto& claim = claimSupports.claim;
BOOST_CHECK(fixture.getProofForName(name, proof, [&claim](const CClaimValue& value) {
return claim.claimId == value.claimId;
}));
BOOST_CHECK(proof.hasValue);
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
ValidatePairs(fixture, proof, claimHash);
ValidatePairs(fixture, proof.pairs, claimHash);
}
}
}
@ -4225,13 +4234,16 @@ BOOST_AUTO_TEST_CASE(hash_includes_all_claims_branched_test)
fixture.IncrementBlocks(1);
for (const auto& name : names) {
for (auto& claim : fixture.getClaimsForName(name).claims) {
for (auto& claimSupports : fixture.getClaimsForName(name).claimsNsupports) {
CClaimTrieProof proof;
BOOST_CHECK(fixture.getProofForName(name, proof, claim.claimId));
auto& claim = claimSupports.claim;
BOOST_CHECK(fixture.getProofForName(name, proof, [&claim](const CClaimValue& value) {
return claim.claimId == value.claimId;
}));
BOOST_CHECK(proof.hasValue);
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
uint256 claimHash = getValueHash(claim.outPoint, proof.nHeightOfLastTakeover);
ValidatePairs(fixture, proof, claimHash);
ValidatePairs(fixture, proof.pairs, claimHash);
}
}
}
@ -4257,15 +4269,232 @@ BOOST_AUTO_TEST_CASE(hash_claims_children_fuzzer_test)
}
for (const auto& name : names) {
for (auto& claim : fixture.getClaimsForName(name).claims) {
for (auto& claimSupports : fixture.getClaimsForName(name).claimsNsupports) {
CClaimTrieProof proof;
BOOST_CHECK(fixture.getProofForName(name, proof, claim.claimId));
auto& claim = claimSupports.claim;
BOOST_CHECK(fixture.getProofForName(name, proof, [&claim](const CClaimValue& value) {
return claim.claimId == value.claimId;
}));
BOOST_CHECK(proof.hasValue);
BOOST_CHECK_EQUAL(proof.outPoint, claim.outPoint);
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_CASE(claim_rpc_pending_amount_test)
{
ClaimTrieChainFixture fixture;
std::string sName1("test");
std::string sValue1("test1");
std::string sValue2("test2");
rpcfn_type getclaimsforname = tableRPC["getclaimsforname"]->actor;
JSONRPCRequest req;
req.params = UniValue(UniValue::VARR);
req.params.push_back(UniValue(sName1));
fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 1);
fixture.IncrementBlocks(1);
fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue2, 2);
fixture.IncrementBlocks(1);
auto claims = getclaimsforname(req)[T_CLAIMS];
BOOST_CHECK_EQUAL(claims.size(), 2U);
BOOST_CHECK_EQUAL(claims[0][T_EFFECTIVEAMOUNT].get_int(), 1);
BOOST_CHECK(!claims[0].exists(T_PENDINGAMOUNT));
BOOST_CHECK_EQUAL(claims[1][T_EFFECTIVEAMOUNT].get_int(), 0);
BOOST_CHECK(claims[1].exists(T_PENDINGAMOUNT));
BOOST_CHECK_EQUAL(claims[1][T_PENDINGAMOUNT].get_int(), 2);
fixture.IncrementBlocks(1);
claims = getclaimsforname(req)[T_CLAIMS];
BOOST_CHECK_EQUAL(claims.size(), 2U);
BOOST_CHECK_EQUAL(claims[0][T_EFFECTIVEAMOUNT].get_int(), 2);
BOOST_CHECK(!claims[0].exists(T_PENDINGAMOUNT));
BOOST_CHECK_EQUAL(claims[1][T_EFFECTIVEAMOUNT].get_int(), 1);
BOOST_CHECK(!claims[1].exists(T_PENDINGAMOUNT));
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -210,13 +210,13 @@ BOOST_AUTO_TEST_CASE(basic_insertion_info_test)
CClaimValue claimVal(claimOutPoint, claimId, amount, height, validHeight);
ctc.insertClaimIntoTrie("test", claimVal, true);
// try getClaimsForName, getEffectiveAmountForClaim, getInfoForName
// try getClaimsForName, effectiveAmount, getInfoForName
auto res = ctc.getClaimsForName("test");
BOOST_CHECK_EQUAL(res.claims.size(), 1);
BOOST_CHECK_EQUAL(res.claims[0], claimVal);
BOOST_CHECK_EQUAL(res.supports.size(), 0);
BOOST_CHECK_EQUAL(res.claimsNsupports.size(), 1);
BOOST_CHECK_EQUAL(res.claimsNsupports[0].claim, claimVal);
BOOST_CHECK_EQUAL(res.claimsNsupports[0].supports.size(), 0);
BOOST_CHECK_EQUAL(10, ctc.getEffectiveAmountForClaim("test", claimId));
BOOST_CHECK_EQUAL(10, res.claimsNsupports[0].effectiveAmount);
CClaimValue claim;
BOOST_CHECK(ctc.getInfoForName("test", claim));
@ -231,12 +231,12 @@ BOOST_AUTO_TEST_CASE(basic_insertion_info_test)
CSupportValue support(supportOutPoint, claimId, supportAmount, height, validHeight);
ctc.insertSupportIntoMap("test", support, false);
res = ctc.getClaimsForName("test");
BOOST_CHECK_EQUAL(res.claims.size(), 1);
BOOST_CHECK_EQUAL(res.supports.size(), 1);
auto res1 = ctc.getClaimsForName("test");
BOOST_CHECK_EQUAL(res1.claimsNsupports.size(), 1);
BOOST_CHECK_EQUAL(res1.claimsNsupports[0].supports.size(), 1);
// try getEffectiveAmount
BOOST_CHECK_EQUAL(20, ctc.getEffectiveAmountForClaim("test", claimId));
BOOST_CHECK_EQUAL(20, res1.claimsNsupports[0].effectiveAmount);
}
BOOST_AUTO_TEST_CASE(recursive_prune_test)

View file

@ -1351,36 +1351,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
return true;
}
namespace {
bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
{
// Open history file to append
CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
return error("%s: OpenUndoFile failed", __func__);
// Write index header
unsigned int nSize = GetSerializeSize(fileout, blockundo);
fileout << messageStart << nSize;
// Write undo data
long fileOutPos = ftell(fileout.Get());
if (fileOutPos < 0)
return error("%s: ftell failed", __func__);
pos.nPos = (unsigned int)fileOutPos;
fileout << blockundo;
// calculate & write checksum
CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
hasher << hashBlock;
hasher << blockundo;
fileout << hasher.GetHash();
return true;
}
static bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex *pindex)
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex *pindex)
{
CDiskBlockPos pos = pindex->GetUndoPos();
if (pos.IsNull()) {
@ -1411,6 +1382,35 @@ static bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex *pindex)
return true;
}
namespace {
bool UndoWriteToDisk(const CBlockUndo& blockundo, CDiskBlockPos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
{
// Open history file to append
CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION);
if (fileout.IsNull())
return error("%s: OpenUndoFile failed", __func__);
// Write index header
unsigned int nSize = GetSerializeSize(fileout, blockundo);
fileout << messageStart << nSize;
// Write undo data
long fileOutPos = ftell(fileout.Get());
if (fileOutPos < 0)
return error("%s: ftell failed", __func__);
pos.nPos = (unsigned int)fileOutPos;
fileout << blockundo;
// calculate & write checksum
CHashWriter hasher(SER_GETHASH, PROTOCOL_VERSION);
hasher << hashBlock;
hasher << blockundo;
fileout << hasher.GetHash();
return true;
}
/** Abort with a message */
static bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
{

View file

@ -880,7 +880,7 @@ UniValue supportclaim(const JSONRPCRequest& request)
return NullUniValue;
}
if (request.fHelp || request.params.size() < 3 || request.params.size() > 5)
if (request.fHelp || request.params.size() < 1 || request.params.size() > 5)
throw std::runtime_error(
"supportclaim \"name\" \"claimid\" \"amount\" \"value\"\n"
"Increase the value of a claim. Whichever claim has the greatest value, including all support values, will be the authoritative claim, according to the rest of the rules. The name is the name which is claimed by the claim that will be supported, the txid is the txid\
@ -889,31 +889,45 @@ UniValue supportclaim(const JSONRPCRequest& request)
+ HelpRequiringPassphrase(pwallet) +
"\nArguments:\n"
"1. \"name\" (string, required) The name claimed by the claim to support.\n"
"2. \"claimid\" (string, required) The claimid of the claim to support.\n"
"3. \"amount\" (numeric, required) The amount in LBC to use to support the claim.\n"
"2. \"claimid\" (string, optional) The claimid or partialid of the claim to support.\n"
"3. \"amount\" (numeric, optional) The amount in LBC to use to support the claim.\n"
"4. \"value\" (string, optional) The metadata of the support encoded in hexadecimal.\n"
"\nResult:\n"
"\"transactionid\" (string) The transaction id of the support.\n");
"5. \"isTip\" (boolean, optional, defaults to false) spendable by owning claim's address when true.\n"
"\nResult: [\n"
"\"txId\" (string) The transaction id of the support.\n"
"\"address\" (string) The destination address of the claim.\n"
"\n]");
auto sName = request.params[0].get_str();
auto sClaimId = request.params[1].get_str();
std::string sClaimId;
if (request.params.size() > 1)
sClaimId = request.params[1].get_str();
const size_t claimLength = 40;
if (!IsHex(sClaimId))
if (!IsHexNumber(sClaimId))
throw JSONRPCError(RPC_INVALID_PARAMETER, "claimid must be a 20-character hexadecimal string (not '" + sClaimId + "')");
if (sClaimId.length() != claimLength)
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("claimid must be of length %d", claimLength));
uint160 claimId;
claimId.SetHex(sClaimId);
std::vector<unsigned char> vchName (sName.begin(), sName.end());
std::vector<unsigned char> vchClaimId (claimId.begin(), claimId.end());
CAmount nAmount = AmountFromValue(request.params[2]);
if (sClaimId.length() > claimLength)
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("claimid must be maximum of length %d", claimLength));
pwallet->BlockUntilSyncedToCurrentChain();
LOCK2(cs_main, pwallet->cs_wallet);
EnsureWalletIsUnlocked(pwallet);
CClaimTrieCache trieCache(pclaimTrie);
auto csToName = trieCache.getClaimsForName(sName);
if (csToName.claimsNsupports.empty())
return NullUniValue;
auto& claimNsupports = !sClaimId.empty() ? csToName.find(sClaimId) : csToName.claimsNsupports[0];
if (claimNsupports.IsNull())
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unable to find a claimid that starts with %s", sClaimId));
auto& claimId = claimNsupports.claim.claimId;
std::vector<unsigned char> vchName (sName.begin(), sName.end());
std::vector<unsigned char> vchClaimId (claimId.begin(), claimId.end());
CAmount nAmount = AmountFromValue(request.params.size() > 2 ? request.params[2] : "0.00000001");
CScript supportScript = CScript() << OP_SUPPORT_CLAIM << vchName << vchClaimId;
auto lastOp = OP_DROP;
if (request.params.size() > 3) {
@ -930,18 +944,37 @@ UniValue supportclaim(const JSONRPCRequest& request)
supportScript = supportScript << OP_2DROP << lastOp;
auto isTip = false;
if (request.params.size() > 4)
isTip = request.params[4].get_bool();
CTxDestination dest;
if (isTip) {
CTransactionRef ref;
uint256 block;
if (!GetTransaction(claimNsupports.claim.outPoint.hash, ref, Params().GetConsensus(), block, true))
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unable to locate the TX with the claim's output.");
if (!ExtractDestination(ref->vout[claimNsupports.claim.outPoint.n].scriptPubKey, dest))
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unable to extract the destination from the chosen claim.");
}
else {
CPubKey newKey;
if (!pwallet->GetKeyFromPool(newKey))
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
OutputType output_type = pwallet->m_default_address_type;
pwallet->LearnRelatedScripts(newKey, output_type);
CTxDestination dest = GetDestinationForKey(newKey, output_type);
dest = GetDestinationForKey(newKey, output_type);
}
CCoinControl cc;
cc.m_change_type = pwallet->m_default_change_type;
auto tx = SendMoney(pwallet, dest, nAmount, false, cc, {}, {}, supportScript);
return tx->GetHash().GetHex();
UniValue result(UniValue::VOBJ);
result.pushKV("txId", tx->GetHash().GetHex());
result.pushKV("address", EncodeDestination(dest));
return result;
}
UniValue abandonsupport(const JSONRPCRequest& request)

View file

@ -78,7 +78,7 @@ uint256 SupportAName(const std::string& name, const std::string& claimId, const
req.params.push_back(price);
UniValue results = rpc_method(req);
auto txid = results.get_str();
auto txid = results["txId"].get_str();
uint256 ret;
ret.SetHex(txid);
return ret;