Instantiate m_curve_trees on BlockchainLMDB class in c'tor

This commit is contained in:
j-berman 2024-07-26 15:47:42 -07:00
parent d36b6fe96f
commit c383087955
8 changed files with 136 additions and 132 deletions

View File

@ -317,7 +317,8 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
std::multimap<uint64_t, fcmp::curve_trees::CurveTreesV1::LeafTupleContext> leaf_tuples_by_unlock_block;
// Get miner tx's leaf tuples
fcmp::curve_trees::curve_trees_v1.tx_outs_to_leaf_tuples(
CHECK_AND_ASSERT_THROW_MES(m_curve_trees != nullptr, "curve trees must be set");
m_curve_trees->tx_outs_to_leaf_tuples(
blk.miner_tx,
miner_output_ids,
prev_height,
@ -327,7 +328,7 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
// Get all other txs' leaf tuples
for (std::size_t i = 0; i < txs.size(); ++i)
{
fcmp::curve_trees::curve_trees_v1.tx_outs_to_leaf_tuples(
m_curve_trees->tx_outs_to_leaf_tuples(
txs[i].first,
output_ids[i],
prev_height,

View File

@ -591,12 +591,14 @@ protected:
HardFork* m_hardfork;
fcmp::curve_trees::CurveTreesV1* m_curve_trees;
public:
/**
* @brief An empty constructor.
*/
BlockchainDB(): m_hardfork(NULL), m_open(false) { }
BlockchainDB(): m_hardfork(NULL), m_open(false), m_curve_trees(NULL) { }
/**
* @brief An empty destructor.
@ -1780,13 +1782,12 @@ public:
virtual bool for_all_alt_blocks(std::function<bool(const crypto::hash &blkid, const alt_block_data_t &data, const cryptonote::blobdata_ref *blob)> f, bool include_blob = false) const = 0;
// TODO: description and make private
virtual void grow_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees,
std::vector<fcmp::curve_trees::CurveTreesV1::LeafTupleContext> &&new_leaves) = 0;
virtual void grow_tree(std::vector<fcmp::curve_trees::CurveTreesV1::LeafTupleContext> &&new_leaves) = 0;
virtual void trim_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees, const uint64_t trim_n_leaf_tuples) = 0;
virtual void trim_tree(const uint64_t trim_n_leaf_tuples) = 0;
// TODO: description
virtual bool audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees, const uint64_t expected_n_leaf_tuples) const = 0;
virtual bool audit_tree(const uint64_t expected_n_leaf_tuples) const = 0;
//
// Hard fork related storage

View File

@ -847,7 +847,7 @@ void BlockchainLMDB::add_block(const block& blk, size_t block_weight, uint64_t l
// Grow the tree with outputs that unlock at this block height
auto unlocked_leaf_tuples = this->get_leaf_tuples_at_unlock_block_id(m_height);
this->grow_tree(fcmp::curve_trees::curve_trees_v1, std::move(unlocked_leaf_tuples));
this->grow_tree(std::move(unlocked_leaf_tuples));
// Now that we've used the unlocked leaves to grow the tree, we can delete them from the locked leaves table
this->del_locked_leaf_tuples_at_block_id(m_height);
@ -1363,8 +1363,7 @@ void BlockchainLMDB::remove_spent_key(const crypto::key_image& k_image)
}
}
void BlockchainLMDB::grow_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees,
std::vector<fcmp::curve_trees::CurveTreesV1::LeafTupleContext> &&new_leaves)
void BlockchainLMDB::grow_tree(std::vector<fcmp::curve_trees::CurveTreesV1::LeafTupleContext> &&new_leaves)
{
if (new_leaves.empty())
return;
@ -1384,7 +1383,8 @@ void BlockchainLMDB::grow_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tree
const auto last_hashes = this->get_tree_last_hashes();
// Use the number of leaf tuples and the existing last hashes to get a struct we can use to extend the tree
const auto tree_extension = curve_trees.get_tree_extension(old_n_leaf_tuples, last_hashes, std::move(new_leaves));
CHECK_AND_ASSERT_THROW_MES(m_curve_trees != nullptr, "curve trees must be set");
const auto tree_extension = m_curve_trees->get_tree_extension(old_n_leaf_tuples, last_hashes, std::move(new_leaves));
// Insert the leaves
// TODO: grow_leaves
@ -1422,7 +1422,7 @@ void BlockchainLMDB::grow_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tree
throw0(DB_ERROR(("Growing odd c2 layer, expected even layer idx for c1: "
+ std::to_string(layer_idx)).c_str()));
this->grow_layer<fcmp::curve_trees::Selene>(curve_trees.m_c2,
this->grow_layer<fcmp::curve_trees::Selene>(m_curve_trees->m_c2,
c2_extensions,
c2_idx,
layer_idx);
@ -1435,7 +1435,7 @@ void BlockchainLMDB::grow_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tree
throw0(DB_ERROR(("Growing even c1 layer, expected odd layer idx for c2: "
+ std::to_string(layer_idx)).c_str()));
this->grow_layer<fcmp::curve_trees::Helios>(curve_trees.m_c1,
this->grow_layer<fcmp::curve_trees::Helios>(m_curve_trees->m_c1,
c1_extensions,
c1_idx,
layer_idx);
@ -1500,7 +1500,7 @@ void BlockchainLMDB::grow_layer(const C &curve,
}
}
void BlockchainLMDB::trim_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees, const uint64_t trim_n_leaf_tuples)
void BlockchainLMDB::trim_tree(const uint64_t trim_n_leaf_tuples)
{
// TODO: block_wtxn_start like pop_block, then call BlockchainDB::trim_tree
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
@ -1515,14 +1515,15 @@ void BlockchainLMDB::trim_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tree
const uint64_t old_n_leaf_tuples = this->get_num_leaf_tuples();
CHECK_AND_ASSERT_THROW_MES(old_n_leaf_tuples > trim_n_leaf_tuples, "cannot trim more leaves than exist");
const auto trim_instructions = curve_trees.get_trim_instructions(old_n_leaf_tuples, trim_n_leaf_tuples);
CHECK_AND_ASSERT_THROW_MES(m_curve_trees != nullptr, "curve trees must be set");
const auto trim_instructions = m_curve_trees->get_trim_instructions(old_n_leaf_tuples, trim_n_leaf_tuples);
// Do initial tree reads
const auto last_chunk_children_to_trim = this->get_last_chunk_children_to_trim(curve_trees, trim_instructions);
const auto last_chunk_children_to_trim = this->get_last_chunk_children_to_trim(trim_instructions);
const auto last_hashes_to_trim = this->get_last_hashes_to_trim(trim_instructions);
// Get the new hashes, wrapped in a simple struct we can use to trim the tree
const auto tree_reduction = curve_trees.get_tree_reduction(
const auto tree_reduction = m_curve_trees->get_tree_reduction(
trim_instructions,
last_chunk_children_to_trim,
last_hashes_to_trim);
@ -1727,12 +1728,12 @@ std::array<uint8_t, 32UL> BlockchainLMDB::get_tree_root() const
if ((layer_idx % 2) == 0)
{
const auto *lv = (layer_val<fcmp::curve_trees::Selene> *)v.mv_data;
root = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(lv->child_chunk_hash);
root = m_curve_trees->m_c2.to_bytes(lv->child_chunk_hash);
}
else
{
const auto *lv = (layer_val<fcmp::curve_trees::Helios> *)v.mv_data;
root = fcmp::curve_trees::curve_trees_v1.m_c1.to_bytes(lv->child_chunk_hash);
root = m_curve_trees->m_c1.to_bytes(lv->child_chunk_hash);
}
}
else if (result != MDB_NOTFOUND)
@ -1798,12 +1799,13 @@ fcmp::curve_trees::CurveTreesV1::LastHashes BlockchainLMDB::get_tree_last_hashes
}
fcmp::curve_trees::CurveTreesV1::LastChunkChildrenToTrim BlockchainLMDB::get_last_chunk_children_to_trim(
const fcmp::curve_trees::CurveTreesV1 &curve_trees,
const std::vector<fcmp::curve_trees::TrimLayerInstructions> &trim_instructions) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
CHECK_AND_ASSERT_THROW_MES(m_curve_trees != nullptr, "curve trees must be set");
TXN_PREFIX_RDONLY();
RCURSOR(layers)
@ -1885,13 +1887,13 @@ fcmp::curve_trees::CurveTreesV1::LastChunkChildrenToTrim BlockchainLMDB::get_las
if (parent_is_c1)
{
const auto *lv = (layer_val<fcmp::curve_trees::Selene> *)v.mv_data;
auto child_scalar = curve_trees.m_c2.point_to_cycle_scalar(lv->child_chunk_hash);
auto child_scalar = m_curve_trees->m_c2.point_to_cycle_scalar(lv->child_chunk_hash);
c1_children.emplace_back(std::move(child_scalar));
}
else
{
const auto *lv = (layer_val<fcmp::curve_trees::Helios> *)v.mv_data;
auto child_scalar = curve_trees.m_c1.point_to_cycle_scalar(lv->child_chunk_hash);
auto child_scalar = m_curve_trees->m_c1.point_to_cycle_scalar(lv->child_chunk_hash);
c2_children.emplace_back(std::move(child_scalar));
}
@ -1958,8 +1960,7 @@ fcmp::curve_trees::CurveTreesV1::LastHashes BlockchainLMDB::get_last_hashes_to_t
return last_hashes_out;
}
bool BlockchainLMDB::audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees,
const uint64_t expected_n_leaf_tuples) const
bool BlockchainLMDB::audit_tree(const uint64_t expected_n_leaf_tuples) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
@ -1984,6 +1985,8 @@ bool BlockchainLMDB::audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tre
return true;
}
CHECK_AND_ASSERT_THROW_MES(m_curve_trees != nullptr, "curve trees must be set");
// Check chunks of leaves hash into first layer as expected
uint64_t layer_idx = 0;
uint64_t child_chunk_idx = 0;
@ -1992,7 +1995,7 @@ bool BlockchainLMDB::audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tre
{
// Get next leaf chunk
std::vector<fcmp::curve_trees::CurveTreesV1::LeafTuple> leaf_tuples_chunk;
leaf_tuples_chunk.reserve(curve_trees.m_c2_width);
leaf_tuples_chunk.reserve(m_curve_trees->m_c2_width);
// Iterate until chunk is full or we get to the end of all leaves
while (1)
@ -2008,7 +2011,7 @@ bool BlockchainLMDB::audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tre
const auto leaf = *(fcmp::curve_trees::CurveTreesV1::LeafTuple *)v.mv_data;
leaf_tuples_chunk.push_back(leaf);
if (leaf_tuples_chunk.size() == curve_trees.m_c2_width)
if (leaf_tuples_chunk.size() == m_curve_trees->m_c2_width)
break;
}
@ -2035,23 +2038,23 @@ bool BlockchainLMDB::audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tre
throw0(DB_ERROR(lmdb_error("Failed to get parent in first layer: ", result).c_str()));
// Get the expected leaf chunk hash
const std::vector<fcmp::curve_trees::Selene::Scalar> leaves = curve_trees.flatten_leaves(leaf_tuples_chunk);
const auto leaves = m_curve_trees->flatten_leaves(leaf_tuples_chunk);
const fcmp::curve_trees::Selene::Chunk chunk{leaves.data(), leaves.size()};
// Hash the chunk of leaves
for (uint64_t i = 0; i < leaves.size(); ++i)
MDEBUG("Hashing " << curve_trees.m_c2.to_string(leaves[i]));
MDEBUG("Hashing " << m_curve_trees->m_c2.to_string(leaves[i]));
const fcmp::curve_trees::Selene::Point chunk_hash = fcmp::curve_trees::get_new_parent(curve_trees.m_c2, chunk);
MDEBUG("chunk_hash " << curve_trees.m_c2.to_string(chunk_hash) << " , hash init point: "
<< curve_trees.m_c2.to_string(curve_trees.m_c2.m_hash_init_point) << " (" << leaves.size() << " leaves)");
const fcmp::curve_trees::Selene::Point chunk_hash = fcmp::curve_trees::get_new_parent(m_curve_trees->m_c2, chunk);
MDEBUG("chunk_hash " << m_curve_trees->m_c2.to_string(chunk_hash) << " , hash init point: "
<< m_curve_trees->m_c2.to_string(m_curve_trees->m_c2.m_hash_init_point) << " (" << leaves.size() << " leaves)");
// Now compare to value from the db
const auto *lv = (layer_val<fcmp::curve_trees::Selene> *)v_parent.mv_data;
MDEBUG("Actual leaf chunk hash " << curve_trees.m_c2.to_string(lv->child_chunk_hash));
MDEBUG("Actual leaf chunk hash " << m_curve_trees->m_c2.to_string(lv->child_chunk_hash));
const auto expected_bytes = curve_trees.m_c2.to_bytes(chunk_hash);
const auto actual_bytes = curve_trees.m_c2.to_bytes(lv->child_chunk_hash);
const auto expected_bytes = m_curve_trees->m_c2.to_bytes(chunk_hash);
const auto actual_bytes = m_curve_trees->m_c2.to_bytes(lv->child_chunk_hash);
CHECK_AND_ASSERT_MES(expected_bytes == actual_bytes, false, "unexpected leaf chunk hash");
++child_chunk_idx;
@ -2065,12 +2068,12 @@ bool BlockchainLMDB::audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tre
if (parent_is_c1)
{
if (this->audit_layer(
/*c_child*/ curve_trees.m_c2,
/*c_parent*/ curve_trees.m_c1,
/*c_child*/ m_curve_trees->m_c2,
/*c_parent*/ m_curve_trees->m_c1,
layer_idx,
/*child_start_idx*/ 0,
/*child_chunk_idx*/ 0,
/*chunk_width*/ curve_trees.m_c1_width))
/*chunk_width*/ m_curve_trees->m_c1_width))
{
break;
}
@ -2078,12 +2081,12 @@ bool BlockchainLMDB::audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_tre
else
{
if (this->audit_layer(
/*c_child*/ curve_trees.m_c1,
/*c_parent*/ curve_trees.m_c2,
/*c_child*/ m_curve_trees->m_c1,
/*c_parent*/ m_curve_trees->m_c2,
layer_idx,
/*child_start_idx*/ 0,
/*child_chunk_idx*/ 0,
/*chunk_width*/ curve_trees.m_c2_width))
/*chunk_width*/ m_curve_trees->m_c2_width))
{
break;
}
@ -2291,7 +2294,7 @@ BlockchainLMDB::~BlockchainLMDB()
BlockchainLMDB::close();
}
BlockchainLMDB::BlockchainLMDB(bool batch_transactions): BlockchainDB()
BlockchainLMDB::BlockchainLMDB(bool batch_transactions, fcmp::curve_trees::CurveTreesV1 *curve_trees): BlockchainDB()
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
// initialize folder to something "safe" just in case
@ -2308,6 +2311,8 @@ BlockchainLMDB::BlockchainLMDB(bool batch_transactions): BlockchainDB()
// reset may also need changing when initialize things here
m_hardfork = nullptr;
m_curve_trees = curve_trees;
}
void BlockchainLMDB::open(const std::string& filename, const int db_flags)
@ -2320,6 +2325,9 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags)
if (m_open)
throw0(DB_OPEN_FAILURE("Attempted to open db, but it's already open"));
if (m_curve_trees == nullptr)
throw0(DB_OPEN_FAILURE("curve trees not set yet, must be set before opening db"));
boost::filesystem::path direc(filename);
if (!boost::filesystem::exists(direc) &&
!boost::filesystem::create_directories(direc)) {
@ -6727,8 +6735,7 @@ void BlockchainLMDB::migrate_5_6()
{
LOGIF(el::Level::Info)
{
// TODO: total num elems in m_output_amounts
std::cout << i << " / TODO outputs \r" << std::flush;
std::cout << i << " / " << n_outputs << " \r" << std::flush;
}
txn.commit();
result = mdb_txn_begin(m_env, NULL, 0, txn);
@ -6787,7 +6794,7 @@ void BlockchainLMDB::migrate_5_6()
// Convert the output into a leaf tuple
try
{
tuple_context.leaf_tuple = fcmp::curve_trees::curve_trees_v1.output_to_leaf_tuple(
tuple_context.leaf_tuple = m_curve_trees->output_to_leaf_tuple(
output_data.pubkey,
rct::rct2pk(output_data.commitment));
}
@ -6888,7 +6895,7 @@ void BlockchainLMDB::migrate_5_6()
// Get the leaf tuples that unlock at the given block
auto unlocked_leaf_tuples = this->get_leaf_tuples_at_unlock_block_id(i);
this->grow_tree(fcmp::curve_trees::curve_trees_v1, std::move(unlocked_leaf_tuples));
this->grow_tree(std::move(unlocked_leaf_tuples));
// Now that we've used the unlocked leaves to grow the tree, we can delete them from the locked leaves table
this->del_locked_leaf_tuples_at_block_id(i);

View File

@ -193,7 +193,7 @@ struct mdb_txn_safe
class BlockchainLMDB : public BlockchainDB
{
public:
BlockchainLMDB(bool batch_transactions=true);
BlockchainLMDB(bool batch_transactions=true, fcmp::curve_trees::CurveTreesV1 *curve_trees=&fcmp::curve_trees::CURVE_TREES_V1);
~BlockchainLMDB();
virtual void open(const std::string& filename, const int mdb_flags=0);
@ -367,13 +367,11 @@ public:
static int compare_string(const MDB_val *a, const MDB_val *b);
// make private
virtual void grow_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees,
std::vector<fcmp::curve_trees::CurveTreesV1::LeafTupleContext> &&new_leaves);
virtual void grow_tree(std::vector<fcmp::curve_trees::CurveTreesV1::LeafTupleContext> &&new_leaves);
virtual void trim_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees, const uint64_t trim_n_leaf_tuples);
virtual void trim_tree(const uint64_t trim_n_leaf_tuples);
virtual bool audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees,
const uint64_t expected_n_leaf_tuples) const;
virtual bool audit_tree(const uint64_t expected_n_leaf_tuples) const;
private:
void do_resize(uint64_t size_increase=0);
@ -435,7 +433,6 @@ private:
fcmp::curve_trees::CurveTreesV1::LastHashes get_tree_last_hashes() const;
fcmp::curve_trees::CurveTreesV1::LastChunkChildrenToTrim get_last_chunk_children_to_trim(
const fcmp::curve_trees::CurveTreesV1 &curve_trees,
const std::vector<fcmp::curve_trees::TrimLayerInstructions> &trim_instructions) const;
fcmp::curve_trees::CurveTreesV1::LastHashes get_last_hashes_to_trim(
@ -547,8 +544,6 @@ private:
mdb_txn_cursors m_wcursors;
mutable boost::thread_specific_ptr<mdb_threadinfo> m_tinfo;
// TODO: m_curve_trees
#if defined(__arm__)
// force a value so it can compile with 32-bit ARM
constexpr static uint64_t DEFAULT_MAPSIZE = 1LL << 31;

View File

@ -116,10 +116,9 @@ public:
virtual void add_tx_amount_output_indices(const uint64_t tx_index, const std::vector<uint64_t>& amount_output_indices) override {}
virtual void add_spent_key(const crypto::key_image& k_image) override {}
virtual void remove_spent_key(const crypto::key_image& k_image) override {}
virtual void grow_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees,
std::vector<fcmp::curve_trees::CurveTreesV1::LeafTupleContext> &&new_leaves) override {};
virtual void trim_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees, const uint64_t trim_n_leaf_tuples) override {};
virtual bool audit_tree(const fcmp::curve_trees::CurveTreesV1 &curve_trees, const uint64_t expected_n_leaf_tuples) const override { return false; };
virtual void grow_tree(std::vector<fcmp::curve_trees::CurveTreesV1::LeafTupleContext> &&new_leaves) override {};
virtual void trim_tree(const uint64_t trim_n_leaf_tuples) override {};
virtual bool audit_tree(const uint64_t expected_n_leaf_tuples) const override { return false; };
virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const override { return true; }
virtual bool for_blocks_range(const uint64_t&, const uint64_t&, std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const override { return true; }

View File

@ -285,11 +285,11 @@ using CurveTreesV1 = CurveTrees<Helios, Selene>;
// https://github.com/kayabaNerve/fcmp-plus-plus/blob
// /b2742e86f3d18155fd34dd1ed69cb8f79b900fce/crypto/fcmps/src/tests.rs#L81-L82
static const std::size_t HELIOS_CHUNK_WIDTH = 38;
static const std::size_t SELENE_CHUNK_WIDTH = 18;
static const Helios HELIOS;
static const Selene SELENE;
static const CurveTreesV1 curve_trees_v1(HELIOS, SELENE, HELIOS_CHUNK_WIDTH, SELENE_CHUNK_WIDTH);
const std::size_t HELIOS_CHUNK_WIDTH = 38;
const std::size_t SELENE_CHUNK_WIDTH = 18;
const Helios HELIOS;
const Selene SELENE;
static CurveTreesV1 CURVE_TREES_V1(HELIOS, SELENE, HELIOS_CHUNK_WIDTH, SELENE_CHUNK_WIDTH);
//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
} //namespace curve_trees

View File

@ -852,7 +852,7 @@ static bool grow_tree_db(const std::size_t init_leaves,
CurveTreesV1 &curve_trees,
unit_test::BlockchainLMDBTest &test_db)
{
INIT_BLOCKCHAIN_LMDB_TEST_DB();
INIT_BLOCKCHAIN_LMDB_TEST_DB(&curve_trees);
{
cryptonote::db_wtxn_guard guard(test_db.m_db);
@ -861,8 +861,8 @@ static bool grow_tree_db(const std::size_t init_leaves,
auto init_leaf_tuples = generate_random_leaves(curve_trees, 0, init_leaves);
test_db.m_db->grow_tree(curve_trees, std::move(init_leaf_tuples));
CHECK_AND_ASSERT_MES(test_db.m_db->audit_tree(curve_trees, init_leaves), false,
test_db.m_db->grow_tree(std::move(init_leaf_tuples));
CHECK_AND_ASSERT_MES(test_db.m_db->audit_tree(init_leaves), false,
"failed to add initial leaves to db");
MDEBUG("Successfully added initial " << init_leaves << " leaves to db, extending by "
@ -870,8 +870,8 @@ static bool grow_tree_db(const std::size_t init_leaves,
auto ext_leaf_tuples = generate_random_leaves(curve_trees, init_leaves, ext_leaves);
test_db.m_db->grow_tree(curve_trees, std::move(ext_leaf_tuples));
CHECK_AND_ASSERT_MES(test_db.m_db->audit_tree(curve_trees, init_leaves + ext_leaves), false,
test_db.m_db->grow_tree(std::move(ext_leaf_tuples));
CHECK_AND_ASSERT_MES(test_db.m_db->audit_tree(init_leaves + ext_leaves), false,
"failed to extend tree in db");
MDEBUG("Successfully extended tree in db by " << ext_leaves << " leaves");
@ -885,7 +885,7 @@ static bool trim_tree_db(const std::size_t init_leaves,
CurveTreesV1 &curve_trees,
unit_test::BlockchainLMDBTest &test_db)
{
INIT_BLOCKCHAIN_LMDB_TEST_DB();
INIT_BLOCKCHAIN_LMDB_TEST_DB(&curve_trees);
{
cryptonote::db_wtxn_guard guard(test_db.m_db);
@ -894,15 +894,15 @@ static bool trim_tree_db(const std::size_t init_leaves,
auto init_leaf_tuples = generate_random_leaves(curve_trees, 0, init_leaves);
test_db.m_db->grow_tree(curve_trees, std::move(init_leaf_tuples));
CHECK_AND_ASSERT_MES(test_db.m_db->audit_tree(curve_trees, init_leaves), false,
test_db.m_db->grow_tree(std::move(init_leaf_tuples));
CHECK_AND_ASSERT_MES(test_db.m_db->audit_tree(init_leaves), false,
"failed to add initial leaves to db");
MDEBUG("Successfully added initial " << init_leaves << " leaves to db, trimming by "
<< trim_leaves << " leaves");
test_db.m_db->trim_tree(curve_trees, trim_leaves);
CHECK_AND_ASSERT_MES(test_db.m_db->audit_tree(curve_trees, init_leaves - trim_leaves), false,
test_db.m_db->trim_tree(trim_leaves);
CHECK_AND_ASSERT_MES(test_db.m_db->audit_tree(init_leaves - trim_leaves), false,
"failed to trim tree in db");
MDEBUG("Successfully trimmed tree in db by " << trim_leaves << " leaves");
@ -1037,29 +1037,29 @@ TEST(curve_trees, hash_trim)
// Get the initial hash of the 2 scalars
std::vector<Selene::Scalar> init_children{selene_scalar_0, selene_scalar_1};
const auto init_hash = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto init_hash = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{init_children.data(), init_children.size()});
// Trim selene_scalar_1
const auto &trimmed_children = Selene::Chunk{init_children.data() + 1, 1};
const auto trim_res = fcmp::curve_trees::curve_trees_v1.m_c2.hash_trim(
const auto trim_res = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_trim(
init_hash,
1,
trimmed_children,
fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar());
const auto trim_res_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(trim_res);
fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar());
const auto trim_res_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(trim_res);
// Now compare to calling hash_grow{selene_scalar_0}
std::vector<Selene::Scalar> remaining_children{selene_scalar_0};
const auto grow_res = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto grow_res = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{remaining_children.data(), remaining_children.size()});
const auto grow_res_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(grow_res);
const auto grow_res_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(grow_res);
ASSERT_EQ(trim_res_bytes, grow_res_bytes);
}
@ -1074,29 +1074,29 @@ TEST(curve_trees, hash_trim)
// Get the initial hash of the 3 selene scalars
std::vector<Selene::Scalar> init_children{selene_scalar_0, selene_scalar_1, selene_scalar_2};
const auto init_hash = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto init_hash = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{init_children.data(), init_children.size()});
// Trim the initial result by 2 children
const auto &trimmed_children = Selene::Chunk{init_children.data() + 1, 2};
const auto trim_res = fcmp::curve_trees::curve_trees_v1.m_c2.hash_trim(
const auto trim_res = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_trim(
init_hash,
1,
trimmed_children,
fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar());
const auto trim_res_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(trim_res);
fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar());
const auto trim_res_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(trim_res);
// Now compare to calling hash_grow{selene_scalar_0}
std::vector<Selene::Scalar> remaining_children{selene_scalar_0};
const auto grow_res = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto grow_res = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{remaining_children.data(), remaining_children.size()});
const auto grow_res_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(grow_res);
const auto grow_res_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(grow_res);
ASSERT_EQ(trim_res_bytes, grow_res_bytes);
}
@ -1110,31 +1110,31 @@ TEST(curve_trees, hash_trim)
// Get the initial hash of the 2 selene scalars
std::vector<Selene::Scalar> init_children{selene_scalar_0, selene_scalar_1};
const auto init_hash = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto init_hash = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{init_children.data(), init_children.size()});
const auto selene_scalar_2 = generate_random_selene_scalar();
// Trim the 2nd child and grow with new child
const auto &trimmed_children = Selene::Chunk{init_children.data() + 1, 1};
const auto trim_res = fcmp::curve_trees::curve_trees_v1.m_c2.hash_trim(
const auto trim_res = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_trim(
init_hash,
1,
trimmed_children,
selene_scalar_2);
const auto trim_res_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(trim_res);
const auto trim_res_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(trim_res);
// Now compare to calling hash_grow{selene_scalar_0, selene_scalar_2}
std::vector<Selene::Scalar> remaining_children{selene_scalar_0, selene_scalar_2};
const auto grow_res = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto grow_res = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{remaining_children.data(), remaining_children.size()});
const auto grow_res_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(grow_res);
const auto grow_res_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(grow_res);
ASSERT_EQ(trim_res_bytes, grow_res_bytes);
}
@ -1149,31 +1149,31 @@ TEST(curve_trees, hash_trim)
// Get the initial hash of the 3 selene scalars
std::vector<Selene::Scalar> init_children{selene_scalar_0, selene_scalar_1, selene_scalar_2};
const auto init_hash = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto init_hash = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{init_children.data(), init_children.size()});
const auto selene_scalar_3 = generate_random_selene_scalar();
// Trim the initial result by 2 children+grow by 1
const auto &trimmed_children = Selene::Chunk{init_children.data() + 1, 2};
const auto trim_res = fcmp::curve_trees::curve_trees_v1.m_c2.hash_trim(
const auto trim_res = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_trim(
init_hash,
1,
trimmed_children,
selene_scalar_3);
const auto trim_res_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(trim_res);
const auto trim_res_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(trim_res);
// Now compare to calling hash_grow{selene_scalar_0, selene_scalar_3}
std::vector<Selene::Scalar> remaining_children{selene_scalar_0, selene_scalar_3};
const auto grow_res = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto grow_res = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{remaining_children.data(), remaining_children.size()});
const auto grow_res_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(grow_res);
const auto grow_res_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(grow_res);
ASSERT_EQ(trim_res_bytes, grow_res_bytes);
}
@ -1189,30 +1189,30 @@ TEST(curve_trees, hash_grow)
// Get the initial hash of the 2 selene scalars
std::vector<Selene::Scalar> all_children{selene_scalar_0, selene_scalar_1};
const auto init_hash = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto init_hash = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{all_children.data(), all_children.size()});
// Extend with a new child
const auto selene_scalar_2 = generate_random_selene_scalar();
std::vector<Selene::Scalar> new_children{selene_scalar_2};
const auto ext_hash = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
const auto ext_hash = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
init_hash,
all_children.size(),
fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
Selene::Chunk{new_children.data(), new_children.size()});
const auto ext_hash_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(ext_hash);
const auto ext_hash_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(ext_hash);
// Now compare to calling hash_grow{selene_scalar_0, selene_scalar_1, selene_scalar_2}
all_children.push_back(selene_scalar_2);
const auto grow_res = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto grow_res = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{all_children.data(), all_children.size()});
const auto grow_res_bytes = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(grow_res);
const auto grow_res_bytes = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(grow_res);
ASSERT_EQ(ext_hash_bytes, grow_res_bytes);
@ -1220,21 +1220,21 @@ TEST(curve_trees, hash_grow)
const auto selene_scalar_3 = generate_random_selene_scalar();
new_children.clear();
new_children = {selene_scalar_3};
const auto ext_hash2 = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
const auto ext_hash2 = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
ext_hash,
all_children.size(),
fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
Selene::Chunk{new_children.data(), new_children.size()});
const auto ext_hash_bytes2 = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(ext_hash2);
const auto ext_hash_bytes2 = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(ext_hash2);
// Now compare to calling hash_grow{selene_scalar_0, selene_scalar_1, selene_scalar_2, selene_scalar_3}
all_children.push_back(selene_scalar_3);
const auto grow_res2 = fcmp::curve_trees::curve_trees_v1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::curve_trees_v1.m_c2.m_hash_init_point,
const auto grow_res2 = fcmp::curve_trees::CURVE_TREES_V1.m_c2.hash_grow(
/*existing_hash*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.m_hash_init_point,
/*offset*/ 0,
/*existing_child_at_offset*/ fcmp::curve_trees::curve_trees_v1.m_c2.zero_scalar(),
/*existing_child_at_offset*/ fcmp::curve_trees::CURVE_TREES_V1.m_c2.zero_scalar(),
/*children*/ Selene::Chunk{all_children.data(), all_children.size()});
const auto grow_res_bytes2 = fcmp::curve_trees::curve_trees_v1.m_c2.to_bytes(grow_res2);
const auto grow_res_bytes2 = fcmp::curve_trees::CURVE_TREES_V1.m_c2.to_bytes(grow_res2);
ASSERT_EQ(ext_hash_bytes2, grow_res_bytes2);
}

View File

@ -34,6 +34,7 @@
#include "blockchain_db/blockchain_db.h"
#include "blockchain_db/lmdb/db_lmdb.h"
#include "fcmp/curve_trees.h"
#include "misc_log_ex.h"
#include <atomic>
@ -83,10 +84,10 @@ namespace unit_test
remove_files();
}
void init_new_db()
void init_new_db(fcmp::curve_trees::CurveTreesV1 *curve_trees)
{
CHECK_AND_ASSERT_THROW_MES(this->m_db == nullptr, "expected nullptr m_db");
this->m_db = new cryptonote::BlockchainLMDB();
this->m_db = new cryptonote::BlockchainLMDB(true/*batch_transactions*/, curve_trees);
const auto temp_db_path = boost::filesystem::unique_path();
const std::string dir_path = m_temp_db_dir + temp_db_path.string();
@ -111,8 +112,8 @@ namespace unit_test
};
}
#define INIT_BLOCKCHAIN_LMDB_TEST_DB() \
test_db.init_new_db(); \
#define INIT_BLOCKCHAIN_LMDB_TEST_DB(curve_trees) \
test_db.init_new_db(curve_trees); \
auto hardfork = cryptonote::HardFork(*test_db.m_db, 1, 0); \
test_db.init_hardfork(&hardfork); \
auto scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ \