Auto merge of #3255 - str4d:sapling-value-pool, r=ebfull
Track net value entering and exiting the Sapling circuit
This commit is contained in:
commit
f62fff80d5
18
src/chain.h
18
src/chain.h
|
@ -17,6 +17,7 @@
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
static const int SPROUT_VALUE_VERSION = 1001400;
|
static const int SPROUT_VALUE_VERSION = 1001400;
|
||||||
|
static const int SAPLING_VALUE_VERSION = 1010100;
|
||||||
|
|
||||||
struct CDiskBlockPos
|
struct CDiskBlockPos
|
||||||
{
|
{
|
||||||
|
@ -166,6 +167,15 @@ public:
|
||||||
//! Will be boost::none if nChainTx is zero.
|
//! Will be boost::none if nChainTx is zero.
|
||||||
boost::optional<CAmount> nChainSproutValue;
|
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
|
//! block header
|
||||||
int nVersion;
|
int nVersion;
|
||||||
uint256 hashMerkleRoot;
|
uint256 hashMerkleRoot;
|
||||||
|
@ -197,6 +207,8 @@ public:
|
||||||
nSequenceId = 0;
|
nSequenceId = 0;
|
||||||
nSproutValue = boost::none;
|
nSproutValue = boost::none;
|
||||||
nChainSproutValue = boost::none;
|
nChainSproutValue = boost::none;
|
||||||
|
nSaplingValue = 0;
|
||||||
|
nChainSaplingValue = boost::none;
|
||||||
|
|
||||||
nVersion = 0;
|
nVersion = 0;
|
||||||
hashMerkleRoot = uint256();
|
hashMerkleRoot = uint256();
|
||||||
|
@ -383,6 +395,12 @@ public:
|
||||||
if ((s.GetType() & SER_DISK) && (nVersion >= SPROUT_VALUE_VERSION)) {
|
if ((s.GetType() & SER_DISK) && (nVersion >= SPROUT_VALUE_VERSION)) {
|
||||||
READWRITE(nSproutValue);
|
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
|
uint256 GetBlockHash() const
|
||||||
|
|
22
src/main.cpp
22
src/main.cpp
|
@ -3246,7 +3246,14 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||||
pindexNew->nTx = block.vtx.size();
|
pindexNew->nTx = block.vtx.size();
|
||||||
pindexNew->nChainTx = 0;
|
pindexNew->nChainTx = 0;
|
||||||
CAmount sproutValue = 0;
|
CAmount sproutValue = 0;
|
||||||
|
CAmount saplingValue = 0;
|
||||||
for (auto tx : block.vtx) {
|
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) {
|
for (auto js : tx.vjoinsplit) {
|
||||||
sproutValue += js.vpub_old;
|
sproutValue += js.vpub_old;
|
||||||
sproutValue -= js.vpub_new;
|
sproutValue -= js.vpub_new;
|
||||||
|
@ -3254,6 +3261,8 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||||
}
|
}
|
||||||
pindexNew->nSproutValue = sproutValue;
|
pindexNew->nSproutValue = sproutValue;
|
||||||
pindexNew->nChainSproutValue = boost::none;
|
pindexNew->nChainSproutValue = boost::none;
|
||||||
|
pindexNew->nSaplingValue = saplingValue;
|
||||||
|
pindexNew->nChainSaplingValue = boost::none;
|
||||||
pindexNew->nFile = pos.nFile;
|
pindexNew->nFile = pos.nFile;
|
||||||
pindexNew->nDataPos = pos.nPos;
|
pindexNew->nDataPos = pos.nPos;
|
||||||
pindexNew->nUndoPos = 0;
|
pindexNew->nUndoPos = 0;
|
||||||
|
@ -3277,8 +3286,14 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
|
||||||
} else {
|
} else {
|
||||||
pindex->nChainSproutValue = boost::none;
|
pindex->nChainSproutValue = boost::none;
|
||||||
}
|
}
|
||||||
|
if (pindex->pprev->nChainSaplingValue) {
|
||||||
|
pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
|
||||||
|
} else {
|
||||||
|
pindex->nChainSaplingValue = boost::none;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pindex->nChainSproutValue = pindex->nSproutValue;
|
pindex->nChainSproutValue = pindex->nSproutValue;
|
||||||
|
pindex->nChainSaplingValue = pindex->nSaplingValue;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
LOCK(cs_nBlockSequenceId);
|
LOCK(cs_nBlockSequenceId);
|
||||||
|
@ -3961,14 +3976,21 @@ bool static LoadBlockIndexDB()
|
||||||
} else {
|
} else {
|
||||||
pindex->nChainSproutValue = boost::none;
|
pindex->nChainSproutValue = boost::none;
|
||||||
}
|
}
|
||||||
|
if (pindex->pprev->nChainSaplingValue) {
|
||||||
|
pindex->nChainSaplingValue = *pindex->pprev->nChainSaplingValue + pindex->nSaplingValue;
|
||||||
|
} else {
|
||||||
|
pindex->nChainSaplingValue = boost::none;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pindex->nChainTx = 0;
|
pindex->nChainTx = 0;
|
||||||
pindex->nChainSproutValue = boost::none;
|
pindex->nChainSproutValue = boost::none;
|
||||||
|
pindex->nChainSaplingValue = boost::none;
|
||||||
mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
|
mapBlocksUnlinked.insert(std::make_pair(pindex->pprev, pindex));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pindex->nChainTx = pindex->nTx;
|
pindex->nChainTx = pindex->nTx;
|
||||||
pindex->nChainSproutValue = pindex->nSproutValue;
|
pindex->nChainSproutValue = pindex->nSproutValue;
|
||||||
|
pindex->nChainSaplingValue = pindex->nSaplingValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Construct in-memory chain of branch IDs.
|
// Construct in-memory chain of branch IDs.
|
||||||
|
|
|
@ -159,6 +159,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
|
||||||
|
|
||||||
UniValue valuePools(UniValue::VARR);
|
UniValue valuePools(UniValue::VARR);
|
||||||
valuePools.push_back(ValuePoolDesc("sprout", blockindex->nChainSproutValue, blockindex->nSproutValue));
|
valuePools.push_back(ValuePoolDesc("sprout", blockindex->nChainSproutValue, blockindex->nSproutValue));
|
||||||
|
valuePools.push_back(ValuePoolDesc("sapling", blockindex->nChainSaplingValue, blockindex->nSaplingValue));
|
||||||
result.push_back(Pair("valuePools", valuePools));
|
result.push_back(Pair("valuePools", valuePools));
|
||||||
|
|
||||||
if (blockindex->pprev)
|
if (blockindex->pprev)
|
||||||
|
@ -776,6 +777,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp)
|
||||||
CBlockIndex* tip = chainActive.Tip();
|
CBlockIndex* tip = chainActive.Tip();
|
||||||
UniValue valuePools(UniValue::VARR);
|
UniValue valuePools(UniValue::VARR);
|
||||||
valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, boost::none));
|
valuePools.push_back(ValuePoolDesc("sprout", tip->nChainSproutValue, boost::none));
|
||||||
|
valuePools.push_back(ValuePoolDesc("sapling", tip->nChainSaplingValue, boost::none));
|
||||||
obj.push_back(Pair("valuePools", valuePools));
|
obj.push_back(Pair("valuePools", valuePools));
|
||||||
|
|
||||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||||
|
|
Loading…
Reference in New Issue