aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r--src/wallet/wallet.cpp67
1 files changed, 29 insertions, 38 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 50405b78fe..6df0d12df6 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1229,7 +1229,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const SyncTxS
// (e.g. it wasn't generated on this node or we're restoring from backup)
// add it to the address book for proper transaction accounting
if (!*dest.internal && !FindAddressBookEntry(dest.dest, /* allow_change= */ false)) {
- SetAddressBook(dest.dest, "", "receive");
+ SetAddressBook(dest.dest, "", AddressPurpose::RECEIVE);
}
}
}
@@ -1777,7 +1777,7 @@ bool CWallet::ImportScriptPubKeys(const std::string& label, const std::set<CScri
CTxDestination dest;
ExtractDestination(script, dest);
if (IsValidDestination(dest)) {
- SetAddressBookWithDB(batch, dest, label, "receive");
+ SetAddressBookWithDB(batch, dest, label, AddressPurpose::RECEIVE);
}
}
}
@@ -2400,35 +2400,40 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
return DBErrors::LOAD_OK;
}
-bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
+bool CWallet::SetAddressBookWithDB(WalletBatch& batch, const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& new_purpose)
{
bool fUpdated = false;
bool is_mine;
+ std::optional<AddressPurpose> purpose;
{
LOCK(cs_wallet);
std::map<CTxDestination, CAddressBookData>::iterator mi = m_address_book.find(address);
fUpdated = (mi != m_address_book.end() && !mi->second.IsChange());
m_address_book[address].SetLabel(strName);
- if (!strPurpose.empty()) /* update purpose only if requested */
- m_address_book[address].purpose = strPurpose;
is_mine = IsMine(address) != ISMINE_NO;
+ if (new_purpose) { /* update purpose only if requested */
+ purpose = m_address_book[address].purpose = new_purpose;
+ } else {
+ purpose = m_address_book[address].purpose;
+ }
}
+ // In very old wallets, address purpose may not be recorded so we derive it from IsMine
NotifyAddressBookChanged(address, strName, is_mine,
- strPurpose, (fUpdated ? CT_UPDATED : CT_NEW));
- if (!strPurpose.empty() && !batch.WritePurpose(EncodeDestination(address), strPurpose))
+ purpose.value_or(is_mine ? AddressPurpose::RECEIVE : AddressPurpose::SEND),
+ (fUpdated ? CT_UPDATED : CT_NEW));
+ if (new_purpose && !batch.WritePurpose(EncodeDestination(address), PurposeToString(*new_purpose)))
return false;
return batch.WriteName(EncodeDestination(address), strName);
}
-bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
+bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& strName, const std::optional<AddressPurpose>& purpose)
{
WalletBatch batch(GetDatabase());
- return SetAddressBookWithDB(batch, address, strName, strPurpose);
+ return SetAddressBookWithDB(batch, address, strName, purpose);
}
bool CWallet::DelAddressBook(const CTxDestination& address)
{
- bool is_mine;
WalletBatch batch(GetDatabase());
{
LOCK(cs_wallet);
@@ -2446,10 +2451,9 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
batch.EraseDestData(strAddress, item.first);
}
m_address_book.erase(address);
- is_mine = IsMine(address) != ISMINE_NO;
}
- NotifyAddressBookChanged(address, "", is_mine, "", CT_DELETED);
+ NotifyAddressBookChanged(address, "", /*is_mine=*/false, AddressPurpose::SEND, CT_DELETED);
batch.ErasePurpose(EncodeDestination(address));
return batch.EraseName(EncodeDestination(address));
@@ -2503,7 +2507,7 @@ util::Result<CTxDestination> CWallet::GetNewDestination(const OutputType type, c
auto op_dest = spk_man->GetNewDestination(type);
if (op_dest) {
- SetAddressBook(*op_dest, label, "receive");
+ SetAddressBook(*op_dest, label, AddressPurpose::RECEIVE);
}
return op_dest;
@@ -2553,7 +2557,7 @@ void CWallet::ForEachAddrBookEntry(const ListAddrBookFunc& func) const
AssertLockHeld(cs_wallet);
for (const std::pair<const CTxDestination, CAddressBookData>& item : m_address_book) {
const auto& entry = item.second;
- func(item.first, entry.GetLabel(), entry.purpose, entry.IsChange());
+ func(item.first, entry.GetLabel(), entry.IsChange(), entry.purpose);
}
}
@@ -2562,7 +2566,7 @@ std::vector<CTxDestination> CWallet::ListAddrBookAddresses(const std::optional<A
AssertLockHeld(cs_wallet);
std::vector<CTxDestination> result;
AddrBookFilter filter = _filter ? *_filter : AddrBookFilter();
- ForEachAddrBookEntry([&result, &filter](const CTxDestination& dest, const std::string& label, const std::string& purpose, bool is_change) {
+ ForEachAddrBookEntry([&result, &filter](const CTxDestination& dest, const std::string& label, bool is_change, const std::optional<AddressPurpose>& purpose) {
// Filter by change
if (filter.ignore_change && is_change) return;
// Filter by label
@@ -2573,14 +2577,14 @@ std::vector<CTxDestination> CWallet::ListAddrBookAddresses(const std::optional<A
return result;
}
-std::set<std::string> CWallet::ListAddrBookLabels(const std::string& purpose) const
+std::set<std::string> CWallet::ListAddrBookLabels(const std::optional<AddressPurpose> purpose) const
{
AssertLockHeld(cs_wallet);
std::set<std::string> label_set;
ForEachAddrBookEntry([&](const CTxDestination& _dest, const std::string& _label,
- const std::string& _purpose, bool _is_change) {
+ bool _is_change, const std::optional<AddressPurpose>& _purpose) {
if (_is_change) return;
- if (purpose.empty() || _purpose == purpose) {
+ if (!purpose || purpose == _purpose) {
label_set.insert(_label);
}
});
@@ -3792,7 +3796,7 @@ ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const Flat
for (const auto& script : script_pub_keys) {
CTxDestination dest;
if (ExtractDestination(script, dest)) {
- SetAddressBook(dest, label, "receive");
+ SetAddressBook(dest, label, AddressPurpose::RECEIVE);
}
}
}
@@ -3978,7 +3982,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
std::vector<CTxDestination> dests_to_delete;
for (const auto& addr_pair : m_address_book) {
// Labels applied to receiving addresses should go based on IsMine
- if (addr_pair.second.purpose == "receive") {
+ if (addr_pair.second.purpose == AddressPurpose::RECEIVE) {
if (!IsMine(addr_pair.first)) {
// Check the address book data is the watchonly wallet's
if (data.watchonly_wallet) {
@@ -3986,10 +3990,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
if (data.watchonly_wallet->IsMine(addr_pair.first)) {
// Add to the watchonly. Preserve the labels, purpose, and change-ness
std::string label = addr_pair.second.GetLabel();
- std::string purpose = addr_pair.second.purpose;
- if (!purpose.empty()) {
- data.watchonly_wallet->m_address_book[addr_pair.first].purpose = purpose;
- }
+ data.watchonly_wallet->m_address_book[addr_pair.first].purpose = addr_pair.second.purpose;
if (!addr_pair.second.IsChange()) {
data.watchonly_wallet->m_address_book[addr_pair.first].SetLabel(label);
}
@@ -4002,10 +4003,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
if (data.solvable_wallet->IsMine(addr_pair.first)) {
// Add to the solvable. Preserve the labels, purpose, and change-ness
std::string label = addr_pair.second.GetLabel();
- std::string purpose = addr_pair.second.purpose;
- if (!purpose.empty()) {
- data.solvable_wallet->m_address_book[addr_pair.first].purpose = purpose;
- }
+ data.solvable_wallet->m_address_book[addr_pair.first].purpose = addr_pair.second.purpose;
if (!addr_pair.second.IsChange()) {
data.solvable_wallet->m_address_book[addr_pair.first].SetLabel(label);
}
@@ -4023,10 +4021,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
LOCK(data.watchonly_wallet->cs_wallet);
// Add to the watchonly. Preserve the labels, purpose, and change-ness
std::string label = addr_pair.second.GetLabel();
- std::string purpose = addr_pair.second.purpose;
- if (!purpose.empty()) {
- data.watchonly_wallet->m_address_book[addr_pair.first].purpose = purpose;
- }
+ data.watchonly_wallet->m_address_book[addr_pair.first].purpose = addr_pair.second.purpose;
if (!addr_pair.second.IsChange()) {
data.watchonly_wallet->m_address_book[addr_pair.first].SetLabel(label);
}
@@ -4036,10 +4031,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
LOCK(data.solvable_wallet->cs_wallet);
// Add to the solvable. Preserve the labels, purpose, and change-ness
std::string label = addr_pair.second.GetLabel();
- std::string purpose = addr_pair.second.purpose;
- if (!purpose.empty()) {
- data.solvable_wallet->m_address_book[addr_pair.first].purpose = purpose;
- }
+ data.solvable_wallet->m_address_book[addr_pair.first].purpose = addr_pair.second.purpose;
if (!addr_pair.second.IsChange()) {
data.solvable_wallet->m_address_book[addr_pair.first].SetLabel(label);
}
@@ -4054,10 +4046,9 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
WalletBatch batch{wallet.GetDatabase()};
for (const auto& [destination, addr_book_data] : wallet.m_address_book) {
auto address{EncodeDestination(destination)};
- auto purpose{addr_book_data.purpose};
auto label{addr_book_data.GetLabel()};
// don't bother writing default values (unknown purpose, empty label)
- if (purpose != "unknown") batch.WritePurpose(address, purpose);
+ if (addr_book_data.purpose) batch.WritePurpose(address, PurposeToString(*addr_book_data.purpose));
if (!label.empty()) batch.WriteName(address, label);
}
};