diff --git a/src/Makefile.test.include b/src/Makefile.test.include index f44f9139bbaa..b05116eaee52 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -162,6 +162,7 @@ BITCOIN_TESTS =\ test/random_tests.cpp \ test/ratecheck_tests.cpp \ test/rest_tests.cpp \ + test/result_tests.cpp \ test/reverselock_tests.cpp \ test/rpc_tests.cpp \ test/sanity_tests.cpp \ @@ -214,6 +215,7 @@ BITCOIN_TESTS += \ wallet/test/wallet_crypto_tests.cpp \ wallet/test/wallet_transaction_tests.cpp \ wallet/test/coinselector_tests.cpp \ + wallet/test/availablecoins_tests.cpp \ wallet/test/init_tests.cpp \ wallet/test/ismine_tests.cpp \ wallet/test/scriptpubkeyman_tests.cpp diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 689524a716ea..7b44f5425bdc 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -54,10 +54,10 @@ static void CoinSelection(benchmark::Bench& bench) addCoin(3 * COIN, wallet, wtxs); // Create coins - std::vector coins; + wallet::CoinsResult available_coins; for (const auto& wtx : wtxs) { const auto txout = wtx->tx->vout.at(0); - coins.emplace_back(COutPoint(wtx->GetHash(), 0), txout, /*depth=*/6 * 24, CalculateMaximumSignedInputSize(txout, &wallet, /*coin_control=*/nullptr), /*spendable=*/true, /*solvable=*/true, /*safe=*/true, wtx->GetTxTime(), /*from_me=*/true, /*fees=*/ 0); + available_coins.legacy.emplace_back(COutPoint(wtx->GetHash(), 0), txout, /*depth=*/6 * 24, CalculateMaximumSignedInputSize(txout, &wallet, /*coin_control=*/nullptr), /*spendable=*/true, /*solvable=*/true, /*safe=*/true, wtx->GetTxTime(), /*from_me=*/true, /*fees=*/ 0); } const CoinEligibilityFilter filter_standard(1, 6, 0); FastRandomContext rand{}; @@ -73,7 +73,7 @@ static void CoinSelection(benchmark::Bench& bench) /*avoid_partial=*/ false, }; bench.run([&] { - auto result = AttemptSelection(wallet, 1003 * COIN, filter_standard, coins, coin_selection_params); + auto result = AttemptSelection(wallet, 1003 * COIN, filter_standard, available_coins, coin_selection_params, /*allow_mixed_output_types=*/true); assert(result); assert(result->GetSelectedValue() == 1003 * COIN); assert(result->GetInputSet().size() == 2); diff --git a/src/bench/wallet_loading.cpp b/src/bench/wallet_loading.cpp index 7fdacc24529a..b01732b615a1 100644 --- a/src/bench/wallet_loading.cpp +++ b/src/bench/wallet_loading.cpp @@ -47,12 +47,8 @@ static void BenchUnloadWallet(std::shared_ptr&& wallet) static void AddTx(CWallet& wallet) { - bilingual_str error; - CTxDestination dest; - wallet.GetNewDestination("", dest, error); - CMutableTransaction mtx; - mtx.vout.push_back({COIN, GetScriptForDestination(dest)}); + mtx.vout.push_back({COIN, GetScriptForDestination(*Assert(wallet.GetNewDestination("")))}); mtx.vin.push_back(CTxIn()); wallet.AddToWallet(MakeTransactionRef(mtx), TxStateInactive{}); diff --git a/src/coinjoin/client.cpp b/src/coinjoin/client.cpp index 35593152c8b2..2f74b9c4f579 100644 --- a/src/coinjoin/client.cpp +++ b/src/coinjoin/client.cpp @@ -1556,7 +1556,7 @@ bool CCoinJoinClientSession::CreateCollateralTransaction(CMutableTransaction& tx AssertLockHeld(m_wallet->cs_wallet); CCoinControl coin_control(CoinType::ONLY_COINJOIN_COLLATERAL); - std::vector vCoins{AvailableCoinsListUnspent(*m_wallet, &coin_control).coins}; + std::vector vCoins{AvailableCoinsListUnspent(*m_wallet, &coin_control).all()}; if (vCoins.empty()) { strReason = strprintf("%s requires a collateral transaction and could not locate an acceptable input!", gCoinJoinName); return false; @@ -1575,11 +1575,10 @@ bool CCoinJoinClientSession::CreateCollateralTransaction(CMutableTransaction& tx if (txout.nValue >= CoinJoin::GetCollateralAmount() * 2) { // make our change address CScript scriptChange; - CTxDestination dest; ReserveDestination reserveDest(m_wallet.get()); - bool success = reserveDest.GetReservedDestination(dest, true); - assert(success); // should never fail, as we just unlocked - scriptChange = GetScriptForDestination(dest); + auto dest_opt = reserveDest.GetReservedDestination(true); + assert(dest_opt); // should never fail, as we just unlocked + scriptChange = GetScriptForDestination(*dest_opt); reserveDest.KeepDestination(); // return change txCollateral.vout.emplace_back(txout.nValue - CoinJoin::GetCollateralAmount(), scriptChange); diff --git a/src/coinjoin/util.cpp b/src/coinjoin/util.cpp index 7b777c0311b8..dd4c27281217 100644 --- a/src/coinjoin/util.cpp +++ b/src/coinjoin/util.cpp @@ -29,7 +29,9 @@ inline unsigned int GetSizeOfCompactSizeDiff(uint64_t nSizePrev, uint64_t nSizeN CKeyHolder::CKeyHolder(CWallet* pwallet) : reserveDestination(pwallet) { - reserveDestination.GetReservedDestination(dest, false); + auto dest_opt = reserveDestination.GetReservedDestination(false); + assert(dest_opt); + dest = *dest_opt; } void CKeyHolder::KeepKey() @@ -99,10 +101,10 @@ CTransactionBuilderOutput::CTransactionBuilderOutput(CTransactionBuilder* pTxBui nAmount(nAmountIn) { assert(pTxBuilder); - CTxDestination txdest; LOCK(wallet.cs_wallet); - dest.GetReservedDestination(txdest, false); - script = ::GetScriptForDestination(txdest); + auto dest_opt = dest.GetReservedDestination(false); + assert(dest_opt); + script = ::GetScriptForDestination(*dest_opt); } bool CTransactionBuilderOutput::UpdateAmount(const CAmount nNewAmount) @@ -280,12 +282,13 @@ bool CTransactionBuilder::Commit(bilingual_str& strResult) CTransactionRef tx; { LOCK2(m_wallet.cs_wallet, ::cs_main); - FeeCalculation fee_calc_out; - if (auto txr = wallet::CreateTransaction(m_wallet, vecSend, nChangePosRet, strResult, coinControl, fee_calc_out)) { - tx = txr->tx; - nFeeRet = txr->fee; - nChangePosRet = txr->change_pos; + auto ret = wallet::CreateTransaction(m_wallet, vecSend, nChangePosRet, coinControl); + if (ret) { + tx = ret->tx; + nFeeRet = ret->fee; + nChangePosRet = ret->change_pos; } else { + strResult = util::ErrorString(ret); return false; } } diff --git a/src/dummywallet.cpp b/src/dummywallet.cpp index b37c7c364cd2..e02c4b505149 100644 --- a/src/dummywallet.cpp +++ b/src/dummywallet.cpp @@ -78,7 +78,8 @@ void DummyWalletInit::AddWalletOptions(ArgsManager& argsman) const "-flushwallet", "-privdb", "-walletrejectlongchains", - "-unsafesqlitesync" + "-walletcrosschain", + "-unsafesqlitesync", }); } diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index 85e054b3cde2..9291e8ddc243 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -112,7 +112,7 @@ class Wallet virtual std::string getWalletName() = 0; // Get a new address. - virtual bool getNewDestination(const std::string label, CTxDestination& dest) = 0; + virtual util::Result getNewDestination(const std::string& label) = 0; //! Get public key. virtual bool getPubKey(const CScript& script, const CKeyID& address, CPubKey& pub_key) = 0; @@ -167,12 +167,11 @@ class Wallet virtual std::vector listProTxCoins() = 0; //! Create transaction. - virtual CTransactionRef createTransaction(const std::vector& recipients, + virtual util::Result createTransaction(const std::vector& recipients, const wallet::CCoinControl& coin_control, bool sign, int& change_pos, - CAmount& fee, - bilingual_str& fail_reason) = 0; + CAmount& fee) = 0; //! Commit transaction. virtual void commitTransaction(CTransactionRef tx, @@ -348,35 +347,35 @@ class Wallet class WalletLoader : public ChainClient { public: - //! Register non-core wallet RPCs - virtual void registerOtherRpcs(const Span& commands) = 0; + //! Register non-core wallet RPCs + virtual void registerOtherRpcs(const Span& commands) = 0; - //! Create new wallet. - virtual std::unique_ptr createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, bilingual_str& error, std::vector& warnings) = 0; + //! Create new wallet. + virtual util::Result> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, std::vector& warnings) = 0; - //! Load existing wallet. - virtual std::unique_ptr loadWallet(const std::string& name, bilingual_str& error, std::vector& warnings) = 0; + //! Load existing wallet. + virtual util::Result> loadWallet(const std::string& name, std::vector& warnings) = 0; - //! Return default wallet directory. - virtual std::string getWalletDir() = 0; + //! Return default wallet directory. + virtual std::string getWalletDir() = 0; - //! Restore backup wallet - virtual BResult> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, std::vector& warnings) = 0; + //! Restore backup wallet + virtual util::Result> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, std::vector& warnings) = 0; - //! Return available wallets in wallet directory. - virtual std::vector listWalletDir() = 0; + //! Return available wallets in wallet directory. + virtual std::vector listWalletDir() = 0; - //! Return interfaces for accessing wallets (if any). - virtual std::vector> getWallets() = 0; + //! Return interfaces for accessing wallets (if any). + virtual std::vector> getWallets() = 0; - //! Register handler for load wallet messages. This callback is triggered by - //! createWallet and loadWallet above, and also triggered when wallets are - //! loaded at startup or by RPC. - using LoadWalletFn = std::function wallet)>; - virtual std::unique_ptr handleLoadWallet(LoadWalletFn fn) = 0; + //! Register handler for load wallet messages. This callback is triggered by + //! createWallet and loadWallet above, and also triggered when wallets are + //! loaded at startup or by RPC. + using LoadWalletFn = std::function wallet)>; + virtual std::unique_ptr handleLoadWallet(LoadWalletFn fn) = 0; - //! Return pointer to internal context, useful for testing. - virtual wallet::WalletContext* context() { return nullptr; } + //! Return pointer to internal context, useful for testing. + virtual wallet::WalletContext* context() { return nullptr; } }; //! Information about one wallet address. diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 4a09af9fff5b..d40a3deef6eb 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -366,23 +366,21 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con else if(type == Receive) { // Generate a new address to associate with given label - CTxDestination dest; - if(!walletModel->wallet().getNewDestination(strLabel, dest)) - { + auto op_dest = walletModel->wallet().getNewDestination(strLabel); + if (!op_dest) { WalletModel::UnlockContext ctx(walletModel->requestUnlock()); - if(!ctx.isValid()) - { + if (!ctx.isValid()) { // Unlock wallet failed or was cancelled editStatus = WALLET_UNLOCK_FAILURE; return QString(); } - if(!walletModel->wallet().getNewDestination(strLabel, dest)) - { + op_dest = walletModel->wallet().getNewDestination(strLabel); + if (!op_dest) { editStatus = KEY_GENERATION_FAILURE; return QString(); } } - strAddress = EncodeDestination(dest); + strAddress = EncodeDestination(*op_dest); } else { diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index b80f2a41ff6b..1c0db4616369 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -258,9 +258,13 @@ void CreateWalletActivity::createWallet() } QTimer::singleShot(500ms, worker(), [this, name, flags] { - std::unique_ptr wallet = node().walletLoader().createWallet(name, m_passphrase, flags, m_error_message, m_warning_message); + auto wallet{node().walletLoader().createWallet(name, m_passphrase, flags, m_warning_message)}; - if (wallet) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet)); + if (wallet) { + m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(*wallet)); + } else { + m_error_message = util::ErrorString(wallet); + } QTimer::singleShot(500ms, this, &CreateWalletActivity::finish); }); @@ -330,9 +334,13 @@ void OpenWalletActivity::open(const std::string& path) tr("Opening Wallet %1…").arg(name.toHtmlEscaped())); QTimer::singleShot(0, worker(), [this, path] { - std::unique_ptr wallet = node().walletLoader().loadWallet(path, m_error_message, m_warning_message); + auto wallet{node().walletLoader().loadWallet(path, m_warning_message)}; - if (wallet) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet)); + if (wallet) { + m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(*wallet)); + } else { + m_error_message = util::ErrorString(wallet); + } QTimer::singleShot(0, this, &OpenWalletActivity::finish); }); @@ -375,8 +383,11 @@ void RestoreWalletActivity::restore(const fs::path& backup_file, const std::stri QTimer::singleShot(0, worker(), [this, backup_file, wallet_name] { auto wallet{node().walletLoader().restoreWallet(backup_file, wallet_name, m_warning_message)}; - m_error_message = wallet ? bilingual_str{} : wallet.GetError(); - if (wallet) m_wallet_model = m_wallet_controller->getOrCreateWallet(wallet.ReleaseObj()); + if (wallet) { + m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(*wallet)); + } else { + m_error_message = util::ErrorString(wallet); + } QTimer::singleShot(0, this, &RestoreWalletActivity::finish); }); diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index a2c907c181b7..14f18258b914 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -251,11 +251,11 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact } CAmount nFeeRequired = 0; - bilingual_str error; int nChangePosRet = -1; auto& newTx = transaction.getWtx(); - newTx = m_wallet->createTransaction(vecSend, coinControl, !wallet().privateKeysDisabled() /* sign */, nChangePosRet, nFeeRequired, error); + const auto& res = m_wallet->createTransaction(vecSend, coinControl, !wallet().privateKeysDisabled() /* sign */, nChangePosRet, nFeeRequired); + newTx = res ? *res : nullptr; transaction.setTransactionFee(nFeeRequired); if (fSubtractFeeFromAmount && newTx) transaction.reassignAmounts(nChangePosRet); @@ -266,7 +266,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact { return SendCoinsReturn(AmountWithFeeExceedsBalance); } - Q_EMIT message(tr("Send Coins"), QString::fromStdString(error.translated), + Q_EMIT message(tr("Send Coins"), QString::fromStdString(util::ErrorString(res).translated), CClientUIInterface::MSG_ERROR); return TransactionCreationFailed; } diff --git a/src/rpc/evo.cpp b/src/rpc/evo.cpp index 87c141b56790..02e2fb68de23 100644 --- a/src/rpc/evo.cpp +++ b/src/rpc/evo.cpp @@ -270,7 +270,7 @@ static void FundSpecialTx(CWallet& wallet, CMutableTransaction& tx, const Specia coinControl.destChange = fundDest; coinControl.fRequireAllInputs = false; - for (const auto& out : AvailableCoinsListUnspent(wallet).coins) { + for (const auto& out : AvailableCoinsListUnspent(wallet).all()) { CTxDestination txDest; if (ExtractDestination(out.txout.scriptPubKey, txDest) && txDest == fundDest) { coinControl.Select(out.outpoint); @@ -281,15 +281,12 @@ static void FundSpecialTx(CWallet& wallet, CMutableTransaction& tx, const Specia throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("No funds at specified address %s", EncodeDestination(fundDest))); } - bilingual_str strFailReason; - FeeCalculation fee_calc_out; - auto txr = CreateTransaction(wallet, vecSend, RANDOM_CHANGE_POSITION, strFailReason, coinControl, fee_calc_out, - true, tx.vExtraPayload.size()); - if (!txr) { - throw JSONRPCError(RPC_INTERNAL_ERROR, strFailReason.original); + auto res = CreateTransaction(wallet, vecSend, RANDOM_CHANGE_POSITION, coinControl, /*sign=*/true, tx.vExtraPayload.size()); + if (!res) { + throw JSONRPCError(RPC_INTERNAL_ERROR, util::ErrorString(res).original); } - CTransactionRef newTx = txr->tx; + const CTransactionRef& newTx = res->tx; tx.vin = newTx->vin; tx.vout = newTx->vout; diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index fe437eedb7ea..7f354a5ecc2b 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -140,7 +140,7 @@ static RPCHelpMan masternode_outputs() CCoinControl coin_control(CoinType::ONLY_MASTERNODE_COLLATERAL); UniValue outputsArr(UniValue::VARR); - for (const auto& out : WITH_LOCK(wallet->cs_wallet, return AvailableCoinsListUnspent(*wallet, &coin_control).coins)) { + for (const auto& out : WITH_LOCK(wallet->cs_wallet, return AvailableCoinsListUnspent(*wallet, &coin_control).all())) { outputsArr.push_back(out.outpoint.ToStringShort()); } diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 29c05457a982..d8809f386c71 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -189,6 +189,28 @@ class GenericTransactionSignatureChecker : public BaseSignatureChecker using TransactionSignatureChecker = GenericTransactionSignatureChecker; using MutableTransactionSignatureChecker = GenericTransactionSignatureChecker; +class DeferringSignatureChecker : public BaseSignatureChecker +{ +protected: + BaseSignatureChecker& m_checker; + +public: + DeferringSignatureChecker(BaseSignatureChecker& checker) : m_checker(checker) {} + + bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override + { + return m_checker.CheckSig(scriptSig, vchPubKey, scriptCode, sigversion); + } + bool CheckLockTime(const CScriptNum& nLockTime) const override + { + return m_checker.CheckLockTime(nLockTime); + } + bool CheckSequence(const CScriptNum& nSequence) const override + { + return m_checker.CheckSequence(nSequence); + } +}; + bool EvalScript(std::vector >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker, SigVersion sigversion, ScriptError* error = nullptr); bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* error = nullptr); diff --git a/src/script/sign.cpp b/src/script/sign.cpp index fb61a4fe559f..d58286fbabf7 100644 --- a/src/script/sign.cpp +++ b/src/script/sign.cpp @@ -177,6 +177,8 @@ static CScript PushAll(const std::vector& values) result << OP_0; } else if (v.size() == 1 && v[0] >= 1 && v[0] <= 16) { result << CScript::EncodeOP_N(v[0]); + } else if (v.size() == 1 && v[0] == 0x81) { + result << OP_1NEGATE; } else { result << v; } @@ -216,17 +218,17 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato } namespace { -class SignatureExtractorChecker final : public BaseSignatureChecker +class SignatureExtractorChecker final : public DeferringSignatureChecker { private: SignatureData& sigdata; - BaseSignatureChecker& checker; public: - SignatureExtractorChecker(SignatureData& sigdata, BaseSignatureChecker& checker) : sigdata(sigdata), checker(checker) {} + SignatureExtractorChecker(SignatureData& sigdata, BaseSignatureChecker& checker) : DeferringSignatureChecker(checker), sigdata(sigdata) {} + bool CheckSig(const std::vector& scriptSig, const std::vector& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { - if (checker.CheckSig(scriptSig, vchPubKey, scriptCode, sigversion)) { + if (m_checker.CheckSig(scriptSig, vchPubKey, scriptCode, sigversion)) { CPubKey pubkey(vchPubKey); sigdata.signatures.emplace(pubkey.GetID(), SigPair(pubkey, scriptSig)); return true; diff --git a/src/test/block_reward_reallocation_tests.cpp b/src/test/block_reward_reallocation_tests.cpp index 26f203de4a5e..9b60fd89a69e 100644 --- a/src/test/block_reward_reallocation_tests.cpp +++ b/src/test/block_reward_reallocation_tests.cpp @@ -149,7 +149,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS auto& dmnman = *Assert(m_node.dmnman); const auto& consensus_params = Params().GetConsensus(); - CScript coinbasePubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; + CScript coinbasePubKey = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); BOOST_REQUIRE(DeploymentDIP0003Enforced(WITH_LOCK(cs_main, return m_node.chainman->ActiveChain().Height()), consensus_params)); @@ -160,7 +160,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS auto utxos = BuildSimpleUtxoMap(m_coinbase_txns); auto tx = CreateProRegTx(m_node.chainman->ActiveChain(), *m_node.mempool, utxos, 1, GenerateRandomAddress(), coinbaseKey, ownerKey, operatorKey); - CreateAndProcessBlock({tx}, coinbaseKey); + CreateAndProcessBlock({tx}, coinbasePubKey); { LOCK(cs_main); @@ -173,7 +173,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS BOOST_CHECK(tip->nHeight < Params().GetConsensus().BRRHeight); } - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); { LOCK(cs_main); @@ -186,12 +186,12 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS const auto pblocktemplate = BlockAssembler(m_node.chainman->ActiveChainstate(), m_node, m_node.mempool.get(), Params()).CreateNewBlock(coinbasePubKey); } for ([[maybe_unused]] auto _ : irange::range(499)) { - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); LOCK(cs_main); dmnman.UpdatedBlockTip(m_node.chainman->ActiveChain().Tip()); } BOOST_CHECK(m_node.chainman->ActiveChain().Height() < Params().GetConsensus().BRRHeight); - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); { // Advance to ACTIVE at height = (BRRHeight - 1) @@ -218,7 +218,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS } for ([[maybe_unused]] auto _ : irange::range(consensus_params.nSuperblockCycle - 1)) { - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); } { @@ -237,7 +237,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS for ([[maybe_unused]] auto i : irange::range(19)) { for ([[maybe_unused]] auto j : irange::range(3)) { for ([[maybe_unused]] auto k : irange::range(consensus_params.nSuperblockCycle)) { - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); } LOCK(cs_main); const CBlockIndex* const tip{m_node.chainman->ActiveChain().Tip()}; @@ -274,7 +274,7 @@ BOOST_FIXTURE_TEST_CASE(block_reward_reallocation, TestChainBRRBeforeActivationS // check 10 next superblocks for ([[maybe_unused]] auto i : irange::range(10)) { for ([[maybe_unused]] auto k : irange::range(consensus_params.nSuperblockCycle)) { - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); } LOCK(cs_main); const CBlockIndex* const tip{m_node.chainman->ActiveChain().Tip()}; diff --git a/src/test/dynamic_activation_thresholds_tests.cpp b/src/test/dynamic_activation_thresholds_tests.cpp index 27a6170e9ee4..9c185b5263ea 100644 --- a/src/test/dynamic_activation_thresholds_tests.cpp +++ b/src/test/dynamic_activation_thresholds_tests.cpp @@ -35,16 +35,17 @@ struct TestChainDATSetup : public TestChainSetup void signal(int num_blocks, bool expected_lockin) { const auto& consensus_params = Params().GetConsensus(); + CScript coinbasePubKey = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); // Mine non-signalling blocks gArgs.ForceSetArg("-blockversion", "536870912"); for (int i = 0; i < window - num_blocks; ++i) { - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); } gArgs.ForceRemoveArg("blockversion"); if (num_blocks > 0) { // Mine signalling blocks for (int i = 0; i < num_blocks; ++i) { - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); } } LOCK(cs_main); @@ -58,7 +59,7 @@ struct TestChainDATSetup : public TestChainSetup void test(int activation_index, bool check_activation_at_min) { const auto& consensus_params = Params().GetConsensus(); - CScript coinbasePubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; + CScript coinbasePubKey = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); { LOCK(cs_main); @@ -66,7 +67,7 @@ struct TestChainDATSetup : public TestChainSetup BOOST_CHECK_EQUAL(g_versionbitscache.State(m_node.chainman->ActiveChain().Tip(), consensus_params, deployment_id), ThresholdState::DEFINED); } - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); { LOCK(cs_main); @@ -105,7 +106,7 @@ struct TestChainDATSetup : public TestChainSetup // activate signal(threshold(activation_index), true); for (int i = 0; i < window; ++i) { - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbasePubKey); } { LOCK(cs_main); diff --git a/src/test/evo_assetlocks_tests.cpp b/src/test/evo_assetlocks_tests.cpp index c2179479c5e4..b755fd58a526 100644 --- a/src/test/evo_assetlocks_tests.cpp +++ b/src/test/evo_assetlocks_tests.cpp @@ -45,9 +45,9 @@ SetupDummyInputs(FillableSigningProvider& keystoreRet, CCoinsViewCache& coinsRet // Create some dummy input transactions dummyTransactions[0].vout.resize(2); dummyTransactions[0].vout[0].nValue = 11*CENT; - dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG; + dummyTransactions[0].vout[0].scriptPubKey = GetScriptForRawPubKey(key[0].GetPubKey()); dummyTransactions[0].vout[1].nValue = 50*CENT; - dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG; + dummyTransactions[0].vout[1].scriptPubKey = GetScriptForRawPubKey(key[1].GetPubKey()); AddCoins(coinsRet, CTransaction(dummyTransactions[0]), 0); dummyTransactions[1].vout.resize(2); diff --git a/src/test/evo_deterministicmns_tests.cpp b/src/test/evo_deterministicmns_tests.cpp index 06e97f8b669b..0b58c31613f0 100644 --- a/src/test/evo_deterministicmns_tests.cpp +++ b/src/test/evo_deterministicmns_tests.cpp @@ -256,20 +256,21 @@ void FuncDIP3Activation(TestChainSetup& setup) auto tx = CreateProRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, 1, GetScriptForDestination(payoutDest), setup.coinbaseKey, ownerKey, operatorKey); std::vector txns = {tx}; + const CScript coinbase_pk = GetScriptForRawPubKey(setup.coinbaseKey.GetPubKey()); int nHeight = chainman.ActiveChain().Height(); // We start one block before DIP3 activation, so mining a block with a DIP3 transaction should fail - auto block = std::make_shared(setup.CreateBlock(txns, setup.coinbaseKey, chainman.ActiveChainstate())); + auto block = std::make_shared(setup.CreateBlock(txns, coinbase_pk, chainman.ActiveChainstate())); chainman.ProcessNewBlock(Params(), block, true, nullptr); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight); BOOST_REQUIRE(block->GetHash() != chainman.ActiveChain().Tip()->GetBlockHash()); BOOST_REQUIRE(!dmnman.GetListAtChainTip().HasMN(tx.GetHash())); // This block should activate DIP3 - setup.CreateAndProcessBlock({}, setup.coinbaseKey); + setup.CreateAndProcessBlock({}, coinbase_pk); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1); // Mining a block with a DIP3 transaction should succeed now - block = std::make_shared(setup.CreateBlock(txns, setup.coinbaseKey, chainman.ActiveChainstate())); + block = std::make_shared(setup.CreateBlock(txns, coinbase_pk, chainman.ActiveChainstate())); BOOST_REQUIRE(chainman.ProcessNewBlock(Params(), block, true, nullptr)); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 2); @@ -294,9 +295,10 @@ void FuncV19Activation(TestChainSetup& setup) auto tx_reg = CreateProRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, 1, collateralScript, setup.coinbaseKey, owner_key, operator_key); auto tx_reg_hash = tx_reg.GetHash(); + const CScript coinbase_pk = GetScriptForRawPubKey(setup.coinbaseKey.GetPubKey()); int nHeight = chainman.ActiveChain().Height(); - auto block = std::make_shared(setup.CreateBlock({tx_reg}, setup.coinbaseKey, chainman.ActiveChainstate())); + auto block = std::make_shared(setup.CreateBlock({tx_reg}, coinbase_pk, chainman.ActiveChainstate())); BOOST_REQUIRE(chainman.ProcessNewBlock(Params(), block, true, nullptr)); BOOST_REQUIRE(!DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)); ++nHeight; @@ -314,7 +316,7 @@ void FuncV19Activation(TestChainSetup& setup) operator_key_new.MakeNewKey(); auto tx_upreg = CreateProUpRegTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, tx_reg_hash, owner_key, operator_key_new.GetPublicKey(), owner_key.GetPubKey().GetID(), collateralScript, setup.coinbaseKey); - block = std::make_shared(setup.CreateBlock({tx_upreg}, setup.coinbaseKey, chainman.ActiveChainstate())); + block = std::make_shared(setup.CreateBlock({tx_upreg}, coinbase_pk, chainman.ActiveChainstate())); BOOST_REQUIRE(chainman.ProcessNewBlock(Params(), block, true, nullptr)); BOOST_REQUIRE(!DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)); ++nHeight; @@ -334,7 +336,7 @@ void FuncV19Activation(TestChainSetup& setup) FillableSigningProvider signing_provider; signing_provider.AddKeyPubKey(collateral_key, collateral_key.GetPubKey()); BOOST_REQUIRE(SignSignature(signing_provider, CTransaction(tx_reg), tx_spend, 0, SIGHASH_ALL)); - block = std::make_shared(setup.CreateBlock({tx_spend}, setup.coinbaseKey, chainman.ActiveChainstate())); + block = std::make_shared(setup.CreateBlock({tx_spend}, coinbase_pk, chainman.ActiveChainstate())); BOOST_REQUIRE(chainman.ProcessNewBlock(Params(), block, true, nullptr)); BOOST_REQUIRE(!DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)); ++nHeight; @@ -347,7 +349,7 @@ void FuncV19Activation(TestChainSetup& setup) BOOST_REQUIRE(dmnman.GetListForBlock(pindex_create).HasMN(tx_reg_hash)); // mine another block so that it's not the last one before V19 - setup.CreateAndProcessBlock({}, setup.coinbaseKey); + setup.CreateAndProcessBlock({}, coinbase_pk); BOOST_REQUIRE(!DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)); ++nHeight; BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight); @@ -359,7 +361,7 @@ void FuncV19Activation(TestChainSetup& setup) BOOST_REQUIRE(dmnman.GetListForBlock(pindex_create).HasMN(tx_reg_hash)); // this block should activate V19 - setup.CreateAndProcessBlock({}, setup.coinbaseKey); + setup.CreateAndProcessBlock({}, coinbase_pk); BOOST_REQUIRE(DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)); ++nHeight; BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight); @@ -380,7 +382,7 @@ void FuncV19Activation(TestChainSetup& setup) // mine 10 more blocks for (int i = 0; i < 10; ++i) { - setup.CreateAndProcessBlock({}, setup.coinbaseKey); + setup.CreateAndProcessBlock({}, coinbase_pk); BOOST_REQUIRE( DeploymentActiveAfter(chainman.ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19)); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1 + i); @@ -426,6 +428,7 @@ void FuncDIP3Protx(TestChainSetup& setup) auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns); + const CScript coinbase_pk = GetScriptForRawPubKey(setup.coinbaseKey.GetPubKey()); int nHeight = chainman.ActiveChain().Height(); int port = 1; @@ -460,7 +463,7 @@ void FuncDIP3Protx(TestChainSetup& setup) BOOST_REQUIRE(CheckTransactionSignature(*(setup.m_node.mempool), tx)); BOOST_REQUIRE(!CheckTransactionSignature(*(setup.m_node.mempool), tx2)); - setup.CreateAndProcessBlock({tx}, setup.coinbaseKey); + setup.CreateAndProcessBlock({tx}, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1); @@ -471,7 +474,7 @@ void FuncDIP3Protx(TestChainSetup& setup) int DIP0003EnforcementHeightBackup = Params().GetConsensus().DIP0003EnforcementHeight; const_cast(Params().GetConsensus()).DIP0003EnforcementHeight = chainman.ActiveChain().Height() + 1; - setup.CreateAndProcessBlock({}, setup.coinbaseKey); + setup.CreateAndProcessBlock({}, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); nHeight++; @@ -480,7 +483,7 @@ void FuncDIP3Protx(TestChainSetup& setup) auto dmnExpectedPayee = dmnman.GetListAtChainTip().GetMNPayee(chainman.ActiveChain().Tip()); BOOST_ASSERT(dmnExpectedPayee); - CBlock block = setup.CreateAndProcessBlock({}, setup.coinbaseKey); + CBlock block = setup.CreateAndProcessBlock({}, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_REQUIRE(!block.vtx.empty()); @@ -503,7 +506,7 @@ void FuncDIP3Protx(TestChainSetup& setup) operatorKeys.emplace(tx.GetHash(), operatorKey); txns.emplace_back(tx); } - setup.CreateAndProcessBlock(txns, setup.coinbaseKey); + setup.CreateAndProcessBlock(txns, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1); @@ -516,7 +519,7 @@ void FuncDIP3Protx(TestChainSetup& setup) // test ProUpServTx auto tx = CreateProUpServTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, dmnHashes[0], operatorKeys[dmnHashes[0]], 1000, CScript(), setup.coinbaseKey); - setup.CreateAndProcessBlock({tx}, setup.coinbaseKey); + setup.CreateAndProcessBlock({tx}, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1); nHeight++; @@ -526,7 +529,7 @@ void FuncDIP3Protx(TestChainSetup& setup) // test ProUpRevTx tx = CreateProUpRevTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, dmnHashes[0], operatorKeys[dmnHashes[0]], setup.coinbaseKey); - setup.CreateAndProcessBlock({tx}, setup.coinbaseKey); + setup.CreateAndProcessBlock({tx}, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1); nHeight++; @@ -539,7 +542,7 @@ void FuncDIP3Protx(TestChainSetup& setup) auto dmnExpectedPayee = dmnman.GetListAtChainTip().GetMNPayee(chainman.ActiveChain().Tip()); BOOST_REQUIRE(dmnExpectedPayee && dmnExpectedPayee->proTxHash != dmnHashes[0]); - CBlock block = setup.CreateAndProcessBlock({}, setup.coinbaseKey); + CBlock block = setup.CreateAndProcessBlock({}, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_REQUIRE(!block.vtx.empty()); @@ -568,13 +571,13 @@ void FuncDIP3Protx(TestChainSetup& setup) BOOST_REQUIRE(CheckTransactionSignature(*(setup.m_node.mempool), tx)); BOOST_REQUIRE(!CheckTransactionSignature(*(setup.m_node.mempool), tx2)); // now process the block - setup.CreateAndProcessBlock({tx}, setup.coinbaseKey); + setup.CreateAndProcessBlock({tx}, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1); nHeight++; tx = CreateProUpServTx(chainman.ActiveChain(), *(setup.m_node.mempool), utxos, dmnHashes[0], newOperatorKey, 100, CScript(), setup.coinbaseKey); - setup.CreateAndProcessBlock({tx}, setup.coinbaseKey); + setup.CreateAndProcessBlock({tx}, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1); nHeight++; @@ -592,7 +595,7 @@ void FuncDIP3Protx(TestChainSetup& setup) foundRevived = true; } - CBlock block = setup.CreateAndProcessBlock({}, setup.coinbaseKey); + CBlock block = setup.CreateAndProcessBlock({}, coinbase_pk); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_REQUIRE(!block.vtx.empty()); @@ -611,6 +614,7 @@ void FuncTestMempoolReorg(TestChainSetup& setup) { auto& chainman = *Assert(setup.m_node.chainman.get()); + const CScript coinbase_pk = GetScriptForRawPubKey(setup.coinbaseKey.GetPubKey()); int nHeight = chainman.ActiveChain().Height(); auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns); @@ -632,7 +636,7 @@ void FuncTestMempoolReorg(TestChainSetup& setup) FundTransaction(chainman.ActiveChain(), tx_collateral, utxos, scriptCollateral, dmn_types::Regular.collat_amount, setup.coinbaseKey); SignTransaction(*(setup.m_node.mempool), tx_collateral, setup.coinbaseKey); - auto block = std::make_shared(setup.CreateBlock({tx_collateral}, setup.coinbaseKey, chainman.ActiveChainstate())); + auto block = std::make_shared(setup.CreateBlock({tx_collateral}, coinbase_pk, chainman.ActiveChainstate())); BOOST_REQUIRE(chainman.ProcessNewBlock(Params(), block, true, nullptr)); setup.m_node.dmnman->UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1); @@ -756,6 +760,7 @@ void FuncVerifyDB(TestChainSetup& setup) auto& chainman = *Assert(setup.m_node.chainman.get()); auto& dmnman = *Assert(setup.m_node.dmnman); + const CScript coinbase_pk = GetScriptForRawPubKey(setup.coinbaseKey.GetPubKey()); int nHeight = chainman.ActiveChain().Height(); auto utxos = BuildSimpleUtxoMap(setup.m_coinbase_txns); @@ -777,7 +782,7 @@ void FuncVerifyDB(TestChainSetup& setup) FundTransaction(chainman.ActiveChain(), tx_collateral, utxos, scriptCollateral, dmn_types::Regular.collat_amount, setup.coinbaseKey); SignTransaction(*(setup.m_node.mempool), tx_collateral, setup.coinbaseKey); - auto block = std::make_shared(setup.CreateBlock({tx_collateral}, setup.coinbaseKey, chainman.ActiveChainstate())); + auto block = std::make_shared(setup.CreateBlock({tx_collateral}, coinbase_pk, chainman.ActiveChainstate())); BOOST_REQUIRE(chainman.ProcessNewBlock(Params(), block, true, nullptr)); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 1); @@ -810,7 +815,7 @@ void FuncVerifyDB(TestChainSetup& setup) auto tx_reg_hash = tx_reg.GetHash(); - block = std::make_shared(setup.CreateBlock({tx_reg}, setup.coinbaseKey, chainman.ActiveChainstate())); + block = std::make_shared(setup.CreateBlock({tx_reg}, coinbase_pk, chainman.ActiveChainstate())); BOOST_REQUIRE(chainman.ProcessNewBlock(Params(), block, true, nullptr)); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 2); @@ -822,7 +827,7 @@ void FuncVerifyDB(TestChainSetup& setup) collateral_utxos.emplace(payload.collateralOutpoint, std::make_pair(1, 1000)); auto proUpRevTx = CreateProUpRevTx(chainman.ActiveChain(), *(setup.m_node.mempool), collateral_utxos, tx_reg_hash, operatorKey, collateralKey); - block = std::make_shared(setup.CreateBlock({proUpRevTx}, setup.coinbaseKey, chainman.ActiveChainstate())); + block = std::make_shared(setup.CreateBlock({proUpRevTx}, coinbase_pk, chainman.ActiveChainstate())); BOOST_REQUIRE(chainman.ProcessNewBlock(Params(), block, true, nullptr)); dmnman.UpdatedBlockTip(chainman.ActiveChain().Tip()); BOOST_CHECK_EQUAL(chainman.ActiveChain().Height(), nHeight + 3); @@ -940,7 +945,7 @@ struct TestChainDIP3Setup : public TestChainDIP3BeforeActivationSetup { TestChainDIP3Setup() { // Activate DIP3 here - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); } }; @@ -951,9 +956,10 @@ struct TestChainV19BeforeActivationSetup : public TestChainSetup { struct TestChainV19Setup : public TestChainV19BeforeActivationSetup { TestChainV19Setup() { + const CScript coinbase_pk = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); // Activate V19 for (int i = 0; i < 5; ++i) { - CreateAndProcessBlock({}, coinbaseKey); + CreateAndProcessBlock({}, coinbase_pk); } bool v19_just_activated{DeploymentActiveAfter(m_node.chainman->ActiveChain().Tip(), Params().GetConsensus(), Consensus::DEPLOYMENT_V19) && diff --git a/src/test/result_tests.cpp b/src/test/result_tests.cpp new file mode 100644 index 000000000000..6a23a7b8950a --- /dev/null +++ b/src/test/result_tests.cpp @@ -0,0 +1,96 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include + +inline bool operator==(const bilingual_str& a, const bilingual_str& b) +{ + return a.original == b.original && a.translated == b.translated; +} + +inline std::ostream& operator<<(std::ostream& os, const bilingual_str& s) +{ + return os << "bilingual_str('" << s.original << "' , '" << s.translated << "')"; +} + +BOOST_AUTO_TEST_SUITE(result_tests) + +struct NoCopy { + NoCopy(int n) : m_n{std::make_unique(n)} {} + std::unique_ptr m_n; +}; + +bool operator==(const NoCopy& a, const NoCopy& b) +{ + return *a.m_n == *b.m_n; +} + +std::ostream& operator<<(std::ostream& os, const NoCopy& o) +{ + return os << "NoCopy(" << *o.m_n << ")"; +} + +util::Result IntFn(int i, bool success) +{ + if (success) return i; + return util::Error{Untranslated(strprintf("int %i error.", i))}; +} + +util::Result StrFn(bilingual_str s, bool success) +{ + if (success) return s; + return util::Error{strprintf(Untranslated("str %s error."), s.original)}; +} + +util::Result NoCopyFn(int i, bool success) +{ + if (success) return {i}; + return util::Error{Untranslated(strprintf("nocopy %i error.", i))}; +} + +template +void ExpectResult(const util::Result& result, bool success, const bilingual_str& str) +{ + BOOST_CHECK_EQUAL(bool(result), success); + BOOST_CHECK_EQUAL(util::ErrorString(result), str); +} + +template +void ExpectSuccess(const util::Result& result, const bilingual_str& str, Args&&... args) +{ + ExpectResult(result, true, str); + BOOST_CHECK_EQUAL(result.has_value(), true); + BOOST_CHECK_EQUAL(result.value(), T{std::forward(args)...}); + BOOST_CHECK_EQUAL(&result.value(), &*result); +} + +template +void ExpectFail(const util::Result& result, const bilingual_str& str) +{ + ExpectResult(result, false, str); +} + +BOOST_AUTO_TEST_CASE(check_returned) +{ + ExpectSuccess(IntFn(5, true), {}, 5); + ExpectFail(IntFn(5, false), Untranslated("int 5 error.")); + ExpectSuccess(NoCopyFn(5, true), {}, 5); + ExpectFail(NoCopyFn(5, false), Untranslated("nocopy 5 error.")); + ExpectSuccess(StrFn(Untranslated("S"), true), {}, Untranslated("S")); + ExpectFail(StrFn(Untranslated("S"), false), Untranslated("str S error.")); +} + +BOOST_AUTO_TEST_CASE(check_value_or) +{ + BOOST_CHECK_EQUAL(IntFn(10, true).value_or(20), 10); + BOOST_CHECK_EQUAL(IntFn(10, false).value_or(20), 20); + BOOST_CHECK_EQUAL(NoCopyFn(10, true).value_or(20), 10); + BOOST_CHECK_EQUAL(NoCopyFn(10, false).value_or(20), 20); + BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), true).value_or(Untranslated("B")), Untranslated("A")); + BOOST_CHECK_EQUAL(StrFn(Untranslated("A"), false).value_or(Untranslated("B")), Untranslated("B")); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 457d52460cd9..6c8d35946412 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -442,7 +442,7 @@ TestChainSetup::TestChainSetup(int num_blocks, const std::string& chain_name, co void TestChainSetup::mineBlocks(int num_blocks) { - CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; + CScript scriptPubKey = GetScriptForRawPubKey(coinbaseKey.GetPubKey()); for (int i = 0; i < num_blocks; i++) { std::vector noTxns; CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey); @@ -474,15 +474,6 @@ CBlock TestChainSetup::CreateAndProcessBlock( return block; } -CBlock TestChainSetup::CreateAndProcessBlock( - const std::vector& txns, - const CKey& scriptKey, - CChainState* chainstate) -{ - CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; - return CreateAndProcessBlock(txns, scriptPubKey, chainstate); -} - CBlock TestChainSetup::CreateBlock( const std::vector& txns, const CScript& scriptPubKey, @@ -546,16 +537,6 @@ CBlock TestChainSetup::CreateBlock( return result; } -CBlock TestChainSetup::CreateBlock( - const std::vector& txns, - const CKey& scriptKey, - CChainState& chainstate) -{ - CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG; - return CreateBlock(txns, scriptPubKey, chainstate); -} - - CMutableTransaction TestChainSetup::CreateValidMempoolTransaction(CTransactionRef input_transaction, int input_vout, int input_height, diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index 84ca35163deb..0f2ce36d2433 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -148,9 +148,6 @@ struct TestChainSetup : public TestingSetup CBlock CreateAndProcessBlock(const std::vector& txns, const CScript& scriptPubKey, CChainState* chainstate = nullptr); - CBlock CreateAndProcessBlock(const std::vector& txns, - const CKey& scriptKey, - CChainState* chainstate = nullptr); /** * Create a new block with just given transactions, coinbase paying to @@ -159,9 +156,6 @@ struct TestChainSetup : public TestingSetup CBlock CreateBlock(const std::vector& txns, const CScript& scriptPubKey, CChainState& chainstate); - CBlock CreateBlock(const std::vector& txns, - const CKey& scriptKey, - CChainState& chainstate); //! Mine a series of new blocks on the active chain. void mineBlocks(int num_blocks); diff --git a/src/test/util/wallet.cpp b/src/test/util/wallet.cpp index 190abea0c3c0..e1d59b3bc76e 100644 --- a/src/test/util/wallet.cpp +++ b/src/test/util/wallet.cpp @@ -12,6 +12,7 @@ #include #include