From 743804e3fdd4d0192da20614329eba400c4dde67 Mon Sep 17 00:00:00 2001 From: Evan Klitzke Date: Tue, 6 Mar 2018 12:50:20 -0500 Subject: [PATCH 1/6] Set SCHED_BATCH priority on the loadblk thread. While reading another PR I saw a mention of #6358. The use case for SCHED_BATCH is to hint to the kernel that the thread is running a non-interactive workload that consumes a lot of CPU time. This is helpful on desktop machines where the loadblk thread can interfere with interactive applications. More details can be found in the sched(7) man page. --- src/init.cpp | 1 + src/util.cpp | 15 +++++++++++++++ src/util.h | 9 +++++++++ 3 files changed, 25 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index db5a288358d8..aaff86b7c621 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -672,6 +672,7 @@ struct CImportingNow { void ThreadImport(std::vector vImportFiles) { util::ThreadRename("pivx-loadblk"); + ScheduleBatchPriority(); // -reindex if (fReindex) { diff --git a/src/util.cpp b/src/util.cpp index ca94f0e963db..f0794d5eebdd 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -838,3 +839,17 @@ int GetNumCores() return std::thread::hardware_concurrency(); } + +int ScheduleBatchPriority(void) +{ +#ifdef SCHED_BATCH + const static sched_param param{.sched_priority = 0}; + if (int ret = pthread_setschedparam(0, SCHED_BATCH, ¶m)) { + LogPrintf("Failed to pthread_setschedparam: %s\n", strerror(errno)); + return ret; + } + return 0; +#else + return 1; +#endif +} diff --git a/src/util.h b/src/util.h index 6f159f0cb395..bb3f22a7e38d 100644 --- a/src/util.h +++ b/src/util.h @@ -261,4 +261,13 @@ void TraceThread(const char* name, Callable func) fs::path AbsPathForConfigVal(const fs::path& path, bool net_specific = true); +/** + * On platforms that support it, tell the kernel the calling thread is + * CPU-intensive and non-interactive. See SCHED_BATCH in sched(7) for details. + * + * @return The return value of sched_setschedule(), or 1 on systems without + * sched_setchedule(). + */ +int ScheduleBatchPriority(void); + #endif // BITCOIN_UTIL_H From 5ee47e26659de62cdbc87482dec0d0a30ea5267c Mon Sep 17 00:00:00 2001 From: furszy Date: Wed, 17 Feb 2021 00:19:41 -0300 Subject: [PATCH 2/6] Bugfix: RPC: savemempool: Don't save until LoadMempool() is finished Adaptation of btc@cb1e319fe9e198c9c5cf5236fe9af5a3d748b9e8 --- src/init.cpp | 5 ++--- src/validation.cpp | 1 + src/validation.h | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index aaff86b7c621..ca7499ddb5c0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -155,7 +155,6 @@ CClientUIInterface uiInterface; // Declared but not defined in guiinterface.h // volatile bool fRequestShutdown = false; -std::atomic fDumpMempoolLater(false); void StartShutdown() { @@ -254,7 +253,7 @@ void PrepareShutdown() DumpBudgets(g_budgetman); DumpMasternodePayments(); UnregisterNodeSignals(GetNodeSignals()); - if (fDumpMempoolLater && gArgs.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { + if (g_is_mempool_loaded && gArgs.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { DumpMempool(); } @@ -730,8 +729,8 @@ void ThreadImport(std::vector vImportFiles) if (gArgs.GetBoolArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { LoadMempool(); - fDumpMempoolLater = !fRequestShutdown; } + g_is_mempool_loaded = !fRequestShutdown; } /** Sanity checks diff --git a/src/validation.cpp b/src/validation.cpp index b9034fe5907f..e4b739d8e9c0 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -108,6 +108,7 @@ int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE; CFeeRate minRelayTxFee = CFeeRate(10000); CTxMemPool mempool(::minRelayTxFee); +std::atomic_bool g_is_mempool_loaded{false}; std::map mapRejectedBlocks; diff --git a/src/validation.h b/src/validation.h index e70ae6b30b2d..407455208ba9 100644 --- a/src/validation.h +++ b/src/validation.h @@ -124,6 +124,7 @@ struct BlockHasher { extern CScript COINBASE_FLAGS; extern RecursiveMutex cs_main; extern CTxMemPool mempool; +extern std::atomic_bool g_is_mempool_loaded; typedef std::unordered_map BlockMap; extern BlockMap mapBlockIndex; extern uint64_t nLastBlockTx; From a8e812160c0a5b17085f1c3e077a2bac5edcce47 Mon Sep 17 00:00:00 2001 From: furszy Date: Wed, 17 Feb 2021 00:21:37 -0300 Subject: [PATCH 3/6] init: fRequestShutdown moved to std::atomic --- src/init.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index ca7499ddb5c0..111efb12c95d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -55,14 +55,9 @@ #include "validationinterface.h" #include "zpivchain.h" -// Sapling -#include "sapling/sapling_util.h" -#include - #ifdef ENABLE_WALLET #include "wallet/db.h" #include "wallet/wallet.h" -#include "wallet/walletdb.h" #include "wallet/rpcwallet.h" #endif @@ -154,7 +149,7 @@ CClientUIInterface uiInterface; // Declared but not defined in guiinterface.h // shutdown thing. // -volatile bool fRequestShutdown = false; +std::atomic fRequestShutdown{false}; void StartShutdown() { From 63bcb8db6a71fc6303fa66cfbede5b187770a7e8 Mon Sep 17 00:00:00 2001 From: furszy Date: Thu, 18 Feb 2021 10:30:48 -0300 Subject: [PATCH 4/6] init.cpp: solved several Clang-Tidy warnings --- src/init.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 111efb12c95d..5095d0eaf679 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -362,7 +362,7 @@ void HandleSIGHUP(int) #ifndef WIN32 static void registerSignalHandler(int signal, void(*handler)(int)) { - struct sigaction sa; + struct sigaction sa{}; sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; @@ -400,7 +400,7 @@ void OnRPCPreCommand(const CRPCCommand& cmd) { // Observe safe mode std::string strWarning = GetWarnings("rpc"); - if (strWarning != "" && !gArgs.GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) && + if (!strWarning.empty() && !gArgs.GetBoolArg("-disablesafemode", DEFAULT_DISABLE_SAFEMODE) && !cmd.okSafeMode) throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, std::string("Safe mode: ") + strWarning); } @@ -663,7 +663,7 @@ struct CImportingNow { } }; -void ThreadImport(std::vector vImportFiles) +void ThreadImport(const std::vector& vImportFiles) { util::ThreadRename("pivx-loadblk"); ScheduleBatchPriority(); @@ -706,7 +706,7 @@ void ThreadImport(std::vector vImportFiles) } // -loadblock= - for (fs::path& path : vImportFiles) { + for (const fs::path& path : vImportFiles) { FILE* file = fsbridge::fopen(path, "rb"); if (file) { CImportingNow imp; @@ -752,9 +752,9 @@ bool InitSanityCheck(void) static void LoadSaplingParams() { - struct timeval tv_start, tv_end; + struct timeval tv_start{}, tv_end{}; float elapsed; - gettimeofday(&tv_start, 0); + gettimeofday(&tv_start, nullptr); try { initZKSNARKS(); @@ -769,7 +769,7 @@ static void LoadSaplingParams() return; } - gettimeofday(&tv_end, 0); + gettimeofday(&tv_end, nullptr); elapsed = float(tv_end.tv_sec-tv_start.tv_sec) + (tv_end.tv_usec-tv_start.tv_usec)/float(1000000); LogPrintf("Loaded Sapling parameters in %fs seconds.\n", elapsed); } @@ -803,7 +803,7 @@ bool AppInitServers() // The log was successful, terminate now. std::terminate(); -}; +} namespace { // Variables internal to initialization process only @@ -1446,7 +1446,7 @@ bool AppInitMain() // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default std::string proxyArg = gArgs.GetArg("-proxy", ""); SetLimited(NET_TOR); - if (proxyArg != "" && proxyArg != "0") { + if (!proxyArg.empty() && proxyArg != "0") { CService proxyAddr; if (!Lookup(proxyArg.c_str(), proxyAddr, 9050, fNameLookup)) { return UIError(strprintf(_("Lookup(): Invalid -proxy address or hostname: '%s'"), proxyArg)); @@ -1467,7 +1467,7 @@ bool AppInitMain() // -noonion (or -onion=0) disables connecting to .onion entirely // An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none) std::string onionArg = gArgs.GetArg("-onion", ""); - if (onionArg != "") { + if (!onionArg.empty()) { if (onionArg == "0") { // Handle -noonion/-onion=0 SetLimited(NET_TOR); // set onions as unreachable } else { @@ -1601,7 +1601,7 @@ bool AppInitMain() sporkManager.LoadSporksFromDB(); uiInterface.InitMessage(_("Loading block index...")); - std::string strBlockIndexError = ""; + std::string strBlockIndexError; if (!LoadBlockIndex(strBlockIndexError)) { if (ShutdownRequested()) break; strLoadError = _("Error loading block database"); @@ -1776,7 +1776,7 @@ bool AppInitMain() std::vector vImportFiles; for (const std::string& strFile : gArgs.GetArgs("-loadblock")) { - vImportFiles.push_back(strFile);; + vImportFiles.emplace_back(strFile); } threadGroup.create_thread(std::bind(&ThreadImport, vImportFiles)); @@ -1857,10 +1857,10 @@ bool AppInitMain() LOCK(pwalletMain->cs_wallet); LogPrintf("Locking Masternodes:\n"); uint256 mnTxHash; - for (CMasternodeConfig::CMasternodeEntry mne : masternodeConfig.getEntries()) { + for (const CMasternodeConfig::CMasternodeEntry& mne : masternodeConfig.getEntries()) { LogPrintf(" %s %s\n", mne.getTxHash(), mne.getOutputIndex()); mnTxHash.SetHex(mne.getTxHash()); - COutPoint outpoint = COutPoint(mnTxHash, (unsigned int) std::stoul(mne.getOutputIndex().c_str())); + COutPoint outpoint = COutPoint(mnTxHash, (unsigned int) std::stoul(mne.getOutputIndex())); pwalletMain->LockCoin(outpoint); } } From 54e4b781fe1610cb04d8799fcf98f2eeb4e56a54 Mon Sep 17 00:00:00 2001 From: furszy Date: Wed, 24 Feb 2021 17:34:43 -0300 Subject: [PATCH 5/6] validation: DisconnectBlock remove nValueOut and nValueIn calculation. --- src/legacy/validation_zerocoin_legacy.cpp | 4 +--- src/legacy/validation_zerocoin_legacy.h | 2 +- src/validation.cpp | 8 +------- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/legacy/validation_zerocoin_legacy.cpp b/src/legacy/validation_zerocoin_legacy.cpp index 904e1d8f5fab..53d5d179fc10 100644 --- a/src/legacy/validation_zerocoin_legacy.cpp +++ b/src/legacy/validation_zerocoin_legacy.cpp @@ -42,7 +42,7 @@ bool AcceptToMemoryPoolZerocoin(const CTransaction& tx, CAmount& nValueIn, int c return true; } -bool DisconnectZerocoinTx(const CTransaction& tx, CAmount& nValueIn, CZerocoinDB* zerocoinDB) +bool DisconnectZerocoinTx(const CTransaction& tx, CZerocoinDB* zerocoinDB) { /** UNDO ZEROCOIN DATABASING * note we only undo zerocoin databasing in the following statement, value to and from PIVX @@ -63,11 +63,9 @@ bool DisconnectZerocoinTx(const CTransaction& tx, CAmount& nValueIn, CZerocoinDB return error("Failed to parse public spend"); } serial = publicSpend.getCoinSerialNumber(); - nValueIn += publicSpend.getDenomination() * COIN; } else { libzerocoin::CoinSpend spend = TxInToZerocoinSpend(txin); serial = spend.getCoinSerialNumber(); - nValueIn += spend.getDenomination() * COIN; } if (!zerocoinDB->EraseCoinSpend(serial)) diff --git a/src/legacy/validation_zerocoin_legacy.h b/src/legacy/validation_zerocoin_legacy.h index 27cdc54b468b..f544358bbe60 100644 --- a/src/legacy/validation_zerocoin_legacy.h +++ b/src/legacy/validation_zerocoin_legacy.h @@ -11,7 +11,7 @@ #include "validationinterface.h" bool AcceptToMemoryPoolZerocoin(const CTransaction& tx, CAmount& nValueIn, int chainHeight, CValidationState& state, const Consensus::Params& consensus); -bool DisconnectZerocoinTx(const CTransaction& tx, CAmount& nValueIn, CZerocoinDB* zerocoinDB); +bool DisconnectZerocoinTx(const CTransaction& tx, CZerocoinDB* zerocoinDB); void DataBaseAccChecksum(const CBlockIndex* pindex, bool fWrite); #endif //VALIDATION_ZEROCOIN_LEGACY_H diff --git a/src/validation.cpp b/src/validation.cpp index e4b739d8e9c0..5d345c550827 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1253,8 +1253,6 @@ DisconnectResult DisconnectBlock(CBlock& block, const CBlockIndex* pindex, CCoin bool fClean = true; CBlockUndo blockUndo; - CAmount nValueOut = 0; - CAmount nValueIn = 0; CDiskBlockPos pos = pindex->GetUndoPos(); if (pos.IsNull()) { error("%s: no undo data available", __func__); @@ -1274,10 +1272,9 @@ DisconnectResult DisconnectBlock(CBlock& block, const CBlockIndex* pindex, CCoin for (int i = block.vtx.size() - 1; i >= 0; i--) { const CTransaction& tx = *block.vtx[i]; - if (!DisconnectZerocoinTx(tx, nValueIn, zerocoinDB)) + if (!DisconnectZerocoinTx(tx, zerocoinDB)) return DISCONNECT_FAILED; - nValueOut += tx.GetValueOut(); const uint256& hash = tx.GetHash(); // if tx is a budget collateral tx, remove relative object @@ -1317,9 +1314,6 @@ DisconnectResult DisconnectBlock(CBlock& block, const CBlockIndex* pindex, CCoin fClean = fClean && res != DISCONNECT_UNCLEAN; } // At this point, all of txundo.vprevout should have been moved out. - - if (view.HaveInputs(tx)) - nValueIn += view.GetValueIn(tx); } const Consensus::Params& consensus = Params().GetConsensus(); From 4bc4728cd0b6ef069e200afacca37a28f1331315 Mon Sep 17 00:00:00 2001 From: furszy Date: Wed, 24 Feb 2021 17:37:51 -0300 Subject: [PATCH 6/6] deterministicmint.h/cpp unused files removed. --- CMakeLists.txt | 2 - src/Makefile.am | 3 -- src/stakeinput.cpp | 1 - src/wallet/rpcwallet.cpp | 1 - src/wallet/walletdb.cpp | 1 - src/wallet/walletdb.h | 1 - src/zpiv/deterministicmint.cpp | 44 ---------------------- src/zpiv/deterministicmint.h | 67 ---------------------------------- 8 files changed, 120 deletions(-) delete mode 100644 src/zpiv/deterministicmint.cpp delete mode 100644 src/zpiv/deterministicmint.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 18cf29739db5..196d2bae8ac9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,7 +283,6 @@ set(WALLET_SOURCES ./src/zpiv/mintpool.cpp ./src/wallet/hdchain.cpp ./src/wallet/rpcdump.cpp - ./src/zpiv/deterministicmint.cpp ./src/zpiv/zerocoin.cpp ./src/wallet/scriptpubkeyman.cpp ./src/wallet/rpcwallet.cpp @@ -389,7 +388,6 @@ set(COMMON_SOURCES ./src/consensus/tx_verify.cpp ./src/consensus/zerocoin_verify.cpp ./src/primitives/block.cpp - ./src/zpiv/deterministicmint.cpp ./src/primitives/transaction.cpp ./src/zpiv/zerocoin.cpp ./src/core_read.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 12009b40a2bb..da8a73f1b1a3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -294,7 +294,6 @@ BITCOIN_CORE_H = \ wallet/walletdb.h \ warnings.h \ zpivchain.h \ - zpiv/deterministicmint.h \ zpiv/mintpool.h \ zpiv/zerocoin.h \ zpiv/zpos.h \ @@ -404,7 +403,6 @@ libbitcoin_wallet_a_SOURCES = \ destination_io.cpp \ wallet/wallet.cpp \ wallet/walletdb.cpp \ - zpiv/deterministicmint.cpp \ zpiv/zerocoin.cpp \ zpiv/mintpool.cpp \ stakeinput.cpp \ @@ -497,7 +495,6 @@ libbitcoin_common_a_SOURCES = \ compressor.cpp \ consensus/merkle.cpp \ primitives/block.cpp \ - zpiv/deterministicmint.cpp \ primitives/transaction.cpp \ zpiv/zerocoin.cpp \ core_read.cpp \ diff --git a/src/stakeinput.cpp b/src/stakeinput.cpp index cef92e7854ca..398ddac4e5cd 100644 --- a/src/stakeinput.cpp +++ b/src/stakeinput.cpp @@ -6,7 +6,6 @@ #include "chain.h" #include "txdb.h" -#include "zpiv/deterministicmint.h" #include "wallet/wallet.h" CPivStake* CPivStake::NewPivStake(const CTxIn& txin) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 2b5dd3355693..faf71fa1bda3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -31,7 +31,6 @@ #include #include "spork.h" -#include "zpiv/deterministicmint.h" #include #include diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 1260f57a7257..0579b1784b21 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -17,7 +17,6 @@ #include "util.h" #include "utiltime.h" #include "wallet/wallet.h" -#include #include #include diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index f7cb0b0593e2..ccc2b198ff97 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -43,7 +43,6 @@ class CMasterKey; class CScript; class CWallet; class CWalletTx; -class CDeterministicMint; class uint160; class uint256; diff --git a/src/zpiv/deterministicmint.cpp b/src/zpiv/deterministicmint.cpp deleted file mode 100644 index db961ea8d798..000000000000 --- a/src/zpiv/deterministicmint.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2018-2020 The PIVX developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include "deterministicmint.h" - - -CDeterministicMint::CDeterministicMint() -{ - SetNull(); -} - -CDeterministicMint::CDeterministicMint(uint8_t nVersion, const uint32_t& nCount, const uint256& hashSeed, const uint256& hashSerial, const uint256& hashPubcoin, const uint256& hashStake) -{ - SetNull(); - this->nVersion = nVersion; - this->nCount = nCount; - this->hashSeed = hashSeed; - this->hashSerial = hashSerial; - this->hashPubcoin = hashPubcoin; - this->hashStake = hashStake; -} - -void CDeterministicMint::SetNull() -{ - nVersion = libzerocoin::PrivateCoin::CURRENT_VERSION; - nCount = 0; - hashSeed.SetNull(); - hashSerial.SetNull(); - hashStake.SetNull(); - hashPubcoin.SetNull(); - txid.SetNull(); - nHeight = 0; - denom = libzerocoin::CoinDenomination::ZQ_ERROR; - isUsed = false; -} - -std::string CDeterministicMint::ToString() const -{ - return strprintf(" DeterministicMint:\n version=%d\n count=%d\n hashseed=%s\n hashSerial=%s\n hashStake=%s\n hashPubcoin=%s\n txid=%s\n height=%d\n denom=%d\n isUsed=%d\n", - nVersion, nCount, hashSeed.GetHex(), hashSerial.GetHex(), hashStake.GetHex(), hashPubcoin.GetHex(), txid.GetHex(), nHeight, denom, isUsed); -} diff --git a/src/zpiv/deterministicmint.h b/src/zpiv/deterministicmint.h deleted file mode 100644 index c7810688ef08..000000000000 --- a/src/zpiv/deterministicmint.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2018 The PIVX developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef PIVX_DETERMINISTICMINT_H -#define PIVX_DETERMINISTICMINT_H - -#include -#include -#include - -//struct that is safe to store essential mint data, without holding any information that allows for actual spending (serial, randomness, private key) -class CDeterministicMint -{ -private: - uint8_t nVersion; - uint32_t nCount; - uint256 hashSeed; - uint256 hashSerial; - uint256 hashStake; - uint256 hashPubcoin; - uint256 txid; - int nHeight; - libzerocoin::CoinDenomination denom; - bool isUsed; - -public: - CDeterministicMint(); - CDeterministicMint(uint8_t nVersion, const uint32_t& nCount, const uint256& hashSeed, const uint256& hashSerial, const uint256& hashPubcoin, const uint256& hashStake); - - libzerocoin::CoinDenomination GetDenomination() const { return denom; } - uint32_t GetCount() const { return nCount; } - int GetHeight() const { return nHeight; } - uint256 GetSeedHash() const { return hashSeed; } - uint256 GetSerialHash() const { return hashSerial; } - uint256 GetStakeHash() const { return hashStake; } - uint256 GetPubcoinHash() const { return hashPubcoin; } - uint256 GetTxHash() const { return txid; } - uint8_t GetVersion() const { return nVersion; } - bool IsUsed() const { return isUsed; } - void SetDenomination(const libzerocoin::CoinDenomination denom) { this->denom = denom; } - void SetHeight(const int& nHeight) { this->nHeight = nHeight; } - void SetNull(); - void SetStakeHash(const uint256& hashStake) { this->hashStake = hashStake; } - void SetTxHash(const uint256& txid) { this->txid = txid; } - void SetUsed(const bool isUsed) { this->isUsed = isUsed; } - std::string ToString() const; - - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) - { - READWRITE(nVersion); - READWRITE(nCount); - READWRITE(hashSeed); - READWRITE(hashSerial); - READWRITE(hashStake); - READWRITE(hashPubcoin); - READWRITE(txid); - READWRITE(nHeight); - READWRITE(denom); - READWRITE(isUsed); - }; -}; - -#endif //PIVX_DETERMINISTICMINT_H