Skip to content

Commit

Permalink
[zPIV] Update supply when disconnecting blocks too
Browse files Browse the repository at this point in the history
  • Loading branch information
random-zebra committed Apr 10, 2020
1 parent b738103 commit ee5c843
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 62 deletions.
59 changes: 1 addition & 58 deletions src/consensus/zerocoin_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ bool RecalculatePIVSupply(int nHeightStart, bool fSkipZpiv)

// Rewrite zpiv supply too
if (!fSkipZpiv && pindex->nHeight >= consensus.height_start_ZC) {
UpdateZPIVSupply(block, pindex, true);
UpdateZPIVSupplyConnect(block, pindex, true);
}

// Add fraudulent funds to the supply and remove any recovered funds.
Expand Down Expand Up @@ -275,63 +275,6 @@ bool RecalculatePIVSupply(int nHeightStart, bool fSkipZpiv)
return true;
}

bool UpdateZPIVSupply(const CBlock& block, CBlockIndex* pindex, bool fJustCheck)
{
const Consensus::Params& consensus = Params().GetConsensus();
if (pindex->nHeight < consensus.height_start_ZC)
return true;

//Add mints to zPIV supply (mints are forever disabled after last checkpoint)
if (pindex->nHeight < consensus.height_last_ZC_AccumCheckpoint) {
std::list<CZerocoinMint> listMints;
std::set<uint256> setAddedToWallet;
BlockToZerocoinMintList(block, listMints, true);
for (const auto& m : listMints) {
mapZerocoinSupply.at(m.GetDenomination())++;
//Remove any of our own mints from the mintpool
if (!fJustCheck && pwalletMain) {
if (pwalletMain->IsMyMint(m.GetValue())) {
pwalletMain->UpdateMint(m.GetValue(), pindex->nHeight, m.GetTxHash(), m.GetDenomination());
// Add the transaction to the wallet
for (auto& tx : block.vtx) {
uint256 txid = tx.GetHash();
if (setAddedToWallet.count(txid))
continue;
if (txid == m.GetTxHash()) {
CWalletTx wtx(pwalletMain, tx);
wtx.nTimeReceived = block.GetBlockTime();
wtx.SetMerkleBranch(block);
pwalletMain->AddToWallet(wtx, false, nullptr);
setAddedToWallet.insert(txid);
}
}
}
}
}
}

//Remove spends from zPIV supply
std::list<libzerocoin::CoinDenomination> listDenomsSpent = ZerocoinSpendListFromBlock(block, true);
for (const auto& denom : listDenomsSpent) {
mapZerocoinSupply.at(denom)--;
// zerocoin failsafe
if (mapZerocoinSupply.at(denom) < 0)
return error("Block contains zerocoins that spend more than are in the available supply to spend");
}

// Update Wrapped Serials amount
// A one-time event where only the zPIV supply was off (due to serial duplication off-chain on main net)
if (Params().NetworkID() == CBaseChainParams::MAIN && pindex->nHeight == consensus.height_last_ZC_WrappedSerials + 1) {
for (const auto& denom : libzerocoin::zerocoinDenomList)
mapZerocoinSupply.at(denom) += GetWrapppedSerialInflation(denom);
}

for (const auto& denom : libzerocoin::zerocoinDenomList)
LogPrint(BCLog::LEGACYZC, "%s coins for denomination %d pubcoin %s\n", __func__, denom, mapZerocoinSupply.at(denom));

return true;
}

CAmount GetInvalidUTXOValue()
{
CAmount nValue = 0;
Expand Down
1 change: 0 additions & 1 deletion src/consensus/zerocoin_verify.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ bool CheckPublicCoinSpendVersion(int version);
bool ContextualCheckZerocoinSpend(const CTransaction& tx, const libzerocoin::CoinSpend* spend, int nHeight, const uint256& hashBlock);
bool ContextualCheckZerocoinSpendNoSerialCheck(const CTransaction& tx, const libzerocoin::CoinSpend* spend, int nHeight, const uint256& hashBlock);
bool RecalculatePIVSupply(int nHeightStart, bool fSkipZpiv = true);
bool UpdateZPIVSupply(const CBlock& block, CBlockIndex* pindex, bool fJustCheck);
CAmount GetInvalidUTXOValue();

#endif //PIVX_CONSENSUS_ZEROCOIN_VERIFY_H
6 changes: 5 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2310,6 +2310,10 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
return error("DisconnectBlock() : block and undo data inconsistent");

//Track zPIV money supply
if (!UpdateZPIVSupplyDisconnect(block, pindex))
return error("%s: Failed to calculate new zPIV supply", __func__);

// undo transactions in reverse order
for (int i = block.vtx.size() - 1; i >= 0; i--) {
const CTransaction& tx = block.vtx[i];
Expand Down Expand Up @@ -2767,7 +2771,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
view.SetBestBlock(pindex->GetBlockHash());

// Update zPIV money supply map
if (!UpdateZPIVSupply(block, pindex, fJustCheck)) {
if (!UpdateZPIVSupplyConnect(block, pindex, fJustCheck)) {
return state.DoS(100, error("%s: Failed to calculate new zPIV supply for block=%s height=%d", __func__,
block.GetHash().GetHex(), pindex->nHeight), REJECT_INVALID);
}
Expand Down
101 changes: 99 additions & 2 deletions src/zpivchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "zpivchain.h"
#include "zpiv/zpivmodule.h"

#include "guiinterface.h"
#include "invalid.h"
#include "main.h"
#include "txdb.h"
#include "guiinterface.h"
#include "wallet/wallet.h"
#include "zpiv/zpivmodule.h"

// 6 comes from OPCODE (1) + vch.size() (1) + BIGNUM size (4)
#define SCRIPT_OFFSET 6
Expand Down Expand Up @@ -406,3 +408,98 @@ int64_t GetZerocoinSupply()
return nTotal;
}

bool UpdateZPIVSupplyConnect(const CBlock& block, CBlockIndex* pindex, bool fJustCheck)
{
const Consensus::Params& consensus = Params().GetConsensus();
if (pindex->nHeight < consensus.height_start_ZC)
return true;

//Add mints to zPIV supply (mints are forever disabled after last checkpoint)
if (pindex->nHeight < consensus.height_last_ZC_AccumCheckpoint) {
std::list<CZerocoinMint> listMints;
std::set<uint256> setAddedToWallet;
BlockToZerocoinMintList(block, listMints, true);
for (const CZerocoinMint& m : listMints) {
mapZerocoinSupply.at(m.GetDenomination())++;
//Remove any of our own mints from the mintpool
if (!fJustCheck && pwalletMain) {
if (pwalletMain->IsMyMint(m.GetValue())) {
pwalletMain->UpdateMint(m.GetValue(), pindex->nHeight, m.GetTxHash(), m.GetDenomination());
// Add the transaction to the wallet
for (auto& tx : block.vtx) {
uint256 txid = tx.GetHash();
if (setAddedToWallet.count(txid))
continue;
if (txid == m.GetTxHash()) {
CWalletTx wtx(pwalletMain, tx);
wtx.nTimeReceived = block.GetBlockTime();
wtx.SetMerkleBranch(block);
pwalletMain->AddToWallet(wtx, false, nullptr);
setAddedToWallet.insert(txid);
}
}
}
}
}
}

//Remove spends from zPIV supply
std::list<libzerocoin::CoinDenomination> listDenomsSpent = ZerocoinSpendListFromBlock(block, true);
for (const libzerocoin::CoinDenomination& denom : listDenomsSpent) {
mapZerocoinSupply.at(denom)--;
// zerocoin failsafe
if (mapZerocoinSupply.at(denom) < 0)
return error("Block contains zerocoins that spend more than are in the available supply to spend");
}

// Update Wrapped Serials amount
// A one-time event where only the zPIV supply was off (due to serial duplication off-chain on main net)
if (Params().NetworkID() == CBaseChainParams::MAIN && pindex->nHeight == consensus.height_last_ZC_WrappedSerials + 1) {
for (const libzerocoin::CoinDenomination& denom : libzerocoin::zerocoinDenomList)
mapZerocoinSupply.at(denom) += GetWrapppedSerialInflation(denom);
}

for (const libzerocoin::CoinDenomination& denom : libzerocoin::zerocoinDenomList)
LogPrint(BCLog::LEGACYZC, "%s coins for denomination %d pubcoin %s\n", __func__, denom, mapZerocoinSupply.at(denom));

return true;
}

bool UpdateZPIVSupplyDisconnect(const CBlock& block, CBlockIndex* pindex)
{
const Consensus::Params& consensus = Params().GetConsensus();
if (pindex->nHeight < consensus.height_start_ZC)
return true;

// Undo Update Wrapped Serials amount
// A one-time event where only the zPIV supply was off (due to serial duplication off-chain on main net)
if (Params().NetworkID() == CBaseChainParams::MAIN && pindex->nHeight == consensus.height_last_ZC_WrappedSerials + 1) {
for (const libzerocoin::CoinDenomination& denom : libzerocoin::zerocoinDenomList)
mapZerocoinSupply.at(denom) -= GetWrapppedSerialInflation(denom);
}

// Re-add spends to zPIV supply
std::list<libzerocoin::CoinDenomination> listDenomsSpent = ZerocoinSpendListFromBlock(block, true);
for (const libzerocoin::CoinDenomination& denom : listDenomsSpent) {
mapZerocoinSupply.at(denom)++;
}

// Remove mints from zPIV supply (mints are forever disabled after last checkpoint)
if (pindex->nHeight < consensus.height_last_ZC_AccumCheckpoint) {
std::list<CZerocoinMint> listMints;
std::set<uint256> setAddedToWallet;
BlockToZerocoinMintList(block, listMints, true);
for (const CZerocoinMint& m : listMints) {
const libzerocoin::CoinDenomination denom = m.GetDenomination();
mapZerocoinSupply.at(denom)--;
// zerocoin failsafe
if (mapZerocoinSupply.at(denom) < 0)
return error("Block contains zerocoins that spend more than are in the available supply to spend");
}
}

for (const libzerocoin::CoinDenomination& denom : libzerocoin::zerocoinDenomList)
LogPrint(BCLog::LEGACYZC, "%s coins for denomination %d pubcoin %s\n", __func__, denom, mapZerocoinSupply.at(denom));

return true;
}
4 changes: 4 additions & 0 deletions src/zpivchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
#ifndef PIVX_ZPIVCHAIN_H
#define PIVX_ZPIVCHAIN_H

#include "chain.h"
#include "libzerocoin/Coin.h"
#include "libzerocoin/Denominations.h"
#include "libzerocoin/CoinSpend.h"
#include <list>
#include <string>

class CBlock;
class CBlockIndex;
class CBigNum;
struct CMintMeta;
class CTransaction;
Expand Down Expand Up @@ -40,6 +42,8 @@ std::list<libzerocoin::CoinDenomination> ZerocoinSpendListFromBlock(const CBlock
/** Global variable for the zerocoin supply */
extern std::map<libzerocoin::CoinDenomination, int64_t> mapZerocoinSupply;
int64_t GetZerocoinSupply();
bool UpdateZPIVSupplyConnect(const CBlock& block, CBlockIndex* pindex, bool fJustCheck);
bool UpdateZPIVSupplyDisconnect(const CBlock& block, CBlockIndex* pindex);


#endif //PIVX_ZPIVCHAIN_H

0 comments on commit ee5c843

Please sign in to comment.