Skip to content

Commit

Permalink
Merge pull request #566 from zcoinofficial/logging
Browse files Browse the repository at this point in the history
Add RPC function to regenerate mint pool if incorrect indexes used
  • Loading branch information
levonpetrosyan93 authored Aug 1, 2019
2 parents 0350571 + 45239ba commit 53fb75c
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 12 deletions.
8 changes: 8 additions & 0 deletions src/hdmint/tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ bool CHDMintTracker::UpdateMetaStatus(const std::set<uint256>& setMempool, CMint
COutPoint outPoint;
sigma::PublicCoin pubCoin(mint.GetPubCoinValue(), mint.denom);
bool isMintInChain = GetOutPoint(outPoint, pubCoin);
LogPrintf("UpdateMetaStatus : isMintInChain: %d\n", isMintInChain);
const uint256& txidMint = outPoint.hash;

//See if there is internal record of spending this mint (note this is memory only, would reset on restart - next function checks this)
Expand All @@ -396,10 +397,13 @@ bool CHDMintTracker::UpdateMetaStatus(const std::set<uint256>& setMempool, CMint
if(!isPendingSpend && fSpend)
isPendingSpend = IsMempoolSpendOurs(setMempool, mint.hashSerial);

LogPrintf("UpdateMetaStatus : isPendingSpend: %d\n", isPendingSpend);

// See if there is a blockchain record of spending this mint
CSigmaState *sigmaState = sigma::CSigmaState::GetState();
Scalar bnSerial;
bool isConfirmedSpend = sigmaState->IsUsedCoinSerialHash(bnSerial, mint.hashSerial);
LogPrintf("UpdateMetaStatus : isConfirmedSpend: %d\n", isConfirmedSpend);

bool isUsed = isPendingSpend || isConfirmedSpend;

Expand All @@ -421,6 +425,8 @@ bool CHDMintTracker::UpdateMetaStatus(const std::set<uint256>& setMempool, CMint
mint.txid = txidMint;
}

LogPrintf("UpdateMetaStatus : mint.txid = %d\n", mint.txid.GetHex());

if (setMempool.count(mint.txid)) {
if(mint.nHeight>-1) mint.nHeight = -1;
if(mint.nId>-1) mint.nId = -1;
Expand Down Expand Up @@ -550,6 +556,8 @@ void CHDMintTracker::UpdateMintStateFromMempool(const std::vector<GroupElement>&
std::set<uint256> setMempool = GetMempoolTxids();
for (auto& pubcoin : pubCoins) {
uint256 hashPubcoin = primitives::GetPubCoinValueHash(pubcoin);

LogPrintf("UpdateMintStateFromMempool: hashPubcoin=%d\n", hashPubcoin.GetHex());
// Check hashPubcoin in db
if(walletdb.ReadMintPoolPair(hashPubcoin, hashSeedMasterEntry, seedId, nCount)){
// If found in db but not in memory - this is likely a resync
Expand Down
48 changes: 39 additions & 9 deletions src/hdmint/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ CHDMintWallet::CHDMintWallet(const std::string& strWalletFile) : tracker(strWall

// Use MasterKeyId from HDChain as index for mintpool
uint160 hashSeedMaster = pwalletMain->GetHDChain().masterKeyID;
LogPrintf("hashSeedMaster: %d\n", hashSeedMaster.GetHex());

if (!SetupWallet(hashSeedMaster)) {
LogPrintf("%s: failed to save deterministic seed for hashseed %s\n", __func__, hashSeedMaster.GetHex());
Expand All @@ -37,7 +38,6 @@ CHDMintWallet::CHDMintWallet(const std::string& strWalletFile) : tracker(strWall
}
bool CHDMintWallet::SetupWallet(const uint160& hashSeedMaster, bool fResetCount)
{

CWalletDB walletdb(strWalletFile);
if (pwalletMain->IsLocked())
return false;
Expand Down Expand Up @@ -65,29 +65,38 @@ bool CHDMintWallet::SetupWallet(const uint160& hashSeedMaster, bool fResetCount)
}

// Regenerate mintPool entry from given values
void CHDMintWallet::RegenerateMintPoolEntry(const uint160& mintHashSeedMaster, CKeyID& seedId, const int32_t& nCount)
std::pair<uint256,uint256> CHDMintWallet::RegenerateMintPoolEntry(const uint160& mintHashSeedMaster, CKeyID& seedId, const int32_t& nCount)
{
// hashPubcoin, hashSerial
std::pair<uint256,uint256> nIndexes;

CWalletDB walletdb(strWalletFile);
//Is locked
if (pwalletMain->IsLocked())
return;
throw ZerocoinException("Error: Please enter the wallet passphrase with walletpassphrase first.");

uint512 seedZerocoin;
if(!CreateZerocoinSeed(seedZerocoin, nCount, seedId, false))
return;
throw ZerocoinException("Unable to create seed for mint regeneration.");

GroupElement commitmentValue;
sigma::PrivateCoin coin(sigma::Params::get_default(), sigma::CoinDenomination::SIGMA_DENOM_1);
if(!SeedToZerocoin(seedZerocoin, commitmentValue, coin))
return;
throw ZerocoinException("Unable to create zerocoin from seed in mint regeneration.");

uint256 hashPubcoin = primitives::GetPubCoinValueHash(commitmentValue);
uint256 hashSerial = primitives::GetSerialHash(coin.getSerialNumber());

MintPoolEntry mintPoolEntry(mintHashSeedMaster, seedId, nCount);
mintPool.Add(make_pair(hashPubcoin, mintPoolEntry));
CWalletDB(strWalletFile).WritePubcoin(primitives::GetSerialHash(coin.getSerialNumber()), commitmentValue);
CWalletDB(strWalletFile).WritePubcoin(hashSerial, commitmentValue);
CWalletDB(strWalletFile).WriteMintPoolPair(hashPubcoin, mintPoolEntry);
LogPrintf("%s : hashSeedMaster=%s hashPubcoin=%s count=%d\n", __func__, hashSeedMaster.GetHex(), hashPubcoin.GetHex(), nCount);
LogPrintf("%s : hashSeedMaster=%s hashPubcoin=%s seedId=%s\n count=%d\n", __func__, hashSeedMaster.GetHex(), hashPubcoin.GetHex(), seedId.GetHex(), nCount);

nIndexes.first = hashPubcoin;
nIndexes.second = hashSerial;

return nIndexes;

}

Expand Down Expand Up @@ -129,7 +138,7 @@ void CHDMintWallet::GenerateMintPool(int32_t nIndex)
mintPool.Add(make_pair(hashPubcoin, mintPoolEntry));
CWalletDB(strWalletFile).WritePubcoin(primitives::GetSerialHash(coin.getSerialNumber()), commitmentValue);
CWalletDB(strWalletFile).WriteMintPoolPair(hashPubcoin, mintPoolEntry);
LogPrintf("%s : hashSeedMaster=%s hashPubcoin=%s count=%d\n", __func__, hashSeedMaster.GetHex(), hashPubcoin.GetHex(), nLastCount);
LogPrintf("%s : hashSeedMaster=%s hashPubcoin=%s seedId=%d count=%d\n", __func__, hashSeedMaster.GetHex(), hashPubcoin.GetHex(), seedId.GetHex(), nLastCount);
}

// Update local + DB entries for count last generated
Expand All @@ -142,12 +151,29 @@ bool CHDMintWallet::LoadMintPoolFromDB()
{
vector<std::pair<uint256, MintPoolEntry>> listMintPool = CWalletDB(strWalletFile).ListMintPool();

for (auto& mintPoolPair : listMintPool)
for (auto& mintPoolPair : listMintPool){
LogPrintf("LoadMintPoolFromDB: hashPubcoin: %d hashSeedMaster: %d seedId: %d nCount: %s\n",
mintPoolPair.first.GetHex(), get<0>(mintPoolPair.second).GetHex(), get<1>(mintPoolPair.second).GetHex(), get<2>(mintPoolPair.second));
mintPool.Add(mintPoolPair);
}

return true;
}

bool CHDMintWallet::GetSerialForPubcoin(const std::vector<std::pair<uint256, GroupElement>>& serialPubcoinPairs, const uint256& hashPubcoin, uint256& hashSerial)
{
bool fFound = false;
for(const auto& serialPubcoinPair : serialPubcoinPairs){
if(hashPubcoin == primitives::GetPubCoinValueHash(serialPubcoinPair.second)){
hashSerial = serialPubcoinPair.first;
fFound = true;
break;
}
}

return fFound;
}

//Catch the counter up with the chain
void CHDMintWallet::SyncWithChain(bool fGenerateMintPool, boost::optional<std::list<std::pair<uint256, MintPoolEntry>>> listMints)
{
Expand Down Expand Up @@ -453,6 +479,9 @@ bool CHDMintWallet::GenerateMint(const sigma::CoinDenomination denom, sigma::Pri
UpdateCountLocal();
}

LogPrintf("GenerateMint: hashSeedMaster: %s seedId: %s nCount: %d\n",
get<0>(mintPoolEntry.get()).GetHex(), get<1>(mintPoolEntry.get()).GetHex(), get<2>(mintPoolEntry.get()));

uint512 seedZerocoin;
CreateZerocoinSeed(seedZerocoin, get<2>(mintPoolEntry.get()), get<1>(mintPoolEntry.get()), false);

Expand All @@ -465,6 +494,7 @@ bool CHDMintWallet::GenerateMint(const sigma::CoinDenomination denom, sigma::Pri

uint256 hashSerial = primitives::GetSerialHash(coin.getSerialNumber());
dMint = CHDMint(get<2>(mintPoolEntry.get()), get<1>(mintPoolEntry.get()), hashSerial, coin.getPublicCoin().getValue());
LogPrintf("GenerateMint: hashPubcoin: %s\n", dMint.GetPubCoinHash().GetHex());
dMint.SetDenomination(denom);

return true;
Expand Down
3 changes: 2 additions & 1 deletion src/hdmint/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ class CHDMintWallet
bool GenerateMint(const sigma::CoinDenomination denom, sigma::PrivateCoin& coin, CHDMint& dMint, boost::optional<MintPoolEntry> mintPoolEntry = boost::none);
bool LoadMintPoolFromDB();
bool RegenerateMint(const CHDMint& dMint, CSigmaEntry& zerocoin);
bool GetSerialForPubcoin(const std::vector<std::pair<uint256, GroupElement>>& serialPubcoinPairs, const uint256& hashPubcoin, uint256& hashSerial);
bool IsSerialInBlockchain(const uint256& hashSerial, int& nHeightTx, uint256& txidSpend, CTransaction& tx);
bool TxOutToPublicCoin(const CTxOut& txout, sigma::PublicCoin& pubCoin, CValidationState& state);
void RegenerateMintPoolEntry(const uint160& mintHashSeedMaster, CKeyID& seedId, const int32_t& nCount);
std::pair<uint256,uint256> RegenerateMintPoolEntry(const uint160& mintHashSeedMaster, CKeyID& seedId, const int32_t& nCount);
void GenerateMintPool(int32_t nIndex = 0);
bool SetMintSeedSeen(std::pair<uint256,MintPoolEntry> mintPoolEntryPair, const int& nHeight, const uint256& txid, const sigma::CoinDenomination& denom);
bool SeedToZerocoin(const uint512& seedZerocoin, GroupElement& bnValue, sigma::PrivateCoin& coin);
Expand Down
5 changes: 5 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1820,6 +1820,7 @@ bool AcceptToMemoryPoolWorker(
LogPrintf("Updating mint tracker state from Mempool..");
#ifdef ENABLE_WALLET
if (zwalletMain) {
LogPrintf("Updating spend state from Mempool..");
zwalletMain->GetTracker().UpdateSpendStateFromMempool(zcSpendSerialsV3);
}
#endif
Expand All @@ -1835,6 +1836,7 @@ bool AcceptToMemoryPoolWorker(
}
}
if (zwalletMain) {
LogPrintf("Updating mint state from Mempool..");
zwalletMain->GetTracker().UpdateMintStateFromMempool(zcMintPubcoinsV3);
}
}
Expand Down Expand Up @@ -3587,11 +3589,14 @@ ConnectTip(CValidationState &state, const CChainParams &chainparams, CBlockIndex
#ifdef ENABLE_WALLET
// Sync with HDMint wallet
if (zwalletMain) {
LogPrintf("Checking if block contains wallet mints..\n");
if (pblock->sigmaTxInfo->spentSerials.size() > 0) {
LogPrintf("HDmint: UpdateSpendStateFromBlock. [height: %d]\n", GetHeight());
zwalletMain->GetTracker().UpdateSpendStateFromBlock(pblock->sigmaTxInfo->spentSerials);
}

if (pblock->sigmaTxInfo->mints.size() > 0) {
LogPrintf("HDmint: UpdateMintStateFromBlock. [height: %d]\n", GetHeight());
zwalletMain->GetTracker().UpdateMintStateFromBlock(pblock->sigmaTxInfo->mints);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/rpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listunspent", 0 },
{ "listunspent", 1 },
{ "listunspent", 2 },
{ "regeneratemintpool", 0 },
{ "listunspentmintzerocoins", 0 },
{ "listunspentmintzerocoins", 1 },
{ "listunspentmintzerocoins", 2 },
Expand Down
51 changes: 51 additions & 0 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2652,6 +2652,56 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp)
return result;
}

UniValue regeneratemintpool(const UniValue &params, bool fHelp) {

if (pwalletMain->IsLocked())
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED,
"Error: Please enter the wallet passphrase with walletpassphrase first.");

if (!pwalletMain->IsHDSeedAvailable() || !zwalletMain) {
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED,
"Error: Can only regenerate mintpool on a HD-enabled wallet.");
}

CWalletDB walletdb(pwalletMain->strWalletFile);
vector<std::pair<uint256, MintPoolEntry>> listMintPool = walletdb.ListMintPool();
std::vector<std::pair<uint256, GroupElement>> serialPubcoinPairs = walletdb.ListSerialPubcoinPairs();

// <hashPubcoin, hashSerial>
std::pair<uint256,uint256> nIndexes;

uint256 oldHashSerial;
uint256 oldHashPubcoin;

bool reindexRequired = false;

for (auto& mintPoolPair : listMintPool){
LogPrintf("regeneratemintpool: hashPubcoin: %d hashSeedMaster: %d seedId: %d nCount: %s\n",
mintPoolPair.first.GetHex(), get<0>(mintPoolPair.second).GetHex(), get<1>(mintPoolPair.second).GetHex(), get<2>(mintPoolPair.second));

oldHashPubcoin = mintPoolPair.first;
bool hasSerial = zwalletMain->GetSerialForPubcoin(serialPubcoinPairs, oldHashPubcoin, oldHashSerial);

MintPoolEntry entry = mintPoolPair.second;
nIndexes = zwalletMain->RegenerateMintPoolEntry(get<0>(entry),get<1>(entry),get<2>(entry));

if(nIndexes.first != oldHashPubcoin){
walletdb.EraseMintPoolPair(oldHashPubcoin);
reindexRequired = true;
}

if(!hasSerial || nIndexes.second != oldHashSerial){
walletdb.ErasePubcoin(oldHashSerial);
reindexRequired = true;
}
}

if(reindexRequired)
return "Mintpool issue corrected. Please shutdown zcoin and restart with -reindex flag.";

return "No issues with mintpool detected.";
}

//[zcoin]: zerocoin section
// zerocoin section

Expand Down Expand Up @@ -4033,6 +4083,7 @@ static const CRPCCommand commands[] =
{ "wallet", "walletpassphrase", &walletpassphrase, true },
{ "wallet", "removeprunedfunds", &removeprunedfunds, true },
{ "wallet", "setmininput", &setmininput, false },
{ "wallet", "regeneratemintpool", &regeneratemintpool, false },
{ "wallet", "listunspentmintzerocoins", &listunspentmintzerocoins, false },
{ "wallet", "listunspentsigmamints", &listunspentsigmamints, false },
{ "wallet", "mint", &mint, false },
Expand Down
2 changes: 0 additions & 2 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7906,8 +7906,6 @@ bool CWallet::InitLoadWallet() {
zwalletMain = new CHDMintWallet(pwalletMain->strWalletFile);
}



RegisterValidationInterface(walletInstance);

CBlockIndex *pindexRescan = chainActive.Tip();
Expand Down
10 changes: 10 additions & 0 deletions src/wallet/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,11 @@ bool CWalletDB::ReadPubcoin(const uint256& hashSerial, GroupElement& pubcoin)
return Read(make_pair(string("pubcoin"), hashSerial), pubcoin);
}

bool CWalletDB::ErasePubcoin(const uint256& hashSerial)
{
return Erase(make_pair(string("pubcoin"), hashSerial));
}

std::vector<std::pair<uint256, GroupElement>> CWalletDB::ListSerialPubcoinPairs()
{
std::vector<std::pair<uint256, GroupElement>> listSerialPubcoin;
Expand Down Expand Up @@ -1372,6 +1377,11 @@ std::vector<std::pair<uint256, GroupElement>> CWalletDB::ListSerialPubcoinPairs(

}

bool CWalletDB::EraseMintPoolPair(const uint256& hashPubcoin)
{
return Erase(make_pair(string("mintpool"), hashPubcoin));
}

bool CWalletDB::WriteMintPoolPair(const uint256& hashPubcoin, const std::tuple<uint160, CKeyID, int32_t>& hashSeedMintPool)
{
return Write(make_pair(string("mintpool"), hashPubcoin), hashSeedMintPool);
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/walletdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,9 @@ class CWalletDB : public CDB
std::list<CHDMint> ListHDMints();
bool WritePubcoin(const uint256& hashSerial, const GroupElement& hashPubcoin);
bool ReadPubcoin(const uint256& hashSerial, GroupElement& hashPubcoin);
bool ErasePubcoin(const uint256& hashSerial);
std::vector<std::pair<uint256, GroupElement>> ListSerialPubcoinPairs();
bool EraseMintPoolPair(const uint256& hashPubcoin);
bool WriteMintPoolPair(const uint256& hashPubcoin, const std::tuple<uint160, CKeyID, int32_t>& hashSeedMintPool);
bool ReadMintPoolPair(const uint256& hashPubcoin, uint160& hashSeedMaster, CKeyID& seedId, int32_t& nCount);
std::vector<std::pair<uint256, MintPoolEntry>> ListMintPool();
Expand Down

0 comments on commit 53fb75c

Please sign in to comment.