Merge pull request #27 from MyHush/ztxstats
Add shielded stats to getchaintxstats via zindex
This commit is contained in:
128
src/chain.h
128
src/chain.h
@@ -29,6 +29,7 @@ class CChainPower;
|
||||
#include "tinyformat.h"
|
||||
#include "uint256.h"
|
||||
extern int8_t is_STAKED(const char *chain_name);
|
||||
extern bool fZindex;
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -254,15 +255,108 @@ public:
|
||||
//! (memory only) Total amount of work (expected number of hashes) in the chain up to and including this block
|
||||
CChainPower chainPower;
|
||||
|
||||
// block stats
|
||||
//! Number of transactions in this block.
|
||||
//! Note: in a potential headers-first mode, this number cannot be relied upon
|
||||
unsigned int nTx;
|
||||
|
||||
//! Number of notarization transactions in this block.
|
||||
unsigned int nNotarizations;
|
||||
|
||||
//! (memory only) Number of payments (shielded or transparent) in the block
|
||||
//! up to and including this block. One transaction can contain one or more
|
||||
//! payments. This stat allows us to calculate ratios of shielded/transparent
|
||||
//! when combined with shielded payment stats
|
||||
unsigned int nPayments;
|
||||
|
||||
//! (memory only) Number of shielded transactions (of any kind) in the block up to and including this block.
|
||||
//! A shielded transaction is defined as a transaction that contains at least 1 JoinSplit, which includes
|
||||
//! shielding/de-shielding and other complex transaction possibilties including multiple taddrs/zaddrs as
|
||||
//! inputs and outputs.
|
||||
unsigned int nShieldedTx;
|
||||
|
||||
//! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined
|
||||
//! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent
|
||||
// inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc...
|
||||
unsigned int nFullyShieldedTx;
|
||||
|
||||
//! (memory only) Number of shielding payments. A shielding payment is defined
|
||||
//! as having a shielded output but transparent input: t->z
|
||||
unsigned int nShieldingPayments;
|
||||
|
||||
//! (memory only) Number of shielded payments. A shielded payment is defined
|
||||
//! as having a shielded input or output: t->z or z->t
|
||||
unsigned int nShieldedPayments;
|
||||
|
||||
//! (memory only) Number of fully shielded payments. A fully shielded payment is defined
|
||||
//! as having a shielded input and shielded output: z->z
|
||||
unsigned int nFullyShieldedPayments;
|
||||
|
||||
//! (memory only) Number of deshielding transactions. A deshielding transaction is defined
|
||||
//! as a transaction containing JoinSplits and at least one transparent output.
|
||||
unsigned int nDeshieldingTx;
|
||||
|
||||
//! (memory only) Number of deshielding payments. A deshielding payment is defined
|
||||
//! as one transparent input and one shielded output: z->t
|
||||
unsigned int nDeshieldingPayments;
|
||||
|
||||
//! (memory only) Number of shielding transactions. A shielding transaction is defined
|
||||
//! as a transaction containing JoinSplits and at least one transparent input
|
||||
// i.e. t->z or t->(z,t) or z->(z,z,t)
|
||||
unsigned int nShieldingTx;
|
||||
|
||||
// chain stats
|
||||
//! (memory only) Number of transactions in the chain up to and including this block.
|
||||
//! This value will be non-zero only if and only if transactions for this block and all its parents are available.
|
||||
//! Change to 64-bit type when necessary; won't happen before 2030
|
||||
unsigned int nChainTx;
|
||||
|
||||
//! Number of notarization transactions in this chain
|
||||
int64_t nChainNotarizations;
|
||||
|
||||
//! (memory only) Number of payments (shielded or transparent) in the chain
|
||||
//! up to and including this block. One transaction can contain one or more
|
||||
//! payments. This stat allows us to calculate ratios of shielded/transparent
|
||||
//! when combined with shielded payment stats
|
||||
int64_t nChainPayments;
|
||||
|
||||
//! (memory only) Number of shielded transactions (of any kind) in the chain up to and including this block.
|
||||
//! A shielded transaction is defined as a transaction that contains at least 1 JoinSplit, which includes
|
||||
//! shielding/de-shielding and other complex transaction possibilties including multiple taddrs/zaddrs as
|
||||
//! inputs and outputs.
|
||||
int64_t nChainShieldedTx;
|
||||
|
||||
//! (memory only) Number of fully shielded transactions. A fully shielded transaction is defined
|
||||
//! as a transaction containing JoinSplits and only shielded inputs and outputs, i.e. no transparent
|
||||
// inputs or outputs: z->z or z->(z,z) or z->(z,z,z,) etc...
|
||||
int64_t nChainFullyShieldedTx;
|
||||
|
||||
//! (memory only) Number of shielding payments. A shielding payment is defined
|
||||
//! as having a shielded output but transparent input: t->z
|
||||
int64_t nChainShieldingPayments;
|
||||
|
||||
//! (memory only) Number of shielded payments. A shielded payment is defined
|
||||
//! as having a shielded input or output: t->z or z->t
|
||||
int64_t nChainShieldedPayments;
|
||||
|
||||
//! (memory only) Number of fully shielded payments. A fully shielded payment is defined
|
||||
//! as having a shielded input and shielded output: z->z
|
||||
int64_t nChainFullyShieldedPayments;
|
||||
|
||||
//! (memory only) Number of deshielding transactions. A deshielding transaction is defined
|
||||
//! as a transaction containing JoinSplits and at least one transparent output.
|
||||
int64_t nChainDeshieldingTx;
|
||||
|
||||
//! (memory only) Number of deshielding payments. A deshielding payment is defined
|
||||
//! as one transparent input and one shielded output: z->t
|
||||
int64_t nChainDeshieldingPayments;
|
||||
|
||||
//! (memory only) Number of shielding transactions. A shielding transaction is defined
|
||||
//! as a transaction containing JoinSplits and at least one transparent input
|
||||
// i.e. t->z or t->(z,t) or z->(z,z,t)
|
||||
int64_t nChainShieldingTx;
|
||||
|
||||
|
||||
//! Verification status of this block. See enum BlockStatus
|
||||
unsigned int nStatus;
|
||||
|
||||
@@ -321,6 +415,24 @@ public:
|
||||
chainPower = CChainPower();
|
||||
nTx = 0;
|
||||
nChainTx = 0;
|
||||
|
||||
nChainShieldedTx = 0;
|
||||
nChainShieldingTx = 0;
|
||||
nChainDeshieldingTx = 0;
|
||||
nChainFullyShieldedTx = 0;
|
||||
nChainShieldedPayments = 0;
|
||||
nChainShieldingPayments = 0;
|
||||
nChainDeshieldingPayments = 0;
|
||||
nChainFullyShieldedPayments = 0;
|
||||
nShieldedTx = 0;
|
||||
nShieldingTx = 0;
|
||||
nDeshieldingTx = 0;
|
||||
nFullyShieldedTx = 0;
|
||||
nShieldedPayments = 0;
|
||||
nShieldingPayments = 0;
|
||||
nDeshieldingPayments = 0;
|
||||
nFullyShieldedPayments = 0;
|
||||
|
||||
nStatus = 0;
|
||||
nCachedBranchId = boost::none;
|
||||
hashSproutAnchor = uint256();
|
||||
@@ -506,6 +618,22 @@ public:
|
||||
READWRITE(VARINT(chainPower.nHeight));
|
||||
READWRITE(VARINT(nStatus));
|
||||
READWRITE(VARINT(nTx));
|
||||
|
||||
// These values only serialized when -zindex enabled
|
||||
if(fZindex) {
|
||||
READWRITE(VARINT(nShieldedTx));
|
||||
READWRITE(VARINT(nShieldingTx));
|
||||
READWRITE(VARINT(nDeshieldingTx));
|
||||
READWRITE(VARINT(nFullyShieldedTx));
|
||||
|
||||
READWRITE(VARINT(nShieldedPayments));
|
||||
READWRITE(VARINT(nShieldingPayments));
|
||||
READWRITE(VARINT(nDeshieldingPayments));
|
||||
READWRITE(VARINT(nFullyShieldedPayments));
|
||||
|
||||
READWRITE(VARINT(nNotarizations));
|
||||
}
|
||||
|
||||
if (nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO))
|
||||
READWRITE(VARINT(nFile));
|
||||
if (nStatus & BLOCK_HAVE_DATA)
|
||||
|
||||
10
src/init.cpp
10
src/init.cpp
@@ -400,6 +400,7 @@ std::string HelpMessage(HelpMessageMode mode)
|
||||
strUsage += HelpMessageOpt("-addressindex", strprintf(_("Maintain a full address index, used to query for the balance, txids and unspent outputs for addresses (default: %u)"), DEFAULT_ADDRESSINDEX));
|
||||
strUsage += HelpMessageOpt("-timestampindex", strprintf(_("Maintain a timestamp index for block hashes, used to query blocks hashes by a range of timestamps (default: %u)"), DEFAULT_TIMESTAMPINDEX));
|
||||
strUsage += HelpMessageOpt("-spentindex", strprintf(_("Maintain a full spent index, used to query the spending txid and input index for an outpoint (default: %u)"), DEFAULT_SPENTINDEX));
|
||||
strUsage += HelpMessageOpt("-zindex", strprintf(_("Maintain extra statistics about shielded transactions and payments (default: %u)"), 0));
|
||||
strUsage += HelpMessageGroup(_("Connection options:"));
|
||||
strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open"));
|
||||
strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), 100));
|
||||
@@ -1282,14 +1283,11 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Komodo is probably already running.") + " %s.", strDataDir, e.what()));
|
||||
}
|
||||
|
||||
fprintf(stderr,"About to create pidfile\n");
|
||||
#ifndef _WIN32
|
||||
CreatePidFile(GetPidFile(), getpid());
|
||||
#endif
|
||||
fprintf(stderr,"created pidfile\n");
|
||||
if (GetBoolArg("-shrinkdebugfile", !fDebug))
|
||||
ShrinkDebugFile();
|
||||
fprintf(stderr,"past shrinkdebugfile\n");
|
||||
LogPrintf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
LogPrintf("Komodo version %s (%s)\n", FormatFullVersion(), CLIENT_DATE);
|
||||
|
||||
@@ -1668,6 +1666,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stderr, "zindex=%s in block index\n", fZindex ? "enabled" : "disabled");
|
||||
if (fZindex != GetBoolArg("-zindex", false)) {
|
||||
strLoadError = _("You need to rebuild the database using -reindex to change -zindex");
|
||||
break;
|
||||
}
|
||||
|
||||
// Check for changed -prune state. What we are concerned about is a user who has pruned blocks
|
||||
// in the past, but is now trying to run unpruned.
|
||||
if (fHavePruned && !fPruneMode) {
|
||||
|
||||
179
src/main.cpp
179
src/main.cpp
@@ -98,6 +98,7 @@ bool fExperimentalMode = true;
|
||||
bool fImporting = false;
|
||||
bool fReindex = false;
|
||||
bool fTxIndex = false;
|
||||
bool fZindex = false;
|
||||
bool fAddressIndex = false;
|
||||
bool fTimestampIndex = false;
|
||||
bool fSpentIndex = false;
|
||||
@@ -4767,10 +4768,17 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block)
|
||||
/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
|
||||
bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBlockIndex *pindexNew, const CDiskBlockPos& pos)
|
||||
{
|
||||
pindexNew->nTx = block.vtx.size();
|
||||
pindexNew->nChainTx = 0;
|
||||
CAmount sproutValue = 0;
|
||||
CAmount saplingValue = 0;
|
||||
pindexNew->nTx = block.vtx.size();
|
||||
pindexNew->nChainTx = 0;
|
||||
pindexNew->nChainPayments = 0;
|
||||
CAmount sproutValue = 0;
|
||||
CAmount saplingValue = 0;
|
||||
bool isShieldedTx = false;
|
||||
int64_t nShieldedSpends=0,nShieldedOutputs=0,nPayments=0;
|
||||
int64_t nShieldedTx=0,nFullyShieldedTx=0,nDeshieldingTx=0,nShieldingTx=0;
|
||||
int64_t nShieldedPayments=0,nFullyShieldedPayments=0,nShieldingPayments=0,nDeshieldingPayments=0;
|
||||
int64_t nNotarizations=0;
|
||||
|
||||
for (auto tx : block.vtx) {
|
||||
// Negative valueBalance "takes" money from the transparent value pool
|
||||
// and adds it to the Sapling value pool. Positive valueBalance "gives"
|
||||
@@ -4782,7 +4790,71 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
sproutValue += js.vpub_old;
|
||||
sproutValue -= js.vpub_new;
|
||||
}
|
||||
|
||||
// Ignore following stats unless -zindex
|
||||
if (!fZindex)
|
||||
continue;
|
||||
|
||||
nShieldedSpends = tx.vShieldedSpend.size();
|
||||
nShieldedOutputs = tx.vShieldedOutput.size();
|
||||
isShieldedTx = (nShieldedSpends + nShieldedOutputs) > 0 ? true : false;
|
||||
|
||||
// We want to avoid full verification with a low false-positive rate
|
||||
if(tx.vin.size()==13 && tx.vout.size()==2 && tx.vout[1].scriptPubKey.IsOpReturn() && tx.vout[1].nValue==0) {
|
||||
nNotarizations++;
|
||||
}
|
||||
|
||||
if(isShieldedTx) {
|
||||
nShieldedTx++;
|
||||
if(tx.vin.size()==0 && tx.vout.size()==0) {
|
||||
nFullyShieldedTx++;
|
||||
} else if(tx.vin.size()>0) {
|
||||
nShieldingTx++;
|
||||
} else if(tx.vout.size()>0) {
|
||||
nDeshieldingTx++;
|
||||
}
|
||||
//NOTE: These are at best heuristics. Improve them as much as possible.
|
||||
// You cannot compare stats generated from different sets of heuristics, so
|
||||
// if you change this code, you must delete and resync from scratch, or you
|
||||
// will be mixing together data from two set of heuristics.
|
||||
|
||||
if (nShieldedOutputs >= 1) {
|
||||
// If there are shielded outputs, count each as a payment
|
||||
// By default, if there is more than 1 output, we assume 1 change output which is not a payment.
|
||||
// In the case of multiple outputs which spend inputs exactly, there is no change output and this
|
||||
// heuristic will undercount payments. Since this edge case is rare, this seems acceptable.
|
||||
// t->(t,t,z) = 1 shielded payment
|
||||
// z->(z,z) = 1 shielded payment + shielded change
|
||||
// t->(z,z) = 1 shielded payment + shielded change
|
||||
// t->(t,z) = 1 shielded payment + transparent change
|
||||
// (z,z)->z = 1 shielded payment (has this xtn ever occurred?)
|
||||
// z->(z,z,z) = 2 shielded payments + shielded change
|
||||
// Assume that there is always 1 change output when there are more than one
|
||||
nShieldedPayments += nShieldedOutputs > 1 ? (nShieldedOutputs-1) : 1;
|
||||
|
||||
// Fully shielded do not count toward shielding/deshielding
|
||||
if(tx.vin.size()==0 && tx.vout.size()==0) {
|
||||
nFullyShieldedPayments += nShieldedOutputs > 1 ? (nShieldedOutputs-1) : 1;
|
||||
} else {
|
||||
nShieldingPayments += nShieldedOutputs > 1 ? (nShieldedOutputs-1) : 1;
|
||||
}
|
||||
} else if (nShieldedSpends >=1) {
|
||||
// Shielded inputs with no shielded outputs. We know none are change output because
|
||||
// change would flow back to the zaddr
|
||||
// z->t = 1 shielded payment
|
||||
// z->(t,t) = 2 shielded payments
|
||||
// z->(t,t,t) = 3 shielded payments
|
||||
nShieldedPayments += tx.vout.size();
|
||||
nDeshieldingPayments += tx.vout.size() > 1 ? tx.vout.size()-1 : tx.vout.size();
|
||||
}
|
||||
//TODO: correctly add shielded payments to total chain payments
|
||||
nPayments += nShieldedPayments;
|
||||
} else {
|
||||
// No shielded payments, add transparent payments minus a change address
|
||||
nPayments += tx.vout.size() > 1 ? tx.vout.size()-1 : tx.vout.size();
|
||||
}
|
||||
}
|
||||
|
||||
pindexNew->nSproutValue = sproutValue;
|
||||
pindexNew->nChainSproutValue = boost::none;
|
||||
pindexNew->nSaplingValue = saplingValue;
|
||||
@@ -4792,6 +4864,20 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
pindexNew->nUndoPos = 0;
|
||||
pindexNew->nStatus |= BLOCK_HAVE_DATA;
|
||||
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
|
||||
|
||||
if (fZindex) {
|
||||
pindexNew->nPayments = nPayments;
|
||||
pindexNew->nShieldedTx = nShieldedTx;
|
||||
pindexNew->nFullyShieldedTx = nFullyShieldedTx;
|
||||
pindexNew->nDeshieldingTx = nDeshieldingTx;
|
||||
pindexNew->nShieldingTx = nShieldingTx;
|
||||
pindexNew->nShieldedPayments = nShieldedPayments;
|
||||
pindexNew->nFullyShieldedPayments = nFullyShieldedPayments;
|
||||
pindexNew->nDeshieldingPayments = nDeshieldingPayments;
|
||||
pindexNew->nShieldingPayments = nShieldingPayments;
|
||||
pindexNew->nNotarizations = nNotarizations;
|
||||
}
|
||||
|
||||
setDirtyBlockIndex.insert(pindexNew);
|
||||
|
||||
if (pindexNew->pprev == NULL || pindexNew->pprev->nChainTx) {
|
||||
@@ -4803,7 +4889,22 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
while (!queue.empty()) {
|
||||
CBlockIndex *pindex = queue.front();
|
||||
queue.pop_front();
|
||||
pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
|
||||
|
||||
if (fZindex) {
|
||||
pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx;
|
||||
pindex->nChainNotarizations = (pindex->pprev ? pindex->pprev->nChainNotarizations : 0) + pindex->nNotarizations;
|
||||
pindex->nChainShieldedTx = (pindex->pprev ? pindex->pprev->nChainShieldedTx : 0) + pindex->nShieldedTx;
|
||||
pindex->nChainFullyShieldedTx = (pindex->pprev ? pindex->pprev->nChainFullyShieldedTx : 0) + pindex->nFullyShieldedTx;
|
||||
pindex->nChainShieldingTx = (pindex->pprev ? pindex->pprev->nChainShieldingTx : 0) + pindex->nShieldingTx;
|
||||
pindex->nChainDeshieldingTx = (pindex->pprev ? pindex->pprev->nChainDeshieldingTx : 0) + pindex->nDeshieldingTx;
|
||||
|
||||
pindex->nChainPayments = (pindex->pprev ? pindex->pprev->nChainPayments : 0) + pindex->nPayments;
|
||||
pindex->nChainShieldedPayments = (pindex->pprev ? pindex->pprev->nChainShieldedPayments : 0) + pindex->nShieldedPayments;
|
||||
pindex->nChainFullyShieldedPayments = (pindex->pprev ? pindex->pprev->nChainFullyShieldedPayments : 0) + pindex->nFullyShieldedPayments;
|
||||
pindex->nChainShieldingPayments = (pindex->pprev ? pindex->pprev->nChainShieldingPayments : 0) + pindex->nShieldingPayments;
|
||||
pindex->nChainDeshieldingPayments = (pindex->pprev ? pindex->pprev->nChainDeshieldingPayments : 0) + pindex->nDeshieldingPayments;
|
||||
}
|
||||
|
||||
if (pindex->pprev) {
|
||||
if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
|
||||
pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
|
||||
@@ -4840,6 +4941,10 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||
}
|
||||
}
|
||||
|
||||
if (fZindex)
|
||||
fprintf(stderr, "ht.%d, ShieldedPayments=%d, ShieldedTx=%d, FullyShieldedTx=%d, ntz=%d\n",
|
||||
pindexNew->GetHeight(), nShieldedPayments, nShieldedTx, nFullyShieldedTx, nNotarizations );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6070,7 +6175,20 @@ bool static LoadBlockIndexDB()
|
||||
if (pindex->nTx > 0) {
|
||||
if (pindex->pprev) {
|
||||
if (pindex->pprev->nChainTx) {
|
||||
pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
|
||||
|
||||
if (fZindex) {
|
||||
pindex->nChainNotarizations = pindex->pprev->nChainNotarizations + pindex->nNotarizations;
|
||||
pindex->nChainTx = pindex->pprev->nChainTx + pindex->nTx;
|
||||
pindex->nChainShieldedTx = pindex->pprev->nChainShieldedTx + pindex->nShieldedTx;
|
||||
pindex->nChainShieldedPayments = pindex->pprev->nChainShieldedPayments + pindex->nShieldedPayments;
|
||||
pindex->nChainShieldingTx = pindex->pprev->nChainShieldingTx + pindex->nShieldingTx;
|
||||
pindex->nChainShieldingPayments = pindex->pprev->nChainShieldingPayments + pindex->nShieldingPayments;
|
||||
pindex->nChainDeshieldingTx = pindex->pprev->nChainShieldedTx + pindex->nShieldedTx;
|
||||
pindex->nChainDeshieldingPayments = pindex->pprev->nChainShieldedPayments + pindex->nShieldedPayments;
|
||||
pindex->nChainFullyShieldedTx = pindex->pprev->nChainFullyShieldedTx + pindex->nFullyShieldedTx;
|
||||
pindex->nChainFullyShieldedPayments = pindex->pprev->nChainFullyShieldedPayments + pindex->nFullyShieldedPayments;
|
||||
}
|
||||
|
||||
if (pindex->pprev->nChainSproutValue && pindex->nSproutValue) {
|
||||
pindex->nChainSproutValue = *pindex->pprev->nChainSproutValue + *pindex->nSproutValue;
|
||||
} else {
|
||||
@@ -6082,15 +6200,36 @@ bool static LoadBlockIndexDB()
|
||||
pindex->nChainSaplingValue = boost::none;
|
||||
}
|
||||
} else {
|
||||
pindex->nChainTx = 0;
|
||||
pindex->nChainSproutValue = boost::none;
|
||||
pindex->nChainSaplingValue = boost::none;
|
||||
pindex->nChainTx = 0;
|
||||
if (fZindex) {
|
||||
pindex->nChainNotarizations = 0;
|
||||
pindex->nChainShieldedTx = 0;
|
||||
pindex->nChainFullyShieldedTx = 0;
|
||||
pindex->nChainShieldedPayments = 0;
|
||||
pindex->nChainShieldingPayments = 0;
|
||||
pindex->nChainDeshieldingTx = 0;
|
||||
pindex->nChainDeshieldingPayments = 0;
|
||||
pindex->nChainFullyShieldedTx = 0;
|
||||
pindex->nChainFullyShieldedPayments = 0;
|
||||
}
|
||||
pindex->nChainSproutValue = boost::none;
|
||||
pindex->nChainSaplingValue = boost::none;
|
||||
mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
|
||||
}
|
||||
} else {
|
||||
pindex->nChainTx = pindex->nTx;
|
||||
pindex->nChainSproutValue = pindex->nSproutValue;
|
||||
pindex->nChainSaplingValue = pindex->nSaplingValue;
|
||||
pindex->nChainTx = pindex->nTx;
|
||||
pindex->nChainSproutValue = pindex->nSproutValue;
|
||||
pindex->nChainSaplingValue = pindex->nSaplingValue;
|
||||
if (fZindex) {
|
||||
pindex->nChainNotarizations = pindex->nNotarizations;
|
||||
pindex->nChainShieldedTx = pindex->nShieldedTx;
|
||||
pindex->nChainShieldedPayments = pindex->nShieldedPayments;
|
||||
pindex->nChainShieldingTx = pindex->nShieldingTx;
|
||||
pindex->nChainShieldingPayments = pindex->nShieldingPayments;
|
||||
pindex->nChainDeshieldingTx = pindex->nDeshieldingTx;
|
||||
pindex->nChainDeshieldingPayments = pindex->nDeshieldingPayments;
|
||||
pindex->nChainFullyShieldedPayments = pindex->nFullyShieldedPayments;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Construct in-memory chain of branch IDs.
|
||||
@@ -6168,10 +6307,15 @@ bool static LoadBlockIndexDB()
|
||||
// Check whether we have a transaction index
|
||||
pblocktree->ReadFlag("txindex", fTxIndex);
|
||||
LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
|
||||
|
||||
// Check whether we have an address index
|
||||
pblocktree->ReadFlag("addressindex", fAddressIndex);
|
||||
LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
|
||||
|
||||
// Check whether we have a shielded index
|
||||
pblocktree->ReadFlag("zindex", fZindex);
|
||||
LogPrintf("%s: shielded index %s\n", __func__, fZindex ? "enabled" : "disabled");
|
||||
|
||||
// Check whether we have a timestamp index
|
||||
pblocktree->ReadFlag("timestampindex", fTimestampIndex);
|
||||
LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
|
||||
@@ -6535,17 +6679,22 @@ bool InitBlockIndex() {
|
||||
// Use the provided setting for -txindex in the new database
|
||||
fTxIndex = GetBoolArg("-txindex", true);
|
||||
pblocktree->WriteFlag("txindex", fTxIndex);
|
||||
|
||||
// Use the provided setting for -addressindex in the new database
|
||||
fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
|
||||
pblocktree->WriteFlag("addressindex", fAddressIndex);
|
||||
|
||||
|
||||
// Use the provided setting for -zindex in the new database
|
||||
fZindex = GetBoolArg("-zindex", DEFAULT_SHIELDEDINDEX);
|
||||
pblocktree->WriteFlag("zindex", fZindex);
|
||||
|
||||
// Use the provided setting for -timestampindex in the new database
|
||||
fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
|
||||
pblocktree->WriteFlag("timestampindex", fTimestampIndex);
|
||||
|
||||
|
||||
fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
|
||||
pblocktree->WriteFlag("spentindex", fSpentIndex);
|
||||
fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX);
|
||||
fprintf(stderr,"fAddressIndex.%d/%d fSpentIndex.%d/%d fZindex.%d/%d\n",fAddressIndex,DEFAULT_ADDRESSINDEX,fSpentIndex,DEFAULT_SPENTINDEX,fZindex, DEFAULT_SHIELDEDINDEX );
|
||||
LogPrintf("Initializing databases...\n");
|
||||
}
|
||||
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
|
||||
|
||||
@@ -125,6 +125,7 @@ static const int64_t DEFAULT_MAX_TIP_AGE = 24 * 60 * 60;
|
||||
#define DEFAULT_ADDRESSINDEX (GetArg("-ac_cc",0) != 0 || GetArg("-ac_ccactivate",0) != 0)
|
||||
#define DEFAULT_SPENTINDEX (GetArg("-ac_cc",0) != 0 || GetArg("-ac_ccactivate",0) != 0)
|
||||
static const bool DEFAULT_TIMESTAMPINDEX = false;
|
||||
static const bool DEFAULT_SHIELDEDINDEX = false;
|
||||
static const unsigned int DEFAULT_DB_MAX_OPEN_FILES = 1000;
|
||||
static const bool DEFAULT_DB_COMPRESSION = true;
|
||||
|
||||
@@ -157,6 +158,7 @@ extern bool fImporting;
|
||||
extern bool fReindex;
|
||||
extern int nScriptCheckThreads;
|
||||
extern bool fTxIndex;
|
||||
extern bool fZindex;
|
||||
extern bool fIsBareMultisigStd;
|
||||
extern bool fCheckBlockIndex;
|
||||
extern bool fCheckpointsEnabled;
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
using namespace std;
|
||||
|
||||
extern int32_t KOMODO_INSYNC;
|
||||
extern bool fZindex;
|
||||
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
|
||||
void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
|
||||
int32_t komodo_notarized_height(int32_t *prevMoMheightp,uint256 *hashp,uint256 *txidp);
|
||||
@@ -1949,7 +1950,7 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp)
|
||||
"{\n"
|
||||
" \"time\": xxxxx, (numeric) The timestamp for the final block in the window in UNIX format.\n"
|
||||
" \"txcount\": xxxxx, (numeric) The total number of transactions in the chain up to that point.\n"
|
||||
" \"window_final_block_hash\": \"...\", (string) The hash of the final block in the window.\n"
|
||||
" \"window_final_block_hash\": \"...\", (string) The hash of the final block in the window.\n"
|
||||
" \"window_block_count\": xxxxx, (numeric) Size of the window in number of blocks.\n"
|
||||
" \"window_tx_count\": xxxxx, (numeric) The number of transactions in the window. Only returned if \"window_block_count\" is > 0.\n"
|
||||
" \"window_interval\": xxxxx, (numeric) The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0.\n"
|
||||
@@ -1990,20 +1991,91 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp)
|
||||
}
|
||||
}
|
||||
|
||||
const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->GetHeight() - blockcount);
|
||||
int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
|
||||
int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
|
||||
const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->GetHeight() - blockcount);
|
||||
int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast();
|
||||
int nTxDiff = pindex->nChainTx - pindexPast->nChainTx;
|
||||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.pushKV("time", (int64_t)pindex->nTime);
|
||||
ret.pushKV("txcount", (int64_t)pindex->nChainTx);
|
||||
|
||||
if (fZindex) {
|
||||
ret.pushKV("notarizations", (int64_t)pindex->nChainNotarizations);
|
||||
ret.pushKV("shielded_txcount", (int64_t)pindex->nChainShieldedTx);
|
||||
ret.pushKV("fully_shielded_txcount", (int64_t)pindex->nChainFullyShieldedTx);
|
||||
ret.pushKV("deshielding_txcount", (int64_t)pindex->nChainDeshieldingTx);
|
||||
ret.pushKV("shielding_txcount", (int64_t)pindex->nChainShieldingTx);
|
||||
ret.pushKV("shielded_payments", (int64_t)pindex->nChainShieldedPayments);
|
||||
ret.pushKV("fully_shielded_payments", (int64_t)pindex->nChainFullyShieldedPayments);
|
||||
ret.pushKV("deshielding_payments", (int64_t)pindex->nChainDeshieldingPayments);
|
||||
ret.pushKV("shielding_payments", (int64_t)pindex->nChainShieldingPayments);
|
||||
}
|
||||
|
||||
ret.pushKV("window_final_block_hash", pindex->GetBlockHash().GetHex());
|
||||
ret.pushKV("window_final_block_height", pindex->GetHeight());
|
||||
ret.pushKV("window_block_count", blockcount);
|
||||
|
||||
if (blockcount > 0) {
|
||||
ret.pushKV("window_tx_count", nTxDiff);
|
||||
int64_t nPaymentsDiff = pindex->nChainPayments - pindexPast->nChainPayments;
|
||||
int64_t nShieldedTxDiff = pindex->nChainShieldedTx - pindexPast->nChainShieldedTx;
|
||||
int64_t nShieldingTxDiff = pindex->nChainShieldingTx - pindexPast->nChainShieldingTx;
|
||||
int64_t nDeshieldingTxDiff = pindex->nChainDeshieldingTx - pindexPast->nChainDeshieldingTx;
|
||||
int64_t nFullyShieldedTxDiff = pindex->nChainFullyShieldedTx - pindexPast->nChainFullyShieldedTx;
|
||||
int64_t nShieldedPaymentsDiff = pindex->nChainShieldedPayments - pindexPast->nChainShieldedPayments;
|
||||
int64_t nShieldingPaymentsDiff = pindex->nChainShieldingPayments - pindexPast->nChainShieldingPayments;
|
||||
int64_t nDeshieldingPaymentsDiff = pindex->nChainDeshieldingPayments - pindexPast->nChainDeshieldingPayments;
|
||||
int64_t nFullyShieldedPaymentsDiff = pindex->nChainFullyShieldedPayments - pindexPast->nChainFullyShieldedPayments;
|
||||
unsigned int nNotarizationsDiff = pindex->nChainNotarizations - pindexPast->nChainNotarizations;
|
||||
|
||||
ret.pushKV("window_interval", nTimeDiff);
|
||||
ret.pushKV("window_txcount", nTxDiff);
|
||||
ret.pushKV("window_payments", nPaymentsDiff);
|
||||
ret.pushKV("window_notarizations", (int) nNotarizationsDiff);
|
||||
|
||||
if (nTimeDiff > 0) {
|
||||
ret.pushKV("txrate", ((double)nTxDiff) / nTimeDiff);
|
||||
ret.pushKV("txrate", ((double)nTxDiff) / nTimeDiff);
|
||||
if (fZindex) {
|
||||
ret.pushKV("notarization_txrate", ((double)nNotarizationsDiff) / nTimeDiff);
|
||||
ret.pushKV("shielded_txrate", ((double)nShieldedTxDiff) / nTimeDiff);
|
||||
ret.pushKV("fully_shielded_txrate", ((double)nFullyShieldedTxDiff) / nTimeDiff);
|
||||
ret.pushKV("paymentrate", ((double)nPaymentsDiff) / nTimeDiff);
|
||||
ret.pushKV("shielded_paymentrate", ((double)nShieldedPaymentsDiff) / nTimeDiff);
|
||||
ret.pushKV("fully_shielded_paymentrate", ((double)nFullyShieldedPaymentsDiff) / nTimeDiff);
|
||||
}
|
||||
}
|
||||
|
||||
if (fZindex) {
|
||||
ret.pushKV("window_fully_shielded_payments", nFullyShieldedPaymentsDiff);
|
||||
ret.pushKV("window_shielded_payments", nShieldedPaymentsDiff);
|
||||
ret.pushKV("window_shielding_payments", nShieldingPaymentsDiff);
|
||||
ret.pushKV("window_deshielding_payments", nDeshieldingPaymentsDiff);
|
||||
if (nTxDiff > 0) {
|
||||
ret.pushKV("shielded_tx_percent", ((double)nShieldedTxDiff) / nTxDiff);
|
||||
ret.pushKV("fully_shielded_tx_percent", ((double)nFullyShieldedTxDiff) / nTxDiff);
|
||||
ret.pushKV("shielding_tx_percent", ((double)nShieldingTxDiff) / nTxDiff);
|
||||
ret.pushKV("deshielding_tx_percent", ((double)nDeshieldingTxDiff) / nTxDiff);
|
||||
}
|
||||
if (nPaymentsDiff > 0) {
|
||||
ret.pushKV("shielded_payments_percent", ((double)nShieldedPaymentsDiff) / nPaymentsDiff);
|
||||
ret.pushKV("fully_shielded_payments_percent", ((double)nFullyShieldedPaymentsDiff) / nPaymentsDiff);
|
||||
ret.pushKV("shielding_payments_percent", ((double)nShieldingPaymentsDiff) / nPaymentsDiff);
|
||||
ret.pushKV("deshielding_payments_percent", ((double)nDeshieldingPaymentsDiff) / nPaymentsDiff);
|
||||
}
|
||||
|
||||
// Shielded-only statistics
|
||||
UniValue shielded(UniValue::VOBJ);
|
||||
if (nShieldedTxDiff > 0) {
|
||||
shielded.pushKV("fully_shielded_tx_percent", ((double)nFullyShieldedTxDiff) / nShieldedTxDiff );
|
||||
shielded.pushKV("shielding_tx_percent", ((double)nShieldingTxDiff) / nShieldedTxDiff );
|
||||
shielded.pushKV("deshielding_tx_percent", ((double)nDeshieldingTxDiff) / nShieldedTxDiff );
|
||||
}
|
||||
if (nShieldedPaymentsDiff > 0) {
|
||||
shielded.pushKV("fully_shielded_payments_percent", ((double)nFullyShieldedPaymentsDiff) / nShieldedPaymentsDiff );
|
||||
shielded.pushKV("shielding_payments_percent", ((double)nShieldingPaymentsDiff) / nShieldedPaymentsDiff );
|
||||
shielded.pushKV("deshielding_payments_percent", ((double)nDeshieldingPaymentsDiff) / nShieldedPaymentsDiff );
|
||||
}
|
||||
if(nShieldedTxDiff+nShieldedPaymentsDiff > 0)
|
||||
ret.pushKV("shielded_only", shielded);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
43
src/txdb.cpp
43
src/txdb.cpp
@@ -702,24 +702,33 @@ bool CBlockTreeDB::LoadBlockIndexGuts()
|
||||
CBlockIndex* pindexNew = InsertBlockIndex(diskindex.GetBlockHash());
|
||||
pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev);
|
||||
pindexNew->SetHeight(diskindex.GetHeight());
|
||||
pindexNew->nFile = diskindex.nFile;
|
||||
pindexNew->nDataPos = diskindex.nDataPos;
|
||||
pindexNew->nUndoPos = diskindex.nUndoPos;
|
||||
pindexNew->hashSproutAnchor = diskindex.hashSproutAnchor;
|
||||
pindexNew->nVersion = diskindex.nVersion;
|
||||
pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
|
||||
pindexNew->nFile = diskindex.nFile;
|
||||
pindexNew->nDataPos = diskindex.nDataPos;
|
||||
pindexNew->nUndoPos = diskindex.nUndoPos;
|
||||
pindexNew->hashSproutAnchor = diskindex.hashSproutAnchor;
|
||||
pindexNew->nVersion = diskindex.nVersion;
|
||||
pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
|
||||
pindexNew->hashFinalSaplingRoot = diskindex.hashFinalSaplingRoot;
|
||||
pindexNew->nTime = diskindex.nTime;
|
||||
pindexNew->nBits = diskindex.nBits;
|
||||
pindexNew->nNonce = diskindex.nNonce;
|
||||
pindexNew->nSolution = diskindex.nSolution;
|
||||
pindexNew->nStatus = diskindex.nStatus;
|
||||
pindexNew->nCachedBranchId = diskindex.nCachedBranchId;
|
||||
pindexNew->nTx = diskindex.nTx;
|
||||
pindexNew->nSproutValue = diskindex.nSproutValue;
|
||||
pindexNew->nSaplingValue = diskindex.nSaplingValue;
|
||||
pindexNew->segid = diskindex.segid;
|
||||
pindexNew->nNotaryPay = diskindex.nNotaryPay;
|
||||
pindexNew->nTime = diskindex.nTime;
|
||||
pindexNew->nBits = diskindex.nBits;
|
||||
pindexNew->nNonce = diskindex.nNonce;
|
||||
pindexNew->nSolution = diskindex.nSolution;
|
||||
pindexNew->nStatus = diskindex.nStatus;
|
||||
pindexNew->nCachedBranchId = diskindex.nCachedBranchId;
|
||||
pindexNew->nTx = diskindex.nTx;
|
||||
pindexNew->nShieldedTx = diskindex.nShieldedTx;
|
||||
pindexNew->nShieldedPayments = diskindex.nShieldedPayments;
|
||||
pindexNew->nShieldingTx = diskindex.nShieldingTx;
|
||||
pindexNew->nShieldingPayments = diskindex.nShieldingPayments;
|
||||
pindexNew->nDeshieldingTx = diskindex.nDeshieldingTx;
|
||||
pindexNew->nDeshieldingPayments = diskindex.nDeshieldingPayments;
|
||||
pindexNew->nFullyShieldedTx = diskindex.nFullyShieldedTx;
|
||||
pindexNew->nFullyShieldedPayments = diskindex.nFullyShieldedPayments;
|
||||
pindexNew->nSproutValue = diskindex.nSproutValue;
|
||||
pindexNew->nSaplingValue = diskindex.nSaplingValue;
|
||||
pindexNew->segid = diskindex.segid;
|
||||
pindexNew->nNotaryPay = diskindex.nNotaryPay;
|
||||
|
||||
//fprintf(stderr,"loadguts ht.%d\n",pindexNew->GetHeight());
|
||||
// Consistency checks
|
||||
auto header = pindexNew->GetBlockHeader();
|
||||
|
||||
Reference in New Issue
Block a user