mirror of
https://github.com/oxen-io/oxen-core.git
synced 2023-12-14 02:22:56 +01:00
Use string_view for address lookups
Also DRY out a bunch of identical address-from-string code blocks.
This commit is contained in:
parent
5634c46d3d
commit
6f3d3edd0d
7 changed files with 89 additions and 132 deletions
|
@ -416,8 +416,9 @@ std::vector<std::vector<std::string>> DNSResolver::get_many(int type, const std:
|
|||
return results;
|
||||
}
|
||||
|
||||
std::string DNSResolver::get_dns_format_from_oa_address(std::string addr)
|
||||
std::string DNSResolver::get_dns_format_from_oa_address(std::string_view addr_v)
|
||||
{
|
||||
std::string addr{addr_v};
|
||||
auto first_at = addr.find("@");
|
||||
if (first_at == std::string::npos)
|
||||
return addr;
|
||||
|
@ -454,30 +455,25 @@ namespace dns_utils
|
|||
|
||||
//-----------------------------------------------------------------------
|
||||
// TODO: parse the string in a less stupid way, probably with regex
|
||||
std::string address_from_txt_record(const std::string& s)
|
||||
std::string address_from_txt_record(std::string_view s)
|
||||
{
|
||||
// make sure the txt record has "oa1:xmr" and find it
|
||||
auto pos = s.find("oa1:xmr");
|
||||
if (pos == std::string::npos)
|
||||
if (auto pos = s.find("oa1:xmr"); pos == std::string_view::npos)
|
||||
return {};
|
||||
// search from there to find "recipient_address="
|
||||
pos = s.find("recipient_address=", pos);
|
||||
if (pos == std::string::npos)
|
||||
s.remove_prefix(7); // eat it
|
||||
|
||||
if (auto pos = s.find("recipient_address="); pos == std::string_view::npos)
|
||||
return {};
|
||||
pos += 18; // move past "recipient_address="
|
||||
s.remove_prefix(18); // eat it
|
||||
|
||||
// find the next semicolon
|
||||
auto pos2 = s.find(";", pos);
|
||||
if (pos2 != std::string::npos)
|
||||
if (auto pos = s.find(";"); pos != std::string::npos)
|
||||
{
|
||||
// length of address == 95, we can at least validate that much here
|
||||
if (pos2 - pos == 95)
|
||||
{
|
||||
return s.substr(pos, 95);
|
||||
}
|
||||
else if (pos2 - pos == 106) // length of address == 106 --> integrated address
|
||||
{
|
||||
return s.substr(pos, 106);
|
||||
}
|
||||
if (pos == 95)
|
||||
return std::string{s.substr(0, 95)};
|
||||
else if (pos == 106) // length of address == 106 --> integrated address
|
||||
return std::string{s.substr(0, 106)};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -495,7 +491,7 @@ std::string address_from_txt_record(const std::string& s)
|
|||
*
|
||||
* @return a loki address (as a string) or an empty string
|
||||
*/
|
||||
std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec_valid)
|
||||
std::vector<std::string> addresses_from_url(const std::string_view url, bool& dnssec_valid)
|
||||
{
|
||||
std::vector<std::string> addresses;
|
||||
// get txt records
|
||||
|
@ -516,13 +512,14 @@ std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec
|
|||
std::string addr = address_from_txt_record(rec);
|
||||
if (addr.size())
|
||||
{
|
||||
addresses.push_back(addr);
|
||||
addresses.push_back(std::move(addr));
|
||||
}
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
|
||||
std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm)
|
||||
std::string get_account_address_as_str_from_url(const std::string_view url, bool& dnssec_valid,
|
||||
std::function<std::string(const std::string_view, const std::vector<std::string>&, bool)> dns_confirm)
|
||||
{
|
||||
// attempt to get address from dns query
|
||||
auto addresses = addresses_from_url(url, dnssec_valid);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <functional>
|
||||
#include <optional>
|
||||
#include <chrono>
|
||||
#include <string_view>
|
||||
|
||||
struct ub_ctx;
|
||||
|
||||
|
@ -133,7 +134,7 @@ public:
|
|||
*
|
||||
* @return dns_addr DNS address
|
||||
*/
|
||||
std::string get_dns_format_from_oa_address(std::string oa_addr);
|
||||
std::string get_dns_format_from_oa_address(std::string_view oa_addr);
|
||||
|
||||
/**
|
||||
* @brief Gets the singleton instance of DNSResolver
|
||||
|
@ -179,10 +180,11 @@ private:
|
|||
namespace dns_utils
|
||||
{
|
||||
|
||||
std::string address_from_txt_record(const std::string& s);
|
||||
std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec_valid);
|
||||
std::string address_from_txt_record(std::string_view s);
|
||||
std::vector<std::string> addresses_from_url(const std::string_view url, bool& dnssec_valid);
|
||||
|
||||
std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> confirm_dns);
|
||||
std::string get_account_address_as_str_from_url(const std::string_view url, bool& dnssec_valid,
|
||||
std::function<std::string(const std::string_view, const std::vector<std::string>&, bool)> confirm_dns);
|
||||
|
||||
bool load_txt_records_from_dns(std::vector<std::string> &records, const std::vector<std::string> &dns_urls);
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ namespace cryptonote {
|
|||
bool get_account_address_from_str(
|
||||
address_parse_info& info
|
||||
, network_type nettype
|
||||
, std::string const & str
|
||||
, const std::string_view str
|
||||
)
|
||||
{
|
||||
uint64_t address_prefix = get_config(nettype).CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX;
|
||||
|
@ -268,8 +268,8 @@ namespace cryptonote {
|
|||
bool get_account_address_from_str_or_url(
|
||||
address_parse_info& info
|
||||
, network_type nettype
|
||||
, const std::string& str_or_url
|
||||
, std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm
|
||||
, const std::string_view str_or_url
|
||||
, std::function<std::string(const std::string_view, const std::vector<std::string>&, bool)> dns_confirm
|
||||
)
|
||||
{
|
||||
if (get_account_address_from_str(info, nettype, str_or_url))
|
||||
|
|
|
@ -94,14 +94,11 @@ namespace cryptonote {
|
|||
};
|
||||
#pragma pack (pop)
|
||||
|
||||
namespace
|
||||
inline std::string return_first_address(const std::string_view url, const std::vector<std::string> &addresses, bool dnssec_valid)
|
||||
{
|
||||
inline std::string return_first_address(const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)
|
||||
{
|
||||
if (addresses.empty())
|
||||
return {};
|
||||
return addresses[0];
|
||||
}
|
||||
if (addresses.empty())
|
||||
return {};
|
||||
return addresses[0];
|
||||
}
|
||||
|
||||
struct address_parse_info
|
||||
|
@ -110,6 +107,8 @@ namespace cryptonote {
|
|||
bool is_subaddress;
|
||||
bool has_payment_id;
|
||||
crypto::hash8 payment_id;
|
||||
|
||||
std::string as_str(network_type nettype) const;
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -135,17 +134,25 @@ namespace cryptonote {
|
|||
, const crypto::hash8& payment_id
|
||||
);
|
||||
|
||||
inline std::string address_parse_info::as_str(network_type nettype) const
|
||||
{
|
||||
if (has_payment_id)
|
||||
return get_account_integrated_address_as_str(nettype, address, payment_id);
|
||||
else
|
||||
return get_account_address_as_str(nettype, is_subaddress, address);
|
||||
}
|
||||
|
||||
bool get_account_address_from_str(
|
||||
address_parse_info& info
|
||||
, network_type nettype
|
||||
, const std::string& str
|
||||
, const std::string_view str
|
||||
);
|
||||
|
||||
bool get_account_address_from_str_or_url(
|
||||
address_parse_info& info
|
||||
, network_type nettype
|
||||
, const std::string& str_or_url
|
||||
, std::function<std::string(const std::string&, const std::vector<std::string>&, bool)> dns_confirm = return_first_address
|
||||
, const std::string_view str_or_url
|
||||
, std::function<std::string(const std::string_view, const std::vector<std::string>&, bool)> dns_confirm = return_first_address
|
||||
);
|
||||
|
||||
bool is_coinbase(const transaction& tx);
|
||||
|
|
|
@ -496,7 +496,7 @@ bool command_parser_executor::start_mining(const std::vector<std::string>& args)
|
|||
{
|
||||
bool dnssec_valid;
|
||||
std::string address_str = tools::dns_utils::get_account_address_as_str_from_url(args.front(), dnssec_valid,
|
||||
[](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid){return addresses[0];});
|
||||
[](const std::string_view url, const std::vector<std::string> &addresses, bool dnssec_valid){return addresses[0];});
|
||||
if(!cryptonote::get_account_address_from_str(info, cryptonote::MAINNET, address_str))
|
||||
{
|
||||
if(!cryptonote::get_account_address_from_str(info, cryptonote::TESTNET, address_str))
|
||||
|
|
|
@ -454,7 +454,7 @@ namespace
|
|||
return "invalid";
|
||||
}
|
||||
|
||||
std::string oa_prompter(const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)
|
||||
std::string oa_prompter(const std::string_view url, const std::vector<std::string> &addresses, bool dnssec_valid)
|
||||
{
|
||||
if (addresses.empty())
|
||||
return {};
|
||||
|
|
|
@ -609,6 +609,41 @@ namespace tools
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool extract_account_addr(
|
||||
cryptonote::address_parse_info& info,
|
||||
cryptonote::network_type nettype,
|
||||
std::string_view addr_or_url,
|
||||
epee::json_rpc::error& er)
|
||||
{
|
||||
if (!get_account_address_from_str_or_url(info, nettype, addr_or_url,
|
||||
[&er](const std::string_view url, const std::vector<std::string> &addresses, bool dnssec_valid) {
|
||||
if (!dnssec_valid)
|
||||
{
|
||||
er.message = "Invalid DNSSEC for "s;
|
||||
er.message += url;
|
||||
return ""s;
|
||||
}
|
||||
if (addresses.empty())
|
||||
{
|
||||
er.message = "No Loki address found at "s;
|
||||
er.message += url;
|
||||
return ""s;
|
||||
}
|
||||
return addresses[0];
|
||||
}))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
|
||||
if (er.message.empty())
|
||||
{
|
||||
er.message = "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: "s;
|
||||
er.message += addr_or_url;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::validate_transfer(const std::list<transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er)
|
||||
{
|
||||
|
@ -617,29 +652,11 @@ namespace tools
|
|||
for (auto it = destinations.begin(); it != destinations.end(); it++)
|
||||
{
|
||||
cryptonote::address_parse_info info;
|
||||
cryptonote::tx_destination_entry de;
|
||||
er.message = "";
|
||||
if(!get_account_address_from_str_or_url(info, m_wallet->nettype(), it->address,
|
||||
[&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
|
||||
if (!dnssec_valid)
|
||||
{
|
||||
er.message = std::string("Invalid DNSSEC for ") + url;
|
||||
return {};
|
||||
}
|
||||
if (addresses.empty())
|
||||
{
|
||||
er.message = std::string("No Loki address found at ") + url;
|
||||
return {};
|
||||
}
|
||||
return addresses[0];
|
||||
}))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
|
||||
if (er.message.empty())
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + it->address;
|
||||
if (!extract_account_addr(info, m_wallet->nettype(), it->address, er))
|
||||
return false;
|
||||
}
|
||||
|
||||
cryptonote::tx_destination_entry de;
|
||||
de.original = it->address;
|
||||
de.addr = info.address;
|
||||
de.is_subaddress = info.is_subaddress;
|
||||
|
@ -1877,24 +1894,8 @@ namespace tools
|
|||
|
||||
cryptonote::address_parse_info info;
|
||||
er.message = "";
|
||||
if(!get_account_address_from_str_or_url(info, m_wallet->nettype(), req.address,
|
||||
[&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
|
||||
if (!dnssec_valid)
|
||||
{
|
||||
er.message = std::string("Invalid DNSSEC for ") + url;
|
||||
return {};
|
||||
}
|
||||
if (addresses.empty())
|
||||
{
|
||||
er.message = std::string("No Loki address found at ") + url;
|
||||
return {};
|
||||
}
|
||||
return addresses[0];
|
||||
}))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
|
||||
if (!extract_account_addr(info, m_wallet->nettype(), req.address, er))
|
||||
return false;
|
||||
}
|
||||
|
||||
res.good = m_wallet->verify(req.data, info.address, req.signature);
|
||||
return true;
|
||||
|
@ -2685,26 +2686,9 @@ namespace tools
|
|||
|
||||
cryptonote::address_parse_info info;
|
||||
er.message = "";
|
||||
if(!get_account_address_from_str_or_url(info, m_wallet->nettype(), req.address,
|
||||
[&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
|
||||
if (!dnssec_valid)
|
||||
{
|
||||
er.message = std::string("Invalid DNSSEC for ") + url;
|
||||
return {};
|
||||
}
|
||||
if (addresses.empty())
|
||||
{
|
||||
er.message = std::string("No Loki address found at ") + url;
|
||||
return {};
|
||||
}
|
||||
return addresses[0];
|
||||
}))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
|
||||
if (er.message.empty())
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address;
|
||||
if (!extract_account_addr(info, m_wallet->nettype(), req.address, er))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_wallet->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : NULL, req.description, info.is_subaddress))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
|
||||
|
@ -2739,26 +2723,8 @@ namespace tools
|
|||
if (req.set_address)
|
||||
{
|
||||
er.message = "";
|
||||
if(!get_account_address_from_str_or_url(info, m_wallet->nettype(), req.address,
|
||||
[&er](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
|
||||
if (!dnssec_valid)
|
||||
{
|
||||
er.message = std::string("Invalid DNSSEC for ") + url;
|
||||
return {};
|
||||
}
|
||||
if (addresses.empty())
|
||||
{
|
||||
er.message = std::string("No Monero address found at ") + url;
|
||||
return {};
|
||||
}
|
||||
return addresses[0];
|
||||
}))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
|
||||
if (er.message.empty())
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: ") + req.address;
|
||||
if (!extract_account_addr(info, m_wallet->nettype(), req.address, er))
|
||||
return false;
|
||||
}
|
||||
entry.m_address = info.address;
|
||||
entry.m_is_subaddress = info.is_subaddress;
|
||||
if (info.has_payment_id)
|
||||
|
@ -4016,24 +3982,9 @@ namespace tools
|
|||
continue;
|
||||
if (req.allow_openalias)
|
||||
{
|
||||
std::string address;
|
||||
res.valid = get_account_address_from_str_or_url(info, net_type.type, req.address,
|
||||
[&er, &address](const std::string &url, const std::vector<std::string> &addresses, bool dnssec_valid)->std::string {
|
||||
if (!dnssec_valid)
|
||||
{
|
||||
er.message = std::string("Invalid DNSSEC for ") + url;
|
||||
return {};
|
||||
}
|
||||
if (addresses.empty())
|
||||
{
|
||||
er.message = std::string("No Loki address found at ") + url;
|
||||
return {};
|
||||
}
|
||||
address = addresses[0];
|
||||
return address;
|
||||
});
|
||||
res.valid = extract_account_addr(info, net_type.type, req.address, er);
|
||||
if (res.valid)
|
||||
res.openalias_address = address;
|
||||
res.openalias_address = info.as_str(net_type.type);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue