Track net value entering and exiting the Sapling circuit

This commit is contained in:
Jack Grigg 2018-05-09 12:15:46 +01:00
parent f0daf3915f
commit ae97177c86
No known key found for this signature in database
GPG Key ID: 665DBCD284F7DAFF
3 changed files with 42 additions and 0 deletions

View File

@ -17,6 +17,7 @@
#include <boost/foreach.hpp>
static const int SPROUT_VALUE_VERSION = 1001400;
static const int SAPLING_VALUE_VERSION = 1010100;
struct CDiskBlockPos
{
@ -166,6 +167,15 @@ public:
//! Will be boost::none if nChainTx is zero.
boost::optional<CAmount> nChainSproutValue;
//! Change in value held by the Sapling circuit over this block.
//! Not a boost::optional because this was added before Sapling activated, so we can
//! rely on the invariant that every block before this was added had nSaplingValue = 0.
CAmount nSaplingValue;
//! (memory only) Total value held by the Sapling circuit up to and including this block.
//! Will be boost::none if nChainTx is zero.
boost::optional<CAmount> nChainSaplingValue;
//! block header
int nVersion;
uint256 hashMerkleRoot;
@ -197,6 +207,8 @@ public:
nSequenceId = 0;
nSproutValue = boost::none;
nChainSproutValue = boost::none;
nSaplingValue = 0;
nChainSaplingValue = boost::none;
nVersion = 0;
hashMerkleRoot = uint256();
@ -383,6 +395,12 @@ public:
if ((s.GetType() & SER_DISK) && (nVersion >= SPROUT_VALUE_VERSION)) {
READWRITE(nSproutValue);
}
// Only read/write nSaplingValue if the client version used to create
// this index was storing them.
if ((s.GetType() & SER_DISK) && (nVersion >= SAPLING_VALUE_VERSION)) {
READWRITE(nSaplingValue);
}
}
uint256 GetBlockHash() const

View File

@ -3162,7 +3162,14 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
pindexNew->nTx = block.vtx.size();
pindexNew->nChainTx = 0;
CAmount sproutValue = 0;
CAmount saplingValue = 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"
// money to the transparent value pool, removing from the Sapling value
// pool. So we invert the sign here.
saplingValue += -tx.valueBalance;
for (auto js : tx.vjoinsplit) {
sproutValue += js.vpub_old;
sproutValue -= js.vpub_new;
@ -3170,6 +3177,8 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
}
pindexNew->nSproutValue = sproutValue;
pindexNew->nChainSproutValue = boost::none;
pindexNew->nSaplingValue = saplingValue;
pindexNew->nChainSaplingValue = boost::none;
pindexNew->nFile = pos.nFile;
pindexNew->nDataPos = pos.nPos;
pindexNew->nUndoPos = 0;
@ -3193,8 +3202,14 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
} else {
pindex->nChainSproutValue = boost::none;
}
if (pindex->pprev->nChainSaplingValue) {
pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
} else {
pindex->nChainSaplingValue = boost::none;
}
} else {
pindex->nChainSproutValue = pindex->nSproutValue;
pindex->nChainSaplingValue = pindex->nSaplingValue;
}
{
LOCK(cs_nBlockSequenceId);
@ -3877,14 +3892,21 @@ bool static LoadBlockIndexDB()
} else {
pindex->nChainSproutValue = boost::none;
}
if (pindex->pprev->nChainSaplingValue) {
pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
} else {
pindex->nChainSaplingValue = boost::none;
}
} else {
pindex->nChainTx = 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;
}
}
// Construct in-memory chain of branch IDs.

View File

@ -159,6 +159,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
UniValue valuePools(UniValue::VARR);
valuePools.push_back(ValuePoolDesc("sprout", blockindex->nChainSproutValue, blockindex->nSproutValue));
valuePools.push_back(ValuePoolDesc("sapling", blockindex->nChainSaplingValue, blockindex->nSaplingValue));
result.push_back(Pair("valuePools", valuePools));
if (blockindex->pprev)
@ -776,6 +777,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp)
CBlockIndex* tip = chainActive.Tip();
UniValue valuePools(UniValue::VARR);
valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, boost::none));
valuePools.push_back(ValuePoolDesc("sapling", tip->nChainSaplingValue, boost::none));
obj.push_back(Pair("valuePools", valuePools));
const Consensus::Params& consensusParams = Params().GetConsensus();