Merge pull request #1105 from loki-project/dev

Merge Valiant Vidar 7.1.3 to Master
This commit is contained in:
Doyle 2020-04-01 11:23:43 +11:00 committed by GitHub
commit cb4dde8b0c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 1145 additions and 497 deletions

View file

@ -791,7 +791,12 @@ if(STATIC)
set(Boost_USE_STATIC_RUNTIME ON)
endif()
set(Boost_USE_MULTITHREADED TRUE) # Needed for macOS, at least, and won't hurt elsewhere
find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options locale)
if (WIN32)
find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options locale)
else()
find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options)
endif()
set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES})
if(NOT Boost_FOUND)

View file

@ -40,7 +40,7 @@ find_package(PkgConfig REQUIRED)
if(NOT STATIC)
pkg_check_modules(MINIUPNPC miniupnpc>=2.1)
pkg_check_modules(UNBOUND libunbound)
pkg_check_modules(LOKIMQ liblokimq)
pkg_check_modules(LOKIMQ liblokimq>=1.0.4)
endif()
if(MINIUPNPC_FOUND)

2
external/loki-mq vendored

@ -1 +1 @@
Subproject commit a36e53d409909657b768c9937b1033a64d9aea0e
Subproject commit 6ba70923b9c689dacbb3a55a06336bf5002f224c

View file

@ -307,6 +307,9 @@ namespace cryptonote
m_db = db;
m_nettype = nettype;
if (db->is_read_only())
return true;
#if !defined(LOKI_ENABLE_INTEGRATION_TEST_HOOKS)
if (nettype == MAINNET)
{
@ -316,11 +319,6 @@ namespace cryptonote
ADD_CHECKPOINT(checkpoint.height, checkpoint.hash);
}
}
else if (nettype == TESTNET)
{
auto guard = db_wtxn_guard(m_db);
m_db->remove_block_checkpoint(127028);
}
#endif
return true;

View file

@ -1,5 +1,6 @@
#pragma once
#include <string>
#include "span.h"
namespace crypto
{
@ -10,9 +11,8 @@ namespace base32z
{
bool decode(std::string const &src, crypto::ed25519_public_key &dest);
/// adapted from i2pd
template <typename stack_t>
const char *encode(std::string const &src, stack_t &stack)
const char *encode(epee::span<const uint8_t> src, stack_t &stack)
{
// from https://en.wikipedia.org/wiki/Base32#z-base-32
static const char zbase32_alpha[] = {'y', 'b', 'n', 'd', 'r', 'f', 'g', '8', 'e', 'j', 'k', 'm', 'c', 'p', 'q', 'x',
@ -21,7 +21,7 @@ const char *encode(std::string const &src, stack_t &stack)
size_t ret = 0, pos = 1;
int bits = 8;
uint32_t tmp = src[0];
size_t len = sizeof(src);
size_t len = src.size();
while (ret < sizeof(stack) && (bits > 0 || pos < len))
{
if (bits < 5)
@ -52,4 +52,12 @@ const char *encode(std::string const &src, stack_t &stack)
}
return &stack[0];
}
/// adapted from i2pd
template <typename stack_t>
const char *encode(std::string const &src, stack_t &stack)
{
char *result = encode(epee::strspan<uint8_t>(src), stack);
return result;
}
};

View file

@ -73,23 +73,3 @@ if (ANDROID OR IOS)
endif()
endif()
option(NO_AES "Explicitly disable AES support" ${NO_AES})
if(NO_AES)
message(STATUS "AES support explicitly disabled")
target_compile_definitions(cncrypto PRIVATE NO_AES)
elseif(NOT ARM AND NOT PPC64LE AND NOT PPC64 AND NOT PPC AND NOT S390X)
message(STATUS "AES support enabled")
target_compile_options(cncrypto PRIVATE "-maes")
elseif(PPC64LE OR PPC64 OR PPC)
message(STATUS "AES support not available on POWER")
elseif(S390X)
message(STATUS "AES support not available on s390x")
elseif(ARM6)
message(STATUS "AES support not available on ARMv6")
elseif(ARM7)
message(STATUS "AES support not available on ARMv7")
else()
message(STATUS "AES support disabled")
endif()

View file

@ -188,7 +188,7 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp
lo ^= *(U64(hp_state + (j ^ 0x20)) + 1); \
} while (0)
#if !defined NO_AES && (defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64)))
#if defined(__AES__) && (defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64)))
// Optimised code below, uses x86-specific intrinsics, SSE2, AES-NI
// Fall back to more portable code is down at the bottom
@ -804,7 +804,7 @@ void cn_turtle_hash(const void *data, size_t length, char *hash, int light, int
slow_hash_free_state(CN_TURTLE_PAGE_SIZE);
}
#elif !defined NO_AES && (defined(__arm__) || defined(__aarch64__))
#elif defined(__arm__) || defined(__aarch64__)
void slow_hash_allocate_state(void)
{
// Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c

View file

@ -87,7 +87,7 @@ constexpr inline extra_field& operator|=(extra_field& a, extra_field b) { return
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
struct alignas(size_t) generic_owner
{
union {
crypto::ed25519_public_key ed25519;
@ -103,7 +103,7 @@ struct generic_owner
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; }
explicit 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()
@ -131,7 +131,7 @@ struct generic_signature
unsigned char data[sizeof(crypto::ed25519_signature)];
};
static constexpr generic_signature null() { return {}; }
operator bool() const { return memcmp(data, null().data, sizeof(data)); }
explicit 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()

View file

@ -305,7 +305,7 @@ bool Blockchain::load_missing_blocks_into_loki_subsystems()
int64_t const total_blocks = static_cast<int64_t>(end_height) - static_cast<int64_t>(start_height);
if (total_blocks <= 0) return true;
if (total_blocks > 1)
MGINFO("Loading blocks into loki subsystems, scanning blockchain from height: " << start_height << " to: " << end_height);
MGINFO("Loading blocks into loki subsystems, scanning blockchain from height: " << start_height << " to: " << end_height << " (snl: " << snl_height << ", lns: " << lns_height << ")");
using clock = std::chrono::steady_clock;
using work_time = std::chrono::duration<float>;
@ -577,15 +577,10 @@ bool Blockchain::init(BlockchainDB* db, sqlite3 *lns_db, const network_type nett
return false;
}
if (lns_db) // Initialise LNS
if (lns_db && !m_lns_db.init(this, nettype, lns_db))
{
uint64_t lns_height = 0;
crypto::hash lns_hash = get_tail_id(lns_height);
if (!m_lns_db.init(nettype, lns_db, lns_height, lns_hash))
{
MERROR("LNS failed to initialise");
return false;
}
MERROR("LNS failed to initialise");
return false;
}
hook_block_added(m_checkpoints);
@ -593,7 +588,7 @@ bool Blockchain::init(BlockchainDB* db, sqlite3 *lns_db, const network_type nett
for (InitHook* hook : m_init_hooks)
hook->init();
if (!load_missing_blocks_into_loki_subsystems())
if (!m_db->is_read_only() && !load_missing_blocks_into_loki_subsystems())
{
MERROR("Failed to load blocks into loki subsystems");
return false;

View file

@ -1053,7 +1053,9 @@ namespace cryptonote
*/
bool blink_rollback(uint64_t rollback_height);
lns::name_system_db const &name_system_db() { return m_lns_db; }
lns::name_system_db &name_system_db() { return m_lns_db; }
const lns::name_system_db &name_system_db() const { return m_lns_db; }
#ifndef IN_UNIT_TESTS
private:

View file

@ -543,7 +543,8 @@ namespace cryptonote
{
std::string s;
s.reserve(128);
s += "Height: ";
s += 'v'; s += LOKI_VERSION_STR;
s += "; Height: ";
s += std::to_string(c.get_blockchain_storage().get_current_blockchain_height());
s += ", SN: ";
auto keys = c.get_service_node_keys();

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,7 @@ struct mapping_value
std::string to_string() const { return std::string(reinterpret_cast<char const *>(buffer.data()), len); }
epee::span<const uint8_t> to_span() const { return epee::span<const uint8_t>(reinterpret_cast<const uint8_t *>(buffer.data()), len); }
std::string to_readable_value(cryptonote::network_type nettype, mapping_type type) const;
bool operator==(mapping_value const &other) const { return other.len == len && memcmp(buffer.data(), other.buffer.data(), len) == 0; }
bool operator==(std::string const &other) const { return other.size() == len && memcmp(buffer.data(), other.data(), len) == 0; }
};
@ -125,10 +126,12 @@ struct mapping_record
operator bool() const { return loaded; }
bool loaded;
int64_t id;
mapping_type type;
std::string name_hash; // name hashed and represented in base64 encoding
mapping_value encrypted_value;
uint64_t register_height;
uint64_t update_height;
crypto::hash txid;
crypto::hash prev_txid;
int64_t owner_id;
@ -137,16 +140,59 @@ struct mapping_record
generic_owner backup_owner;
};
struct name_system_db;
class sql_compiled_statement final
{
public:
/// The name_system_db upon which this object operates
name_system_db& nsdb;
/// The stored, owned statement
sqlite3_stmt* statement = nullptr;
/// Constructor; takes a reference to the name_system_db.
explicit sql_compiled_statement(name_system_db& nsdb) : nsdb{nsdb} {}
/// Non-copyable (because we own an internal sqlite3 statement handle)
sql_compiled_statement(const sql_compiled_statement&) = delete;
sql_compiled_statement& operator=(const sql_compiled_statement&) = delete;
/// Move construction; ownership of the internal statement handle, if present, is transferred to
/// the new object.
sql_compiled_statement(sql_compiled_statement&& from) : nsdb{from.nsdb}, statement{from.statement} { from.statement = nullptr; }
/// Move copying. The referenced name_system_db must be the same. Ownership of the internal
/// statement handle is transferred. If the target already has a statement handle then it is
/// destroyed.
sql_compiled_statement& operator=(sql_compiled_statement&& from);
/// Destroys the internal sqlite3 statement on destruction
~sql_compiled_statement();
/// Attempts to prepare the given statement. MERRORs and returns false on failure. If the object
/// already has a prepare statement then it is finalized first.
bool compile(lokimq::string_view query, bool optimise_for_multiple_usage = true);
template <size_t N>
bool compile(const char (&query)[N], bool optimise_for_multiple_usage = true)
{
return compile({&query[0], N}, optimise_for_multiple_usage);
}
/// Returns true if the object owns a prepared statement
explicit operator bool() const { return statement != nullptr; }
};
struct name_system_db
{
bool init (cryptonote::network_type nettype, sqlite3 *db, uint64_t top_height, crypto::hash const &top_hash);
bool init (cryptonote::Blockchain const *blockchain, cryptonote::network_type nettype, sqlite3 *db);
bool add_block (const cryptonote::block& block, const std::vector<cryptonote::transaction>& txs);
cryptonote::network_type network_type() const { return nettype; }
uint64_t height () const { return last_processed_height; }
// 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 (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_settings (uint64_t top_height, crypto::hash const &top_hash, int version);
@ -154,33 +200,36 @@ struct name_system_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);
owner_record get_owner_by_key (generic_owner const &owner) 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;
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 (generic_owner const &key) const;
std::vector<mapping_record> get_mappings_by_owners(std::vector<generic_owner> const &keys) const;
settings_record get_settings () const;
owner_record get_owner_by_key (generic_owner const &owner);
owner_record get_owner_by_id (int64_t owner_id);
mapping_record get_mapping (mapping_type type, std::string const &name_base64_hash);
std::vector<mapping_record> get_mappings (std::vector<uint16_t> const &types, std::string const &name_base64_hash);
std::vector<mapping_record> get_mappings_by_owner (generic_owner const &key);
std::vector<mapping_record> get_mappings_by_owners(std::vector<generic_owner> const &keys);
settings_record get_settings ();
// entry: (optional) if function returns true, the Loki Name System entry in the TX extra is copied into 'entry'
bool validate_lns_tx (uint8_t hf_version, uint64_t blockchain_height, cryptonote::transaction const &tx, cryptonote::tx_extra_loki_name_system *entry = nullptr, std::string *reason = nullptr) const;
bool validate_lns_tx (uint8_t hf_version, uint64_t blockchain_height, cryptonote::transaction const &tx, cryptonote::tx_extra_loki_name_system *entry = nullptr, std::string *reason = nullptr);
// Destructor; closes the sqlite3 database if one is open
~name_system_db();
sqlite3 *db = nullptr;
bool transaction_begun = false;
private:
cryptonote::network_type nettype;
uint64_t last_processed_height = 0;
sqlite3_stmt *save_owner_sql = nullptr;
sqlite3_stmt *save_mapping_sql = nullptr;
sqlite3_stmt *save_settings_sql = nullptr;
sqlite3_stmt *get_owner_by_key_sql = nullptr;
sqlite3_stmt *get_owner_by_id_sql = nullptr;
sqlite3_stmt *get_mapping_sql = nullptr;
sqlite3_stmt *get_settings_sql = nullptr;
sqlite3_stmt *prune_mappings_sql = nullptr;
sqlite3_stmt *prune_owners_sql = nullptr;
sqlite3_stmt *get_mappings_by_owner_sql = nullptr;
sqlite3_stmt *get_mappings_on_height_and_newer_sql = nullptr;
uint64_t last_processed_height = 0;
sql_compiled_statement save_owner_sql{*this};
sql_compiled_statement save_mapping_sql{*this};
sql_compiled_statement save_settings_sql{*this};
sql_compiled_statement get_owner_by_key_sql{*this};
sql_compiled_statement get_owner_by_id_sql{*this};
sql_compiled_statement get_mapping_sql{*this};
sql_compiled_statement get_settings_sql{*this};
sql_compiled_statement prune_mappings_sql{*this};
sql_compiled_statement prune_owners_sql{*this};
sql_compiled_statement get_mappings_by_owner_sql{*this};
sql_compiled_statement get_mappings_on_height_and_newer_sql{*this};
};
}; // namespace service_nodes

View file

@ -76,6 +76,17 @@ namespace
}
}
namespace std
{
template <>
struct hash<lns::generic_owner>
{
static_assert(sizeof(lns::generic_owner) >= sizeof(std::size_t) && alignof(lns::generic_owner) >= alignof(std::size_t),
"Size and alignment of hash must be at least that of size_t");
std::size_t operator()(const lns::generic_owner &v) const { return reinterpret_cast<const std::size_t &>(v); }
};
} // namespace std
namespace cryptonote
{
//-----------------------------------------------------------------------------------
@ -3383,7 +3394,7 @@ namespace cryptonote
if (exceeds_quantity_limit(ctx, error_resp, m_restricted, req.entries.size(), COMMAND_RPC_LNS_NAMES_TO_OWNERS::MAX_REQUEST_ENTRIES))
return false;
lns::name_system_db const &db = m_core.get_blockchain_storage().name_system_db();
lns::name_system_db &db = m_core.get_blockchain_storage().name_system_db();
for (size_t request_index = 0; request_index < req.entries.size(); request_index++)
{
COMMAND_RPC_LNS_NAMES_TO_OWNERS::request_entry const &request = req.entries[request_index];
@ -3402,6 +3413,7 @@ namespace cryptonote
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.register_height = record.register_height;
entry.update_height = record.update_height;
entry.txid = epee::string_tools::pod_to_hex(record.txid);
if (record.prev_txid) entry.prev_txid = epee::string_tools::pod_to_hex(record.prev_txid);
}
@ -3416,7 +3428,7 @@ namespace cryptonote
if (exceeds_quantity_limit(ctx, error_resp, m_restricted, req.entries.size(), COMMAND_RPC_LNS_OWNERS_TO_NAMES::MAX_REQUEST_ENTRIES))
return false;
std::map<lns::generic_owner, size_t> owner_to_request_index;
std::unordered_map<lns::generic_owner, size_t> owner_to_request_index;
std::vector<lns::generic_owner> owners;
owners.reserve(req.entries.size());
@ -3430,11 +3442,15 @@ namespace cryptonote
return false;
}
// TODO(loki): We now serialize both owner and backup_owner, since if
// we specify an owner that is backup owner, we don't show the (other)
// owner. For RPC compatibility we keep the request_index around until the
// next hard fork (16)
owners.push_back(lns_owner);
owner_to_request_index[owners.back()] = request_index;
owner_to_request_index[lns_owner] = request_index;
}
lns::name_system_db const &db = m_core.get_blockchain_storage().name_system_db();
lns::name_system_db &db = m_core.get_blockchain_storage().name_system_db();
std::vector<lns::mapping_record> records = db.get_mappings_by_owners(owners);
for (auto &record : records)
{
@ -3452,9 +3468,11 @@ namespace cryptonote
entry.request_index = it->second;
entry.type = static_cast<uint16_t>(record.type);
entry.name_hash = std::move(record.name_hash);
if (record.owner) entry.owner = record.owner.to_string(nettype());
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.register_height = record.register_height;
entry.update_height = record.update_height;
entry.txid = epee::string_tools::pod_to_hex(record.txid);
if (record.prev_txid) entry.prev_txid = epee::string_tools::pod_to_hex(record.prev_txid);
}

View file

@ -94,7 +94,7 @@ constexpr char const CORE_RPC_STATUS_TX_LONG_POLL_MAX_CONNECTIONS[] = "Daemon ma
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 3
#define CORE_RPC_VERSION_MINOR 2
#define CORE_RPC_VERSION_MINOR 3
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
@ -3496,6 +3496,7 @@ constexpr char const CORE_RPC_STATUS_TX_LONG_POLL_MAX_CONNECTIONS[] = "Daemon ma
std::string backup_owner; // The backup public key that the owner specified when purchasing the Loki Name Service entry.
std::string encrypted_value; // The encrypted value that the name maps to. This value is encrypted using the name (not the hash) as the secret.
uint64_t register_height; // The height that this Loki Name Service entry was purchased on the Blockchain.
uint64_t update_height; // The last height that this Loki Name Service entry was updated on the Blockchain.
std::string txid; // The txid of who purchased the mapping, null hash if not applicable.
std::string prev_txid; // The previous txid that purchased the mapping, null hash if not applicable.
BEGIN_KV_SERIALIZE_MAP()
@ -3506,6 +3507,7 @@ constexpr char const CORE_RPC_STATUS_TX_LONG_POLL_MAX_CONNECTIONS[] = "Daemon ma
KV_SERIALIZE(backup_owner)
KV_SERIALIZE(encrypted_value)
KV_SERIALIZE(register_height)
KV_SERIALIZE(update_height)
KV_SERIALIZE(txid)
KV_SERIALIZE(prev_txid)
END_KV_SERIALIZE_MAP()
@ -3538,21 +3540,25 @@ constexpr char const CORE_RPC_STATUS_TX_LONG_POLL_MAX_CONNECTIONS[] = "Daemon ma
struct response_entry
{
uint64_t request_index; // The index in request's `entries` array that was resolved via Loki Name Service.
uint64_t request_index; // (Deprecated) The index in request's `entries` array that was resolved via Loki Name Service.
uint16_t type; // The category the Loki Name Service entry belongs to, currently only Session whose value is 0.
std::string name_hash; // The hash of the name that the owner purchased via Loki Name Service in base64
std::string owner; // The backup public key specified by the owner that purchased the Loki Name Service entry.
std::string backup_owner; // The backup public key specified by the owner that purchased the Loki Name Service entry.
std::string encrypted_value; // The encrypted value that the name maps to. This value is encrypted using the name (not the hash) as the secret.
uint64_t register_height; // The height that this Loki Name Service entry was purchased on the Blockchain.
uint64_t update_height; // The last height that this Loki Name Service entry was updated on the Blockchain.
std::string txid; // The txid of who purchases the mapping.
std::string prev_txid; // The previous txid that purchased the mapping, null hash if not applicable.
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(request_index)
KV_SERIALIZE(type)
KV_SERIALIZE(name_hash)
KV_SERIALIZE(owner)
KV_SERIALIZE(backup_owner)
KV_SERIALIZE(encrypted_value)
KV_SERIALIZE(register_height)
KV_SERIALIZE(update_height)
KV_SERIALIZE(txid)
KV_SERIALIZE(prev_txid)
END_KV_SERIALIZE_MAP()

View file

@ -41,8 +41,11 @@ target_link_libraries(simplewallet
Boost::chrono
Boost::program_options
Boost::filesystem
Boost::locale
Boost::regex
icu
Boost::thread
extra)
if (WIN32)
target_link_libraries(simplewallet PRIVATE Boost::locale)
endif()

View file

@ -6604,8 +6604,9 @@ bool simple_wallet::lns_print_name_to_owners(const std::vector<std::string>& arg
<< ", owner=" << mapping.owner
<< ", backup_owner=" << (mapping.backup_owner.empty() ? NULL_STR : mapping.backup_owner)
<< ", height=" << mapping.register_height
<< ", update_height=" << mapping.update_height
<< ", encrypted_value=" << mapping.encrypted_value
<< ", value=" << epee::to_hex::string(value.to_span())
<< ", value=" << value.to_readable_value(m_wallet->nettype(), static_cast<lns::mapping_type>(mapping.type))
<< ", prev_txid=" << (mapping.prev_txid.empty() ? NULL_STR : mapping.prev_txid);
}
@ -6618,13 +6619,17 @@ bool simple_wallet::lns_print_owners_to_names(const std::vector<std::string>& ar
return false;
boost::optional<std::string> failed;
std::vector<std::vector<cryptonote::COMMAND_RPC_LNS_OWNERS_TO_NAMES::response_entry>> rpc_results;
std::vector<cryptonote::COMMAND_RPC_LNS_OWNERS_TO_NAMES::request> requests(1);
std::string my_key;
cryptonote::COMMAND_RPC_LNS_OWNERS_TO_NAMES::request request = {};
if (args.size() == 0)
{
my_key = m_wallet->get_subaddress_as_str({m_current_subaddress_account, 0});
request.entries.push_back(my_key);
for (uint32_t index = 0; index < m_wallet->get_num_subaddresses(m_current_subaddress_account); ++index)
{
if (requests.back().entries.size() >= cryptonote::COMMAND_RPC_LNS_OWNERS_TO_NAMES::MAX_REQUEST_ENTRIES)
requests.emplace_back();
requests.back().entries.push_back(m_wallet->get_subaddress_as_str({m_current_subaddress_account, index}));
}
}
else
{
@ -6641,40 +6646,50 @@ bool simple_wallet::lns_print_owners_to_names(const std::vector<std::string>& ar
fail_msg_writer() << "arg contains non-hex characters: " << arg;
return false;
}
request.entries.push_back(arg);
if (requests.back().entries.size() >= cryptonote::COMMAND_RPC_LNS_OWNERS_TO_NAMES::MAX_REQUEST_ENTRIES)
requests.emplace_back();
requests.back().entries.push_back(arg);
}
}
std::vector<cryptonote::COMMAND_RPC_LNS_OWNERS_TO_NAMES::response_entry> entries = m_wallet->lns_owners_to_names(request, failed);
if (failed)
rpc_results.reserve(requests.size());
for (auto const &request : requests)
{
fail_msg_writer() << *failed;
return false;
std::vector<cryptonote::COMMAND_RPC_LNS_OWNERS_TO_NAMES::response_entry> result = m_wallet->lns_owners_to_names(request, failed);
if (failed)
{
fail_msg_writer() << *failed;
return false;
}
rpc_results.emplace_back(std::move(result));
}
for (cryptonote::COMMAND_RPC_LNS_OWNERS_TO_NAMES::response_entry const &entry : entries)
for (size_t i = 0; i < rpc_results.size(); i++)
{
std::string const *owner = &my_key;
if (args.size()) // If specified owner to look up, retrieve it
auto const &rpc = rpc_results[i];
for (auto const &entry : rpc)
{
std::string const *owner = nullptr;
try
{
owner = &args.at(entry.request_index);
owner = &requests[i].entries.at(entry.request_index);
}
catch (std::exception const &e)
{
fail_msg_writer() << "Daemon returned an invalid owner index = " << entry.request_index << " skipping mapping";
continue;
}
}
tools::msg_writer() << "owner=" << *owner
<< ", backup_owner=" << (entry.backup_owner.empty() ? NULL_STR : entry.backup_owner)
<< ", type=" << static_cast<lns::mapping_type>(entry.type)
<< ", height=" << entry.register_height
<< ", name_hash=" << entry.name_hash
<< ", encrypted_value=" << entry.encrypted_value
<< ", prev_txid=" << (entry.prev_txid.empty() ? NULL_STR : entry.prev_txid);
tools::msg_writer() << "owner=" << *owner
<< ", backup_owner=" << (entry.backup_owner.empty() ? NULL_STR : entry.backup_owner)
<< ", type=" << static_cast<lns::mapping_type>(entry.type)
<< ", height=" << entry.register_height
<< ", update_height=" << entry.update_height
<< ", name_hash=" << entry.name_hash
<< ", encrypted_value=" << entry.encrypted_value
<< ", prev_txid=" << (entry.prev_txid.empty() ? NULL_STR : entry.prev_txid);
}
}
return true;
}

View file

@ -1,6 +1,6 @@
#define DEF_LOKI_VERSION_MAJOR 7
#define DEF_LOKI_VERSION_MINOR 1
#define DEF_LOKI_VERSION_PATCH 2
#define DEF_LOKI_VERSION_PATCH 3
#define LOKI_STRINGIFY2(val) #val
#define LOKI_STRINGIFY(val) LOKI_STRINGIFY2(val)

View file

@ -168,8 +168,6 @@ public:
Subaddress * subaddress() override;
SubaddressAccount * subaddressAccount() override;
void setListener(WalletListener * l) override;
uint32_t defaultMixin() const override;
void setDefaultMixin(uint32_t arg) override;
bool setUserNote(const std::string &txid, const std::string &note) override;
std::string getUserNote(const std::string &txid) const override;
std::string getTxKey(const std::string &txid) const override;

View file

@ -877,16 +877,6 @@ struct Wallet
virtual Subaddress * subaddress() = 0;
virtual SubaddressAccount * subaddressAccount() = 0;
virtual void setListener(WalletListener *) = 0;
/*!
* \brief defaultMixin - returns number of mixins used in transactions
* \return
*/
virtual uint32_t defaultMixin() const = 0;
/*!
* \brief setDefaultMixin - setum number of mixins to be used for new transactions
* \param arg
*/
virtual void setDefaultMixin(uint32_t arg) = 0;
/*!
* \brief setUserNote - attach an arbitrary string note to a txid

View file

@ -8439,6 +8439,36 @@ struct lns_prepared_args
crypto::hash prev_txid;
};
static bool try_generate_lns_signature(wallet2 const &wallet, std::string const &curr_owner, std::string const *new_owner, std::string const *new_backup_owner, lns_prepared_args &result)
{
cryptonote::address_parse_info curr_owner_parsed = {};
if (!cryptonote::get_account_address_from_str(curr_owner_parsed, wallet.nettype(), curr_owner))
return false;
boost::optional<cryptonote::subaddress_index> index = wallet.get_subaddress_index(curr_owner_parsed.address);
if (!index) return false;
// 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(),
new_owner ? &result.owner : nullptr,
new_backup_owner ? &result.backup_owner : nullptr,
result.prev_txid);
if (!hash) return false;
result.signature = lns::make_monero_signature(hash, pkey, skey);
return true;
}
static lns_prepared_args prepare_tx_extra_loki_name_system_values(wallet2 const &wallet,
lns::mapping_type type,
uint32_t priority,
@ -8506,27 +8536,32 @@ static lns_prepared_args prepare_tx_extra_loki_name_system_values(wallet2 const
return result;
}
}
}
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())
if (make_signature)
{
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);
if (response.empty())
{
if (reason) *reason = "Signature requested when preparing LNS TX but record to update does not exist";
return result;
}
cryptonote::address_parse_info curr_owner_parsed = {};
cryptonote::address_parse_info curr_backup_owner_parsed = {};
bool curr_owner = cryptonote::get_account_address_from_str(curr_owner_parsed, wallet.nettype(), response[0].owner);
bool curr_backup_owner = cryptonote::get_account_address_from_str(curr_backup_owner_parsed, wallet.nettype(), response[0].backup_owner);
if (!try_generate_lns_signature(wallet, response[0].owner, owner, backup_owner, result))
{
if (!try_generate_lns_signature(wallet, response[0].backup_owner, owner, backup_owner, result))
{
if (reason)
{
*reason = "Signature requested when preparing LNS TX, but this wallet is not the owner of the record owner=" + response[0].owner;
if (response[0].backup_owner.size()) *reason += ", backup_owner=" + response[0].backup_owner;
}
return result;
}
}
}
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);
if (!hash) return result;
result.signature = lns::make_monero_signature(hash, pkey, skey);
}
result.prepared = true;

View file

@ -860,8 +860,7 @@ namespace tools
try
{
uint32_t priority = req.priority;
if (req.blink || priority == 0x626c6e6b /* deprecated blink priority, can remove post-HF15 */)
if (req.blink || priority != tx_priority_unimportant)
priority = tx_priority_blink;
boost::optional<uint8_t> hf_version = m_wallet->get_hard_fork_version();
@ -923,8 +922,7 @@ namespace tools
try
{
uint32_t priority = req.priority;
if (req.blink || priority == 0x626c6e6b /* deprecated blink priority, can remove post-HF15 */)
if (req.blink || priority != tx_priority_unimportant)
priority = tx_priority_blink;
boost::optional<uint8_t> hf_version = m_wallet->get_hard_fork_version();
@ -1345,8 +1343,7 @@ namespace tools
try
{
uint32_t priority = req.priority;
if (req.blink || priority == 0x626c6e6b /* deprecated blink priority, can remove post-HF15 */)
if (req.blink || priority != tx_priority_unimportant)
priority = tx_priority_blink;
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, req.outputs, CRYPTONOTE_DEFAULT_TX_MIXIN, req.unlock_time, priority, extra, req.account_index, req.subaddr_indices);
@ -1403,8 +1400,7 @@ namespace tools
try
{
uint32_t priority = req.priority;
if (req.blink || priority == 0x626c6e6b /* deprecated blink priority, can remove post-HF15 */)
if (req.blink || priority != tx_priority_unimportant)
priority = tx_priority_blink;
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_single(ki, dsts[0].addr, dsts[0].is_subaddress, req.outputs, CRYPTONOTE_DEFAULT_TX_MIXIN, req.unlock_time, priority, extra);
@ -4179,8 +4175,17 @@ namespace tools
}
std::vector<tools::wallet2::pending_tx> ptx_vector = {stake_result.ptx};
return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.multisig_txset, res.unsigned_txset, req.do_not_relay, false /*blink*/,
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er);
try
{
return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.multisig_txset, res.unsigned_txset, req.do_not_relay, false /*blink*/,
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er);
}
catch (const std::exception &e)
{
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
return false;
}
}
bool wallet_rpc_server::on_register_service_node(const wallet_rpc::COMMAND_RPC_REGISTER_SERVICE_NODE::request& req, wallet_rpc::COMMAND_RPC_REGISTER_SERVICE_NODE::response& res, epee::json_rpc::error& er, const connection_context *ctx)
@ -4212,8 +4217,16 @@ namespace tools
}
std::vector<tools::wallet2::pending_tx> ptx_vector = {register_result.ptx};
return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.multisig_txset, res.unsigned_txset, req.do_not_relay, false /*blink*/,
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er);
try
{
return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.multisig_txset, res.unsigned_txset, req.do_not_relay, false /*blink*/,
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er);
}
catch (const std::exception &e)
{
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
return false;
}
}
bool wallet_rpc_server::on_can_request_stake_unlock(const wallet_rpc::COMMAND_RPC_CAN_REQUEST_STAKE_UNLOCK::request& req, wallet_rpc::COMMAND_RPC_CAN_REQUEST_STAKE_UNLOCK::response& res, epee::json_rpc::error& er, const connection_context *ctx)
@ -4306,21 +4319,29 @@ namespace tools
return false;
}
return fill_response(ptx_vector,
req.get_tx_key,
res.tx_key,
res.amount,
res.fee,
res.multisig_txset,
res.unsigned_txset,
req.do_not_relay,
false /*blink*/,
res.tx_hash,
req.get_tx_hex,
res.tx_blob,
req.get_tx_metadata,
res.tx_metadata,
er);
try
{
return fill_response(ptx_vector,
req.get_tx_key,
res.tx_key,
res.amount,
res.fee,
res.multisig_txset,
res.unsigned_txset,
req.do_not_relay,
false /*blink*/,
res.tx_hash,
req.get_tx_hex,
res.tx_blob,
req.get_tx_metadata,
res.tx_metadata,
er);
}
catch (const std::exception &e)
{
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
return false;
}
}
bool wallet_rpc_server::on_lns_update_mapping(const wallet_rpc::COMMAND_RPC_LNS_UPDATE_MAPPING::request &req, wallet_rpc::COMMAND_RPC_LNS_UPDATE_MAPPING::response &res, epee::json_rpc::error &er, const connection_context *ctx)
@ -4353,21 +4374,29 @@ namespace tools
return false;
}
return fill_response(ptx_vector,
req.get_tx_key,
res.tx_key,
res.amount,
res.fee,
res.multisig_txset,
res.unsigned_txset,
req.do_not_relay,
false /*blink*/,
res.tx_hash,
req.get_tx_hex,
res.tx_blob,
req.get_tx_metadata,
res.tx_metadata,
er);
try
{
return fill_response(ptx_vector,
req.get_tx_key,
res.tx_key,
res.amount,
res.fee,
res.multisig_txset,
res.unsigned_txset,
req.do_not_relay,
false /*blink*/,
res.tx_hash,
req.get_tx_hex,
res.tx_blob,
req.get_tx_metadata,
res.tx_metadata,
er);
}
catch (const std::exception &e)
{
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
return false;
}
}
bool wallet_rpc_server::on_lns_make_update_mapping_signature(const wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE::request& req, wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE::response& res, epee::json_rpc::error& er, const connection_context *ctx)
@ -4407,6 +4436,104 @@ namespace tools
res.signature = epee::string_tools::pod_to_hex(signature.ed25519);
return true;
}
bool wallet_rpc_server::on_lns_hash_name(const wallet_rpc::COMMAND_RPC_LNS_HASH_NAME::request& req, wallet_rpc::COMMAND_RPC_LNS_HASH_NAME::response& res, epee::json_rpc::error& er, const connection_context *ctx)
{
if (!m_wallet) return not_open(er);
std::string reason;
lns::mapping_type type;
if (!lns::validate_mapping_type(req.type, &type, &reason))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_LNS_TYPE;
er.message = "Wrong lns type given=" + reason;
return false;
}
if (!lns::validate_lns_name(type, req.name, &reason))
{
er.code = WALLET_RPC_ERROR_CODE_LNS_BAD_NAME;
er.message = "Bad lns name given=" + reason;
return false;
}
res.name = lns::name_to_base64_hash(req.name);
return true;
}
bool wallet_rpc_server::on_lns_decrypt_value(const wallet_rpc::COMMAND_RPC_LNS_DECRYPT_VALUE::request& req, wallet_rpc::COMMAND_RPC_LNS_DECRYPT_VALUE::response& res, epee::json_rpc::error& er, const connection_context *ctx)
{
if (!m_wallet) return not_open(er);
// ---------------------------------------------------------------------------------------------
//
// Validate encrypted value
//
// ---------------------------------------------------------------------------------------------
if (req.encrypted_value.size() % 2 != 0)
{
er.code = WALLET_RPC_ERROR_CODE_LNS_VALUE_LENGTH_NOT_EVEN;
er.message = "Value length not divisible by 2, length=" + std::to_string(req.encrypted_value.size());
return false;
}
if (req.encrypted_value.size() >= (lns::mapping_value::BUFFER_SIZE * 2))
{
er.code = WALLET_RPC_ERROR_CODE_LNS_VALUE_TOO_LONG;
er.message = "Value too long to decrypt=" + req.encrypted_value;
return false;
}
if (!lokimq::is_hex(req.encrypted_value))
{
er.code = WALLET_RPC_ERROR_CODE_LNS_VALUE_NOT_HEX;
er.message = "Value is not hex=" + req.encrypted_value;
return false;
}
// ---------------------------------------------------------------------------------------------
//
// Validate type and name
//
// ---------------------------------------------------------------------------------------------
std::string reason;
lns::mapping_type type = {};
{
if (!lns::validate_mapping_type(req.type, &type, &reason))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_LNS_TYPE;
er.message = "Wrong lns type given=" + reason;
return false;
}
if (!lns::validate_lns_name(type, req.name, &reason))
{
er.code = WALLET_RPC_ERROR_CODE_LNS_VALUE_NOT_HEX;
er.message = "Value is not hex=" + req.encrypted_value;
return false;
}
}
// ---------------------------------------------------------------------------------------------
//
// Decrypt value
//
// ---------------------------------------------------------------------------------------------
lns::mapping_value encrypted_value = {};
encrypted_value.len = req.encrypted_value.size() / 2;
lokimq::from_hex(req.encrypted_value.begin(), req.encrypted_value.end(), encrypted_value.buffer.begin());
lns::mapping_value value = {};
if (!lns::decrypt_mapping_value(req.name, encrypted_value, value))
{
er.code = WALLET_RPC_ERROR_CODE_LNS_VALUE_NOT_HEX;
er.message = "Value decryption failure";
return false;
}
res.value = value.to_readable_value(m_wallet->nettype(), type);
return true;
}
}
class t_daemon

View file

@ -167,6 +167,8 @@ namespace tools
MAP_JON_RPC_WE("lns_buy_mapping", on_lns_buy_mapping, wallet_rpc::COMMAND_RPC_LNS_BUY_MAPPING)
MAP_JON_RPC_WE("lns_update_mapping", on_lns_update_mapping, wallet_rpc::COMMAND_RPC_LNS_UPDATE_MAPPING)
MAP_JON_RPC_WE("lns_make_update_mapping_signature", on_lns_make_update_mapping_signature, wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE)
MAP_JON_RPC_WE("lns_hash_name", on_lns_hash_name, wallet_rpc::COMMAND_RPC_LNS_HASH_NAME)
MAP_JON_RPC_WE("lns_decrypt_value", on_lns_decrypt_value, wallet_rpc::COMMAND_RPC_LNS_DECRYPT_VALUE)
END_JSON_RPC_MAP()
END_URI_MAP2()
@ -260,6 +262,8 @@ namespace tools
bool on_lns_buy_mapping(const wallet_rpc::COMMAND_RPC_LNS_BUY_MAPPING::request& req, wallet_rpc::COMMAND_RPC_LNS_BUY_MAPPING::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_lns_update_mapping(const wallet_rpc::COMMAND_RPC_LNS_UPDATE_MAPPING::request& req, wallet_rpc::COMMAND_RPC_LNS_UPDATE_MAPPING::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_lns_make_update_mapping_signature(const wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE::request& req, wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_lns_hash_name(const wallet_rpc::COMMAND_RPC_LNS_HASH_NAME::request& req, wallet_rpc::COMMAND_RPC_LNS_HASH_NAME::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_lns_decrypt_value(const wallet_rpc::COMMAND_RPC_LNS_DECRYPT_VALUE::request& req, wallet_rpc::COMMAND_RPC_LNS_DECRYPT_VALUE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
//json rpc v2
bool on_query_key(const wallet_rpc::COMMAND_RPC_QUERY_KEY::request& req, wallet_rpc::COMMAND_RPC_QUERY_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);

View file

@ -3033,5 +3033,57 @@ This command is only required if the open wallet is one of the owners of a LNS r
};
typedef epee::misc_utils::struct_init<response_t> response;
};
LOKI_RPC_DOC_INTROSPECT
// Takes a LNS name, upon validating it, generates the hash and returns the base64 representation of the hash suitable for use in the daemon LNS name queries.
struct COMMAND_RPC_LNS_HASH_NAME
{
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 name; // The desired name to hash
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(type);
KV_SERIALIZE(name);
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
struct response_t
{
std::string name; // The name hashed and represented in base64
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(name)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
};
LOKI_RPC_DOC_INTROSPECT
// Takes a LNS encrypted value and decrypts the mapping value.
struct COMMAND_RPC_LNS_DECRYPT_VALUE
{
struct request_t
{
std::string name; // The desired name to hash
std::string type; // The mapping type, currently we only support "session". In future "lokinet" and "blockchain" mappings will be available.
std::string encrypted_value; // The encrypted value represented in hex
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(name);
KV_SERIALIZE(type);
KV_SERIALIZE(encrypted_value);
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;
struct response_t
{
std::string value; // The value decrypted
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(value)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;
};
}
}

View file

@ -80,3 +80,8 @@
#define WALLET_RPC_ERROR_CODE_BLINK_FAILED -1000
#define WALLET_RPC_ERROR_CODE_HF_QUERY_FAILED -1001
#define WALLET_RPC_ERROR_CODE_WRONG_LNS_TYPE -1002
#define WALLET_RPC_ERROR_CODE_LNS_BAD_NAME -1003
#define WALLET_RPC_ERROR_CODE_LNS_VALUE_TOO_LONG -1004
#define WALLET_RPC_ERROR_CODE_LNS_VALUE_NOT_HEX -1005
#define WALLET_RPC_ERROR_CODE_LNS_VALUE_LENGTH_NOT_EVEN -1006
#define WALLET_RPC_ERROR_CODE_LNS_VALUE_DECRYPT_FAILED -1007

View file

@ -135,7 +135,7 @@ loki_chain_generator::loki_chain_generator(std::vector<test_event_entry> &events
: events_(events)
, hard_forks_(hard_forks)
{
bool init = lns_db_.init(cryptonote::FAKECHAIN, lns::init_loki_name_system(""), 0, crypto::null_hash);
bool init = lns_db_->init(nullptr, cryptonote::FAKECHAIN, lns::init_loki_name_system(""));
assert(init);
first_miner_.generate();
@ -152,11 +152,6 @@ loki_chain_generator::loki_chain_generator(std::vector<test_event_entry> &events
events_.push_back(settings);
}
loki_chain_generator::~loki_chain_generator()
{
sqlite3_close_v2(lns_db_.db);
}
service_nodes::quorum_manager loki_chain_generator::top_quorum() const
{
service_nodes::quorum_manager result = top().service_node_state.quorums;
@ -210,7 +205,7 @@ loki_blockchain_entry &loki_chain_generator::add_block(loki_blockchain_entry con
if (can_be_added_to_blockchain && entry.block.major_version >= cryptonote::network_version_15_lns)
{
lns_db_.add_block(entry.block, entry.txs);
lns_db_->add_block(entry.block, entry.txs);
}
// TODO(loki): State history culling and alt states
@ -554,7 +549,7 @@ cryptonote::transaction loki_chain_generator::create_loki_name_system_tx(crypton
crypto::hash name_hash = lns::name_to_hash(name);
std::string name_base64_hash = lns::name_to_base64_hash(name);
crypto::hash prev_txid = crypto::null_hash;
if (lns::mapping_record mapping = lns_db_.get_mapping(type, name_base64_hash))
if (lns::mapping_record mapping = lns_db_->get_mapping(type, name_base64_hash))
prev_txid = mapping.txid;
lns::mapping_value encrypted_value = {};
@ -588,7 +583,7 @@ cryptonote::transaction loki_chain_generator::create_loki_name_system_tx_update(
crypto::hash prev_txid = {};
{
std::string name_base64_hash = lns::name_to_base64_hash(name);
lns::mapping_record mapping = lns_db_.get_mapping(type, name_base64_hash);
lns::mapping_record mapping = lns_db_->get_mapping(type, name_base64_hash);
if (use_asserts) assert(mapping);
prev_txid = mapping.txid;
}

View file

@ -1385,7 +1385,7 @@ struct loki_chain_generator
mutable std::unordered_map<crypto::public_key, crypto::secret_key> service_node_keys_;
service_nodes::service_node_list::state_set state_history_;
uint64_t last_cull_height_ = 0;
lns::name_system_db lns_db_;
std::shared_ptr<lns::name_system_db> lns_db_ = std::make_shared<lns::name_system_db>();
loki_chain_generator_db db_;
uint8_t hf_version_ = cryptonote::network_version_7;
std::vector<test_event_entry>& events_;
@ -1393,7 +1393,6 @@ struct loki_chain_generator
cryptonote::account_base first_miner_;
loki_chain_generator(std::vector<test_event_entry> &events, const std::vector<std::pair<uint8_t, uint64_t>> &hard_forks);
~loki_chain_generator();
uint64_t height() const { return cryptonote::get_block_height(db_.blocks.back().block); }
uint64_t chain_height() const { return height() + 1; }

View file

@ -1063,6 +1063,7 @@ static bool verify_lns_mapping_record(char const *perr_context,
std::string const &name,
lns::mapping_value const &value,
uint64_t register_height,
uint64_t update_height,
crypto::hash const &txid,
crypto::hash const &prev_txid,
lns::generic_owner const &owner,
@ -1074,10 +1075,11 @@ static bool verify_lns_mapping_record(char const *perr_context,
CHECK_EQ(record.name_hash, lns::name_to_base64_hash(name));
CHECK_EQ(record.encrypted_value, encrypted_value);
CHECK_EQ(record.register_height, register_height);
CHECK_EQ(record.update_height, update_height);
CHECK_EQ(record.txid, txid);
CHECK_EQ(record.prev_txid, prev_txid);
CHECK_EQ(record.owner, owner);
CHECK_EQ(record.backup_owner, backup_owner);
CHECK_TEST_CONDITION_MSG(record.owner == owner, record.owner.to_string(cryptonote::FAKECHAIN) << " == "<< owner.to_string(cryptonote::FAKECHAIN));
CHECK_TEST_CONDITION_MSG(record.backup_owner == backup_owner, record.backup_owner.to_string(cryptonote::FAKECHAIN) << " == "<< backup_owner.to_string(cryptonote::FAKECHAIN));
return true;
}
@ -1154,14 +1156,16 @@ bool loki_name_system_expiration::generate(std::vector<test_event_entry> &events
loki_register_callback(events, "check_lns_entries", [=](cryptonote::core &c, size_t ev_index)
{
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 &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.owner, owner.address);
CHECK_TEST_CONDITION_MSG(miner_key.owner == owner.address,
miner_key.owner.to_string(cryptonote::FAKECHAIN)
<< " == " << owner.address.to_string(cryptonote::FAKECHAIN));
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.owner, {} /*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, height_of_lns_entry, tx_hash, crypto::null_hash, miner_key.owner, {} /*backup_owner*/));
return true;
});
@ -1171,16 +1175,18 @@ bool loki_name_system_expiration::generate(std::vector<test_event_entry> &events
loki_register_callback(events, "check_expired", [=, blockchain_height = gen.chain_height()](cryptonote::core &c, size_t ev_index)
{
DEFINE_TESTS_ERROR_CONTEXT("check_expired");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
// 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.owner);
CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.owner, owner.address);
CHECK_TEST_CONDITION_MSG(miner_key.owner == owner.address,
miner_key.owner.to_string(cryptonote::FAKECHAIN)
<< " == " << owner.address.to_string(cryptonote::FAKECHAIN));
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.owner, {} /*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, height_of_lns_entry, tx_hash, crypto::null_hash, miner_key.owner, {} /*backup_owner*/));
CHECK_EQ(record.active(cryptonote::FAKECHAIN, blockchain_height), false);
return true;
});
@ -1257,7 +1263,7 @@ bool loki_name_system_get_mappings_by_owner::generate(std::vector<test_event_ent
loki_register_callback(events, "check_lns_entries", [=](cryptonote::core &c, size_t ev_index)
{
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 &lns_db = c.get_blockchain_storage().name_system_db();
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(bob_key.owner);
size_t expected_size = 0;
@ -1268,20 +1274,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))
{
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.owner, {} /*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_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_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))
{
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.owner, {} /*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_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_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))
{
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.owner, {} /*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_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_height, wallet_name2_txid, crypto::null_hash, bob_key.owner, {} /*backup_owner*/));
}
return true;
});
@ -1339,7 +1345,7 @@ bool loki_name_system_get_mappings_by_owners::generate(std::vector<test_event_en
loki_register_callback(events, "check_lns_entries", [=](cryptonote::core &c, size_t ev_index)
{
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 &lns_db = c.get_blockchain_storage().name_system_db();
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owners({bob_key.owner, miner_key.owner});
CHECK_EQ(records.size(), 3);
std::sort(records.begin(), records.end(), [](lns::mapping_record const &lhs, lns::mapping_record const &rhs) {
@ -1347,9 +1353,9 @@ bool loki_name_system_get_mappings_by_owners::generate(std::vector<test_event_en
});
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.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.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.owner, {}));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, records[index++], lns::mapping_type::session, session_name1, bob_key.session_value, session_height1, 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_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_height3, session_tx_hash3, crypto::null_hash, miner_key.owner, {}));
return true;
});
@ -1387,11 +1393,11 @@ bool loki_name_system_get_mappings::generate(std::vector<test_event_entry> &even
loki_register_callback(events, "check_lns_entries", [&events, bob_key, session_height, session_name1, session_tx_hash](cryptonote::core &c, size_t ev_index)
{
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 &lns_db = c.get_blockchain_storage().name_system_db();
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);
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.owner, {} /*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_height, session_tx_hash, crypto::null_hash /*prev_txid*/, bob_key.owner, {} /*backup_owner*/));
return true;
});
@ -1446,22 +1452,24 @@ bool loki_name_system_handles_duplicate_in_lns_db::generate(std::vector<test_eve
loki_register_callback(events, "check_lns_entries", [=](cryptonote::core &c, size_t ev_index)
{
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 &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.owner, owner.address);
CHECK_TEST_CONDITION_MSG(miner_key.owner == owner.address,
miner_key.owner.to_string(cryptonote::FAKECHAIN)
<< " == " << owner.address.to_string(cryptonote::FAKECHAIN));
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);
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_TEST_CONDITION(verify_lns_mapping_record(perr_context, record1, lns::mapping_type::session, session_name, bob_key.session_value, height_of_lns_entry, height_of_lns_entry, session_tx_hash, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
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))
{
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.owner, {} /*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, height_of_lns_entry, lokinet_tx_hash, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
CHECK_EQ(record2.owner_id, owner.id);
}
@ -1698,8 +1706,9 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
loki_register_callback(events, "check_first_lns_entries", [=](cryptonote::core &c, size_t ev_index)
{
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 &lns_db = c.get_blockchain_storage().name_system_db();
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(miner_key.owner);
CHECK_EQ(lns_db.height(), first_lns_height);
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;
@ -1709,11 +1718,11 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
for (lns::mapping_record const &record : records)
{
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.owner, {} /*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, 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)
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*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, lokinet_name1, miner_key.lokinet_value, first_lns_height, first_lns_height, lokinet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
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.owner, {} /*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, first_lns_height, wallet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else
{
assert(false);
@ -1726,11 +1735,13 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
while (gen.height() <= miner_earliest_renewable_height)
gen.create_and_add_next_block();
// NOTE: Generate and add the second round of (transactions + block) to the blockchain, renew lokinet and add bob's session
// NOTE: Generate and add the second round of (transactions + block) to the blockchain, renew lokinet and add bob's session, update miner's session value to other's session value
cryptonote::account_base const other = gen.add_account();
lns_keys_t const other_key = make_lns_keys(other);
uint64_t second_lns_height = 0;
{
std::string const bob_session_name1 = "I Like Session";
crypto::hash session_tx_hash2 = {}, lokinet_tx_hash2 = {};
crypto::hash session_tx_hash2 = {}, lokinet_tx_hash2 = {}, session_tx_hash3;
{
std::vector<cryptonote::transaction> txs;
txs.push_back(gen.create_and_add_loki_name_system_tx(bob, lns::mapping_type::session, bob_session_name1, bob_key.session_value));
@ -1738,6 +1749,10 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
if (lns::mapping_type_allowed(gen.hardfork(), lns::mapping_type::lokinet_1year))
txs.push_back(gen.create_and_add_loki_name_system_tx(miner, lns::mapping_type::lokinet_1year, "loki.loki", miner_key.lokinet_value));
txs.push_back(gen.create_and_add_loki_name_system_tx_update(miner, lns::mapping_type::session, session_name1, &other_key.session_value));
session_tx_hash3 = cryptonote::get_transaction_hash(txs.back());
gen.create_and_add_next_block(txs);
}
second_lns_height = gen.height();
@ -1745,7 +1760,8 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
loki_register_callback(events, "check_second_lns_entries", [=](cryptonote::core &c, size_t ev_index)
{
DEFINE_TESTS_ERROR_CONTEXT("check_second_lns_entries");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
CHECK_EQ(lns_db.height(), second_lns_height);
// NOTE: Check miner's record
if (lns::mapping_type_allowed(c.get_blockchain_storage().get_current_hard_fork_version(), lns::mapping_type::lokinet_1year))
@ -1754,11 +1770,11 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
for (lns::mapping_record const &record : records)
{
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.owner, {} /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, session_name1, other_key.session_value, first_lns_height, second_lns_height, session_tx_hash3, session_tx_hash1 /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
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.owner, {} /*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, second_lns_height, lokinet_tx_hash2, lokinet_tx_hash1 /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
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.owner, {} /*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, first_lns_height, wallet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else
{
assert(false);
@ -1770,7 +1786,7 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
{
std::vector<lns::mapping_record> records = lns_db.get_mappings_by_owner(bob_key.owner);
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.owner, {} /*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, second_lns_height, session_tx_hash2, crypto::null_hash /*prev_txid*/, bob_key.owner, {} /*backup_owner*/));
}
return true;
@ -1786,7 +1802,8 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
uint64_t curr_height = blockchain.get_current_blockchain_height();
uint64_t blocks_to_pop = curr_height - second_lns_height;
blockchain.pop_blocks(blocks_to_pop);
lns::name_system_db const &lns_db = blockchain.name_system_db();
lns::name_system_db &lns_db = blockchain.name_system_db();
CHECK_EQ(lns_db.height(), blockchain.get_current_blockchain_height() - 1);
// NOTE: Check bob's records got removed due to popping back to before it existed
{
@ -1808,11 +1825,11 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
for (lns::mapping_record const &record : records)
{
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.owner, {} /*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, 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)
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*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, lokinet_name1, miner_key.lokinet_value, first_lns_height, first_lns_height, lokinet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
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.owner, {} /*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, first_lns_height, wallet_tx_hash1, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
else
{
assert(false);
@ -1832,7 +1849,8 @@ bool loki_name_system_large_reorg::generate(std::vector<test_event_entry> &event
uint64_t curr_height = blockchain.get_current_blockchain_height();
uint64_t blocks_to_pop = curr_height - first_lns_height;
blockchain.pop_blocks(blocks_to_pop);
lns::name_system_db const &lns_db = blockchain.name_system_db();
lns::name_system_db &lns_db = blockchain.name_system_db();
CHECK_EQ(lns_db.height(), blockchain.get_current_blockchain_height() - 1);
// NOTE: Check miner's records are gone
{
@ -1876,16 +1894,18 @@ bool loki_name_system_name_renewal::generate(std::vector<test_event_entry> &even
loki_register_callback(events, "check_lns_entries", [=](cryptonote::core &c, size_t ev_index)
{
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 &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.owner, owner.address);
CHECK_TEST_CONDITION_MSG(miner_key.owner == owner.address,
miner_key.owner.to_string(cryptonote::FAKECHAIN)
<< " == " << owner.address.to_string(cryptonote::FAKECHAIN));
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);
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*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, height_of_lns_entry, prev_txid, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
return true;
});
@ -1901,16 +1921,18 @@ bool loki_name_system_name_renewal::generate(std::vector<test_event_entry> &even
loki_register_callback(events, "check_renewed", [=](cryptonote::core &c, size_t ev_index)
{
DEFINE_TESTS_ERROR_CONTEXT("check_renewed");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.owner, owner.address);
CHECK_TEST_CONDITION_MSG(miner_key.owner == owner.address,
miner_key.owner.to_string(cryptonote::FAKECHAIN)
<< " == " << owner.address.to_string(cryptonote::FAKECHAIN));
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);
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*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, renewal_height, renewal_height, txid, prev_txid, miner_key.owner, {} /*backup_owner*/));
return true;
});
@ -2024,16 +2046,18 @@ bool loki_name_system_update_mapping_after_expiry_fails::generate(std::vector<te
loki_register_callback(events, "check_still_expired", [=](cryptonote::core &c, size_t ev_index)
{
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 &lns_db = c.get_blockchain_storage().name_system_db();
lns::owner_record owner = lns_db.get_owner_by_key(miner_key.owner);
CHECK_EQ(owner.loaded, true);
CHECK_EQ(owner.id, 1);
CHECK_EQ(miner_key.owner, owner.address);
CHECK_TEST_CONDITION_MSG(miner_key.owner == owner.address,
miner_key.owner.to_string(cryptonote::FAKECHAIN)
<< " == " << owner.address.to_string(cryptonote::FAKECHAIN));
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);
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_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::lokinet_1year, name, miner_key.lokinet_value, height_of_lns_entry, height_of_lns_entry, tx_hash, crypto::null_hash /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
CHECK_EQ(record.owner_id, owner.id);
return true;
});
@ -2065,13 +2089,13 @@ bool loki_name_system_update_mapping::generate(std::vector<test_event_entry> &ev
loki_register_callback(events, "check_registered", [=](cryptonote::core &c, size_t ev_index)
{
DEFINE_TESTS_ERROR_CONTEXT("check_registered");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
std::string 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)}, name_hash);
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.owner, {} /*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, register_height, session_tx_hash1, {} /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
return true;
});
@ -2088,16 +2112,16 @@ bool loki_name_system_update_mapping::generate(std::vector<test_event_entry> &ev
gen.create_and_add_next_block({tx1});
}
loki_register_callback(events, "check_updated", [=](cryptonote::core &c, size_t ev_index)
loki_register_callback(events, "check_updated", [=, blockchain_height = gen.height()](cryptonote::core &c, size_t ev_index)
{
DEFINE_TESTS_ERROR_CONTEXT("check_updated");
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
std::string 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)}, name_hash);
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.owner, {} /*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, blockchain_height, session_tx_hash2, session_tx_hash1 /*prev_txid*/, miner_key.owner, {} /*backup_owner*/));
return true;
});
@ -2138,9 +2162,9 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
loki_register_callback(events, "check_update0", [=](cryptonote::core &c, size_t ev_index)
{
const char* perr_context = "check_update0";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::mapping_record const record = lns_db.get_mapping(lns::mapping_type::session, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, miner_key.session_value, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, miner_key.session_value, height, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
return true;
});
@ -2156,12 +2180,12 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
prev_txid = txid;
txid = cryptonote::get_transaction_hash(tx2);
loki_register_callback(events, "check_update1", [=](cryptonote::core &c, size_t ev_index)
loki_register_callback(events, "check_update1", [=, blockchain_height = gen.height()](cryptonote::core &c, size_t ev_index)
{
const char* perr_context = "check_update1";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::mapping_record const record = lns_db.get_mapping(lns::mapping_type::session, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, blockchain_height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
return true;
});
}
@ -2178,12 +2202,12 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
prev_txid = txid;
txid = cryptonote::get_transaction_hash(tx2);
loki_register_callback(events, "check_update2", [=](cryptonote::core &c, size_t ev_index)
loki_register_callback(events, "check_update2", [=, blockchain_height = gen.height()](cryptonote::core &c, size_t ev_index)
{
const char* perr_context = "check_update2";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::mapping_record const record = lns_db.get_mapping(lns::mapping_type::session, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, blockchain_height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
return true;
});
}
@ -2216,12 +2240,12 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
prev_txid = txid;
txid = cryptonote::get_transaction_hash(tx2);
loki_register_callback(events, "check_update3", [=](cryptonote::core &c, size_t ev_index)
loki_register_callback(events, "check_update3", [=, blockchain_height = gen.height()](cryptonote::core &c, size_t ev_index)
{
const char* perr_context = "check_update3";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::mapping_record const record = lns_db.get_mapping(lns::mapping_type::session, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, blockchain_height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
return true;
});
}
@ -2238,12 +2262,12 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
prev_txid = txid;
txid = cryptonote::get_transaction_hash(tx2);
loki_register_callback(events, "check_update3", [=](cryptonote::core &c, size_t ev_index)
loki_register_callback(events, "check_update3", [=, blockchain_height = gen.height()](cryptonote::core &c, size_t ev_index)
{
const char* perr_context = "check_update3";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::mapping_record const record = lns_db.get_mapping(lns::mapping_type::session, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, blockchain_height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
return true;
});
}
@ -2280,12 +2304,12 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
prev_txid = txid;
txid = cryptonote::get_transaction_hash(tx2);
loki_register_callback(events, "check_update4", [=](cryptonote::core &c, size_t ev_index)
loki_register_callback(events, "check_update4", [=, blockchain_height = gen.height()](cryptonote::core &c, size_t ev_index)
{
const char* perr_context = "check_update4";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::mapping_record const record = lns_db.get_mapping(lns::mapping_type::session, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, blockchain_height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
return true;
});
}
@ -2302,12 +2326,12 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
prev_txid = txid;
txid = cryptonote::get_transaction_hash(tx2);
loki_register_callback(events, "check_update5", [=](cryptonote::core &c, size_t ev_index)
loki_register_callback(events, "check_update5", [=, blockchain_height = gen.height()](cryptonote::core &c, size_t ev_index)
{
const char* perr_context = "check_update5";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::mapping_record const record = lns_db.get_mapping(lns::mapping_type::session, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, blockchain_height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
return true;
});
}
@ -2344,12 +2368,12 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
prev_txid = txid;
txid = cryptonote::get_transaction_hash(tx2);
loki_register_callback(events, "check_update6", [=](cryptonote::core &c, size_t ev_index)
loki_register_callback(events, "check_update6", [=, blockchain_height = gen.height()](cryptonote::core &c, size_t ev_index)
{
const char* perr_context = "check_update6";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::mapping_record const record = lns_db.get_mapping(lns::mapping_type::session, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, blockchain_height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
return true;
});
}
@ -2367,12 +2391,12 @@ bool loki_name_system_update_mapping_multiple_owners::generate(std::vector<test_
prev_txid = txid;
txid = cryptonote::get_transaction_hash(tx2);
loki_register_callback(events, "check_update7", [=](cryptonote::core &c, size_t ev_index)
loki_register_callback(events, "check_update7", [=, blockchain_height = gen.height()](cryptonote::core &c, size_t ev_index)
{
const char* perr_context = "check_update7";
lns::name_system_db const &lns_db = c.get_blockchain_storage().name_system_db();
lns::name_system_db &lns_db = c.get_blockchain_storage().name_system_db();
lns::mapping_record const record = lns_db.get_mapping(lns::mapping_type::session, name_hash);
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
CHECK_TEST_CONDITION(verify_lns_mapping_record(perr_context, record, lns::mapping_type::session, name, temp_keys.session_value, height, blockchain_height, txid, prev_txid, owner1, owner2 /*backup_owner*/));
return true;
});
}