Skip to content

Commit 172213b

Browse files
committed
Add GetNewDestination to CWallet to fetch new destinations
Instead of having the same multiple lines of code everywhere that new destinations are fetched, introduce GetNewDestination as a member function of CWallet which does the key fetching, label setting, script generation, and destination generation.
1 parent 0853d8d commit 172213b

File tree

9 files changed

+52
-41
lines changed

9 files changed

+52
-41
lines changed

src/interfaces/wallet.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,11 @@ class WalletImpl : public Wallet
140140
void abortRescan() override { m_wallet->AbortRescan(); }
141141
bool backupWallet(const std::string& filename) override { return m_wallet->BackupWallet(filename); }
142142
std::string getWalletName() override { return m_wallet->GetName(); }
143-
bool getKeyFromPool(bool internal, CPubKey& pub_key) override
143+
bool getNewDestination(const OutputType type, const std::string label, CTxDestination& dest) override
144144
{
145-
return m_wallet->GetKeyFromPool(pub_key, internal);
145+
LOCK(m_wallet->cs_wallet);
146+
std::string error;
147+
return m_wallet->GetNewDestination(type, label, dest, error);
146148
}
147149
bool getPubKey(const CKeyID& address, CPubKey& pub_key) override { return m_wallet->GetPubKey(address, pub_key); }
148150
bool getPrivKey(const CKeyID& address, CKey& key) override { return m_wallet->GetKey(address, key); }

src/interfaces/wallet.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ class Wallet
7676
//! Get wallet name.
7777
virtual std::string getWalletName() = 0;
7878

79-
// Get key from pool.
80-
virtual bool getKeyFromPool(bool internal, CPubKey& pub_key) = 0;
79+
// Get a new address.
80+
virtual bool getNewDestination(const OutputType type, const std::string label, CTxDestination& dest) = 0;
8181

8282
//! Get public key.
8383
virtual bool getPubKey(const CKeyID& address, CPubKey& pub_key) = 0;

src/qt/addresstablemodel.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -358,12 +358,15 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
358358
return QString();
359359
}
360360
}
361+
362+
// Add entry
363+
walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel, "send");
361364
}
362365
else if(type == Receive)
363366
{
364367
// Generate a new address to associate with given label
365-
CPubKey newKey;
366-
if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey))
368+
CTxDestination dest;
369+
if(!walletModel->wallet().getNewDestination(address_type, strLabel, dest))
367370
{
368371
WalletModel::UnlockContext ctx(walletModel->requestUnlock());
369372
if(!ctx.isValid())
@@ -372,23 +375,18 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
372375
editStatus = WALLET_UNLOCK_FAILURE;
373376
return QString();
374377
}
375-
if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey))
378+
if(!walletModel->wallet().getNewDestination(address_type, strLabel, dest))
376379
{
377380
editStatus = KEY_GENERATION_FAILURE;
378381
return QString();
379382
}
380383
}
381-
walletModel->wallet().learnRelatedScripts(newKey, address_type);
382-
strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type));
384+
strAddress = EncodeDestination(dest);
383385
}
384386
else
385387
{
386388
return QString();
387389
}
388-
389-
// Add entry
390-
walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel,
391-
(type == Send ? "send" : "receive"));
392390
return QString::fromStdString(strAddress);
393391
}
394392

src/qt/paymentserver.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -666,16 +666,14 @@ void PaymentServer::fetchPaymentACK(WalletModel* walletModel, const SendCoinsRec
666666
payment.add_transactions(transaction.data(), transaction.size());
667667

668668
// Create a new refund address, or re-use:
669-
CPubKey newKey;
670-
if (walletModel->wallet().getKeyFromPool(false /* internal */, newKey)) {
669+
CTxDestination dest;
670+
const OutputType change_type = walletModel->wallet().getDefaultChangeType() != OutputType::CHANGE_AUTO ? walletModel->wallet().getDefaultChangeType() : walletModel->wallet().getDefaultAddressType();
671+
if (walletModel->wallet().getNewDestination(change_type, "", dest)) {
671672
// BIP70 requests encode the scriptPubKey directly, so we are not restricted to address
672673
// types supported by the receiver. As a result, we choose the address format we also
673674
// use for change. Despite an actual payment and not change, this is a close match:
674675
// it's the output type we use subject to privacy issues, but not restricted by what
675676
// other software supports.
676-
const OutputType change_type = walletModel->wallet().getDefaultChangeType() != OutputType::CHANGE_AUTO ? walletModel->wallet().getDefaultChangeType() : walletModel->wallet().getDefaultAddressType();
677-
walletModel->wallet().learnRelatedScripts(newKey, change_type);
678-
CTxDestination dest = GetDestinationForKey(newKey, change_type);
679677
std::string label = tr("Refund from %1").arg(recipient.authenticatedMerchant).toStdString();
680678
walletModel->wallet().setAddressBook(dest, label, "refund");
681679

src/test/util.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,9 @@ const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqq
2525
std::string getnewaddress(CWallet& w)
2626
{
2727
constexpr auto output_type = OutputType::BECH32;
28-
29-
CPubKey new_key;
30-
if (!w.GetKeyFromPool(new_key)) assert(false);
31-
32-
w.LearnRelatedScripts(new_key, output_type);
33-
const auto dest = GetDestinationForKey(new_key, output_type);
34-
35-
w.SetAddressBook(dest, /* label */ "", "receive");
28+
CTxDestination dest;
29+
std::string error;
30+
if (!w.GetNewDestination(output_type, "", dest, error)) assert(false);
3631

3732
return EncodeDestination(dest);
3833
}

src/wallet/rpcwallet.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -185,19 +185,11 @@ static UniValue getnewaddress(const JSONRPCRequest& request)
185185
}
186186
}
187187

188-
if (!pwallet->IsLocked()) {
189-
pwallet->TopUpKeyPool();
190-
}
191-
192-
// Generate a new key that is added to wallet
193-
CPubKey newKey;
194-
if (!pwallet->GetKeyFromPool(newKey)) {
195-
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
188+
CTxDestination dest;
189+
std::string error;
190+
if (!pwallet->GetNewDestination(output_type, label, dest, error)) {
191+
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, error);
196192
}
197-
pwallet->LearnRelatedScripts(newKey, output_type);
198-
CTxDestination dest = GetDestinationForKey(newKey, output_type);
199-
200-
pwallet->SetAddressBook(dest, label, "receive");
201193

202194
return EncodeDestination(dest);
203195
}

src/wallet/test/wallet_tests.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,9 @@ BOOST_FIXTURE_TEST_CASE(wallet_disableprivkeys, TestChain100Setup)
466466
wallet->SetMinVersion(FEATURE_LATEST);
467467
wallet->SetWalletFlag(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
468468
BOOST_CHECK(!wallet->TopUpKeyPool(1000));
469-
CPubKey pubkey;
470-
BOOST_CHECK(!wallet->GetKeyFromPool(pubkey, false));
469+
CTxDestination dest;
470+
std::string error;
471+
BOOST_CHECK(!wallet->GetNewDestination(OutputType::BECH32, "", dest, error));
471472
}
472473

473474
// Explicit calculation which is used to test the wallet constant

src/wallet/wallet.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3513,6 +3513,27 @@ bool CWallet::GetKeyFromPool(CPubKey& result, bool internal)
35133513
return true;
35143514
}
35153515

3516+
bool CWallet::GetNewDestination(const OutputType type, const std::string label, CTxDestination& dest, std::string& error)
3517+
{
3518+
LOCK(cs_wallet);
3519+
error.clear();
3520+
if (!IsLocked()) {
3521+
TopUpKeyPool();
3522+
}
3523+
3524+
// Generate a new key that is added to wallet
3525+
CPubKey new_key;
3526+
if (!GetKeyFromPool(new_key)) {
3527+
error = "Error: Keypool ran out, please call keypoolrefill first";
3528+
return false;
3529+
}
3530+
LearnRelatedScripts(new_key, type);
3531+
dest = GetDestinationForKey(new_key, type);
3532+
3533+
SetAddressBook(dest, label, "receive");
3534+
return true;
3535+
}
3536+
35163537
static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, WalletBatch& batch) {
35173538
if (setKeyPool.empty()) {
35183539
return GetTime();

src/wallet/wallet.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,9 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
815815
*/
816816
uint256 m_last_block_processed GUARDED_BY(cs_wallet);
817817

818+
//! Fetches a key from the keypool
819+
bool GetKeyFromPool(CPubKey &key, bool internal = false);
820+
818821
public:
819822
/*
820823
* Main wallet lock.
@@ -1110,7 +1113,6 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
11101113
bool ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
11111114
void KeepKey(int64_t nIndex);
11121115
void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey);
1113-
bool GetKeyFromPool(CPubKey &key, bool internal = false);
11141116
int64_t GetOldestKeyPoolTime();
11151117
/**
11161118
* Marks all keys in the keypool up to and including reserve_key as used.
@@ -1123,6 +1125,8 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
11231125

11241126
std::set<CTxDestination> GetLabelAddresses(const std::string& label) const;
11251127

1128+
bool GetNewDestination(const OutputType type, const std::string label, CTxDestination& dest, std::string& error);
1129+
11261130
isminetype IsMine(const CTxIn& txin) const;
11271131
/**
11281132
* Returns amount of debit if the input matches the

0 commit comments

Comments
 (0)