Skip to content

Commit

Permalink
Merge branch 'release2'
Browse files Browse the repository at this point in the history
  • Loading branch information
sowle committed Mar 27, 2024
2 parents 7c3e2cb + 98d1248 commit 9f845bb
Show file tree
Hide file tree
Showing 41 changed files with 923 additions and 360 deletions.
12 changes: 12 additions & 0 deletions contrib/epee/include/serialization/keyvalue_helpers.h
Expand Up @@ -85,6 +85,18 @@ namespace epee
}
return res;
}

// helper for blob-to-base64 serialization
inline std::string transfrom_binbuf_to_base64(const std::string& a)
{
return epee::string_encoding::base64_encode(a);
}

inline std::string transform_base64_to_binbuf(const std::string& a)
{
return epee::string_encoding::base64_decode(a);
}

//-------------------------------------------------------------------------------------------------------------------
#pragma pack(push, 1)
template<class first_t, class second_t>
Expand Down
5 changes: 4 additions & 1 deletion contrib/epee/include/serialization/keyvalue_serialization.h
Expand Up @@ -81,6 +81,8 @@ public: \
#define KV_SERIALIZE_BLOB_AS_HEX_STRING_N(varialble, val_name) \
KV_SERIALIZE_CUSTOM_N(varialble, std::string, epee::transform_binbuf_to_hexstr, epee::transform_hexstr_to_binbuff, val_name)

#define KV_SERIALIZE_BLOB_AS_BASE64_STRING_N(varialble, val_name) \
KV_SERIALIZE_CUSTOM_N(varialble, std::string, epee::transfrom_binbuf_to_base64, epee::transform_base64_to_binbuf, val_name)

#define KV_SERIALIZE_VAL_POD_AS_BLOB_FORCE_N(varialble, val_name) \
epee::serialization::selector<is_store>::serialize_t_val_as_blob(this_ref.varialble, stg, hparent_section, val_name);
Expand All @@ -100,7 +102,8 @@ public: \
#define KV_SERIALIZE_CONTAINER_POD_AS_BLOB(varialble) KV_SERIALIZE_CONTAINER_POD_AS_BLOB_N(varialble, #varialble)
#define KV_SERIALIZE_CUSTOM(varialble, stored_type, from_v_to_stored, from_stored_to_v) KV_SERIALIZE_CUSTOM_N(varialble, stored_type, from_v_to_stored, from_stored_to_v, #varialble)
#define KV_SERIALIZE_POD_AS_HEX_STRING(varialble) KV_SERIALIZE_POD_AS_HEX_STRING_N(varialble, #varialble)
#define KV_SERIALIZE_BLOB_AS_HEX_STRING(varialble) KV_SERIALIZE_BLOB_AS_HEX_STRING_N(varialble, #varialble)
#define KV_SERIALIZE_BLOB_AS_HEX_STRING(varialble) KV_SERIALIZE_BLOB_AS_HEX_STRING_N(varialble, #varialble)
#define KV_SERIALIZE_BLOB_AS_BASE64_STRING(variable) KV_SERIALIZE_BLOB_AS_BASE64_STRING_N(variable, #variable)



Expand Down
230 changes: 85 additions & 145 deletions src/currency_core/blockchain_storage.cpp

Large diffs are not rendered by default.

15 changes: 9 additions & 6 deletions src/currency_core/blockchain_storage.h
Expand Up @@ -280,13 +280,13 @@ namespace currency
bool get_short_chain_history(std::list<crypto::hash>& ids)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0, bool need_global_indexes = false)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0, bool request_coinbase_info = false)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0)const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0)const;
//bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count)const;
bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp)const;
bool handle_get_objects(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)const;
bool get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)const;
bool get_random_outs_for_amounts2(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res)const;
bool get_random_outs_for_amounts3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res)const;
bool get_backward_blocks_sizes(size_t from_height, std::vector<size_t>& sz, size_t count)const;
bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs)const;
bool get_alias_info(const std::string& alias, extra_alias_entry_base& info)const;
Expand All @@ -299,6 +299,7 @@ namespace currency
uint64_t get_aliases_count()const;
uint64_t get_block_h_older_then(uint64_t timestamp) const;
bool validate_tx_service_attachmens_in_services(const tx_service_attachment& a, size_t i, const transaction& tx)const;
bool get_asset_history(const crypto::public_key& asset_id, std::list<asset_descriptor_operation>& result) const;
bool get_asset_info(const crypto::public_key& asset_id, asset_descriptor_base& info)const;
uint64_t get_assets_count() const;
bool check_tx_input(const transaction& tx, size_t in_index, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, uint64_t& max_related_block_height, uint64_t& source_max_unlock_time_for_pos_coinbase)const;
Expand Down Expand Up @@ -374,6 +375,8 @@ namespace currency
bool for_altchain,
const alt_chain_type& alt_chain = alt_chain_type(),
uint64_t split_height = 0)const;
bool validate_asset_operation_against_current_blochain_state(asset_op_verification_context& avc) const;

void set_core_runtime_config(const core_runtime_config& pc) const;
const core_runtime_config& get_core_runtime_config()const;
size_t get_current_sequence_factor(bool pos)const;
Expand Down Expand Up @@ -493,6 +496,7 @@ namespace currency
bool print_tx_outputs_lookup(const crypto::hash& tx_id) const;
uint64_t get_last_x_block_height(bool pos)const;
bool is_tx_spendtime_unlocked(uint64_t unlock_time)const;

private:

//-------------- DB containers --------------
Expand Down Expand Up @@ -643,8 +647,8 @@ namespace currency
bool push_transaction_to_global_outs_index(const transaction& tx, const crypto::hash& tx_id, std::vector<uint64_t>& global_indexes);
bool pop_transaction_from_global_index(const transaction& tx, const crypto::hash& tx_id);
bool add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i, uint64_t mix_count, bool use_only_forced_to_mix = false, uint64_t height_upper_limit = 0) const;
bool get_target_outs_for_amount_prezarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map<uint64_t, uint64_t>& amounts_to_up_index_limit_cache) const;
bool get_target_outs_for_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map<uint64_t, uint64_t>& amounts_to_up_index_limit_cache) const;
bool get_target_outs_for_amount_prezarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map<uint64_t, uint64_t>& amounts_to_up_index_limit_cache) const;
bool get_target_outs_for_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map<uint64_t, uint64_t>& amounts_to_up_index_limit_cache) const;
bool add_block_as_invalid(const block& bl, const crypto::hash& h);
bool add_block_as_invalid(const block_extended_info& bei, const crypto::hash& h);
size_t find_end_of_allowed_index(uint64_t amount)const;
Expand All @@ -669,7 +673,6 @@ namespace currency
bool unprocess_blockchain_tx_extra(const transaction& tx);
bool process_blockchain_tx_attachments(const transaction& tx, uint64_t h, const crypto::hash& bl_id, uint64_t timestamp);
bool unprocess_blockchain_tx_attachments(const transaction& tx, uint64_t h, uint64_t timestamp);
bool validate_ado_ownership(asset_op_verification_context& avc);
bool pop_alias_info(const extra_alias_entry& ai);
bool put_alias_info(const transaction& tx, extra_alias_entry& ai);
bool pop_asset_info(const crypto::public_key& asset_id);
Expand Down
10 changes: 3 additions & 7 deletions src/currency_core/currency_config.h
Expand Up @@ -249,13 +249,9 @@
#define BC_OFFERS_CURRENT_OFFERS_SERVICE_ARCHIVE_VER CURRENCY_FORMATION_VERSION + BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION + 9
#define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin"

#ifndef TESTNET
#define WALLET_FILE_SERIALIZATION_VERSION 163
#define WALLET_FILE_LAST_SUPPORTED_VERSION 163
#else
#define WALLET_FILE_LAST_SUPPORTED_VERSION (CURRENCY_FORMATION_VERSION+76)
#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+76)
#endif

#define WALLET_FILE_SERIALIZATION_VERSION 165
#define WALLET_FILE_LAST_SUPPORTED_VERSION 165

#define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31)

Expand Down
23 changes: 22 additions & 1 deletion src/currency_core/currency_format_utils_abstract.h
Expand Up @@ -134,7 +134,7 @@ namespace currency
//---------------------------------------------------------------
// if cb returns true, it means "continue", false -- means "stop"
template<typename specific_type_t, typename variant_container_t, typename callback_t>
bool process_type_in_variant_container(const variant_container_t& av, callback_t& cb, bool return_value_if_none_found = true)
bool process_type_in_variant_container(const variant_container_t& av, callback_t&& cb, bool return_value_if_none_found = true)
{
bool found = false;
for (auto& ai : av)
Expand All @@ -151,6 +151,27 @@ namespace currency
return return_value_if_none_found;
}
//---------------------------------------------------------------
// if cb returns false, stop immediately and return false
template<typename specific_type_t, typename variant_container_t, typename callback_t>
bool process_type_in_variant_container_and_make_sure_its_unique(const variant_container_t& av, callback_t&& cb, bool return_value_if_none_found = true)
{
bool found = false;
for (auto& ai : av)
{
if (ai.type() == typeid(specific_type_t))
{
if (found)
return false; // already have it, type in not unique
found = true;
if (!cb(boost::get<specific_type_t>(ai)))
return false;
}
}
if (found)
return true;
return return_value_if_none_found;
}
//---------------------------------------------------------------
// callback should return true to continue iterating through the container
template <typename A, typename B, typename container_t, typename callback_t>
bool handle_2_alternative_types_in_variant_container(const container_t& container, callback_t cb)
Expand Down
53 changes: 44 additions & 9 deletions src/currency_core/tx_pool.cpp
Expand Up @@ -104,6 +104,20 @@ namespace currency
//---------------------------------------------------------------------------------
bool tx_memory_pool::add_tx(const transaction &tx, const crypto::hash &id, uint64_t blob_size, tx_verification_context& tvc, bool kept_by_block, bool from_core)
{
// ------------------ UNSECURE CODE FOR TESTS ---------------------
if (m_unsecure_disable_tx_validation_on_addition)
{
uint64_t tx_fee = 0;
CHECK_AND_ASSERT_MES(get_tx_fee(tx, tx_fee), false, "get_tx_fee failed");
do_insert_transaction(tx, id, blob_size, kept_by_block, tx_fee, null_hash, 0);
tvc.m_added_to_pool = true;
tvc.m_should_be_relayed = true;
tvc.m_verification_failed = false;
tvc.m_verification_impossible = false;
return true;
}
// ---------------- END OF UNSECURE CODE FOR TESTS -------------------

bool r = false;

// defaults
Expand Down Expand Up @@ -224,6 +238,20 @@ namespace currency
}
TIME_MEASURE_FINISH_PD(check_inputs_time);

if (tx.version > TRANSACTION_VERSION_PRE_HF4)
{
TIME_MEASURE_START_PD(check_post_hf4_balance);
r = check_tx_balance(tx, id);
CHECK_AND_ASSERT_MES_CUSTOM(r, false, { tvc.m_verification_failed = true; }, "post-HF4 tx: balance proof is invalid");
TIME_MEASURE_FINISH_PD(check_post_hf4_balance);

r = process_type_in_variant_container_and_make_sure_its_unique<asset_descriptor_operation>(tx.extra, [&](const asset_descriptor_operation& ado){
asset_op_verification_context avc = { tx, id, ado };
return m_blockchain.validate_asset_operation_against_current_blochain_state(avc);
}, true);
CHECK_AND_ASSERT_MES_CUSTOM(r, false, { tvc.m_verification_failed = true; }, "post-HF4 tx: asset operation is invalid");
}

do_insert_transaction(tx, id, blob_size, kept_by_block, tx_fee, ch_inp_res ? max_used_block_id : null_hash, ch_inp_res ? max_used_block_height : 0);

TIME_MEASURE_FINISH_PD(tx_processing_time);
Expand All @@ -240,9 +268,11 @@ namespace currency
<< "/" << m_performance_data.validate_alias_time.get_last_val()
<< "/" << m_performance_data.check_keyimages_ws_ms_time.get_last_val()
<< "/" << m_performance_data.check_inputs_time.get_last_val()
<< "/b"<< m_performance_data.check_post_hf4_balance.get_last_val()
<< "/" << m_performance_data.begin_tx_time.get_last_val()
<< "/" << m_performance_data.update_db_time.get_last_val()
<< "/" << m_performance_data.db_commit_time.get_last_val() << ")" );
<< "/" << m_performance_data.db_commit_time.get_last_val()
<< ")");

return true;
}
Expand Down Expand Up @@ -875,7 +905,7 @@ namespace currency
{
//not the best implementation at this time, sorry :(

if (m_db_black_tx_list.get(get_transaction_hash(txd.tx)))
if (is_tx_blacklisted(get_transaction_hash(txd.tx)))
return false;

//check is ring_signature already checked ?
Expand Down Expand Up @@ -966,26 +996,26 @@ namespace currency
return "(no transactions, the pool is empty)";
// sort output by receive time
txs.sort([](const std::pair<crypto::hash, tx_details>& lhs, const std::pair<crypto::hash, tx_details>& rhs) -> bool { return lhs.second.receive_time < rhs.second.receive_time; });
ss << "# | transaction id | size | fee | ins | outs | outs money | live_time | max used block | last failed block | kept by a block?" << ENDL;
// 1234 f99fe6d4335fc0ddd69e6880a4d95e0f6ea398de0324a6837021a61c6a31cacd 87157 0.10000111 2000 2000 112000.12345678 d0.h10.m16.s17 123456 <12345..> 123456 <12345..> YES
ss << "# | transaction id | size | fee | ins | outs | live_time | max used block | last failed block | ver | status " << ENDL;
// 1234 f99fe6d4335fc0ddd69e6880a4d95e0f6ea398de0324a6837021a61c6a31cacd 187157 0.10000111 2000 2000 d0.h10.m16.s17 1234567 <12345..> 1234567 <12345..> 2 kept_by_block BLACKLISTED
size_t i = 0;
for (auto& tx : txs)
{
auto& txd = tx.second;
ss << std::left
<< std::setw(4) << i++ << " "
<< tx.first << " "
<< std::setw(5) << txd.blob_size << " "
<< std::setw(6) << txd.blob_size << " "
<< std::setw(10) << print_money_brief(txd.fee) << " "
<< std::setw(4) << txd.tx.vin.size() << " "
<< std::setw(4) << txd.tx.vout.size() << " "
<< std::right << std::setw(15) << print_money(get_outs_money_amount(txd.tx)) << std::left << " "
<< std::setw(14) << epee::misc_utils::get_time_interval_string(get_core_time() - txd.receive_time) << " "
<< std::setw(6) << txd.max_used_block_height << " "
<< std::setw(7) << txd.max_used_block_height << " "
<< std::setw(9) << print16(txd.max_used_block_id) << " "
<< std::setw(6) << txd.last_failed_height << " "
<< std::setw(7) << txd.last_failed_height << " "
<< std::setw(9) << print16(txd.last_failed_id) << " "
<< (txd.kept_by_block ? "YES" : "no ")
<< std::setw(3) << txd.tx.version << " "
<< (txd.kept_by_block ? "kept_by_block " : "") << (is_tx_blacklisted(tx.first) ? "BLACKLISTED " : "")
<< ENDL;
}
return ss.str();
Expand Down Expand Up @@ -1314,6 +1344,11 @@ namespace currency
}
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::is_tx_blacklisted(const crypto::hash& id) const
{
return m_db_black_tx_list.get(id) != nullptr;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::load_keyimages_cache()
{
CRITICAL_REGION_LOCAL(m_key_images_lock);
Expand Down
10 changes: 9 additions & 1 deletion src/currency_core/tx_pool.h
Expand Up @@ -77,7 +77,8 @@ namespace currency
epee::math_helper::average<uint64_t, 5> check_inputs_time;
epee::math_helper::average<uint64_t, 5> begin_tx_time;
epee::math_helper::average<uint64_t, 5> update_db_time;
epee::math_helper::average<uint64_t, 5> db_commit_time;
epee::math_helper::average<uint64_t, 5> db_commit_time;
epee::math_helper::average<uint64_t, 1> check_post_hf4_balance;
};

typedef std::unordered_map<crypto::key_image, std::set<crypto::hash>> key_image_cache;
Expand Down Expand Up @@ -140,6 +141,12 @@ namespace currency

void remove_incompatible_txs(); // made public to be called after the BCS is loaded and hardfork info is ready

bool is_tx_blacklisted(const crypto::hash& id) const;

#ifdef TX_POOL_USE_UNSECURE_TEST_FUNCTIONS
void unsecure_disable_tx_validation_on_addition(bool validation_disabled) { m_unsecure_disable_tx_validation_on_addition = validation_disabled; }
#endif

private:
bool on_tx_add(crypto::hash tx_id, const transaction& tx, bool kept_by_block);
bool on_tx_remove(const crypto::hash &tx_id, const transaction& tx, bool kept_by_block);
Expand Down Expand Up @@ -194,6 +201,7 @@ namespace currency
key_image_cache m_key_images;
mutable epee::critical_section m_remove_stuck_txs_lock;

bool m_unsecure_disable_tx_validation_on_addition = false;
};
}

Expand Down

0 comments on commit 9f845bb

Please sign in to comment.