mirror of
https://github.com/vtnerd/monero-lws.git
synced 2025-05-07 03:32:13 +00:00
WIP subaddress testing
This commit is contained in:
parent
d81e3ff833
commit
a982098427
2 changed files with 263 additions and 64 deletions
|
@ -416,15 +416,22 @@ namespace lws
|
||||||
|
|
||||||
bool found_pub = false;
|
bool found_pub = false;
|
||||||
db::address_index account_index{db::major_index::primary, db::minor_index::primary};
|
db::address_index account_index{db::major_index::primary, db::minor_index::primary};
|
||||||
crypto::key_derivation active_derived;
|
crypto::key_derivation active_derived{};
|
||||||
|
crypto::public_key active_pub{};
|
||||||
|
|
||||||
// inspect the additional and traditional keys
|
// inspect the additional and traditional keys
|
||||||
for (std::size_t attempt = 0; attempt < 2; ++attempt)
|
for (std::size_t attempt = 0; attempt < 2; ++attempt)
|
||||||
{
|
{
|
||||||
if (attempt == 0)
|
if (attempt == 0)
|
||||||
|
{
|
||||||
active_derived = derived;
|
active_derived = derived;
|
||||||
|
active_pub = key.pub_key;
|
||||||
|
}
|
||||||
else if (!additional_derivations.empty())
|
else if (!additional_derivations.empty())
|
||||||
|
{
|
||||||
active_derived = additional_derivations.at(index);
|
active_derived = additional_derivations.at(index);
|
||||||
|
active_pub = additional_tx_pub_keys.data.at(index);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break; // inspection loop
|
break; // inspection loop
|
||||||
|
|
||||||
|
@ -491,7 +498,6 @@ namespace lws
|
||||||
lws::decrypt_payment_id(payment_id.second.short_, active_derived);
|
lws::decrypt_payment_id(payment_id.second.short_, active_derived);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool added = output_action(
|
const bool added = output_action(
|
||||||
user,
|
user,
|
||||||
db::output{
|
db::output{
|
||||||
|
@ -501,7 +507,7 @@ namespace lws
|
||||||
amount,
|
amount,
|
||||||
mixin,
|
mixin,
|
||||||
boost::numeric_cast<std::uint32_t>(index),
|
boost::numeric_cast<std::uint32_t>(index),
|
||||||
key.pub_key
|
active_pub
|
||||||
},
|
},
|
||||||
timestamp,
|
timestamp,
|
||||||
tx.unlock_time,
|
tx.unlock_time,
|
||||||
|
|
|
@ -36,10 +36,11 @@
|
||||||
#include "cryptonote_core/cryptonote_tx_utils.h" // monero/src
|
#include "cryptonote_core/cryptonote_tx_utils.h" // monero/src
|
||||||
#include "db/chain.test.h"
|
#include "db/chain.test.h"
|
||||||
#include "db/storage.test.h"
|
#include "db/storage.test.h"
|
||||||
#include "hardforks/hardforks.h" // monero/src
|
#include "device/device_default.hpp" // monero/src
|
||||||
#include "net/zmq.h" // monero/src
|
#include "hardforks/hardforks.h" // monero/src
|
||||||
|
#include "net/zmq.h" // monero/src
|
||||||
#include "rpc/client.h"
|
#include "rpc/client.h"
|
||||||
#include "rpc/daemon_messages.h" // monero/src
|
#include "rpc/daemon_messages.h" // monero/src
|
||||||
#include "scanner.h"
|
#include "scanner.h"
|
||||||
#include "wire/error.h"
|
#include "wire/error.h"
|
||||||
#include "wire/json/write.h"
|
#include "wire/json/write.h"
|
||||||
|
@ -143,23 +144,28 @@ namespace
|
||||||
|
|
||||||
struct transaction
|
struct transaction
|
||||||
{
|
{
|
||||||
cryptonote::transaction tx;
|
std::unique_ptr<cryptonote::transaction> tx;
|
||||||
std::vector<crypto::secret_key> additional_keys;
|
std::vector<crypto::secret_key> additional_keys;
|
||||||
crypto::secret_key key;
|
std::vector<crypto::public_key> pub_keys;
|
||||||
crypto::public_key pub_key;
|
std::vector<crypto::public_key> spend_publics;
|
||||||
crypto::public_key spend_public;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
transaction make_miner_tx(lest::env& lest_env, lws::db::block_id height, const lws::db::account_address& miner_address, bool use_view_tags)
|
transaction make_miner_tx(lest::env& lest_env, lws::db::block_id height, const lws::db::account_address& miner_address, bool use_view_tags)
|
||||||
{
|
{
|
||||||
static constexpr std::uint64_t fee = 0;
|
static constexpr std::uint64_t fee = 0;
|
||||||
|
|
||||||
transaction tx{};
|
transaction tx{};
|
||||||
crypto::generate_keys(tx.pub_key, tx.key);
|
tx.tx.reset(new cryptonote::transaction);
|
||||||
EXPECT(add_tx_pub_key_to_extra(tx.tx, tx.pub_key));
|
tx.pub_keys.emplace_back();
|
||||||
|
tx.spend_publics.emplace_back();
|
||||||
|
|
||||||
|
crypto::secret_key key;
|
||||||
|
crypto::generate_keys(tx.pub_keys.back(), key);
|
||||||
|
EXPECT(add_tx_pub_key_to_extra(*tx.tx, tx.pub_keys.back()));
|
||||||
|
|
||||||
cryptonote::txin_gen in;
|
cryptonote::txin_gen in;
|
||||||
in.height = std::uint64_t(height);
|
in.height = std::uint64_t(height);
|
||||||
tx.tx.vin.push_back(in);
|
tx.tx->vin.push_back(in);
|
||||||
|
|
||||||
// This will work, until size of constructed block is less then CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE
|
// This will work, until size of constructed block is less then CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE
|
||||||
uint64_t block_reward;
|
uint64_t block_reward;
|
||||||
|
@ -167,24 +173,39 @@ namespace
|
||||||
block_reward += fee;
|
block_reward += fee;
|
||||||
|
|
||||||
crypto::key_derivation derivation;
|
crypto::key_derivation derivation;
|
||||||
EXPECT(crypto::generate_key_derivation(miner_address.view_public, tx.key, derivation));
|
EXPECT(crypto::generate_key_derivation(miner_address.view_public, key, derivation));
|
||||||
EXPECT(crypto::derive_public_key(derivation, 0, miner_address.spend_public, tx.spend_public));
|
EXPECT(crypto::derive_public_key(derivation, 0, miner_address.spend_public, tx.spend_publics.back()));
|
||||||
|
|
||||||
crypto::view_tag view_tag;
|
crypto::view_tag view_tag;
|
||||||
if (use_view_tags)
|
if (use_view_tags)
|
||||||
crypto::derive_view_tag(derivation, 0, view_tag);
|
crypto::derive_view_tag(derivation, 0, view_tag);
|
||||||
|
|
||||||
cryptonote::tx_out out;
|
cryptonote::tx_out out;
|
||||||
cryptonote::set_tx_out(block_reward, tx.spend_public, use_view_tags, view_tag, out);
|
cryptonote::set_tx_out(block_reward, tx.spend_publics.back(), use_view_tags, view_tag, out);
|
||||||
|
|
||||||
tx.tx.vout.push_back(out);
|
tx.tx->vout.push_back(out);
|
||||||
tx.tx.version = 2;
|
tx.tx->version = 2;
|
||||||
tx.tx.unlock_time = std::uint64_t(height) + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
tx.tx->unlock_time = std::uint64_t(height) + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW;
|
||||||
|
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction make_tx(lest::env& lest_env, const cryptonote::account_keys& keys, const std::uint32_t ring_base, const bool use_view_tag)
|
struct get_spend_public
|
||||||
|
{
|
||||||
|
std::vector<crypto::public_key>& pub_keys;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void operator()(const T&) const noexcept
|
||||||
|
{}
|
||||||
|
|
||||||
|
void operator()(const cryptonote::txout_to_key& val) const
|
||||||
|
{ pub_keys.push_back(val.key); }
|
||||||
|
|
||||||
|
void operator()(const cryptonote::txout_to_tagged_key& val) const
|
||||||
|
{ pub_keys.push_back(val.key); }
|
||||||
|
};
|
||||||
|
|
||||||
|
transaction make_tx(lest::env& lest_env, const cryptonote::account_keys& keys, std::vector<cryptonote::tx_destination_entry>& destinations, const std::uint32_t ring_base, const bool use_view_tag)
|
||||||
{
|
{
|
||||||
static constexpr std::uint64_t input_amount = 20000;
|
static constexpr std::uint64_t input_amount = 20000;
|
||||||
static constexpr std::uint64_t output_amount = 8000;
|
static constexpr std::uint64_t output_amount = 8000;
|
||||||
|
@ -201,8 +222,13 @@ namespace
|
||||||
EXPECT(crypto::generate_key_derivation(keys.m_account_address.m_view_public_key, og_tx_key, derivation));
|
EXPECT(crypto::generate_key_derivation(keys.m_account_address.m_view_public_key, og_tx_key, derivation));
|
||||||
EXPECT(crypto::derive_public_key(derivation, 0, keys.m_account_address.m_spend_public_key, spend_public));
|
EXPECT(crypto::derive_public_key(derivation, 0, keys.m_account_address.m_spend_public_key, spend_public));
|
||||||
|
|
||||||
|
std::uint32_t index = -1;
|
||||||
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
std::unordered_map<crypto::public_key, cryptonote::subaddress_index> subaddresses;
|
||||||
subaddresses[keys.m_account_address.m_spend_public_key] = {0, 0};
|
for (const auto& destination : destinations)
|
||||||
|
{
|
||||||
|
++index;
|
||||||
|
subaddresses[destination.addr.m_spend_public_key] = {0, index};
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<cryptonote::tx_source_entry> sources;
|
std::vector<cryptonote::tx_source_entry> sources;
|
||||||
sources.emplace_back();
|
sources.emplace_back();
|
||||||
|
@ -220,23 +246,38 @@ namespace
|
||||||
sources.back().outputs.emplace_back();
|
sources.back().outputs.emplace_back();
|
||||||
sources.back().outputs.back().first = 15 + ring_base;
|
sources.back().outputs.back().first = 15 + ring_base;
|
||||||
sources.back().outputs.back().second.dest = rct::pk2rct(spend_public);
|
sources.back().outputs.back().second.dest = rct::pk2rct(spend_public);
|
||||||
|
|
||||||
std::vector<cryptonote::tx_destination_entry> destinations;
|
|
||||||
destinations.emplace_back();
|
|
||||||
destinations.back().amount = output_amount;
|
|
||||||
destinations.back().addr = keys.m_account_address;
|
|
||||||
|
|
||||||
transaction out{};
|
transaction out{};
|
||||||
|
out.tx.reset(new cryptonote::transaction);
|
||||||
EXPECT(
|
EXPECT(
|
||||||
cryptonote::construct_tx_and_get_tx_key(
|
cryptonote::construct_tx_and_get_tx_key(
|
||||||
keys, subaddresses, sources, destinations, keys.m_account_address, {}, out.tx, 0, out.key,
|
keys, subaddresses, sources, destinations, keys.m_account_address, {}, *out.tx, 0, unused_key,
|
||||||
out.additional_keys, true, {rct::RangeProofType::RangeProofBulletproof, 2}, use_view_tag
|
out.additional_keys, true, {rct::RangeProofType::RangeProofBulletproof, 2}, use_view_tag
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
crypto::secret_key_to_public_key(out.key, out.pub_key);
|
for (const auto& vout : out.tx->vout)
|
||||||
crypto::generate_key_derivation(keys.m_account_address.m_view_public_key, out.key, derivation);
|
boost::apply_visitor(get_spend_public{out.spend_publics}, vout.target);
|
||||||
crypto::derive_public_key(derivation, 0, keys.m_account_address.m_spend_public_key, out.spend_public);
|
|
||||||
|
if (out.additional_keys.empty())
|
||||||
|
{
|
||||||
|
std::vector<cryptonote::tx_extra_field> extra;
|
||||||
|
EXPECT(cryptonote::parse_tx_extra(out.tx->extra, extra));
|
||||||
|
|
||||||
|
cryptonote::tx_extra_pub_key key;
|
||||||
|
EXPECT(cryptonote::find_tx_extra_field_by_type(extra, key));
|
||||||
|
|
||||||
|
out.pub_keys.emplace_back();
|
||||||
|
out.pub_keys.back() = key.pub_key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto& this_key : out.additional_keys)
|
||||||
|
{
|
||||||
|
out.pub_keys.emplace_back();
|
||||||
|
EXPECT(crypto::secret_key_to_public_key(this_key, out.pub_keys.back()));
|
||||||
|
}
|
||||||
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,6 +293,23 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||||
keys.m_account_address.m_spend_public_key
|
keys.m_account_address.m_spend_public_key
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cryptonote::account_keys keys_subaddr1{};
|
||||||
|
cryptonote::account_keys keys_subaddr2{};
|
||||||
|
{
|
||||||
|
hw::core::device_default hw{};
|
||||||
|
keys_subaddr1.m_account_address = hw.get_subaddress(keys, cryptonote::subaddress_index{0, 1});
|
||||||
|
keys_subaddr2.m_account_address = hw.get_subaddress(keys, cryptonote::subaddress_index{0, 2});
|
||||||
|
|
||||||
|
const auto sub1_secret = hw.get_subaddress_secret_key(keys.m_view_secret_key, cryptonote::subaddress_index{0, 1});
|
||||||
|
const auto sub2_secret = hw.get_subaddress_secret_key(keys.m_view_secret_key, cryptonote::subaddress_index{0, 1});
|
||||||
|
|
||||||
|
sc_add(to_bytes(keys_subaddr1.m_spend_secret_key), to_bytes(sub1_secret), to_bytes(keys.m_spend_secret_key));
|
||||||
|
sc_add(to_bytes(keys_subaddr1.m_view_secret_key), to_bytes(keys_subaddr1.m_spend_secret_key), to_bytes(keys.m_view_secret_key));
|
||||||
|
|
||||||
|
sc_add(to_bytes(keys_subaddr2.m_spend_secret_key), to_bytes(sub2_secret), to_bytes(keys.m_spend_secret_key));
|
||||||
|
sc_add(to_bytes(keys_subaddr2.m_view_secret_key), to_bytes(keys_subaddr2.m_spend_secret_key), to_bytes(keys.m_view_secret_key));
|
||||||
|
}
|
||||||
|
|
||||||
cryptonote::account_keys keys2{};
|
cryptonote::account_keys keys2{};
|
||||||
crypto::generate_keys(keys2.m_account_address.m_spend_public_key, keys2.m_spend_secret_key);
|
crypto::generate_keys(keys2.m_account_address.m_spend_public_key, keys2.m_spend_secret_key);
|
||||||
crypto::generate_keys(keys2.m_account_address.m_view_public_key, keys2.m_view_secret_key);
|
crypto::generate_keys(keys2.m_account_address.m_view_public_key, keys2.m_view_secret_key);
|
||||||
|
@ -351,20 +409,73 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||||
|
|
||||||
SECTION("lws::scanner::run")
|
SECTION("lws::scanner::run")
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
const std::vector<lws::db::subaddress_dict> indexes{
|
||||||
|
lws::db::subaddress_dict{
|
||||||
|
lws::db::major_index::primary,
|
||||||
|
lws::db::index_ranges{
|
||||||
|
lws::db::index_range{lws::db::minor_index(1), lws::db::minor_index(2)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const auto result =
|
||||||
|
db.upsert_subaddresses(lws::db::account_id(1), account, keys.m_view_secret_key, indexes, 2);
|
||||||
|
EXPECT(result);
|
||||||
|
EXPECT(result->size() == 1);
|
||||||
|
EXPECT(result->at(0).first == lws::db::major_index::primary);
|
||||||
|
EXPECT(result->at(0).second.size() == 1);
|
||||||
|
EXPECT(result->at(0).second.at(0).size() == 2);
|
||||||
|
EXPECT(result->at(0).second.at(0).at(0) == lws::db::minor_index(1));
|
||||||
|
EXPECT(result->at(0).second.at(0).at(1) == lws::db::minor_index(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cryptonote::tx_destination_entry> destinations;
|
||||||
|
destinations.emplace_back();
|
||||||
|
destinations.back().amount = 8000;
|
||||||
|
destinations.back().addr = keys.m_account_address;
|
||||||
|
|
||||||
std::vector<epee::byte_slice> messages{};
|
std::vector<epee::byte_slice> messages{};
|
||||||
transaction tx = make_miner_tx(lest_env, last_block.id, account, false);
|
transaction tx = make_miner_tx(lest_env, last_block.id, account, false);
|
||||||
transaction tx2 = make_tx(lest_env, keys, 20, true);
|
EXPECT(tx.pub_keys.size() == 1);
|
||||||
transaction tx3 = make_tx(lest_env, keys, 86, true);
|
EXPECT(tx.spend_publics.size() == 1);
|
||||||
|
|
||||||
|
transaction tx2 = make_tx(lest_env, keys, destinations, 20, true);
|
||||||
|
EXPECT(tx2.pub_keys.size() == 1);
|
||||||
|
EXPECT(tx2.spend_publics.size() == 1);
|
||||||
|
|
||||||
|
transaction tx3 = make_tx(lest_env, keys, destinations, 86, false);
|
||||||
|
EXPECT(tx3.pub_keys.size() == 1);
|
||||||
|
EXPECT(tx3.spend_publics.size() == 1);
|
||||||
|
|
||||||
|
destinations.emplace_back();
|
||||||
|
destinations.back().amount = 2000;
|
||||||
|
destinations.back().addr = keys_subaddr1.m_account_address;
|
||||||
|
destinations.back().is_subaddress = true;
|
||||||
|
|
||||||
|
transaction tx4 = make_tx(lest_env, keys, destinations, 50, false);
|
||||||
|
EXPECT(tx4.pub_keys.size() == 1);
|
||||||
|
EXPECT(tx4.spend_publics.size() == 2);
|
||||||
|
|
||||||
|
//destinations.emplace_back();
|
||||||
|
//destinations.back().amount = 1000;
|
||||||
|
//destinations.back().addr = keys_subaddr2.m_account_address;
|
||||||
|
//destinations.back().is_subaddress = true;
|
||||||
|
|
||||||
|
transaction tx5 = make_tx(lest_env, keys, destinations, 200, true);
|
||||||
|
//EXPECT(tx5.pub_keys.size() == 3);
|
||||||
|
//EXPECT(tx5.spend_publics.size() == 3);
|
||||||
|
|
||||||
cryptonote::rpc::GetBlocksFast::Response bmessage{};
|
cryptonote::rpc::GetBlocksFast::Response bmessage{};
|
||||||
bmessage.start_height = std::uint64_t(last_block.id) + 1;
|
bmessage.start_height = std::uint64_t(last_block.id) + 1;
|
||||||
bmessage.current_height = bmessage.start_height + 1;
|
bmessage.current_height = bmessage.start_height + 1;
|
||||||
bmessage.blocks.emplace_back();
|
bmessage.blocks.emplace_back();
|
||||||
bmessage.blocks.back().block.miner_tx = tx.tx;
|
bmessage.blocks.back().block.miner_tx = *tx.tx;
|
||||||
bmessage.blocks.back().block.tx_hashes.push_back(cryptonote::get_transaction_hash(tx2.tx));
|
bmessage.blocks.back().block.tx_hashes.push_back(cryptonote::get_transaction_hash(*tx2.tx));
|
||||||
bmessage.blocks.back().block.tx_hashes.push_back(cryptonote::get_transaction_hash(tx3.tx));
|
bmessage.blocks.back().block.tx_hashes.push_back(cryptonote::get_transaction_hash(*tx3.tx));
|
||||||
bmessage.blocks.back().transactions.push_back(tx2.tx);
|
bmessage.blocks.back().block.tx_hashes.push_back(cryptonote::get_transaction_hash(*tx4.tx));
|
||||||
bmessage.blocks.back().transactions.push_back(tx3.tx);
|
bmessage.blocks.back().transactions.push_back(*tx2.tx);
|
||||||
|
bmessage.blocks.back().transactions.push_back(*tx3.tx);
|
||||||
|
bmessage.blocks.back().transactions.push_back(*tx4.tx);
|
||||||
bmessage.output_indices.emplace_back();
|
bmessage.output_indices.emplace_back();
|
||||||
bmessage.output_indices.back().emplace_back();
|
bmessage.output_indices.back().emplace_back();
|
||||||
bmessage.output_indices.back().back().push_back(100);
|
bmessage.output_indices.back().back().push_back(100);
|
||||||
|
@ -372,6 +483,9 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||||
bmessage.output_indices.back().back().push_back(101);
|
bmessage.output_indices.back().back().push_back(101);
|
||||||
bmessage.output_indices.back().emplace_back();
|
bmessage.output_indices.back().emplace_back();
|
||||||
bmessage.output_indices.back().back().push_back(102);
|
bmessage.output_indices.back().back().push_back(102);
|
||||||
|
bmessage.output_indices.back().emplace_back();
|
||||||
|
bmessage.output_indices.back().back().push_back(200);
|
||||||
|
bmessage.output_indices.back().back().push_back(201);
|
||||||
bmessage.blocks.push_back(bmessage.blocks.back());
|
bmessage.blocks.push_back(bmessage.blocks.back());
|
||||||
bmessage.output_indices.push_back(bmessage.output_indices.back());
|
bmessage.output_indices.push_back(bmessage.output_indices.back());
|
||||||
|
|
||||||
|
@ -414,7 +528,7 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||||
{
|
{
|
||||||
boost::thread server_thread(&rpc_thread, rpc.zmq_context(), std::cref(messages));
|
boost::thread server_thread(&rpc_thread, rpc.zmq_context(), std::cref(messages));
|
||||||
const join on_scope_exit{server_thread};
|
const join on_scope_exit{server_thread};
|
||||||
lws::scanner::run(db.clone(), std::move(rpc), 1, epee::net_utils::ssl_verification_t::none);
|
lws::scanner::run(db.clone(), std::move(rpc), 1, epee::net_utils::ssl_verification_t::none, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hashes.push_back(cryptonote::get_block_hash(bmessage.blocks.back().block));
|
hashes.push_back(cryptonote::get_block_hash(bmessage.blocks.back().block));
|
||||||
|
@ -423,68 +537,144 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||||
const lws::db::block_id new_last_block_id = lws::db::block_id(std::uint64_t(last_block.id) + 2);
|
const lws::db::block_id new_last_block_id = lws::db::block_id(std::uint64_t(last_block.id) + 2);
|
||||||
EXPECT(get_account().scan_height == new_last_block_id);
|
EXPECT(get_account().scan_height == new_last_block_id);
|
||||||
{
|
{
|
||||||
const std::unordered_map<crypto::hash, lws::db::output> expected{
|
const std::map<std::pair<lws::db::output_id, std::uint32_t>, lws::db::output> expected{
|
||||||
{
|
{
|
||||||
cryptonote::get_transaction_hash(tx.tx), lws::db::output{
|
{lws::db::output_id{0, 100}, 35184372088830}, lws::db::output{
|
||||||
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(tx.tx)},
|
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(*tx.tx)},
|
||||||
lws::db::output::spend_meta_{
|
lws::db::output::spend_meta_{
|
||||||
lws::db::output_id{0, 100}, 35184372088830, 0, 0, tx.pub_key
|
lws::db::output_id{0, 100}, 35184372088830, 0, 0, tx.pub_keys.at(0)
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
cryptonote::get_transaction_prefix_hash(tx.tx),
|
cryptonote::get_transaction_prefix_hash(*tx.tx),
|
||||||
tx.spend_public,
|
tx.spend_publics.at(0),
|
||||||
rct::commit(35184372088830, rct::identity()),
|
rct::commit(35184372088830, rct::identity()),
|
||||||
{},
|
{},
|
||||||
lws::db::pack(lws::db::extra::coinbase_output, 0),
|
lws::db::pack(lws::db::extra::coinbase_output, 0),
|
||||||
{},
|
{},
|
||||||
0 // fee
|
0, // fee
|
||||||
|
lws::db::address_index{}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cryptonote::get_transaction_hash(tx2.tx), lws::db::output{
|
{lws::db::output_id{0, 101}, 8000}, lws::db::output{
|
||||||
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(tx2.tx)},
|
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(*tx2.tx)},
|
||||||
lws::db::output::spend_meta_{
|
lws::db::output::spend_meta_{
|
||||||
lws::db::output_id{0, 101}, 8000, 15, 0, tx2.pub_key
|
lws::db::output_id{0, 101}, 8000, 15, 0, tx2.pub_keys.at(0)
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
cryptonote::get_transaction_prefix_hash(tx2.tx),
|
cryptonote::get_transaction_prefix_hash(*tx2.tx),
|
||||||
tx2.spend_public,
|
tx2.spend_publics.at(0),
|
||||||
tx2.tx.rct_signatures.outPk.at(0).mask,
|
tx2.tx->rct_signatures.outPk.at(0).mask,
|
||||||
{},
|
{},
|
||||||
lws::db::pack(lws::db::extra::ringct_output, 8),
|
lws::db::pack(lws::db::extra::ringct_output, 8),
|
||||||
{},
|
{},
|
||||||
12000 // fee
|
12000, // fee
|
||||||
|
lws::db::address_index{}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
cryptonote::get_transaction_hash(tx3.tx), lws::db::output{
|
{lws::db::output_id{0, 102}, 8000}, lws::db::output{
|
||||||
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(tx3.tx)},
|
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(*tx3.tx)},
|
||||||
lws::db::output::spend_meta_{
|
lws::db::output::spend_meta_{
|
||||||
lws::db::output_id{0, 102}, 8000, 15, 0, tx3.pub_key
|
lws::db::output_id{0, 102}, 8000, 15, 0, tx3.pub_keys.at(0)
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
cryptonote::get_transaction_prefix_hash(tx3.tx),
|
cryptonote::get_transaction_prefix_hash(*tx3.tx),
|
||||||
tx3.spend_public,
|
tx3.spend_publics.at(0),
|
||||||
tx3.tx.rct_signatures.outPk.at(0).mask,
|
tx3.tx->rct_signatures.outPk.at(0).mask,
|
||||||
{},
|
{},
|
||||||
lws::db::pack(lws::db::extra::ringct_output, 8),
|
lws::db::pack(lws::db::extra::ringct_output, 8),
|
||||||
{},
|
{},
|
||||||
12000 // fee
|
12000, // fee
|
||||||
|
lws::db::address_index{}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{lws::db::output_id{0, 200}, 8000}, lws::db::output{
|
||||||
|
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(*tx4.tx)},
|
||||||
|
lws::db::output::spend_meta_{
|
||||||
|
lws::db::output_id{0, 200}, 8000, 15, 0, tx4.pub_keys.at(0)
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
cryptonote::get_transaction_prefix_hash(*tx4.tx),
|
||||||
|
tx4.spend_publics.at(0),
|
||||||
|
tx4.tx->rct_signatures.outPk.at(0).mask,
|
||||||
|
{},
|
||||||
|
lws::db::pack(lws::db::extra::ringct_output, 8),
|
||||||
|
{},
|
||||||
|
10000, // fee
|
||||||
|
lws::db::address_index{}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{lws::db::output_id{0, 201}, 8000}, lws::db::output{
|
||||||
|
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(*tx4.tx)},
|
||||||
|
lws::db::output::spend_meta_{
|
||||||
|
lws::db::output_id{0, 201}, 8000, 15, 1, tx4.pub_keys.at(0)
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
cryptonote::get_transaction_prefix_hash(*tx4.tx),
|
||||||
|
tx4.spend_publics.at(1),
|
||||||
|
tx4.tx->rct_signatures.outPk.at(1).mask,
|
||||||
|
{},
|
||||||
|
lws::db::pack(lws::db::extra::ringct_output, 8),
|
||||||
|
{},
|
||||||
|
10000, // fee
|
||||||
|
lws::db::address_index{}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{lws::db::output_id{0, 200}, 2000}, lws::db::output{
|
||||||
|
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(*tx4.tx)},
|
||||||
|
lws::db::output::spend_meta_{
|
||||||
|
lws::db::output_id{0, 200}, 2000, 15, 0, tx4.pub_keys.at(0)
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
cryptonote::get_transaction_prefix_hash(*tx4.tx),
|
||||||
|
tx4.spend_publics.at(0),
|
||||||
|
tx4.tx->rct_signatures.outPk.at(0).mask,
|
||||||
|
{},
|
||||||
|
lws::db::pack(lws::db::extra::ringct_output, 8),
|
||||||
|
{},
|
||||||
|
10000, // fee
|
||||||
|
lws::db::address_index{lws::db::major_index::primary, lws::db::minor_index(1)}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{lws::db::output_id{0, 201}, 2000}, lws::db::output{
|
||||||
|
lws::db::transaction_link{new_last_block_id, cryptonote::get_transaction_hash(*tx4.tx)},
|
||||||
|
lws::db::output::spend_meta_{
|
||||||
|
lws::db::output_id{0, 201}, 2000, 15, 1, tx4.pub_keys.at(0)
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
cryptonote::get_transaction_prefix_hash(*tx4.tx),
|
||||||
|
tx4.spend_publics.at(1),
|
||||||
|
tx4.tx->rct_signatures.outPk.at(1).mask,
|
||||||
|
{},
|
||||||
|
lws::db::pack(lws::db::extra::ringct_output, 8),
|
||||||
|
{},
|
||||||
|
10000, // fee
|
||||||
|
lws::db::address_index{lws::db::major_index::primary, lws::db::minor_index(1)}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto reader = MONERO_UNWRAP(db.start_read());
|
auto reader = MONERO_UNWRAP(db.start_read());
|
||||||
auto outputs = MONERO_UNWRAP(reader.get_outputs(lws::db::account_id(1)));
|
auto outputs = MONERO_UNWRAP(reader.get_outputs(lws::db::account_id(1)));
|
||||||
EXPECT(outputs.count() == 3);
|
EXPECT(outputs.count() == 5);
|
||||||
auto output_it = outputs.make_iterator();
|
auto output_it = outputs.make_iterator();
|
||||||
for (auto output_it = outputs.make_iterator(); !output_it.is_end(); ++output_it)
|
for (auto output_it = outputs.make_iterator(); !output_it.is_end(); ++output_it)
|
||||||
{
|
{
|
||||||
auto real_output = *output_it;
|
auto real_output = *output_it;
|
||||||
const auto expected_output = expected.find(real_output.link.tx_hash);
|
const auto expected_output =
|
||||||
|
expected.find(std::make_pair(real_output.spend_meta.id, real_output.spend_meta.amount));
|
||||||
EXPECT(expected_output != expected.end());
|
EXPECT(expected_output != expected.end());
|
||||||
|
|
||||||
EXPECT(real_output.link.height == expected_output->second.link.height);
|
EXPECT(real_output.link.height == expected_output->second.link.height);
|
||||||
|
@ -501,6 +691,7 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||||
if (unpack(expected_output->second.extra).second == 8)
|
if (unpack(expected_output->second.extra).second == 8)
|
||||||
EXPECT(real_output.payment_id.short_ == expected_output->second.payment_id.short_);
|
EXPECT(real_output.payment_id.short_ == expected_output->second.payment_id.short_);
|
||||||
EXPECT(real_output.fee == expected_output->second.fee);
|
EXPECT(real_output.fee == expected_output->second.fee);
|
||||||
|
EXPECT(real_output.recipient == expected_output->second.recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto spends = MONERO_UNWRAP(reader.get_spends(lws::db::account_id(1)));
|
auto spends = MONERO_UNWRAP(reader.get_spends(lws::db::account_id(1)));
|
||||||
|
@ -510,24 +701,26 @@ LWS_CASE("lws::scanner::sync and lws::scanner::run")
|
||||||
|
|
||||||
auto real_spend = *spend_it;
|
auto real_spend = *spend_it;
|
||||||
EXPECT(real_spend.link.height == new_last_block_id);
|
EXPECT(real_spend.link.height == new_last_block_id);
|
||||||
EXPECT(real_spend.link.tx_hash == cryptonote::get_transaction_hash(tx3.tx));
|
EXPECT(real_spend.link.tx_hash == cryptonote::get_transaction_hash(*tx3.tx));
|
||||||
lws::db::output_id expected_out{0, 100};
|
lws::db::output_id expected_out{0, 100};
|
||||||
EXPECT(real_spend.source == expected_out);
|
EXPECT(real_spend.source == expected_out);
|
||||||
EXPECT(real_spend.mixin_count == 15);
|
EXPECT(real_spend.mixin_count == 15);
|
||||||
EXPECT(real_spend.length == 0);
|
EXPECT(real_spend.length == 0);
|
||||||
EXPECT(real_spend.payment_id == crypto::hash{});
|
EXPECT(real_spend.payment_id == crypto::hash{});
|
||||||
|
EXPECT(real_spend.sender == lws::db::address_index{});
|
||||||
|
|
||||||
++spend_it;
|
++spend_it;
|
||||||
EXPECT(!spend_it.is_end());
|
EXPECT(!spend_it.is_end());
|
||||||
|
|
||||||
real_spend = *spend_it;
|
real_spend = *spend_it;
|
||||||
EXPECT(real_spend.link.height == new_last_block_id);
|
EXPECT(real_spend.link.height == new_last_block_id);
|
||||||
EXPECT(real_spend.link.tx_hash == cryptonote::get_transaction_hash(tx3.tx));
|
EXPECT(real_spend.link.tx_hash == cryptonote::get_transaction_hash(*tx3.tx));
|
||||||
expected_out = lws::db::output_id{0, 101};
|
expected_out = lws::db::output_id{0, 101};
|
||||||
EXPECT(real_spend.source == expected_out);
|
EXPECT(real_spend.source == expected_out);
|
||||||
EXPECT(real_spend.mixin_count == 15);
|
EXPECT(real_spend.mixin_count == 15);
|
||||||
EXPECT(real_spend.length == 0);
|
EXPECT(real_spend.length == 0);
|
||||||
EXPECT(real_spend.payment_id == crypto::hash{});
|
EXPECT(real_spend.payment_id == crypto::hash{});
|
||||||
|
EXPECT(real_spend.sender == lws::db::address_index{});
|
||||||
|
|
||||||
EXPECT(MONERO_UNWRAP(reader.get_outputs(lws::db::account_id(2))).count() == 0);
|
EXPECT(MONERO_UNWRAP(reader.get_outputs(lws::db::account_id(2))).count() == 0);
|
||||||
EXPECT(MONERO_UNWRAP(reader.get_spends(lws::db::account_id(2))).count() == 0);
|
EXPECT(MONERO_UNWRAP(reader.get_spends(lws::db::account_id(2))).count() == 0);
|
||||||
|
|
Loading…
Reference in a new issue