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.
This commit is contained in:
parent
0853d8d2fd
commit
172213be5b
9 changed files with 52 additions and 41 deletions
|
@ -140,9 +140,11 @@ public:
|
|||
void abortRescan() override { m_wallet->AbortRescan(); }
|
||||
bool backupWallet(const std::string& filename) override { return m_wallet->BackupWallet(filename); }
|
||||
std::string getWalletName() override { return m_wallet->GetName(); }
|
||||
bool getKeyFromPool(bool internal, CPubKey& pub_key) override
|
||||
bool getNewDestination(const OutputType type, const std::string label, CTxDestination& dest) override
|
||||
{
|
||||
return m_wallet->GetKeyFromPool(pub_key, internal);
|
||||
LOCK(m_wallet->cs_wallet);
|
||||
std::string error;
|
||||
return m_wallet->GetNewDestination(type, label, dest, error);
|
||||
}
|
||||
bool getPubKey(const CKeyID& address, CPubKey& pub_key) override { return m_wallet->GetPubKey(address, pub_key); }
|
||||
bool getPrivKey(const CKeyID& address, CKey& key) override { return m_wallet->GetKey(address, key); }
|
||||
|
|
|
@ -76,8 +76,8 @@ public:
|
|||
//! Get wallet name.
|
||||
virtual std::string getWalletName() = 0;
|
||||
|
||||
// Get key from pool.
|
||||
virtual bool getKeyFromPool(bool internal, CPubKey& pub_key) = 0;
|
||||
// Get a new address.
|
||||
virtual bool getNewDestination(const OutputType type, const std::string label, CTxDestination& dest) = 0;
|
||||
|
||||
//! Get public key.
|
||||
virtual bool getPubKey(const CKeyID& address, CPubKey& pub_key) = 0;
|
||||
|
|
|
@ -358,12 +358,15 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
// Add entry
|
||||
walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel, "send");
|
||||
}
|
||||
else if(type == Receive)
|
||||
{
|
||||
// Generate a new address to associate with given label
|
||||
CPubKey newKey;
|
||||
if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey))
|
||||
CTxDestination dest;
|
||||
if(!walletModel->wallet().getNewDestination(address_type, strLabel, dest))
|
||||
{
|
||||
WalletModel::UnlockContext ctx(walletModel->requestUnlock());
|
||||
if(!ctx.isValid())
|
||||
|
@ -372,23 +375,18 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
|
|||
editStatus = WALLET_UNLOCK_FAILURE;
|
||||
return QString();
|
||||
}
|
||||
if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey))
|
||||
if(!walletModel->wallet().getNewDestination(address_type, strLabel, dest))
|
||||
{
|
||||
editStatus = KEY_GENERATION_FAILURE;
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
walletModel->wallet().learnRelatedScripts(newKey, address_type);
|
||||
strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type));
|
||||
strAddress = EncodeDestination(dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
// Add entry
|
||||
walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel,
|
||||
(type == Send ? "send" : "receive"));
|
||||
return QString::fromStdString(strAddress);
|
||||
}
|
||||
|
||||
|
|
|
@ -666,16 +666,14 @@ void PaymentServer::fetchPaymentACK(WalletModel* walletModel, const SendCoinsRec
|
|||
payment.add_transactions(transaction.data(), transaction.size());
|
||||
|
||||
// Create a new refund address, or re-use:
|
||||
CPubKey newKey;
|
||||
if (walletModel->wallet().getKeyFromPool(false /* internal */, newKey)) {
|
||||
CTxDestination dest;
|
||||
const OutputType change_type = walletModel->wallet().getDefaultChangeType() != OutputType::CHANGE_AUTO ? walletModel->wallet().getDefaultChangeType() : walletModel->wallet().getDefaultAddressType();
|
||||
if (walletModel->wallet().getNewDestination(change_type, "", dest)) {
|
||||
// BIP70 requests encode the scriptPubKey directly, so we are not restricted to address
|
||||
// types supported by the receiver. As a result, we choose the address format we also
|
||||
// use for change. Despite an actual payment and not change, this is a close match:
|
||||
// it's the output type we use subject to privacy issues, but not restricted by what
|
||||
// other software supports.
|
||||
const OutputType change_type = walletModel->wallet().getDefaultChangeType() != OutputType::CHANGE_AUTO ? walletModel->wallet().getDefaultChangeType() : walletModel->wallet().getDefaultAddressType();
|
||||
walletModel->wallet().learnRelatedScripts(newKey, change_type);
|
||||
CTxDestination dest = GetDestinationForKey(newKey, change_type);
|
||||
std::string label = tr("Refund from %1").arg(recipient.authenticatedMerchant).toStdString();
|
||||
walletModel->wallet().setAddressBook(dest, label, "refund");
|
||||
|
||||
|
|
|
@ -25,14 +25,9 @@ const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqq
|
|||
std::string getnewaddress(CWallet& w)
|
||||
{
|
||||
constexpr auto output_type = OutputType::BECH32;
|
||||
|
||||
CPubKey new_key;
|
||||
if (!w.GetKeyFromPool(new_key)) assert(false);
|
||||
|
||||
w.LearnRelatedScripts(new_key, output_type);
|
||||
const auto dest = GetDestinationForKey(new_key, output_type);
|
||||
|
||||
w.SetAddressBook(dest, /* label */ "", "receive");
|
||||
CTxDestination dest;
|
||||
std::string error;
|
||||
if (!w.GetNewDestination(output_type, "", dest, error)) assert(false);
|
||||
|
||||
return EncodeDestination(dest);
|
||||
}
|
||||
|
|
|
@ -185,20 +185,12 @@ static UniValue getnewaddress(const JSONRPCRequest& request)
|
|||
}
|
||||
}
|
||||
|
||||
if (!pwallet->IsLocked()) {
|
||||
pwallet->TopUpKeyPool();
|
||||
CTxDestination dest;
|
||||
std::string error;
|
||||
if (!pwallet->GetNewDestination(output_type, label, dest, error)) {
|
||||
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, error);
|
||||
}
|
||||
|
||||
// Generate a new key that is added to wallet
|
||||
CPubKey newKey;
|
||||
if (!pwallet->GetKeyFromPool(newKey)) {
|
||||
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
|
||||
}
|
||||
pwallet->LearnRelatedScripts(newKey, output_type);
|
||||
CTxDestination dest = GetDestinationForKey(newKey, output_type);
|
||||
|
||||
pwallet->SetAddressBook(dest, label, "receive");
|
||||
|
||||
return EncodeDestination(dest);
|
||||
}
|
||||
|
||||
|
|
|
@ -466,8 +466,9 @@ BOOST_FIXTURE_TEST_CASE(wallet_disableprivkeys, TestChain100Setup)
|
|||
wallet->SetMinVersion(FEATURE_LATEST);
|
||||
wallet->SetWalletFlag(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
|
||||
BOOST_CHECK(!wallet->TopUpKeyPool(1000));
|
||||
CPubKey pubkey;
|
||||
BOOST_CHECK(!wallet->GetKeyFromPool(pubkey, false));
|
||||
CTxDestination dest;
|
||||
std::string error;
|
||||
BOOST_CHECK(!wallet->GetNewDestination(OutputType::BECH32, "", dest, error));
|
||||
}
|
||||
|
||||
// Explicit calculation which is used to test the wallet constant
|
||||
|
|
|
@ -3513,6 +3513,27 @@ bool CWallet::GetKeyFromPool(CPubKey& result, bool internal)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CWallet::GetNewDestination(const OutputType type, const std::string label, CTxDestination& dest, std::string& error)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
error.clear();
|
||||
if (!IsLocked()) {
|
||||
TopUpKeyPool();
|
||||
}
|
||||
|
||||
// Generate a new key that is added to wallet
|
||||
CPubKey new_key;
|
||||
if (!GetKeyFromPool(new_key)) {
|
||||
error = "Error: Keypool ran out, please call keypoolrefill first";
|
||||
return false;
|
||||
}
|
||||
LearnRelatedScripts(new_key, type);
|
||||
dest = GetDestinationForKey(new_key, type);
|
||||
|
||||
SetAddressBook(dest, label, "receive");
|
||||
return true;
|
||||
}
|
||||
|
||||
static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, WalletBatch& batch) {
|
||||
if (setKeyPool.empty()) {
|
||||
return GetTime();
|
||||
|
|
|
@ -815,6 +815,9 @@ private:
|
|||
*/
|
||||
uint256 m_last_block_processed GUARDED_BY(cs_wallet);
|
||||
|
||||
//! Fetches a key from the keypool
|
||||
bool GetKeyFromPool(CPubKey &key, bool internal = false);
|
||||
|
||||
public:
|
||||
/*
|
||||
* Main wallet lock.
|
||||
|
@ -1110,7 +1113,6 @@ public:
|
|||
bool ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal);
|
||||
void KeepKey(int64_t nIndex);
|
||||
void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey);
|
||||
bool GetKeyFromPool(CPubKey &key, bool internal = false);
|
||||
int64_t GetOldestKeyPoolTime();
|
||||
/**
|
||||
* Marks all keys in the keypool up to and including reserve_key as used.
|
||||
|
@ -1123,6 +1125,8 @@ public:
|
|||
|
||||
std::set<CTxDestination> GetLabelAddresses(const std::string& label) const;
|
||||
|
||||
bool GetNewDestination(const OutputType type, const std::string label, CTxDestination& dest, std::string& error);
|
||||
|
||||
isminetype IsMine(const CTxIn& txin) const;
|
||||
/**
|
||||
* Returns amount of debit if the input matches the
|
||||
|
|
Loading…
Reference in a new issue