merge bitcoin#24812: Add CHECK_NONFATAL identity function and NONFATAL_UNREACHABLE macro

This commit is contained in:
Kittywhiskers Van Gogh 2022-04-09 02:14:02 +02:00
parent 1caaa85716
commit 10203560f5
No known key found for this signature in database
GPG Key ID: 30CD0C065E5C4AAD
13 changed files with 110 additions and 144 deletions

View File

@ -39,6 +39,7 @@
#include <sync.h> #include <sync.h>
#include <txmempool.h> #include <txmempool.h>
#include <undo.h> #include <undo.h>
#include <util/check.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/string.h> #include <util/string.h>
#include <util/system.h> #include <util/system.h>
@ -1359,8 +1360,7 @@ static RPCHelpMan pruneblockchain()
} }
PruneBlockFilesManual(active_chainstate, height); PruneBlockFilesManual(active_chainstate, height);
const CBlockIndex* block = active_chain.Tip(); const CBlockIndex* block = CHECK_NONFATAL(active_chain.Tip());
CHECK_NONFATAL(block);
while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) { while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
block = block->pprev; block = block->pprev;
} }
@ -1635,14 +1635,13 @@ static RPCHelpMan verifychain()
const int check_depth{request.params[1].isNull() ? DEFAULT_CHECKBLOCKS : request.params[1].get_int()}; const int check_depth{request.params[1].isNull() ? DEFAULT_CHECKBLOCKS : request.params[1].get_int()};
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
CHECK_NONFATAL(node.evodb);
ChainstateManager& chainman = EnsureChainman(node); ChainstateManager& chainman = EnsureChainman(node);
LOCK(cs_main); LOCK(cs_main);
CChainState& active_chainstate = chainman.ActiveChainstate(); CChainState& active_chainstate = chainman.ActiveChainstate();
return CVerifyDB().VerifyDB( return CVerifyDB().VerifyDB(
active_chainstate, Params(), active_chainstate.CoinsTip(), *node.evodb, check_level, check_depth); active_chainstate, Params(), active_chainstate.CoinsTip(), *CHECK_NONFATAL(node.evodb), check_level, check_depth);
}, },
}; };
} }
@ -1782,13 +1781,11 @@ RPCHelpMan getblockchaininfo()
LOCK(cs_main); LOCK(cs_main);
CChainState& active_chainstate = chainman.ActiveChainstate(); CChainState& active_chainstate = chainman.ActiveChainstate();
const CBlockIndex* tip = active_chainstate.m_chain.Tip();
CHECK_NONFATAL(tip); const CBlockIndex* tip = CHECK_NONFATAL(active_chainstate.m_chain.Tip());
const int height = tip->nHeight; const int height = tip->nHeight;
CHECK_NONFATAL(node.mnhf_manager); const auto ehfSignals = CHECK_NONFATAL(node.mnhf_manager)->GetSignalsStage(tip);
const auto ehfSignals = node.mnhf_manager->GetSignalsStage(tip);
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
if (args.IsArgSet("-devnet")) { if (args.IsArgSet("-devnet")) {
@ -1808,8 +1805,7 @@ RPCHelpMan getblockchaininfo()
obj.pushKV("size_on_disk", chainman.m_blockman.CalculateCurrentUsage()); obj.pushKV("size_on_disk", chainman.m_blockman.CalculateCurrentUsage());
obj.pushKV("pruned", fPruneMode); obj.pushKV("pruned", fPruneMode);
if (fPruneMode) { if (fPruneMode) {
const CBlockIndex* block = tip; const CBlockIndex* block = CHECK_NONFATAL(tip);
CHECK_NONFATAL(block);
while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) { while (block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA)) {
block = block->pprev; block = block->pprev;
} }
@ -2863,10 +2859,8 @@ static RPCHelpMan scantxoutset()
LOCK(cs_main); LOCK(cs_main);
CChainState& active_chainstate = chainman.ActiveChainstate(); CChainState& active_chainstate = chainman.ActiveChainstate();
active_chainstate.ForceFlushStateToDisk(); active_chainstate.ForceFlushStateToDisk();
pcursor = active_chainstate.CoinsDB().Cursor(); pcursor = CHECK_NONFATAL(active_chainstate.CoinsDB().Cursor());
CHECK_NONFATAL(pcursor); tip = CHECK_NONFATAL(active_chainstate.m_chain.Tip());
tip = active_chainstate.m_chain.Tip();
CHECK_NONFATAL(tip);
} }
bool res = FindScriptPubKey(g_scan_progress, g_should_abort_scan, count, pcursor.get(), needles, coins, node.rpc_interruption_point); bool res = FindScriptPubKey(g_scan_progress, g_should_abort_scan, count, pcursor.get(), needles, coins, node.rpc_interruption_point);
result.pushKV("success", res); result.pushKV("success", res);
@ -3061,8 +3055,7 @@ UniValue CreateUTXOSnapshot(NodeContext& node, CChainState& chainstate, CAutoFil
} }
pcursor = chainstate.CoinsDB().Cursor(); pcursor = chainstate.CoinsDB().Cursor();
tip = chainstate.m_blockman.LookupBlockIndex(stats.hashBlock); tip = CHECK_NONFATAL(chainstate.m_blockman.LookupBlockIndex(stats.hashBlock));
CHECK_NONFATAL(tip);
} }
SnapshotMetadata metadata{tip->GetBlockHash(), stats.coins_count, tip->nChainTx}; SnapshotMetadata metadata{tip->GetBlockHash(), stats.coins_count, tip->nChainTx};

View File

@ -9,6 +9,7 @@
#include <rpc/blockchain.h> #include <rpc/blockchain.h>
#include <rpc/server.h> #include <rpc/server.h>
#include <rpc/server_util.h> #include <rpc/server_util.h>
#include <util/check.h>
#include <rpc/util.h> #include <rpc/util.h>
#include <util/strencodings.h> #include <util/strencodings.h>
@ -83,11 +84,8 @@ static RPCHelpMan coinjoin_reset()
ValidateCoinJoinArguments(); ValidateCoinJoinArguments();
CHECK_NONFATAL(node.coinjoin_loader); auto cj_clientman = CHECK_NONFATAL(node.coinjoin_loader)->walletman().Get(wallet->GetName());
auto cj_clientman = node.coinjoin_loader->walletman().Get(wallet->GetName()); CHECK_NONFATAL(cj_clientman)->ResetPool();
CHECK_NONFATAL(cj_clientman);
cj_clientman->ResetPool();
return "Mixing was reset"; return "Mixing was reset";
}, },
@ -126,10 +124,7 @@ static RPCHelpMan coinjoin_start()
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please unlock wallet for mixing with walletpassphrase first."); throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please unlock wallet for mixing with walletpassphrase first.");
} }
CHECK_NONFATAL(node.coinjoin_loader); auto cj_clientman = CHECK_NONFATAL(CHECK_NONFATAL(node.coinjoin_loader)->walletman().Get(wallet->GetName()));
auto cj_clientman = node.coinjoin_loader->walletman().Get(wallet->GetName());
CHECK_NONFATAL(cj_clientman);
if (!cj_clientman->StartMixing()) { if (!cj_clientman->StartMixing()) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing has been started already."); throw JSONRPCError(RPC_INTERNAL_ERROR, "Mixing has been started already.");
} }
@ -450,8 +445,7 @@ static RPCHelpMan getcoinjoininfo()
return obj; return obj;
} }
auto manager = node.coinjoin_loader->walletman().Get(wallet->GetName()); auto* manager = CHECK_NONFATAL(node.coinjoin_loader->walletman().Get(wallet->GetName()));
CHECK_NONFATAL(manager != nullptr);
manager->GetJsonInfo(obj); manager->GetJsonInfo(obj);
std::string warning_msg{""}; std::string warning_msg{""};

View File

@ -26,6 +26,7 @@
#include <rpc/server.h> #include <rpc/server.h>
#include <rpc/server_util.h> #include <rpc/server_util.h>
#include <rpc/util.h> #include <rpc/util.h>
#include <util/check.h>
#include <util/moneystr.h> #include <util/moneystr.h>
#include <util/translation.h> #include <util/translation.h>
#include <validation.h> #include <validation.h>
@ -628,8 +629,7 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.chain_helper); CChainstateHelper& chain_helper = *CHECK_NONFATAL(node.chain_helper);
CChainstateHelper& chain_helper = *node.chain_helper;
const bool isEvoRequested = mnType == MnType::Evo; const bool isEvoRequested = mnType == MnType::Evo;
@ -855,8 +855,7 @@ static RPCHelpMan protx_register_submit()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.chain_helper); CChainstateHelper& chain_helper = *CHECK_NONFATAL(node.chain_helper);
CChainstateHelper& chain_helper = *node.chain_helper;
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
if (!wallet) return NullUniValue; if (!wallet) return NullUniValue;
@ -954,11 +953,8 @@ static UniValue protx_update_service_common_wrapper(const JSONRPCRequest& reques
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman); CDeterministicMNManager& dmnman = *CHECK_NONFATAL(node.dmnman);
CDeterministicMNManager& dmnman = *node.dmnman; CChainstateHelper& chain_helper = *CHECK_NONFATAL(node.chain_helper);
CHECK_NONFATAL(node.chain_helper);
CChainstateHelper& chain_helper = *node.chain_helper;
const bool isEvoRequested = mnType == MnType::Evo; const bool isEvoRequested = mnType == MnType::Evo;
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
@ -1092,11 +1088,8 @@ static RPCHelpMan protx_update_registrar_wrapper(bool specific_legacy_bls_scheme
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman); CDeterministicMNManager& dmnman = *CHECK_NONFATAL(node.dmnman);
CDeterministicMNManager& dmnman = *node.dmnman; CChainstateHelper& chain_helper = *CHECK_NONFATAL(node.chain_helper);
CHECK_NONFATAL(node.chain_helper);
CChainstateHelper& chain_helper = *node.chain_helper;
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
if (!wallet) return NullUniValue; if (!wallet) return NullUniValue;
@ -1207,12 +1200,8 @@ static RPCHelpMan protx_revoke()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman); CDeterministicMNManager& dmnman = *CHECK_NONFATAL(node.dmnman);
CDeterministicMNManager& dmnman = *node.dmnman; CChainstateHelper& chain_helper = *CHECK_NONFATAL(node.chain_helper);
CHECK_NONFATAL(node.chain_helper);
CChainstateHelper& chain_helper = *node.chain_helper;
std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
if (!pwallet) return NullUniValue; if (!pwallet) return NullUniValue;
@ -1370,11 +1359,8 @@ static RPCHelpMan protx_list()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman); CDeterministicMNManager& dmnman = *CHECK_NONFATAL(node.dmnman);
CDeterministicMNManager& dmnman = *node.dmnman; CMasternodeMetaMan& mn_metaman = *CHECK_NONFATAL(node.mn_metaman);
CHECK_NONFATAL(node.mn_metaman);
CMasternodeMetaMan& mn_metaman = *node.mn_metaman;
std::shared_ptr<CWallet> wallet{nullptr}; std::shared_ptr<CWallet> wallet{nullptr};
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
@ -1486,11 +1472,8 @@ static RPCHelpMan protx_info()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman); CDeterministicMNManager& dmnman = *CHECK_NONFATAL(node.dmnman);
CDeterministicMNManager& dmnman = *node.dmnman; CMasternodeMetaMan& mn_metaman = *CHECK_NONFATAL(node.mn_metaman);
CHECK_NONFATAL(node.mn_metaman);
CMasternodeMetaMan& mn_metaman = *node.mn_metaman;
std::shared_ptr<CWallet> wallet{nullptr}; std::shared_ptr<CWallet> wallet{nullptr};
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
@ -1560,11 +1543,8 @@ static RPCHelpMan protx_diff()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman); CDeterministicMNManager& dmnman = *CHECK_NONFATAL(node.dmnman);
CDeterministicMNManager& dmnman = *node.dmnman; const LLMQContext& llmq_ctx = *CHECK_NONFATAL(node.llmq_ctx);
CHECK_NONFATAL(node.llmq_ctx);
const LLMQContext& llmq_ctx = *node.llmq_ctx;
LOCK(cs_main); LOCK(cs_main);
uint256 baseBlockHash = ParseBlock(request.params[0], chainman, "baseBlock"); uint256 baseBlockHash = ParseBlock(request.params[0], chainman, "baseBlock");
@ -1621,8 +1601,7 @@ static RPCHelpMan protx_listdiff()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman); CDeterministicMNManager& dmnman = *CHECK_NONFATAL(node.dmnman);
CDeterministicMNManager& dmnman = *node.dmnman;
LOCK(cs_main); LOCK(cs_main);
UniValue ret(UniValue::VOBJ); UniValue ret(UniValue::VOBJ);

View File

@ -21,6 +21,7 @@
#include <rpc/server_util.h> #include <rpc/server_util.h>
#include <rpc/util.h> #include <rpc/util.h>
#include <timedata.h> #include <timedata.h>
#include <util/check.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/system.h> #include <util/system.h>
#include <validation.h> #include <validation.h>
@ -194,12 +195,11 @@ static RPCHelpMan gobject_prepare()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman);
{ {
LOCK(cs_main); LOCK(cs_main);
std::string strError = ""; std::string strError = "";
if (!govobj.IsValidLocally(node.dmnman->GetListAtChainTip(), chainman, strError, false)) if (!govobj.IsValidLocally(CHECK_NONFATAL(node.dmnman)->GetListAtChainTip(), chainman, strError, false))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Governance object is not valid - " + govobj.GetHash().ToString() + " - " + strError); throw JSONRPCError(RPC_INTERNAL_ERROR, "Governance object is not valid - " + govobj.GetHash().ToString() + " - " + strError);
} }
@ -303,14 +303,12 @@ static RPCHelpMan gobject_submit()
{ {
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman);
CHECK_NONFATAL(node.govman);
if(!node.mn_sync->IsBlockchainSynced()) { if(!node.mn_sync->IsBlockchainSynced()) {
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Must wait for client to sync with masternode network. Try again in a minute or so."); throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Must wait for client to sync with masternode network. Try again in a minute or so.");
} }
auto mnList = node.dmnman->GetListAtChainTip(); auto mnList = CHECK_NONFATAL(node.dmnman)->GetListAtChainTip();
if (node.mn_activeman) { if (node.mn_activeman) {
const bool fMnFound = mnList.HasValidMNByCollateral(node.mn_activeman->GetOutPoint()); const bool fMnFound = mnList.HasValidMNByCollateral(node.mn_activeman->GetOutPoint());
@ -373,7 +371,6 @@ static RPCHelpMan gobject_submit()
} }
LOCK2(cs_main, mempool.cs); LOCK2(cs_main, mempool.cs);
CHECK_NONFATAL(node.dmnman);
std::string strError; std::string strError;
if (!govobj.IsValidLocally(node.dmnman->GetListAtChainTip(), chainman, strError, fMissingConfirmations, true) && !fMissingConfirmations) { if (!govobj.IsValidLocally(node.dmnman->GetListAtChainTip(), chainman, strError, fMissingConfirmations, true) && !fMissingConfirmations) {
@ -384,7 +381,7 @@ static RPCHelpMan gobject_submit()
// RELAY THIS OBJECT // RELAY THIS OBJECT
// Reject if rate check fails but don't update buffer // Reject if rate check fails but don't update buffer
if (!node.govman->MasternodeRateCheck(govobj)) { if (!CHECK_NONFATAL(node.govman)->MasternodeRateCheck(govobj)) {
LogPrintf("gobject(submit) -- Object submission rejected because of rate check failure - hash = %s\n", strHash); LogPrintf("gobject(submit) -- Object submission rejected because of rate check failure - hash = %s\n", strHash);
throw JSONRPCError(RPC_INVALID_PARAMETER, "Object creation rate limit exceeded"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Object creation rate limit exceeded");
} }
@ -393,9 +390,8 @@ static RPCHelpMan gobject_submit()
PeerManager& peerman = EnsurePeerman(node); PeerManager& peerman = EnsurePeerman(node);
if (fMissingConfirmations) { if (fMissingConfirmations) {
CHECK_NONFATAL(node.mn_sync);
node.govman->AddPostponedObject(govobj); node.govman->AddPostponedObject(govobj);
govobj.Relay(peerman, *node.mn_sync); govobj.Relay(peerman, *CHECK_NONFATAL(node.mn_sync));
} else { } else {
node.govman->AddGovernanceObject(govobj, peerman); node.govman->AddGovernanceObject(govobj, peerman);
} }
@ -452,7 +448,7 @@ static UniValue VoteWithMasternodes(const JSONRPCRequest& request, const CWallet
int nSuccessful = 0; int nSuccessful = 0;
int nFailed = 0; int nFailed = 0;
auto mnList = node.dmnman->GetListAtChainTip(); auto mnList = CHECK_NONFATAL(node.dmnman)->GetListAtChainTip();
UniValue resultsObj(UniValue::VOBJ); UniValue resultsObj(UniValue::VOBJ);
@ -529,7 +525,6 @@ static RPCHelpMan gobject_vote_many()
if (!wallet) return NullUniValue; if (!wallet) return NullUniValue;
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
CHECK_NONFATAL(node.dmnman);
uint256 hash(ParseHashV(request.params[0], "Object hash")); uint256 hash(ParseHashV(request.params[0], "Object hash"));
std::string strVoteSignal = request.params[1].get_str(); std::string strVoteSignal = request.params[1].get_str();
@ -551,7 +546,7 @@ static RPCHelpMan gobject_vote_many()
std::map<uint256, CKeyID> votingKeys; std::map<uint256, CKeyID> votingKeys;
auto mnList = node.dmnman->GetListAtChainTip(); auto mnList = CHECK_NONFATAL(node.dmnman)->GetListAtChainTip();
mnList.ForEachMN(true, [&](auto& dmn) { mnList.ForEachMN(true, [&](auto& dmn) {
const bool is_mine = CheckWalletOwnsKey(*wallet, dmn.pdmnState->keyIDVoting); const bool is_mine = CheckWalletOwnsKey(*wallet, dmn.pdmnState->keyIDVoting);
if (is_mine) { if (is_mine) {
@ -583,7 +578,6 @@ static RPCHelpMan gobject_vote_alias()
if (!wallet) return NullUniValue; if (!wallet) return NullUniValue;
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
CHECK_NONFATAL(node.dmnman);
uint256 hash(ParseHashV(request.params[0], "Object hash")); uint256 hash(ParseHashV(request.params[0], "Object hash"));
std::string strVoteSignal = request.params[1].get_str(); std::string strVoteSignal = request.params[1].get_str();
@ -604,7 +598,7 @@ static RPCHelpMan gobject_vote_alias()
EnsureWalletIsUnlocked(*wallet); EnsureWalletIsUnlocked(*wallet);
uint256 proTxHash(ParseHashV(request.params[3], "protx-hash")); uint256 proTxHash(ParseHashV(request.params[3], "protx-hash"));
auto dmn = node.dmnman->GetListAtChainTip().GetValidMN(proTxHash); auto dmn = CHECK_NONFATAL(node.dmnman)->GetListAtChainTip().GetValidMN(proTxHash);
if (!dmn) { if (!dmn) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid or unknown proTxHash"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid or unknown proTxHash");
} }
@ -718,11 +712,10 @@ static RPCHelpMan gobject_list_helper(const bool make_a_diff)
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman);
CHECK_NONFATAL(node.govman);
const int64_t last_time = make_a_diff ? node.govman->GetLastDiffTime() : 0; const int64_t last_time = make_a_diff ? node.govman->GetLastDiffTime() : 0;
return ListObjects(*node.govman, node.dmnman->GetListAtChainTip(), chainman, strCachedSignal, strType, last_time); return ListObjects(*CHECK_NONFATAL(node.govman), CHECK_NONFATAL(node.dmnman)->GetListAtChainTip(), chainman,
strCachedSignal, strType, last_time);
}, },
}; };
} }
@ -759,8 +752,8 @@ static RPCHelpMan gobject_get()
// FIND THE GOVERNANCE OBJECT THE USER IS LOOKING FOR // FIND THE GOVERNANCE OBJECT THE USER IS LOOKING FOR
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman && node.govman);
CHECK_NONFATAL(node.govman);
LOCK2(cs_main, node.govman->cs); LOCK2(cs_main, node.govman->cs);
const CGovernanceObject* pGovObj = node.govman->FindConstGovernanceObject(hash); const CGovernanceObject* pGovObj = node.govman->FindConstGovernanceObject(hash);
@ -785,7 +778,7 @@ static RPCHelpMan gobject_get()
// SHOW (MUCH MORE) INFORMATION ABOUT VOTES FOR GOVERNANCE OBJECT (THAN LIST/DIFF ABOVE) // SHOW (MUCH MORE) INFORMATION ABOUT VOTES FOR GOVERNANCE OBJECT (THAN LIST/DIFF ABOVE)
// -- FUNDING VOTING RESULTS // -- FUNDING VOTING RESULTS
auto tip_mn_list = node.dmnman->GetListAtChainTip(); auto tip_mn_list = CHECK_NONFATAL(node.dmnman)->GetListAtChainTip();
UniValue objFundingResult(UniValue::VOBJ); UniValue objFundingResult(UniValue::VOBJ);
objFundingResult.pushKV("AbsoluteYesCount", pGovObj->GetAbsoluteYesCount(tip_mn_list, VOTE_SIGNAL_FUNDING)); objFundingResult.pushKV("AbsoluteYesCount", pGovObj->GetAbsoluteYesCount(tip_mn_list, VOTE_SIGNAL_FUNDING));
@ -858,8 +851,8 @@ static RPCHelpMan gobject_getcurrentvotes()
// FIND OBJECT USER IS LOOKING FOR // FIND OBJECT USER IS LOOKING FOR
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
CHECK_NONFATAL(node.govman);
CHECK_NONFATAL(node.govman);
LOCK(node.govman->cs); LOCK(node.govman->cs);
const CGovernanceObject* pGovObj = node.govman->FindConstGovernanceObject(hash); const CGovernanceObject* pGovObj = node.govman->FindConstGovernanceObject(hash);
@ -872,10 +865,9 @@ static RPCHelpMan gobject_getcurrentvotes()
UniValue bResult(UniValue::VOBJ); UniValue bResult(UniValue::VOBJ);
// GET MATCHING VOTES BY HASH, THEN SHOW USERS VOTE INFORMATION // GET MATCHING VOTES BY HASH, THEN SHOW USERS VOTE INFORMATION
CHECK_NONFATAL(node.dmnman);
std::vector<CGovernanceVote> vecVotes = node.govman->GetCurrentVotes(hash, mnCollateralOutpoint); std::vector<CGovernanceVote> vecVotes = node.govman->GetCurrentVotes(hash, mnCollateralOutpoint);
for (const auto& vote : vecVotes) { for (const auto& vote : vecVotes) {
bResult.pushKV(vote.GetHash().ToString(), vote.ToString(node.dmnman->GetListAtChainTip())); bResult.pushKV(vote.GetHash().ToString(), vote.ToString(CHECK_NONFATAL(node.dmnman)->GetListAtChainTip()));
} }
return bResult; return bResult;
@ -975,8 +967,7 @@ static RPCHelpMan voteraw()
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
} }
CHECK_NONFATAL(node.dmnman); const auto tip_mn_list = CHECK_NONFATAL(node.dmnman)->GetListAtChainTip();
const auto tip_mn_list = node.dmnman->GetListAtChainTip();
auto dmn = tip_mn_list.GetValidMNByCollateral(outpoint); auto dmn = tip_mn_list.GetValidMNByCollateral(outpoint);
if (!dmn) { if (!dmn) {
@ -1034,7 +1025,6 @@ static RPCHelpMan getgovernanceinfo()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureAnyChainman(request.context); const ChainstateManager& chainman = EnsureAnyChainman(request.context);
CHECK_NONFATAL(node.dmnman);
const auto* pindex = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip()); const auto* pindex = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
int nBlockHeight = pindex->nHeight; int nBlockHeight = pindex->nHeight;
@ -1048,7 +1038,7 @@ static RPCHelpMan getgovernanceinfo()
obj.pushKV("superblockmaturitywindow", Params().GetConsensus().nSuperblockMaturityWindow); obj.pushKV("superblockmaturitywindow", Params().GetConsensus().nSuperblockMaturityWindow);
obj.pushKV("lastsuperblock", nLastSuperblock); obj.pushKV("lastsuperblock", nLastSuperblock);
obj.pushKV("nextsuperblock", nNextSuperblock); obj.pushKV("nextsuperblock", nNextSuperblock);
obj.pushKV("fundingthreshold", int(node.dmnman->GetListAtChainTip().GetValidWeightedMNsCount() / 10)); obj.pushKV("fundingthreshold", int(CHECK_NONFATAL(node.dmnman)->GetListAtChainTip().GetValidWeightedMNsCount() / 10));
obj.pushKV("governancebudget", ValueFromAmount(CSuperblock::GetPaymentsLimit(chainman.ActiveChain(), nNextSuperblock))); obj.pushKV("governancebudget", ValueFromAmount(CSuperblock::GetPaymentsLimit(chainman.ActiveChain(), nNextSuperblock)));
return obj; return obj;

View File

@ -19,6 +19,7 @@
#include <rpc/server_util.h> #include <rpc/server_util.h>
#include <rpc/util.h> #include <rpc/util.h>
#include <univalue.h> #include <univalue.h>
#include <util/check.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <validation.h> #include <validation.h>
#include <wallet/coincontrol.h> #include <wallet/coincontrol.h>
@ -138,8 +139,7 @@ static RPCHelpMan masternode_winner()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman); return GetNextMasternodeForPayment(chainman.ActiveChain(), *CHECK_NONFATAL(node.dmnman), 10);
return GetNextMasternodeForPayment(chainman.ActiveChain(), *node.dmnman, 10);
}, },
}; };
} }
@ -159,8 +159,7 @@ static RPCHelpMan masternode_current()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman); return GetNextMasternodeForPayment(chainman.ActiveChain(), *CHECK_NONFATAL(node.dmnman), 1);
return GetNextMasternodeForPayment(chainman.ActiveChain(), *node.dmnman, 1);
}, },
}; };
} }
@ -212,7 +211,7 @@ static RPCHelpMan masternode_status()
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{ {
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
CHECK_NONFATAL(node.dmnman);
if (!node.mn_activeman) { if (!node.mn_activeman) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "This node does not run an active masternode."); throw JSONRPCError(RPC_INTERNAL_ERROR, "This node does not run an active masternode.");
} }
@ -221,7 +220,7 @@ static RPCHelpMan masternode_status()
// keep compatibility with legacy status for now (might get deprecated/removed later) // keep compatibility with legacy status for now (might get deprecated/removed later)
mnObj.pushKV("outpoint", node.mn_activeman->GetOutPoint().ToStringShort()); mnObj.pushKV("outpoint", node.mn_activeman->GetOutPoint().ToStringShort());
mnObj.pushKV("service", node.mn_activeman->GetService().ToStringAddrPort()); mnObj.pushKV("service", node.mn_activeman->GetService().ToStringAddrPort());
CDeterministicMNCPtr dmn = node.dmnman->GetListAtChainTip().GetMN(node.mn_activeman->GetProTxHash()); CDeterministicMNCPtr dmn = CHECK_NONFATAL(node.dmnman)->GetListAtChainTip().GetMN(node.mn_activeman->GetProTxHash());
if (dmn) { if (dmn) {
mnObj.pushKV("proTxHash", dmn->proTxHash.ToString()); mnObj.pushKV("proTxHash", dmn->proTxHash.ToString());
mnObj.pushKV("type", std::string(GetMnType(dmn->nType).description)); mnObj.pushKV("type", std::string(GetMnType(dmn->nType).description));
@ -243,12 +242,12 @@ static std::string GetRequiredPaymentsString(CGovernanceManager& govman, const C
if (payee) { if (payee) {
CTxDestination dest; CTxDestination dest;
if (!ExtractDestination(payee->pdmnState->scriptPayout, dest)) { if (!ExtractDestination(payee->pdmnState->scriptPayout, dest)) {
CHECK_NONFATAL(false); NONFATAL_UNREACHABLE();
} }
strPayments = EncodeDestination(dest); strPayments = EncodeDestination(dest);
if (payee->nOperatorReward != 0 && payee->pdmnState->scriptOperatorPayout != CScript()) { if (payee->nOperatorReward != 0 && payee->pdmnState->scriptOperatorPayout != CScript()) {
if (!ExtractDestination(payee->pdmnState->scriptOperatorPayout, dest)) { if (!ExtractDestination(payee->pdmnState->scriptOperatorPayout, dest)) {
CHECK_NONFATAL(false); NONFATAL_UNREACHABLE();
} }
strPayments += ", " + EncodeDestination(dest); strPayments += ", " + EncodeDestination(dest);
} }
@ -310,14 +309,11 @@ static RPCHelpMan masternode_winners()
int nChainTipHeight = pindexTip->nHeight; int nChainTipHeight = pindexTip->nHeight;
int nStartHeight = std::max(nChainTipHeight - nCount, 1); int nStartHeight = std::max(nChainTipHeight - nCount, 1);
CHECK_NONFATAL(node.dmnman); const auto tip_mn_list = CHECK_NONFATAL(node.dmnman)->GetListAtChainTip();
CHECK_NONFATAL(node.govman);
const auto tip_mn_list = node.dmnman->GetListAtChainTip();
for (int h = nStartHeight; h <= nChainTipHeight; h++) { for (int h = nStartHeight; h <= nChainTipHeight; h++) {
const CBlockIndex* pIndex = pindexTip->GetAncestor(h - 1); const CBlockIndex* pIndex = pindexTip->GetAncestor(h - 1);
auto payee = node.dmnman->GetListForBlock(pIndex).GetMNPayee(pIndex); auto payee = node.dmnman->GetListForBlock(pIndex).GetMNPayee(pIndex);
std::string strPayments = GetRequiredPaymentsString(*node.govman, tip_mn_list, h, payee); std::string strPayments = GetRequiredPaymentsString(*CHECK_NONFATAL(node.govman), tip_mn_list, h, payee);
if (strFilter != "" && strPayments.find(strFilter) == std::string::npos) continue; if (strFilter != "" && strPayments.find(strFilter) == std::string::npos) continue;
obj.pushKV(strprintf("%d", h), strPayments); obj.pushKV(strprintf("%d", h), strPayments);
} }
@ -558,11 +554,10 @@ static RPCHelpMan masternodelist_helper(bool is_composite)
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
CHECK_NONFATAL(node.dmnman);
UniValue obj(UniValue::VOBJ); UniValue obj(UniValue::VOBJ);
const auto mnList = node.dmnman->GetListAtChainTip(); const auto mnList = CHECK_NONFATAL(node.dmnman)->GetListAtChainTip();
const auto dmnToStatus = [&](const auto& dmn) { const auto dmnToStatus = [&](const auto& dmn) {
if (mnList.IsMNValid(dmn)) { if (mnList.IsMNValid(dmn)) {
return "ENABLED"; return "ENABLED";

View File

@ -36,6 +36,7 @@
#include <spork.h> #include <spork.h>
#include <txmempool.h> #include <txmempool.h>
#include <univalue.h> #include <univalue.h>
#include <util/check.h>
#include <util/fees.h> #include <util/fees.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/string.h> #include <util/string.h>
@ -391,12 +392,11 @@ static RPCHelpMan generateblock()
block.vtx.insert(block.vtx.end(), txs.begin(), txs.end()); block.vtx.insert(block.vtx.end(), txs.begin(), txs.end());
{ {
CHECK_NONFATAL(node.evodb);
LOCK(cs_main); LOCK(cs_main);
BlockValidationState state; BlockValidationState state;
if (!TestBlockValidity(state, *llmq_ctx.clhandler, *node.evodb, chainparams, active_chainstate, block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), false, false)) { if (!TestBlockValidity(state, *llmq_ctx.clhandler, *CHECK_NONFATAL(node.evodb), chainparams, active_chainstate,
block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), false, false)) {
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.GetRejectReason())); throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.GetRejectReason()));
} }
} }
@ -710,14 +710,14 @@ static RPCHelpMan getblocktemplate()
} }
LLMQContext& llmq_ctx = EnsureLLMQContext(node); LLMQContext& llmq_ctx = EnsureLLMQContext(node);
CHECK_NONFATAL(node.evodb);
CBlockIndex* const pindexPrev = active_chain.Tip(); CBlockIndex* const pindexPrev = active_chain.Tip();
// TestBlockValidity only supports blocks built on the current Tip // TestBlockValidity only supports blocks built on the current Tip
if (block.hashPrevBlock != pindexPrev->GetBlockHash()) if (block.hashPrevBlock != pindexPrev->GetBlockHash())
return "inconclusive-not-best-prevblk"; return "inconclusive-not-best-prevblk";
BlockValidationState state; BlockValidationState state;
TestBlockValidity(state, *llmq_ctx.clhandler, *node.evodb, Params(), active_chainstate, block, pindexPrev, false, true); TestBlockValidity(state, *llmq_ctx.clhandler, *CHECK_NONFATAL(node.evodb), Params(), active_chainstate,
block, pindexPrev, false, true);
return BIP22ValidationResult(state); return BIP22ValidationResult(state);
} }

View File

@ -1194,9 +1194,8 @@ static RPCHelpMan mockscheduler()
throw std::runtime_error("delta_time must be between 1 and 3600 seconds (1 hr)"); throw std::runtime_error("delta_time must be between 1 and 3600 seconds (1 hr)");
} }
auto* node_context = GetContext<NodeContext>(request.context); auto* node_context = CHECK_NONFATAL(GetContext<NodeContext>(request.context));
// protect against null pointer dereference // protect against null pointer dereference
CHECK_NONFATAL(node_context);
CHECK_NONFATAL(node_context->scheduler); CHECK_NONFATAL(node_context->scheduler);
node_context->scheduler->MockForward(std::chrono::seconds(delta_seconds)); node_context->scheduler->MockForward(std::chrono::seconds(delta_seconds));

View File

@ -11,6 +11,7 @@
#include <rpc/server.h> #include <rpc/server.h>
#include <rpc/server_util.h> #include <rpc/server_util.h>
#include <rpc/util.h> #include <rpc/util.h>
#include <util/check.h>
#include <validation.h> #include <validation.h>
#include <masternode/node.h> #include <masternode/node.h>
@ -282,7 +283,6 @@ static RPCHelpMan quorum_dkgstatus()
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node); const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
const CConnman& connman = EnsureConnman(node); const CConnman& connman = EnsureConnman(node);
CHECK_NONFATAL(node.dmnman);
CHECK_NONFATAL(node.sporkman); CHECK_NONFATAL(node.sporkman);
int detailLevel = 0; int detailLevel = 0;
@ -296,7 +296,7 @@ static RPCHelpMan quorum_dkgstatus()
llmq::CDKGDebugStatus status; llmq::CDKGDebugStatus status;
llmq_ctx.dkg_debugman->GetLocalDebugStatus(status); llmq_ctx.dkg_debugman->GetLocalDebugStatus(status);
auto ret = status.ToJson(*node.dmnman, chainman, detailLevel); auto ret = status.ToJson(*CHECK_NONFATAL(node.dmnman), chainman, detailLevel);
CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip()); CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
int tipHeight = pindexTip->nHeight; int tipHeight = pindexTip->nHeight;
@ -385,7 +385,6 @@ static RPCHelpMan quorum_memberof()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node); const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
CHECK_NONFATAL(node.dmnman);
uint256 protxHash(ParseHashV(request.params[0], "proTxHash")); uint256 protxHash(ParseHashV(request.params[0], "proTxHash"));
int scanQuorumsCount = -1; int scanQuorumsCount = -1;
@ -397,7 +396,7 @@ static RPCHelpMan quorum_memberof()
} }
const CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip()); const CBlockIndex* pindexTip = WITH_LOCK(cs_main, return chainman.ActiveChain().Tip());
auto mnList = node.dmnman->GetListForBlock(pindexTip); auto mnList = CHECK_NONFATAL(node.dmnman)->GetListForBlock(pindexTip);
auto dmn = mnList.GetMN(protxHash); auto dmn = mnList.GetMN(protxHash);
if (!dmn) { if (!dmn) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "masternode not found"); throw JSONRPCError(RPC_INVALID_PARAMETER, "masternode not found");
@ -842,7 +841,7 @@ static RPCHelpMan quorum_rotationinfo()
const NodeContext& node = EnsureAnyNodeContext(request.context); const NodeContext& node = EnsureAnyNodeContext(request.context);
const ChainstateManager& chainman = EnsureChainman(node); const ChainstateManager& chainman = EnsureChainman(node);
const LLMQContext& llmq_ctx = EnsureLLMQContext(node); const LLMQContext& llmq_ctx = EnsureLLMQContext(node);
CHECK_NONFATAL(node.dmnman); ;
llmq::CGetQuorumRotationInfo cmd; llmq::CGetQuorumRotationInfo cmd;
llmq::CQuorumRotationInfo quorumRotationInfoRet; llmq::CQuorumRotationInfo quorumRotationInfoRet;
@ -859,7 +858,8 @@ static RPCHelpMan quorum_rotationinfo()
LOCK(cs_main); LOCK(cs_main);
if (!BuildQuorumRotationInfo(*node.dmnman, chainman, *llmq_ctx.qman, *llmq_ctx.quorum_block_processor, cmd, quorumRotationInfoRet, strError)) { if (!BuildQuorumRotationInfo(*CHECK_NONFATAL(node.dmnman), chainman, *llmq_ctx.qman, *llmq_ctx.quorum_block_processor,
cmd, quorumRotationInfoRet, strError)) {
throw JSONRPCError(RPC_INVALID_REQUEST, strError); throw JSONRPCError(RPC_INVALID_REQUEST, strError);
} }
@ -1073,7 +1073,8 @@ static RPCHelpMan verifyislock()
auto llmqType = Params().GetConsensus().llmqTypeDIP0024InstantSend; auto llmqType = Params().GetConsensus().llmqTypeDIP0024InstantSend;
const auto llmq_params_opt = Params().GetLLMQ(llmqType); const auto llmq_params_opt = Params().GetLLMQ(llmqType);
CHECK_NONFATAL(llmq_params_opt.has_value()); CHECK_NONFATAL(llmq_params_opt.has_value());
return VerifyRecoveredSigLatestQuorums(*llmq_params_opt, chainman.ActiveChain(), *llmq_ctx.qman, signHeight, id, txid, sig); return VerifyRecoveredSigLatestQuorums(*llmq_params_opt, chainman.ActiveChain(), *CHECK_NONFATAL(llmq_ctx.qman),
signHeight, id, txid, sig);
}, },
}; };
} }

View File

@ -38,6 +38,7 @@
#include <txmempool.h> #include <txmempool.h>
#include <uint256.h> #include <uint256.h>
#include <util/bip32.h> #include <util/bip32.h>
#include <util/check.h>
#include <util/moneystr.h> #include <util/moneystr.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/string.h> #include <util/string.h>
@ -495,8 +496,6 @@ static RPCHelpMan getassetunlockstatuses()
throw JSONRPCError(RPC_INTERNAL_ERROR, "No blocks in chain"); throw JSONRPCError(RPC_INTERNAL_ERROR, "No blocks in chain");
} }
CHECK_NONFATAL(node.cpoolman);
std::optional<CCreditPool> poolCL{std::nullopt}; std::optional<CCreditPool> poolCL{std::nullopt};
std::optional<CCreditPool> poolOnTip{std::nullopt}; std::optional<CCreditPool> poolOnTip{std::nullopt};
std::optional<int> nSpecificCoreHeight{std::nullopt}; std::optional<int> nSpecificCoreHeight{std::nullopt};
@ -506,7 +505,7 @@ static RPCHelpMan getassetunlockstatuses()
if (nSpecificCoreHeight.value() < 0 || nSpecificCoreHeight.value() > chainman.ActiveChain().Height()) { if (nSpecificCoreHeight.value() < 0 || nSpecificCoreHeight.value() > chainman.ActiveChain().Height()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range");
} }
poolCL = std::make_optional(node.cpoolman->GetCreditPool(chainman.ActiveChain()[nSpecificCoreHeight.value()], Params().GetConsensus())); poolCL = std::make_optional(CHECK_NONFATAL(node.cpoolman)->GetCreditPool(chainman.ActiveChain()[nSpecificCoreHeight.value()], Params().GetConsensus()));
} }
else { else {
const auto pBlockIndexBestCL = [&]() -> const CBlockIndex* { const auto pBlockIndexBestCL = [&]() -> const CBlockIndex* {

View File

@ -10,6 +10,7 @@
#include <script/descriptor.h> #include <script/descriptor.h>
#include <script/signingprovider.h> #include <script/signingprovider.h>
#include <tinyformat.h> #include <tinyformat.h>
#include <util/check.h>
#include <util/system.h> #include <util/system.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/string.h> #include <util/string.h>
@ -494,7 +495,7 @@ RPCHelpMan::RPCHelpMan(std::string name, std::string description, std::vector<RP
// Null values are accepted in all arguments // Null values are accepted in all arguments
break; break;
default: default:
CHECK_NONFATAL(false); NONFATAL_UNREACHABLE();
break; break;
} }
} }
@ -743,7 +744,7 @@ void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const
return; return;
} }
case Type::ANY: { case Type::ANY: {
CHECK_NONFATAL(false); // Only for testing NONFATAL_UNREACHABLE(); // Only for testing
} }
case Type::NONE: { case Type::NONE: {
sections.PushSection({indent + "null" + maybe_separator, Description("json null")}); sections.PushSection({indent + "null" + maybe_separator, Description("json null")});
@ -807,7 +808,7 @@ void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const
return; return;
} }
} // no default case, so the compiler can warn about missing cases } // no default case, so the compiler can warn about missing cases
CHECK_NONFATAL(false); NONFATAL_UNREACHABLE();
} }
bool RPCResult::MatchesType(const UniValue& result) const bool RPCResult::MatchesType(const UniValue& result) const
@ -843,7 +844,7 @@ bool RPCResult::MatchesType(const UniValue& result) const
return UniValue::VOBJ == result.getType(); return UniValue::VOBJ == result.getType();
} }
} // no default case, so the compiler can warn about missing cases } // no default case, so the compiler can warn about missing cases
CHECK_NONFATAL(false); NONFATAL_UNREACHABLE();
} }
std::string RPCArg::ToStringObj(const bool oneline) const std::string RPCArg::ToStringObj(const bool oneline) const
@ -878,9 +879,9 @@ std::string RPCArg::ToStringObj(const bool oneline) const
case Type::OBJ: case Type::OBJ:
case Type::OBJ_USER_KEYS: case Type::OBJ_USER_KEYS:
// Currently unused, so avoid writing dead code // Currently unused, so avoid writing dead code
CHECK_NONFATAL(false); NONFATAL_UNREACHABLE();
} // no default case, so the compiler can warn about missing cases } // no default case, so the compiler can warn about missing cases
CHECK_NONFATAL(false); NONFATAL_UNREACHABLE();
} }
std::string RPCArg::ToString(const bool oneline) const std::string RPCArg::ToString(const bool oneline) const
@ -915,7 +916,7 @@ std::string RPCArg::ToString(const bool oneline) const
return "[" + res + "...]"; return "[" + res + "...]";
} }
} // no default case, so the compiler can warn about missing cases } // no default case, so the compiler can warn about missing cases
CHECK_NONFATAL(false); NONFATAL_UNREACHABLE();
} }
static std::pair<int64_t, int64_t> ParseRange(const UniValue& value) static std::pair<int64_t, int64_t> ParseRange(const UniValue& value)

View File

@ -18,8 +18,24 @@ class NonFatalCheckError : public std::runtime_error
using std::runtime_error::runtime_error; using std::runtime_error::runtime_error;
}; };
#define format_internal_error(msg, file, line, func, report) \
strprintf("Internal bug detected: \"%s\"\n%s:%d (%s)\nPlease report this issue here: %s\n", \
msg, file, line, func, report)
/** Helper for CHECK_NONFATAL() */
template <typename T>
T&& inline_check_non_fatal(T&& val, const char* file, int line, const char* func, const char* assertion)
{
if (!(val)) {
throw NonFatalCheckError(
format_internal_error(assertion, file, line, func, PACKAGE_BUGREPORT));
}
return std::forward<T>(val);
}
/** /**
* Throw a NonFatalCheckError when the condition evaluates to false * Identity function. Throw a NonFatalCheckError when the condition evaluates to false
* *
* This should only be used * This should only be used
* - where the condition is assumed to be true, not for error handling or validating user input * - where the condition is assumed to be true, not for error handling or validating user input
@ -29,18 +45,8 @@ class NonFatalCheckError : public std::runtime_error
* asserts or recoverable logic errors. A NonFatalCheckError in RPC code is caught and passed as a string to the RPC * asserts or recoverable logic errors. A NonFatalCheckError in RPC code is caught and passed as a string to the RPC
* caller, which can then report the issue to the developers. * caller, which can then report the issue to the developers.
*/ */
#define CHECK_NONFATAL(condition) \ #define CHECK_NONFATAL(condition) \
do { \ inline_check_non_fatal(condition, __FILE__, __LINE__, __func__, #condition)
if (!(condition)) { \
throw NonFatalCheckError( \
strprintf("Internal bug detected: '%s'\n" \
"%s:%d (%s)\n" \
"You may report this issue here: %s\n", \
(#condition), \
__FILE__, __LINE__, __func__, \
PACKAGE_BUGREPORT)); \
} \
} while (false)
#if defined(NDEBUG) #if defined(NDEBUG)
#error "Cannot compile without assertions!" #error "Cannot compile without assertions!"
@ -80,4 +86,13 @@ T&& inline_assertion_check(T&& val, [[maybe_unused]] const char* file, [[maybe_u
*/ */
#define Assume(val) inline_assertion_check<false>(val, __FILE__, __LINE__, __func__, #val) #define Assume(val) inline_assertion_check<false>(val, __FILE__, __LINE__, __func__, #val)
/**
* NONFATAL_UNREACHABLE() is a macro that is used to mark unreachable code. It throws a NonFatalCheckError.
* This is used to mark code that is not yet implemented or is not yet reachable.
*/
#define NONFATAL_UNREACHABLE() \
throw NonFatalCheckError( \
format_internal_error("Unreachable code reached (non-fatal)", \
__FILE__, __LINE__, __func__, PACKAGE_BUGREPORT))
#endif // BITCOIN_UTIL_CHECK_H #endif // BITCOIN_UTIL_CHECK_H

View File

@ -1135,7 +1135,7 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
case TxoutType::NONSTANDARD: case TxoutType::NONSTANDARD:
return "unrecognized script"; return "unrecognized script";
} // no default case, so the compiler can warn about missing cases } // no default case, so the compiler can warn about missing cases
CHECK_NONFATAL(false); NONFATAL_UNREACHABLE();
} }
static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool& have_solving_data, const UniValue& data, std::vector<CKeyID>& ordered_pubkeys) static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool& have_solving_data, const UniValue& data, std::vector<CKeyID>& ordered_pubkeys)

View File

@ -27,7 +27,7 @@ class RpcMiscTest(BitcoinTestFramework):
self.log.info("test CHECK_NONFATAL") self.log.info("test CHECK_NONFATAL")
assert_raises_rpc_error( assert_raises_rpc_error(
-1, -1,
'Internal bug detected: \'request.params[9].get_str() != "trigger_internal_bug"\'', 'Internal bug detected: "request.params[9].get_str() != "trigger_internal_bug""',
lambda: node.echo(arg9='trigger_internal_bug'), lambda: node.echo(arg9='trigger_internal_bug'),
) )