From 1204a72304aeef71b7ba5d525ca27a0638fcfd61 Mon Sep 17 00:00:00 2001 From: psolstice Date: Tue, 21 Nov 2023 09:48:50 +0100 Subject: [PATCH] Spark runaway exceptions (#1344) * Avoid catch(...) when possible * Add wrappers around major sigma/lelantus/spark calls to catch exceptions * Catch exception thrown from CheckLelantusJMintTransaction * Bug fix * Fixed tests * Disable failing elysium test --- src/batchproof_container.cpp | 6 ++-- src/bip47/account.cpp | 2 +- src/bip47/bip47utils.cpp | 2 +- src/chainparams.cpp | 6 ++-- src/hdmint/tracker.cpp | 4 +-- src/hdmint/wallet.cpp | 2 +- src/lelantus.cpp | 51 ++++++++++++++++++----------- src/liblelantus/lelantus_prover.cpp | 2 +- src/libspark/coin.cpp | 4 +-- src/libspark/hash.cpp | 4 +-- src/libspark/transcript.cpp | 2 +- src/libspark/util.cpp | 2 +- src/rpc/rawtransaction.cpp | 4 +-- src/sigma.cpp | 24 ++++++++++---- src/spark/sparkwallet.cpp | 10 +++--- src/spark/state.cpp | 44 +++++++++++++++---------- src/test/lelantus_state_tests.cpp | 3 -- src/validation.cpp | 31 +++++++++++------- src/wallet/rpcwallet.cpp | 16 ++++----- src/wallet/wallet.cpp | 26 +++++++-------- 20 files changed, 141 insertions(+), 104 deletions(-) diff --git a/src/batchproof_container.cpp b/src/batchproof_container.cpp index 9b89c69b25..d82e4638ea 100644 --- a/src/batchproof_container.cpp +++ b/src/batchproof_container.cpp @@ -213,7 +213,7 @@ void BatchProofContainer::batch_sigma() { try { if (!sigmaVerifier.batch_verify(anonymity_set, serials, fPadding, setSizes, proofs)) return false; - } catch (...) { + } catch (const std::exception &) { return false; } return true; @@ -316,7 +316,7 @@ void BatchProofContainer::batch_lelantus() { try { if (!sigmaVerifier.batchverify(anonymity_set, challenges, serials, setSizes, proofs)) return false; - } catch (...) { + } catch (const std::exception &) { return false; } return true; @@ -431,7 +431,7 @@ void BatchProofContainer::batch_spark() { bool passed; try { passed = spark::SpendTransaction::verify(params, sparkTransactions, cover_sets); - } catch (...) { + } catch (const std::exception &) { passed = false; } diff --git a/src/bip47/account.cpp b/src/bip47/account.cpp index 09ef4ce7b2..adb0c7fac6 100644 --- a/src/bip47/account.cpp +++ b/src/bip47/account.cpp @@ -254,7 +254,7 @@ bool CAccountReceiver::acceptMaskedPayload(std::vector const & ma std::unique_ptr jsplit; try { jsplit = lelantus::ParseLelantusJoinSplit(tx); - }catch (...) { + }catch (const std::exception &) { return false; } if (!jsplit) diff --git a/src/bip47/bip47utils.cpp b/src/bip47/bip47utils.cpp index 6b2e482e0d..8dacc6359b 100644 --- a/src/bip47/bip47utils.cpp +++ b/src/bip47/bip47utils.cpp @@ -170,7 +170,7 @@ GroupElement GeFromPubkey(CPubKey const & pubKey) serializedGe.push_back(0x0); try { result.deserialize(&serializedGe[0]); - } catch (...) { + } catch (const std::exception &) { result = GroupElement(); } return result; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index d0f497ba5e..2b328599f3 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -426,7 +426,7 @@ class CMainParams : public CChainParams { GroupElement coin; try { coin.deserialize(ParseHex(str).data()); - } catch (...) { + } catch (const std::exception &) { continue; } consensus.lelantusBlacklist.insert(coin); @@ -436,7 +436,7 @@ class CMainParams : public CChainParams { GroupElement coin; try { coin.deserialize(ParseHex(str).data()); - } catch (...) { + } catch (const std::exception &) { continue; } consensus.sigmaBlacklist.insert(coin); @@ -735,7 +735,7 @@ class CTestNetParams : public CChainParams { GroupElement coin; try { coin.deserialize(ParseHex(str).data()); - } catch (...) { + } catch (const std::exception &) { continue; } consensus.lelantusBlacklist.insert(coin); diff --git a/src/hdmint/tracker.cpp b/src/hdmint/tracker.cpp index 068563cb97..1a26322d2b 100644 --- a/src/hdmint/tracker.cpp +++ b/src/hdmint/tracker.cpp @@ -546,7 +546,7 @@ bool CHDMintTracker::IsMempoolSpendOurs(const std::set& setMempool, con uint32_t pubcoinId; try { std::tie(spend, pubcoinId) = sigma::ParseSigmaSpend(txin); - } catch (...) { + } catch (const std::exception &) { return false; } @@ -560,7 +560,7 @@ bool CHDMintTracker::IsMempoolSpendOurs(const std::set& setMempool, con std::unique_ptr joinsplit; try { joinsplit = lelantus::ParseLelantusJoinSplit(tx); - } catch (...) { + } catch (const std::exception &) { return false; } diff --git a/src/hdmint/wallet.cpp b/src/hdmint/wallet.cpp index 0f59316ff9..81a6172eda 100644 --- a/src/hdmint/wallet.cpp +++ b/src/hdmint/wallet.cpp @@ -1183,7 +1183,7 @@ bool CHDMintWallet::TxOutToPublicCoin(const CTxOut& txout, sigma::PublicCoin& pu secp_primitives::GroupElement publicSigma; try { publicSigma.deserialize(&coin_serialised[0]); - } catch (...) { + } catch (const std::exception &) { return state.DoS(100, error("TxOutToPublicCoin : deserialize failed")); } diff --git a/src/lelantus.cpp b/src/lelantus.cpp index 10f0870e1f..95e45e2fab 100644 --- a/src/lelantus.cpp +++ b/src/lelantus.cpp @@ -402,7 +402,7 @@ bool CheckLelantusJoinSplitTransaction( REJECT_MALFORMED, "CheckLelantusJoinSplitTransaction: invalid joinsplit transaction"); } - catch (...) { + catch (const std::exception &) { return state.DoS(100, false, REJECT_MALFORMED, @@ -444,8 +444,13 @@ bool CheckLelantusJoinSplitTransaction( for (const CTxOut &txout : tx.vout) { if (!txout.scriptPubKey.empty() && txout.scriptPubKey.IsLelantusJMint()) { - if (!CheckLelantusJMintTransaction(txout, state, hashTx, fStatefulSigmaCheck, Cout, lelantusTxInfo)) - return false; + try { + if (!CheckLelantusJMintTransaction(txout, state, hashTx, fStatefulSigmaCheck, Cout, lelantusTxInfo)) + return false; + } + catch (const std::exception &x) { + return state.Error(x.what()); + } } else if(txout.scriptPubKey.IsLelantusMint()) { return false; //putting regular mints at JoinSplit transactions is not allowed } else { @@ -774,8 +779,13 @@ bool CheckLelantusTransaction( if (allowLelantus && !isVerifyDB) { for (const CTxOut &txout : tx.vout) { if (!txout.scriptPubKey.empty() && txout.scriptPubKey.IsLelantusMint()) { - if (!CheckLelantusMintTransaction(txout, state, hashTx, fStatefulSigmaCheck, lelantusTxInfo)) - return false; + try { + if (!CheckLelantusMintTransaction(txout, state, hashTx, fStatefulSigmaCheck, lelantusTxInfo)) + return false; + } + catch (const std::exception &x) { + return state.Error(x.what()); + } } } } @@ -796,10 +806,15 @@ bool CheckLelantusTransaction( } if (!isVerifyDB) { - if (!CheckLelantusJoinSplitTransaction( - tx, state, hashTx, isVerifyDB, nHeight, realHeight, - isCheckWallet, fStatefulSigmaCheck, sigmaTxInfo, lelantusTxInfo)) { - return false; + try { + if (!CheckLelantusJoinSplitTransaction( + tx, state, hashTx, isVerifyDB, nHeight, realHeight, + isCheckWallet, fStatefulSigmaCheck, sigmaTxInfo, lelantusTxInfo)) { + return false; + } + } + catch (const std::exception &x) { + return state.Error(x.what()); } } } @@ -822,7 +837,7 @@ void RemoveLelantusJoinSplitReferencingBlock(CTxMemPool& pool, CBlockIndex* bloc try { joinsplit = ParseLelantusJoinSplit(tx); } - catch (...) { + catch (const std::exception &) { txn_to_remove.push_back(tx); break; } @@ -861,7 +876,7 @@ std::vector GetLelantusJoinSplitSerialNumbers(const CTransaction &tx, co try { return ParseLelantusJoinSplit(tx)->getCoinSerialNumbers(); } - catch (...) { + catch (const std::exception &) { return std::vector(); } } @@ -873,7 +888,7 @@ std::vector GetLelantusJoinSplitIds(const CTransaction &tx, const CTxI try { return ParseLelantusJoinSplit(tx)->getCoinGroupIds(); } - catch (...) { + catch (const std::exception &) { return std::vector(); } } @@ -1015,7 +1030,7 @@ bool GetOutPointFromBlock(COutPoint& outPoint, const GroupElement &pubCoinValue, try { ParseLelantusMintScript(txout.scriptPubKey, txPubCoinValue); } - catch (...) { + catch (const std::exception &) { continue; } if(pubCoinValue==txPubCoinValue){ @@ -1140,13 +1155,11 @@ void CLelantusState::Containers::RemoveMint(lelantus::PublicCoin const & pubCoin } void CLelantusState::Containers::AddSpend(Scalar const & serial, int coinGroupId) { - if (!mintMetaInfo.count(coinGroupId)) { - throw std::invalid_argument("group id doesn't exist"); + if (mintMetaInfo.count(coinGroupId) > 0) { + usedCoinSerials[serial] = coinGroupId; + spendMetaInfo[coinGroupId] += 1; + CheckSurgeCondition(); } - - usedCoinSerials[serial] = coinGroupId; - spendMetaInfo[coinGroupId] += 1; - CheckSurgeCondition(); } void CLelantusState::Containers::RemoveSpend(Scalar const & serial) { diff --git a/src/liblelantus/lelantus_prover.cpp b/src/liblelantus/lelantus_prover.cpp index 96d908b676..3154b51ea6 100644 --- a/src/liblelantus/lelantus_prover.cpp +++ b/src/liblelantus/lelantus_prover.cpp @@ -155,7 +155,7 @@ void LelantusProver::generate_sigma_proofs( parallelTasks.emplace_back(threadPool.PostTask([&]() { try { prover.sigma_commit(commits, index, rA_i, rB_i, rC_i, rD_i, a_i, Tk_i, Pk_i, Yk_i, sigma_i, proof); - } catch (...) { + } catch (const std::exception &) { return false; } return true; diff --git a/src/libspark/coin.cpp b/src/libspark/coin.cpp index d97040d4f2..b7d87fd89b 100644 --- a/src/libspark/coin.cpp +++ b/src/libspark/coin.cpp @@ -130,7 +130,7 @@ IdentifiedCoinData Coin::identify(const IncomingViewKey& incoming_view_key) { // Decrypt recipient data CDataStream stream = AEAD::decrypt_and_verify(this->K*incoming_view_key.get_s1(), "Mint coin data", this->r_); stream >> r; - } catch (...) { + } catch (const std::exception &) { throw std::runtime_error("Unable to identify coin"); } @@ -151,7 +151,7 @@ IdentifiedCoinData Coin::identify(const IncomingViewKey& incoming_view_key) { // Decrypt recipient data CDataStream stream = AEAD::decrypt_and_verify(this->K*incoming_view_key.get_s1(), "Spend coin data", this->r_); stream >> r; - } catch (...) { + } catch (const std::exception &) { throw std::runtime_error("Unable to identify coin"); } diff --git a/src/libspark/hash.cpp b/src/libspark/hash.cpp index c37d29a1ea..2c6d71317d 100644 --- a/src/libspark/hash.cpp +++ b/src/libspark/hash.cpp @@ -83,7 +83,7 @@ Scalar Hash::finalize_scalar() { EVP_MD_CTX_free(state_finalize); return candidate; - } catch (...) { + } catch (const std::exception &) { counter++; } } @@ -144,7 +144,7 @@ GroupElement Hash::finalize_group() { EVP_MD_CTX_free(state_finalize); return candidate; - } catch (...) { + } catch (const std::exception &) { counter++; } } diff --git a/src/libspark/transcript.cpp b/src/libspark/transcript.cpp index 8cada15b2e..5cd67c63c0 100644 --- a/src/libspark/transcript.cpp +++ b/src/libspark/transcript.cpp @@ -139,7 +139,7 @@ Scalar Transcript::challenge(const std::string label) { EVP_MD_CTX_free(state_finalize); return candidate; - } catch (...) { + } catch (const std::exception &) { counter++; } } diff --git a/src/libspark/util.cpp b/src/libspark/util.cpp index f33310ef85..db80b32606 100644 --- a/src/libspark/util.cpp +++ b/src/libspark/util.cpp @@ -131,7 +131,7 @@ GroupElement SparkUtils::hash_generator(const std::string label) { EVP_MD_CTX_free(state_finalize); return candidate; - } catch (...) { + } catch (const std::exception &) { counter++; } } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 38606f55ed..c2fe430098 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -127,7 +127,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) try { jsplit = lelantus::ParseLelantusJoinSplit(tx); } - catch (...) { + catch (const std::exception &) { continue; } in.push_back(Pair("nFees", ValueFromAmount(jsplit->getFee()))); @@ -143,7 +143,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) try { sparkSpend = std::make_unique(spark::ParseSparkSpend(tx)); } - catch (...) { + catch (const std::exception &) { continue; } in.push_back(Pair("nFees", ValueFromAmount(sparkSpend->getFee()))); diff --git a/src/sigma.cpp b/src/sigma.cpp index 5b9d27b111..36c9a1e044 100644 --- a/src/sigma.cpp +++ b/src/sigma.cpp @@ -457,8 +457,13 @@ bool CheckSigmaTransaction( if (allowSigma) { for (const CTxOut &txout : tx.vout) { if (!txout.scriptPubKey.empty() && txout.scriptPubKey.IsSigmaMint()) { - if (!CheckSigmaMintTransaction(txout, state, hashTx, fStatefulSigmaCheck, sigmaTxInfo)) - return false; + try { + if (!CheckSigmaMintTransaction(txout, state, hashTx, fStatefulSigmaCheck, sigmaTxInfo)) + return false; + } + catch (const std::exception &x) { + return state.Error(x.what()); + } } } } @@ -508,10 +513,15 @@ bool CheckSigmaTransaction( // Check vOut // Only one loop, we checked on the format before entering this case if (!isVerifyDB) { - if (!CheckSigmaSpendTransaction( - tx, denominations, state, hashTx, isVerifyDB, nHeight, realHeight, - isCheckWallet, fStatefulSigmaCheck, sigmaTxInfo)) { - return false; + try { + if (!CheckSigmaSpendTransaction( + tx, denominations, state, hashTx, isVerifyDB, nHeight, realHeight, + isCheckWallet, fStatefulSigmaCheck, sigmaTxInfo)) { + return false; + } + } + catch (const std::exception &x) { + return state.Error(x.what()); } } } @@ -667,7 +677,7 @@ bool GetOutPointFromBlock(COutPoint& outPoint, const GroupElement &pubCoinValue, txout.scriptPubKey.end()); try { txPubCoinValue.deserialize(&coin_serialised[0]); - } catch (...) { + } catch (const std::exception &) { return false; } if(pubCoinValue==txPubCoinValue){ diff --git a/src/spark/sparkwallet.cpp b/src/spark/sparkwallet.cpp index 73552c7a90..6069417378 100644 --- a/src/spark/sparkwallet.cpp +++ b/src/spark/sparkwallet.cpp @@ -260,7 +260,7 @@ bool CSparkWallet::isAddressMine(const std::string& encodedAddr) { spark::Address address(params); try { address.decode(encodedAddr); - } catch (...) { + } catch (const std::exception &) { return false; } @@ -273,7 +273,7 @@ bool CSparkWallet::isAddressMine(const std::string& encodedAddr) { try { d = viewKey.get_diversifier(address.get_d()); - } catch (...) { + } catch (const std::exception &) { return false; } @@ -437,7 +437,7 @@ bool CSparkWallet::getMintAmount(spark::Coin coin, CAmount& amount) { spark::IdentifiedCoinData identifiedCoinData; try { identifiedCoinData = coin.identify(this->viewKey); - } catch (...) { + } catch (const std::exception &) { return false; } amount = identifiedCoinData.v; @@ -501,7 +501,7 @@ void CSparkWallet::UpdateSpendStateFromBlock(const CBlock& block) { uint256 lTagHash = primitives::GetLTagHash(txLTag); UpdateSpendState(txLTag, lTagHash, txHash); } - } catch (...) { + } catch (const std::exception &) { } } } @@ -511,7 +511,7 @@ void CSparkWallet::UpdateSpendStateFromBlock(const CBlock& block) { bool CSparkWallet::isMine(spark::Coin coin) const { try { spark::IdentifiedCoinData identifiedCoinData = coin.identify(this->viewKey); - } catch (...) { + } catch (const std::exception &) { return false; } diff --git a/src/spark/state.cpp b/src/spark/state.cpp index 6e40c65d3f..29a2e47ecc 100644 --- a/src/spark/state.cpp +++ b/src/spark/state.cpp @@ -129,7 +129,7 @@ void ParseSparkMintTransaction(const std::vector& scripts, MintTransact } try { mintTransaction.setMintTransaction(serializedCoins); - } catch (...) { + } catch (const std::exception &) { throw std::invalid_argument("Unable to deserialize Spark mint transaction"); } } @@ -152,7 +152,7 @@ void ParseSparkMintCoin(const CScript& script, spark::Coin& txCoin) try { stream >> txCoin; - } catch (...) { + } catch (const std::exception &) { throw std::invalid_argument("Unable to deserialize Spark mint"); } } @@ -184,7 +184,7 @@ std::vector GetSparkUsedTags(const CTransaction &tx) spark::SpendTransaction spendTransaction(params); try { spendTransaction = ParseSparkSpend(tx); - } catch (...) { + } catch (const std::exception &) { return std::vector(); } @@ -205,7 +205,7 @@ std::vector GetSparkMintCoins(const CTransaction &tx) ParseSparkMintCoin(script, coin); coin.setSerialContext(serial_context); result.push_back(coin); - } catch (...) { + } catch (const std::exception &) { //Continue } } @@ -332,7 +332,7 @@ void RemoveSpendReferencingBlock(CTxMemPool& pool, CBlockIndex* blockIndex) { try { sparkSpend = std::make_unique(ParseSparkSpend(tx)); } - catch (...) { + catch (const std::exception &) { txn_to_remove.push_back(tx); break; } @@ -470,7 +470,7 @@ bool CheckSparkSMintTransaction( spark::Coin coin(Params::get_default()); ParseSparkMintCoin(script, coin); out_coins.push_back(coin); - } catch (...) { + } catch (const std::exception &) { return state.DoS(100, false, REJECT_INVALID, @@ -529,7 +529,7 @@ bool CheckSparkSpendTransaction( REJECT_MALFORMED, "CheckSparkSpendTransaction: invalid spend transaction"); } - catch (...) { + catch (const std::exception &) { return state.DoS(100, false, REJECT_MALFORMED, @@ -653,7 +653,7 @@ bool CheckSparkSpendTransaction( } else { try { passVerify = spark::SpendTransaction::verify(*spend, cover_sets); - } catch (...) { + } catch (const std::exception &) { passVerify = false; } } @@ -730,9 +730,14 @@ bool CheckSparkTransaction( } } if (!txOuts.empty()) { - if (!CheckSparkMintTransaction(txOuts, state, hashTx, fStatefulSigmaCheck, sparkTxInfo)) { - LogPrintf("CheckSparkTransaction::Mint verification failed.\n"); - return false; + try { + if (!CheckSparkMintTransaction(txOuts, state, hashTx, fStatefulSigmaCheck, sparkTxInfo)) { + LogPrintf("CheckSparkTransaction::Mint verification failed.\n"); + return false; + } + } + catch (const std::exception &x) { + return state.Error(x.what()); } } else { return state.DoS(100, false, @@ -750,10 +755,15 @@ bool CheckSparkTransaction( } if (!isVerifyDB) { - if (!CheckSparkSpendTransaction( - tx, state, hashTx, isVerifyDB, nHeight, - isCheckWallet, fStatefulSigmaCheck, sparkTxInfo)) { - return false; + try { + if (!CheckSparkSpendTransaction( + tx, state, hashTx, isVerifyDB, nHeight, + isCheckWallet, fStatefulSigmaCheck, sparkTxInfo)) { + return false; + } + } + catch (const std::exception &x) { + return state.Error(x.what()); } } } @@ -810,7 +820,7 @@ bool GetOutPointFromBlock(COutPoint& outPoint, const spark::Coin& coin, const CB try { ParseSparkMintCoin(txout.scriptPubKey, txCoin); } - catch (...) { + catch (const std::exception &) { continue; } if (coin == txCoin) { @@ -830,7 +840,7 @@ std::vector getSerialContext(const CTransaction &tx) { try { spark::SpendTransaction spend = ParseSparkSpend(tx); serialContextStream << spend.getUsedLTags(); - } catch (...) { + } catch (const std::exception &) { return std::vector(); } } else { diff --git a/src/test/lelantus_state_tests.cpp b/src/test/lelantus_state_tests.cpp index a493271952..a48dc54c0e 100644 --- a/src/test/lelantus_state_tests.cpp +++ b/src/test/lelantus_state_tests.cpp @@ -187,9 +187,6 @@ BOOST_AUTO_TEST_CASE(serial_adding) BOOST_CHECK(!lelantusState->IsUsedCoinSerial(serial2)); BOOST_CHECK(!lelantusState->IsUsedCoinSerialHash(receivedSerial, serialHash2)); - - // add serials to group that doesn't exist, should fail - BOOST_CHECK_THROW(lelantusState->AddSpend(Scalar(1), 100), std::invalid_argument); } BOOST_AUTO_TEST_CASE(mempool) diff --git a/src/validation.cpp b/src/validation.cpp index 1731d8e5d0..79986de31a 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -961,7 +961,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C catch (CBadTxIn&) { return state.Invalid(false, REJECT_CONFLICT, "txn-invalid-lelantus-joinsplit"); } - catch (...) { + catch (const std::exception &) { return state.Invalid(false, REJECT_CONFLICT, "failed to deserialize joinsplit"); } @@ -1004,7 +1004,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C try { sparkUsedLTags = spark::GetSparkUsedTags(tx); } - catch (...) { + catch (const std::exception &) { return state.Invalid(false, REJECT_CONFLICT, "failed to deserialize spark spend"); } @@ -1052,7 +1052,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C try { sparkMintCoins = spark::GetSparkMintCoins(tx); } - catch (...) { + catch (const std::exception &) { return state.Invalid(false, REJECT_CONFLICT, "failed to deserialize spark mint"); } @@ -1248,7 +1248,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C catch (CBadTxIn&) { return state.DoS(0, false, REJECT_INVALID, "unable to parse joinsplit"); } - catch (...) { + catch (const std::exception &) { return state.DoS(0, false, REJECT_INVALID, "failed to deserialize joinsplit"); } } else { @@ -1258,7 +1258,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C catch (CBadTxIn&) { return state.DoS(0, false, REJECT_INVALID, "unable to parse joinsplit"); } - catch (...) { + catch (const std::exception &) { return state.DoS(0, false, REJECT_INVALID, "failed to deserialize joinsplit"); } } @@ -1692,7 +1692,14 @@ bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const { LogPrintf("AcceptToMemoryPool(), transaction: %s\n", tx->GetHash().ToString()); std::vector coins_to_uncache; - bool res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache, isCheckWalletTransaction, markFiroSpendTransactionSerial); + bool res = false; + try { + res = AcceptToMemoryPoolWorker(pool, state, tx, fLimitFree, pfMissingInputs, nAcceptTime, plTxnReplaced, fOverrideMempoolLimit, nAbsurdFee, coins_to_uncache, isCheckWalletTransaction, markFiroSpendTransactionSerial); + } + catch (const std::exception &x) { + state.Error(x.what()); + res = false; + } if (!res) { BOOST_FOREACH(const COutPoint& hashTx, coins_to_uncache) pcoinsTip->Uncache(hashTx); @@ -2184,7 +2191,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins catch (CBadTxIn&) { return state.DoS(0, false, REJECT_INVALID, "unable to parse joinsplit"); } - catch (...) { + catch (const std::exception &) { return state.DoS(0, false, REJECT_INVALID, "failed to deserialize joinsplit"); } } @@ -2621,7 +2628,7 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s try { nFees += lelantus::ParseLelantusJoinSplit(tx)->getFee(); } - catch (...) { + catch (const std::exception &) { // do nothing } } @@ -2629,7 +2636,7 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s try { nFees = spark::ParseSparkSpend(tx).getFee(); } - catch (...) { + catch (const std::exception &) { // do nothing } } @@ -3019,7 +3026,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin catch (CBadTxIn&) { return state.DoS(0, false, REJECT_INVALID, "unable to parse joinsplit"); } - catch (...) { + catch (const std::exception &) { return state.DoS(0, false, REJECT_INVALID, "failed to deserialize joinsplit"); } } @@ -3031,7 +3038,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin catch (CBadTxIn&) { return state.DoS(0, false, REJECT_INVALID, "unable to parse spark spend"); } - catch (...) { + catch (const std::exception &) { return state.DoS(0, false, REJECT_INVALID, "failed to deserialize spark spend"); } } @@ -3600,7 +3607,7 @@ bool static DisconnectTip(CValidationState& state, const CChainParams& chainpara try { joinsplit = lelantus::ParseLelantusJoinSplit(*tx); } - catch (...) { + catch (const std::exception &) { continue; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fc4d3e84d5..7216be91c2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2201,14 +2201,14 @@ UniValue gettransaction(const JSONRPCRequest& request) try { nFee = (0 - lelantus::ParseLelantusJoinSplit(*wtx.tx)->getFee()); } - catch (...) { + catch (const std::exception &) { // do nothing } } else if (wtx.tx->IsSparkSpend()) { try { nFee = (0 - spark::ParseSparkSpend(*wtx.tx).getFee()); } - catch (...) { + catch (const std::exception &) { // do nothing } } @@ -3569,7 +3569,7 @@ UniValue getsparkaddressbalance(const JSONRPCRequest& request) { unsigned char coinNetwork; try { coinNetwork = address.decode(strAddress); - } catch (...) { + } catch (const std::exception &) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Spark address: ")+strAddress); } @@ -3691,7 +3691,7 @@ UniValue mintspark(const JSONRPCRequest& request) unsigned char coinNetwork; try { coinNetwork = address.decode(name_); - } catch (...) { + } catch (const std::exception &) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Spark address: ")+name_); } @@ -3826,7 +3826,7 @@ UniValue spendspark(const JSONRPCRequest& request) isSparkAddress = true; if (coinNetwork != network) throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid address, wrong network type: ")+name_); - } catch (...) { + } catch (const std::exception &) { isSparkAddress = false; } @@ -3900,7 +3900,7 @@ UniValue spendspark(const JSONRPCRequest& request) CWalletTx wtx; try { wtx = pwallet->SpendAndStoreSpark(recipients, privateRecipients, fee); - } catch (...) { + } catch (const std::exception &) { throw JSONRPCError(RPC_WALLET_ERROR, "Spark spend creation failed."); } @@ -3932,7 +3932,7 @@ UniValue lelantustospark(const JSONRPCRequest& request) { bool passed = false; try { passed = pwallet->LelantusToSpark(strFailReason); - } catch (...) { + } catch (const std::exception &) { throw JSONRPCError(RPC_WALLET_ERROR, "Lelantus to Spark failed!"); } if (!passed || strFailReason != "") @@ -4923,7 +4923,7 @@ UniValue listlelantusjoinsplits(const JSONRPCRequest& request) { std::unique_ptr joinsplit; try { joinsplit = lelantus::ParseLelantusJoinSplit(*pwtx->tx); - } catch (...) { + } catch (const std::exception &) { continue; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 17d30648bd..1fc64d8e8f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1506,7 +1506,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) try { joinsplit = lelantus::ParseLelantusJoinSplit(*wtx.tx); } - catch (...) { + catch (const std::exception &) { continue; } @@ -1532,7 +1532,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx) spark::SpendTransaction spend = spark::ParseSparkSpend(*wtx.tx); lTags = spend.getUsedLTags(); } - catch (...) { + catch (const std::exception &) { continue; } @@ -1690,7 +1690,7 @@ isminetype CWallet::IsMine(const CTxIn &txin, const CTransaction& tx) const try { joinsplit = lelantus::ParseLelantusJoinSplit(tx); } - catch (...) { + catch (const std::exception &) { return ISMINE_NO; } @@ -1705,7 +1705,7 @@ isminetype CWallet::IsMine(const CTxIn &txin, const CTransaction& tx) const spark::SpendTransaction spend = spark::ParseSparkSpend(tx); lTags = spend.getUsedLTags(); } - catch (...) { + catch (const std::exception &) { return ISMINE_NO; } if (!sparkWallet) @@ -1763,7 +1763,7 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const CTransaction& tx, const ismin try { joinsplit = lelantus::ParseLelantusJoinSplit(tx); } - catch (...) { + catch (const std::exception &) { goto end; } @@ -1785,7 +1785,7 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const CTransaction& tx, const ismin spark::SpendTransaction spend = spark::ParseSparkSpend(tx); lTags = spend.getUsedLTags(); } - catch (...) { + catch (const std::exception &) { goto end; } if (!sparkWallet) @@ -1947,7 +1947,7 @@ CAmount CWallet::GetChange(const uint256& tx, const CTxOut &txout) const try { spark::ParseSparkMintCoin(txout.scriptPubKey, coin); coin.setSerialContext(serial_context); - } catch (...) { + } catch (const std::exception &) { return 0; } return sparkWallet->getMyCoinV(coin); @@ -2375,14 +2375,14 @@ void CWalletTx::GetAmounts(std::list& listReceived, try { nFee = lelantus::ParseLelantusJoinSplit(*tx)->getFee(); } - catch (...) { + catch (const std::exception &) { // do nothing } } else if (tx->IsSparkSpend()) { try { nFee = spark::ParseSparkSpend(*tx).getFee(); } - catch (...) { + catch (const std::exception &) { // do nothing } } else { @@ -2834,7 +2834,7 @@ bool CWalletTx::IsChange(uint32_t out) const { try { spark::ParseSparkMintCoin(tx->vout[out].scriptPubKey, coin); coin.setSerialContext(serial_context); - } catch (...) { + } catch (const std::exception &) { return false; } return pwallet->sparkWallet->getMyCoinIsChange(coin); @@ -5781,7 +5781,7 @@ bool CWallet::CommitSigmaTransaction(CWalletTx& wtxNew, std::vector CValidationState state; CReserveKey reserveKey(this); CommitTransaction(wtxNew, reserveKey, g_connman.get(), state); - } catch (...) { + } catch (const std::exception &) { auto error = _( "Error: The transaction was rejected! This might happen if some of " "the coins in your wallet were already spent, such as if you used " @@ -5933,7 +5933,7 @@ CWalletTx CWallet::SpendAndStoreSpark( CValidationState state; CReserveKey reserveKey(this); CommitTransaction(result, reserveKey, g_connman.get(), state); - } catch (...) { + } catch (const std::exception &) { auto error = _( "Error: The transaction was rejected! This might happen if some of " "the coins in your wallet were already spent, such as if you used " @@ -6094,7 +6094,7 @@ bool CWallet::CommitLelantusTransaction(CWalletTx& wtxNew, std::vector