Don't cache decrypted LNS values

Our cached value could well be wrong, if another owner (or another copy
of the wallet) has updated it, and so the information we have in the
cache other than the name and type (which don't change) can be
unreliable.

Drop the cached value/owner fields and instead use queried values for
encrypted/owner/backup, and decrypt value on the fly when needed.
This commit is contained in:
Jason Rhinelander 2020-10-08 23:09:53 -03:00
parent f76c75f28c
commit 7e270530d3
3 changed files with 29 additions and 39 deletions

View File

@ -6528,10 +6528,7 @@ bool simple_wallet::lns_buy_mapping(std::vector<std::string> args)
tools::wallet2::lns_detail detail = {
*type,
name,
name_hash_str,
value,
owner.size() ? owner : m_wallet->get_subaddress_as_str({m_current_subaddress_account, 0}),
backup_owner.size() ? backup_owner : ""};
name_hash_str};
m_wallet->set_lns_cache_record(detail);
}
catch (const std::exception &e)
@ -6735,10 +6732,7 @@ bool simple_wallet::lns_update_mapping(std::vector<std::string> args)
tools::wallet2::lns_detail detail = {
type,
name,
name_hash_str,
value,
owner.size() ? owner : m_wallet->get_subaddress_as_str({m_current_subaddress_account, 0}),
backup_owner.size() ? backup_owner : ""};
name_hash_str};
m_wallet->set_lns_cache_record(detail);
}
@ -6923,8 +6917,6 @@ bool simple_wallet::lns_print_name_to_owners(std::vector<std::string> args)
return false;
}
std::unordered_map<std::string, tools::wallet2::lns_detail> cache = m_wallet->get_lns_cache();
// Print any skipped (i.e. not registered) results:
for (size_t i = last_index + 1; i < mapping.entry_index; i++)
fail_msg_writer() << args[i] << " not found\n";
@ -6942,8 +6934,6 @@ bool simple_wallet::lns_print_name_to_owners(std::vector<std::string> args)
return false;
}
std::unordered_map<std::string,tools::wallet2::lns_detail>::const_iterator got = cache.find (lns::name_to_base64_hash(name));
auto writer = tools::msg_writer();
writer
<< "Name: " << name
@ -6956,8 +6946,6 @@ bool simple_wallet::lns_print_name_to_owners(std::vector<std::string> args)
<< "\n Last updated height: " << mapping.update_height;
if (mapping.expiration_height) writer
<< "\n Expiration height: " << *mapping.expiration_height;
if ( got != cache.end() ) writer
<< "\n Value: " << got->second.value;
writer
<< "\n Encrypted value: " << enc_hex;
writer
@ -6967,10 +6955,7 @@ bool simple_wallet::lns_print_name_to_owners(std::vector<std::string> args)
{
static_cast<lns::mapping_type>(mapping.type),
name,
request.entries[0].name_hash,
value.to_readable_value(m_wallet->nettype(), static_cast<lns::mapping_type>(mapping.type)),
mapping.owner,
mapping.backup_owner.value_or(NULL_STR)};
request.entries[0].name_hash};
m_wallet->set_lns_cache_record(detail);
}
for (size_t i = last_index + 1; i < args.size(); i++)
@ -7034,6 +7019,7 @@ bool simple_wallet::lns_print_owners_to_names(const std::vector<std::string>& ar
}
auto nettype = m_wallet->nettype();
for (size_t i = 0; i < rpc_results.size(); i++)
{
auto const &rpc = rpc_results[i];
@ -7050,15 +7036,27 @@ bool simple_wallet::lns_print_owners_to_names(const std::vector<std::string>& ar
continue;
}
auto got = cache.find(entry.name_hash);
std::string_view name;
std::string value;
if (auto got = cache.find(entry.name_hash); got != cache.end())
{
name = got->second.name;
lns::mapping_value mv;
if (lns::mapping_value::validate_encrypted(entry.type, lokimq::from_hex(entry.encrypted_value), &mv)
&& mv.decrypt(name, entry.type))
value = mv.to_readable_value(nettype, entry.type);
}
auto writer = tools::msg_writer();
writer
<< "Name (hashed): " << entry.name_hash;
if ( got != cache.end() ) writer
<< "\n Name: " << got->second.name;
if (!name.empty()) writer
<< "\n Name: " << name;
writer
<< "\n Type: " << entry.type;
if (!value.empty()) writer
<< "\n Value: " << value;
writer
<< "\n Type: " << entry.type
<< "\n Owner: " << *owner;
if (entry.backup_owner) writer
<< "\n Backup owner: " << *entry.backup_owner;
@ -7066,8 +7064,6 @@ bool simple_wallet::lns_print_owners_to_names(const std::vector<std::string>& ar
<< "\n Last updated height: " << entry.update_height;
if (entry.expiration_height) writer
<< "\n Expiration height: " << *entry.expiration_height;
if ( got != cache.end() ) writer
<< "\n Value: " << got->second.value;
writer
<< "\n Encrypted value: " << entry.encrypted_value;
}

View File

@ -802,9 +802,6 @@ private:
lns::mapping_type type;
std::string name;
std::string hashed_name;
std::string value;
std::string owner;
std::string backup_owner;
};
std::unordered_map<std::string, lns_detail> lns_records_cache;
@ -1687,18 +1684,21 @@ BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 9)
BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 8)
BOOST_CLASS_VERSION(tools::wallet2::address_book_row, 18)
BOOST_CLASS_VERSION(tools::wallet2::reserve_proof_entry, 0)
BOOST_CLASS_VERSION(tools::wallet2::lns_detail, 1)
namespace boost::serialization
{
template <class Archive>
inline void serialize(Archive &a, tools::wallet2::lns_detail &x, const boost::serialization::version_type ver)
void serialize(Archive &a, tools::wallet2::lns_detail &x, const unsigned int ver)
{
a & x.type;
a & x.name;
a & x.hashed_name;
a & x.value;
a & x.owner;
a & x.backup_owner;
if (ver < 1)
{ // Old fields, no longer used:
std::string value, owner, backup_owner;
a & value & owner & backup_owner;
}
}
template <class Archive>

View File

@ -3081,10 +3081,7 @@ namespace {
tools::wallet2::lns_detail detail = {
*type,
req.name,
name_hash_str,
req.value,
req.owner.size() ? req.owner : m_wallet->get_subaddress_as_str({req.account_index, 0}),
req.backup_owner.size() ? req.backup_owner : ""};
name_hash_str};
m_wallet->set_lns_cache_record(detail);
fill_response( ptx_vector,
@ -3170,10 +3167,7 @@ namespace {
tools::wallet2::lns_detail detail = {
*type,
req.name,
name_hash_str,
req.value,
req.owner.size() ? req.owner : m_wallet->get_subaddress_as_str({req.account_index, 0}),
req.backup_owner.size() ? req.backup_owner : ""};
name_hash_str};
m_wallet->set_lns_cache_record(detail);
fill_response( ptx_vector,