Merge pull request #1075 from Doy-lee/LNSStoreWalletAddress

LNS: Store wallet addresses in LNS DB
This commit is contained in:
Doyle 2020-03-16 10:13:22 +11:00 committed by GitHub
commit 575cab3454
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 422 additions and 396 deletions

View file

@ -125,38 +125,6 @@ namespace crypto {
}; };
using x25519_secret_key = epee::mlocked<tools::scrubbed<x25519_secret_key_>>; using x25519_secret_key = epee::mlocked<tools::scrubbed<x25519_secret_key_>>;
enum struct generic_key_sig_type : uint8_t { monero, ed25519 };
struct generic_public_key
{
union
{
ed25519_public_key ed25519;
public_key monero;
unsigned char data[sizeof(ed25519_public_key)];
};
generic_key_sig_type type;
static constexpr generic_public_key null() { return {}; }
operator bool() const { return memcmp(data, null().data, sizeof(data)); }
bool operator==(generic_public_key const &other) const { return other.type == type && memcmp(data, other.data, sizeof(data)) == 0; }
};
struct generic_signature
{
union
{
ed25519_signature ed25519;
signature monero;
unsigned char data[sizeof(ed25519_signature)];
};
generic_key_sig_type type;
static constexpr generic_signature null() { return {}; }
operator bool() const { return memcmp(data, null().data, sizeof(data)); }
bool operator==(generic_signature const &other) const { return other.type == type && memcmp(data, other.data, sizeof(data)) == 0; }
};
static_assert(sizeof(ed25519_signature) == sizeof(crypto::signature), "LNS allows storing either ed25519 or monero style signatures, we store all signatures into crypto::signature in LNS");
static_assert(sizeof(ed25519_public_key) == sizeof(crypto::public_key), "LNS allows storing either ed25519 or monero style keys interchangeably, we store all keys into ed25519_public_key in LNS");
void hash_to_scalar(const void *data, size_t length, ec_scalar &res); void hash_to_scalar(const void *data, size_t length, ec_scalar &res);
void random32_unbiased(unsigned char *bytes); void random32_unbiased(unsigned char *bytes);
@ -306,12 +274,6 @@ namespace crypto {
inline std::ostream &operator <<(std::ostream &o, const crypto::x25519_public_key &v) { inline std::ostream &operator <<(std::ostream &o, const crypto::x25519_public_key &v) {
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
} }
inline std::ostream &operator <<(std::ostream &o, const crypto::generic_public_key &v) {
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
}
inline std::ostream &operator <<(std::ostream &o, const crypto::generic_signature &v) {
epee::to_hex::formatted(o, epee::as_byte_span(v)); return o;
}
const extern crypto::public_key null_pkey; const extern crypto::public_key null_pkey;
const extern crypto::secret_key null_skey; const extern crypto::secret_key null_skey;
} }
@ -324,8 +286,6 @@ EPEE_TYPE_IS_SPANNABLE(crypto::signature)
EPEE_TYPE_IS_SPANNABLE(crypto::ed25519_signature) EPEE_TYPE_IS_SPANNABLE(crypto::ed25519_signature)
EPEE_TYPE_IS_SPANNABLE(crypto::ed25519_public_key) EPEE_TYPE_IS_SPANNABLE(crypto::ed25519_public_key)
EPEE_TYPE_IS_SPANNABLE(crypto::x25519_public_key) EPEE_TYPE_IS_SPANNABLE(crypto::x25519_public_key)
EPEE_TYPE_IS_SPANNABLE(crypto::generic_public_key)
EPEE_TYPE_IS_SPANNABLE(crypto::generic_signature)
CRYPTO_MAKE_HASHABLE(public_key) CRYPTO_MAKE_HASHABLE(public_key)
CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(secret_key) CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(secret_key)

View file

@ -31,9 +31,7 @@
#pragma once #pragma once
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <boost/functional/hash/hash.hpp>
#include <vector> #include <vector>
#include <cstring> // memcmp
#include <sstream> #include <sstream>
#include <atomic> #include <atomic>
#include "serialization/variant.h" #include "serialization/variant.h"
@ -46,7 +44,6 @@
#include "cryptonote_config.h" #include "cryptonote_config.h"
#include "crypto/crypto.h" #include "crypto/crypto.h"
#include "crypto/hash.h" #include "crypto/hash.h"
#include "misc_language.h"
#include "ringct/rctTypes.h" #include "ringct/rctTypes.h"
#include "device/device.hpp" #include "device/device.hpp"
@ -520,6 +517,7 @@ namespace cryptonote
return !(*this == rhs); return !(*this == rhs);
} }
}; };
constexpr account_public_address const null_address{};
struct keypair struct keypair
{ {

View file

@ -1722,4 +1722,24 @@ namespace cryptonote
sc_sub((unsigned char*)key.data, (const unsigned char*)key.data, (const unsigned char*)hash.data); sc_sub((unsigned char*)key.data, (const unsigned char*)key.data, (const unsigned char*)hash.data);
return key; return key;
} }
}
std::string lns::generic_owner::to_string(cryptonote::network_type nettype) const
{
if (type == lns::generic_owner_sig_type::monero)
return cryptonote::get_account_address_as_str(nettype, wallet.is_subaddress, wallet.address);
else
return epee::to_hex::string(epee::as_byte_span(ed25519));
}
bool lns::generic_owner::operator==(generic_owner const &other) const
{
if (type != other.type)
return false;
if (type == lns::generic_owner_sig_type::monero)
return wallet.is_subaddress == other.wallet.is_subaddress && wallet.address == other.wallet.address;
else
return ed25519 == other.ed25519;
} }

View file

@ -36,6 +36,7 @@
#include "crypto/crypto.h" #include "crypto/crypto.h"
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include "loki_economy.h" #include "loki_economy.h"
#include "cryptonote_basic.h"
#define TX_EXTRA_PADDING_MAX_COUNT 255 #define TX_EXTRA_PADDING_MAX_COUNT 255
@ -84,6 +85,62 @@ constexpr inline extra_field operator|(extra_field a, extra_field b) { return st
constexpr inline extra_field operator&(extra_field a, extra_field b) { return static_cast<extra_field>(static_cast<uint8_t>(a) & static_cast<uint8_t>(b)); } constexpr inline extra_field operator&(extra_field a, extra_field b) { return static_cast<extra_field>(static_cast<uint8_t>(a) & static_cast<uint8_t>(b)); }
constexpr inline extra_field& operator|=(extra_field& a, extra_field b) { return a = a | b; } constexpr inline extra_field& operator|=(extra_field& a, extra_field b) { return a = a | b; }
constexpr inline extra_field& operator&=(extra_field& a, extra_field b) { return a = a & b; } constexpr inline extra_field& operator&=(extra_field& a, extra_field b) { return a = a & b; }
enum struct generic_owner_sig_type : uint8_t { monero, ed25519, _count };
struct generic_owner
{
union {
crypto::ed25519_public_key ed25519;
struct
{
cryptonote::account_public_address address;
bool is_subaddress;
char padding01_[7];
} wallet;
};
generic_owner_sig_type type;
char padding02_[7];
std::string to_string(cryptonote::network_type nettype) const;
operator bool() const { return (type == generic_owner_sig_type::monero) ? wallet.address != cryptonote::null_address : ed25519; }
bool operator==(generic_owner const &other) const;
BEGIN_SERIALIZE()
ENUM_FIELD(type, type < generic_owner_sig_type::_count)
if (type == generic_owner_sig_type::monero)
{
FIELD(wallet.address);
FIELD(wallet.is_subaddress);
}
else
{
FIELD(ed25519);
}
END_SERIALIZE()
};
static_assert(sizeof(generic_owner) == 80, "Unexpected padding, we store binary blobs into the LNS DB");
struct generic_signature
{
generic_owner_sig_type type;
union
{
crypto::ed25519_signature ed25519;
crypto::signature monero;
unsigned char data[sizeof(crypto::ed25519_signature)];
};
static constexpr generic_signature null() { return {}; }
operator bool() const { return memcmp(data, null().data, sizeof(data)); }
bool operator==(generic_signature const &other) const { return other.type == type && memcmp(data, other.data, sizeof(data)) == 0; }
BEGIN_SERIALIZE()
ENUM_FIELD(type, type < generic_owner_sig_type::_count)
FIELD(ed25519);
END_SERIALIZE()
};
static_assert(sizeof(crypto::ed25519_signature) == sizeof(crypto::signature), "LNS allows storing either ed25519 or monero style signatures, we store all signatures into crypto::signature in LNS");
inline std::ostream &operator<<(std::ostream &o, const generic_signature &v) { epee::to_hex::formatted(o, epee::as_byte_span(v.data)); return o; }
} }
namespace service_nodes { namespace service_nodes {
@ -408,15 +465,15 @@ namespace cryptonote
struct tx_extra_loki_name_system struct tx_extra_loki_name_system
{ {
uint8_t version = 0; uint8_t version = 0;
lns::mapping_type type; lns::mapping_type type;
crypto::hash name_hash; crypto::hash name_hash;
crypto::hash prev_txid = crypto::null_hash; // previous txid that purchased the mapping crypto::hash prev_txid = crypto::null_hash; // previous txid that purchased the mapping
lns::extra_field fields; lns::extra_field fields;
crypto::generic_public_key owner = {}; lns::generic_owner owner = {};
crypto::generic_public_key backup_owner = {}; lns::generic_owner backup_owner = {};
crypto::generic_signature signature = {}; lns::generic_signature signature = {};
std::string encrypted_value; // binary format of the name->value mapping std::string encrypted_value; // binary format of the name->value mapping
bool field_is_set (lns::extra_field bit) const { return (fields & bit) == bit; } bool field_is_set (lns::extra_field bit) const { return (fields & bit) == bit; }
bool field_any_set(lns::extra_field bit) const { return (fields & bit) != lns::extra_field::none; } bool field_any_set(lns::extra_field bit) const { return (fields & bit) != lns::extra_field::none; }
@ -424,7 +481,7 @@ namespace cryptonote
bool is_updating() const { return field_is_set(lns::extra_field::signature) && field_any_set(lns::extra_field::updatable_fields); } bool is_updating() const { return field_is_set(lns::extra_field::signature) && field_any_set(lns::extra_field::updatable_fields); }
bool is_buying() const { return (fields == lns::extra_field::buy || fields == lns::extra_field::buy_no_backup); } bool is_buying() const { return (fields == lns::extra_field::buy || fields == lns::extra_field::buy_no_backup); }
static tx_extra_loki_name_system make_buy(crypto::generic_public_key const &owner, crypto::generic_public_key const *backup_owner, lns::mapping_type type, crypto::hash const &name_hash, std::string const &encrypted_value, crypto::hash const &prev_txid) static tx_extra_loki_name_system make_buy(lns::generic_owner const &owner, lns::generic_owner const *backup_owner, lns::mapping_type type, crypto::hash const &name_hash, std::string const &encrypted_value, crypto::hash const &prev_txid)
{ {
tx_extra_loki_name_system result = {}; tx_extra_loki_name_system result = {};
result.fields = lns::extra_field::buy; result.fields = lns::extra_field::buy;
@ -442,12 +499,12 @@ namespace cryptonote
return result; return result;
} }
static tx_extra_loki_name_system make_update(crypto::generic_signature const &signature, static tx_extra_loki_name_system make_update(lns::generic_signature const &signature,
lns::mapping_type type, lns::mapping_type type,
crypto::hash const &name_hash, crypto::hash const &name_hash,
epee::span<const uint8_t> encrypted_value, epee::span<const uint8_t> encrypted_value,
crypto::generic_public_key const *owner, lns::generic_owner const *owner,
crypto::generic_public_key const *backup_owner, lns::generic_owner const *backup_owner,
crypto::hash const &prev_txid) crypto::hash const &prev_txid)
{ {
tx_extra_loki_name_system result = {}; tx_extra_loki_name_system result = {};

View file

@ -58,7 +58,7 @@ enum struct lns_db_setting_column
enum struct owner_record_column enum struct owner_record_column
{ {
id, id,
public_key, address,
}; };
enum struct mapping_record_column enum struct mapping_record_column
@ -92,19 +92,20 @@ static char const *mapping_record_column_string(mapping_record_column col)
} }
} }
static std::ostream &operator<<(std::ostream &stream, cryptonote::tx_extra_loki_name_system const &data) static std::string lns_extra_string(cryptonote::network_type nettype, cryptonote::tx_extra_loki_name_system const &data)
{ {
std::stringstream stream;
stream << "LNS Extra={"; stream << "LNS Extra={";
if (data.is_buying()) if (data.is_buying())
{ {
stream << "owner=" << data.owner; stream << "owner=" << data.owner.to_string(nettype);
if (data.backup_owner) stream << "backup_owner=" << data.backup_owner; stream << ", backup_owner=" << data.backup_owner ? data.backup_owner.to_string(nettype) : "(none)";
} }
else else
stream << "signature=" << epee::string_tools::pod_to_hex(data.signature); stream << "signature=" << epee::string_tools::pod_to_hex(data.signature.data);
stream << ", type=" << data.type << ", name_hash=" << data.name_hash << "}"; stream << ", type=" << data.type << ", name_hash=" << data.name_hash << "}";
return stream; return stream.str();
} }
static bool sql_copy_blob(sqlite3_stmt *statement, int column, void *dest, int dest_size) static bool sql_copy_blob(sqlite3_stmt *statement, int column, void *dest, int dest_size)
@ -198,7 +199,7 @@ static bool sql_run_statement(cryptonote::network_type nettype, lns_sql_type typ
{ {
auto *entry = reinterpret_cast<owner_record *>(context); auto *entry = reinterpret_cast<owner_record *>(context);
entry->id = sqlite3_column_int(statement, static_cast<int>(owner_record_column::id)); entry->id = sqlite3_column_int(statement, static_cast<int>(owner_record_column::id));
if (!sql_copy_blob(statement, static_cast<int>(owner_record_column::public_key), reinterpret_cast<void *>(&entry->key), sizeof(entry->key))) if (!sql_copy_blob(statement, static_cast<int>(owner_record_column::address), reinterpret_cast<void *>(&entry->address), sizeof(entry->address)))
return false; return false;
data_loaded = true; data_loaded = true;
} }
@ -334,7 +335,30 @@ uint64_t expiry_blocks(cryptonote::network_type nettype, mapping_type type, uint
return result; return result;
} }
crypto::hash tx_extra_signature_hash(epee::span<const uint8_t> value, crypto::generic_public_key const *owner, crypto::generic_public_key const *backup_owner, crypto::hash const &prev_txid) static uint8_t *memcpy_helper(uint8_t *dest, void const *src, size_t size)
{
memcpy(reinterpret_cast<uint8_t *>(dest), src, size);
return dest + size;
}
static uint8_t *memcpy_generic_owner_helper(uint8_t *dest, lns::generic_owner const *owner)
{
if (!owner) return dest;
uint8_t *result = memcpy_helper(dest, reinterpret_cast<uint8_t const *>(&owner->type), sizeof(owner->type));
void const *src = &owner->wallet.address;
size_t src_len = sizeof(owner->wallet.address);
if (owner->type == lns::generic_owner_sig_type::ed25519)
{
src = &owner->ed25519;
src_len = sizeof(owner->ed25519);
}
result = memcpy_helper(result, src, src_len);
return result;
}
crypto::hash tx_extra_signature_hash(epee::span<const uint8_t> value, lns::generic_owner const *owner, lns::generic_owner const *backup_owner, crypto::hash const &prev_txid)
{ {
static_assert(sizeof(crypto::hash) == crypto_generichash_BYTES, "Using libsodium generichash for signature hash, require we fit into crypto::hash"); static_assert(sizeof(crypto::hash) == crypto_generichash_BYTES, "Using libsodium generichash for signature hash, require we fit into crypto::hash");
crypto::hash result = {}; crypto::hash result = {};
@ -344,85 +368,78 @@ crypto::hash tx_extra_signature_hash(epee::span<const uint8_t> value, crypto::ge
return result; return result;
} }
unsigned char buffer[mapping_value::BUFFER_SIZE + sizeof(*owner) + sizeof(*backup_owner) + sizeof(prev_txid)] = {}; uint8_t buffer[mapping_value::BUFFER_SIZE + sizeof(*owner) + sizeof(*backup_owner) + sizeof(prev_txid)] = {};
size_t buffer_len = value.size() + sizeof(prev_txid); uint8_t *ptr = memcpy_helper(buffer, value.data(), value.size());
if (owner) buffer_len += sizeof(owner->data) + sizeof(owner->type); ptr = memcpy_generic_owner_helper(ptr, owner);
if (backup_owner) buffer_len += sizeof(backup_owner->data) + sizeof(backup_owner->type); ptr = memcpy_generic_owner_helper(ptr, backup_owner);
unsigned char *ptr = buffer; if (ptr > (buffer + sizeof(buffer)))
memcpy(ptr, value.data(), value.size());
ptr += value.size();
if (owner)
{ {
memcpy(ptr, owner->data, sizeof(owner->data)); ptr += sizeof(owner->data); assert(ptr < buffer + sizeof(buffer));
memcpy(ptr, reinterpret_cast<uint8_t const *>(&owner->type), sizeof(owner->type)); ptr += sizeof(owner->type); MERROR("Unexpected buffer overflow");
return {};
} }
if (backup_owner) size_t buffer_len = ptr - buffer;
{
memcpy(ptr, backup_owner->data, sizeof(backup_owner->data)); ptr += sizeof(backup_owner->data);
memcpy(ptr, reinterpret_cast<uint8_t const *>(&backup_owner->type), sizeof(backup_owner->type)); ptr += sizeof(backup_owner->type);
}
static_assert(sizeof(owner->type) == sizeof(char), "Require byte alignment to avoid unaligned access exceptions"); static_assert(sizeof(owner->type) == sizeof(char), "Require byte alignment to avoid unaligned access exceptions");
crypto_generichash(reinterpret_cast<unsigned char *>(result.data), sizeof(result), buffer, buffer_len, NULL /*key*/, 0 /*key_len*/); crypto_generichash(reinterpret_cast<unsigned char *>(result.data), sizeof(result), buffer, buffer_len, NULL /*key*/, 0 /*key_len*/);
return result; return result;
} }
crypto::generic_signature make_monero_signature(crypto::hash const &hash, crypto::public_key const &pkey, crypto::secret_key const &skey) lns::generic_signature make_monero_signature(crypto::hash const &hash, crypto::public_key const &pkey, crypto::secret_key const &skey)
{ {
crypto::generic_signature result = {}; lns::generic_signature result = {};
result.type = crypto::generic_key_sig_type::monero; result.type = lns::generic_owner_sig_type::monero;
generate_signature(hash, pkey, skey, result.monero); generate_signature(hash, pkey, skey, result.monero);
return result; return result;
} }
crypto::generic_signature make_ed25519_signature(crypto::hash const &hash, crypto::ed25519_secret_key const &skey) lns::generic_signature make_ed25519_signature(crypto::hash const &hash, crypto::ed25519_secret_key const &skey)
{ {
crypto::generic_signature result = {}; lns::generic_signature result = {};
result.type = crypto::generic_key_sig_type::ed25519; result.type = lns::generic_owner_sig_type::ed25519;
crypto_sign_detached(result.ed25519.data, NULL, reinterpret_cast<unsigned char const *>(hash.data), sizeof(hash), skey.data); crypto_sign_detached(result.ed25519.data, NULL, reinterpret_cast<unsigned char const *>(hash.data), sizeof(hash), skey.data);
return result; return result;
} }
crypto::generic_public_key make_monero_public_key(crypto::public_key const &pkey) lns::generic_owner make_monero_owner(cryptonote::account_public_address const &owner, bool is_subaddress)
{ {
crypto::generic_public_key result = {}; lns::generic_owner result = {};
result.type = crypto::generic_key_sig_type::monero; result.type = lns::generic_owner_sig_type::monero;
result.monero = pkey; result.wallet.address = owner;
result.wallet.is_subaddress = is_subaddress;
return result; return result;
} }
crypto::generic_public_key make_ed25519_public_key(crypto::ed25519_public_key const &pkey) lns::generic_owner make_ed25519_owner(crypto::ed25519_public_key const &pkey)
{ {
crypto::generic_public_key result = {}; lns::generic_owner result = {};
result.type = crypto::generic_key_sig_type::ed25519; result.type = lns::generic_owner_sig_type::ed25519;
result.ed25519 = pkey; result.ed25519 = pkey;
return result; return result;
} }
bool parse_owner_to_generic_key(cryptonote::network_type nettype, std::string const &owner, crypto::generic_public_key &key, std::string *reason) bool parse_owner_to_generic_owner(cryptonote::network_type nettype, std::string const &owner, generic_owner &result, std::string *reason)
{ {
cryptonote::address_parse_info parsed_addr; cryptonote::address_parse_info parsed_addr;
crypto::ed25519_public_key ed_key; crypto::ed25519_public_key ed_owner;
if (cryptonote::get_account_address_from_str(parsed_addr, nettype, owner)) if (cryptonote::get_account_address_from_str(parsed_addr, nettype, owner))
{ {
key = lns::make_monero_public_key(parsed_addr.address.m_spend_public_key); result = lns::make_monero_owner(parsed_addr.address, parsed_addr.is_subaddress);
} }
else if (epee::string_tools::hex_to_pod(owner, key)) else if (epee::string_tools::hex_to_pod(owner, ed_owner))
{ {
key = lns::make_ed25519_public_key(ed_key); result = lns::make_ed25519_owner(ed_owner);
} }
else else
{ {
if (reason) if (reason)
{ {
char const *type_heuristic = char const *type_heuristic = (owner.size() == sizeof(crypto::ed25519_public_key) * 2) ? "ED25519 Key" : "Wallet address";
(owner.size() == sizeof(crypto::ed25519_public_key) * 2) ? "ED25519 Key" : "Wallet address";
*reason = type_heuristic; *reason = type_heuristic;
*reason += " provided could not be parsed owner="; *reason += " provided could not be parsed owner=";
*reason += key; *reason += owner;
} }
return false; return false;
} }
@ -689,17 +706,17 @@ static std::string hash_to_base64(crypto::hash const &hash)
return result; return result;
} }
static bool verify_lns_signature(crypto::hash const &hash, crypto::generic_signature const &signature, crypto::generic_public_key const &key) static bool verify_lns_signature(crypto::hash const &hash, lns::generic_signature const &signature, lns::generic_owner const &owner)
{ {
if (!key) return false; if (!owner || !signature) return false;
if (key.type != signature.type) return false; if (owner.type != signature.type) return false;
if (signature.type == crypto::generic_key_sig_type::monero) if (signature.type == lns::generic_owner_sig_type::monero)
{ {
return crypto::check_signature(hash, key.monero, signature.monero); return crypto::check_signature(hash, owner.wallet.address.m_spend_public_key, signature.monero);
} }
else else
{ {
return (crypto_sign_verify_detached(signature.data, reinterpret_cast<unsigned char const *>(hash.data), sizeof(hash.data), key.ed25519.data) == 0); return (crypto_sign_verify_detached(signature.data, reinterpret_cast<unsigned char const *>(hash.data), sizeof(hash.data), owner.ed25519.data) == 0);
} }
} }
@ -712,7 +729,7 @@ static bool validate_against_previous_mapping(lns::name_system_db const &lns_db,
std::string name_hash = hash_to_base64(lns_extra.name_hash); std::string name_hash = hash_to_base64(lns_extra.name_hash);
lns::mapping_record mapping = lns_db.get_mapping(lns_extra.type, name_hash); lns::mapping_record mapping = lns_db.get_mapping(lns_extra.type, name_hash);
if (check_condition(lns_extra.is_updating() && !mapping, reason, tx, ", ", lns_extra, " update requested but mapping does not exist.")) if (check_condition(lns_extra.is_updating() && !mapping, reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), " update requested but mapping does not exist."))
return false; return false;
if (mapping) if (mapping)
@ -720,19 +737,19 @@ static bool validate_against_previous_mapping(lns::name_system_db const &lns_db,
expected_prev_txid = mapping.txid; expected_prev_txid = mapping.txid;
if (lns_extra.is_updating()) if (lns_extra.is_updating())
{ {
if (check_condition(is_lokinet_type(lns_extra.type) && !mapping.active(lns_db.network_type(), blockchain_height), reason, tx, ", ", lns_extra, " TX requested to update mapping that has already expired")) if (check_condition(is_lokinet_type(lns_extra.type) && !mapping.active(lns_db.network_type(), blockchain_height), reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), " TX requested to update mapping that has already expired"))
return false; return false;
auto span_a = epee::strspan<uint8_t>(lns_extra.encrypted_value); auto span_a = epee::strspan<uint8_t>(lns_extra.encrypted_value);
auto span_b = mapping.encrypted_value.to_span(); auto span_b = mapping.encrypted_value.to_span();
char const SPECIFYING_SAME_VALUE_ERR[] = " field to update is specifying the same mapping "; char const SPECIFYING_SAME_VALUE_ERR[] = " field to update is specifying the same mapping ";
if (check_condition(lns_extra.field_is_set(lns::extra_field::encrypted_value) && (span_a.size() == span_b.size() && memcmp(span_a.data(), span_b.data(), span_a.size()) == 0), reason, tx, ", ", lns_extra, SPECIFYING_SAME_VALUE_ERR, "value")) if (check_condition(lns_extra.field_is_set(lns::extra_field::encrypted_value) && (span_a.size() == span_b.size() && memcmp(span_a.data(), span_b.data(), span_a.size()) == 0), reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), SPECIFYING_SAME_VALUE_ERR, "value"))
return false; return false;
if (check_condition(lns_extra.field_is_set(lns::extra_field::owner) && lns_extra.owner == mapping.owner, reason, tx, ", ", lns_extra, SPECIFYING_SAME_VALUE_ERR, "owner")) if (check_condition(lns_extra.field_is_set(lns::extra_field::owner) && lns_extra.owner == mapping.owner, reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), SPECIFYING_SAME_VALUE_ERR, "owner"))
return false; return false;
if (check_condition(lns_extra.field_is_set(lns::extra_field::backup_owner) && lns_extra.backup_owner == mapping.backup_owner, reason, tx, ", ", lns_extra, SPECIFYING_SAME_VALUE_ERR, "backup_owner")) if (check_condition(lns_extra.field_is_set(lns::extra_field::backup_owner) && lns_extra.backup_owner == mapping.backup_owner, reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), SPECIFYING_SAME_VALUE_ERR, "backup_owner"))
return false; return false;
// Validate signature // Validate signature
@ -744,7 +761,7 @@ static bool validate_against_previous_mapping(lns::name_system_db const &lns_db,
expected_prev_txid); expected_prev_txid);
if (check_condition(!verify_lns_signature(hash, lns_extra.signature, mapping.owner) && if (check_condition(!verify_lns_signature(hash, lns_extra.signature, mapping.owner) &&
!verify_lns_signature(hash, lns_extra.signature, mapping.backup_owner), reason, !verify_lns_signature(hash, lns_extra.signature, mapping.backup_owner), reason,
tx, ", ", lns_extra, " failed to verify signature for LNS update, current owner=", mapping.owner, ", backup owner=", mapping.backup_owner)) tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), " failed to verify signature for LNS update, current owner=", mapping.owner.to_string(lns_db.network_type()), ", backup owner=", mapping.backup_owner.to_string(lns_db.network_type())))
{ {
return false; return false;
} }
@ -754,8 +771,7 @@ static bool validate_against_previous_mapping(lns::name_system_db const &lns_db,
{ {
if (!is_lokinet_type(lns_extra.type)) if (!is_lokinet_type(lns_extra.type))
{ {
lns::owner_record owner = lns_db.get_owner_by_id(mapping.owner_id); if (check_condition(true, reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), " non-lokinet entries can NOT be renewed, mapping already exists with name_hash=", mapping.name_hash, ", owner=", mapping.owner.to_string(lns_db.network_type()), ", type=", mapping.type))
if (check_condition(true, reason, tx, ", ", lns_extra, " non-lokinet entries can NOT be renewed, mapping already exists with name_hash=", mapping.name_hash, ", owner=", owner.key, ", type=", mapping.type))
return false; return false;
} }
@ -770,7 +786,7 @@ static bool validate_against_previous_mapping(lns::name_system_db const &lns_db,
uint64_t const renew_window_offset = expiry_blocks - renew_window; uint64_t const renew_window_offset = expiry_blocks - renew_window;
uint64_t const min_renew_height = mapping.register_height + renew_window_offset; uint64_t const min_renew_height = mapping.register_height + renew_window_offset;
if (check_condition(min_renew_height >= blockchain_height, reason, tx, ", ", lns_extra, " trying to renew too early, the earliest renew height=", min_renew_height, ", current height=", blockchain_height)) if (check_condition(min_renew_height >= blockchain_height, reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), " trying to renew too early, the earliest renew height=", min_renew_height, ", current height=", blockchain_height))
return false; return false;
if (mapping.active(lns_db.network_type(), blockchain_height)) if (mapping.active(lns_db.network_type(), blockchain_height))
@ -778,14 +794,14 @@ static bool validate_against_previous_mapping(lns::name_system_db const &lns_db,
// Lokinet entry expired i.e. it's no longer active. A purchase for this name is valid // Lokinet entry expired i.e. it's no longer active. A purchase for this name is valid
// Check that the request originates from the owner of this mapping // Check that the request originates from the owner of this mapping
lns::owner_record const requester = lns_db.get_owner_by_key(lns_extra.owner); lns::owner_record const requester = lns_db.get_owner_by_key(lns_extra.owner);
if (check_condition(requester, reason, tx, ", ", lns_extra, " trying to renew existing mapping but owner specified in LNS extra does not exist, rejected")) if (check_condition(requester, reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), " trying to renew existing mapping but owner specified in LNS extra does not exist, rejected"))
return false; return false;
lns::owner_record const owner = lns_db.get_owner_by_id(mapping.owner_id); lns::owner_record const owner = lns_db.get_owner_by_id(mapping.owner_id);
if (check_condition(owner, reason, tx, ", ", lns_extra, " unexpected owner_id=", mapping.owner_id, " does not exist")) if (check_condition(owner, reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), " unexpected owner_id=", mapping.owner_id, " does not exist"))
return false; return false;
if (check_condition(requester.id != owner.id, reason, tx, ", ", lns_extra, " actual owner=", owner.key, ", with owner_id=", mapping.owner_id, ", does not match requester=", requester.key, ", with id=", requester.id)) if (check_condition(requester.id != owner.id, reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), " actual owner=", mapping.owner.to_string(lns_db.network_type()), ", with owner_id=", mapping.owner_id, ", does not match requester=", requester.address.to_string(lns_db.network_type()), ", with id=", requester.id))
return false; return false;
} }
@ -793,7 +809,7 @@ static bool validate_against_previous_mapping(lns::name_system_db const &lns_db,
} }
} }
if (check_condition(lns_extra.prev_txid != expected_prev_txid, reason, tx, ", ", lns_extra, " specified prior txid=", lns_extra.prev_txid, ", but LNS DB reports=", expected_prev_txid, ", possible competing TX was submitted and accepted before this TX was processed")) if (check_condition(lns_extra.prev_txid != expected_prev_txid, reason, tx, ", ", lns_extra_string(lns_db.network_type(), lns_extra), " specified prior txid=", lns_extra.prev_txid, ", but LNS DB reports=", expected_prev_txid, ", possible competing TX was submitted and accepted before this TX was processed"))
return false; return false;
return true; return true;
@ -820,16 +836,16 @@ bool name_system_db::validate_lns_tx(uint8_t hf_version, uint64_t blockchain_hei
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
{ {
char const VALUE_SPECIFIED_BUT_NOT_REQUESTED[] = ", given field but field is not requested to be serialised="; char const VALUE_SPECIFIED_BUT_NOT_REQUESTED[] = ", given field but field is not requested to be serialised=";
if (check_condition(!lns_extra->field_is_set(lns::extra_field::encrypted_value) && lns_extra->encrypted_value.size(), reason, tx, ", ", *lns_extra, VALUE_SPECIFIED_BUT_NOT_REQUESTED, "encrypted_value")) if (check_condition(!lns_extra->field_is_set(lns::extra_field::encrypted_value) && lns_extra->encrypted_value.size(), reason, tx, ", ", lns_extra_string(nettype, *lns_extra), VALUE_SPECIFIED_BUT_NOT_REQUESTED, "encrypted_value"))
return false; return false;
if (check_condition(!lns_extra->field_is_set(lns::extra_field::owner) && lns_extra->owner, reason, tx, ", ", *lns_extra, VALUE_SPECIFIED_BUT_NOT_REQUESTED, "owner")) if (check_condition(!lns_extra->field_is_set(lns::extra_field::owner) && lns_extra->owner, reason, tx, ", ", lns_extra_string(nettype, *lns_extra), VALUE_SPECIFIED_BUT_NOT_REQUESTED, "owner"))
return false; return false;
if (check_condition(!lns_extra->field_is_set(lns::extra_field::backup_owner) && lns_extra->backup_owner, reason, tx, ", ", *lns_extra, VALUE_SPECIFIED_BUT_NOT_REQUESTED, "backup_owner")) if (check_condition(!lns_extra->field_is_set(lns::extra_field::backup_owner) && lns_extra->backup_owner, reason, tx, ", ", lns_extra_string(nettype, *lns_extra), VALUE_SPECIFIED_BUT_NOT_REQUESTED, "backup_owner"))
return false; return false;
if (check_condition(!lns_extra->field_is_set(lns::extra_field::signature) && lns_extra->signature, reason, tx, ", ", *lns_extra, VALUE_SPECIFIED_BUT_NOT_REQUESTED, "signature")) if (check_condition(!lns_extra->field_is_set(lns::extra_field::signature) && lns_extra->signature, reason, tx, ", ", lns_extra_string(nettype, *lns_extra), VALUE_SPECIFIED_BUT_NOT_REQUESTED, "signature"))
return false; return false;
} }
@ -837,22 +853,22 @@ bool name_system_db::validate_lns_tx(uint8_t hf_version, uint64_t blockchain_hei
// Simple LNS Extra Validation // Simple LNS Extra Validation
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
{ {
if (check_condition(lns_extra->version != 0, reason, tx, ", ", *lns_extra, " unexpected version=", std::to_string(lns_extra->version), ", expected=0")) if (check_condition(lns_extra->version != 0, reason, tx, ", ", lns_extra_string(nettype, *lns_extra), " unexpected version=", std::to_string(lns_extra->version), ", expected=0"))
return false; return false;
if (check_condition(!lns::mapping_type_allowed(hf_version, lns_extra->type), reason, tx, ", ", *lns_extra, " specifying type=", lns_extra->type, " that is disallowed")) if (check_condition(!lns::mapping_type_allowed(hf_version, lns_extra->type), reason, tx, ", ", lns_extra_string(nettype, *lns_extra), " specifying type=", lns_extra->type, " that is disallowed"))
return false; return false;
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
// Serialized Values Check // Serialized Values Check
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
if (check_condition(!lns_extra->is_buying() && !lns_extra->is_updating(), reason, tx, ", ", *lns_extra, " TX extra does not specify valid combination of bits for serialized fields=", std::bitset<sizeof(lns_extra->fields) * 8>(static_cast<size_t>(lns_extra->fields)).to_string())) if (check_condition(!lns_extra->is_buying() && !lns_extra->is_updating(), reason, tx, ", ", lns_extra_string(nettype, *lns_extra), " TX extra does not specify valid combination of bits for serialized fields=", std::bitset<sizeof(lns_extra->fields) * 8>(static_cast<size_t>(lns_extra->fields)).to_string()))
return false; return false;
if (check_condition(lns_extra->field_is_set(lns::extra_field::owner) && if (check_condition(lns_extra->field_is_set(lns::extra_field::owner) &&
lns_extra->field_is_set(lns::extra_field::backup_owner) && lns_extra->field_is_set(lns::extra_field::backup_owner) &&
lns_extra->owner == lns_extra->backup_owner, lns_extra->owner == lns_extra->backup_owner,
reason, tx, ", ", *lns_extra, " specifying owner the same as the backup owner=", lns_extra->backup_owner)) reason, tx, ", ", lns_extra_string(nettype, *lns_extra), " specifying owner the same as the backup owner=", lns_extra->backup_owner.to_string(nettype)))
{ {
return false; return false;
} }
@ -863,7 +879,7 @@ bool name_system_db::validate_lns_tx(uint8_t hf_version, uint64_t blockchain_hei
// ----------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------
{ {
static const crypto::hash null_name_hash = name_to_hash(""); // Sanity check the empty name hash static const crypto::hash null_name_hash = name_to_hash(""); // Sanity check the empty name hash
if (check_condition((lns_extra->name_hash == null_name_hash || lns_extra->name_hash == crypto::null_hash), reason, tx, ", ", *lns_extra, " specified the null name hash")) if (check_condition((lns_extra->name_hash == null_name_hash || lns_extra->name_hash == crypto::null_hash), reason, tx, ", ", lns_extra_string(nettype, *lns_extra), " specified the null name hash"))
return false; return false;
if (lns_extra->field_is_set(lns::extra_field::encrypted_value)) if (lns_extra->field_is_set(lns::extra_field::encrypted_value))
@ -885,7 +901,7 @@ bool name_system_db::validate_lns_tx(uint8_t hf_version, uint64_t blockchain_hei
if (burn != burn_required) if (burn != burn_required)
{ {
char const *over_or_under = burn > burn_required ? "too much " : "insufficient "; char const *over_or_under = burn > burn_required ? "too much " : "insufficient ";
if (check_condition(true, reason, tx, ", ", *lns_extra, " burned ", over_or_under, "loki=", burn, ", require=", burn_required)) if (check_condition(true, reason, tx, ", ", lns_extra_string(nettype, *lns_extra), " burned ", over_or_under, "loki=", burn, ", require=", burn_required))
return false; return false;
} }
} }
@ -987,7 +1003,7 @@ static bool build_default_tables(sqlite3 *db)
constexpr char BUILD_TABLE_SQL[] = R"( constexpr char BUILD_TABLE_SQL[] = R"(
CREATE TABLE IF NOT EXISTS "owner"( CREATE TABLE IF NOT EXISTS "owner"(
"id" INTEGER PRIMARY KEY AUTOINCREMENT, "id" INTEGER PRIMARY KEY AUTOINCREMENT,
"public_key" BLOB NOT NULL UNIQUE "address" BLOB NOT NULL UNIQUE
); );
CREATE TABLE IF NOT EXISTS "settings" ( CREATE TABLE IF NOT EXISTS "settings" (
@ -1029,7 +1045,7 @@ static std::string sql_cmd_combine_mappings_and_owner_table(char const *suffix)
{ {
std::stringstream stream; std::stringstream stream;
stream << stream <<
R"(SELECT "mappings".*, "o1"."public_key", "o2"."public_key" FROM "mappings" R"(SELECT "mappings".*, "o1"."address", "o2"."address" FROM "mappings"
JOIN "owner" "o1" ON "mappings"."owner_id" = "o1"."id" JOIN "owner" "o1" ON "mappings"."owner_id" = "o1"."id"
LEFT JOIN "owner" "o2" ON "mappings"."backup_owner_id" = "o2"."id")" << "\n"; LEFT JOIN "owner" "o2" ON "mappings"."backup_owner_id" = "o2"."id")" << "\n";
@ -1046,12 +1062,12 @@ bool name_system_db::init(cryptonote::network_type nettype, sqlite3 *db, uint64_
this->db = db; this->db = db;
this->nettype = nettype; this->nettype = nettype;
std::string const get_mappings_by_owner_str = sql_cmd_combine_mappings_and_owner_table(R"(WHERE ? IN ("o1"."public_key", "o2"."public_key"))"); std::string const get_mappings_by_owner_str = sql_cmd_combine_mappings_and_owner_table(R"(WHERE ? IN ("o1"."address", "o2"."address"))");
std::string const get_mappings_on_height_and_newer_str = sql_cmd_combine_mappings_and_owner_table(R"(WHERE "register_height" >= ?)"); std::string const get_mappings_on_height_and_newer_str = sql_cmd_combine_mappings_and_owner_table(R"(WHERE "register_height" >= ?)");
std::string const get_mapping_str = sql_cmd_combine_mappings_and_owner_table(R"(WHERE "type" = ? AND "name_hash" = ?)"); std::string const get_mapping_str = sql_cmd_combine_mappings_and_owner_table(R"(WHERE "type" = ? AND "name_hash" = ?)");
char constexpr GET_OWNER_BY_ID_STR[] = R"(SELECT * FROM "owner" WHERE "id" = ?)"; char constexpr GET_OWNER_BY_ID_STR[] = R"(SELECT * FROM "owner" WHERE "id" = ?)";
char constexpr GET_OWNER_BY_KEY_STR[] = R"(SELECT * FROM "owner" WHERE "public_key" = ?)"; char constexpr GET_OWNER_BY_KEY_STR[] = R"(SELECT * FROM "owner" WHERE "address" = ?)";
char constexpr GET_SETTINGS_STR[] = R"(SELECT * FROM "settings" WHERE "id" = 1)"; char constexpr GET_SETTINGS_STR[] = R"(SELECT * FROM "settings" WHERE "id" = 1)";
char constexpr PRUNE_MAPPINGS_STR[] = R"(DELETE FROM "mappings" WHERE "register_height" >= ?)"; char constexpr PRUNE_MAPPINGS_STR[] = R"(DELETE FROM "mappings" WHERE "register_height" >= ?)";
@ -1061,7 +1077,7 @@ WHERE NOT EXISTS (SELECT * FROM "mappings" WHERE "owner"."id" = "mappings"."owne
AND NOT EXISTS (SELECT * FROM "mappings" WHERE "owner"."id" = "mappings"."backup_owner_id"))"; AND NOT EXISTS (SELECT * FROM "mappings" WHERE "owner"."id" = "mappings"."backup_owner_id"))";
char constexpr SAVE_MAPPING_STR[] = R"(INSERT OR REPLACE INTO "mappings" ("type", "name_hash", "encrypted_value", "txid", "prev_txid", "register_height", "owner_id", "backup_owner_id") VALUES (?,?,?,?,?,?,?,?))"; char constexpr SAVE_MAPPING_STR[] = R"(INSERT OR REPLACE INTO "mappings" ("type", "name_hash", "encrypted_value", "txid", "prev_txid", "register_height", "owner_id", "backup_owner_id") VALUES (?,?,?,?,?,?,?,?))";
char constexpr SAVE_OWNER_STR[] = R"(INSERT INTO "owner" ("public_key") VALUES (?))"; char constexpr SAVE_OWNER_STR[] = R"(INSERT INTO "owner" ("address") VALUES (?))";
char constexpr SAVE_SETTINGS_STR[] = R"(INSERT OR REPLACE INTO "settings" ("id", "top_height", "top_hash", "version") VALUES (1,?,?,?))"; char constexpr SAVE_SETTINGS_STR[] = R"(INSERT OR REPLACE INTO "settings" ("id", "top_height", "top_hash", "version") VALUES (1,?,?,?))";
sqlite3_stmt *test; sqlite3_stmt *test;
@ -1155,7 +1171,7 @@ scoped_db_transaction::~scoped_db_transaction()
lns_db.transaction_begun = false; lns_db.transaction_begun = false;
} }
static int64_t add_or_get_owner_id(lns::name_system_db &lns_db, crypto::hash const &tx_hash, cryptonote::tx_extra_loki_name_system const &entry, crypto::generic_public_key const &key) static int64_t add_or_get_owner_id(lns::name_system_db &lns_db, crypto::hash const &tx_hash, cryptonote::tx_extra_loki_name_system const &entry, lns::generic_owner const &key)
{ {
int64_t result = 0; int64_t result = 0;
if (owner_record owner = lns_db.get_owner_by_key(key)) result = owner.id; if (owner_record owner = lns_db.get_owner_by_key(key)) result = owner.id;
@ -1163,7 +1179,7 @@ static int64_t add_or_get_owner_id(lns::name_system_db &lns_db, crypto::hash con
{ {
if (!lns_db.save_owner(key, &result)) if (!lns_db.save_owner(key, &result))
{ {
LOG_PRINT_L1("Failed to save LNS owner to DB tx: " << tx_hash << ", type: " << entry.type << ", name_hash: " << entry.name_hash << ", owner: " << entry.owner); LOG_PRINT_L1("Failed to save LNS owner to DB tx: " << tx_hash << ", type: " << entry.type << ", name_hash: " << entry.name_hash << ", owner: " << entry.owner.to_string(lns_db.network_type()));
return result; return result;
} }
} }
@ -1180,7 +1196,7 @@ static bool add_lns_entry(lns::name_system_db &lns_db, uint64_t height, cryptono
int64_t owner_id = add_or_get_owner_id(lns_db, tx_hash, entry, entry.owner); int64_t owner_id = add_or_get_owner_id(lns_db, tx_hash, entry, entry.owner);
if (owner_id == 0) if (owner_id == 0)
{ {
MERROR("Failed to add or get owner with key=" << entry.owner); MERROR("Failed to add or get owner with key=" << entry.owner.to_string(lns_db.network_type()));
assert(owner_id != 0); assert(owner_id != 0);
return false; return false;
} }
@ -1191,7 +1207,7 @@ static bool add_lns_entry(lns::name_system_db &lns_db, uint64_t height, cryptono
backup_owner_id = add_or_get_owner_id(lns_db, tx_hash, entry, entry.backup_owner); backup_owner_id = add_or_get_owner_id(lns_db, tx_hash, entry, entry.backup_owner);
if (backup_owner_id == 0) if (backup_owner_id == 0)
{ {
MERROR("Failed to add or get backup owner with key=" << entry.backup_owner); MERROR("Failed to add or get backup owner with key=" << entry.backup_owner.to_string(lns_db.network_type()));
assert(backup_owner_id != 0); assert(backup_owner_id != 0);
return false; return false;
} }
@ -1199,7 +1215,7 @@ static bool add_lns_entry(lns::name_system_db &lns_db, uint64_t height, cryptono
if (!lns_db.save_mapping(tx_hash, entry, height, owner_id, backup_owner_id)) if (!lns_db.save_mapping(tx_hash, entry, height, owner_id, backup_owner_id))
{ {
LOG_PRINT_L1("Failed to save LNS entry to DB tx: " << tx_hash << ", type: " << entry.type << ", name_hash: " << entry.name_hash << ", owner: " << entry.owner); LOG_PRINT_L1("Failed to save LNS entry to DB tx: " << tx_hash << ", type: " << entry.type << ", name_hash: " << entry.name_hash << ", owner: " << entry.owner.to_string(lns_db.network_type()));
return false; return false;
} }
} }
@ -1225,7 +1241,7 @@ static bool add_lns_entry(lns::name_system_db &lns_db, uint64_t height, cryptono
owner_id = add_or_get_owner_id(lns_db, tx_hash, entry, entry.owner); owner_id = add_or_get_owner_id(lns_db, tx_hash, entry, entry.owner);
if (owner_id == 0) if (owner_id == 0)
{ {
MERROR("Failed to add or get owner with key=" << entry.owner); MERROR("Failed to add or get owner with key=" << entry.owner.to_string(lns_db.network_type()));
assert(owner_id != 0); assert(owner_id != 0);
return false; return false;
} }
@ -1237,7 +1253,7 @@ static bool add_lns_entry(lns::name_system_db &lns_db, uint64_t height, cryptono
backup_owner_id = add_or_get_owner_id(lns_db, tx_hash, entry, entry.backup_owner); backup_owner_id = add_or_get_owner_id(lns_db, tx_hash, entry, entry.backup_owner);
if (backup_owner_id == 0) if (backup_owner_id == 0)
{ {
MERROR("Failed to add or get backup owner with key=" << entry.backup_owner); MERROR("Failed to add or get backup owner with key=" << entry.backup_owner.to_string(lns_db.network_type()));
assert(backup_owner_id != 0); assert(backup_owner_id != 0);
return false; return false;
} }
@ -1471,11 +1487,11 @@ void name_system_db::block_detach(cryptonote::Blockchain const &blockchain, uint
} }
} }
bool name_system_db::save_owner(crypto::generic_public_key const &key, int64_t *row_id) bool name_system_db::save_owner(lns::generic_owner const &owner, int64_t *row_id)
{ {
sqlite3_stmt *statement = save_owner_sql; sqlite3_stmt *statement = save_owner_sql;
sqlite3_clear_bindings(statement); sqlite3_clear_bindings(statement);
sqlite3_bind_blob(statement, 1 /*sql param index*/, &key, sizeof(key), nullptr /*destructor*/); sqlite3_bind_blob(statement, 1 /*sql param index*/, &owner, sizeof(owner), nullptr /*destructor*/);
bool result = sql_run_statement(nettype, lns_sql_type::save_owner, statement, nullptr); bool result = sql_run_statement(nettype, lns_sql_type::save_owner, statement, nullptr);
if (row_id) *row_id = sqlite3_last_insert_rowid(db); if (row_id) *row_id = sqlite3_last_insert_rowid(db);
return result; return result;
@ -1529,11 +1545,11 @@ bool name_system_db::prune_db(uint64_t height)
return true; return true;
} }
owner_record name_system_db::get_owner_by_key(crypto::generic_public_key const &key) const owner_record name_system_db::get_owner_by_key(lns::generic_owner const &owner) const
{ {
sqlite3_stmt *statement = get_owner_by_key_sql; sqlite3_stmt *statement = get_owner_by_key_sql;
sqlite3_clear_bindings(statement); sqlite3_clear_bindings(statement);
sqlite3_bind_blob(statement, 1 /*sql param index*/, &key, sizeof(key), nullptr /*destructor*/); sqlite3_bind_blob(statement, 1 /*sql param index*/, &owner, sizeof(owner), nullptr /*destructor*/);
owner_record result = {}; owner_record result = {};
result.loaded = sql_run_statement(nettype, lns_sql_type::get_owner, statement, &result); result.loaded = sql_run_statement(nettype, lns_sql_type::get_owner, statement, &result);
@ -1599,37 +1615,38 @@ std::vector<mapping_record> name_system_db::get_mappings(std::vector<uint16_t> c
return result; return result;
} }
std::vector<mapping_record> name_system_db::get_mappings_by_owners(std::vector<crypto::generic_public_key> const &keys) const std::vector<mapping_record> name_system_db::get_mappings_by_owners(std::vector<generic_owner> const &owners) const
{ {
std::string sql_statement; std::string sql_statement;
// Generate string statement // Generate string statement
{ {
std::string const sql_prefix_str = sql_cmd_combine_mappings_and_owner_table(R"(WHERE "o1"."public_key" in ()"); std::string const sql_prefix_str = sql_cmd_combine_mappings_and_owner_table(R"(WHERE "o1"."address" in ()");
char constexpr SQL_MIDDLE[] = R"(OR "o2"."public_key" in ()"; char constexpr SQL_MIDDLE[] = R"( OR "o2"."address" in ()";
char constexpr SQL_SUFFIX[] = R"())"; char constexpr SQL_SUFFIX[] = R"())";
std::stringstream stream; std::stringstream stream;
stream << sql_prefix_str; stream << sql_prefix_str;
for (size_t i = 0; i < keys.size(); i++) for (size_t i = 0; i < owners.size(); i++)
{ {
stream << "?"; stream << "?";
if (i < (keys.size() - 1)) stream << ", "; if (i < (owners.size() - 1)) stream << ", ";
} }
stream << SQL_SUFFIX; stream << SQL_SUFFIX;
stream << SQL_MIDDLE; stream << SQL_MIDDLE;
for (size_t i = 0; i < keys.size(); i++) for (size_t i = 0; i < owners.size(); i++)
{ {
stream << "?"; stream << "?";
if (i < (keys.size() - 1)) stream << ", "; if (i < (owners.size() - 1)) stream << ", ";
} }
stream << SQL_SUFFIX; stream << SQL_SUFFIX;
stream << SQL_MIDDLE; stream << SQL_MIDDLE;
for (size_t i = 0; i < keys.size(); i++) for (size_t i = 0; i < owners.size(); i++)
{ {
stream << "?"; stream << "?";
if (i < (keys.size() - 1)) stream << ", "; if (i < (owners.size() - 1)) stream << ", ";
} }
stream << SQL_SUFFIX; stream << SQL_SUFFIX;
sql_statement = stream.str(); sql_statement = stream.str();
@ -1643,22 +1660,22 @@ std::vector<mapping_record> name_system_db::get_mappings_by_owners(std::vector<c
// Bind parameters statements // Bind parameters statements
int sql_param_index = 1; int sql_param_index = 1;
for (size_t i = 0; i < keys.size(); i++) for (size_t i = 0; i < owners.size(); i++)
for (auto const &key : keys) for (auto const &owner : owners)
sqlite3_bind_blob(statement, sql_param_index++, key.data, sizeof(key), nullptr /*destructor*/); sqlite3_bind_blob(statement, sql_param_index++, &owner, sizeof(owner), nullptr /*destructor*/);
// Execute // Execute
sql_run_statement(nettype, lns_sql_type::get_mappings_by_owners, statement, &result); sql_run_statement(nettype, lns_sql_type::get_mappings_by_owners, statement, &result);
return result; return result;
} }
std::vector<mapping_record> name_system_db::get_mappings_by_owner(crypto::generic_public_key const &key) const std::vector<mapping_record> name_system_db::get_mappings_by_owner(generic_owner const &owner) const
{ {
std::vector<mapping_record> result = {}; std::vector<mapping_record> result = {};
sqlite3_stmt *statement = get_mappings_by_owner_sql; sqlite3_stmt *statement = get_mappings_by_owner_sql;
sqlite3_clear_bindings(statement); sqlite3_clear_bindings(statement);
sqlite3_bind_blob(statement, 1 /*sql param index*/, key.data, sizeof(key), nullptr /*destructor*/); sqlite3_bind_blob(statement, 1 /*sql param index*/, &owner, sizeof(owner), nullptr /*destructor*/);
sqlite3_bind_blob(statement, 2 /*sql param index*/, key.data, sizeof(key), nullptr /*destructor*/); sqlite3_bind_blob(statement, 2 /*sql param index*/, &owner, sizeof(owner), nullptr /*destructor*/);
sql_run_statement(nettype, lns_sql_type::get_mappings_by_owner, statement, &result); sql_run_statement(nettype, lns_sql_type::get_mappings_by_owner, statement, &result);
return result; return result;
} }

View file

@ -67,12 +67,12 @@ uint64_t constexpr NO_EXPIRY = static_cast<uint64_t>(-1);
uint64_t expiry_blocks(cryptonote::network_type nettype, mapping_type type, uint64_t *renew_window = nullptr); uint64_t expiry_blocks(cryptonote::network_type nettype, mapping_type type, uint64_t *renew_window = nullptr);
bool validate_lns_name(mapping_type type, std::string name, std::string *reason = nullptr); bool validate_lns_name(mapping_type type, std::string name, std::string *reason = nullptr);
crypto::generic_signature make_monero_signature(crypto::hash const &hash, crypto::public_key const &pkey, crypto::secret_key const &skey); generic_signature make_monero_signature(crypto::hash const &hash, crypto::public_key const &pkey, crypto::secret_key const &skey);
crypto::generic_signature make_ed25519_signature(crypto::hash const &hash, crypto::ed25519_secret_key const &skey); generic_signature make_ed25519_signature(crypto::hash const &hash, crypto::ed25519_secret_key const &skey);
crypto::generic_public_key make_monero_public_key(crypto::public_key const &pkey); generic_owner make_monero_owner(cryptonote::account_public_address const &owner, bool is_subaddress);
crypto::generic_public_key make_ed25519_public_key(crypto::ed25519_public_key const &pkey); generic_owner make_ed25519_owner(crypto::ed25519_public_key const &pkey);
bool parse_owner_to_generic_key(cryptonote::network_type nettype, std::string const &owner, crypto::generic_public_key &key, std::string *reason); bool parse_owner_to_generic_owner(cryptonote::network_type nettype, std::string const &owner, generic_owner &key, std::string *reason);
crypto::hash tx_extra_signature_hash(epee::span<const uint8_t> value, crypto::generic_public_key const *owner, crypto::generic_public_key const *backup_owner, crypto::hash const &prev_txid); crypto::hash tx_extra_signature_hash(epee::span<const uint8_t> value, generic_owner const *owner, generic_owner const *backup_owner, crypto::hash const &prev_txid);
// Validate a human readable mapping value representation in 'value' and write the binary form into 'blob'. // Validate a human readable mapping value representation in 'value' and write the binary form into 'blob'.
// value: if type is session, 66 character hex string of an ed25519 public key // value: if type is session, 66 character hex string of an ed25519 public key
@ -101,7 +101,7 @@ struct owner_record
bool loaded; bool loaded;
int64_t id; int64_t id;
crypto::generic_public_key key; generic_owner address;
}; };
struct settings_record struct settings_record
@ -124,17 +124,17 @@ struct mapping_record
bool active(cryptonote::network_type nettype, uint64_t blockchain_height) const; bool active(cryptonote::network_type nettype, uint64_t blockchain_height) const;
operator bool() const { return loaded; } operator bool() const { return loaded; }
bool loaded; bool loaded;
mapping_type type; mapping_type type;
std::string name_hash; // name hashed and represented in base64 encoding std::string name_hash; // name hashed and represented in base64 encoding
mapping_value encrypted_value; mapping_value encrypted_value;
uint64_t register_height; uint64_t register_height;
crypto::hash txid; crypto::hash txid;
crypto::hash prev_txid; crypto::hash prev_txid;
int64_t owner_id; int64_t owner_id;
int64_t backup_owner_id; int64_t backup_owner_id;
crypto::generic_public_key owner; generic_owner owner;
crypto::generic_public_key backup_owner; generic_owner backup_owner;
}; };
struct name_system_db struct name_system_db
@ -147,19 +147,19 @@ struct name_system_db
// Signifies the blockchain has reorganized commences the rollback and pruning procedures. // Signifies the blockchain has reorganized commences the rollback and pruning procedures.
void block_detach(cryptonote::Blockchain const &blockchain, uint64_t new_blockchain_height); void block_detach(cryptonote::Blockchain const &blockchain, uint64_t new_blockchain_height);
bool save_owner (crypto::generic_public_key const &key, int64_t *row_id); bool save_owner (generic_owner const &owner, int64_t *row_id);
bool save_mapping (crypto::hash const &tx_hash, cryptonote::tx_extra_loki_name_system const &src, uint64_t height, int64_t owner_id, int64_t backup_owner_id = 0); bool save_mapping (crypto::hash const &tx_hash, cryptonote::tx_extra_loki_name_system const &src, uint64_t height, int64_t owner_id, int64_t backup_owner_id = 0);
bool save_settings (uint64_t top_height, crypto::hash const &top_hash, int version); bool save_settings (uint64_t top_height, crypto::hash const &top_hash, int version);
// Delete all mappings that are registered on height or newer followed by deleting all owners no longer referenced in the DB // Delete all mappings that are registered on height or newer followed by deleting all owners no longer referenced in the DB
bool prune_db(uint64_t height); bool prune_db(uint64_t height);
owner_record get_owner_by_key (crypto::generic_public_key const &key) const; owner_record get_owner_by_key (generic_owner const &owner) const;
owner_record get_owner_by_id (int64_t owner_id) const; owner_record get_owner_by_id (int64_t owner_id) const;
mapping_record get_mapping (mapping_type type, std::string const &name_base64_hash) const; mapping_record get_mapping (mapping_type type, std::string const &name_base64_hash) const;
std::vector<mapping_record> get_mappings (std::vector<uint16_t> const &types, std::string const &name_base64_hash) const; std::vector<mapping_record> get_mappings (std::vector<uint16_t> const &types, std::string const &name_base64_hash) const;
std::vector<mapping_record> get_mappings_by_owner (crypto::generic_public_key const &key) const; std::vector<mapping_record> get_mappings_by_owner (generic_owner const &key) const;
std::vector<mapping_record> get_mappings_by_owners(std::vector<crypto::generic_public_key> const &keys) const; std::vector<mapping_record> get_mappings_by_owners(std::vector<generic_owner> const &keys) const;
settings_record get_settings () const; settings_record get_settings () const;
// entry: (optional) if function returns true, the Loki Name System entry in the TX extra is copied into 'entry' // entry: (optional) if function returns true, the Loki Name System entry in the TX extra is copied into 'entry'

View file

@ -567,7 +567,6 @@ namespace service_nodes
bool make_friendly, bool make_friendly,
boost::optional<std::string&> err_msg); boost::optional<std::string&> err_msg);
const static cryptonote::account_public_address null_address{crypto::null_pkey, crypto::null_pkey}; const static std::vector<payout_entry> null_winner = {{cryptonote::null_address, STAKING_PORTIONS}};
const static std::vector<payout_entry> null_winner = {{null_address, STAKING_PORTIONS}};
const static block_winner null_block_winner = {crypto::null_pkey, {null_winner}}; const static block_winner null_block_winner = {crypto::null_pkey, {null_winner}};
} }

View file

@ -3409,8 +3409,8 @@ namespace cryptonote
entry.entry_index = request_index; entry.entry_index = request_index;
entry.type = static_cast<uint16_t>(record.type); entry.type = static_cast<uint16_t>(record.type);
entry.name_hash = record.name_hash; entry.name_hash = record.name_hash;
entry.owner = epee::string_tools::pod_to_hex(record.owner); entry.owner = record.owner.to_string(nettype());
if (record.backup_owner) entry.backup_owner = epee::string_tools::pod_to_hex(record.backup_owner); if (record.backup_owner) entry.backup_owner = record.backup_owner.to_string(nettype());
entry.encrypted_value = epee::to_hex::string(record.encrypted_value.to_span()); entry.encrypted_value = epee::to_hex::string(record.encrypted_value.to_span());
entry.register_height = record.register_height; entry.register_height = record.register_height;
entry.txid = epee::string_tools::pod_to_hex(record.txid); entry.txid = epee::string_tools::pod_to_hex(record.txid);
@ -3427,43 +3427,43 @@ namespace cryptonote
if (exceeds_quantity_limit(ctx, error_resp, m_restricted, req.entries.size(), COMMAND_RPC_LNS_OWNERS_TO_NAMES::MAX_REQUEST_ENTRIES)) if (exceeds_quantity_limit(ctx, error_resp, m_restricted, req.entries.size(), COMMAND_RPC_LNS_OWNERS_TO_NAMES::MAX_REQUEST_ENTRIES))
return false; return false;
std::map<crypto::generic_public_key, size_t> key_to_request_index; std::map<lns::generic_owner, size_t> owner_to_request_index;
std::vector<crypto::generic_public_key> keys; std::vector<lns::generic_owner> owners;
keys.reserve(req.entries.size()); owners.reserve(req.entries.size());
for (size_t request_index = 0; request_index < req.entries.size(); request_index++) for (size_t request_index = 0; request_index < req.entries.size(); request_index++)
{ {
std::string const &owner = req.entries[request_index]; std::string const &owner = req.entries[request_index];
crypto::generic_public_key pkey = {}; lns::generic_owner lns_owner = {};
if (!lns::parse_owner_to_generic_key(m_core.get_nettype(), owner, pkey, &error_resp.message)) if (!lns::parse_owner_to_generic_owner(m_core.get_nettype(), owner, lns_owner, &error_resp.message))
{ {
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM; error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
return false; return false;
} }
keys.push_back(pkey); owners.push_back(lns_owner);
key_to_request_index[keys.back()] = request_index; owner_to_request_index[owners.back()] = request_index;
} }
lns::name_system_db const &db = m_core.get_blockchain_storage().name_system_db(); lns::name_system_db const &db = m_core.get_blockchain_storage().name_system_db();
std::vector<lns::mapping_record> records = db.get_mappings_by_owners(keys); std::vector<lns::mapping_record> records = db.get_mappings_by_owners(owners);
for (auto &record : records) for (auto &record : records)
{ {
res.entries.emplace_back(); res.entries.emplace_back();
COMMAND_RPC_LNS_OWNERS_TO_NAMES::response_entry &entry = res.entries.back(); COMMAND_RPC_LNS_OWNERS_TO_NAMES::response_entry &entry = res.entries.back();
auto it = key_to_request_index.find(record.owner); auto it = owner_to_request_index.find(record.owner);
if (it == key_to_request_index.end()) if (it == owner_to_request_index.end())
{ {
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Public key=" + epee::string_tools::pod_to_hex(record.owner) + ", could not be mapped back a index in the request 'entries' array"; error_resp.message = "Owner=" + record.owner.to_string(nettype()) + ", could not be mapped back a index in the request 'entries' array";
return false; return false;
} }
entry.request_index = it->second; entry.request_index = it->second;
entry.type = static_cast<uint16_t>(record.type); entry.type = static_cast<uint16_t>(record.type);
entry.name_hash = std::move(record.name_hash); entry.name_hash = std::move(record.name_hash);
if (record.backup_owner) entry.backup_owner = epee::string_tools::pod_to_hex(record.backup_owner); if (record.backup_owner) entry.backup_owner = record.backup_owner.to_string(nettype());
entry.encrypted_value = epee::to_hex::string(record.encrypted_value.to_span()); entry.encrypted_value = epee::to_hex::string(record.encrypted_value.to_span());
entry.register_height = record.register_height; entry.register_height = record.register_height;
entry.txid = epee::string_tools::pod_to_hex(record.txid); entry.txid = epee::string_tools::pod_to_hex(record.txid);

View file

@ -77,42 +77,6 @@ bool do_serialize(Archive<true> &ar, std::vector<crypto::signature> &v)
return true; return true;
} }
template <template <bool> class Archive>
bool do_serialize(Archive<true /*write*/> &ar, crypto::generic_signature &sig)
{
ar.serialize_blob(sig.data, sizeof(crypto::signature), "");
ar.serialize_uint(static_cast<uint8_t>(sig.type));
return ar.stream().good();
}
template <template <bool> class Archive>
bool do_serialize(Archive<false /*read*/> &ar, crypto::generic_signature &sig)
{
ar.serialize_blob(sig.data, sizeof(sig.data), "");
uint8_t type = 0;
ar.serialize_uint(type);
sig.type = static_cast<decltype(sig.type)>(type);
return ar.stream().good();
}
template <template <bool> class Archive>
bool do_serialize(Archive<true /*write*/> &ar, crypto::generic_public_key &key)
{
ar.serialize_blob(key.data, sizeof(key.data), "");
ar.serialize_uint(static_cast<uint8_t>(key.type));
return ar.stream().good();
}
template <template <bool> class Archive>
bool do_serialize(Archive<false /*read*/> &ar, crypto::generic_public_key &key)
{
ar.serialize_blob(key.data, sizeof(key.data), "");
uint8_t type = 0;
ar.serialize_uint(type);
key.type = static_cast<decltype(key.type)>(type);
return ar.stream().good();
}
BLOB_SERIALIZER(crypto::chacha_iv); BLOB_SERIALIZER(crypto::chacha_iv);
BLOB_SERIALIZER(crypto::hash); BLOB_SERIALIZER(crypto::hash);
BLOB_SERIALIZER(crypto::hash8); BLOB_SERIALIZER(crypto::hash8);
@ -132,6 +96,3 @@ VARIANT_TAG(debug_archive, crypto::key_image, "key_image");
VARIANT_TAG(debug_archive, crypto::signature, "signature"); VARIANT_TAG(debug_archive, crypto::signature, "signature");
VARIANT_TAG(debug_archive, crypto::ed25519_public_key, "ed25519_public_key"); VARIANT_TAG(debug_archive, crypto::ed25519_public_key, "ed25519_public_key");
VARIANT_TAG(debug_archive, crypto::ed25519_signature, "ed25519_signature"); VARIANT_TAG(debug_archive, crypto::ed25519_signature, "ed25519_signature");
VARIANT_TAG(debug_archive, crypto::generic_public_key, "generic_public_key");
VARIANT_TAG(debug_archive, crypto::generic_signature, "generic_signature");

View file

@ -6507,7 +6507,7 @@ bool simple_wallet::lns_make_update_mapping_signature(const std::vector<std::str
std::string const &name = local_args[0]; std::string const &name = local_args[0];
SCOPED_WALLET_UNLOCK(); SCOPED_WALLET_UNLOCK();
crypto::generic_signature signature_binary; lns::generic_signature signature_binary;
std::string reason; std::string reason;
if (m_wallet->lns_make_update_mapping_signature(lns::mapping_type::session, if (m_wallet->lns_make_update_mapping_signature(lns::mapping_type::session,
name, name,
@ -6515,8 +6515,9 @@ bool simple_wallet::lns_make_update_mapping_signature(const std::vector<std::str
owner.size() ? &owner : nullptr, owner.size() ? &owner : nullptr,
backup_owner.size() ? &backup_owner : nullptr, backup_owner.size() ? &backup_owner : nullptr,
signature_binary, signature_binary,
m_current_subaddress_account,
&reason)) &reason))
tools::success_msg_writer() << "signature=" << epee::string_tools::pod_to_hex(signature_binary); tools::success_msg_writer() << "signature=" << epee::string_tools::pod_to_hex(signature_binary.ed25519);
else else
fail_msg_writer() << reason; fail_msg_writer() << reason;

View file

@ -8432,9 +8432,9 @@ struct lns_prepared_args
operator bool() const { return prepared; } operator bool() const { return prepared; }
lns::mapping_value encrypted_value; lns::mapping_value encrypted_value;
crypto::hash name_hash; crypto::hash name_hash;
crypto::generic_public_key owner; lns::generic_owner owner;
crypto::generic_public_key backup_owner; lns::generic_owner backup_owner;
crypto::generic_signature signature; lns::generic_signature signature;
crypto::hash prev_txid; crypto::hash prev_txid;
}; };
@ -8446,6 +8446,7 @@ static lns_prepared_args prepare_tx_extra_loki_name_system_values(wallet2 const
std::string const *owner, std::string const *owner,
std::string const *backup_owner, std::string const *backup_owner,
bool make_signature, bool make_signature,
uint32_t account_index,
std::string *reason) std::string *reason)
{ {
lns_prepared_args result = {}; lns_prepared_args result = {};
@ -8473,10 +8474,10 @@ static lns_prepared_args prepare_tx_extra_loki_name_system_values(wallet2 const
} }
} }
if (owner && !lns::parse_owner_to_generic_key(wallet.nettype(), *owner, result.owner, reason)) if (owner && !lns::parse_owner_to_generic_owner(wallet.nettype(), *owner, result.owner, reason))
return {}; return {};
if (backup_owner && !lns::parse_owner_to_generic_key(wallet.nettype(), *backup_owner, result.backup_owner, reason)) if (backup_owner && !lns::parse_owner_to_generic_owner(wallet.nettype(), *backup_owner, result.backup_owner, reason))
return {}; return {};
{ {
@ -8508,8 +8509,22 @@ static lns_prepared_args prepare_tx_extra_loki_name_system_values(wallet2 const
if (make_signature) if (make_signature)
{ {
cryptonote::subaddress_index const index = {account_index, 0};
// TODO(doyle): Taken from wallet2.cpp::get_reserve_proof
crypto::secret_key skey = wallet.get_account().get_keys().m_spend_secret_key;
if (!index.is_zero())
{
crypto::secret_key m = wallet.get_account().get_device().get_subaddress_secret_key(wallet.get_account().get_keys().m_view_secret_key, index);
crypto::secret_key tmp = skey;
sc_add((unsigned char*)&skey, (unsigned char*)&m, (unsigned char*)&tmp);
}
crypto::public_key pkey;
crypto::secret_key_to_public_key(skey, pkey);
crypto::hash hash = lns::tx_extra_signature_hash(result.encrypted_value.to_span(), owner ? &result.owner : nullptr, backup_owner ? &result.backup_owner : nullptr, result.prev_txid); crypto::hash hash = lns::tx_extra_signature_hash(result.encrypted_value.to_span(), owner ? &result.owner : nullptr, backup_owner ? &result.backup_owner : nullptr, result.prev_txid);
result.signature = lns::make_monero_signature(hash, wallet.get_account().get_keys().m_account_address.m_spend_public_key, wallet.get_account().get_keys().m_spend_secret_key); result.signature = lns::make_monero_signature(hash, pkey, skey);
} }
result.prepared = true; result.prepared = true;
@ -8526,7 +8541,10 @@ std::vector<wallet2::pending_tx> wallet2::lns_create_buy_mapping_tx(lns::mapping
uint32_t account_index, uint32_t account_index,
std::set<uint32_t> subaddr_indices) std::set<uint32_t> subaddr_indices)
{ {
lns_prepared_args prepared_args = prepare_tx_extra_loki_name_system_values(*this, type, priority, name, &value, owner, backup_owner, false /*make_signature*/, reason); lns_prepared_args prepared_args = prepare_tx_extra_loki_name_system_values(*this, type, priority, name, &value, owner, backup_owner, false /*make_signature*/, account_index, reason);
if (!owner)
prepared_args.owner = lns::make_monero_owner(get_subaddress({account_index, 0}), account_index != 0);
if (!prepared_args) if (!prepared_args)
return {}; return {};
@ -8595,14 +8613,14 @@ std::vector<wallet2::pending_tx> wallet2::lns_create_update_mapping_tx(lns::mapp
} }
bool make_signature = signature == nullptr; bool make_signature = signature == nullptr;
lns_prepared_args prepared_args = prepare_tx_extra_loki_name_system_values(*this, type, priority, name, value, owner, backup_owner, make_signature, reason); lns_prepared_args prepared_args = prepare_tx_extra_loki_name_system_values(*this, type, priority, name, value, owner, backup_owner, make_signature, account_index, reason);
if (!prepared_args) return {}; if (!prepared_args) return {};
if (!make_signature) if (!make_signature)
{ {
if (!epee::string_tools::hex_to_pod(*signature, prepared_args.signature)) if (!epee::string_tools::hex_to_pod(*signature, prepared_args.signature.ed25519))
{ {
if (reason) *reason = "Hex signature provided failed to convert to a ed25519_signature, signature=" + *signature; if (reason) *reason = "Hex signature provided failed to convert to a signature, signature=" + *signature;
return {}; return {};
} }
} }
@ -8681,10 +8699,11 @@ bool wallet2::lns_make_update_mapping_signature(lns::mapping_type type,
std::string const *value, std::string const *value,
std::string const *owner, std::string const *owner,
std::string const *backup_owner, std::string const *backup_owner,
crypto::generic_signature &signature, lns::generic_signature &signature,
uint32_t account_index,
std::string *reason) std::string *reason)
{ {
lns_prepared_args prepared_args = prepare_tx_extra_loki_name_system_values(*this, type, tx_priority_unimportant, name, value, owner, backup_owner, true /*make_signature*/, reason); lns_prepared_args prepared_args = prepare_tx_extra_loki_name_system_values(*this, type, tx_priority_unimportant, name, value, owner, backup_owner, true /*make_signature*/, account_index, reason);
if (!prepared_args) return false; if (!prepared_args) return false;
if (prepared_args.prev_txid == crypto::null_hash) if (prepared_args.prev_txid == crypto::null_hash)

View file

@ -1547,7 +1547,7 @@ private:
std::vector<wallet2::pending_tx> lns_create_update_mapping_tx(std::string const &type, std::string const &name, std::string const *value, std::string const *owner, std::string const *backup_owner, std::string const *signature, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {}); std::vector<wallet2::pending_tx> lns_create_update_mapping_tx(std::string const &type, std::string const &name, std::string const *value, std::string const *owner, std::string const *backup_owner, std::string const *signature, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {});
// Generate just the signature required for putting into lns_update_mapping command in the wallet // Generate just the signature required for putting into lns_update_mapping command in the wallet
bool lns_make_update_mapping_signature(lns::mapping_type type, std::string name, std::string const *value, std::string const *owner, std::string const *backup_owner, crypto::generic_signature &signature, std::string *reason = nullptr); bool lns_make_update_mapping_signature(lns::mapping_type type, std::string name, std::string const *value, std::string const *owner, std::string const *backup_owner, lns::generic_signature &signature, uint32_t account_index = 0, std::string *reason = nullptr);
void freeze(size_t idx); void freeze(size_t idx);
void thaw(size_t idx); void thaw(size_t idx);

View file

@ -4389,13 +4389,14 @@ namespace tools
return false; return false;
} }
crypto::generic_signature signature; lns::generic_signature signature;
if (!m_wallet->lns_make_update_mapping_signature(type, if (!m_wallet->lns_make_update_mapping_signature(type,
req.name, req.name,
req.value.size() ? &req.value : nullptr, req.value.size() ? &req.value : nullptr,
req.owner.size() ? &req.owner : nullptr, req.owner.size() ? &req.owner : nullptr,
req.backup_owner.size() ? &req.backup_owner : nullptr, req.backup_owner.size() ? &req.backup_owner : nullptr,
signature, signature,
req.account_index,
&reason)) &reason))
{ {
er.code = WALLET_RPC_ERROR_CODE_TX_NOT_POSSIBLE; er.code = WALLET_RPC_ERROR_CODE_TX_NOT_POSSIBLE;
@ -4403,7 +4404,7 @@ namespace tools
return false; return false;
} }
res.signature = epee::string_tools::pod_to_hex(signature); res.signature = epee::string_tools::pod_to_hex(signature.ed25519);
return true; return true;
} }
} }

View file

@ -2855,19 +2855,19 @@ namespace wallet_rpc
struct COMMAND_RPC_LNS_BUY_MAPPING struct COMMAND_RPC_LNS_BUY_MAPPING
{ {
static constexpr const char *description = static constexpr const char *description =
R"(Buy a Loki Name System mapping. Loki Name System allows multiple owners that are authorised to update the underlying mapping. An owner can be either a ed25519 public key or a wallet address. By default if no owner is specified, the purchasing wallet's public spend key is used from the wallet as the owner. R"(Buy a Loki Name System mapping. Loki Name System allows multiple owners that are authorised to update the underlying mapping. An owner can be either a ed25519 public key or a wallet address. By default if no owner is specified, the purchasing wallet's active [sub]address is stored as the owner.
- For Session, the recommended owner is the ed25519 public key of the user's Session ID set to owner - For Session, the recommended owner is the ed25519 public key of the user's Session ID set to owner
In future, support for mappings on Blockchain wallets and Lokinet addresses will be available. The recommended owner is the monero ed25519 public key of the user's wallet spend key set to owner. In future, support for mappings on Blockchain wallets and Lokinet addresses will be available. The recommended owner is the wallet's [sub]address.
When specifying owners, either a Monero twist or standard ed25519 public key is supported per mapping. Updating the value that a name maps to requires one of the owner keys to sign the update transaction. When specifying owners, either a wallet [sub]address or standard ed25519 public key is supported per mapping. Updating the value that a name maps to requires one of the owner's to sign the update transaction. For wallets, this is signed using the subaddress's spend key.
For information on updating & signing, refer to COMMAND_RPC_LNS_UPDATE_MAPPING)"; For information on updating & signing, refer to COMMAND_RPC_LNS_UPDATE_MAPPING)";
struct request_t struct request_t
{ {
std::string type; // The mapping type, currently we only support "session". In future "lokinet" and "blockchain" mappings will be available. std::string type; // The mapping type, currently we only support "session". In future "lokinet" and "blockchain" mappings will be available.
std::string owner; // (Optional): The public key that has authority to update the mapping. std::string owner; // (Optional): The ed25519 public key or wallet address that has authority to update the mapping.
std::string backup_owner; // (Optional): The secondary, backup public key that has authority to update the mapping. std::string backup_owner; // (Optional): The secondary, backup public key that has authority to update the mapping.
std::string name; // The name to purchase via Loki Name Service std::string name; // The name to purchase via Loki Name Service
std::string value; // The value that the name maps to via Loki Name Service, (i.e. For Session: [display name->session public key]. In future, for wallets: [name->wallet address], for Lokinet: [name->domain name]). std::string value; // The value that the name maps to via Loki Name Service, (i.e. For Session: [display name->session public key]. In future, for wallets: [name->wallet address], for Lokinet: [name->domain name]).
@ -2927,14 +2927,14 @@ For information on updating & signing, refer to COMMAND_RPC_LNS_UPDATE_MAPPING)"
struct COMMAND_RPC_LNS_UPDATE_MAPPING struct COMMAND_RPC_LNS_UPDATE_MAPPING
{ {
static constexpr const char *description = static constexpr const char *description =
R"(Update a Loki Name System mapping's underlying value. The owner (wallet address/ed25519 public key) of the mapping must be able to validate. R"(Update a Loki Name System mapping's underlying value. The pre-existing owner (wallet address/ed25519 public key) of the mapping must be able to validate. At least one field must be specified to update, otherwise the funtion returns an error message.
The signature is generated from signing a hash generated by using Libsodium's generichash on the {prev_txid field (in the current mapping to update), value (new value to update to)} in binary. The signature is generated from signing a hash generated by using Libsodium's generichash on the {new value (if provided), new owner (if provided), new backup_owner (if provided), prev_txid field (in the current mapping to update)} in binary.
Depending on the owner's public key(s) associated with the mapping the signature can sign the hash in 2 ways. If the owner public key associated with the mapping is- Depending on the owner associated with the mapping the signature can be generated in 2 ways. If the owner associated with the mapping is-
- a monero public key, the signature is generated by using Monero's crypto::generate_signature on the hash - a wallet [sub]address, the signature is generated by using Monero's crypto::generate_signature on the hash with the [sub]address's spend key.
- a ed25519 public key, the signature is generated by using Libsodium's crypto_sign_detached on the hash - a ed25519 public key, the signature is generated by using Libsodium's crypto_sign_detached on the hash
Providing the signature is an optional field and if not provided, will default to attempting to sign using the wallet's Monero-style spend keys.)"; Providing the signature is an optional field and if not provided, will default to attempting to sign using the wallet's active [sub]address's spend keys.)";
struct request_t struct request_t
{ {
@ -3001,12 +3001,9 @@ Providing the signature is an optional field and if not provided, will default t
struct COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE struct COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE
{ {
static constexpr const char *description = static constexpr const char *description =
R"(Generate the signature necessary for updating the requested record using the wallet's spend key. The signature is R"(Generate the signature necessary for updating the requested record using the wallet's active [sub]address's spend key. The signature is only valid if the queried wallet is one of the owners of the LNS record.
only valid if the queried wallet is one of the owners of the LNS record.
This command is only required if the open wallet is one of the owners of a LNS record but want the update This command is only required if the open wallet is one of the owners of a LNS record but wants the update transaction to occur via another non-owning wallet. By default, if no signature is specified to the update transaction, the open wallet is assumed the owner and it's active [sub]address's spend key will automatically be used.)";
transaction to occur via another non-owning wallet. By default, if no signature is specified to the update
transaction, the open wallet is assumed the owner and it's spend key will automatically be used.)";
struct request_t struct request_t
{ {
@ -3015,6 +3012,7 @@ transaction, the open wallet is assumed the owner and it's spend key will automa
std::string value; // (Optional): The new value that the name maps to via Loki Name Service. If not specified or given the empty string "", then the mapping's value remains unchanged. std::string value; // (Optional): The new value that the name maps to via Loki Name Service. If not specified or given the empty string "", then the mapping's value remains unchanged.
std::string owner; // (Optional): The new owner of the mapping. If not specified or given the empty string "", then the mapping's owner remains unchanged. std::string owner; // (Optional): The new owner of the mapping. If not specified or given the empty string "", then the mapping's owner remains unchanged.
std::string backup_owner; // (Optional): The new backup owner of the mapping. If not specified or given the empty string "", then the mapping's backup owner remains unchanged. std::string backup_owner; // (Optional): The new backup owner of the mapping. If not specified or given the empty string "", then the mapping's backup owner remains unchanged.
uint32_t account_index; // (Optional) Use this wallet's subaddress account for generating the signature
BEGIN_KV_SERIALIZE_MAP() BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(type); KV_SERIALIZE(type);

View file

@ -297,8 +297,8 @@ loki_chain_generator::create_and_add_loki_name_system_tx(cryptonote::account_bas
lns::mapping_type type, lns::mapping_type type,
std::string const &name, std::string const &name,
lns::mapping_value const &value, lns::mapping_value const &value,
crypto::generic_public_key const *owner, lns::generic_owner const *owner,
crypto::generic_public_key const *backup_owner, lns::generic_owner const *backup_owner,
bool kept_by_block) bool kept_by_block)
{ {
cryptonote::transaction t = create_loki_name_system_tx(src, type, name, value, owner, backup_owner); cryptonote::transaction t = create_loki_name_system_tx(src, type, name, value, owner, backup_owner);
@ -311,9 +311,9 @@ loki_chain_generator::create_and_add_loki_name_system_tx_update(cryptonote::acco
lns::mapping_type type, lns::mapping_type type,
std::string const &name, std::string const &name,
lns::mapping_value const *value, lns::mapping_value const *value,
crypto::generic_public_key const *owner, lns::generic_owner const *owner,
crypto::generic_public_key const *backup_owner, lns::generic_owner const *backup_owner,
crypto::generic_signature *signature, lns::generic_signature *signature,
bool kept_by_block) bool kept_by_block)
{ {
cryptonote::transaction t = create_loki_name_system_tx_update(src, type, name, value, owner, backup_owner, signature); cryptonote::transaction t = create_loki_name_system_tx_update(src, type, name, value, owner, backup_owner, signature);
@ -531,18 +531,18 @@ cryptonote::transaction loki_chain_generator::create_loki_name_system_tx(crypton
lns::mapping_type type, lns::mapping_type type,
std::string const &name, std::string const &name,
lns::mapping_value const &value, lns::mapping_value const &value,
crypto::generic_public_key const *owner, lns::generic_owner const *owner,
crypto::generic_public_key const *backup_owner, lns::generic_owner const *backup_owner,
uint64_t burn) const uint64_t burn) const
{ {
crypto::generic_public_key pkey; lns::generic_owner generic_owner = {};
if (owner) if (owner)
{ {
pkey = *owner; generic_owner = *owner;
} }
else else
{ {
pkey = lns::make_monero_public_key(src.get_keys().m_account_address.m_spend_public_key); generic_owner = lns::make_monero_owner(src.get_keys().m_account_address, false /*subaddress*/);
} }
cryptonote::block const &head = top().block; cryptonote::block const &head = top().block;
@ -562,7 +562,7 @@ cryptonote::transaction loki_chain_generator::create_loki_name_system_tx(crypton
assert(encrypted); assert(encrypted);
std::vector<uint8_t> extra; std::vector<uint8_t> extra;
cryptonote::tx_extra_loki_name_system data = cryptonote::tx_extra_loki_name_system::make_buy(pkey, backup_owner, type, name_hash, encrypted_value.to_string(), prev_txid); cryptonote::tx_extra_loki_name_system data = cryptonote::tx_extra_loki_name_system::make_buy(generic_owner, backup_owner, type, name_hash, encrypted_value.to_string(), prev_txid);
cryptonote::add_loki_name_system_to_tx_extra(extra, data); cryptonote::add_loki_name_system_to_tx_extra(extra, data);
cryptonote::add_burned_amount_to_tx_extra(extra, burn); cryptonote::add_burned_amount_to_tx_extra(extra, burn);
cryptonote::transaction result = {}; cryptonote::transaction result = {};
@ -579,9 +579,9 @@ cryptonote::transaction loki_chain_generator::create_loki_name_system_tx_update(
lns::mapping_type type, lns::mapping_type type,
std::string const &name, std::string const &name,
lns::mapping_value const *value, lns::mapping_value const *value,
crypto::generic_public_key const *owner, lns::generic_owner const *owner,
crypto::generic_public_key const *backup_owner, lns::generic_owner const *backup_owner,
crypto::generic_signature *signature, lns::generic_signature *signature,
bool use_asserts) const bool use_asserts) const
{ {
crypto::hash name_hash = lns::name_to_hash(name); crypto::hash name_hash = lns::name_to_hash(name);
@ -600,7 +600,7 @@ cryptonote::transaction loki_chain_generator::create_loki_name_system_tx_update(
if (use_asserts) assert(encrypted); if (use_asserts) assert(encrypted);
} }
crypto::generic_signature signature_ = {}; lns::generic_signature signature_ = {};
if (!signature) if (!signature)
{ {
signature = &signature_; signature = &signature_;

View file

@ -1421,8 +1421,8 @@ struct loki_chain_generator
// NOTE: Add constructed TX to events_ and assume that it is valid to add to the blockchain. If the TX is meant to be unaddable to the blockchain use the individual create + add functions to // NOTE: Add constructed TX to events_ and assume that it is valid to add to the blockchain. If the TX is meant to be unaddable to the blockchain use the individual create + add functions to
// be able to mark the add TX event as something that should trigger a failure. // be able to mark the add TX event as something that should trigger a failure.
cryptonote::transaction create_and_add_loki_name_system_tx(cryptonote::account_base const &src, lns::mapping_type type, std::string const &name, lns::mapping_value const &value, crypto::generic_public_key const *owner = nullptr, crypto::generic_public_key const *backup_owner = nullptr, bool kept_by_block = false); cryptonote::transaction create_and_add_loki_name_system_tx(cryptonote::account_base const &src, lns::mapping_type type, std::string const &name, lns::mapping_value const &value, lns::generic_owner const *owner = nullptr, lns::generic_owner const *backup_owner = nullptr, bool kept_by_block = false);
cryptonote::transaction create_and_add_loki_name_system_tx_update(cryptonote::account_base const &src, lns::mapping_type type, std::string const &name, lns::mapping_value const *value, crypto::generic_public_key const *owner = nullptr, crypto::generic_public_key const *backup_owner = nullptr, crypto::generic_signature *signature = nullptr, bool kept_by_block = false); cryptonote::transaction create_and_add_loki_name_system_tx_update(cryptonote::account_base const &src, lns::mapping_type type, std::string const &name, lns::mapping_value const *value, lns::generic_owner const *owner = nullptr, lns::generic_owner const *backup_owner = nullptr, lns::generic_signature *signature = nullptr, bool kept_by_block = false);
cryptonote::transaction create_and_add_tx (const cryptonote::account_base& src, const cryptonote::account_public_address& dest, uint64_t amount, uint64_t fee = TESTS_DEFAULT_FEE, bool kept_by_block = false); cryptonote::transaction create_and_add_tx (const cryptonote::account_base& src, const cryptonote::account_public_address& dest, uint64_t amount, uint64_t fee = TESTS_DEFAULT_FEE, bool kept_by_block = false);
cryptonote::transaction create_and_add_state_change_tx(service_nodes::new_state state, const crypto::public_key& pub_key, uint64_t height = -1, const std::vector<uint64_t>& voters = {}, uint64_t fee = 0, bool kept_by_block = false); cryptonote::transaction create_and_add_state_change_tx(service_nodes::new_state state, const crypto::public_key& pub_key, uint64_t height = -1, const std::vector<uint64_t>& voters = {}, uint64_t fee = 0, bool kept_by_block = false);
cryptonote::transaction create_and_add_registration_tx(const cryptonote::account_base& src, const cryptonote::keypair& sn_keys = cryptonote::keypair::generate(hw::get_device("default")), bool kept_by_block = false); cryptonote::transaction create_and_add_registration_tx(const cryptonote::account_base& src, const cryptonote::keypair& sn_keys = cryptonote::keypair::generate(hw::get_device("default")), bool kept_by_block = false);
@ -1443,8 +1443,8 @@ struct loki_chain_generator
// value: Takes the binary value NOT the human readable version, of the name->value mapping // value: Takes the binary value NOT the human readable version, of the name->value mapping
static const uint64_t LNS_AUTO_BURN = static_cast<uint64_t>(-1); static const uint64_t LNS_AUTO_BURN = static_cast<uint64_t>(-1);
cryptonote::transaction create_loki_name_system_tx(cryptonote::account_base const &src, lns::mapping_type type, std::string const &name, lns::mapping_value const &value, crypto::generic_public_key const *owner = nullptr, crypto::generic_public_key const *backup_owner = nullptr, uint64_t burn = LNS_AUTO_BURN) const; cryptonote::transaction create_loki_name_system_tx(cryptonote::account_base const &src, lns::mapping_type type, std::string const &name, lns::mapping_value const &value, lns::generic_owner const *owner = nullptr, lns::generic_owner const *backup_owner = nullptr, uint64_t burn = LNS_AUTO_BURN) const;
cryptonote::transaction create_loki_name_system_tx_update(cryptonote::account_base const &src, lns::mapping_type type, std::string const &name, lns::mapping_value const *value, crypto::generic_public_key const *owner = nullptr, crypto::generic_public_key const *backup_owner = nullptr, crypto::generic_signature *signature = nullptr, bool use_asserts = false) const; cryptonote::transaction create_loki_name_system_tx_update(cryptonote::account_base const &src, lns::mapping_type type, std::string const &name, lns::mapping_value const *value, lns::generic_owner const *owner = nullptr, lns::generic_owner const *backup_owner = nullptr, lns::generic_signature *signature = nullptr, bool use_asserts = false) const;
cryptonote::transaction create_loki_name_system_tx_update_w_extra(cryptonote::account_base const &src, cryptonote::tx_extra_loki_name_system const &lns_extra) const; cryptonote::transaction create_loki_name_system_tx_update_w_extra(cryptonote::account_base const &src, cryptonote::tx_extra_loki_name_system const &lns_extra) const;
loki_blockchain_entry create_genesis_block(const cryptonote::account_base &miner, uint64_t timestamp); loki_blockchain_entry create_genesis_block(const cryptonote::account_base &miner, uint64_t timestamp);

View file

@ -1065,8 +1065,8 @@ static bool verify_lns_mapping_record(char const *perr_context,
uint64_t register_height, uint64_t register_height,
crypto::hash const &txid, crypto::hash const &txid,
crypto::hash const &prev_txid, crypto::hash const &prev_txid,
crypto::generic_public_key const &owner, lns::generic_owner const &owner,
crypto::generic_public_key const &backup_owner) lns::generic_owner const &backup_owner)
{ {
lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, value); lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, value);
CHECK_EQ(record.loaded, true); CHECK_EQ(record.loaded, true);
@ -1102,23 +1102,25 @@ bool loki_name_system_disallow_reserved_type::generate(std::vector<test_event_en
struct lns_keys_t struct lns_keys_t
{ {
crypto::generic_public_key key; lns::generic_owner owner;
lns::mapping_value wallet_value; // NOTE: this field is the binary (value) part of the name -> (value) mapping lns::mapping_value wallet_value; // NOTE: this field is the binary (value) part of the name -> (value) mapping
lns::mapping_value lokinet_value; lns::mapping_value lokinet_value;
lns::mapping_value session_value; lns::mapping_value session_value;
}; };
static lns_keys_t make_lns_keys(cryptonote::account_base const &src) static lns_keys_t make_lns_keys(cryptonote::account_base const &src)
{ {
lns_keys_t result = {}; lns_keys_t result = {};
result.key.monero = src.get_keys().m_account_address.m_spend_public_key; result.owner = lns::make_monero_owner(src.get_keys().m_account_address, false /*is_subaddress*/);
result.session_value.len = lns::SESSION_PUBLIC_KEY_BINARY_LENGTH; result.session_value.len = lns::SESSION_PUBLIC_KEY_BINARY_LENGTH;
result.wallet_value.len = sizeof(src.get_keys().m_account_address); result.wallet_value.len = sizeof(src.get_keys().m_account_address);
result.lokinet_value.len = sizeof(result.key.data); result.lokinet_value.len = sizeof(result.owner.wallet.address.m_spend_public_key);
memcpy(&result.session_value.buffer[0], &result.key, sizeof(result.key)); memcpy(&result.session_value.buffer[0] + 1, &result.owner.wallet.address.m_spend_public_key, result.lokinet_value.len);
memcpy(&result.wallet_value.buffer[0], (char *)&src.get_keys().m_account_address, result.wallet_value.len); memcpy(&result.wallet_value.buffer[0], (char *)&src.get_keys().m_account_address, result.wallet_value.len);
memcpy(&result.lokinet_value.buffer[0], (char *)result.key.data, result.lokinet_value.len);
// NOTE: Just needs a 32 byte key. Reuse spend key
memcpy(&result.lokinet_value.buffer[0], (char *)&result.owner.wallet.address.m_spend_public_key, result.lokinet_value.len);
result.session_value.buffer[0] = 5; // prefix with 0x05 result.session_value.buffer[0] = 5; // prefix with 0x05
return result; return result;
@ -1153,13 +1155,13 @@ bool loki_name_system_expiration::generate(std::vector<test_event_entry> &events
{ {
DEFINE_TESTS_ERROR_CONTEXT("check_lns_entries"); DEFINE_TESTS_ERROR_CONTEXT("check_lns_entries");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db(); lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.key); lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true); CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1); CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.key, owner.key); CHECK_EQ(miner_key.owner, owner.address);
lns::mapping_record record = lns_db.get_mapping(mapping_type, name_hash); lns::mapping_record record = lns_db.get_mapping(mapping_type, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, tx_hash, crypto::null_hash, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, tx_hash, crypto::null_hash, miner_key.owner, {} /*backup_owner*/));
return true; return true;
}); });
@ -1172,13 +1174,13 @@ bool loki_name_system_expiration::generate(std::vector<test_event_entry> &events
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db(); lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
// TODO(loki): We should probably expire owners that no longer have any mappings remaining // TODO(loki): We should probably expire owners that no longer have any mappings remaining
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.key); lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true); CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1); CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.key, owner.key); CHECK_EQ(miner_key.owner, owner.address);
lns::mapping_record record = lns_db.get_mapping(mapping_type, name_hash); lns::mapping_record record = lns_db.get_mapping(mapping_type, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, tx_hash, crypto::null_hash, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, tx_hash, crypto::null_hash, miner_key.owner, {} /*backup_owner*/));
CHECK_EQ(record.active(cryptonote::FAKECHAIN, blockchain_height), false); CHECK_EQ(record.active(cryptonote::FAKECHAIN, blockchain_height), false);
return true; return true;
}); });
@ -1216,7 +1218,7 @@ bool loki_name_system_get_mappings_by_owner::generate(std::vector<test_event_ent
crypto::hash session_name1_txid = {}, session_name2_txid = {}; crypto::hash session_name1_txid = {}, session_name2_txid = {};
{ {
cryptonote::transaction tx1 = gen.create_and_add_loki_name_system_tx(bob, lns::mapping_type::session, session_name1, bob_key.session_value); cryptonote::transaction tx1 = gen.create_and_add_loki_name_system_tx(bob, lns::mapping_type::session, session_name1, bob_key.session_value);
cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx(miner, lns::mapping_type::session, session_name2, bob_key.session_value, &bob_key.key); cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx(miner, lns::mapping_type::session, session_name2, bob_key.session_value, &bob_key.owner);
gen.create_and_add_next_block({tx1, tx2}); gen.create_and_add_next_block({tx1, tx2});
session_name1_txid = get_transaction_hash(tx1); session_name1_txid = get_transaction_hash(tx1);
session_name2_txid = get_transaction_hash(tx2); session_name2_txid = get_transaction_hash(tx2);
@ -1230,7 +1232,7 @@ bool loki_name_system_get_mappings_by_owner::generate(std::vector<test_event_ent
if (lns::mapping_type_allowed(gen.hardfork(), lns::mapping_type::lokinet_1year)) if (lns::mapping_type_allowed(gen.hardfork(), lns::mapping_type::lokinet_1year))
{ {
cryptonote::transaction tx1 = gen.create_and_add_loki_name_system_tx(bob, lns::mapping_type::lokinet_1year, lokinet_name1, bob_key.lokinet_value); cryptonote::transaction tx1 = gen.create_and_add_loki_name_system_tx(bob, lns::mapping_type::lokinet_1year, lokinet_name1, bob_key.lokinet_value);
cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx(miner, lns::mapping_type::lokinet_1year, lokinet_name2, bob_key.lokinet_value, &bob_key.key); cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx(miner, lns::mapping_type::lokinet_1year, lokinet_name2, bob_key.lokinet_value, &bob_key.owner);
gen.create_and_add_next_block({tx1, tx2}); gen.create_and_add_next_block({tx1, tx2});
lokinet_name1_txid = get_transaction_hash(tx1); lokinet_name1_txid = get_transaction_hash(tx1);
lokinet_name2_txid = get_transaction_hash(tx2); lokinet_name2_txid = get_transaction_hash(tx2);
@ -1245,7 +1247,7 @@ bool loki_name_system_get_mappings_by_owner::generate(std::vector<test_event_ent
{ {
std::string bob_addr = cryptonote::get_account_address_as_str(cryptonote::FAKECHAIN, false, bob.get_keys().m_account_address); std::string bob_addr = cryptonote::get_account_address_as_str(cryptonote::FAKECHAIN, false, bob.get_keys().m_account_address);
cryptonote::transaction tx1 = gen.create_and_add_loki_name_system_tx(bob, lns::mapping_type::wallet, wallet_name1, bob_key.wallet_value); cryptonote::transaction tx1 = gen.create_and_add_loki_name_system_tx(bob, lns::mapping_type::wallet, wallet_name1, bob_key.wallet_value);
cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx(miner, lns::mapping_type::wallet, wallet_name2, bob_key.wallet_value, &bob_key.key); cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx(miner, lns::mapping_type::wallet, wallet_name2, bob_key.wallet_value, &bob_key.owner);
gen.create_and_add_next_block({tx1, tx2}); gen.create_and_add_next_block({tx1, tx2});
wallet_name1_txid = get_transaction_hash(tx1); wallet_name1_txid = get_transaction_hash(tx1);
wallet_name2_txid = get_transaction_hash(tx2); wallet_name2_txid = get_transaction_hash(tx2);
@ -1256,7 +1258,7 @@ bool loki_name_system_get_mappings_by_owner::generate(std::vector<test_event_ent
{ {
const char* perr_context = "check_lns_entries"; const char* perr_context = "check_lns_entries";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db(); lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(bob_key.key); std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(bob_key.owner);
size_t expected_size = 0; size_t expected_size = 0;
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::session)) expected_size += 2; if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::session)) expected_size += 2;
@ -1266,20 +1268,20 @@ bool loki_name_system_get_mappings_by_owner::generate(std::vector<test_event_ent
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::session)) if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::session))
{ {
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, session_name1, bob_key.session_value, session_height, session_name1_txid, crypto::null_hash, bob_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, session_name1, bob_key.session_value, session_height, session_name1_txid, crypto::null_hash, bob_key.owner, {} /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[1], lns::mapping_type::session, session_name2, bob_key.session_value, session_height, session_name2_txid, crypto::null_hash, bob_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[1], lns::mapping_type::session, session_name2, bob_key.session_value, session_height, session_name2_txid, crypto::null_hash, bob_key.owner, {} /*backup_owner*/));
} }
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::lokinet_1year)) if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::lokinet_1year))
{ {
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[2], lns::mapping_type::lokinet_1year, lokinet_name1, bob_key.lokinet_value, lokinet_height, lokinet_name1_txid, crypto::null_hash, bob_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[2], lns::mapping_type::lokinet_1year, lokinet_name1, bob_key.lokinet_value, lokinet_height, lokinet_name1_txid, crypto::null_hash, bob_key.owner, {} /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[3], lns::mapping_type::lokinet_1year, lokinet_name2, bob_key.lokinet_value, lokinet_height, lokinet_name2_txid, crypto::null_hash, bob_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[3], lns::mapping_type::lokinet_1year, lokinet_name2, bob_key.lokinet_value, lokinet_height, lokinet_name2_txid, crypto::null_hash, bob_key.owner, {} /*backup_owner*/));
} }
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::wallet)) if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::wallet))
{ {
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[4], lns::mapping_type::wallet, wallet_name1, bob_key.wallet_value, wallet_height, wallet_name1_txid, crypto::null_hash, bob_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[4], lns::mapping_type::wallet, wallet_name1, bob_key.wallet_value, wallet_height, wallet_name1_txid, crypto::null_hash, bob_key.owner, {} /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[5], lns::mapping_type::wallet, wallet_name2, bob_key.wallet_value, wallet_height, wallet_name2_txid, crypto::null_hash, bob_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[5], lns::mapping_type::wallet, wallet_name2, bob_key.wallet_value, wallet_height, wallet_name2_txid, crypto::null_hash, bob_key.owner, {} /*backup_owner*/));
} }
return true; return true;
}); });
@ -1338,16 +1340,16 @@ bool loki_name_system_get_mappings_by_owners::generate(std::vector<test_event_en
{ {
DEFINE_TESTS_ERROR_CONTEXT("check_lns_entries"); DEFINE_TESTS_ERROR_CONTEXT("check_lns_entries");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db(); lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owners({bob_key.key, miner_key.key}); std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owners({bob_key.owner, miner_key.owner});
CHECK_EQ(records.size(), 3); CHECK_EQ(records.size(), 3);
std::sort(records.begin(), records.end(), [](lns::mapping_record const &lhs, lns::mapping_record const &rhs) { std::sort(records.begin(), records.end(), [](lns::mapping_record const &lhs, lns::mapping_record const &rhs) {
return lhs.register_height < rhs.register_height; return lhs.register_height < rhs.register_height;
}); });
int index = 0; int index = 0;
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[index++], lns::mapping_type::session, session_name1, bob_key.session_value, session_height1, session_tx_hash1, crypto::null_hash, bob_key.key, {})); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[index++], lns::mapping_type::session, session_name1, bob_key.session_value, session_height1, session_tx_hash1, crypto::null_hash, bob_key.owner, {}));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[index++], lns::mapping_type::session, session_name2, bob_key.session_value, session_height2, session_tx_hash2, crypto::null_hash, bob_key.key, {})); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[index++], lns::mapping_type::session, session_name2, bob_key.session_value, session_height2, session_tx_hash2, crypto::null_hash, bob_key.owner, {}));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[index++], lns::mapping_type::session, session_name3, miner_key.session_value, session_height3, session_tx_hash3, crypto::null_hash, miner_key.key, {})); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[index++], lns::mapping_type::session, session_name3, miner_key.session_value, session_height3, session_tx_hash3, crypto::null_hash, miner_key.owner, {}));
return true; return true;
}); });
@ -1389,7 +1391,7 @@ bool loki_name_system_get_mappings::generate(std::vector<test_event_entry> &even
std::string session_name_hash = lns::name_to_base64_hash(session_name1); std::string session_name_hash = lns::name_to_base64_hash(session_name1);
std::vector<lns::mapping_record> records = lns_db.get_mappings({static_cast<uint16_t>(lns::mapping_type::session)}, session_name_hash); std::vector<lns::mapping_record> records = lns_db.get_mappings({static_cast<uint16_t>(lns::mapping_type::session)}, session_name_hash);
CHECK_EQ(records.size(), 1); CHECK_EQ(records.size(), 1);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, session_name1, bob_key.session_value, session_height, session_tx_hash, crypto::null_hash /*prev_txid*/, bob_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, session_name1, bob_key.session_value, session_height, session_tx_hash, crypto::null_hash /*prev_txid*/, bob_key.owner, {} /*backup_owner*/));
return true; return true;
}); });
@ -1446,24 +1448,24 @@ bool loki_name_system_handles_duplicate_in_lns_db::generate(std::vector<test_eve
DEFINE_TESTS_ERROR_CONTEXT("check_lns_entries"); DEFINE_TESTS_ERROR_CONTEXT("check_lns_entries");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db(); lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.key); lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true); CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1); CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.key, owner.key); CHECK_EQ(miner_key.owner, owner.address);
std::string session_name_hash = lns::name_to_base64_hash(session_name); std::string session_name_hash = lns::name_to_base64_hash(session_name);
lns::mapping_record record1 = lns_db.get_mapping(lns::mapping_type::session, session_name_hash); lns::mapping_record record1 = lns_db.get_mapping(lns::mapping_type::session, session_name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record1, lns::mapping_type::session, session_name, bob_key.session_value, height_of_lns_entry, session_tx_hash, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record1, lns::mapping_type::session, session_name, bob_key.session_value, height_of_lns_entry, session_tx_hash, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
CHECK_EQ(record1.owner_id, owner.id); CHECK_EQ(record1.owner_id, owner.id);
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::lokinet_1year)) if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::lokinet_1year))
{ {
lns::mapping_record record2 = lns_db.get_mapping(lns::mapping_type::lokinet_1year, session_name); lns::mapping_record record2 = lns_db.get_mapping(lns::mapping_type::lokinet_1year, session_name);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record2, lns::mapping_type::lokinet_1year, lokinet_name, miner_key.lokinet_value, height_of_lns_entry, lokinet_tx_hash, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record2, lns::mapping_type::lokinet_1year, lokinet_name, miner_key.lokinet_value, height_of_lns_entry, lokinet_tx_hash, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
CHECK_EQ(record2.owner_id, owner.id); CHECK_EQ(record2.owner_id, owner.id);
} }
lns::owner_record owner2 = lns_db.get_owner_by_key(bob_key.key); lns::owner_record owner2 = lns_db.get_owner_by_key(bob_key.owner);
CHECK_EQ(owner2.loaded, false); CHECK_EQ(owner2.loaded, false);
return true; return true;
}); });
@ -1543,7 +1545,7 @@ bool loki_name_system_invalid_tx_extra_params::generate(std::vector<test_event_e
std::string name = "my_lns_name"; std::string name = "my_lns_name";
cryptonote::tx_extra_loki_name_system valid_data = {}; cryptonote::tx_extra_loki_name_system valid_data = {};
valid_data.fields |= lns::extra_field::buy_no_backup; valid_data.fields |= lns::extra_field::buy_no_backup;
valid_data.owner = miner_key.key; valid_data.owner = miner_key.owner;
valid_data.type = lns::mapping_type::wallet; valid_data.type = lns::mapping_type::wallet;
valid_data.encrypted_value = helper_encrypt_lns_value(name, miner_key.wallet_value).to_string(); valid_data.encrypted_value = helper_encrypt_lns_value(name, miner_key.wallet_value).to_string();
valid_data.name_hash = lns::name_to_hash(name); valid_data.name_hash = lns::name_to_hash(name);
@ -1697,7 +1699,7 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
{ {
DEFINE_TESTS_ERROR_CONTEXT("check_first_lns_entries"); DEFINE_TESTS_ERROR_CONTEXT("check_first_lns_entries");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db(); lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(miner_key.key); std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(miner_key.owner);
size_t expected_size = 1; size_t expected_size = 1;
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::wallet)) expected_size += 1; if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::wallet)) expected_size += 1;
@ -1707,11 +1709,11 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
for (lns::mapping_record const &record : records) for (lns::mapping_record const &record : records)
{ {
if (record.type == lns::mapping_type::session) if (record.type == lns::mapping_type::session)
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, session_name1, miner_key.session_value, first_lns_height, session_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, session_name1, miner_key.session_value, first_lns_height, session_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else if (record.type == lns::mapping_type::lokinet_1year) else if (record.type == lns::mapping_type::lokinet_1year)
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, lokinet_name1, miner_key.lokinet_value, first_lns_height, lokinet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, lokinet_name1, miner_key.lokinet_value, first_lns_height, lokinet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else if (record.type == lns::mapping_type::wallet) else if (record.type == lns::mapping_type::wallet)
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::wallet, wallet_name1, miner_key.wallet_value, first_lns_height, wallet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::wallet, wallet_name1, miner_key.wallet_value, first_lns_height, wallet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else else
{ {
assert(false); assert(false);
@ -1748,15 +1750,15 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
// NOTE: Check miner's record // NOTE: Check miner's record
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::lokinet_1year)) if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::lokinet_1year))
{ {
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(miner_key.key); std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(miner_key.owner);
for (lns::mapping_record const &record : records) for (lns::mapping_record const &record : records)
{ {
if (record.type == lns::mapping_type::session) if (record.type == lns::mapping_type::session)
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, session_name1, miner_key.session_value, first_lns_height, session_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, session_name1, miner_key.session_value, first_lns_height, session_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else if (record.type == lns::mapping_type::lokinet_1year) else if (record.type == lns::mapping_type::lokinet_1year)
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, lokinet_name1, miner_key.lokinet_value, second_lns_height, lokinet_tx_hash2, lokinet_tx_hash1 /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, lokinet_name1, miner_key.lokinet_value, second_lns_height, lokinet_tx_hash2, lokinet_tx_hash1 /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else if (record.type == lns::mapping_type::wallet) else if (record.type == lns::mapping_type::wallet)
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::wallet, wallet_name1, miner_key.wallet_value, first_lns_height, wallet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::wallet, wallet_name1, miner_key.wallet_value, first_lns_height, wallet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else else
{ {
assert(false); assert(false);
@ -1766,9 +1768,9 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
// NOTE: Check bob's records // NOTE: Check bob's records
{ {
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(bob_key.key); std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(bob_key.owner);
CHECK_EQ(records.size(), 1); CHECK_EQ(records.size(), 1);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, bob_session_name1, bob_key.session_value, second_lns_height, session_tx_hash2, crypto::null_hash /*prev_txid*/, bob_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, bob_session_name1, bob_key.session_value, second_lns_height, session_tx_hash2, crypto::null_hash /*prev_txid*/, bob_key.owner, {} /*backup_owner*/));
} }
return true; return true;
@ -1788,16 +1790,16 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
// NOTE: Check bob's records got removed due to popping back to before it existed // NOTE: Check bob's records got removed due to popping back to before it existed
{ {
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(bob_key.key); std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(bob_key.owner);
CHECK_EQ(records.size(), 0); CHECK_EQ(records.size(), 0);
lns::owner_record owner = lns_db.get_owner_by_key(bob_key.key); lns::owner_record owner = lns_db.get_owner_by_key(bob_key.owner);
CHECK_EQ(owner.loaded, false); CHECK_EQ(owner.loaded, false);
} }
// NOTE: Check miner's records reverted // NOTE: Check miner's records reverted
{ {
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(miner_key.key); std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(miner_key.owner);
size_t expected_size = 1; size_t expected_size = 1;
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::wallet)) expected_size += 1; if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::wallet)) expected_size += 1;
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::lokinet_1year)) expected_size += 1; if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::lokinet_1year)) expected_size += 1;
@ -1806,11 +1808,11 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
for (lns::mapping_record const &record : records) for (lns::mapping_record const &record : records)
{ {
if (record.type == lns::mapping_type::session) if (record.type == lns::mapping_type::session)
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, session_name1, miner_key.session_value, first_lns_height, session_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, session_name1, miner_key.session_value, first_lns_height, session_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else if (record.type == lns::mapping_type::lokinet_1year) else if (record.type == lns::mapping_type::lokinet_1year)
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, lokinet_name1, miner_key.lokinet_value, first_lns_height, lokinet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, lokinet_name1, miner_key.lokinet_value, first_lns_height, lokinet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else if (record.type == lns::mapping_type::wallet) else if (record.type == lns::mapping_type::wallet)
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::wallet, wallet_name1, miner_key.wallet_value, first_lns_height, wallet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::wallet, wallet_name1, miner_key.wallet_value, first_lns_height, wallet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else else
{ {
assert(false); assert(false);
@ -1834,10 +1836,10 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
// NOTE: Check miner's records are gone // NOTE: Check miner's records are gone
{ {
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(miner_key.key); std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(miner_key.owner);
CHECK_EQ(records.size(), 0); CHECK_EQ(records.size(), 0);
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.key); lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, false); CHECK_EQ(owner.loaded, false);
} }
return true; return true;
@ -1876,14 +1878,14 @@ bool loki_name_system_name_renewal::generate(std::vector<test_event_entry> &even
DEFINE_TESTS_ERROR_CONTEXT("check_lns_entries"); DEFINE_TESTS_ERROR_CONTEXT("check_lns_entries");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db(); lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.key); lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true); CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1); CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.key, owner.key); CHECK_EQ(miner_key.owner, owner.address);
std::string name_hash = lns::name_to_base64_hash(name); std::string name_hash = lns::name_to_base64_hash(name);
lns::mapping_record record = lns_db.get_mapping(lns::mapping_type::lokinet_1year, name_hash); lns::mapping_record record = lns_db.get_mapping(lns::mapping_type::lokinet_1year, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, prev_txid, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, prev_txid, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
return true; return true;
}); });
@ -1901,14 +1903,14 @@ bool loki_name_system_name_renewal::generate(std::vector<test_event_entry> &even
DEFINE_TESTS_ERROR_CONTEXT("check_renewed"); DEFINE_TESTS_ERROR_CONTEXT("check_renewed");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db(); lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.key); lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true); CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1); CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.key, owner.key); CHECK_EQ(miner_key.owner, owner.address);
std::string name_hash = lns::name_to_base64_hash(name); std::string name_hash = lns::name_to_base64_hash(name);
lns::mapping_record record = lns_db.get_mapping(lns::mapping_type::lokinet_1year, name_hash); lns::mapping_record record = lns_db.get_mapping(lns::mapping_type::lokinet_1year, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, renewal_height, txid, prev_txid, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, renewal_height, txid, prev_txid, miner_key.owner, {} /*backup_owner*/));
return true; return true;
}); });
@ -1949,7 +1951,7 @@ bool loki_name_system_name_value_max_lengths::generate(std::vector<test_event_en
lns_keys_t miner_key = make_lns_keys(miner); lns_keys_t miner_key = make_lns_keys(miner);
cryptonote::tx_extra_loki_name_system data = {}; cryptonote::tx_extra_loki_name_system data = {};
data.fields |= lns::extra_field::buy_no_backup; data.fields |= lns::extra_field::buy_no_backup;
data.owner = miner_key.key; data.owner = miner_key.owner;
// Wallet // Wallet
if (lns::mapping_type_allowed(gen.hardfork(), lns::mapping_type::wallet)) if (lns::mapping_type_allowed(gen.hardfork(), lns::mapping_type::wallet))
@ -2024,14 +2026,14 @@ bool loki_name_system_update_mapping_after_expiry_fails::generate(std::vector<te
DEFINE_TESTS_ERROR_CONTEXT("check_still_expired"); DEFINE_TESTS_ERROR_CONTEXT("check_still_expired");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db(); lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.key); lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true); CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1); CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.key, owner.key); CHECK_EQ(miner_key.owner, owner.address);
std::string name_hash = lns::name_to_base64_hash(name); std::string name_hash = lns::name_to_base64_hash(name);
lns::mapping_record record = lns_db.get_mapping(lns::mapping_type::lokinet_1year, name_hash); lns::mapping_record record = lns_db.get_mapping(lns::mapping_type::lokinet_1year, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, tx_hash, crypto::null_hash /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, tx_hash, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
CHECK_EQ(record.owner_id, owner.id); CHECK_EQ(record.owner_id, owner.id);
return true; return true;
}); });
@ -2069,7 +2071,7 @@ bool loki_name_system_update_mapping::generate(std::vector<test_event_entry> &ev
std::vector<lns::mapping_record> records = lns_db.get_mappings({static_cast<uint16_t>(lns::mapping_type::session)}, name_hash); std::vector<lns::mapping_record> records = lns_db.get_mappings({static_cast<uint16_t>(lns::mapping_type::session)}, name_hash);
CHECK_EQ(records.size(), 1); CHECK_EQ(records.size(), 1);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, session_name1, miner_key.session_value, register_height, session_tx_hash1, {} /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, session_name1, miner_key.session_value, register_height, session_tx_hash1, {} /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
return true; return true;
}); });
@ -2095,7 +2097,7 @@ bool loki_name_system_update_mapping::generate(std::vector<test_event_entry> &ev
std::vector<lns::mapping_record> records = lns_db.get_mappings({static_cast<uint16_t>(lns::mapping_type::session)}, name_hash); std::vector<lns::mapping_record> records = lns_db.get_mappings({static_cast<uint16_t>(lns::mapping_type::session)}, name_hash);
CHECK_EQ(records.size(), 1); CHECK_EQ(records.size(), 1);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, session_name1, bob_key.session_value, register_height, session_tx_hash2, session_tx_hash1 /*prev_txid*/, miner_key.key, {} /*backup_owner*/)); CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[0], lns::mapping_type::session, session_name1, bob_key.session_value, register_height, session_tx_hash2, session_tx_hash1 /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
return true; return true;
}); });
@ -2115,15 +2117,15 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
// Test 2 ed keys as owner // Test 2 ed keys as owner
{ {
crypto::generic_public_key owner1; lns::generic_owner owner1;
crypto::generic_public_key owner2; lns::generic_owner owner2;
crypto::ed25519_secret_key owner1_key; crypto::ed25519_secret_key owner1_key;
crypto::ed25519_secret_key owner2_key; crypto::ed25519_secret_key owner2_key;
crypto_sign_ed25519_keypair(owner1.data, owner1_key.data); crypto_sign_ed25519_keypair(owner1.ed25519.data, owner1_key.data);
crypto_sign_ed25519_keypair(owner2.data, owner2_key.data); crypto_sign_ed25519_keypair(owner2.ed25519.data, owner2_key.data);
owner1.type = crypto::generic_key_sig_type::ed25519; owner1.type = lns::generic_owner_sig_type::ed25519;
owner2.type = crypto::generic_key_sig_type::ed25519; owner2.type = lns::generic_owner_sig_type::ed25519;
std::string name = "Hello_World"; std::string name = "Hello_World";
std::string name_hash = lns::name_to_base64_hash(name); std::string name_hash = lns::name_to_base64_hash(name);
@ -2189,15 +2191,10 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
// Test 2 monero keys as owner // Test 2 monero keys as owner
{ {
crypto::generic_public_key owner1; cryptonote::account_base account1 = gen.add_account();
crypto::generic_public_key owner2; cryptonote::account_base account2 = gen.add_account();
crypto::secret_key owner1_key; lns::generic_owner owner1 = lns::make_monero_owner(account1.get_keys().m_account_address, false /*subaddress*/);
crypto::secret_key owner2_key; lns::generic_owner owner2 = lns::make_monero_owner(account2.get_keys().m_account_address, false /*subaddress*/);
crypto::generate_keys(owner1.monero, owner1_key);
crypto::generate_keys(owner2.monero, owner2_key);
owner1.type = crypto::generic_key_sig_type::monero;
owner2.type = crypto::generic_key_sig_type::monero;
std::string name = "Hello_Sailor"; std::string name = "Hello_Sailor";
std::string name_hash = lns::name_to_base64_hash(name); std::string name_hash = lns::name_to_base64_hash(name);
@ -2212,7 +2209,7 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
lns_keys_t temp_keys = make_lns_keys(gen.add_account()); lns_keys_t temp_keys = make_lns_keys(gen.add_account());
lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, temp_keys.session_value); lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, temp_keys.session_value);
crypto::hash hash = lns::tx_extra_signature_hash(encrypted_value.to_span(), nullptr /*owner*/, nullptr /*backup_owner*/, txid); crypto::hash hash = lns::tx_extra_signature_hash(encrypted_value.to_span(), nullptr /*owner*/, nullptr /*backup_owner*/, txid);
auto signature = lns::make_monero_signature(hash, owner1.monero, owner1_key); auto signature = lns::make_monero_signature(hash, owner1.wallet.address.m_spend_public_key, account1.get_keys().m_spend_secret_key);
cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &temp_keys.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &signature); cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &temp_keys.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &signature);
gen.create_and_add_next_block({tx2}); gen.create_and_add_next_block({tx2});
@ -2234,7 +2231,7 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
lns_keys_t temp_keys = make_lns_keys(gen.add_account()); lns_keys_t temp_keys = make_lns_keys(gen.add_account());
lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, temp_keys.session_value); lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, temp_keys.session_value);
crypto::hash hash = lns::tx_extra_signature_hash(encrypted_value.to_span(), nullptr /*owner*/, nullptr /*backup_owner*/, txid); crypto::hash hash = lns::tx_extra_signature_hash(encrypted_value.to_span(), nullptr /*owner*/, nullptr /*backup_owner*/, txid);
auto signature = lns::make_monero_signature(hash, owner2.monero, owner2_key); auto signature = lns::make_monero_signature(hash, owner2.wallet.address.m_spend_public_key, account2.get_keys().m_spend_secret_key);
cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &temp_keys.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &signature); cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &temp_keys.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &signature);
gen.create_and_add_next_block({tx2}); gen.create_and_add_next_block({tx2});
@ -2254,15 +2251,14 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
// Test 1 ed/1 monero as owner // Test 1 ed/1 monero as owner
{ {
crypto::generic_public_key owner1; cryptonote::account_base account2 = gen.add_account();
crypto::generic_public_key owner2;
crypto::ed25519_secret_key owner1_key;
crypto::secret_key owner2_key;
crypto_sign_ed25519_keypair(owner1.data, owner1_key.data); lns::generic_owner owner1;
crypto::generate_keys(owner2.monero, owner2_key); lns::generic_owner owner2 = lns::make_monero_owner(account2.get_keys().m_account_address, false /*subaddress*/);
owner1.type = crypto::generic_key_sig_type::ed25519; crypto::ed25519_secret_key owner1_key;
owner2.type = crypto::generic_key_sig_type::monero;
crypto_sign_ed25519_keypair(owner1.ed25519.data, owner1_key.data);
owner1.type = lns::generic_owner_sig_type::ed25519;
std::string name = "Hello_Driver"; std::string name = "Hello_Driver";
std::string name_hash = lns::name_to_base64_hash(name); std::string name_hash = lns::name_to_base64_hash(name);
@ -2299,7 +2295,7 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
lns_keys_t temp_keys = make_lns_keys(gen.add_account()); lns_keys_t temp_keys = make_lns_keys(gen.add_account());
lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, temp_keys.session_value); lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, temp_keys.session_value);
crypto::hash hash = lns::tx_extra_signature_hash(encrypted_value.to_span(), nullptr /*owner*/, nullptr /*backup_owner*/, txid); crypto::hash hash = lns::tx_extra_signature_hash(encrypted_value.to_span(), nullptr /*owner*/, nullptr /*backup_owner*/, txid);
auto signature = lns::make_monero_signature(hash, owner2.monero, owner2_key); auto signature = lns::make_monero_signature(hash, owner2.wallet.address.m_spend_public_key, account2.get_keys().m_spend_secret_key);
cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &temp_keys.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &signature); cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &temp_keys.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &signature);
gen.create_and_add_next_block({tx2}); gen.create_and_add_next_block({tx2});
@ -2319,14 +2315,13 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
// Test 1 monero/1 ed as owner // Test 1 monero/1 ed as owner
{ {
crypto::generic_public_key owner1; cryptonote::account_base account1 = gen.add_account();
crypto::generic_public_key owner2; lns::generic_owner owner1 = lns::make_monero_owner(account1.get_keys().m_account_address, false /*subaddress*/);
crypto::secret_key owner1_key; lns::generic_owner owner2;
crypto::ed25519_secret_key owner2_key; crypto::ed25519_secret_key owner2_key;
crypto::generate_keys(owner1.monero, owner1_key); crypto_sign_ed25519_keypair(owner2.ed25519.data, owner2_key.data);
crypto_sign_ed25519_keypair(owner2.data, owner2_key.data); owner2.type = lns::generic_owner_sig_type::ed25519;
owner1.type = crypto::generic_key_sig_type::monero;
owner2.type = crypto::generic_key_sig_type::ed25519;
std::string name = "Hello_Passenger"; std::string name = "Hello_Passenger";
std::string name_hash = lns::name_to_base64_hash(name); std::string name_hash = lns::name_to_base64_hash(name);
@ -2342,7 +2337,7 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, temp_keys.session_value); lns::mapping_value encrypted_value = helper_encrypt_lns_value(name, temp_keys.session_value);
crypto::hash hash = lns::tx_extra_signature_hash(encrypted_value.to_span(), nullptr /*owner*/, nullptr /*backup_owner*/, txid); crypto::hash hash = lns::tx_extra_signature_hash(encrypted_value.to_span(), nullptr /*owner*/, nullptr /*backup_owner*/, txid);
auto signature = lns::make_monero_signature(hash, owner1.monero, owner1_key); auto signature = lns::make_monero_signature(hash, owner1.wallet.address.m_spend_public_key, account1.get_keys().m_spend_secret_key);
cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &temp_keys.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &signature); cryptonote::transaction tx2 = gen.create_and_add_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &temp_keys.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &signature);
gen.create_and_add_next_block({tx2}); gen.create_and_add_next_block({tx2});
@ -2415,7 +2410,7 @@ bool loki_name_system_update_mapping_invalid_signature::generate(std::vector<tes
gen.create_and_add_next_block({tx1}); gen.create_and_add_next_block({tx1});
lns_keys_t bob_key = make_lns_keys(gen.add_account()); lns_keys_t bob_key = make_lns_keys(gen.add_account());
crypto::generic_signature invalid_signature = {}; lns::generic_signature invalid_signature = {};
cryptonote::transaction tx2 = gen.create_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &bob_key.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &invalid_signature, false /*use_asserts*/); cryptonote::transaction tx2 = gen.create_loki_name_system_tx_update(miner, lns::mapping_type::session, name, &bob_key.session_value, nullptr /*owner*/, nullptr /*backup_owner*/, &invalid_signature, false /*use_asserts*/);
gen.add_tx(tx2, false /*can_be_added_to_blockchain*/, "Can not add a updating LNS TX with an invalid signature"); gen.add_tx(tx2, false /*can_be_added_to_blockchain*/, "Can not add a updating LNS TX with an invalid signature");
return true; return true;
@ -2538,7 +2533,7 @@ bool loki_name_system_wrong_version::generate(std::vector<test_event_entry> &eve
lns_keys_t miner_key = make_lns_keys(miner); lns_keys_t miner_key = make_lns_keys(miner);
cryptonote::tx_extra_loki_name_system data = {}; cryptonote::tx_extra_loki_name_system data = {};
data.version = 0xFF; data.version = 0xFF;
data.owner = miner_key.key; data.owner = miner_key.owner;
data.type = lns::mapping_type::session; data.type = lns::mapping_type::session;
data.name_hash = lns::name_to_hash(name); data.name_hash = lns::name_to_hash(name);
data.encrypted_value = helper_encrypt_lns_value(name, miner_key.session_value).to_string(); data.encrypted_value = helper_encrypt_lns_value(name, miner_key.session_value).to_string();