Add bid, sequence like rpc methods

Reuse a bunch of rpc help texts
This commit is contained in:
Anthony Fieroni 2019-08-13 16:38:34 +03:00 committed by Brannon King
parent 5bdbc9e0d6
commit 3a0b4232a5
3 changed files with 604 additions and 273 deletions

View file

@ -1,5 +1,6 @@
#include <string> #ifndef CLAIMRPCHELP_H
#define CLAIMRPCHELP_H
// always keep defines T_ + value in upper case // always keep defines T_ + value in upper case
#define T_NORMALIZEDNAME "normalizedName" #define T_NORMALIZEDNAME "normalizedName"
@ -37,6 +38,13 @@
#define T_PAIRS "pairs" #define T_PAIRS "pairs"
#define T_ODD "odd" #define T_ODD "odd"
#define T_HASH "hash" #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"
enum { enum {
GETCLAIMSINTRIE = 0, GETCLAIMSINTRIE = 0,
@ -50,241 +58,284 @@ enum {
GETCLAIMSFORTX, GETCLAIMSFORTX,
GETNAMEPROOF, GETNAMEPROOF,
CHECKNORMALIZATION, CHECKNORMALIZATION,
GETCLAIMBYBID,
GETCLAIMBYSEQ,
GETCLAIMPROOFBYID,
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 \
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_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 latest 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[] = { static const char* const rpc_help[] = {
// GETCLAIMSINTRIE // GETCLAIMSINTRIE
R"(getclaimsintrie S1(R"(getclaimsintrie
Return all claims in the name trie. Deprecated Return all claims in the name trie. Deprecated
Arguments: Arguments:)")
1. ")" T_BLOCKHASH R"(" (string, optional) get claims in the trie S3("1. ", T_BLOCKHASH, BLOCKHASH_TEXT)
at the block specified S1("Result: [")
by this block hash. S3(" ", T_NORMALIZEDNAME, " (string) the name of the claim(s) (after normalization)")
If none is given, S3(" ", T_CLAIMS, ": [ (array of object) the claims for this name")
the latest active S3(" ", T_NAME, " (string) the original name of this claim (before normalization)")
block will be used. S3(" ", T_VALUE, " (string) the value of this claim")
Result: [ S3(" ", T_ADDRESS, " (string) the destination address of this claim")
")" T_NORMALIZEDNAME R"(" (string) the name of the claim(s) (after normalization) S3(" ", T_CLAIMID, " (string) the claimId of the claim")
")" T_CLAIMS R"(": [ (array of object) the claims for this name S3(" ", T_TXID, " (string) the txid of the claim")
")" T_NAME R"(" (string) the original name of this claim (before normalization) S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs")
")" T_VALUE R"(" (string) the value of this claim S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located")
")" T_CLAIMID R"(" (string) the claimId of the claim S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the claim became/becomes valid")
")" T_TXID R"(" (string) the txid of the claim S3(" ", T_AMOUNT, " (numeric) the amount of the claim")
")" T_N R"(" (numeric) the index of the claim in the transaction's list of outputs S1(" ]")
")" T_HEIGHT R"(" (numeric) the height of the block in which this transaction is located "]",
")" T_VALIDATHEIGHT R"(" (numeric) the height at which the claim became/becomes valid
")" T_AMOUNT R"(" (numeric) the amount of the claim
]
])",
// GETNAMESINTRIE // GETNAMESINTRIE
R"(getnamesintrie S1(R"(getnamesintrie
Return all claim names in the trie. Return all claim names in the trie.
Arguments: Arguments:)")
1. ")" T_BLOCKHASH R"(" (string, optional) get claims in the trie S3("1. ", T_BLOCKHASH, BLOCKHASH_TEXT)
at the block specified S1("Result: [")
by this block hash. S3(" ", T_NAMES, " all names in the trie that have claims")
If none is given, "]",
the latest active
block will be used.
Result: [
")" T_NAMES R"(" all names in the trie that have claims
])",
// GETVALUEFORNAME // GETVALUEFORNAME
R"(getvalueforname S1(R"(getvalueforname
Return the winning or specified by claimId value associated with a name Return the winning or specified by claimId value associated with a name
Arguments: Arguments:)")
1. ")" T_NAME R"(" (string) the name to look up S3("1. ", T_NAME, NAME_TEXT)
2. ")" T_BLOCKHASH R"(" (string, optional) get the value S3("2. ", T_BLOCKHASH, BLOCKHASH_TEXT)
associated with the name S3("3. ", T_CLAIMID, " (string, optional) can be partial one")
at the block specified S1("Result: [")
by this block hash. CLAIM_OUTPUT
If none is given, "]",
the latest active
block will be used.
3. ")" T_CLAIMID R"(" (string, optional) can be partial one
Result: [
")" T_NORMALIZEDNAME R"(" (string) the name of the claim(s) (after normalization)
")" T_NAME R"(" (string) the original name of this claim (before normalization)
")" T_VALUE R"(" (string) the value of this claim
")" T_CLAIMID R"(" (string) the claimId of the claim
")" T_TXID R"(" (string) the txid of the claim
")" T_N R"(" (numeric) the index of the claim in the transaction's list of outputs
")" T_HEIGHT R"(" (numeric) the height of the block in which this transaction is located
")" T_VALIDATHEIGHT R"(" (numeric) the height at which the support became/becomes valid
")" T_AMOUNT R"(" (numeric) the amount of the claim
")" T_EFFECTIVEAMOUNT R"(" (numeric) the amount plus amount from all supports associated with the claim
")" T_SUPPORTS R"(": [ (array of object) supports for this claim
")" T_VALUE R"(" (string) the metadata of the support if any
")" T_TXID R"(" (string) the txid of the support
")" T_N R"(" (numeric) the index of the support in the transaction's list of outputs
")" T_HEIGHT R"(" (numeric) the height of the block in which this transaction is located
")" T_VALIDATHEIGHT R"(" (numeric) the height at which the support became/becomes valid
")" T_AMOUNT R"(" (numeric) the amount of the support
]
")" T_LASTTAKEOVERHEIGHT R"(" (numeric) the last height at which ownership of the name changed
])",
// GETCLAIMSFORNAME // GETCLAIMSFORNAME
R"(getclaimsforname S1(R"(getclaimsforname
Return all claims and supports for a name Return all claims and supports for a name
Arguments: Arguments:)")
1. ")" T_NAME R"(" (string) the name to look up S3("1. ", T_NAME, NAME_TEXT)
2. ")" T_BLOCKHASH R"(" (string, optional) get claims in the trie S3("2. ", T_BLOCKHASH, BLOCKHASH_TEXT)
at the block specified S1("Result: [")
by this block hash. S3(" ", T_NORMALIZEDNAME, " (string) the name of the claim(s) (after normalization)")
If none is given, S3(" ", T_CLAIMS, ": [ (array of object) the claims for this name")
the latest active S3(" ", T_NAME, " (string) the original name of this claim (before normalization)")
block will be used. S3(" ", T_VALUE, " (string) the value of this claim")
Result: [ S3(" ", T_ADDRESS, " (string) the destination address of this claim")
")" T_NORMALIZEDNAME R"(" (string) the name of the claim(s) (after normalization) S3(" ", T_CLAIMID, " (string) the claimId of the claim")
")" T_CLAIMS R"(": [ (array of object) the claims for this name S3(" ", T_TXID, " (string) the txid of the claim")
")" T_NAME R"(" (string) the original name of this claim (before normalization) S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs")
")" T_VALUE R"(" (string) the value of this claim S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located")
")" T_CLAIMID R"(" (string) the claimId of the claim S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the claim became/becomes valid")
")" T_TXID R"(" (string) the txid of the claim S3(" ", T_AMOUNT, " (numeric) the amount of the claim")
")" T_N R"(" (numeric) the index of the claim in the transaction's list of outputs S3(" ", T_EFFECTIVEAMOUNT, " (numeric) the amount plus amount from all supports associated with the claim")
")" T_HEIGHT R"(" (numeric) the height of the block in which this transaction is located S3(" ", T_SUPPORTS, ": [ (array of object) supports for this claim")
")" T_VALIDATHEIGHT R"(" (numeric) the height at which the claim became/becomes valid S3(" ", T_VALUE, " (string) the metadata of the support if any")
")" T_AMOUNT R"(" (numeric) the amount of the claim S3(" ", T_ADDRESS, " (string) the destination address of the support")
")" T_EFFECTIVEAMOUNT R"(" (numeric) the amount plus amount from all supports associated with the claim S3(" ", T_TXID, " (string) the txid of the support")
")" T_SUPPORTS R"(": [ (array of object) supports for this claim S3(" ", T_N, " (numeric) the index of the support in the transaction's list of outputs")
")" T_VALUE R"(" (string) the metadata of the support if any S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located")
")" T_TXID R"(" (string) the txid of the support S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the support became/becomes valid")
")" T_N R"(" (numeric) the index of the support in the transaction's list of outputs S3(" ", T_AMOUNT, " (numeric) the amount of the support")
")" T_HEIGHT R"(" (numeric) the height of the block in which this transaction is located S1(" ]")
")" T_VALIDATHEIGHT R"(" (numeric) the height at which the support became/becomes valid S3(" ", T_BID, " (numeric) lower value means a higher bid rate, ordered by effective amount")
")" T_AMOUNT R"(" (numeric) the amount of the support S3(" ", T_SEQUENCE, " (numeric) lower value means latest in sequence, ordered by height of insertion")
] S1(" ]")
] S3(" ", T_LASTTAKEOVERHEIGHT, " (numeric) the last height at which ownership of the name changed")
")" T_LASTTAKEOVERHEIGHT R"(" (numeric) the last height at which ownership of the name changed S3(" ", T_SUPPORTSWITHOUTCLAIM, ": [")
")" T_SUPPORTSWITHOUTCLAIM R"(": [ S3(" ", T_TXID, " (string) the txid of the support")
")" T_TXID R"(" (string) the txid of the support S3(" ", T_N, " (numeric) the index of the support in the transaction's list of outputs")
")" T_N R"(" (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")
")" T_HEIGHT R"(" (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")
")" T_VALIDATHEIGHT R"(" (numeric) the height at which the support became/becomes valid S3(" ", T_AMOUNT, " (numeric) the amount of the support")
")" T_AMOUNT R"(" (numeric) the amount of the support S1(" ]")
] "]",
])",
// GETCLAIMBYID // GETCLAIMBYID
R"(getclaimbyid S1(R"(getclaimbyid
Get a claim by claim id Get a claim by claim id
Arguments: Arguments:)")
1. ")" T_CLAIMID R"(" (string) the claimId of this claim or patial id (at least 3 chars) S3("1. ", T_CLAIMID, " (string) the claimId of this claim or patial id (at least 3 chars)")
Result: [ S1("Result: [")
")" T_NORMALIZEDNAME R"(" (string) the name of the claim(s) (after normalization) CLAIM_OUTPUT
")" T_NAME R"(" (string) the original name of this claim (before normalization) "]",
")" T_VALUE R"(" (string) the value of this claim
")" T_CLAIMID R"(" (string) the claimId of the claim
")" T_TXID R"(" (string) the txid of the claim
")" T_N R"(" (numeric) the index of the claim in the transaction's list of outputs
")" T_HEIGHT R"(" (numeric) the height of the block in which this transaction is located
")" T_VALIDATHEIGHT R"(" (numeric) the height at which the support became/becomes valid
")" T_AMOUNT R"(" (numeric) the amount of the claim
")" T_EFFECTIVEAMOUNT R"(" (numeric) the amount plus amount from all supports associated with the claim
")" T_SUPPORTS R"(": [ (array of object) supports for this claim
")" T_VALUE R"(" (string) the metadata of the support if any
")" T_TXID R"(" (string) the txid of the support
")" T_N R"(" (numeric) the index of the support in the transaction's list of outputs
")" T_HEIGHT R"(" (numeric) the height of the block in which this transaction is located
")" T_VALIDATHEIGHT R"(" (numeric) the height at which the support became/becomes valid
")" T_AMOUNT R"(" (numeric) the amount of the support
]
")" T_LASTTAKEOVERHEIGHT R"(" (numeric) the last height at which ownership of the name changed
])",
// GETTOTALCLAIMEDNAMES // GETTOTALCLAIMEDNAMES
S1(R"(gettotalclaimednames
R"(gettotalclaimednames
Return the total number of names that have been Return the total number of names that have been
Arguments: Arguments:)")
Result: S1("Result:")
")" T_TOTALNAMES R"(" (numeric) the total number of names in the trie S3(" ", T_TOTALNAMES, " (numeric) the total number of names in the trie")
)", ,
// GETTOTALCLAIMS // GETTOTALCLAIMS
R"(gettotalclaims S1(R"(gettotalclaims
Return the total number of active claims in the trie Return the total number of active claims in the trie
Arguments: Arguments:)")
Result: S1("Result:")
")" T_TOTALCLAIMS R"(" (numeric) the total number of active claims S3(" ", T_TOTALCLAIMS, " (numeric) the total number of active claims")
)", ,
// GETTOTALVALUEOFCLAIMS // GETTOTALVALUEOFCLAIMS
R"(gettotalvalueofclaims S1(R"(gettotalvalueofclaims
Return the total value of the claims in the trie Return the total value of the claims in the trie
Arguments: Arguments:)")
1. ")" T_CONTROLLINGONLY R"(" (boolean) only include the value of controlling claims S3("1. ", T_CONTROLLINGONLY, " (boolean) only include the value of controlling claims")
Result: S1("Result:")
")" T_TOTALVALUE R"(" (numeric) the total value of the claims in the trie S3(" ", T_TOTALVALUE, " (numeric) the total value of the claims in the trie")
)", ,
// GETCLAIMSFORTX // GETCLAIMSFORTX
R"(getclaimsfortx S1(R"(getclaimsfortx
Return any claims or supports found in a transaction Return any claims or supports found in a transaction
Arguments: Arguments:)")
1. ")" T_TXID R"(" (string) the txid of the transaction to check for unspent claims S3("1. ", T_TXID, " (string) the txid of the transaction to check for unspent claims")
Result: [ S1("Result: [")
")" T_N R"(" (numeric) the index of the claim in the transaction's list of outputs S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs")
")" T_CLAIMTYPE R"(" (string) claim or support S3(" ", T_CLAIMTYPE, " (string) claim or support")
")" T_NAME R"(" (string) the name claimed or supported S3(" ", T_NAME, " (string) the name claimed or supported")
")" T_CLAIMID R"(" (string) if a claim, its ID S3(" ", T_CLAIMID, " (string) if a claim, its ID")
")" T_VALUE R"(" (string) if a claim, its value S3(" ", T_VALUE, " (string) if a claim, its value")
")" T_DEPTH R"(" (numeric) the depth of the transaction in the main chain S3(" ", T_DEPTH, " (numeric) the depth of the transaction in the main chain")
")" T_INCLAIMTRIE R"(" (boolean) if a name claim, whether the claim is active, i.e. has made it into the trie S3(" ", T_INCLAIMTRIE, " (boolean) if a name claim, whether the claim is active, i.e. has made it into the trie")
")" T_ISCONTROLLING R"(" (boolean) if a name claim, whether the claim is the current controlling claim for the name S3(" ", T_ISCONTROLLING, " (boolean) if a name claim, whether the claim is the current controlling claim for the name")
")" T_INSUPPORTMAP R"(" (boolean) if a support, whether the support is active, i.e. has made it into the support map S3(" ", T_INSUPPORTMAP, " (boolean) if a support, whether the support is active, i.e. has made it into the support map")
")" T_INQUEUE R"(" (boolean) whether the claim is in a queue waiting to be inserted into the trie or support map S3(" ", T_INQUEUE, " (boolean) whether the claim is in a queue waiting to be inserted into the trie or support map")
")" T_BLOCKSTOVALID R"(" (numeric) if in a queue, the number of blocks until it's 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 // GETNAMEPROOF
R"(getnameproof S1(R"(getnameproof
Return the cryptographic proof that a name maps to a value or doesn't. Return the cryptographic proof that a name maps to a value or doesn't.
Arguments: Arguments:)")
1. ")" T_NAME R"(" (string) the name to look up S3("1. ", T_NAME, NAME_TEXT)
2. ")" T_BLOCKHASH R"(" (string, optional) get the value S3("2. ", T_BLOCKHASH, BLOCKHASH_TEXT)
associated with the name S3("3. ", T_CLAIMID, R"( (string, optional, post-fork) for validating a specific claim
at the block specified can be partial one)")
by this block hash. S1("Result: [")
If none is given, PROOF_OUTPUT
the latest active "]",
block will be used.
3. ")" T_CLAIMID R"(" (string, optional, post-fork) for validating a specific claim
can be partial one
Result: [
")" T_NODES R"(": [ (array of object, pre-fork) full nodes
(i.e. those which lead to the requested name)
")" T_CHILDREN R"(": [ (array of object) the children of the node
")" T_CHARACTER R"(" (string) the character which leads from the parent
to this child node
")" T_NODEHASH R"(" (string, if exists) the hash of the node if this is a leaf node
]
")" T_VALUEHASH R"(" (string, if exists) the hash of this node's value, if
it has one. If this is the requested name this
will not exist whether the node has a value or not
]
")" T_PAIRS R"(": [ (array of pairs, post-fork) hash can be validated by
hashing claim from the bottom up
")" T_ODD R"(" (boolean) this value goes on the right of hash
")" T_HASH R"(" (string) the hash to be mixed in
]
")" T_TXID R"(" (string, if exists) the txid of the claim which controls
this name, if there is one.
")" T_N R"(" (numeric) the index of the claim in the transaction's list of outputs
")" T_LASTTAKEOVERHEIGHT R"(" (numeric) the last height at which ownership of the name changed
])",
// CHECKNORMALIZATION // CHECKNORMALIZATION
R"(checknormalization S1(R"(checknormalization
Given an unnormalized name of a claim, return normalized version of it Given an unnormalized name of a claim, return normalized version of it
Arguments: Arguments:)")
1. ")" T_NAME R"(" (string) the name to normalize S3("1. ", T_NAME, " (string) the name to normalize")
Result: S1("Result:")
")" T_NORMALIZEDNAME R"(" (string) normalized name 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
"]",
// GETCLAIMPROOFBYID
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 in a block or doesn't."
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

View file

@ -1,13 +1,16 @@
#include <claimtrie.h> #include <claimtrie.h>
#include <coins.h> #include <coins.h>
#include <core_io.h> #include <core_io.h>
#include <key_io.h>
#include <logging.h> #include <logging.h>
#include <nameclaim.h> #include <nameclaim.h>
#include <rpc/claimrpchelp.h> #include <rpc/claimrpchelp.h>
#include <rpc/server.h> #include <rpc/server.h>
#include <script/standard.h>
#include <shutdown.h> #include <shutdown.h>
#include <txdb.h> #include <txdb.h>
#include <txmempool.h> #include <txmempool.h>
#include <undo.h>
#include <univalue.h> #include <univalue.h>
#include <validation.h> #include <validation.h>
@ -104,15 +107,11 @@ std::string escapeNonUtf8(const std::string& name)
} }
} }
static bool getValueForOutPoint(const CCoinsViewCache& coinsCache, const COutPoint& out, std::string& sValue) static bool getValueForOutPoint(const CScript& scriptPubKey, std::string& sValue)
{ {
const Coin& coin = coinsCache.AccessCoin(out);
if (coin.IsSpent())
return false;
int op; int op;
std::vector<std::vector<unsigned char> > vvchParams; std::vector<std::vector<unsigned char> > vvchParams;
if (!DecodeClaimScript(coin.out.scriptPubKey, op, vvchParams)) if (!DecodeClaimScript(scriptPubKey, op, vvchParams))
return false; return false;
if (op == OP_CLAIM_NAME) if (op == OP_CLAIM_NAME)
@ -170,6 +169,30 @@ bool getClaimById(const std::string& partialId, std::string& name, CClaimValue*
return false; return false;
} }
std::vector<CClaimNsupports> seqSort(const std::vector<CClaimNsupports>& source)
{
auto claimsNsupports = source;
std::sort(claimsNsupports.begin(), claimsNsupports.end(), [](const CClaimNsupports& lhs, const CClaimNsupports& rhs) {
if (lhs.claim.nHeight > rhs.claim.nHeight)
return true;
if (lhs.claim.nHeight != rhs.claim.nHeight)
return false;
return lhs.claim.outPoint.n > rhs.claim.outPoint.n;
});
return claimsNsupports;
}
std::size_t indexOf(const std::vector<CClaimNsupports>& source, const uint160& claimId)
{
auto it = std::find_if(source.begin(), source.end(), [&claimId](const CClaimNsupports& claimNsupports) {
return claimNsupports.claim.claimId == claimId;
});
assert(it != source.end());
return std::distance(source.begin(), it);
}
UniValue claimToJSON(const CCoinsViewCache& coinsCache, const CClaimValue& claim) UniValue claimToJSON(const CCoinsViewCache& coinsCache, const CClaimValue& claim)
{ {
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
@ -178,9 +201,16 @@ UniValue claimToJSON(const CCoinsViewCache& coinsCache, const CClaimValue& claim
if (getClaimById(claim.claimId, targetName)) if (getClaimById(claim.claimId, targetName))
result.pushKV(T_NAME, escapeNonUtf8(targetName)); result.pushKV(T_NAME, escapeNonUtf8(targetName));
std::string sValue; auto& coin = coinsCache.AccessCoin(claim.outPoint);
if (getValueForOutPoint(coinsCache, claim.outPoint, sValue)) if (!coin.IsSpent()) {
result.pushKV(T_VALUE, sValue); std::string value;
if (getValueForOutPoint(coin.out.scriptPubKey, value))
result.pushKV(T_VALUE, value);
CTxDestination address;
if (ExtractDestination(coin.out.scriptPubKey, address))
result.pushKV(T_ADDRESS, EncodeDestination(address));
}
result.pushKV(T_CLAIMID, claim.claimId.GetHex()); result.pushKV(T_CLAIMID, claim.claimId.GetHex());
result.pushKV(T_TXID, claim.outPoint.hash.GetHex()); result.pushKV(T_TXID, claim.outPoint.hash.GetHex());
@ -196,10 +226,17 @@ UniValue supportToJSON(const CCoinsViewCache& coinsCache, const CSupportValue& s
{ {
UniValue ret(UniValue::VOBJ); UniValue ret(UniValue::VOBJ);
auto& coin = coinsCache.AccessCoin(support.outPoint);
if (!coin.IsSpent()) {
std::string value; std::string value;
if (getValueForOutPoint(coinsCache, support.outPoint, value)) if (getValueForOutPoint(coin.out.scriptPubKey, value))
ret.pushKV(T_VALUE, value); ret.pushKV(T_VALUE, value);
CTxDestination address;
if (ExtractDestination(coin.out.scriptPubKey, address))
ret.pushKV(T_ADDRESS, EncodeDestination(address));
}
ret.pushKV(T_TXID, support.outPoint.hash.GetHex()); ret.pushKV(T_TXID, support.outPoint.hash.GetHex());
ret.pushKV(T_N, (int)support.outPoint.n); ret.pushKV(T_N, (int)support.outPoint.n);
ret.pushKV(T_HEIGHT, support.nHeight); ret.pushKV(T_HEIGHT, support.nHeight);
@ -221,7 +258,6 @@ UniValue claimAndSupportsToJSON(const CCoinsViewCache& coinsCache, const CClaimN
for (auto& support : supports) for (auto& support : supports)
supportObjs.push_back(supportToJSON(coinsCache, support)); supportObjs.push_back(supportToJSON(coinsCache, support));
if (!supportObjs.empty())
result.pushKV(T_SUPPORTS, supportObjs); result.pushKV(T_SUPPORTS, supportObjs);
return result; return result;
@ -256,7 +292,7 @@ static UniValue getclaimsintrie(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie); CClaimTrieCache trieCache(pclaimTrie);
if (!request.params.empty()) { if (!request.params.empty()) {
CBlockIndex *blockIndex = BlockHashIndex(ParseHashV(request.params[0], "blockhash (optional parameter 1)")); CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[0], T_BLOCKHASH " (optional parameter 1)"));
RollBackTo(blockIndex, coinsCache, trieCache); RollBackTo(blockIndex, coinsCache, trieCache);
} }
@ -296,7 +332,7 @@ static UniValue getnamesintrie(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie); CClaimTrieCache trieCache(pclaimTrie);
if (!request.params.empty()) { if (!request.params.empty()) {
CBlockIndex *blockIndex = BlockHashIndex(ParseHashV(request.params[0], "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);
@ -322,32 +358,42 @@ static UniValue getvalueforname(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie); CClaimTrieCache trieCache(pclaimTrie);
if (request.params.size() > 1) { if (request.params.size() > 1) {
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[1], "blockhash (optional parameter 2)")); CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[1], T_BLOCKHASH " (optional parameter 2)"));
RollBackTo(blockIndex, coinsCache, trieCache); RollBackTo(blockIndex, coinsCache, trieCache);
} }
uint160 claimId; uint160 claimId;
std::string partialId; std::string partialId;
if (request.params.size() > 2) if (request.params.size() > 2)
ParseClaimtrieId(request.params[2], partialId, claimId, "claimId (optional parameter 3)"); ParseClaimtrieId(request.params[2], partialId, 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);
auto res = trieCache.getClaimsForName(name); auto csToName = trieCache.getClaimsForName(name);
if (res.claimsNsupports.empty()) if (csToName.claimsNsupports.empty())
return ret; return ret;
auto& claimNsupports = auto& claimNsupports =
!claimId.IsNull() ? res.find(claimId) : !claimId.IsNull() ? csToName.find(claimId) :
!partialId.empty() ? res.find(partialId) : res.claimsNsupports[0]; !partialId.empty() ? csToName.find(partialId) : csToName.claimsNsupports[0];
if (claimNsupports.IsNull()) if (claimNsupports.IsNull())
return ret; return ret;
ret.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(res.name)); std::size_t seq = 0, bid = 0;
if (csToName.claimsNsupports.size() > 1) {
auto& claimId = claimNsupports.claim.claimId;
auto seqOrder = seqSort(csToName.claimsNsupports);
seq = indexOf(seqOrder, claimId);
bid = indexOf(csToName.claimsNsupports, claimId);
}
ret.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(csToName.name));
ret.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports)); ret.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports));
ret.pushKV(T_LASTTAKEOVERHEIGHT, res.nLastTakeoverHeight); ret.pushKV(T_LASTTAKEOVERHEIGHT, csToName.nLastTakeoverHeight);
ret.pushKV(T_BID, (int)bid);
ret.pushKV(T_SEQUENCE, (int)seq);
return ret; return ret;
} }
@ -361,30 +407,125 @@ UniValue getclaimsforname(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie); CClaimTrieCache trieCache(pclaimTrie);
if (request.params.size() > 1) { if (request.params.size() > 1) {
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[1], "blockhash (optional parameter 2)")); CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[1], T_BLOCKHASH " (optional parameter 2)"));
RollBackTo(blockIndex, coinsCache, trieCache); RollBackTo(blockIndex, coinsCache, trieCache);
} }
std::string name = request.params[0].get_str(); std::string name = request.params[0].get_str();
auto claimsForName = trieCache.getClaimsForName(name); auto csToName = trieCache.getClaimsForName(name);
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
result.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(claimsForName.name)); result.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(csToName.name));
auto seqOrder = seqSort(csToName.claimsNsupports);
UniValue claimObjs(UniValue::VARR); UniValue claimObjs(UniValue::VARR);
for (auto& claim : claimsForName.claimsNsupports) for (std::size_t i = 0; i < csToName.claimsNsupports.size(); ++i) {
claimObjs.push_back(claimAndSupportsToJSON(coinsCache, claim)); auto& claimNsupports = csToName.claimsNsupports[i];
auto claim = claimAndSupportsToJSON(coinsCache, claimNsupports);
claim.pushKV(T_BID, (int)i);
claim.pushKV(T_SEQUENCE, (int)indexOf(seqOrder, claimNsupports.claim.claimId));
claimObjs.push_back(claim);
}
UniValue unmatchedSupports(UniValue::VARR); UniValue unmatchedSupports(UniValue::VARR);
for (auto& support : claimsForName.unmatchedSupports) for (auto& support : csToName.unmatchedSupports)
unmatchedSupports.push_back(supportToJSON(coinsCache, support)); unmatchedSupports.push_back(supportToJSON(coinsCache, support));
result.pushKV(T_CLAIMS, claimObjs); result.pushKV(T_CLAIMS, claimObjs);
result.pushKV(T_LASTTAKEOVERHEIGHT, claimsForName.nLastTakeoverHeight); result.pushKV(T_LASTTAKEOVERHEIGHT, csToName.nLastTakeoverHeight);
result.pushKV(T_SUPPORTSWITHOUTCLAIM, unmatchedSupports); result.pushKV(T_SUPPORTSWITHOUTCLAIM, unmatchedSupports);
return result; return result;
} }
UniValue getclaimbybid(const JSONRPCRequest& request)
{
validateRequest(request, GETCLAIMBYBID, 1, 2);
LOCK(cs_main);
CCoinsViewCache coinsCache(pcoinsTip.get());
CClaimTrieCache trieCache(pclaimTrie);
int bid = 0;
if (request.params.size() > 1)
bid = request.params[1].get_int();
if (bid < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, T_BID " (parameter 2) should be greater than 0");
if (request.params.size() > 2) {
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3)"));
RollBackTo(blockIndex, coinsCache, trieCache);
}
std::string name = request.params[0].get_str();
auto csToName = trieCache.getClaimsForName(name);
UniValue result(UniValue::VOBJ);
if (uint32_t(bid) >= csToName.claimsNsupports.size())
return result;
auto& claimNsupports = csToName.claimsNsupports[bid];
std::size_t seq = 0;
if (csToName.claimsNsupports.size() > 1) {
auto seqOrder = seqSort(csToName.claimsNsupports);
seq = indexOf(seqOrder, claimNsupports.claim.claimId);
}
result.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(csToName.name));
result.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports));
result.pushKV(T_LASTTAKEOVERHEIGHT, csToName.nLastTakeoverHeight);
result.pushKV(T_BID, bid);
result.pushKV(T_SEQUENCE, (int)seq);
return result;
}
UniValue getclaimbyseq(const JSONRPCRequest& request)
{
validateRequest(request, GETCLAIMBYSEQ, 1, 2);
LOCK(cs_main);
CCoinsViewCache coinsCache(pcoinsTip.get());
CClaimTrieCache trieCache(pclaimTrie);
int seq = 0;
if (request.params.size() > 1)
seq = request.params[1].get_int();
if (seq < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, T_SEQUENCE " (parameter 2) should be greater than 0");
if (request.params.size() > 2) {
CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3)"));
RollBackTo(blockIndex, coinsCache, trieCache);
}
std::string name = request.params[0].get_str();
auto csToName = trieCache.getClaimsForName(name);
UniValue result(UniValue::VOBJ);
if (uint32_t(seq) >= csToName.claimsNsupports.size())
return result;
std::size_t bid = 0;
const auto claimNsupports = [&bid, &seq, &csToName]() -> CClaimNsupports {
if (csToName.claimsNsupports.size() == 1)
return csToName.claimsNsupports[0];
auto claimNsupports = seqSort(csToName.claimsNsupports)[seq];
bid = indexOf(csToName.claimsNsupports, claimNsupports.claim.claimId);
return claimNsupports;
}();
result.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(csToName.name));
result.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports));
result.pushKV(T_LASTTAKEOVERHEIGHT, csToName.nLastTakeoverHeight);
result.pushKV(T_BID, (int)bid);
result.pushKV(T_SEQUENCE, seq);
return result;
}
UniValue getclaimbyid(const JSONRPCRequest& request) UniValue getclaimbyid(const JSONRPCRequest& request)
{ {
validateRequest(request, GETCLAIMBYID, 1, 0); validateRequest(request, GETCLAIMBYID, 1, 0);
@ -395,21 +536,29 @@ UniValue getclaimbyid(const JSONRPCRequest& request)
uint160 claimId; uint160 claimId;
std::string partialId; std::string partialId;
ParseClaimtrieId(request.params[0], partialId, claimId, "Claim-id (parameter 1)"); ParseClaimtrieId(request.params[0], partialId, claimId, T_CLAIMID " (parameter 1)");
if (claimId.IsNull() && partialId.length() < 3) if (claimId.IsNull() && partialId.length() < 3)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Claim-id (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); UniValue claim(UniValue::VOBJ);
std::string name; std::string name;
CClaimValue claimValue; CClaimValue claimValue;
if (getClaimById(claimId, name, &claimValue) || getClaimById(partialId, name, &claimValue)) { if (getClaimById(claimId, name, &claimValue) || getClaimById(partialId, name, &claimValue)) {
auto res = trieCache.getClaimsForName(name); auto csToName = trieCache.getClaimsForName(name);
auto& claimNsupports = !claimId.IsNull() ? res.find(claimId) : res.find(partialId); auto& claimNsupports = !claimId.IsNull() ? csToName.find(claimId) : csToName.find(partialId);
if (!claimNsupports.IsNull()) { if (!claimNsupports.IsNull()) {
claim.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(res.name)); std::size_t seq = 0, bid = 0;
if (csToName.claimsNsupports.size() > 1) {
auto seqOrder = seqSort(csToName.claimsNsupports);
seq = indexOf(seqOrder, claimNsupports.claim.claimId);
bid = indexOf(csToName.claimsNsupports, claimNsupports.claim.claimId);
}
claim.pushKV(T_NORMALIZEDNAME, escapeNonUtf8(csToName.name));
claim.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports)); claim.pushKVs(claimAndSupportsToJSON(coinsCache, claimNsupports));
claim.pushKV(T_LASTTAKEOVERHEIGHT, res.nLastTakeoverHeight); claim.pushKV(T_LASTTAKEOVERHEIGHT, csToName.nLastTakeoverHeight);
claim.pushKV(T_BID, (int)bid);
claim.pushKV(T_SEQUENCE, (int)seq);
} }
} }
return claim; return claim;
@ -450,7 +599,7 @@ UniValue getclaimsfortx(const JSONRPCRequest& request)
validateRequest(request, GETCLAIMSFORTX, 1, 0); validateRequest(request, GETCLAIMSFORTX, 1, 0);
LOCK(cs_main); LOCK(cs_main);
uint256 hash = ParseHashV(request.params[0], "txid (parameter 1)"); uint256 hash = ParseHashV(request.params[0], T_TXID " (parameter 1)");
UniValue ret(UniValue::VARR); UniValue ret(UniValue::VARR);
int op; int op;
@ -581,14 +730,14 @@ UniValue getnameproof(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie); CClaimTrieCache trieCache(pclaimTrie);
if (request.params.size() > 1) { if (request.params.size() > 1) {
CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[1], "blockhash (optional parameter 2)")); CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[1], T_BLOCKHASH " (optional parameter 2)"));
RollBackTo(pblockIndex, coinsCache, trieCache); RollBackTo(pblockIndex, coinsCache, trieCache);
} }
uint160 claimId; uint160 claimId;
std::string partialId; std::string partialId;
if (request.params.size() > 2) if (request.params.size() > 2)
ParseClaimtrieId(request.params[2], partialId, claimId, "claimId (optional parameter 3)"); ParseClaimtrieId(request.params[2], partialId, claimId, T_CLAIMID " (optional parameter 3)");
std::function<bool(const CClaimValue&)> comp; std::function<bool(const CClaimValue&)> comp;
if (!claimId.IsNull()) if (!claimId.IsNull())
@ -608,6 +757,132 @@ UniValue getnameproof(const JSONRPCRequest& request)
return proofToJSON(proof); return proofToJSON(proof);
} }
UniValue getclaimproofbybid(const JSONRPCRequest& request)
{
validateRequest(request, GETCLAIMPROOFBYID, 1, 2);
LOCK(cs_main);
CCoinsViewCache coinsCache(pcoinsTip.get());
CClaimTrieCache trieCache(pclaimTrie);
int bid = 0;
if (request.params.size() > 1)
bid = request.params[1].get_int();
if (bid < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, T_BID " (parameter 2) should be greater than 0");
if (request.params.size() > 2) {
CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3)"));
RollBackTo(pblockIndex, coinsCache, trieCache);
}
std::string name = request.params[0].get_str();
std::function<bool(const CClaimValue&)> comp;
if (bid) {
auto csToName = trieCache.getClaimsForName(name);
if (uint32_t(bid) >= csToName.claimsNsupports.size())
return {UniValue::VARR};
auto claimId = csToName.claimsNsupports[bid].claim.claimId;
comp = [claimId](const CClaimValue& claim) {
return claim.claimId == claimId;
};
}
CClaimTrieProof proof;
if (!trieCache.getProofForName(name, proof, comp))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failed to generate proof");
return proofToJSON(proof);
}
UniValue getclaimproofbyseq(const JSONRPCRequest& request)
{
validateRequest(request, GETCLAIMPROOFBYSEQ, 1, 2);
LOCK(cs_main);
CCoinsViewCache coinsCache(pcoinsTip.get());
CClaimTrieCache trieCache(pclaimTrie);
int seq = 0;
if (request.params.size() > 1)
seq = request.params[1].get_int();
if (seq < 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, T_SEQUENCE " (parameter 2) should be greater than 0");
if (request.params.size() > 2) {
CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(request.params[2], T_BLOCKHASH " (optional parameter 3"));
RollBackTo(pblockIndex, coinsCache, trieCache);
}
std::string name = request.params[0].get_str();
auto csToName = trieCache.getClaimsForName(name);
if (uint32_t(seq) >= csToName.claimsNsupports.size())
return {UniValue::VARR};
std::function<bool(const CClaimValue&)> comp;
auto claimId = (csToName.claimsNsupports.size() == 1 ?
csToName.claimsNsupports[0] : seqSort(csToName.claimsNsupports)[seq]).claim.claimId;
comp = [&claimId](const CClaimValue& claim) {
return claim.claimId == claimId;
};
CClaimTrieProof proof;
if (!trieCache.getProofForName(name, proof, comp))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failed to generate proof");
return proofToJSON(proof);
}
extern bool UndoReadFromDisk(CBlockUndo&, const CBlockIndex*);
UniValue getchangesinblock(const JSONRPCRequest& request)
{
validateRequest(request, GETCHANGESINBLOCK, 1, 0);
CBlockUndo undo;
{
LOCK(cs_main);
auto index = chainActive.Tip();
if (request.params.size() > 0)
index = BlockHashIndex(ParseHashV(request.params[0], T_BLOCKHASH " (optional parameter)"));
if (!UndoReadFromDisk(undo, index))
throw JSONRPCError(RPC_INTERNAL_ERROR,
"Unable to read the undo block for height " + std::to_string(index->nHeight));
}
auto addedUpdated = [](const insertUndoType& insertUndo) {
UniValue added(UniValue::VARR);
for (auto& a : insertUndo)
added.push_back(ClaimIdHash(a.outPoint.hash, a.outPoint.n).ToString());
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);
result.pushKV(T_CLAIMSADDEDORUPDATED, addedUpdated(undo.insertUndo));
result.pushKV(T_CLAIMSREMOVED, removedClaims(undo.expireUndo));
result.pushKV(T_SUPPORTSADDEDORUPDATED, addedUpdated(undo.insertSupportUndo));
result.pushKV(T_SUPPORTSREMOVED, removedSupports(undo.expireSupportUndo));
return result;
}
UniValue checknormalization(const JSONRPCRequest& request) UniValue checknormalization(const JSONRPCRequest& request)
{ {
validateRequest(request, CHECKNORMALIZATION, 1, 0); validateRequest(request, CHECKNORMALIZATION, 1, 0);
@ -632,7 +907,12 @@ static const CRPCCommand commands[] =
{ "Claimtrie", "gettotalvalueofclaims", &gettotalvalueofclaims, { T_CONTROLLINGONLY } }, { "Claimtrie", "gettotalvalueofclaims", &gettotalvalueofclaims, { T_CONTROLLINGONLY } },
{ "Claimtrie", "getclaimsfortx", &getclaimsfortx, { T_TXID } }, { "Claimtrie", "getclaimsfortx", &getclaimsfortx, { T_TXID } },
{ "Claimtrie", "getnameproof", &getnameproof, { T_NAME,T_BLOCKHASH,T_CLAIMID } }, { "Claimtrie", "getnameproof", &getnameproof, { T_NAME,T_BLOCKHASH,T_CLAIMID } },
{ "Claimtrie", "getclaimproofbybid", &getclaimproofbybid, { T_NAME,T_BID,T_BLOCKHASH } },
{ "Claimtrie", "getclaimproofbyseq", &getclaimproofbyseq, { T_NAME,T_SEQUENCE,T_BLOCKHASH } },
{ "Claimtrie", "getclaimbyid", &getclaimbyid, { T_CLAIMID } }, { "Claimtrie", "getclaimbyid", &getclaimbyid, { T_CLAIMID } },
{ "Claimtrie", "getclaimbybid", &getclaimbybid, { T_NAME,T_BID,T_BLOCKHASH } },
{ "Claimtrie", "getclaimbyseq", &getclaimbyseq, { T_NAME,T_SEQUENCE,T_BLOCKHASH } },
{ "Claimtrie", "getchangesinblock", &getchangesinblock, { T_BLOCKHASH } },
{ "Claimtrie", "checknormalization", &checknormalization, { T_NAME } }, { "Claimtrie", "checknormalization", &checknormalization, { T_NAME } },
}; };

View file

@ -1351,36 +1351,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
return true; return true;
} }
namespace { bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex *pindex)
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)
{ {
CDiskBlockPos pos = pindex->GetUndoPos(); CDiskBlockPos pos = pindex->GetUndoPos();
if (pos.IsNull()) { if (pos.IsNull()) {
@ -1411,6 +1382,35 @@ static bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex *pindex)
return true; 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 */ /** Abort with a message */
static bool AbortNode(const std::string& strMessage, const std::string& userMessage="") static bool AbortNode(const std::string& strMessage, const std::string& userMessage="")
{ {