From 860541d2e432d51f8f44ebbe2823ebd409f1bc49 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 4 May 2021 12:25:12 -0400 Subject: [PATCH 01/44] Show relay status in getpeerinfo --- src/net.h | 1 + src/rpc/net.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/net.h b/src/net.h index bdc56de1b..d55d500e1 100644 --- a/src/net.h +++ b/src/net.h @@ -223,6 +223,7 @@ public: int nStartingHeight; uint64_t nSendBytes; uint64_t nRecvBytes; + bool fRelayTxes; bool fAllowlisted; // If true this node bypasses DoS ban limits bool fFeeler; // If true this node is being used as a short lived feeler. double dPingTime; diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 46c3cf24d..6ea9819a8 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -95,6 +95,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n" " \"bytessent\": n, (numeric) The total bytes sent\n" " \"bytesrecv\": n, (numeric) The total bytes received\n" + " \"relaytxes\":true|false, (boolean) Whether peer has asked us to relay transactions to it\n" " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n" " \"timeoffset\": ttt, (numeric) The time offset in seconds (deprecated, always 0)\n" " \"pingtime\": n, (numeric) ping time\n" @@ -146,6 +147,8 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) obj.push_back(Pair("lastrecv", stats.nLastRecv)); obj.push_back(Pair("bytessent", stats.nSendBytes)); obj.push_back(Pair("bytesrecv", stats.nRecvBytes)); + obj.push_back(Pair("relaytxes", stats.fRelayTxes)); + obj.push_back(Pair("conntime", stats.nTimeConnected)); obj.push_back(Pair("timeoffset", 0)); obj.push_back(Pair("pingtime", stats.dPingTime)); From d977345b26e53409150a7c9a844c389d96e8052e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 15 May 2021 12:15:00 -0400 Subject: [PATCH 02/44] Specify that cleanwallettransactions only works on utxos, not zutxos --- src/wallet/rpcwallet.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1b90c56a5..4da6204e6 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1103,7 +1103,7 @@ UniValue cleanwallettransactions(const UniValue& params, bool fHelp, const CPubK if (fHelp || params.size() > 1 ) throw runtime_error( "cleanwallettransactions \"txid\"\n" - "\nRemove all txs that are spent. You can clear all txs bar one, by specifiying a txid.\n" + "\nRemove all transparent UTXOs that are spent. You can clear all transactions bar one, by specifiying a txid.\n" "\nPlease backup your wallet.dat before running this command.\n" "\nArguments:\n" "1. \"txid\" (string, optional) The transaction id to keep.\n" @@ -1133,9 +1133,7 @@ UniValue cleanwallettransactions(const UniValue& params, bool fHelp, const CPubK if ( !pwalletMain->IsMine(tmp_tx) ) { throw runtime_error("\nThe transaction is not yours!\n"); - } - else - { + } else { for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it) { const CWalletTx& wtx = (*it).second; @@ -1145,14 +1143,10 @@ UniValue cleanwallettransactions(const UniValue& params, bool fHelp, const CPubK } } } - } - else - { + } else { throw runtime_error("\nThe transaction could not be found!\n"); } - } - else - { + } else { // get all locked utxos to relock them later. vector vLockedUTXO; pwalletMain->ListLockedCoins(vLockedUTXO); From 4db320355b6408e4dbec91ba825eeebd1eb31880 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 19 May 2021 10:51:07 -0400 Subject: [PATCH 03/44] Small optimizations during rescanning and ChainTip() --- src/wallet/wallet.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 0a848ff33..b72e96386 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -480,13 +480,19 @@ void CWallet::ChainTip(const CBlockIndex *pindex, pblock->GetBlockTime() > GetTime() - 144*ASSETCHAINS_BLOCKTIME) { BuildWitnessCache(pindex, false); - RunSaplingConsolidation(pindex->GetHeight()); - DeleteWalletTransactions(pindex); + if (fSaplingConsolidationEnabled) { + RunSaplingConsolidation(pindex->GetHeight()); + } + if (fTxDeleteEnabled) { + DeleteWalletTransactions(pindex); + } } else { //Build initial witnesses on every block BuildWitnessCache(pindex, true); - if (initialDownloadCheck && pindex->GetHeight() % fDeleteInterval == 0) { - DeleteWalletTransactions(pindex); + if (fTxDeleteEnabled) { + if (initialDownloadCheck && pindex->GetHeight() % fDeleteInterval == 0) { + DeleteWalletTransactions(pindex); + } } } } else { @@ -1122,6 +1128,7 @@ void CWallet::BuildWitnessCache(const CBlockIndex* pindex, bool witnessOnly) nd->witnessHeight = pblockindex->GetHeight(); } } + } } @@ -2734,8 +2741,10 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate) BuildWitnessCache(pindex, true); //Delete Transactions - if (pindex->GetHeight() % fDeleteInterval == 0) - DeleteWalletTransactions(pindex); + if (fTxDeleteEnabled) { + if (pindex->GetHeight() % fDeleteInterval == 0) + DeleteWalletTransactions(pindex); + } if (GetTime() >= nNow + 60) { nNow = GetTime(); From 379679556607614e82ec7fbbaf5c37373c50ce96 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 19 May 2021 12:04:04 -0400 Subject: [PATCH 04/44] Allow help, z_listaddresses, listaddresses, z_exportkey and dumpprivkey during RPC warmup --- src/rpc/server.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 5ae2c88e1..bf99a5b78 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -825,9 +825,13 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms { LOCK(cs_rpcWarmup); if (fRPCInWarmup) { - // hush-cli stop is the only valid RPC command during warmup - // We don't know if we have valid blocks or wallet yet, nothing else is safe - if (pcmd->name != "stop") { + // Most RPCs are unsafe to run during warmup, but stop+help are fine + // Others may not have data loaded yet, such as wallet details, but + // those RPCs are written defensively to deal with that. Allowing these + // few RPCs means we can see our addresses and make private key backups + // while a very long wallet rescan is happening + if (pcmd->name != "stop" && pcmd->name != "help" && pcmd->name != "z_listaddresses" && pcmd->name != "z_exportkey" && + pcmd->name != "listaddresses" && pcmd->name != "dumpprivkey" ) { throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); } } From 84f79558d5d7b9a336eb7401b17ec4488ee1026e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 19 May 2021 21:32:36 -0400 Subject: [PATCH 05/44] Desprout --- src/wallet/wallet.cpp | 6 ------ src/wallet/wallet.h | 4 ---- 2 files changed, 10 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b72e96386..f6d2d7f57 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2385,12 +2385,6 @@ bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb) return pwalletdb->WriteTx(GetHash(), *this); } -void CWallet::WitnessNoteCommitment(std::vector commitments, - std::vector>& witnesses, - uint256 &final_anchor) -{ -} - /** * Reorder the transactions based on block hieght and block index. * Transactions can get out of order when they are deleted and subsequently diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index d78834727..965ab5b22 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1122,10 +1122,6 @@ public: void SyncTransaction(const CTransaction& tx, const CBlock* pblock); void RescanWallet(); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate); - void WitnessNoteCommitment( - std::vector commitments, - std::vector>& witnesses, - uint256 &final_anchor); void ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos); void UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder); void DeleteTransactions(std::vector &removeTxs); From d3f12a6b7f437652bb53b75c10d84d87dbe03986 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 14 Jun 2021 21:05:20 -0400 Subject: [PATCH 06/44] desprout --- src/main.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8887292d4..2d352d12d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4429,13 +4429,6 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl // pool. So we invert the sign here. saplingValue += -tx.valueBalance; - /* - for (auto js : tx.vjoinsplit) { - sproutValue += js.vpub_old; - sproutValue -= js.vpub_new; - } - */ - // Ignore following stats unless -zindex enabled if (!fZindex) continue; From 8c25b745b3eb1a70ed965d9db97b9d103b1fa29d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 15 Jun 2021 00:47:56 -0400 Subject: [PATCH 07/44] Start to persist zindex stats to disk --- src/main.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.h | 10 ++++++ 2 files changed, 102 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index 2d352d12d..16389256b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -572,6 +572,96 @@ namespace { } // anon namespace +// CZindexDB +CZindexDB::CZindexDB() +{ + pathAddr = GetDataDir() / "zindex.dat"; +} + +bool CZindexDB::Read(CZindexStats& zstats) +{ + // open input file, and associate with CAutoFile + FILE *file = fopen(pathAddr.string().c_str(), "rb"); + CAutoFile filein(file, SER_DISK, CLIENT_VERSION); + if (filein.IsNull()) + return error("%s: Failed to open file %s", __func__, pathAddr.string()); + + // use file size to size memory buffer + int fileSize = boost::filesystem::file_size(pathAddr); + int dataSize = fileSize - sizeof(uint256); + // Don't try to resize to a negative number if file is small + if (dataSize < 0) + dataSize = 0; + vector vchData; + vchData.resize(dataSize); + uint256 hashIn; + + // read data and checksum from file + try { + filein.read((char *)&vchData[0], dataSize); + filein >> hashIn; + } + catch (const std::exception& e) { + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + } + filein.fclose(); + + CDataStream ssZstats(vchData, SER_DISK, CLIENT_VERSION); + + // verify stored checksum matches input data + uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); + if (hashIn != hashTmp) + return error("%s: Checksum mismatch, data corrupted", __func__); + + unsigned char pchMsgTmp[4]; + try { + // de-serialize file header (network specific magic number) and .. + ssZstats >> FLATDATA(pchMsgTmp); + + // ... verify the network matches ours + if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) + return error("%s: Invalid network magic number", __func__); + + // de-serialize address data into one CAddrMan object + ssZstats >> addr; + } + catch (const std::exception& e) { + return error("%s: Deserialize or I/O error - %s", __func__, e.what()); + } + + return true; +} + +bool CZindexDB::Write(const CZindexStats& zstats) +{ + // Generate random temporary filename + unsigned short randv = 0; + GetRandBytes((unsigned char*)&randv, sizeof(randv)); + std::string tmpfn = strprintf("zindex.dat.%04x", randv); + + // serialize zstats, checksum data up to that point, then append checksum + CDataStream ssZstats(SER_DISK, CLIENT_VERSION); + ssZstats << FLATDATA(Params().MessageStart()); + ssZstats << zstats; + uint256 hash = Hash(ssZstats.begin(), ssZstats.end()); + ssZstats << hash; + + // Write and commit header, data + try { + fileout << ssPeers; + } catch (const std::exception& e) { + return error("%s: Serialize or I/O error - %s", __func__, e.what()); + } + FileCommit(fileout.Get()); + fileout.fclose(); + + // replace existing zindex.dat, if any, with new zindex.dat.XXXX + if (!RenameOver(pathTmp, pathAddr)) + return error("%s: Rename-into-place failed", __func__); + + return true; +} + bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) { LOCK(cs_main); CNodeState *state = State(nodeid); @@ -4603,6 +4693,8 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl } } + // TODO: Update zindex.dat on disk + if (fZindex) fprintf(stderr, "ht.%d, ShieldedPayments=%d, ShieldedTx=%d, ShieldedOutputs=%d, FullyShieldedTx=%d, ntz=%d\n", pindexNew->GetHeight(), nShieldedPayments, nShieldedTx, nShieldedOutputs, nFullyShieldedTx, nNotarizations ); diff --git a/src/main.h b/src/main.h index 078e48cef..9aae210ef 100644 --- a/src/main.h +++ b/src/main.h @@ -950,4 +950,14 @@ std::pair>, uint64_t> DrainRecent void SetChainNotifiedSequence(uint64_t recentlyConflictedSequence); bool ChainIsFullyNotified(); +class CZindexDB +{ +private: + boost::filesystem::path pathAddr; +public: + CZindexDB(); + bool Write(const CZindexDB& addr); + bool Read(CZindexDB& addr); +}; + #endif // HUSH_MAIN_H From 40bd639bd891a67b3c5b4f23ed6d0f69bbbf50e5 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 15 Jun 2021 21:58:18 -0400 Subject: [PATCH 08/44] Read zdb on startup and serialize every 150s and on shutdown --- src/net.cpp | 35 +++++++++++++++++++++++++++++++++-- src/net.h | 1 + 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 808df788c..1dd1cce37 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -48,6 +48,9 @@ using namespace hush; // Satoshi originally used 10 seconds(!), did they know something Peter Wuille didn't? #define DUMP_ADDRESSES_INTERVAL 300 +// This is every 2 blocks, on avg, on HUSH3 +#define DUMP_ZINDEX_INTERVAL 150 + #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 #endif @@ -1400,6 +1403,16 @@ void DumpAddresses() LogPrint("net", "Flushed %d addresses to peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart); } +void DumpZindexStats() +{ + int64_t nStart = GetTimeMillis(); + + CZindexDB zdb; + zdb.Write(zstats); + + LogPrintf("Flushed %d items to zindex.dat %dms\n", zstats.size(), GetTimeMillis() - nStart); +} + void static ProcessOneShot() { string strDest; @@ -1911,6 +1924,19 @@ void static Discover(boost::thread_group& threadGroup) void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) { + if (fZindex) { + uiInterface.InitMessage(_("Loading zindex stats...")); + int64_t nStart = GetTimeMillis(); + { + CZindexDB zdb; + if (!zdb.Read(zstats)) { + LogPrintf("Invalid or missing zindex.dat! Stats may be incorrect!!!\n"); + // TODO: move invalid files out of the way? + } + } + LogPrintf("Loaded %i items from zindex.dat %dms\n", zstats.size(), GetTimeMillis() - nStart); + } + uiInterface.InitMessage(_("Loading addresses...")); // Load addresses for peers.dat int64_t nStart = GetTimeMillis(); @@ -1919,8 +1945,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) if (!adb.Read(addrman)) LogPrintf("Invalid or missing peers.dat! This can happen when upgrading. Whatevz, recreating\n"); } - LogPrintf("Loaded %i addresses from peers.dat %dms\n", - addrman.size(), GetTimeMillis() - nStart); + LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman.size(), GetTimeMillis() - nStart); fAddressesInitialized = true; if (semOutbound == NULL) { @@ -1968,6 +1993,9 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) // Dump network addresses scheduler.scheduleEvery(&DumpAddresses, DUMP_ADDRESSES_INTERVAL); + + // Dump zindex stats + scheduler.scheduleEvery(&DumpZstats, DUMP_ZINDEX_INTERVAL); } bool StopNode() @@ -1977,6 +2005,9 @@ bool StopNode() for (int i=0; i<(MAX_OUTBOUND_CONNECTIONS + MAX_FEELER_CONNECTIONS); i++) semOutbound->post(); + // persist current zindex stats to disk before we exit + DumpZindexStats(); + if (HUSH_NSPV_FULLNODE && fAddressesInitialized) { DumpAddresses(); diff --git a/src/net.h b/src/net.h index d55d500e1..e0437421f 100644 --- a/src/net.h +++ b/src/net.h @@ -174,6 +174,7 @@ extern bool fListen; extern uint64_t nLocalServices; extern uint64_t nLocalHostNonce; extern CAddrMan addrman; +extern CZindexStats zstats; /** Maximum number of connections to simultaneously allow (aka connection slots) */ extern int nMaxConnections; From 646012c35682288f5115708c140377290b50cf93 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 15 Jun 2021 23:21:05 -0400 Subject: [PATCH 09/44] Fix incorrect comments mentioning JoinSplits --- src/chain.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/chain.h b/src/chain.h index 1d8f2a462..bb0b2897f 100644 --- a/src/chain.h +++ b/src/chain.h @@ -266,7 +266,7 @@ public: int64_t 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 + //! A shielded transaction is defined as a transaction that contains at least 1 ShieldedInput or ShieldedOutput //! shielding/de-shielding and other complex transaction possibilties including multiple taddrs/zaddrs as //! inputs and outputs. int64_t nShieldedTx; @@ -278,7 +278,7 @@ public: int64_t nShieldedSpends; //! (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 + //! as a transaction containing 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 nFullyShieldedTx; @@ -295,7 +295,7 @@ public: int64_t nFullyShieldedPayments; //! (memory only) Number of deshielding transactions. A deshielding transaction is defined - //! as a transaction containing JoinSplits and at least one transparent output. + //! as a transaction containing ShieldedInputs and at least one transparent output. int64_t nDeshieldingTx; //! (memory only) Number of deshielding payments. A deshielding payment is defined @@ -303,7 +303,7 @@ public: int64_t nDeshieldingPayments; //! (memory only) Number of shielding transactions. A shielding transaction is defined - //! as a transaction containing JoinSplits and at least one transparent input + //! as a transaction containing ShieldedOutputs and at least one transparent input // i.e. t->z or t->(z,t) or z->(z,z,t) int64_t nShieldingTx; @@ -322,7 +322,7 @@ public: 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 + //! A shielded transaction is defined as a transaction that contains at least 1 ShieldedInput or ShieldedOutput //! shielding/de-shielding and other complex transaction possibilties including multiple taddrs/zaddrs as //! inputs and outputs. int64_t nChainShieldedTx; @@ -334,7 +334,7 @@ public: int64_t nChainShieldedSpends; //! (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 + //! as a transaction containing 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; @@ -351,7 +351,7 @@ public: 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. + //! as a transaction containing ShieldedInputs and at least one transparent output. int64_t nChainDeshieldingTx; //! (memory only) Number of deshielding payments. A deshielding payment is defined @@ -359,7 +359,7 @@ public: 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 + //! as a transaction containing ShieldedOutputs and at least one transparent input // i.e. t->z or t->(z,t) or z->(z,z,t) int64_t nChainShieldingTx; From 231850740ea09142c193c8df82a21a0a7ba60258 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 16 Jun 2021 11:07:20 -0400 Subject: [PATCH 10/44] CZindexStats --- src/main.cpp | 20 ++++++---- src/main.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++- src/net.cpp | 7 ++-- 3 files changed, 119 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 16389256b..77d321251 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -609,9 +609,9 @@ bool CZindexDB::Read(CZindexStats& zstats) CDataStream ssZstats(vchData, SER_DISK, CLIENT_VERSION); // verify stored checksum matches input data - uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); + uint256 hashTmp = Hash(ssZstats.begin(), ssZstats.end()); if (hashIn != hashTmp) - return error("%s: Checksum mismatch, data corrupted", __func__); + return error("%s: zstats Checksum mismatch, data corrupted", __func__); unsigned char pchMsgTmp[4]; try { @@ -622,10 +622,9 @@ bool CZindexDB::Read(CZindexStats& zstats) if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) return error("%s: Invalid network magic number", __func__); - // de-serialize address data into one CAddrMan object - ssZstats >> addr; - } - catch (const std::exception& e) { + // de-serialize data into one CZindexStats object + ssZstats >> zstats; + } catch (const std::exception& e) { return error("%s: Deserialize or I/O error - %s", __func__, e.what()); } @@ -646,9 +645,16 @@ bool CZindexDB::Write(const CZindexStats& zstats) uint256 hash = Hash(ssZstats.begin(), ssZstats.end()); ssZstats << hash; + // open temp output file, and associate with CAutoFile + boost::filesystem::path pathTmp = GetDataDir() / tmpfn; + FILE *file = fopen(pathTmp.string().c_str(), "wb"); + CAutoFile fileout(file, SER_DISK, CLIENT_VERSION); + if (fileout.IsNull()) + return error("%s: Failed to open file %s", __func__, pathTmp.string()); + // Write and commit header, data try { - fileout << ssPeers; + fileout << ssZstats; } catch (const std::exception& e) { return error("%s: Serialize or I/O error - %s", __func__, e.what()); } diff --git a/src/main.h b/src/main.h index 9aae210ef..676a069cd 100644 --- a/src/main.h +++ b/src/main.h @@ -950,14 +950,114 @@ std::pair>, uint64_t> DrainRecent void SetChainNotifiedSequence(uint64_t recentlyConflictedSequence); bool ChainIsFullyNotified(); +class CZindexStats +{ +//private: +public: + int64_t nHeight; + int64_t nChainTx; + int64_t nChainNotarizations; + int64_t nChainPayments; + int64_t nChainShieldedTx; + int64_t nChainShieldedOutputs; + int64_t nChainShieldedSpends; + int64_t nChainFullyShieldedTx; + int64_t nChainShieldingPayments; + int64_t nChainShieldedPayments; + int64_t nChainFullyShieldedPayments; + int64_t nChainDeshieldingTx; + int64_t nChainDeshieldingPayments; + int64_t nChainShieldingTx; + + size_t Height() const + { + return nHeight; + } + + void Clear() + { + LOCK(cs_main); + nChainTx=0; + nChainNotarizations=0; + nChainPayments=0; + nChainShieldedTx=0; + nChainShieldedOutputs=0; + nChainShieldedSpends=0; + nChainFullyShieldedTx=0; + nChainShieldingPayments=0; + nChainShieldedPayments=0; + nChainFullyShieldedPayments=0; + nChainDeshieldingTx=0; + nChainDeshieldingPayments=0; + nChainShieldingTx=0; + } + + CZindexStats() + { + Clear(); + } + + ~CZindexStats() + { + } + + template void Serialize(Stream &s) const + { + LOCK(cs_main); + + // So we can detect a new version and force a rescan + unsigned char nVersion = 1; + s << nVersion; + s << nHeight; + s << nChainTx; + s << nChainNotarizations; + s << nChainPayments; + s << nChainShieldedTx; + s << nChainShieldedOutputs; + s << nChainShieldedSpends; + s << nChainFullyShieldedTx; + s << nChainShieldingPayments; + s << nChainShieldedPayments; + s << nChainFullyShieldedPayments; + s << nChainDeshieldingTx; + s << nChainDeshieldingPayments; + s << nChainShieldingTx; + } + + template void Unserialize(Stream& s) + { + LOCK(cs_main); + + Clear(); + unsigned char nVersion; + s >> nVersion; + s >> nHeight; + s >> nChainTx; + s >> nChainNotarizations; + s >> nChainPayments; + s >> nChainShieldedTx; + s >> nChainShieldedOutputs; + s >> nChainShieldedSpends; + s >> nChainFullyShieldedTx; + s >> nChainShieldingPayments; + s >> nChainShieldedPayments; + s >> nChainFullyShieldedPayments; + s >> nChainDeshieldingTx; + s >> nChainDeshieldingPayments; + s >> nChainShieldingTx; + } +}; + +// Wrapper for zindex.dat stats class CZindexDB { private: boost::filesystem::path pathAddr; public: CZindexDB(); - bool Write(const CZindexDB& addr); - bool Read(CZindexDB& addr); + bool Write(const CZindexStats& zstats); + bool Read(CZindexStats& zstats); }; + #endif // HUSH_MAIN_H diff --git a/src/net.cpp b/src/net.cpp index 1dd1cce37..46e6dac90 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -106,6 +106,7 @@ static CNode* pnodeLocalHost = NULL; uint64_t nLocalHostNonce = 0; static std::vector vhListenSocket; CAddrMan addrman; +CZindexStats zstats; int nMaxConnections = DEFAULT_MAX_PEER_CONNECTIONS; bool fAddressesInitialized = false; std::string strSubVersion; @@ -1410,7 +1411,7 @@ void DumpZindexStats() CZindexDB zdb; zdb.Write(zstats); - LogPrintf("Flushed %d items to zindex.dat %dms\n", zstats.size(), GetTimeMillis() - nStart); + LogPrintf("Flushed stats at height %li to zindex.dat %dms\n", zstats.Height(), GetTimeMillis() - nStart); } void static ProcessOneShot() @@ -1934,7 +1935,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) // TODO: move invalid files out of the way? } } - LogPrintf("Loaded %i items from zindex.dat %dms\n", zstats.size(), GetTimeMillis() - nStart); + LogPrintf("Loaded stats at height %li from zindex.dat %dms\n", zstats.Height(), GetTimeMillis() - nStart); } uiInterface.InitMessage(_("Loading addresses...")); @@ -1995,7 +1996,7 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) scheduler.scheduleEvery(&DumpAddresses, DUMP_ADDRESSES_INTERVAL); // Dump zindex stats - scheduler.scheduleEvery(&DumpZstats, DUMP_ZINDEX_INTERVAL); + scheduler.scheduleEvery(&DumpZindexStats, DUMP_ZINDEX_INTERVAL); } bool StopNode() From 666054bec5c417ab6dd554d37c0a355bcf251a6a Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 16 Jun 2021 12:38:12 -0400 Subject: [PATCH 11/44] Make compiler happy and start updating zstats in-memory data --- src/main.cpp | 6 +++++- src/net.cpp | 1 - src/net.h | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 77d321251..f3892031d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -76,6 +76,7 @@ using namespace std; CCriticalSection cs_main; extern uint8_t NOTARY_PUBKEY33[33]; extern int32_t HUSH_LOADINGBLOCKS,HUSH_LONGESTCHAIN,HUSH_INSYNC,HUSH_CONNECTING,HUSH_EXTRASATOSHI; +extern CZindexStats zstats; int32_t HUSH_NEWBLOCKS; int32_t hush_block2pubkey33(uint8_t *pubkey33,CBlock *block); bool Getscriptaddress(char *destaddr,const CScript &scriptPubKey); @@ -4661,6 +4662,10 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl 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; + + // Update in-memory structure that gets serialized to zindex.dat + zstats.nHeight = pindex->GetHeight(); + zstats.nChainShieldedSpends = pindex->nChainShieldedSpends; } if (pindex->pprev) { @@ -4699,7 +4704,6 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl } } - // TODO: Update zindex.dat on disk if (fZindex) fprintf(stderr, "ht.%d, ShieldedPayments=%d, ShieldedTx=%d, ShieldedOutputs=%d, FullyShieldedTx=%d, ntz=%d\n", diff --git a/src/net.cpp b/src/net.cpp index 46e6dac90..16a397c09 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -95,7 +95,6 @@ namespace { // Global state variables extern uint16_t ASSETCHAINS_P2PPORT; extern char SMART_CHAIN_SYMBOL[65]; - bool fDiscover = true; bool fListen = true; uint64_t nLocalServices = NODE_NETWORK | NODE_NSPV; diff --git a/src/net.h b/src/net.h index e0437421f..d55d500e1 100644 --- a/src/net.h +++ b/src/net.h @@ -174,7 +174,6 @@ extern bool fListen; extern uint64_t nLocalServices; extern uint64_t nLocalHostNonce; extern CAddrMan addrman; -extern CZindexStats zstats; /** Maximum number of connections to simultaneously allow (aka connection slots) */ extern int nMaxConnections; From fe1b7f34b907e825fe279ae018967fdb8c7a3302 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Wed, 16 Jun 2021 13:29:07 -0400 Subject: [PATCH 12/44] Update in-memory zstats --- src/main.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index f3892031d..f1624d7a4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4664,8 +4664,21 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl pindex->nChainDeshieldingPayments = (pindex->pprev ? pindex->pprev->nChainDeshieldingPayments : 0) + pindex->nDeshieldingPayments; // Update in-memory structure that gets serialized to zindex.dat - zstats.nHeight = pindex->GetHeight(); - zstats.nChainShieldedSpends = pindex->nChainShieldedSpends; + zstats.nHeight = pindex->GetHeight(); + zstats.nChainNotarizations = pindex->nChainNotarizations ; + zstats.nChainShieldedTx = pindex->nChainShieldedTx ; + zstats.nChainShieldedOutputs = pindex->nChainShieldedOutputs ; + zstats.nChainShieldedSpends = pindex->nChainShieldedSpends ; + zstats.nChainFullyShieldedTx = pindex->nChainFullyShieldedTx ; + zstats.nChainShieldingTx = pindex->nChainShieldingTx ; + zstats.nChainDeshieldingTx = pindex->nChainDeshieldingTx ; + zstats.nChainPayments = pindex->nChainPayments ; + zstats.nChainShieldedPayments = pindex->nChainShieldedPayments ; + zstats.nChainFullyShieldedPayments = pindex->nChainFullyShieldedPayments ; + zstats.nChainShieldingPayments = pindex->nChainShieldingPayments ; + zstats.nChainDeshieldingPayments = pindex->nChainDeshieldingPayments ; + fprintf(stderr,"%s: setting zstats with zspends=%li, zouts=%li, anonset=%li\n", __FUNCTION__, zstats.nChainShieldedOutputs, zstats.nChainShieldedSpends, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends); + } if (pindex->pprev) { From 20779308d82d595b6ab20c92600b7f48548329ac Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 17 Jun 2021 16:26:24 -0400 Subject: [PATCH 13/44] Dump zindex.dat on first startup, if it does not exist --- src/net.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 16a397c09..51bc90f19 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1922,6 +1922,7 @@ void static Discover(boost::thread_group& threadGroup) #endif } +//extern CWallet pwalletMain; void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) { if (fZindex) { @@ -1930,11 +1931,26 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) { CZindexDB zdb; if (!zdb.Read(zstats)) { - LogPrintf("Invalid or missing zindex.dat! Stats may be incorrect!!!\n"); - // TODO: move invalid files out of the way? + // The first time nodes use zindex.dat code, no file will be found + // TODO: rescan if invalid only + LogPrintf("Invalid or missing zindex.dat! Generating new...\n"); + + //bool update = true; + //pwalletMain->ScanForWalletTransactions(chainActive.Genesis(),update); + + // We assume this is the first startup with zindex.dat code, and serialize current data to disk. + DumpZindexStats(); + + // Now read-in the stats we just wrote to disk to memory + if(!zdb.Read(zstats)) { + LogPrintf("Invalid or missing zindex.dat! Stats may be corrupt\n"); + } else { + LogPrintf("Loaded stats at height %li from zindex.dat %dms\n", zstats.Height(), GetTimeMillis() - nStart); + } + } else { + LogPrintf("Loaded stats at height %li from zindex.dat %dms\n", zstats.Height(), GetTimeMillis() - nStart); } } - LogPrintf("Loaded stats at height %li from zindex.dat %dms\n", zstats.Height(), GetTimeMillis() - nStart); } uiInterface.InitMessage(_("Loading addresses...")); From b03ed9d9d2662386e4b12f35e32cac47c419316e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 17 Jun 2021 16:47:04 -0400 Subject: [PATCH 14/44] If chain stats are zero, load them from zindex.dat data --- src/main.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index f1624d7a4..953a2c1d3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4650,6 +4650,36 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl if (fZdebug) { //fprintf(stderr,"%s: setting blockchain zstats with zspends=%d, zouts=%d\n", __FUNCTION__, nShieldedSpendsInBlock, nShieldedOutputsInBlock ); } + if (pindex->pprev) { + // If chain stats are zero (such as after restart), load data from zindex.dat + if (pindex->pprev->nChainNotarizations == 0) + pindex->pprev->nChainNotarizations = zstats.nChainNotarizations; + if (pindex->pprev->nChainShieldedTx == 0) + pindex->pprev->nChainShieldedTx = zstats.nChainShieldedTx; + if (pindex->pprev->nChainShieldedOutputs == 0) + pindex->pprev->nChainShieldedOutputs = zstats.nChainShieldedOutputs; + if (pindex->pprev->nChainShieldedSpends == 0) { + pindex->pprev->nChainShieldedSpends = zstats.nChainShieldedSpends; + fprintf(stderr, "%s: loaded anonset=%li from disk\n", __func__, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends); + } + if (pindex->pprev->nChainFullyShieldedTx == 0) + pindex->pprev->nChainFullyShieldedTx = zstats.nChainFullyShieldedTx; + if (pindex->pprev->nChainShieldingTx == 0) + pindex->pprev->nChainShieldingTx = zstats.nChainShieldingTx; + if (pindex->pprev->nChainDeshieldingTx == 0) + pindex->pprev->nChainDeshieldingTx = zstats.nChainDeshieldingTx; + if (pindex->pprev->nChainPayments == 0) + pindex->pprev->nChainPayments = zstats.nChainPayments; + if (pindex->pprev->nChainShieldedPayments == 0) + pindex->pprev->nChainShieldedPayments = zstats.nChainShieldedPayments; + if (pindex->pprev->nChainFullyShieldedPayments == 0) + pindex->pprev->nChainFullyShieldedPayments = zstats.nChainFullyShieldedPayments; + if (pindex->pprev->nChainShieldingPayments == 0) + pindex->pprev->nChainShieldingPayments = zstats.nChainShieldingPayments; + if (pindex->pprev->nChainDeshieldingPayments == 0) + pindex->pprev->nChainDeshieldingPayments = zstats.nChainDeshieldingPayments; + } + pindex->nChainNotarizations = (pindex->pprev ? pindex->pprev->nChainNotarizations : 0) + pindex->nNotarizations; pindex->nChainShieldedTx = (pindex->pprev ? pindex->pprev->nChainShieldedTx : 0) + pindex->nShieldedTx; pindex->nChainShieldedOutputs = (pindex->pprev ? pindex->pprev->nChainShieldedOutputs : 0) + pindex->nShieldedOutputs; From 21cca9ec2993223260b8952266cfa7a3e0702925 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 18 Jun 2021 11:41:47 -0400 Subject: [PATCH 15/44] Only dump zindex.dat if -zindex is enabled --- src/net.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 51bc90f19..218f766d3 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2010,8 +2010,10 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) // Dump network addresses scheduler.scheduleEvery(&DumpAddresses, DUMP_ADDRESSES_INTERVAL); - // Dump zindex stats - scheduler.scheduleEvery(&DumpZindexStats, DUMP_ZINDEX_INTERVAL); + // Dump zindex stats if -zindex is enabled + if (fZindex) { + scheduler.scheduleEvery(&DumpZindexStats, DUMP_ZINDEX_INTERVAL); + } } bool StopNode() From 8d9d2322abffe97f86d45994fdb65da4817a2b1c Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 18 Jun 2021 11:57:39 -0400 Subject: [PATCH 16/44] Log stats height vs node local height --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 953a2c1d3..76300e1a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4660,7 +4660,8 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl pindex->pprev->nChainShieldedOutputs = zstats.nChainShieldedOutputs; if (pindex->pprev->nChainShieldedSpends == 0) { pindex->pprev->nChainShieldedSpends = zstats.nChainShieldedSpends; - fprintf(stderr, "%s: loaded anonset=%li from disk\n", __func__, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends); + // TODO: if zstats.nHeight != chainActive.Height() the stats will be off + fprintf(stderr, "%s: loaded anonset=%li at stats height=%li vs local height=%d from disk\n", __func__, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends, zstats.nHeight, chainActive.Height() ); } if (pindex->pprev->nChainFullyShieldedTx == 0) pindex->pprev->nChainFullyShieldedTx = zstats.nChainFullyShieldedTx; From e20315ef213606b12674c361be61c71841f79410 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 18 Jun 2021 18:31:20 +0000 Subject: [PATCH 17/44] checkpoints --- src/chainparams.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 9cd9bb7f9..c6dd5f1f9 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -783,11 +783,79 @@ void *chainparams_commandline() { (492000, uint256S("0x00000013bbbff98ddab19a3178a0088a20628791e94963e5d1ea635015dfa9c6")) (493000, uint256S("0x00000001ed829c061ba14f6953e79d99577079adf5526f1e43e6dc9d9f9571bf")) (494000, uint256S("0x00000018dfeced2d1584a1003fefa4349810239bade096e53b4fa6bbc38a1685")) - (495000, uint256S("0x0000001816af55724cd49c0bfe02c9eac29b4a73db2b7d868b958218a03e6c94")) - (496000, uint256S("0x000000007e2019c5246db5a75122c6826822fa154d68a51eee2ff23f54ec668e")), - (int64_t) 1618760194, // time of last checkpointed block - (int64_t) 842496, // total txs - (double) 1812 // txs in the last day before block 496013 + (495000, uint256S("0x0000001816af55724cd49c0bfe02c9eac29b4a73db2b7d868b958218a03e6c94")) + (496000, uint256S("0x000000007e2019c5246db5a75122c6826822fa154d68a51eee2ff23f54ec668e")) + (497000, uint256S("0x0000000aa5803c0825cfa1a34227d0ecb80be191674365a372f71611eacdc742")) + (498000, uint256S("0x000000166385022d4b4ade0921a5f6c7d4aec56257cd679f7c441aeb0552b28c")) + (499000, uint256S("0x0000002ce5e48efb664e936c9551b2781c742416e519d3a023d087036519507b")) + (500000, uint256S("0x0000000cdfe9389bde0e9f1d649dd2f19ee69d765b00907aa681c3cdaad0bdb6")) + (501000, uint256S("0x00000028736fd4ce6995a46d217c0022d2882165b5f716e94f255877c73f474a")) + (502000, uint256S("0x000000459520215ade21db91a83ad47a806320ba3e290d686149bcf5672e132a")) + (503000, uint256S("0x000000086aee5827d0254e1176a4dfd5c8a7958ee1f61458bdb1eb4d6ffbc131")) + (504000, uint256S("0x000000474906b6ad537fe14eca1316c7be23f181bc554a2244c97634a6d361a7")) + (505000, uint256S("0x00000035db569efc139988b7d506529bb482284bf2dfc40060159b321883974d")) + (506000, uint256S("0x0000000c55ddd54e1f0aa6a59abe774f0e14501743c2594184772031f5bf51fd")) + (507000, uint256S("0x000000061ca0ea34d5d3ddd5d8ceb0dcf9a0720483efd98155c0aa3774387e60")) + (508000, uint256S("0x00000004bd6cdfbbee3945b897c4d6b6f49199d788151fe5536417d31d2f36ab")) + (509000, uint256S("0x0000000b73f9dd08528827a8224decf6635462d2adabac9301e5c17b7a24a5f4")) + (510000, uint256S("0x00000004c41a5b61302564abc741195c915fdf9edd12669f93ac5d4443613664")) + (511000, uint256S("0x000000094319bb7199e5697e458520e95639dcec5180d4442e1470f48feaf125")) + (512000, uint256S("0x00000014516f2d52467edd913c52e1742ca8a767debd9294bbbf8f39bdbae506")) + (513000, uint256S("0x000000177739b5379d196b74faeaabf35dbb9d3f6f9e172f659f68b3288a71c3")) + (514000, uint256S("0x0000000940533509d21f249ab0b0144923e65050a24dbf53863c9c07fd21fd6b")) + (515000, uint256S("0x000000007d256fc4cbfff1c05f83550b8dfdf093b060a98fafac6a090e349bc1")) + (516000, uint256S("0x000000029ee7abc14842e22b4f3e7e3c640c55fa2a898773c83ff34ceb2a5482")) + (517000, uint256S("0x00000019ca7705b4a8b35ae1aa4071401ed1de7449306ef8a34716637f43c2f1")) + (518000, uint256S("0x00000013f4aa06fca6c2a57e80c3950d0e7613f3bcba0b52887d4c7579e5b20a")) + (519000, uint256S("0x0000000b7d1e4efbbb38c91e838a50876be93a6549fdaeb534ec1d8657117e69")) + (520000, uint256S("0x00000000c2fb98b56bf9c549406710b57308081663230a477c7b5983720a456a")) + (521000, uint256S("0x0000000d48660709c9fd60f01b71260e0e6ba3875cdb109b7b037ec6b80f3098")) + (522000, uint256S("0x00000019d0ad6bdebc9d39a5b9a6ae4d844b45bbfcdd97885841a1d8033c956f")) + (523000, uint256S("0x000000121da004ec14c89b67151439765a19aadbdf4d4feca701cce7c3820efb")) + (524000, uint256S("0x00000003d3445c4cb6e980751cd8119679d572f57bbaa3b9c9114e397841827e")) + (525000, uint256S("0x0000000b2a079f083c86f9ab8b0f73dc511c20f6aa44d7735f29409df966f026")) + (526000, uint256S("0x00000004d3ae427a98336ee4bc5e60f00ebd4c88f9ffdd18003f17535465888a")) + (527000, uint256S("0x000000057e5cb13f42332f59b6c2d6f333369b8e4d9bdf6fa9bb441e2ddb5c51")) + (528000, uint256S("0x000000045f51825c19aab9d1d620d7073c2114ccf3e40f63d66c729c71c2bc05")) + (529000, uint256S("0x000000116ac2795cdbde2d3af6d804d9dbf445d2ed12d7cf13c155540f10c119")) + (530000, uint256S("0x0000000be4932b469923d826991810109f2c2ca50d5fa0133c765b5ab96bf315")) + (531000, uint256S("0x0000000a7fdd8ce073da5d95fcbefba5d0366c9b834cac914889108094d0cd18")) + (532000, uint256S("0x0000000600d2ea28f32220c054e2ae66ec8471a2f755ef219a0c81e4a4296135")) + (533000, uint256S("0x0000000a5f4a460970f6dcd3a271315f936648c854c1a7bb251dbc7996f90e92")) + (534000, uint256S("0x00000009b5d0615eb98f06820cc6d66af542b8bbde0cabe5b54b6e7625e77803")) + (535000, uint256S("0x0000000ac06f5d79b927f2dfb54eecd72f9ada28fa59092f5c3c83627b281605")) + (536000, uint256S("0x000000037a51adb2cccf29b9c164386c8418959db16606b70a1389fb8755829f")) + (537000, uint256S("0x0000000a129157792e233e233f85693625abb14be90362ff727ab97e8d5ec340")) + (538000, uint256S("0x00000015e13085045c090a51e9c1114749fa7b465009f2ad70ff278d9ae05b5c")) + (539000, uint256S("0x00000001953384069e477f7e1839dc0498cbeb951adb32bcbf3b96ef487fce4a")) + (540000, uint256S("0x0000000281246b5d2e845aa711b6af76c8cc0d1f39ba25fe414f83bbe47544bb")) + (541000, uint256S("0x0000000f27b777a942d6317438836258c4e34bd3761736a2b32cc2b7c8305d71")) + (542000, uint256S("0x00000005d4667fb45a862d91ba843acbaee033915bf75536c67aeca1a2a3a5ff")) + (543000, uint256S("0x0000000509b08619049b1aec8e715d971b8dbc2175acf7874a37b9ce13dfb137")) + (544000, uint256S("0x0000000582563d79bf72a925ae3bc5c6f0eacbdb317c92fa89eb56d570427fd7")) + (545000, uint256S("0x0000000ff9df3d3a00d682f069819acbc5697b42da69a78f6e07486ac68f0e49")) + (546000, uint256S("0x00000004653460c603fa7a70292a85e286272b587f0b9cea7e73b765e8b0ef7b")) + (547000, uint256S("0x000000074c5f411190c5bf788a37a00506935015df4872cc5471416abadb757d")) + (548000, uint256S("0x00000005444a4ecd1eea940ad5395f2f7839967ee5b01be4a9b68755de4395ac")) + (549000, uint256S("0x0000000216eafee0e40374b8e8db63118cb4e3adc3159068bdafff1f0e0d9deb")) + (550000, uint256S("0x0000000056b84bc88604b9df668b60c020a6926b2dfdcd09955e5d8d3e7a5ca7")) + (551000, uint256S("0x0000000adaaeb79c5c6c49038d7206f88d5b4ecaaf21aaca09b5a7d548f76b25")) + (552000, uint256S("0x00000004185669b566e62cbebc9c50930c8ae0d5c42f23280262a7f55b726553")) + (553000, uint256S("0x00000010112434cdb0203a053e0c22ef16b9d39b8feed2328d7ff97013b216be")) + (554000, uint256S("0x00000006dacee96c0f48fc7250c71cc1e746befa84af8cd2ed0499d8d24cc6cb")) + (555000, uint256S("0x00000001b3b2c149029d5a2e7cedb0683c97692a52cbc91bb532cb78bbcadcc0")) + (556000, uint256S("0x0000000397bdd61939cc3d2c39360c5e3713ef9dd82b8cedac17075b8e177304")) + (557000, uint256S("0x0000000414bb81b82a2e71608086ac585dba19ca249067c9e967d6f44a1d3163")) + (558000, uint256S("0x00000003516d27423b1b5b60eab97d425e7be3f08f14bafd935666b1e955608e")) + (559000, uint256S("0x00000005c44ef4543da5924e65f0fd2d2c8fe926b2f3995b83ccfd1463b443d7")) + (560000, uint256S("0x00000002eb33454ba48e61a50351686115c47cb59b8fb0496432ad58e0484acf")) + (561000, uint256S("0x00000004172d5940c07ec6d493e410fbab8a05dc73e350505e1540d7336eb353")) + (562000, uint256S("0x00000000d9caaf66ad7782046886d3bfdf966c0a015dbae64042cd0c35e516e4")) + (563000, uint256S("0x000000000d953e53c65145bfb41ba544a9ce9e5432c9ed8eabd39873dfcb8ab0")) + (564000, uint256S("0x0000000d49258678c42bc2ea6f9e5d1206c578da8dc564d1a6114ce68bf77817")), + (int64_t) 1623979514, // time of last checkpointed block + (int64_t) 922687, // total txs + (double) 1219 // txs in the last day before block 564690 }; } else { From 0d24faa39ac04b9774eae4c6e5c04287d3ae4a34 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 18 Jun 2021 17:27:18 -0400 Subject: [PATCH 18/44] Allow getpeerinfo during rpc warmup --- src/rpc/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index bf99a5b78..e999cc423 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -831,7 +831,7 @@ UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms // few RPCs means we can see our addresses and make private key backups // while a very long wallet rescan is happening if (pcmd->name != "stop" && pcmd->name != "help" && pcmd->name != "z_listaddresses" && pcmd->name != "z_exportkey" && - pcmd->name != "listaddresses" && pcmd->name != "dumpprivkey" ) { + pcmd->name != "listaddresses" && pcmd->name != "dumpprivkey" && pcmd->name != "getpeerinfo" ) { throw JSONRPCError(RPC_IN_WARMUP, rpcWarmupStatus); } } From e6a7423029881d205f6b6c1305adc7922486c0f5 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 18 Jun 2021 19:27:06 -0400 Subject: [PATCH 19/44] Log height so we can easily see the historical value of anonset size for all block heights --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 76300e1a6..8ae274001 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4708,7 +4708,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl zstats.nChainFullyShieldedPayments = pindex->nChainFullyShieldedPayments ; zstats.nChainShieldingPayments = pindex->nChainShieldingPayments ; zstats.nChainDeshieldingPayments = pindex->nChainDeshieldingPayments ; - fprintf(stderr,"%s: setting zstats with zspends=%li, zouts=%li, anonset=%li\n", __FUNCTION__, zstats.nChainShieldedOutputs, zstats.nChainShieldedSpends, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends); + fprintf(stderr,"%s: setting zstats with height,zspends,zouts,anonset=%li,%li,%li,%li\n", __FUNCTION__, zstats.nHeight, zstats.nChainShieldedOutputs, zstats.nChainShieldedSpends, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends); } From 7a0bdd79c800efef2a88635b6ab82d5ebad97ea6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 21 Jun 2021 17:43:47 -0400 Subject: [PATCH 20/44] . --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 76300e1a6..ef57ccc7f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4708,7 +4708,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl zstats.nChainFullyShieldedPayments = pindex->nChainFullyShieldedPayments ; zstats.nChainShieldingPayments = pindex->nChainShieldingPayments ; zstats.nChainDeshieldingPayments = pindex->nChainDeshieldingPayments ; - fprintf(stderr,"%s: setting zstats with zspends=%li, zouts=%li, anonset=%li\n", __FUNCTION__, zstats.nChainShieldedOutputs, zstats.nChainShieldedSpends, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends); + fprintf(stderr,"%s: setting zstats with zouts=%li, zspends=%li, anonset=%li\n", __FUNCTION__, zstats.nChainShieldedOutputs, zstats.nChainShieldedSpends, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends); } From 6f6b5b739396513485067da139f6a3fc17f2056b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 21 Jun 2021 17:49:41 -0400 Subject: [PATCH 21/44] . --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index ef57ccc7f..cf6a4ce32 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4661,7 +4661,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl if (pindex->pprev->nChainShieldedSpends == 0) { pindex->pprev->nChainShieldedSpends = zstats.nChainShieldedSpends; // TODO: if zstats.nHeight != chainActive.Height() the stats will be off - fprintf(stderr, "%s: loaded anonset=%li at stats height=%li vs local height=%d from disk\n", __func__, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends, zstats.nHeight, chainActive.Height() ); + fprintf(stderr, "%s: loaded anonymity set of %li at stats height=%li vs local height=%d from disk\n", __func__, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends, zstats.nHeight, chainActive.Height() ); } if (pindex->pprev->nChainFullyShieldedTx == 0) pindex->pprev->nChainFullyShieldedTx = zstats.nChainFullyShieldedTx; From e1a5d909a0d058729a1cd2db63c1efa250f6b549 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 21 Jun 2021 17:59:25 -0400 Subject: [PATCH 22/44] . --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 8ae274001..1ea9c3b46 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4708,7 +4708,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl zstats.nChainFullyShieldedPayments = pindex->nChainFullyShieldedPayments ; zstats.nChainShieldingPayments = pindex->nChainShieldingPayments ; zstats.nChainDeshieldingPayments = pindex->nChainDeshieldingPayments ; - fprintf(stderr,"%s: setting zstats with height,zspends,zouts,anonset=%li,%li,%li,%li\n", __FUNCTION__, zstats.nHeight, zstats.nChainShieldedOutputs, zstats.nChainShieldedSpends, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends); + fprintf(stderr,"%s: setting zstats with height,zouts,zspends,anonset=%li,%li,%li,%li\n", __FUNCTION__, zstats.nHeight, zstats.nChainShieldedOutputs, zstats.nChainShieldedSpends, zstats.nChainShieldedOutputs - zstats.nChainShieldedSpends); } From e829822041831948543e3bbc25edeb0179aa0d55 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 26 Jun 2021 12:27:38 -0400 Subject: [PATCH 23/44] logging to help debug window stats being wrong after restart --- src/main.cpp | 4 +++- src/rpc/blockchain.cpp | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 62e4741b3..94b41fe5a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4669,8 +4669,10 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl pindex->pprev->nChainShieldingTx = zstats.nChainShieldingTx; if (pindex->pprev->nChainDeshieldingTx == 0) pindex->pprev->nChainDeshieldingTx = zstats.nChainDeshieldingTx; - if (pindex->pprev->nChainPayments == 0) + if (pindex->pprev->nChainPayments == 0) { + fprintf(stderr, "%s: setting nChainPayments=%li at height %d\n", __func__, zstats.nChainPayments, chainActive.Height() ); pindex->pprev->nChainPayments = zstats.nChainPayments; + } if (pindex->pprev->nChainShieldedPayments == 0) pindex->pprev->nChainShieldedPayments = zstats.nChainShieldedPayments; if (pindex->pprev->nChainFullyShieldedPayments == 0) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 7c38ef1eb..609f26420 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1660,10 +1660,12 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid block count: should be between 0 and the block's height - 1"); } } + LogPrintf("%s: blockcount = %d\n", __func__, blockcount); const CBlockIndex* pindexPast = pindex->GetAncestor(pindex->GetHeight() - blockcount); int nTimeDiff = pindex->GetMedianTimePast() - pindexPast->GetMedianTimePast(); int nTxDiff = pindex->nChainTx - pindexPast->nChainTx; + LogPrintf("%s: pindexPast.height = %d, pindex.height = %d\n", __func__, pindexPast->GetHeight(), pindex->GetHeight() ); UniValue ret(UniValue::VOBJ); ret.pushKV("time", (int64_t)pindex->nTime); @@ -1695,6 +1697,7 @@ UniValue getchaintxstats(const UniValue& params, bool fHelp, const CPubKey& mypk ret.pushKV("window_tx_count", nTxDiff); ret.pushKV("window_interval", nTimeDiff); int64_t nPaymentsDiff = pindex->nChainPayments - pindexPast->nChainPayments; + LogPrintf("%s: pindexPast.nChainPayments = %d, pindex.nChainPayments = %d\n", __func__, pindexPast->nChainPayments, pindex->nChainPayments ); int64_t nShieldedTxDiff = pindex->nChainShieldedTx - pindexPast->nChainShieldedTx; int64_t nShieldingTxDiff = pindex->nChainShieldingTx - pindexPast->nChainShieldingTx; int64_t nDeshieldingTxDiff = pindex->nChainDeshieldingTx - pindexPast->nChainDeshieldingTx; From 2c315965d7ddd486d76d726e02deeb3356e6bb2d Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 26 Jun 2021 13:54:57 -0400 Subject: [PATCH 24/44] Log data about clearing witness cache --- src/wallet/wallet.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f6d2d7f57..3bc3b99cd 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -908,12 +908,15 @@ int64_t CWallet::NullifierCount() void CWallet::ClearNoteWitnessCache() { LOCK(cs_wallet); + int notes = 0; for (std::pair& wtxItem : mapWallet) { for (mapSaplingNoteData_t::value_type& item : wtxItem.second.mapSaplingNoteData) { item.second.witnesses.clear(); item.second.witnessHeight = -1; + notes++; } } + LogPrintf("%s: Cleared witness data from %d wallet items and %d SaplingNotes\n", __func__, mapWallet.size(), notes); } void CWallet::DecrementNoteWitnesses(const CBlockIndex* pindex) From b7be25e2d5f4fa33d282d817263d1363bdfd5686 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 26 Jun 2021 14:42:40 -0400 Subject: [PATCH 25/44] Thanks to hellcatz for this patch --- src/main.cpp | 2 +- src/rpc/net.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 94b41fe5a..ec02f3a79 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4025,7 +4025,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock * int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1; LogPrint("bench", " - Connect postprocess: %.2fms [%.2fs]\n", (nTime6 - nTime5) * 0.001, nTimePostConnect * 0.000001); LogPrint("bench", "- Connect block: %.2fms [%.2fs]\n", (nTime6 - nTime1) * 0.001, nTimeTotal * 0.000001); - if ( HUSH_LONGESTCHAIN != 0 && (pindexNew->GetHeight() == HUSH_LONGESTCHAIN || pindexNew->GetHeight() == HUSH_LONGESTCHAIN+1) ) + if ( HUSH_LONGESTCHAIN != 0 && (pindexNew->GetHeight() >= HUSH_LONGESTCHAIN )) HUSH_INSYNC = (int32_t)pindexNew->GetHeight(); else HUSH_INSYNC = 0; //fprintf(stderr,"connect.%d insync.%d ASSETCHAINS_SAPLING.%d\n",(int32_t)pindexNew->GetHeight(),HUSH_INSYNC,ASSETCHAINS_SAPLING); diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 6ea9819a8..4533b0196 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -180,15 +180,15 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp, const CPubKey& mypk) } int32_t HUSH_LONGESTCHAIN; +static int32_t hush_longest_depth = 0; int32_t hush_longestchain() { - static int32_t depth; int32_t ht,n=0,num=0,maxheight=0,height = 0; - if ( depth < 0 ) - depth = 0; - if ( depth == 0 ) + if ( hush_longest_depth < 0 ) + hush_longest_depth = 0; + if ( hush_longest_depth == 0 ) { - depth++; + hush_longest_depth++; vector vstats; { //LOCK(cs_main); @@ -215,7 +215,7 @@ int32_t hush_longestchain() if ( ht > height ) height = ht; } - depth--; + hush_longest_depth--; if ( num > (n >> 1) ) { if ( 0 && height != HUSH_LONGESTCHAIN ) From 21333ce153c6509b6720c05c8331078a25789e97 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 26 Jun 2021 15:49:47 -0400 Subject: [PATCH 26/44] Add -rescanheight --- src/init.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 2624945bf..ab4e1c0d8 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -467,6 +467,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-opretmintxfee=", strprintf(_("Minimum fee (in %s/kB) to allow for OP_RETURN transactions (default: %s)"), CURRENCY_UNIT, 400000 )); strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); + strUsage += HelpMessageOpt("-rescanheight", _("Rescan from specified height when rescan=1 on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); @@ -2074,6 +2075,14 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) { pwalletMain->ClearNoteWitnessCache(); pindexRescan = chainActive.Genesis(); + int rescanHeight = GetArg("-rescanheight", 0); + if (rescanHeight > 0) { + if (rescanHeight > chainActive.Tip()->GetHeight()) { + pindexRescan = chainActive.Tip(); + } else { + pindexRescan = chainActive[rescanHeight]; + } + } } else { CWalletDB walletdb(strWalletFile); CBlockLocator locator; From 172fefeb7baddcb11160aa9d6ffa22bfbdf62324 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sat, 26 Jun 2021 20:37:57 -0400 Subject: [PATCH 27/44] Sometimes you need to say plz --- src/net.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index 218f766d3..d7833b4a0 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -51,6 +51,8 @@ using namespace hush; // This is every 2 blocks, on avg, on HUSH3 #define DUMP_ZINDEX_INTERVAL 150 +#define CHECK_PLZ_STOP_INTERVAL 120 + #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 #endif @@ -92,6 +94,7 @@ namespace { }; } + // Global state variables extern uint16_t ASSETCHAINS_P2PPORT; extern char SMART_CHAIN_SYMBOL[65]; @@ -111,6 +114,8 @@ bool fAddressesInitialized = false; std::string strSubVersion; TLSManager tlsmanager = TLSManager(); +extern void StartShutdown(); + vector vNodes; CCriticalSection cs_vNodes; map mapRelay; @@ -1413,6 +1418,18 @@ void DumpZindexStats() LogPrintf("Flushed stats at height %li to zindex.dat %dms\n", zstats.Height(), GetTimeMillis() - nStart); } +void CheckIfWeShouldStop() +{ + // If the RPC interface is "stuck", such as filling up with deadlocks + // and cannot process any more requests, the only option was to kill the full node. + // This is a disk-based method where a node can realize it should stop, and which + // can help avoid extremely long rescans + if(boost::filesystem::exists(GetDataDir() / "plz_stop")) { + LogPrintf("%s: Found plz_stop file, shutting down...\n", __func__); + StartShutdown(); + } +} + void static ProcessOneShot() { string strDest; @@ -1925,6 +1942,9 @@ void static Discover(boost::thread_group& threadGroup) //extern CWallet pwalletMain; void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) { + + CheckIfWeShouldStop(); + if (fZindex) { uiInterface.InitMessage(_("Loading zindex stats...")); int64_t nStart = GetTimeMillis(); @@ -2014,6 +2034,8 @@ void StartNode(boost::thread_group& threadGroup, CScheduler& scheduler) if (fZindex) { scheduler.scheduleEvery(&DumpZindexStats, DUMP_ZINDEX_INTERVAL); } + + scheduler.scheduleEvery(&CheckIfWeShouldStop, CHECK_PLZ_STOP_INTERVAL); } bool StopNode() From b8ebbd7da55fcf230b64a41d433900a2633f0394 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 27 Jun 2021 12:52:45 -0700 Subject: [PATCH 28/44] Add -keepnotewitnesscache for advanced users --- src/init.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index ab4e1c0d8..5e7a644f4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -2073,9 +2073,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) CBlockIndex *pindexRescan = chainActive.Tip(); if (clearWitnessCaches || GetBoolArg("-rescan", false)) { - pwalletMain->ClearNoteWitnessCache(); - pindexRescan = chainActive.Genesis(); int rescanHeight = GetArg("-rescanheight", 0); + // Must be used with -rescanheight + if( GetBoolArg("-keepnotewitnesscache", false) && rescanHeight > 0 ) { + LogPrintf("%s: keeping NoteWitnessCache with rescan height=%d\n", __func__, rescanHeight); + } else { + pwalletMain->ClearNoteWitnessCache(); + } + + pindexRescan = chainActive.Genesis(); if (rescanHeight > 0) { if (rescanHeight > chainActive.Tip()->GetHeight()) { pindexRescan = chainActive.Tip(); From 195af2c65a350217f66e3c004e36012b3a2311f2 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 27 Jun 2021 22:19:37 -0400 Subject: [PATCH 29/44] Sietch for z_shieldcoinbase --- src/wallet/asyncrpcoperation_shieldcoinbase.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index e432ffdb0..a4d4857e0 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -46,6 +46,7 @@ using namespace libzcash; extern uint64_t ASSETCHAINS_TIMELOCKGTE; +extern string randomSietchZaddr(); AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase( TransactionBuilder builder, @@ -229,6 +230,17 @@ bool ShieldToAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) c // Send all value to the target z-addr m_op->builder_.SendChangeTo(zaddr, ovk); + // Sietchified Shielding of Coinbase Funds + // Add Sietch zouts so it's unclear which zout contains value :) + // This reduces metadata leakage of coinbase t=>z tx's + CAmount amount = 0; + auto zdust1 = DecodePaymentAddress(randomSietchZaddr()); + auto zdust2 = DecodePaymentAddress(randomSietchZaddr()); + auto sietchZout1 = boost::get(zdust1); + auto sietchZout2 = boost::get(zdust2); + m_op->builder_.AddSaplingOutput(ovk, sietchZout1, amount); + m_op->builder_.AddSaplingOutput(ovk, sietchZout2, amount); + // Build the transaction auto maybe_tx = m_op->builder_.Build(); if (!maybe_tx) { From d58396f05ec27bfdf3487edd507ef63d23bde706 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Sun, 27 Jun 2021 22:35:59 -0400 Subject: [PATCH 30/44] Shuffle zouts to prevent leaking change output position --- src/transaction_builder.cpp | 10 ++++++++++ src/transaction_builder.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/transaction_builder.cpp b/src/transaction_builder.cpp index c17051ff9..3ff6269b2 100644 --- a/src/transaction_builder.cpp +++ b/src/transaction_builder.cpp @@ -59,6 +59,13 @@ void TransactionBuilder::AddSaplingOutput( mtx.valueBalance -= value; } +// randomize the order of outputs +void TransactionBuilder::ShuffleOutputs() +{ + LogPrintf("%s: Shuffling %d zouts\n", __func__, outputs.size() ); + random_shuffle( outputs.begin(), outputs.end(), GetRandInt ); +} + void TransactionBuilder::AddTransparentInput(COutPoint utxo, CScript scriptPubKey, CAmount value, uint32_t _nSequence) { if (keystore == nullptr) { @@ -212,6 +219,9 @@ boost::optional TransactionBuilder::Build() mtx.vShieldedSpend.push_back(sdesc); } + // Prevent leaking metadata about the position of change output + ShuffleOutputs(); + // Create Sapling OutputDescriptions for (auto output : outputs) { auto cm = output.note.cm(); diff --git a/src/transaction_builder.h b/src/transaction_builder.h index dba7e7b43..89a8d6580 100644 --- a/src/transaction_builder.h +++ b/src/transaction_builder.h @@ -92,6 +92,8 @@ public: CAmount value, std::array memo = {{0}}); + void ShuffleOutputs(); + // Assumes that the value correctly corresponds to the provided UTXO. void AddTransparentInput(COutPoint utxo, CScript scriptPubKey, CAmount value, uint32_t nSequence = 0xffffffff); From df8cd1180f78ae7a8bd0512ed539e6c5f758d08a Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 28 Jun 2021 21:00:42 -0400 Subject: [PATCH 31/44] delete dead code --- src/miner.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 159682f32..9a843a52d 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -210,10 +210,6 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32 // Collect memory pool transactions into the block CAmount nFees = 0; - // we will attempt to spend any cheats we see - CTransaction cheatTx; - boost::optional cheatSpend; - uint256 cbHash; boost::this_thread::interruption_point(); // exit thread before entering locks. From 6ca35f2b0ac41004bd2e795c7c6475f2e4a00461 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 28 Jun 2021 21:17:59 -0400 Subject: [PATCH 32/44] Remove dead code --- src/miner.cpp | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 9a843a52d..165497694 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -891,29 +891,6 @@ void komodo_sendmessage(int32_t minpeers,int32_t maxpeers,const char *message,st } } -void komodo_broadcast(CBlock *pblock,int32_t limit) -{ - if (IsInitialBlockDownload()) - return; - int32_t n = 1; - //fprintf(stderr,"broadcast new block t.%u\n",(uint32_t)time(NULL)); - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - { - if ( pnode->hSocket == INVALID_SOCKET ) - continue; - if ( (rand() % n) == 0 ) - { - pnode->PushMessage("block", *pblock); - if ( n++ > limit ) - break; - } - } - } - //fprintf(stderr,"finished broadcast new block t.%u\n",(uint32_t)time(NULL)); -} - static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) #else static bool ProcessBlockFound(CBlock* pblock) @@ -968,7 +945,6 @@ static bool ProcessBlockFound(CBlock* pblock) return error("HushMiner: ProcessNewBlock, block not accepted"); TrackMinedBlock(pblock->GetHash()); - //komodo_broadcast(pblock,16); return true; } From 8e7cf04ad2cbb2c61756475f7882472ba1826d06 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 28 Jun 2021 22:34:35 -0400 Subject: [PATCH 33/44] Fix upstream KMD crash bug in getblocktemplate when disablewallet=1 Originally https://github.com/DeckerSU/komodo/commit/dc8e1695c23908a2e797a48f1e7b428070c336b7 --- src/miner.cpp | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/miner.cpp b/src/miner.cpp index 165497694..7ce7cf404 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -857,19 +857,26 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey, int32_t nHeight, scriptPubKey = CScript() << ParseHex(HexStr(pubkey)) << OP_CHECKSIG; } else { { - if (!reservekey.GetReservedKey(pubkey)) - { - return NULL; - } - scriptPubKey.resize(35); - ptr = (uint8_t *)pubkey.begin(); - scriptPubKey[0] = 33; - for (i=0; i<33; i++) { - scriptPubKey[i+1] = ptr[i]; - } - scriptPubKey[34] = OP_CHECKSIG; - } - } + // Support mining with -disablewallet and minetolocalwallet=0 + if (!GetBoolArg("-disablewallet", false)) { + // wallet enabled + if (!reservekey.GetReservedKey(pubkey)) + return NULL; + scriptPubKey.clear(); + scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG; + } else { + // wallet disabled + CTxDestination dest = DecodeDestination(GetArg("-mineraddress", "")); + if (IsValidDestination(dest)) { + // CKeyID keyID = boost::get(dest); + // scriptPubKey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; + scriptPubKey = GetScriptForDestination(dest); + } else { + return NULL; + } + } + } + } return CreateNewBlock(pubkey, scriptPubKey, gpucount, isStake); } From 2b915599ac316da16d69b37fc983a2f574efdd57 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Mon, 28 Jun 2021 23:56:16 -0400 Subject: [PATCH 34/44] Update rpc docs --- src/rpc/rawtransaction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 1914aa8df..82fcfdf97 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -646,7 +646,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp, const CPubKey& " ]\n" "2. \"outputs\" (object, required) a json object with outputs\n" " {\n" - " \"address\": x.xxx, (numeric or string, required) The key is the komodo address or script (in hex), the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n" + " \"address\": x.xxx, (numeric or string, required) The key is the HUSH address or script (in hex), the numeric value (can be string) is the " + CURRENCY_UNIT + " amount\n" " \"data\": \"hex\" (string, required) The key is \"data\", the value is hex encoded data\n" " ,...\n" " }\n" @@ -821,7 +821,7 @@ UniValue decoderawtransaction(const UniValue& params, bool fHelp, const CPubKey& " \"reqSigs\" : n, (numeric) The required sigs\n" " \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" " \"addresses\" : [ (json array of string)\n" - " \"RTZMZHDFSTFQst8XmX2dR4DaH87cEUs3gC\" (string) komodo address\n" + " \"RTZMZHDFSTFQst8XmX2dR4DaH87cEUs3gC\" (string) HUSH address\n" " ,...\n" " ]\n" " }\n" From b314fd3b4aa0d9c63095dbde19d00a0ff2698352 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 29 Jun 2021 11:32:54 -0400 Subject: [PATCH 35/44] Add -asmap and update addnodes to hushd.bat --- src/hushd.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hushd.bat b/src/hushd.bat index b2580ffaf..5f578d6b6 100644 --- a/src/hushd.bat +++ b/src/hushd.bat @@ -1,6 +1,6 @@ @call :GET_CURRENT_DIR @cd %THIS_DIR% -komodod.exe -ac_name=HUSH3 -ac_sapling=1 -ac_reward=0,1125000000,562500000 -ac_halving=129,340000,840000 -ac_end=128,340000,5422111 -ac_eras=3 -ac_blocktime=150 -ac_cc=2 -ac_ccenable=228,234,235,236,241 -ac_founders=1 -ac_supply=6178674 -ac_perc=11111111 -clientname=GoldenSandtrout -addnode=64.120.113.130 -addnode=209.58.144.205 -addnode=94.130.35.94 -addnode=188.165.212.101 -ac_cclib=hush3 -ac_script=76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac -daemon %1 %2 %3 %4 %5 %6 %7 %8 %9 +komodod.exe -ac_name=HUSH3 -ac_sapling=1 -ac_reward=0,1125000000,562500000 -ac_halving=129,340000,840000 -ac_end=128,340000,5422111 -ac_eras=3 -ac_blocktime=150 -ac_cc=2 -ac_ccenable=228,234,235,236,241 -ac_founders=1 -ac_supply=6178674 -ac_perc=11111111 -clientname=GoldenSandtrout -asmap -addnode=node1.hush.is -addnode=node2.hush.is -addnode=node3.hush.is -addnode=node4.hush.is -addnode=node5.hush.is -addnode=node6.hush.is -addnode=node7.hush.is -addnode=node8.hush.is -ac_cclib=hush3 -ac_script=76a9145eb10cf64f2bab1b457f1f25e658526155928fac88ac -daemon %1 %2 %3 %4 %5 %6 %7 %8 %9 @goto :EOF :GET_CURRENT_DIR From cc2b28a604d0972c6363fe8c40fb14e2116d9e2e Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 29 Jun 2021 11:42:34 -0400 Subject: [PATCH 36/44] hush-tx.bat for completeness --- src/hush-tx.bat | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/hush-tx.bat diff --git a/src/hush-tx.bat b/src/hush-tx.bat new file mode 100644 index 000000000..f3e24881d --- /dev/null +++ b/src/hush-tx.bat @@ -0,0 +1,14 @@ +@call :GET_CURRENT_DIR +@cd %THIS_DIR% +komodo-tx.exe -ac_name=HUSH3 %1 %2 %3 %4 %5 %6 %7 %8 %9 +@goto :EOF + +:GET_CURRENT_DIR +@pushd %~dp0 +@set THIS_DIR=%CD% +@popd +@goto :EOF + + + + From 1cdf998adebab5502e3e6161a0a1eaeb3ce6e366 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Tue, 29 Jun 2021 13:33:43 -0400 Subject: [PATCH 37/44] docs for -keepnotewitnesscache --- src/init.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 5e7a644f4..01916ee76 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -466,6 +466,9 @@ std::string HelpMessage(HelpMessageMode mode) CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-opretmintxfee=", strprintf(_("Minimum fee (in %s/kB) to allow for OP_RETURN transactions (default: %s)"), CURRENCY_UNIT, 400000 )); strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); + // If this is used incorrectly (-rescanheight too large), then the local wallet may attempt to spend funds which it does not have witness data about + // which will cause a "missing inputs" error when added to the mempool. Rescanning from correct height will fix this. + strUsage += HelpMessageOpt("-keepnotewitnesscache", _("Keep partial Sapling Note Witness cache. Must be used with -rescanheight to find missing cache items.")); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); strUsage += HelpMessageOpt("-rescanheight", _("Rescan from specified height when rescan=1 on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); From 14f38e3b0d9aaf7231b9848b4bec3f7f1969310b Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Thu, 8 Jul 2021 18:15:59 -0400 Subject: [PATCH 38/44] Let us be honest --- src/wallet/rpcdump.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 8a5398945..e5a7d2034 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -201,7 +201,7 @@ UniValue importprivkey(const UniValue& params, bool fHelp, const CPubKey& mypk) "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" "4. height (integer, optional, default=0) start at block height?\n" "5. secret_key (integer, optional, default=188) decimal value used to import WIFs of other coins\n" - "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nNote: This call can take a long time to complete if rescan is true.\n" "\nExamples:\n" "\nDump a private key\n" + HelpExampleCli("dumpprivkey", "\"myaddress\"") + @@ -295,7 +295,7 @@ UniValue importaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) "1. \"address\" (string, required) The address\n" "2. \"label\" (string, optional, default=\"\") An optional label\n" "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" - "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nNote: This call can take a long time to complete if rescan is true.\n" "\nExamples:\n" "\nImport an address with rescan\n" + HelpExampleCli("importaddress", "\"myaddress\"") + @@ -749,7 +749,7 @@ UniValue z_importkey(const UniValue& params, bool fHelp, const CPubKey& mypk) "1. \"zkey\" (string, required) The zkey (see z_exportkey)\n" "2. rescan (string, optional, default=\"whenkeyisnew\") Rescan the wallet for transactions - can be \"yes\", \"no\" or \"whenkeyisnew\"\n" "3. startHeight (numeric, optional, default=0) Block height to start rescan from\n" - "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nNote: This call can take a long time to complete if rescan is true.\n" "\nExamples:\n" "\nExport a zkey\n" + HelpExampleCli("z_exportkey", "\"myaddress\"") + @@ -841,7 +841,7 @@ UniValue z_importviewingkey(const UniValue& params, bool fHelp, const CPubKey& m "2. rescan (string, optional, default=\"whenkeyisnew\") Rescan the wallet for transactions - can be \"yes\", \"no\" or \"whenkeyisnew\"\n" "3. startHeight (numeric, optional, default=0) Block height to start rescan from\n" "4. zaddr (string, optional, default=\"\") zaddr in case of importing viewing key for Sapling\n" - "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nNote: This call can take a long time to complete if rescan is true.\n" "\nExamples:\n" "\nImport a viewing key\n" + HelpExampleCli("z_importviewingkey", "\"vkey\"") + From bfe907cb103723570559e6f02e36fc5213c266e4 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 9 Jul 2021 15:09:11 -0400 Subject: [PATCH 39/44] Bump proto version --- src/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.h b/src/version.h index fde7afc4b..3c8f28347 100644 --- a/src/version.h +++ b/src/version.h @@ -21,7 +21,7 @@ #define HUSH_VERSION_H // network protocol versioning -static const int PROTOCOL_VERSION = 1987422; +static const int PROTOCOL_VERSION = 1987423; //! initial proto version, to be increased after version/verack negotiation static const int INIT_PROTO_VERSION = 209; //! In this version, 'getheaders' was introduced. From ab769257e07a61d91902294344c84849dc2963e6 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 9 Jul 2021 15:09:19 -0400 Subject: [PATCH 40/44] Add copyright --- autogen.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/autogen.sh b/autogen.sh index 3e26a1830..6932fae53 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,4 +1,7 @@ #!/bin/sh +# Copyright (c) 2016-2021 The Hush developers +# Distributed under the GPLv3 software license, see the accompanying +# file COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html set -e srcdir="$(dirname $0)" cd "$srcdir" From 10a6706e712157728f1e8f8e85f95f1d92602118 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 9 Jul 2021 15:11:36 -0400 Subject: [PATCH 41/44] Bump version to 3.8.0 --- configure.ac | 4 ++-- src/clientversion.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 526ad358d..35da30d2a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 3) -define(_CLIENT_VERSION_MINOR, 7) -define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_MINOR, 8) +define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 50) define(_ZC_BUILD_VAL, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, m4_incr(_CLIENT_VERSION_BUILD), m4_eval(_CLIENT_VERSION_BUILD < 50), 1, m4_eval(_CLIENT_VERSION_BUILD - 24), m4_eval(_CLIENT_VERSION_BUILD == 50), 1, , m4_eval(_CLIENT_VERSION_BUILD - 50))) define(_CLIENT_VERSION_SUFFIX, m4_if(m4_eval(_CLIENT_VERSION_BUILD < 25), 1, _CLIENT_VERSION_REVISION-beta$1, m4_eval(_CLIENT_VERSION_BUILD < 50), 1, _CLIENT_VERSION_REVISION-rc$1, m4_eval(_CLIENT_VERSION_BUILD == 50), 1, _CLIENT_VERSION_REVISION, _CLIENT_VERSION_REVISION-$1))) diff --git a/src/clientversion.h b/src/clientversion.h index a7e850e7c..375f82690 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -29,8 +29,8 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it // Must be kept in sync with configure.ac , ugh! #define CLIENT_VERSION_MAJOR 3 -#define CLIENT_VERSION_MINOR 7 -#define CLIENT_VERSION_REVISION 1 +#define CLIENT_VERSION_MINOR 8 +#define CLIENT_VERSION_REVISION 0 #define CLIENT_VERSION_BUILD 50 //! Set to true for release, false for prerelease or test build From f9c4da812261e7f7c96947a7d458424e90d4ace3 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 9 Jul 2021 15:25:48 -0400 Subject: [PATCH 42/44] Add release notes for 3.8.0 --- doc/man/hush-cli.1 | 6 +++--- doc/man/hush-tx.1 | 6 +++--- doc/man/hushd.1 | 15 ++++++++++++--- doc/relnotes/README.md | 15 +++++++++++++++ 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/doc/man/hush-cli.1 b/doc/man/hush-cli.1 index 63d05ac06..668b3c4a7 100644 --- a/doc/man/hush-cli.1 +++ b/doc/man/hush-cli.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH HUSH-CLI "1" "April 2021" "hush-cli v3.7.1" "User Commands" +.TH HUSH-CLI "1" "July 2021" "hush-cli v3.8.0" "User Commands" .SH NAME -hush-cli \- manual page for hush-cli v3.7.1 +hush-cli \- manual page for hush-cli v3.8.0 .SH DESCRIPTION -Hush RPC client version v3.7.1\-2da07fe58\-dirty +Hush RPC client version v3.8.0\-10a6706e7\-dirty .PP In order to ensure you are adequately protecting your privacy when using Hush, please see . diff --git a/doc/man/hush-tx.1 b/doc/man/hush-tx.1 index 37c17b9b4..5c07d059a 100644 --- a/doc/man/hush-tx.1 +++ b/doc/man/hush-tx.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH HUSH-TX "1" "April 2021" "hush-tx v3.7.1" "User Commands" +.TH HUSH-TX "1" "July 2021" "hush-tx v3.8.0" "User Commands" .SH NAME -hush-tx \- manual page for hush-tx v3.7.1 +hush-tx \- manual page for hush-tx v3.8.0 .SH DESCRIPTION -hush\-tx utility version v3.7.1\-2da07fe58\-dirty +hush\-tx utility version v3.8.0\-10a6706e7\-dirty .SS "Usage:" .TP hush\-tx [options] [commands] diff --git a/doc/man/hushd.1 b/doc/man/hushd.1 index 23959cf1b..e73677110 100644 --- a/doc/man/hushd.1 +++ b/doc/man/hushd.1 @@ -1,9 +1,9 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH HUSHD "1" "April 2021" "hushd v3.7.1" "User Commands" +.TH HUSHD "1" "July 2021" "hushd v3.8.0" "User Commands" .SH NAME -hushd \- manual page for hushd v3.7.1 +hushd \- manual page for hushd v3.8.0 .SH DESCRIPTION -Hush Daemon version v3.7.1\-2da07fe58\-dirty +Hush Daemon version v3.8.0\-10a6706e7\-dirty .PP In order to ensure you are adequately protecting your privacy when using Hush, please see . @@ -341,10 +341,19 @@ Minimum fee (in HUSH/kB) to allow for OP_RETURN transactions (default: .IP Fee (in HUSH/kB) to add to transactions you send (default: 0.00) .HP +\fB\-keepnotewitnesscache\fR +.IP +Keep partial Sapling Note Witness cache. Must be used with \fB\-rescanheight\fR +to find missing cache items. +.HP \fB\-rescan\fR .IP Rescan the block chain for missing wallet transactions on startup .HP +\fB\-rescanheight\fR +.IP +Rescan from specified height when rescan=1 on startup +.HP \fB\-salvagewallet\fR .IP Attempt to recover private keys from a corrupt wallet.dat on startup diff --git a/doc/relnotes/README.md b/doc/relnotes/README.md index 002b23513..e70343f31 100644 --- a/doc/relnotes/README.md +++ b/doc/relnotes/README.md @@ -10,6 +10,21 @@ and no longer on Github, since they banned Duke Leto and also because they censor many people around the world and work with evil organizations. +# Hush 3.8.0 "XXX YYY" + +This is an OPTIONAL release, but since it contains many privacy improvements, it's HIGHLY RECOMMENDED for all users to upgrade. + + * New Sietch feature: Randomized change output location + * Zcash and Pirate always put the change as the last shielded output, which leaks metadata. Hush no longer has this metadata leakage. + * This feature improves the `z_sendmany`, `z_mergetoaddress` and `z_shieldtocoinbase` since it's done in the Hush TransactionBuilder. + * New Sietch feature: Sitech-ified `z_shieldcoinbase` + * This RPC now leaks less metadata by making it hard for blockchain analysts to know which of the three outputs has value. + * This also increases Hush's "anonset velocity", which is how fast we increase our anonymity set, or "anonset". + * `-keepnotewitnesscache` prevents the Sapling Note Witness cache from being deleted from wallet.dat on shutdown. + * `-rescanheight` can be used with `-keepnotewitnesscache` and `-rescan` to do a partial rescan of history and avoid completely rebuilding the Witness Cache. + * `-zindex` data is now stored on disk in the new `zindex.dat` file + * All nodes that use `-zindex` will now have reliable anonset statistics even after a restart + # Hush 3.7.1 "Neologistic Nautilus" ``` From 4249e155afb4ab86814ad0cdaf86d21d47bf5f09 Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 9 Jul 2021 15:31:40 -0400 Subject: [PATCH 43/44] More relnotery --- doc/relnotes/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/relnotes/README.md b/doc/relnotes/README.md index e70343f31..71a50dee5 100644 --- a/doc/relnotes/README.md +++ b/doc/relnotes/README.md @@ -20,10 +20,19 @@ This is an OPTIONAL release, but since it contains many privacy improvements, it * New Sietch feature: Sitech-ified `z_shieldcoinbase` * This RPC now leaks less metadata by making it hard for blockchain analysts to know which of the three outputs has value. * This also increases Hush's "anonset velocity", which is how fast we increase our anonymity set, or "anonset". + * Previously you could only run `stop` while Hush was in RPC warmup, but now additional RPCs are allowed: + * `stop` - Oops, you started hushd on accident a few seconds ago? Now you can stop it without waiting. + * `help` - Get help during long rescans, finally! + * `z_listaddresses` - See a list of all zaddrs in this wallet, even during a long rescan! + * `z_exportkey` - Export a key from this node, even during rescan! + * `listaddresses` - See a list of taddrs as soon as we load the wallet. + * `dumpprivkey` - Dump the private key of a taddr, even when node isn't fully synced! + * `getpeerinfo` - See current peers even before we get enough peers to start syncing or a long rescan! * `-keepnotewitnesscache` prevents the Sapling Note Witness cache from being deleted from wallet.dat on shutdown. * `-rescanheight` can be used with `-keepnotewitnesscache` and `-rescan` to do a partial rescan of history and avoid completely rebuilding the Witness Cache. * `-zindex` data is now stored on disk in the new `zindex.dat` file * All nodes that use `-zindex` will now have reliable anonset statistics even after a restart + * Improvements to the RPC help documentation # Hush 3.7.1 "Neologistic Nautilus" From be7e4ea94c93cc6d9bec8db540768a812a5c635a Mon Sep 17 00:00:00 2001 From: Duke Leto Date: Fri, 9 Jul 2021 16:00:53 -0400 Subject: [PATCH 44/44] More relnotes is good relnotes --- doc/relnotes/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/relnotes/README.md b/doc/relnotes/README.md index 71a50dee5..529063a8e 100644 --- a/doc/relnotes/README.md +++ b/doc/relnotes/README.md @@ -33,6 +33,8 @@ This is an OPTIONAL release, but since it contains many privacy improvements, it * `-zindex` data is now stored on disk in the new `zindex.dat` file * All nodes that use `-zindex` will now have reliable anonset statistics even after a restart * Improvements to the RPC help documentation + * `hushd.bat` for Windows now uses the ASN map via `-asmap` and has the latest seed nodes + * `hushd-tx.bat` for Windows now exists for making raw transactions on Windows # Hush 3.7.1 "Neologistic Nautilus"