Skip to content

Commit

Permalink
Merge bitcoin#17237: wallet: LearnRelatedScripts only if KeepDestination
Browse files Browse the repository at this point in the history
3958295 wallet: LearnRelatedScripts only if KeepDestination (João Barbosa)
55295fb wallet: Lock address type in ReserveDestination (João Barbosa)

Pull request description:

  Only mutates the wallet if the reserved key is kept.

  First commit is a refactor that makes the address type a class member.

  The second commit moves `LearnRelatedScripts` from `GetReservedDestination` to `KeepDestination` to avoid an unnecessary call to `AddCScript` - which in turn prevents multiple entries of the same script in the wallet DB.

ACKs for top commit:
  achow101:
    Re-ACK 3958295
  Sjors:
    ACK 3958295
  ryanofsky:
    Code review ACK 3958295. I like this change. The new behavior makes more sense, and the change makes the code clearer, since the current LearnRelatedScripts call is hard to understand and explain. (Personally, I'd like it if this PR were merged before bitcoin#17373 or that PR was rebased on top of this one so it would be less confusing.)
  meshcollider:
    utACK 3958295

Tree-SHA512: 49a5f4b022b28042ad37ea309b28378a3983cb904e234a25795b5a360356652e0f8e60f15e3e64d85094ea63af9be01812d90ccfc08ca4f1dd927fdd8566e33f
  • Loading branch information
meshcollider authored and sidhujag committed Nov 22, 2019
1 parent 9861f21 commit fae7ed5
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 14 deletions.
17 changes: 9 additions & 8 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2610,7 +2610,8 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign)
{
CAmount nValue = 0;
ReserveDestination reservedest(this);
const OutputType change_type = TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type : m_default_change_type, vecSend);
ReserveDestination reservedest(this, change_type);
int nChangePosRequest = nChangePosInOut;
unsigned int nSubtractFeeFromAmount = 0;
for (const auto& recipient : vecSend)
Expand Down Expand Up @@ -2669,8 +2670,7 @@ bool CWallet::CreateTransaction(interfaces::Chain::Lock& locked_chain, const std
return false;
}
CTxDestination dest;
const OutputType change_type = TransactionChangeType(coin_control.m_change_type ? *coin_control.m_change_type : m_default_change_type, vecSend);
bool ret = reservedest.GetReservedDestination(change_type, dest, true);
bool ret = reservedest.GetReservedDestination(dest, true);
if (!ret)
{
strFailReason = "Keypool ran out, please call keypoolrefill first";
Expand Down Expand Up @@ -3197,8 +3197,8 @@ bool CWallet::GetNewChangeDestination(const OutputType type, CTxDestination& des

m_spk_man->TopUp();

ReserveDestination reservedest(this);
if (!reservedest.GetReservedDestination(type, dest, true)) {
ReserveDestination reservedest(this, type);
if (!reservedest.GetReservedDestination(dest, true)) {
error = "Error: Keypool ran out, please call keypoolrefill first";
return false;
}
Expand Down Expand Up @@ -3364,7 +3364,7 @@ std::set<CTxDestination> CWallet::GetLabelAddresses(const std::string& label) co
return result;
}

bool ReserveDestination::GetReservedDestination(const OutputType type, CTxDestination& dest, bool internal)
bool ReserveDestination::GetReservedDestination(CTxDestination& dest, bool internal)
{
m_spk_man = pwallet->GetLegacyScriptPubKeyMan();
if (!m_spk_man) {
Expand All @@ -3385,16 +3385,17 @@ bool ReserveDestination::GetReservedDestination(const OutputType type, CTxDestin
fInternal = keypool.fInternal;
}
assert(vchPubKey.IsValid());
m_spk_man->LearnRelatedScripts(vchPubKey, type);
address = GetDestinationForKey(vchPubKey, type);
dest = address;
return true;
}

void ReserveDestination::KeepDestination()
{
if (nIndex != -1)
if (nIndex != -1) {
m_spk_man->KeepDestination(nIndex);
m_spk_man->LearnRelatedScripts(vchPubKey, type);
}
nIndex = -1;
vchPubKey = CPubKey();
address = CNoDestination();
Expand Down
12 changes: 6 additions & 6 deletions src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,9 @@ class ReserveDestination : public CReserveScript
{
protected:
//! The wallet to reserve from
CWallet* pwallet;
CWallet* const pwallet;
LegacyScriptPubKeyMan* m_spk_man{nullptr};
OutputType const type;
//! The index of the address's key in the keypool
int64_t nIndex{-1};
//! The public key for the address
Expand All @@ -154,10 +155,9 @@ class ReserveDestination : public CReserveScript

public:
//! Construct a ReserveDestination object. This does NOT reserve an address yet
explicit ReserveDestination(CWallet* pwalletIn)
{
pwallet = pwalletIn;
}
explicit ReserveDestination(CWallet* pwallet, OutputType type)
: pwallet(pwallet)
, type(type) { }

ReserveDestination(const ReserveDestination&) = delete;
ReserveDestination& operator=(const ReserveDestination&) = delete;
Expand All @@ -169,7 +169,7 @@ class ReserveDestination : public CReserveScript
}

//! Reserve an address
bool GetReservedDestination(const OutputType type, CTxDestination& pubkey, bool internal);
bool GetReservedDestination(CTxDestination& pubkey, bool internal);
//! Return reserved address
void ReturnDestination();
//! Keep the address. Do not return it's key to the keypool when this object goes out of scope
Expand Down

0 comments on commit fae7ed5

Please sign in to comment.