diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 87a8033363..2f0b5be9e2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -406,14 +406,11 @@ static void SendMoney(const CScript& scriptPubKey, CAmount nValue, CAsset asset, throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); // Create and send the transaction - std::vector vpChangeKey; std::vector vChangeKey; vChangeKey.reserve(2); vChangeKey.emplace_back(pwalletMain); - vpChangeKey.push_back(&vChangeKey[0]); if (policyAsset != asset) { vChangeKey.emplace_back(pwalletMain); - vpChangeKey.push_back(&vChangeKey[1]); } CAmount nFeeRequired; @@ -422,13 +419,13 @@ static void SendMoney(const CScript& scriptPubKey, CAmount nValue, CAsset asset, int nChangePosRet = -1; CRecipient recipient = {scriptPubKey, nValue, asset, confidentiality_key, fSubtractFeeFromAmount}; vecSend.push_back(recipient); - if (!pwalletMain->CreateTransaction(vecSend, wtxNew, vpChangeKey, nFeeRequired, nChangePosRet, strError, NULL, true, NULL, true, NULL, NULL, NULL, fIgnoreBlindFail)) { + if (!pwalletMain->CreateTransaction(vecSend, wtxNew, vChangeKey, nFeeRequired, nChangePosRet, strError, NULL, true, NULL, true, NULL, NULL, NULL, fIgnoreBlindFail)) { if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired)); throw JSONRPCError(RPC_WALLET_ERROR, strError); } CValidationState state; - if (!pwalletMain->CommitTransaction(wtxNew, vpChangeKey, g_connman.get(), state)) { + if (!pwalletMain->CommitTransaction(wtxNew, vChangeKey, g_connman.get(), state)) { strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason()); throw JSONRPCError(RPC_WALLET_ERROR, strError); } @@ -449,17 +446,14 @@ static void SendGenerationTransaction(const CScript& assetScriptPubKey, const CP } // Create and send the transaction - std::vector vpChangeKey; std::vector vChangeKey; // Need to be careful to not copy CReserveKeys or bad things happen // We need 2 change outputs possibly for reissuance case: // one for policyAsset, the other for reissuance token vChangeKey.reserve(2); vChangeKey.emplace_back(pwalletMain); - vpChangeKey.push_back(&vChangeKey[0]); if (!reissuanceAsset.IsNull()) { vChangeKey.emplace_back(pwalletMain); - vpChangeKey.push_back(&vChangeKey[1]); } CAmount nFeeRequired; @@ -481,11 +475,11 @@ static void SendGenerationTransaction(const CScript& assetScriptPubKey, const CP } vecSend.push_back(recipient); } - if (!pwalletMain->CreateTransaction(vecSend, wtxNew, vpChangeKey, nFeeRequired, nChangePosRet, strError, NULL, true, NULL, fBlindIssuances, &entropy, &reissuanceAsset, &reissuanceToken)) { + if (!pwalletMain->CreateTransaction(vecSend, wtxNew, vChangeKey, nFeeRequired, nChangePosRet, strError, NULL, true, NULL, fBlindIssuances, &entropy, &reissuanceAsset, &reissuanceToken)) { throw JSONRPCError(RPC_WALLET_ERROR, strError); } CValidationState state; - if (!pwalletMain->CommitTransaction(wtxNew, vpChangeKey, g_connman.get(), state)) + if (!pwalletMain->CommitTransaction(wtxNew, vChangeKey, g_connman.get(), state)) throw JSONRPCError(RPC_WALLET_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 a copy of the wallet and coins were spent in the copy but not marked as spent here."); } @@ -1201,7 +1195,6 @@ UniValue sendmany(const JSONRPCRequest& request) // Send std::vector vChangeKey; - std::vector vpChangeKey; std::set setAssets; setAssets.insert(policyAsset); for (auto recipient : vecSend) { @@ -1210,16 +1203,15 @@ UniValue sendmany(const JSONRPCRequest& request) vChangeKey.reserve(setAssets.size()); for (unsigned int i = 0; i < setAssets.size(); i++) { vChangeKey.emplace_back(pwalletMain); - vpChangeKey.push_back(&vChangeKey[i]); } CAmount nFeeRequired = 0; int nChangePosRet = -1; string strFailReason; - bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, vpChangeKey, nFeeRequired, nChangePosRet, strFailReason, NULL, true, NULL, false, NULL, NULL, NULL, fIgnoreBlindFail); + bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, vChangeKey, nFeeRequired, nChangePosRet, strFailReason, NULL, true, NULL, false, NULL, NULL, NULL, fIgnoreBlindFail); if (!fCreated) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason); CValidationState state; - if (!pwalletMain->CommitTransaction(wtx, vpChangeKey, g_connman.get(), state)) { + if (!pwalletMain->CommitTransaction(wtx, vChangeKey, g_connman.get(), state)) { strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason()); throw JSONRPCError(RPC_WALLET_ERROR, strFailReason); } @@ -3296,7 +3288,7 @@ UniValue bumpfee(const JSONRPCRequest& request) } // commit/broadcast the tx - std::vector vpChangeKey; + std::vector vChangeKey; CWalletTx wtxBumped(pwalletMain, MakeTransactionRef(std::move(tx))); wtxBumped.mapValue = wtx.mapValue; wtxBumped.mapValue["replaces_txid"] = hash.ToString(); @@ -3305,7 +3297,7 @@ UniValue bumpfee(const JSONRPCRequest& request) wtxBumped.fTimeReceivedIsTxTime = true; wtxBumped.fFromMe = true; CValidationState state; - if (!pwalletMain->CommitTransaction(wtxBumped, vpChangeKey, g_connman.get(), state)) { + if (!pwalletMain->CommitTransaction(wtxBumped, vChangeKey, g_connman.get(), state)) { // NOTE: CommitTransaction never returns false, so this should never happen. throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason())); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 51f2244902..50f2bde08a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2607,7 +2607,6 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool ov std::vector vChangeKey; // Avoid copying CReserveKeys which causes badness vChangeKey.reserve((tx.vin.size()+tx.vout.size())*2); - std::vector vpChangeKey; std::set setAssets; // Turn the txout set into a CRecipient vector @@ -2627,7 +2626,6 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool ov if (setAssets.count(txOut.nAsset.GetAsset()) == 0) { vChangeKey.push_back(CReserveKey(this)); - vpChangeKey.push_back(&vChangeKey[vChangeKey.size()-1]); setAssets.insert(txOut.nAsset.GetAsset()); } } @@ -2636,13 +2634,11 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool ov // Any excess will never be reserved, so this should be safe. for (unsigned int i = 0; i < tx.vin.size(); i++) { vChangeKey.push_back(CReserveKey(this)); - vpChangeKey.push_back(&vChangeKey[vChangeKey.size()-1]); } // Always add policyAsset, as fees via policyAsset may create change if (setAssets.count(policyAsset) == 0) { vChangeKey.push_back(CReserveKey(this)); - vpChangeKey.push_back(&vChangeKey[vChangeKey.size()-1]); } CCoinControl coinControl; @@ -2656,7 +2652,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool ov coinControl.Select(txin.prevout); CWalletTx wtx; - if (!CreateTransaction(vecSend, wtx, vpChangeKey, nFeeRet, nChangePosInOut, strFailReason, &coinControl, false)) + if (!CreateTransaction(vecSend, wtx, vChangeKey, nFeeRet, nChangePosInOut, strFailReason, &coinControl, false)) return false; // Wipe outputs and output witness and re-add one by one @@ -2691,14 +2687,14 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, bool ov // optionally keep the change output key if (keepReserveKey) { - for (auto& changekey : vpChangeKey) { - changekey->KeepKey(); + for (auto& changekey : vChangeKey) { + changekey.KeepKey(); } } return true; } -bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wtxNew, std::vector& vpChangeKey, CAmount& nFeeRet, +bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wtxNew, std::vector& vChangeKey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl* coinControl, bool sign, std::vector *outAmounts, bool fBlindIssuances, const uint256* issuanceEntropy, const CAsset* reissuanceAsset, const CAsset* reissuanceToken, bool fIgnoreBlindFail) { // TODO re-enable to support multiple assets in a logical fashion, since the number of possible @@ -2910,7 +2906,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt // Reserve a new key pair from key pool CPubKey vchPubKey; bool ret; - ret = vpChangeKey[changeCounter]->GetReservedKey(vchPubKey); + ret = vChangeKey[changeCounter].GetReservedKey(vchPubKey); if (!ret) { strFailReason = _("Keypool ran out, please call keypoolrefill first"); @@ -2950,7 +2946,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt { nChangePosInOut = -1; nFeeRet += it->second; - vpChangeKey[changeCounter]->ReturnKey(); + vChangeKey[changeCounter].ReturnKey(); } else { @@ -2979,8 +2975,9 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt nChangePosInOut = -1; } } - else - vpChangeKey[changeCounter]->ReturnKey(); + else { + vChangeKey[changeCounter].ReturnKey(); + } changeCounter++; } @@ -3347,7 +3344,7 @@ bool CWallet::CreateTransaction(const vector& vecSend, CWalletTx& wt /** * Call after CreateTransaction unless you want to abort */ -bool CWallet::CommitTransaction(CWalletTx& wtxNew, std::vector& reservekey, CConnman* connman, CValidationState& state) +bool CWallet::CommitTransaction(CWalletTx& wtxNew, std::vector& reservekey, CConnman* connman, CValidationState& state) { { LOCK2(cs_main, cs_wallet); @@ -3355,7 +3352,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, std::vector& re { // Take key pair from key pool so it won't be used again for (auto&& key : reservekey) - key->KeepKey(); + key.KeepKey(); // Add tx to wallet, because if it has change it's also ours, // otherwise just for transaction history. diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 30fd5968ba..c4a4d23cfb 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -874,9 +874,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface * selected by SelectCoins(); Also create the change output, when needed * @note passing nChangePosInOut as -1 will result in setting a random position */ - bool CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, std::vector& vpChangeKey, CAmount& nFeeRet, int& nChangePosInOut, + bool CreateTransaction(const std::vector& vecSend, CWalletTx& wtxNew, std::vector& vChangeKey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl *coinControl = NULL, bool sign = true, std::vector *outAmounts = NULL, bool fBlindIssuances = true, const uint256* issuanceEntropy = NULL, const CAsset* reissuanceAsset = NULL, const CAsset* reissuanceToken = NULL, bool fIgnoreBlindFail = true); - bool CommitTransaction(CWalletTx& wtxNew, std::vector& reservekey, CConnman* connman, CValidationState& state); + bool CommitTransaction(CWalletTx& wtxNew, std::vector& reservekey, CConnman* connman, CValidationState& state); void ListAccountCreditDebit(const std::string& strAccount, std::list& entries); bool AddAccountingEntry(const CAccountingEntry&);