From b90cee8bab14cb3f1a09462a494608d930c83981 Mon Sep 17 00:00:00 2001 From: j-berman Date: Fri, 2 Aug 2024 10:28:13 -0700 Subject: [PATCH] Store {O,C} for each leaf tuple instead of {O.x,I.x,C.x} - Can derive {O.x,I.x,C.x} from {O,C} - Note: this slows down tests since they do the derivation both on insertion into the tree, and when auditing the tree - At the hard fork, we don't need to store {O,C} in the output_amounts table anymore since that table will no longer be useful --- src/blockchain_db/blockchain_db.cpp | 8 +-- src/blockchain_db/blockchain_db.h | 4 +- src/blockchain_db/lmdb/db_lmdb.cpp | 52 ++++++++------- src/blockchain_db/lmdb/db_lmdb.h | 6 +- src/blockchain_db/testdb.h | 4 +- src/fcmp/curve_trees.cpp | 70 ++++++++++++++------- src/fcmp/curve_trees.h | 42 ++++++++----- tests/block_weight/block_weight.cpp | 2 +- tests/core_tests/chaingen.cpp | 2 +- tests/unit_tests/curve_trees.cpp | 35 +++++++---- tests/unit_tests/hardfork.cpp | 2 +- tests/unit_tests/long_term_block_weight.cpp | 2 +- 12 files changed, 144 insertions(+), 85 deletions(-) diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index b44777955..5e3d48efb 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -231,7 +231,7 @@ std::vector BlockchainDB::add_transaction(const crypto::hash& blk_hash { // miner v2 txes have their coinbase output in one single out to save space, // and we store them as rct outputs with an identity mask - // note: tx_outs_to_leaf_tuples in curve_trees.cpp mirrors this logic + // note: tx_outs_to_leaf_tuple_contexts in curve_trees.cpp mirrors this logic if (miner_tx && tx.version == 2) { cryptonote::tx_out vout = tx.vout[i]; @@ -314,11 +314,11 @@ uint64_t BlockchainDB::add_block( const std::pair& blck // When adding a block, we also need to add all the leaf tuples included in // the block to a table keeping track of locked leaf tuples. Once those leaf // tuples unlock, we use them to grow the tree. - std::multimap leaf_tuples_by_unlock_block; + std::multimap leaf_tuples_by_unlock_block; // Get miner tx's leaf tuples CHECK_AND_ASSERT_THROW_MES(m_curve_trees != nullptr, "curve trees must be set"); - m_curve_trees->tx_outs_to_leaf_tuples( + m_curve_trees->tx_outs_to_leaf_tuple_contexts( blk.miner_tx, miner_output_ids, prev_height, @@ -328,7 +328,7 @@ uint64_t BlockchainDB::add_block( const std::pair& blck // Get all other txs' leaf tuples for (std::size_t i = 0; i < txs.size(); ++i) { - m_curve_trees->tx_outs_to_leaf_tuples( + m_curve_trees->tx_outs_to_leaf_tuple_contexts( txs[i].first, output_ids[i], prev_height, diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 09036fbb4..5f600e408 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -417,7 +417,7 @@ private: , const uint64_t& coins_generated , uint64_t num_rct_outs , const crypto::hash& blk_hash - , const std::multimap& leaf_tuples_by_unlock_block + , const std::multimap& leaf_tuples_by_unlock_block ) = 0; /** @@ -1782,7 +1782,7 @@ public: virtual bool for_all_alt_blocks(std::function f, bool include_blob = false) const = 0; // TODO: description and make private - virtual void grow_tree(std::vector &&new_leaves) = 0; + virtual void grow_tree(std::vector &&new_leaves) = 0; virtual void trim_tree(const uint64_t trim_n_leaf_tuples) = 0; diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index dbb7fd903..561d2e3fd 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -216,7 +216,6 @@ namespace * * spent_keys input hash - * - * TODO: don't store leaf tuples, store reference to outputs * locked_leaves block ID [{output ID, leaf tuple}...] * leaves leaf_idx {leaf tuple} * layers layer_idx [{child_chunk_idx, child_chunk_hash}...] @@ -816,7 +815,7 @@ estim: } void BlockchainLMDB::add_block(const block& blk, size_t block_weight, uint64_t long_term_block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, - uint64_t num_rct_outs, const crypto::hash& blk_hash, const std::multimap &leaf_tuples_by_unlock_block) + uint64_t num_rct_outs, const crypto::hash& blk_hash, const std::multimap &leaf_tuples_by_unlock_block) { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -845,8 +844,8 @@ 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(std::move(unlocked_leaf_tuples)); + auto unlocked_leaves = this->get_leaf_tuples_at_unlock_block_id(m_height); + this->grow_tree(std::move(unlocked_leaves)); // 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); @@ -1362,7 +1361,7 @@ void BlockchainLMDB::remove_spent_key(const crypto::key_image& k_image) } } -void BlockchainLMDB::grow_tree(std::vector &&new_leaves) +void BlockchainLMDB::grow_tree(std::vector &&new_leaves) { if (new_leaves.empty()) return; @@ -1815,6 +1814,8 @@ fcmp::curve_trees::CurveTreesV1::LastChunkChildrenToTrim BlockchainLMDB::get_las if (trim_leaf_layer_instructions.end_trim_idx > trim_leaf_layer_instructions.start_trim_idx) { + leaves_to_trim.reserve(trim_leaf_layer_instructions.end_trim_idx - trim_leaf_layer_instructions.start_trim_idx); + uint64_t idx = trim_leaf_layer_instructions.start_trim_idx; CHECK_AND_ASSERT_THROW_MES(idx % fcmp::curve_trees::CurveTreesV1::LEAF_TUPLE_SIZE == 0, "expected divisble by leaf tuple size"); @@ -1833,11 +1834,14 @@ fcmp::curve_trees::CurveTreesV1::LastChunkChildrenToTrim BlockchainLMDB::get_las if (result != MDB_SUCCESS) throw0(DB_ERROR(lmdb_error("Failed to get leaf: ", result).c_str())); - const auto leaf = *(fcmp::curve_trees::CurveTreesV1::LeafTuple *)v.mv_data; + const auto preprocessed_leaf_tuple = *(fcmp::curve_trees::PreprocessedLeafTuple *)v.mv_data; - leaves_to_trim.push_back(leaf.O_x); - leaves_to_trim.push_back(leaf.I_x); - leaves_to_trim.push_back(leaf.C_x); + // TODO: parallelize calls to this function + auto leaf = m_curve_trees->leaf_tuple(preprocessed_leaf_tuple); + + leaves_to_trim.emplace_back(std::move(leaf.O_x)); + leaves_to_trim.emplace_back(std::move(leaf.I_x)); + leaves_to_trim.emplace_back(std::move(leaf.C_x)); idx += fcmp::curve_trees::CurveTreesV1::LEAF_TUPLE_SIZE; } @@ -2002,8 +2006,10 @@ bool BlockchainLMDB::audit_tree(const uint64_t expected_n_leaf_tuples) const if (result != MDB_SUCCESS) throw0(DB_ERROR(lmdb_error("Failed to add leaf: ", result).c_str())); - const auto leaf = *(fcmp::curve_trees::CurveTreesV1::LeafTuple *)v.mv_data; - leaf_tuples_chunk.push_back(leaf); + const auto preprocessed_leaf_tuple = *(fcmp::curve_trees::PreprocessedLeafTuple *)v.mv_data; + auto leaf = m_curve_trees->leaf_tuple(preprocessed_leaf_tuple); + + leaf_tuples_chunk.emplace_back(std::move(leaf)); if (leaf_tuples_chunk.size() == m_curve_trees->m_c2_width) break; @@ -2205,7 +2211,7 @@ bool BlockchainLMDB::audit_layer(const C_CHILD &c_child, chunk_width); } -std::vector BlockchainLMDB::get_leaf_tuples_at_unlock_block_id( +std::vector BlockchainLMDB::get_leaf_tuples_at_unlock_block_id( uint64_t block_id) { LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -2218,7 +2224,7 @@ std::vector BlockchainLMDB::g MDB_val v_tuple; // Get all the locked outputs at the provided block id - std::vector leaf_tuples; + std::vector leaf_tuples; MDB_cursor_op op = MDB_SET; while (1) @@ -2234,8 +2240,8 @@ std::vector BlockchainLMDB::g if (blk_id != block_id) throw0(DB_ERROR(("Blk id " + std::to_string(blk_id) + " not the expected" + std::to_string(block_id)).c_str())); - const auto range_begin = ((const fcmp::curve_trees::CurveTreesV1::LeafTupleContext*)v_tuple.mv_data); - const auto range_end = range_begin + v_tuple.mv_size / sizeof(fcmp::curve_trees::CurveTreesV1::LeafTupleContext); + const auto range_begin = ((const fcmp::curve_trees::LeafTupleContext*)v_tuple.mv_data); + const auto range_end = range_begin + v_tuple.mv_size / sizeof(fcmp::curve_trees::LeafTupleContext); auto it = range_begin; @@ -6772,25 +6778,27 @@ void BlockchainLMDB::migrate_5_6() // Read the output data uint64_t amount = *(const uint64_t*)k.mv_data; output_data_t output_data; - fcmp::curve_trees::CurveTreesV1::LeafTupleContext tuple_context; + uint64_t output_id; if (amount == 0) { const outkey *okp = (const outkey *)v.mv_data; output_data = okp->data; - tuple_context.output_id = okp->output_id; + output_id = okp->output_id; } else { const pre_rct_outkey *okp = (const pre_rct_outkey *)v.mv_data; memcpy(&output_data, &okp->data, sizeof(pre_rct_output_data_t)); output_data.commitment = rct::zeroCommit(amount); - tuple_context.output_id = okp->output_id; + output_id = okp->output_id; } - // Convert the output into a leaf tuple + // Convert the output into a leaf tuple context + fcmp::curve_trees::LeafTupleContext tuple_context; try { - tuple_context.leaf_tuple = m_curve_trees->output_to_leaf_tuple( + tuple_context = m_curve_trees->output_to_leaf_context( + output_id, output_data.pubkey, rct::rct2pk(output_data.commitment)); } @@ -6890,8 +6898,8 @@ 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(std::move(unlocked_leaf_tuples)); + auto unlocked_leaves = this->get_leaf_tuples_at_unlock_block_id(i); + this->grow_tree(std::move(unlocked_leaves)); // 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); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 834b2bf1e..a9263303a 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -368,7 +368,7 @@ public: static int compare_string(const MDB_val *a, const MDB_val *b); // make private - virtual void grow_tree(std::vector &&new_leaves); + virtual void grow_tree(std::vector &&new_leaves); virtual void trim_tree(const uint64_t trim_n_leaf_tuples); @@ -388,7 +388,7 @@ private: , const uint64_t& coins_generated , uint64_t num_rct_outs , const crypto::hash& block_hash - , const std::multimap& leaf_tuples_by_unlock_block + , const std::multimap& leaf_tuples_by_unlock_block ); virtual void remove_block(); @@ -449,7 +449,7 @@ private: const uint64_t child_chunk_idx, const uint64_t chunk_width) const; - std::vector get_leaf_tuples_at_unlock_block_id(uint64_t block_id); + std::vector get_leaf_tuples_at_unlock_block_id(uint64_t block_id); void del_locked_leaf_tuples_at_block_id(uint64_t block_id); diff --git a/src/blockchain_db/testdb.h b/src/blockchain_db/testdb.h index 0a643876d..d6a805d35 100644 --- a/src/blockchain_db/testdb.h +++ b/src/blockchain_db/testdb.h @@ -116,7 +116,7 @@ public: virtual void add_tx_amount_output_indices(const uint64_t tx_index, const std::vector& 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(std::vector &&new_leaves) override {}; + virtual void grow_tree(std::vector &&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; }; @@ -147,7 +147,7 @@ public: , const uint64_t& coins_generated , uint64_t num_rct_outs , const crypto::hash& blk_hash - , const std::multimap& leaf_tuples_by_unlock_block + , const std::multimap& leaf_tuples_by_unlock_block ) override { } virtual cryptonote::block get_block_from_height(const uint64_t& height) const override { return cryptonote::block(); } virtual void set_hard_fork_version(uint64_t height, uint8_t version) override {} diff --git a/src/fcmp/curve_trees.cpp b/src/fcmp/curve_trees.cpp index 90d84d871..837d2faa9 100644 --- a/src/fcmp/curve_trees.cpp +++ b/src/fcmp/curve_trees.cpp @@ -153,6 +153,7 @@ static LayerExtension hash_children_chunks(const C &curve, std::size_t chunk_start_idx = chunk_size; while (chunk_start_idx < new_child_scalars.size()) { + // TODO: this loop can be parallelized chunk_size = std::min(chunk_width, new_child_scalars.size() - chunk_start_idx); const auto chunk_start = new_child_scalars.data() + chunk_start_idx; @@ -626,7 +627,8 @@ static typename fcmp::curve_trees::LayerReduction get_next_layer_reduc // CurveTrees public member functions //---------------------------------------------------------------------------------------------------------------------- template<> -CurveTrees::LeafTuple CurveTrees::output_to_leaf_tuple( +LeafTupleContext CurveTrees::output_to_leaf_context( + const std::uint64_t output_id, const crypto::public_key &output_pubkey, const crypto::public_key &commitment) const { @@ -646,11 +648,26 @@ CurveTrees::LeafTuple CurveTrees::output_to_leaf }; // Torsion clear the output pub key and commitment - const rct::key rct_O = clear_torsion(output_pubkey, "output pub key"); - const rct::key rct_C = clear_torsion(commitment, "commitment"); + rct::key O = clear_torsion(output_pubkey, "output pub key"); + rct::key C = clear_torsion(commitment, "commitment"); - const crypto::public_key &O = rct::rct2pk(rct_O); - const crypto::public_key &C = rct::rct2pk(rct_C); + PreprocessedLeafTuple o_c{ + .O = std::move(O), + .C = std::move(C) + }; + + return LeafTupleContext{ + .output_id = output_id, + .preprocessed_leaf_tuple = std::move(o_c) + }; +}; +//---------------------------------------------------------------------------------------------------------------------- +template<> +CurveTrees::LeafTuple CurveTrees::leaf_tuple( + const PreprocessedLeafTuple &preprocessed_leaf_tuple) const +{ + const crypto::public_key &O = rct::rct2pk(preprocessed_leaf_tuple.O); + const crypto::public_key &C = rct::rct2pk(preprocessed_leaf_tuple.C); crypto::ec_point I; crypto::derive_key_image_generator(O, I); @@ -680,11 +697,11 @@ std::vector CurveTrees::flatten_leaves(const std::v }; //---------------------------------------------------------------------------------------------------------------------- template <> -void CurveTrees::tx_outs_to_leaf_tuples(const cryptonote::transaction &tx, +void CurveTrees::tx_outs_to_leaf_tuple_contexts(const cryptonote::transaction &tx, const std::vector &output_ids, const uint64_t tx_height, const bool miner_tx, - std::multimap::LeafTupleContext> &leaf_tuples_by_unlock_block_inout) const + std::multimap &leaf_tuples_by_unlock_block_inout) const { const uint64_t unlock_block = cryptonote::get_unlock_block_index(tx.unlock_time, tx_height); @@ -692,6 +709,7 @@ void CurveTrees::tx_outs_to_leaf_tuples(const cryptonote::transa for (std::size_t i = 0; i < tx.vout.size(); ++i) { + // TODO: this loop can be parallelized const auto &out = tx.vout[i]; crypto::public_key output_public_key; @@ -708,13 +726,11 @@ void CurveTrees::tx_outs_to_leaf_tuples(const cryptonote::transa ? rct::zeroCommit(out.amount) : tx.rct_signatures.outPk[i].mask; - CurveTrees::LeafTupleContext tuple_context; - tuple_context.output_id = output_ids[i]; - + LeafTupleContext leaf_tuple_context; try { - // Convert output to leaf tuple; throws if output is invalid - tuple_context.leaf_tuple = output_to_leaf_tuple( + // Convert output to leaf tuple context; throws if output is invalid + leaf_tuple_context = output_to_leaf_context(output_ids[i], output_public_key, rct::rct2pk(commitment)); } @@ -724,7 +740,7 @@ void CurveTrees::tx_outs_to_leaf_tuples(const cryptonote::transa continue; }; - leaf_tuples_by_unlock_block_inout.emplace(unlock_block, std::move(tuple_context)); + leaf_tuples_by_unlock_block_inout.emplace(unlock_block, std::move(leaf_tuple_context)); } } //---------------------------------------------------------------------------------------------------------------------- @@ -751,16 +767,25 @@ typename CurveTrees::TreeExtension CurveTrees::get_tree_extensio const auto sort_fn = [](const LeafTupleContext &a, const LeafTupleContext &b) { return a.output_id < b.output_id; }; std::sort(new_leaf_tuples.begin(), new_leaf_tuples.end(), sort_fn); - // Copy the sorted leaves into the tree extension struct - // TODO: don't copy here + // Convert sorted pre-processed tuples into leaf tuples, place each element of each leaf tuple in a flat vector to + // be hashed, and place the pre-processed tuples in tree extension struct for insertion into the db + std::vector flattened_leaves; + flattened_leaves.reserve(new_leaf_tuples.size() * LEAF_TUPLE_SIZE); tree_extension.leaves.tuples.reserve(new_leaf_tuples.size()); - for (const auto &leaf : new_leaf_tuples) + for (auto &l : new_leaf_tuples) { - tree_extension.leaves.tuples.emplace_back(LeafTuple{ - .O_x = leaf.leaf_tuple.O_x, - .I_x = leaf.leaf_tuple.I_x, - .C_x = leaf.leaf_tuple.C_x - }); + // TODO: this loop can be parallelized + auto leaf = leaf_tuple(l.preprocessed_leaf_tuple); + + flattened_leaves.emplace_back(std::move(leaf.O_x)); + flattened_leaves.emplace_back(std::move(leaf.I_x)); + flattened_leaves.emplace_back(std::move(leaf.C_x)); + + // We only need to store O and C in the db, the leaf tuple can be derived from O and C + tree_extension.leaves.tuples.emplace_back(PreprocessedLeafTuple{ + .O = std::move(l.preprocessed_leaf_tuple.O), + .C = std::move(l.preprocessed_leaf_tuple.C) + }); } if (grow_layer_instructions.need_old_last_parent) @@ -772,7 +797,7 @@ typename CurveTrees::TreeExtension CurveTrees::get_tree_extensio grow_layer_instructions.need_old_last_parent ? &existing_last_hashes.c2_last_hashes[0] : nullptr, grow_layer_instructions.start_offset, grow_layer_instructions.next_parent_start_index, - this->flatten_leaves(tree_extension.leaves.tuples), + flattened_leaves, m_leaf_layer_chunk_width ); @@ -865,6 +890,7 @@ typename CurveTrees::TreeReduction CurveTrees::get_tree_reductio { TreeReduction tree_reduction_out; + CHECK_AND_ASSERT_THROW_MES(!trim_instructions.empty(), "missing trim instructions"); CHECK_AND_ASSERT_THROW_MES((trim_instructions[0].new_total_children % LEAF_TUPLE_SIZE) == 0, "unexpected new total leaves"); const uint64_t new_total_leaf_tuples = trim_instructions[0].new_total_children / LEAF_TUPLE_SIZE; diff --git a/src/fcmp/curve_trees.h b/src/fcmp/curve_trees.h index 8218a9eda..a337481e1 100644 --- a/src/fcmp/curve_trees.h +++ b/src/fcmp/curve_trees.h @@ -128,9 +128,27 @@ struct TrimLayerInstructions final uint64_t end_trim_idx; }; +// Output pub key and commitment, ready to be converted into a leaf tuple (from {O,C} -> {O.x, I.x, C.x}) +struct PreprocessedLeafTuple final +{ + // Output pubkey that has been checked valid and torsion cleared + rct::key O; + // Commitment that has been torsion cleared + rct::key C; +}; +static_assert(sizeof(PreprocessedLeafTuple) == (32+32), "db expects 64 bytes for pre-processed leaf tuples"); + +// Contextual wrapper for a pre-processed leaf tuple +struct LeafTupleContext final +{ + // Global output ID useful to order the leaf tuple for insertion into the tree + uint64_t output_id; + PreprocessedLeafTuple preprocessed_leaf_tuple; +}; + //---------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------- -// This class is useful help update the curve trees tree without needing to keep the entire tree in memory +// This class is useful to help update the curve trees merkle tree without needing to keep the entire tree in memory // - It requires instantiation with the C1 and C2 curve classes and widths, hardening the tree structure // - It ties the C2 curve in the tree to the leaf layer template @@ -163,21 +181,13 @@ public: static const std::size_t LEAF_TUPLE_SIZE = 3; static_assert(sizeof(LeafTuple) == (sizeof(typename C2::Scalar) * LEAF_TUPLE_SIZE), "unexpected LeafTuple size"); - // Contextual wrapper for leaf tuple - struct LeafTupleContext final - { - // Global output ID useful to order the leaf tuple for insertion into the tree - uint64_t output_id; - LeafTuple leaf_tuple; - }; - // Contiguous leaves in the tree, starting a specified start_idx in the leaf layer struct Leaves final { // Starting leaf tuple index in the leaf layer - uint64_t start_leaf_tuple_idx{0}; + uint64_t start_leaf_tuple_idx{0}; // Contiguous leaves in a tree that start at the start_idx - std::vector tuples; + std::vector tuples; }; // A struct useful to extend an existing tree @@ -221,13 +231,17 @@ public: //member functions public: // Convert cryptonote output pub key and commitment to a leaf tuple for the curve trees tree - LeafTuple output_to_leaf_tuple(const crypto::public_key &output_pubkey, const crypto::public_key &C) const; + LeafTupleContext output_to_leaf_context(const std::uint64_t output_id, + const crypto::public_key &output_pubkey, + const crypto::public_key &C) const; + + LeafTuple leaf_tuple(const PreprocessedLeafTuple &preprocessed_leaf_tuple) const; // Flatten leaves [(O.x, I.x, C.x),(O.x, I.x, C.x),...] -> [scalar,scalar,scalar,scalar,scalar,scalar,...] std::vector flatten_leaves(const std::vector &leaves) const; - // Convert cryptonote tx outs to leaf tuples, grouped by the leaf tuple unlock height - void tx_outs_to_leaf_tuples(const cryptonote::transaction &tx, + // Convert cryptonote tx outs to contexts ready to be converted to leaf tuples, grouped by unlock height + void tx_outs_to_leaf_tuple_contexts(const cryptonote::transaction &tx, const std::vector &output_ids, const uint64_t tx_height, const bool miner_tx, diff --git a/tests/block_weight/block_weight.cpp b/tests/block_weight/block_weight.cpp index 30f94ddfd..81caa945d 100644 --- a/tests/block_weight/block_weight.cpp +++ b/tests/block_weight/block_weight.cpp @@ -65,7 +65,7 @@ public: , const uint64_t& coins_generated , uint64_t num_rct_outs , const crypto::hash& blk_hash - , const std::multimap& leaf_tuples_by_unlock_block + , const std::multimap& leaf_tuples_by_unlock_block ) override { blocks.push_back({block_weight, long_term_block_weight}); } diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 30e9f920f..376cdcc6a 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -88,7 +88,7 @@ namespace , const uint64_t& coins_generated , uint64_t num_rct_outs , const crypto::hash& blk_hash - , const std::multimap& leaf_tuples_by_unlock_block + , const std::multimap& leaf_tuples_by_unlock_block ) override { blocks.push_back({blk, blk_hash}); diff --git a/tests/unit_tests/curve_trees.cpp b/tests/unit_tests/curve_trees.cpp index 04bacf097..b476a33da 100644 --- a/tests/unit_tests/curve_trees.cpp +++ b/tests/unit_tests/curve_trees.cpp @@ -167,12 +167,14 @@ void CurveTreesGlobalTree::extend_tree(const CurveTreesV1::TreeExtension &tree_e "unexpected leaf start idx"); m_tree.leaves.reserve(m_tree.leaves.size() + tree_extension.leaves.tuples.size()); - for (const auto &leaf : tree_extension.leaves.tuples) + for (const auto &preprocessed_leaf_tuple : tree_extension.leaves.tuples) { + auto leaf = m_curve_trees.leaf_tuple(preprocessed_leaf_tuple); + m_tree.leaves.emplace_back(CurveTreesV1::LeafTuple{ - .O_x = leaf.O_x, - .I_x = leaf.I_x, - .C_x = leaf.C_x + .O_x = std::move(leaf.O_x), + .I_x = std::move(leaf.I_x), + .C_x = std::move(leaf.C_x) }); } @@ -587,6 +589,9 @@ bool CurveTreesGlobalTree::audit_tree(const std::size_t expected_n_leaf_tuples) //---------------------------------------------------------------------------------------------------------------------- void CurveTreesGlobalTree::log_last_hashes(const CurveTreesV1::LastHashes &last_hashes) { + if (!el::Loggers::allowed(el::Level::Debug, "serialization")) + return; + const auto &c1_last_hashes = last_hashes.c1_last_hashes; const auto &c2_last_hashes = last_hashes.c2_last_hashes; @@ -622,6 +627,9 @@ void CurveTreesGlobalTree::log_last_hashes(const CurveTreesV1::LastHashes &last_ //---------------------------------------------------------------------------------------------------------------------- void CurveTreesGlobalTree::log_tree_extension(const CurveTreesV1::TreeExtension &tree_extension) { + if (!el::Loggers::allowed(el::Level::Debug, "serialization")) + return; + const auto &c1_extensions = tree_extension.c1_layer_extensions; const auto &c2_extensions = tree_extension.c2_layer_extensions; @@ -631,7 +639,8 @@ void CurveTreesGlobalTree::log_tree_extension(const CurveTreesV1::TreeExtension MDEBUG("Leaf start idx: " << tree_extension.leaves.start_leaf_tuple_idx); for (std::size_t i = 0; i < tree_extension.leaves.tuples.size(); ++i) { - const auto &leaf = tree_extension.leaves.tuples[i]; + const auto &preprocessed_leaf_tuple = tree_extension.leaves.tuples[i]; + const auto leaf = m_curve_trees.leaf_tuple(preprocessed_leaf_tuple); const auto O_x = m_curve_trees.m_c2.to_string(leaf.O_x); const auto I_x = m_curve_trees.m_c2.to_string(leaf.I_x); @@ -679,6 +688,9 @@ void CurveTreesGlobalTree::log_tree_extension(const CurveTreesV1::TreeExtension //---------------------------------------------------------------------------------------------------------------------- void CurveTreesGlobalTree::log_tree() { + if (!el::Loggers::allowed(el::Level::Debug, "serialization")) + return; + MDEBUG("Tree has " << m_tree.leaves.size() << " leaves, " << m_tree.c1_layers.size() << " helios layers, " << m_tree.c2_layers.size() << " selene layers"); @@ -730,27 +742,26 @@ void CurveTreesGlobalTree::log_tree() //---------------------------------------------------------------------------------------------------------------------- // Test helpers //---------------------------------------------------------------------------------------------------------------------- -static const std::vector generate_random_leaves(const CurveTreesV1 &curve_trees, +static const std::vector generate_random_leaves(const CurveTreesV1 &curve_trees, const std::size_t old_n_leaf_tuples, const std::size_t new_n_leaf_tuples) { - std::vector tuples; + std::vector tuples; tuples.reserve(new_n_leaf_tuples); for (std::size_t i = 0; i < new_n_leaf_tuples; ++i) { + const std::uint64_t output_id = old_n_leaf_tuples + i; + // Generate random output tuple crypto::secret_key o,c; crypto::public_key O,C; crypto::generate_keys(O, o, o, false); crypto::generate_keys(C, c, c, false); - auto leaf_tuple = curve_trees.output_to_leaf_tuple(O, C); + auto tuple_context = curve_trees.output_to_leaf_context(output_id, O, C); - tuples.emplace_back(fcmp::curve_trees::CurveTreesV1::LeafTupleContext{ - .output_id = old_n_leaf_tuples + i, - .leaf_tuple = std::move(leaf_tuple), - }); + tuples.emplace_back(std::move(tuple_context)); } return tuples; diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp index 6061b58e2..c233af0ff 100644 --- a/tests/unit_tests/hardfork.cpp +++ b/tests/unit_tests/hardfork.cpp @@ -54,7 +54,7 @@ public: , const uint64_t& coins_generated , uint64_t num_rct_outs , const crypto::hash& blk_hash - , const std::multimap& leaf_tuples_by_unlock_block + , const std::multimap& leaf_tuples_by_unlock_block ) override { blocks.push_back(blk); } diff --git a/tests/unit_tests/long_term_block_weight.cpp b/tests/unit_tests/long_term_block_weight.cpp index d405a6325..92862372d 100644 --- a/tests/unit_tests/long_term_block_weight.cpp +++ b/tests/unit_tests/long_term_block_weight.cpp @@ -58,7 +58,7 @@ public: , const uint64_t& coins_generated , uint64_t num_rct_outs , const crypto::hash& blk_hash - , const std::multimap& leaf_tuples_by_unlock_block + , const std::multimap& leaf_tuples_by_unlock_block ) override { blocks.push_back({block_weight, long_term_block_weight}); }