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
#define T_NORMALIZEDNAME "normalizedName"
@ -37,6 +38,13 @@
#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"
enum {
GETCLAIMSINTRIE = 0,
@ -50,241 +58,284 @@ enum {
GETCLAIMSFORTX,
GETNAMEPROOF,
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[] = {
// GETCLAIMSINTRIE
R"(getclaimsintrie
S1(R"(getclaimsintrie
Return all claims in the name trie. Deprecated
Arguments:
1. ")" T_BLOCKHASH R"(" (string, optional) get claims in the trie
at the block specified
by this block hash.
If none is given,
the latest active
block will be used.
Result: [
")" T_NORMALIZEDNAME R"(" (string) the name of the claim(s) (after normalization)
")" T_CLAIMS R"(": [ (array of object) the claims for this name
")" 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 claim became/becomes valid
")" T_AMOUNT R"(" (numeric) the amount of the claim
]
])",
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
R"(getnamesintrie
S1(R"(getnamesintrie
Return all claim names in the trie.
Arguments:
1. ")" T_BLOCKHASH R"(" (string, optional) get claims in the trie
at the block specified
by this block hash.
If none is given,
the latest active
block will be used.
Result: [
")" T_NAMES R"(" all names in the trie that have claims
])",
Arguments:)")
S3("1. ", T_BLOCKHASH, BLOCKHASH_TEXT)
S1("Result: [")
S3(" ", T_NAMES, " all names in the trie that have claims")
"]",
// GETVALUEFORNAME
R"(getvalueforname
S1(R"(getvalueforname
Return the winning or specified by claimId value associated with a name
Arguments:
1. ")" T_NAME R"(" (string) the name to look up
2. ")" T_BLOCKHASH R"(" (string, optional) get the value
associated with the name
at the block specified
by this block hash.
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
])",
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
R"(getclaimsforname
S1(R"(getclaimsforname
Return all claims and supports for a name
Arguments:
1. ")" T_NAME R"(" (string) the name to look up
2. ")" T_BLOCKHASH R"(" (string, optional) get claims in the trie
at the block specified
by this block hash.
If none is given,
the latest active
block will be used.
Result: [
")" T_NORMALIZEDNAME R"(" (string) the name of the claim(s) (after normalization)
")" T_CLAIMS R"(": [ (array of object) the claims for this name
")" 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 claim 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
")" T_SUPPORTSWITHOUTCLAIM R"(": [
")" 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
]
])",
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_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 latest 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
R"(getclaimbyid
S1(R"(getclaimbyid
Get a claim by claim id
Arguments:
1. ")" T_CLAIMID R"(" (string) the claimId of this claim or patial id (at least 3 chars)
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
])",
Arguments:)")
S3("1. ", T_CLAIMID, " (string) the claimId of this claim or patial id (at least 3 chars)")
S1("Result: [")
CLAIM_OUTPUT
"]",
// GETTOTALCLAIMEDNAMES
R"(gettotalclaimednames
S1(R"(gettotalclaimednames
Return the total number of names that have been
Arguments:
Result:
")" T_TOTALNAMES R"(" (numeric) the total number of names in the trie
)",
Arguments:)")
S1("Result:")
S3(" ", T_TOTALNAMES, " (numeric) the total number of names in the trie")
,
// GETTOTALCLAIMS
R"(gettotalclaims
S1(R"(gettotalclaims
Return the total number of active claims in the trie
Arguments:
Result:
")" T_TOTALCLAIMS R"(" (numeric) the total number of active claims
)",
Arguments:)")
S1("Result:")
S3(" ", T_TOTALCLAIMS, " (numeric) the total number of active claims")
,
// GETTOTALVALUEOFCLAIMS
R"(gettotalvalueofclaims
S1(R"(gettotalvalueofclaims
Return the total value of the claims in the trie
Arguments:
1. ")" T_CONTROLLINGONLY R"(" (boolean) only include the value of controlling claims
Result:
")" T_TOTALVALUE R"(" (numeric) 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
R"(getclaimsfortx
S1(R"(getclaimsfortx
Return any claims or supports found in a transaction
Arguments:
1. ")" T_TXID R"(" (string) the txid of the transaction to check for unspent claims
Result: [
")" T_N R"(" (numeric) the index of the claim in the transaction's list of outputs
")" T_CLAIMTYPE R"(" (string) claim or support
")" T_NAME R"(" (string) the name claimed or supported
")" T_CLAIMID R"(" (string) if a claim, its ID
")" T_VALUE R"(" (string) if a claim, its value
")" T_DEPTH R"(" (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
")" T_ISCONTROLLING R"(" (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
")" T_INQUEUE R"(" (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
])",
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
R"(getnameproof
S1(R"(getnameproof
Return the cryptographic proof that a name maps to a value or doesn't.
Arguments:
1. ")" T_NAME R"(" (string) the name to look up
2. ")" T_BLOCKHASH R"(" (string, optional) get the value
associated with the name
at the block specified
by this block hash.
If none is given,
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
])",
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
R"(checknormalization
S1(R"(checknormalization
Given an unnormalized name of a claim, return normalized version of it
Arguments:
1. ")" T_NAME R"(" (string) the name to normalize
Result:
")" T_NORMALIZEDNAME R"(" (string) normalized name
)",
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
"]",
// 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 <coins.h>
#include <core_io.h>
#include <key_io.h>
#include <logging.h>
#include <nameclaim.h>
#include <rpc/claimrpchelp.h>
#include <rpc/server.h>
#include <script/standard.h>
#include <shutdown.h>
#include <txdb.h>
#include <txmempool.h>
#include <undo.h>
#include <univalue.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;
std::vector<std::vector<unsigned char> > vvchParams;
if (!DecodeClaimScript(coin.out.scriptPubKey, op, vvchParams))
if (!DecodeClaimScript(scriptPubKey, op, vvchParams))
return false;
if (op == OP_CLAIM_NAME)
@ -170,6 +169,30 @@ bool getClaimById(const std::string& partialId, std::string& name, CClaimValue*
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 result(UniValue::VOBJ);
@ -178,9 +201,16 @@ UniValue claimToJSON(const CCoinsViewCache& coinsCache, const CClaimValue& claim
if (getClaimById(claim.claimId, targetName))
result.pushKV(T_NAME, escapeNonUtf8(targetName));
std::string sValue;
if (getValueForOutPoint(coinsCache, claim.outPoint, sValue))
result.pushKV(T_VALUE, sValue);
auto& coin = coinsCache.AccessCoin(claim.outPoint);
if (!coin.IsSpent()) {
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_TXID, claim.outPoint.hash.GetHex());
@ -196,9 +226,16 @@ UniValue supportToJSON(const CCoinsViewCache& coinsCache, const CSupportValue& s
{
UniValue ret(UniValue::VOBJ);
std::string value;
if (getValueForOutPoint(coinsCache, support.outPoint, value))
ret.pushKV(T_VALUE, value);
auto& coin = coinsCache.AccessCoin(support.outPoint);
if (!coin.IsSpent()) {
std::string value;
if (getValueForOutPoint(coin.out.scriptPubKey, 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_N, (int)support.outPoint.n);
@ -221,8 +258,7 @@ UniValue claimAndSupportsToJSON(const CCoinsViewCache& coinsCache, const CClaimN
for (auto& support : supports)
supportObjs.push_back(supportToJSON(coinsCache, support));
if (!supportObjs.empty())
result.pushKV(T_SUPPORTS, supportObjs);
result.pushKV(T_SUPPORTS, supportObjs);
return result;
}
@ -256,7 +292,7 @@ static UniValue getclaimsintrie(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie);
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);
}
@ -296,7 +332,7 @@ static UniValue getnamesintrie(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie);
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);
}
UniValue ret(UniValue::VARR);
@ -322,32 +358,42 @@ static UniValue getvalueforname(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie);
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);
}
uint160 claimId;
std::string partialId;
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();
UniValue ret(UniValue::VOBJ);
auto res = trieCache.getClaimsForName(name);
if (res.claimsNsupports.empty())
auto csToName = trieCache.getClaimsForName(name);
if (csToName.claimsNsupports.empty())
return ret;
auto& claimNsupports =
!claimId.IsNull() ? res.find(claimId) :
!partialId.empty() ? res.find(partialId) : res.claimsNsupports[0];
!claimId.IsNull() ? csToName.find(claimId) :
!partialId.empty() ? csToName.find(partialId) : csToName.claimsNsupports[0];
if (claimNsupports.IsNull())
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.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;
}
@ -361,30 +407,125 @@ UniValue getclaimsforname(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie);
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);
}
std::string name = request.params[0].get_str();
auto claimsForName = trieCache.getClaimsForName(name);
auto csToName = trieCache.getClaimsForName(name);
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);
for (auto& claim : claimsForName.claimsNsupports)
claimObjs.push_back(claimAndSupportsToJSON(coinsCache, claim));
for (std::size_t i = 0; i < csToName.claimsNsupports.size(); ++i) {
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);
for (auto& support : claimsForName.unmatchedSupports)
for (auto& support : csToName.unmatchedSupports)
unmatchedSupports.push_back(supportToJSON(coinsCache, support));
result.pushKV(T_CLAIMS, claimObjs);
result.pushKV(T_LASTTAKEOVERHEIGHT, claimsForName.nLastTakeoverHeight);
result.pushKV(T_LASTTAKEOVERHEIGHT, csToName.nLastTakeoverHeight);
result.pushKV(T_SUPPORTSWITHOUTCLAIM, unmatchedSupports);
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)
{
validateRequest(request, GETCLAIMBYID, 1, 0);
@ -395,21 +536,29 @@ UniValue getclaimbyid(const JSONRPCRequest& request)
uint160 claimId;
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)
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);
std::string name;
CClaimValue claimValue;
if (getClaimById(claimId, name, &claimValue) || getClaimById(partialId, name, &claimValue)) {
auto res = trieCache.getClaimsForName(name);
auto& claimNsupports = !claimId.IsNull() ? res.find(claimId) : res.find(partialId);
auto csToName = trieCache.getClaimsForName(name);
auto& claimNsupports = !claimId.IsNull() ? csToName.find(claimId) : csToName.find(partialId);
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.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;
@ -450,7 +599,7 @@ UniValue getclaimsfortx(const JSONRPCRequest& request)
validateRequest(request, GETCLAIMSFORTX, 1, 0);
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);
int op;
@ -581,14 +730,14 @@ UniValue getnameproof(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie);
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);
}
uint160 claimId;
std::string partialId;
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;
if (!claimId.IsNull())
@ -608,6 +757,132 @@ UniValue getnameproof(const JSONRPCRequest& request)
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)
{
validateRequest(request, CHECKNORMALIZATION, 1, 0);
@ -631,9 +906,14 @@ static const CRPCCommand commands[] =
{ "Claimtrie", "gettotalclaims", &gettotalclaims, { "" } },
{ "Claimtrie", "gettotalvalueofclaims", &gettotalvalueofclaims, { T_CONTROLLINGONLY } },
{ "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", "checknormalization", &checknormalization, { T_NAME }},
{ "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 } },
};
void RegisterClaimTrieRPCCommands(CRPCTable &tableRPC)

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="")
{