Skip to content

Commit e10e1e8

Browse files
committed
Restrict lifetime of ReserveDestination to CWallet::CreateTransaction
1 parent d9ff862 commit e10e1e8

File tree

6 files changed

+19
-27
lines changed

6 files changed

+19
-27
lines changed

src/interfaces/wallet.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace {
3636
class PendingWalletTxImpl : public PendingWalletTx
3737
{
3838
public:
39-
explicit PendingWalletTxImpl(CWallet& wallet) : m_wallet(wallet), m_dest(&wallet) {}
39+
explicit PendingWalletTxImpl(CWallet& wallet) : m_wallet(wallet) {}
4040

4141
const CTransaction& get() override { return *m_tx; }
4242

@@ -47,7 +47,7 @@ class PendingWalletTxImpl : public PendingWalletTx
4747
auto locked_chain = m_wallet.chain().lock();
4848
LOCK(m_wallet.cs_wallet);
4949
CValidationState state;
50-
if (!m_wallet.CommitTransaction(m_tx, std::move(value_map), std::move(order_form), m_dest, state)) {
50+
if (!m_wallet.CommitTransaction(m_tx, std::move(value_map), std::move(order_form), state)) {
5151
reject_reason = state.GetRejectReason();
5252
return false;
5353
}
@@ -56,7 +56,6 @@ class PendingWalletTxImpl : public PendingWalletTx
5656

5757
CTransactionRef m_tx;
5858
CWallet& m_wallet;
59-
ReserveDestination m_dest;
6059
};
6160

6261
//! Construct wallet tx struct.
@@ -238,7 +237,7 @@ class WalletImpl : public Wallet
238237
auto locked_chain = m_wallet->chain().lock();
239238
LOCK(m_wallet->cs_wallet);
240239
auto pending = MakeUnique<PendingWalletTxImpl>(*m_wallet);
241-
if (!m_wallet->CreateTransaction(*locked_chain, recipients, pending->m_tx, pending->m_dest, fee, change_pos,
240+
if (!m_wallet->CreateTransaction(*locked_chain, recipients, pending->m_tx, fee, change_pos,
242241
fail_reason, coin_control, sign)) {
243242
return {};
244243
}

src/wallet/feebumper.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,10 @@ Result CreateRateBumpTransaction(CWallet* wallet, const uint256& txid, const CCo
272272
new_coin_control.m_min_depth = 1;
273273

274274
CTransactionRef tx_new = MakeTransactionRef();
275-
ReserveDestination reservedest(wallet);
276275
CAmount fee_ret;
277276
int change_pos_in_out = -1; // No requested location for change
278277
std::string fail_reason;
279-
if (!wallet->CreateTransaction(*locked_chain, recipients, tx_new, reservedest, fee_ret, change_pos_in_out, fail_reason, new_coin_control, false)) {
278+
if (!wallet->CreateTransaction(*locked_chain, recipients, tx_new, fee_ret, change_pos_in_out, fail_reason, new_coin_control, false)) {
280279
errors.push_back("Unable to create transaction: " + fail_reason);
281280
return Result::WALLET_ERROR;
282281
}
@@ -327,9 +326,8 @@ Result CommitTransaction(CWallet* wallet, const uint256& txid, CMutableTransacti
327326
mapValue_t mapValue = oldWtx.mapValue;
328327
mapValue["replaces_txid"] = oldWtx.GetHash().ToString();
329328

330-
ReserveDestination reservedest(wallet);
331329
CValidationState state;
332-
if (!wallet->CommitTransaction(tx, std::move(mapValue), oldWtx.vOrderForm, reservedest, state)) {
330+
if (!wallet->CommitTransaction(tx, std::move(mapValue), oldWtx.vOrderForm, state)) {
333331
// NOTE: CommitTransaction never returns false, so this should never happen.
334332
errors.push_back(strprintf("The transaction was rejected: %s", FormatStateMessage(state)));
335333
return Result::WALLET_ERROR;

src/wallet/rpcwallet.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -309,21 +309,20 @@ static CTransactionRef SendMoney(interfaces::Chain::Lock& locked_chain, CWallet
309309
CScript scriptPubKey = GetScriptForDestination(address);
310310

311311
// Create and send the transaction
312-
ReserveDestination reservedest(pwallet);
313312
CAmount nFeeRequired;
314313
std::string strError;
315314
std::vector<CRecipient> vecSend;
316315
int nChangePosRet = -1;
317316
CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
318317
vecSend.push_back(recipient);
319318
CTransactionRef tx;
320-
if (!pwallet->CreateTransaction(locked_chain, vecSend, tx, reservedest, nFeeRequired, nChangePosRet, strError, coin_control)) {
319+
if (!pwallet->CreateTransaction(locked_chain, vecSend, tx, nFeeRequired, nChangePosRet, strError, coin_control)) {
321320
if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
322321
strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
323322
throw JSONRPCError(RPC_WALLET_ERROR, strError);
324323
}
325324
CValidationState state;
326-
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, reservedest, state)) {
325+
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, state)) {
327326
strError = strprintf("Error: The transaction was rejected! Reason given: %s", FormatStateMessage(state));
328327
throw JSONRPCError(RPC_WALLET_ERROR, strError);
329328
}
@@ -907,16 +906,15 @@ static UniValue sendmany(const JSONRPCRequest& request)
907906
std::shuffle(vecSend.begin(), vecSend.end(), FastRandomContext());
908907

909908
// Send
910-
ReserveDestination changedest(pwallet);
911909
CAmount nFeeRequired = 0;
912910
int nChangePosRet = -1;
913911
std::string strFailReason;
914912
CTransactionRef tx;
915-
bool fCreated = pwallet->CreateTransaction(*locked_chain, vecSend, tx, changedest, nFeeRequired, nChangePosRet, strFailReason, coin_control);
913+
bool fCreated = pwallet->CreateTransaction(*locked_chain, vecSend, tx, nFeeRequired, nChangePosRet, strFailReason, coin_control);
916914
if (!fCreated)
917915
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
918916
CValidationState state;
919-
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, changedest, state)) {
917+
if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, state)) {
920918
strFailReason = strprintf("Transaction commit failed:: %s", FormatStateMessage(state));
921919
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
922920
}

src/wallet/test/wallet_tests.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,17 +361,16 @@ class ListCoinsTestingSetup : public TestChain100Setup
361361
CWalletTx& AddTx(CRecipient recipient)
362362
{
363363
CTransactionRef tx;
364-
ReserveDestination reservedest(wallet.get());
365364
CAmount fee;
366365
int changePos = -1;
367366
std::string error;
368367
CCoinControl dummy;
369368
{
370369
auto locked_chain = m_chain->lock();
371-
BOOST_CHECK(wallet->CreateTransaction(*locked_chain, {recipient}, tx, reservedest, fee, changePos, error, dummy));
370+
BOOST_CHECK(wallet->CreateTransaction(*locked_chain, {recipient}, tx, fee, changePos, error, dummy));
372371
}
373372
CValidationState state;
374-
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, reservedest, state));
373+
BOOST_CHECK(wallet->CommitTransaction(tx, {}, {}, state));
375374
CMutableTransaction blocktx;
376375
{
377376
LOCK(wallet->cs_wallet);

src/wallet/wallet.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,9 +2666,8 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC
26662666
auto locked_chain = chain().lock();
26672667
LOCK(cs_wallet);
26682668

2669-
ReserveDestination reservedest(this);
26702669
CTransactionRef tx_new;
2671-
if (!CreateTransaction(*locked_chain, vecSend, tx_new, reservedest, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) {
2670+
if (!CreateTransaction(*locked_chain, vecSend, tx_new, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) {
26722671
return false;
26732672
}
26742673

@@ -2784,10 +2783,11 @@ OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vec
27842783
return m_default_address_type;
27852784
}
27862785

2787-
bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, ReserveDestination& reservedest, CAmount& nFeeRet,
2786+
bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CAmount& nFeeRet,
27882787
int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
27892788
{
27902789
CAmount nValue = 0;
2790+
ReserveDestination reservedest(this);
27912791
int nChangePosRequest = nChangePosInOut;
27922792
unsigned int nSubtractFeeFromAmount = 0;
27932793
for (const auto& recipient : vecSend)
@@ -3147,7 +3147,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
31473147
/**
31483148
* Call after CreateTransaction unless you want to abort
31493149
*/
3150-
bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, ReserveDestination& reservedest, CValidationState& state)
3150+
bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CValidationState& state)
31513151
{
31523152
{
31533153
auto locked_chain = chain().lock();
@@ -3161,8 +3161,6 @@ bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::ve
31613161

31623162
WalletLogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString()); /* Continued */
31633163
{
3164-
// Take key pair from key pool so it won't be used again
3165-
reservedest.KeepDestination();
31663164

31673165
// Add tx to wallet, because if it has change it's also ours,
31683166
// otherwise just for transaction history.

src/wallet/wallet.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,8 @@ class CKeyPool
256256

257257
/** A wrapper to reserve an address from a wallet
258258
*
259-
* ReserveDestination is used to reserve an address. It is passed around
260-
* during the CreateTransaction/CommitTransaction procedure.
259+
* ReserveDestination is used to reserve an address.
260+
* It is currently only used inside of CreateTransaction.
261261
*
262262
* Instantiating a ReserveDestination does not reserve an address. To do so,
263263
* GetReservedDestination() needs to be called on the object. Once an address has been
@@ -1084,9 +1084,9 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
10841084
* selected by SelectCoins(); Also create the change output, when needed
10851085
* @note passing nChangePosInOut as -1 will result in setting a random position
10861086
*/
1087-
bool CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, ReserveDestination& reservedest, CAmount& nFeeRet, int& nChangePosInOut,
1087+
bool CreateTransaction(interfaces::Chain::Lock& locked_chain, const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CAmount& nFeeRet, int& nChangePosInOut,
10881088
std::string& strFailReason, const CCoinControl& coin_control, bool sign = true);
1089-
bool CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, ReserveDestination& reservedest, CValidationState& state);
1089+
bool CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, CValidationState& state);
10901090

10911091
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, bool use_max_sig = false) const
10921092
{

0 commit comments

Comments
 (0)