forked from lthn/blockchain
Merge branch 'develop' into rpc_extension
This commit is contained in:
commit
0662f9bbed
21 changed files with 368 additions and 35 deletions
|
|
@ -30,5 +30,3 @@
|
|||
#define ENABLE_RELEASE_LOGGING
|
||||
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
|
||||
|
|
|
|||
13
src/common/boost_version_check.h
Normal file
13
src/common/boost_version_check.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) 2025 Zano Project
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/config.hpp> // for BOOST_LIB_VERSION
|
||||
|
||||
#if BOOST_VERSION < 107500
|
||||
# error "Boost version 1.75.0 or newer is required, detected: " BOOST_LIB_VERSION
|
||||
#endif
|
||||
|
|
@ -67,6 +67,19 @@ namespace db
|
|||
return m_config_folder + ("/" CURRENCY_BLOCKCHAINDATA_FOLDERNAME_PREFIX) + get_engine_name() + CURRENCY_BLOCKCHAINDATA_FOLDERNAME_SUFFIX;
|
||||
}
|
||||
|
||||
std::string db_backend_selector::get_db_folder_path_old_1() const
|
||||
{
|
||||
//CHECK_AND_ASSERT_THROW_MES(m_engine_type != db_none, "db_backend_selector was no inited");
|
||||
return m_config_folder + ("/" CURRENCY_BLOCKCHAINDATA_FOLDERNAME_PREFIX) + get_engine_name() + CURRENCY_BLOCKCHAINDATA_FOLDERNAME_SUFFIX_OLD_1;
|
||||
}
|
||||
|
||||
std::string db_backend_selector::get_db_folder_path_old_2() const
|
||||
{
|
||||
//CHECK_AND_ASSERT_THROW_MES(m_engine_type != db_none, "db_backend_selector was no inited");
|
||||
return m_config_folder + ("/" CURRENCY_BLOCKCHAINDATA_FOLDERNAME_PREFIX) + get_engine_name() + CURRENCY_BLOCKCHAINDATA_FOLDERNAME_SUFFIX_OLD_2;
|
||||
}
|
||||
|
||||
|
||||
std::string db_backend_selector::get_temp_db_folder_path() const
|
||||
{
|
||||
//CHECK_AND_ASSERT_THROW_MES(m_engine_type != db_none, "db_backend_selector was no inited");
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ namespace tools
|
|||
|
||||
std::shared_ptr<tools::db::i_db_backend> create_backend();
|
||||
|
||||
std::string get_db_folder_path_old_1() const;
|
||||
std::string get_db_folder_path_old_2() const;
|
||||
|
||||
private:
|
||||
db_engine_type m_engine_type;
|
||||
std::string m_config_folder;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ namespace tools
|
|||
};
|
||||
|
||||
#ifndef TESTNET
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "https://f005.backblazeb2.com/file/zano-predownload/zano_mdbx_95_3030303.pak", "937c80a2a212e70f0b5c9001159f983db72dd0cf7a6d55d72bcd9d6998874ffb", 7809031729, 12347842560 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "https://f005.backblazeb2.com/file/zano-predownload/zano_lmdb_95_3030303.pak", "227f20b3998a8622363ebd4b7189e73caac21cfc17fa8544a3fa9d593e41709d", 9450752666, 12102598656 };
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "https://f005.backblazeb2.com/file/zano-predownload/zano_mdbx_95_3083770.pak", "e7cb7b5e1560c3a7615604880feda9df37636be83264a5afff01f44b5f824cc8", 8357805798, 12884705280 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "https://f005.backblazeb2.com/file/zano-predownload/zano_lmdb_95_3083770.pak", "685db01e1a4c827d20e777563009f771be593fe80cc32b8a4dfe2711e6a2b2f8", 10070627937, 12842385408 };
|
||||
#else
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "", "", 0, 0 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "", "", 0, 0 };
|
||||
|
|
|
|||
|
|
@ -1246,7 +1246,7 @@ bool handle_pack_file(po::variables_map& vm)
|
|||
|
||||
if (do_pack)
|
||||
{
|
||||
epee::net_utils::gzip_encoder_lyambda gzip_encoder(Z_BEST_COMPRESSION);
|
||||
epee::net_utils::gzip_encoder_lyambda gzip_encoder(Z_BEST_SPEED);
|
||||
return process_archive(gzip_encoder, true, source, target);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "block_chain_shortener.h"
|
||||
#include "common/crypto_stream_operators.h"
|
||||
//#include "wallet_errors.h"
|
||||
|
||||
#define SHORTENER_EVERYBLOCK_SIZE 20
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ using namespace currency;
|
|||
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MAJOR_COMPATIBILITY_VERSION 3 //DON'T CHANGE THIS, if you need to resync db change BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION
|
||||
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MINOR_COMPATIBILITY_VERSION 4 //mismatch here means some reinitializations
|
||||
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_MAJOR_FAILURE 5 //if not blocks should ever be added with this condition
|
||||
#define BLOCKCHAIN_STORAGE_OPTIONS_ID_MOST_RECENT_HARDFORK_ID 6
|
||||
|
||||
|
||||
#define TARGETDATA_CACHE_SIZE DIFFICULTY_WINDOW + 10
|
||||
|
|
@ -95,6 +96,7 @@ blockchain_storage::blockchain_storage(tx_memory_pool& tx_pool) :m_db(nullptr, m
|
|||
m_db_storage_major_compatibility_version(BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MAJOR_COMPATIBILITY_VERSION, m_db_solo_options),
|
||||
m_db_storage_minor_compatibility_version(BLOCKCHAIN_STORAGE_OPTIONS_ID_STORAGE_MINOR_COMPATIBILITY_VERSION, m_db_solo_options),
|
||||
m_db_major_failure(BLOCKCHAIN_STORAGE_OPTIONS_ID_MAJOR_FAILURE, m_db_solo_options),
|
||||
m_db_most_recent_hardfork_id(BLOCKCHAIN_STORAGE_OPTIONS_ID_MOST_RECENT_HARDFORK_ID, m_db_solo_options),
|
||||
m_db_per_block_gindex_incs(m_db),
|
||||
m_tx_pool(tx_pool),
|
||||
m_is_in_checkpoint_zone(false),
|
||||
|
|
@ -116,6 +118,7 @@ blockchain_storage::blockchain_storage(tx_memory_pool& tx_pool) :m_db(nullptr, m
|
|||
m_services_mgr.set_core_runtime_config(m_core_runtime_config);
|
||||
m_performance_data.epic_failure_happend = false;
|
||||
}
|
||||
|
||||
blockchain_storage::~blockchain_storage()
|
||||
{
|
||||
if (!m_deinit_is_done)
|
||||
|
|
@ -217,6 +220,23 @@ void blockchain_storage::set_db_l2_cache_size(uint64_t ceched_elements) const
|
|||
m_db_assets.set_cache_size(ceched_elements);
|
||||
m_db_addr_to_alias.set_cache_size(ceched_elements);
|
||||
}
|
||||
|
||||
void remove_old_db(const std::string old_db_folder_path)
|
||||
{
|
||||
try {
|
||||
if (boost::filesystem::exists(epee::string_encoding::utf8_to_wstring(old_db_folder_path)))
|
||||
{
|
||||
LOG_PRINT_YELLOW("Removing old DB in " << old_db_folder_path << "...", LOG_LEVEL_0);
|
||||
boost::filesystem::remove_all(epee::string_encoding::utf8_to_wstring(old_db_folder_path));
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool blockchain_storage::init(const std::string& config_folder, const boost::program_options::variables_map& vm)
|
||||
{
|
||||
// CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
|
|
@ -248,12 +268,10 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro
|
|||
m_config_folder = config_folder;
|
||||
|
||||
// remove old incompatible DB
|
||||
const std::string old_db_folder_path = m_config_folder + "/" CURRENCY_BLOCKCHAINDATA_FOLDERNAME_OLD;
|
||||
if (boost::filesystem::exists(epee::string_encoding::utf8_to_wstring(old_db_folder_path)))
|
||||
{
|
||||
LOG_PRINT_YELLOW("Removing old DB in " << old_db_folder_path << "...", LOG_LEVEL_0);
|
||||
boost::filesystem::remove_all(epee::string_encoding::utf8_to_wstring(old_db_folder_path));
|
||||
}
|
||||
std::string old_db_folder_path = m_config_folder + "/" CURRENCY_BLOCKCHAINDATA_FOLDERNAME_OLD;
|
||||
remove_old_db(old_db_folder_path);
|
||||
remove_old_db(dbbs.get_db_folder_path_old_1());
|
||||
remove_old_db(dbbs.get_db_folder_path_old_2());
|
||||
|
||||
const std::string db_folder_path = dbbs.get_db_folder_path();
|
||||
LOG_PRINT_L0("Loading blockchain from " << db_folder_path);
|
||||
|
|
@ -451,7 +469,48 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro
|
|||
m_db.commit_transaction();
|
||||
LOG_PRINT_MAGENTA("migration of m_db_per_block_gindex_incs completed successfully", LOG_LEVEL_0);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef TESTNET
|
||||
// MAINNET ONLY
|
||||
if (m_db_most_recent_hardfork_id == 0)
|
||||
{
|
||||
// HF5 and the first time use: we need to check
|
||||
// to handle this case we manually check hash for the block right after HF5 activation, and if it doesn't match -- truncate the blockchain
|
||||
block blk{};
|
||||
if (get_block_by_height(ZANO_HARDFORK_05_AFTER_HEIGHT + 1, blk))
|
||||
{
|
||||
crypto::hash b3076401_id = epee::string_tools::hex_to_pod<crypto::hash>("8d93e0a7ab93b367dea44862f27ee9ca044649db84a9f44bf095d2eebc133b2d");
|
||||
crypto::hash h = get_block_hash(blk);
|
||||
if (h != b3076401_id)
|
||||
{
|
||||
LOG_PRINT_L0("In the blockchain hash for the block 3076401 is " << h << " while it is expected to be " << b3076401_id <<
|
||||
". Most likely recent blocks are alternative and invalid for the current hardfork, thus we truncate the blockchain, so that block 3076400 becomes new top block...");
|
||||
truncate_blockchain(ZANO_HARDFORK_05_AFTER_HEIGHT + 1);
|
||||
m_tx_pool.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing if there's no such block (yet)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t next_block_height = get_top_block_height() + 1;
|
||||
size_t current_hardfork_id = m_core_runtime_config.hard_forks.get_the_most_recent_hardfork_id_for_height(next_block_height); // note: current rules are effective for top_block_height+1
|
||||
if (m_db_most_recent_hardfork_id < current_hardfork_id)
|
||||
{
|
||||
// most likely we have blocks that don't meet new hardfork criteria, so we need to remove last N blocks till the hardfork height and try to resync them again
|
||||
uint64_t height_right_before_hardfork_activation = m_core_runtime_config.hard_forks.get_height_the_hardfork_active_after(current_hardfork_id);
|
||||
LOG_PRINT_L0("The most recent hardfork id in the DB is " << m_db_most_recent_hardfork_id << " while according to the code, the top block must belong to the hardfork " <<
|
||||
current_hardfork_id << ". Most likely recent blocks are alternative and invalid for the current hardfork, thus we truncate the blockchain, so that block " <<
|
||||
height_right_before_hardfork_activation << " becomes new top block...");
|
||||
truncate_blockchain(height_right_before_hardfork_activation + 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // if (m_db_blocks.size() != 0)
|
||||
|
||||
if (need_reinit)
|
||||
{
|
||||
|
|
@ -505,9 +564,10 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro
|
|||
set_lost_tx_unmixable();
|
||||
m_db.commit_transaction();
|
||||
|
||||
LOG_PRINT_GREEN("Blockchain initialized, ver: " << m_db_storage_major_compatibility_version << "." << m_db_storage_minor_compatibility_version << ", last block: " << m_db_blocks.size() - 1 << ENDL
|
||||
LOG_PRINT_GREEN("Blockchain initialized, ver: " << m_db_storage_major_compatibility_version << "." << m_db_storage_minor_compatibility_version << ENDL
|
||||
<< " genesis: " << get_block_hash(m_db_blocks[0]->bl) << ENDL
|
||||
<< " last block: " << m_db_blocks.size() - 1 << ", " << misc_utils::get_time_interval_string(timestamp_diff) << " ago" << ENDL
|
||||
<< " last hardfork id: " << m_db_most_recent_hardfork_id << ENDL
|
||||
<< " current pos difficulty: " << get_next_diff_conditional(true) << ENDL
|
||||
<< " current pow difficulty: " << get_next_diff_conditional(false) << ENDL
|
||||
<< " total transactions: " << m_db_transactions.size() << ENDL
|
||||
|
|
@ -579,6 +639,7 @@ void blockchain_storage::store_db_solo_options_values()
|
|||
m_db_storage_major_compatibility_version = BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION;
|
||||
m_db_storage_minor_compatibility_version = BLOCKCHAIN_STORAGE_MINOR_COMPATIBILITY_VERSION;
|
||||
m_db_last_worked_version = std::string(PROJECT_VERSION_LONG);
|
||||
m_db_most_recent_hardfork_id = m_core_runtime_config.hard_forks.get_the_most_recent_hardfork_id_for_height(get_top_block_height() + 1 /* <-- next block height */);
|
||||
m_db.commit_transaction();
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
|
@ -4202,7 +4263,6 @@ bool blockchain_storage::pop_asset_info(const asset_descriptor_operation& ado, c
|
|||
if (is_hardfork_active_for_height(ZANO_HARDFORK_05, height))
|
||||
{
|
||||
// NEW HF5 handling
|
||||
assets_container::t_value_type local_asset_hist = *asset_history_ptr;
|
||||
asset_descriptor_operation& last_ado = local_asset_hist.back(); // above we made sure that the history isn't empty
|
||||
CHECK_AND_ASSERT_MES(last_ado.opt_descriptor.has_value(), false, "opt_descriptor is missing during asset pop, op: " << (int)ado.operation_type);
|
||||
asset_descriptor_base& last_adb = last_ado.opt_descriptor.get();
|
||||
|
|
@ -5396,6 +5456,13 @@ void blockchain_storage::do_full_db_warm_up() const
|
|||
}
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
void blockchain_storage::on_hardfork_activated(size_t hardfork_id)
|
||||
{
|
||||
m_db.begin_transaction();
|
||||
m_db_most_recent_hardfork_id = hardfork_id;
|
||||
m_db.commit_transaction();
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::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
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
|
|
@ -7524,11 +7591,11 @@ bool blockchain_storage::add_new_block(const block& bl, block_verification_conte
|
|||
}
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::truncate_blockchain(uint64_t to_height)
|
||||
bool blockchain_storage::truncate_blockchain(uint64_t to_blockchain_size)
|
||||
{
|
||||
m_db.begin_transaction();
|
||||
uint64_t inital_height = get_current_blockchain_size();
|
||||
while (get_current_blockchain_size() > to_height)
|
||||
uint64_t inital_blockchain_size = get_current_blockchain_size();
|
||||
while (get_current_blockchain_size() > to_blockchain_size)
|
||||
{
|
||||
transactions_map ot;
|
||||
pop_block_from_blockchain(ot);
|
||||
|
|
@ -7537,7 +7604,7 @@ bool blockchain_storage::truncate_blockchain(uint64_t to_height)
|
|||
m_alternative_chains.clear();
|
||||
m_altblocks_keyimages.clear();
|
||||
m_alternative_chains_txs.clear();
|
||||
LOG_PRINT_MAGENTA("Blockchain truncated from " << inital_height << " to " << get_current_blockchain_size(), LOG_LEVEL_0);
|
||||
LOG_PRINT_MAGENTA("Blockchain truncated from size " << inital_blockchain_size << " to size " << get_current_blockchain_size() << ". Alt blocks cleared.", LOG_LEVEL_0);
|
||||
m_db.commit_transaction();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ namespace currency
|
|||
bool clear();
|
||||
bool reset_and_set_genesis_block(const block& b);
|
||||
//debug function
|
||||
bool truncate_blockchain(uint64_t to_height);
|
||||
bool truncate_blockchain(uint64_t to_blockchain_size);
|
||||
//------------- readers members -----------------
|
||||
bool pre_validate_relayed_block(block& b, block_verification_context& bvc, const crypto::hash& id)const ;
|
||||
//bool push_new_block();
|
||||
|
|
@ -515,6 +515,7 @@ namespace currency
|
|||
void set_db_l2_cache_size(uint64_t ceched_elements) const;
|
||||
//experimental
|
||||
void do_full_db_warm_up() const;
|
||||
void on_hardfork_activated(size_t hardfork_id);
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -568,6 +569,7 @@ namespace currency
|
|||
tools::db::solo_db_value<uint64_t, uint64_t, solo_options_container> m_db_storage_major_compatibility_version;
|
||||
tools::db::solo_db_value<uint64_t, uint64_t, solo_options_container> m_db_storage_minor_compatibility_version;
|
||||
tools::db::solo_db_value<uint64_t, bool, solo_options_container> m_db_major_failure; //safety fuse
|
||||
tools::db::solo_db_value<uint64_t, uint64_t, solo_options_container> m_db_most_recent_hardfork_id;
|
||||
|
||||
outputs_container m_db_outputs;
|
||||
multisig_outs_container m_db_multisig_outs;
|
||||
|
|
@ -722,7 +724,7 @@ namespace currency
|
|||
bool is_output_allowed_for_input(const txout_to_key& out_v, const txin_v& in_v) const;
|
||||
bool is_output_allowed_for_input(const txout_htlc& out_v, const txin_v& in_v, uint64_t top_minus_source_height) const;
|
||||
bool is_output_allowed_for_input(const tx_out_zarcanum& out, const txin_v& in_v) const;
|
||||
|
||||
void remove_old_dbs();
|
||||
|
||||
|
||||
//POS
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ namespace currency
|
|||
END_SERIALIZE()
|
||||
|
||||
// This is an optional data fields, It is not included in serialization and therefore is never stored in the database.
|
||||
// It might be calculated “on the fly” to speed up access operations.
|
||||
// It might be calculated "on the fly" to speed up access operations.
|
||||
mutable std::shared_ptr<crypto::hash> m_cache_coinbase_id;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,12 @@ namespace currency
|
|||
return epee::string_tools::num_to_string_fast(m_height_the_hardfork_n_active_after[hardfork_id]);
|
||||
}
|
||||
|
||||
uint64_t get_height_the_hardfork_active_after(size_t hardfork_id) const
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(hardfork_id < m_total_count, "invalid hardfork id: " << hardfork_id);
|
||||
return m_height_the_hardfork_n_active_after[hardfork_id];
|
||||
}
|
||||
|
||||
size_t get_the_most_recent_hardfork_id_for_height(uint64_t height) const
|
||||
{
|
||||
for(size_t hid = m_total_count - 1; hid != 0; --hid) // 0 is not including
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "include_base_utils.h"
|
||||
|
||||
#include "common/boost_version_check.h"
|
||||
#include "serialization/binary_archive.h"
|
||||
#include "common/crypto_serialization.h"
|
||||
#include "serialization/stl_containers.h"
|
||||
|
|
|
|||
|
|
@ -232,7 +232,11 @@
|
|||
#define CURRENCY_POOLDATA_FOLDERNAME_PREFIX "poolstate_"
|
||||
#define CURRENCY_POOLDATA_FOLDERNAME_SUFFIX "_v1"
|
||||
#define CURRENCY_BLOCKCHAINDATA_FOLDERNAME_PREFIX "blockchain_"
|
||||
#define CURRENCY_BLOCKCHAINDATA_FOLDERNAME_SUFFIX "_v2"
|
||||
#define CURRENCY_BLOCKCHAINDATA_FOLDERNAME_SUFFIX "_v3"
|
||||
|
||||
#define CURRENCY_BLOCKCHAINDATA_FOLDERNAME_SUFFIX_OLD_1 "_v1"
|
||||
#define CURRENCY_BLOCKCHAINDATA_FOLDERNAME_SUFFIX_OLD_2 "_v2"
|
||||
|
||||
|
||||
#define P2P_NET_DATA_FILENAME "p2pstate.bin"
|
||||
#define MINER_CONFIG_FILENAME "miner_conf.json"
|
||||
|
|
|
|||
|
|
@ -566,6 +566,7 @@ namespace currency
|
|||
if (hardfork_id_for_prev_block != hardfork_id_for_curr_block)
|
||||
{
|
||||
LOG_PRINT_GREEN("Hardfork " << hardfork_id_for_curr_block << " has been activated after the block at height " << h, LOG_LEVEL_0);
|
||||
m_blockchain_storage.on_hardfork_activated(hardfork_id_for_curr_block);
|
||||
m_pprotocol->on_hardfork_activated(hardfork_id_for_curr_block);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,18 +238,21 @@ namespace currency
|
|||
}
|
||||
TIME_MEASURE_FINISH_PD(check_inputs_time);
|
||||
|
||||
if (tx.version > TRANSACTION_VERSION_PRE_HF4)
|
||||
if (!from_core)
|
||||
{
|
||||
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);
|
||||
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){
|
||||
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(avc, m_blockchain.get_current_blockchain_size());
|
||||
}, true);
|
||||
CHECK_AND_ASSERT_MES_CUSTOM(r, false, { tvc.m_verification_failed = true; }, "post-HF4 tx: asset operation is invalid");
|
||||
}, 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);
|
||||
|
|
|
|||
|
|
@ -561,6 +561,7 @@ namespace currency
|
|||
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epst::pod_to_hex(get_blob_hash(block_entry.block))
|
||||
<< " wasn't requested, block_blob: " << epst::buff_to_hex_nodelimer(block_entry.block) << " dropping connection");
|
||||
m_p2p->drop_connection(context);
|
||||
m_p2p->add_ip_fail(context.m_remote_ip);
|
||||
return 1;
|
||||
}
|
||||
if(b.tx_hashes.size() != block_entry.txs.size())
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ using namespace epee;
|
|||
#define LOG_DEFAULT_CHANNEL "p2p"
|
||||
ENABLE_CHANNEL_BY_DEFAULT(LOG_DEFAULT_CHANNEL);
|
||||
|
||||
#define CURRENT_P2P_STORAGE_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+13)
|
||||
|
||||
#define CURRENT_P2P_STORAGE_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+14)
|
||||
|
||||
#define P2P_SERVER_DEFAULT_THREADS_NUM 10
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
#define PROJECT_MAJOR_VERSION "2"
|
||||
#define PROJECT_MINOR_VERSION "1"
|
||||
#define PROJECT_REVISION "1"
|
||||
#define PROJECT_REVISION "5"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 393
|
||||
#define PROJECT_VERSION_BUILD_NO 397
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
|
|
@ -1310,6 +1310,7 @@ int main(int argc, char* argv[])
|
|||
//GENERATE_AND_PLAY_HF(asset_current_and_total_supplies_comparative_constraints, "4-*"); <-- temporary disabled, waiting for Stepan's fix -- sowle
|
||||
GENERATE_AND_PLAY_HF(several_asset_emit_burn_txs_in_pool, "5-*");
|
||||
GENERATE_AND_PLAY_HF(assets_transfer_with_smallest_amount, "4-*");
|
||||
GENERATE_AND_PLAY_HF(asset_operations_and_chain_switching, "4-*");
|
||||
|
||||
GENERATE_AND_PLAY_HF(pos_fuse_test, "4-*");
|
||||
GENERATE_AND_PLAY_HF(wallet_reorganize_and_trim_test, "4-*");
|
||||
|
|
|
|||
|
|
@ -438,8 +438,6 @@ void fill_ado_version_based_onhardfork(currency::asset_descriptor_operation& ass
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
void fill_adb_version_based_onhardfork(currency::asset_descriptor_base& asset_base, size_t current_latest_hf)
|
||||
{
|
||||
if (current_latest_hf < ZANO_HARDFORK_05)
|
||||
|
|
@ -452,6 +450,8 @@ void fill_adb_version_based_onhardfork(currency::asset_descriptor_base& asset_ba
|
|||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
assets_and_explicit_native_coins_in_outs::assets_and_explicit_native_coins_in_outs()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(assets_and_explicit_native_coins_in_outs, c1_alice_cannot_deploy_asset);
|
||||
|
|
@ -2712,3 +2712,210 @@ bool assets_transfer_with_smallest_amount::c1(currency::core& c, size_t ev_index
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
asset_operations_and_chain_switching::asset_operations_and_chain_switching()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(asset_operations_and_chain_switching, c1);
|
||||
REGISTER_CALLBACK_METHOD(asset_operations_and_chain_switching, c2);
|
||||
}
|
||||
|
||||
bool asset_operations_and_chain_switching::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
//
|
||||
// Test idea: make shure asset operations are correctly handled during chain switching
|
||||
// (test intended for HF4 and later hardforks)
|
||||
//
|
||||
|
||||
bool r = false;
|
||||
uint64_t ts = test_core_time::get_time();
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts);
|
||||
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts);
|
||||
account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(); bob_acc.set_createtime(ts);
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
|
||||
// rebuild genesis miner tx
|
||||
//std::vector<tx_destination_entry> destinations;
|
||||
//destinations.emplace_back(MK_TEST_COINS(1), alice_acc.get_public_address());
|
||||
//destinations.emplace_back(MK_TEST_COINS(1), alice_acc.get_public_address());
|
||||
//CHECK_AND_ASSERT_MES(replace_coinbase_in_genesis_block(destinations, generator, events, blk_0), false, ""); // leftover amount will be also send to miner
|
||||
DO_CALLBACK(events, "configure_core"); // necessary to set m_hardforks
|
||||
|
||||
// HF4 requires tests_random_split_strategy (for 2 outputs minimum)
|
||||
test_gentime_settings tgts = generator.get_test_gentime_settings();
|
||||
tgts.split_strategy = tests_random_split_strategy;
|
||||
generator.set_test_gentime_settings(tgts);
|
||||
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
// make sure HF4 has been activated
|
||||
DO_CALLBACK_PARAMS(events, "check_hardfork_active", static_cast<size_t>(ZANO_HARDFORK_04_ZARCANUM));
|
||||
size_t current_hardfork_id = m_hardforks.get_the_most_recent_hardfork_id_for_height(get_block_height(blk_0r));
|
||||
|
||||
// transfer some coins to Alice and Bob so all their UTXO will be ZC
|
||||
MAKE_TX(events, tx_a0, miner_acc, alice_acc, MK_TEST_COINS(100), blk_0r);
|
||||
MAKE_TX(events, tx_a1, miner_acc, alice_acc, MK_TEST_COINS(100), blk_0r);
|
||||
MAKE_TX(events, tx_a2, miner_acc, bob_acc, MK_TEST_COINS(100), blk_0r);
|
||||
MAKE_TX(events, tx_a3, miner_acc, bob_acc, MK_TEST_COINS(100), blk_0r);
|
||||
MAKE_NEXT_BLOCK_TX_LIST(events, blk_1, blk_0r, miner_acc, std::list<transaction>({tx_a0, tx_a1, tx_a2, tx_a3}));
|
||||
|
||||
// add more blocks to unlock Alice and Bob's coins
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_1r, blk_1, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
// register two assets
|
||||
transaction tx_0{};
|
||||
asset_descriptor_base adb_0{};
|
||||
{
|
||||
adb_0.total_max_supply = 911;
|
||||
adb_0.full_name = "I identify as an ambulance";
|
||||
adb_0.ticker = "WEEWOO";
|
||||
adb_0.decimal_point = 0;
|
||||
asset_descriptor_operation ado{};
|
||||
fill_ado_version_based_onhardfork(ado, current_hardfork_id);
|
||||
ado.opt_descriptor = adb_0;
|
||||
fill_adb_version_based_onhardfork(*ado.opt_descriptor, current_hardfork_id);
|
||||
ado.operation_type = ASSET_DESCRIPTOR_OPERATION_REGISTER;
|
||||
if (current_hardfork_id >= ZANO_HARDFORK_05)
|
||||
ado.opt_asset_id_salt = crypto::rand<uint32_t>();
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.emplace_back(1, m_accounts[ALICE_ACC_IDX].get_public_address(), null_pkey);
|
||||
destinations.emplace_back(1, m_accounts[ALICE_ACC_IDX].get_public_address(), null_pkey);
|
||||
r = construct_tx_to_key(m_hardforks, events, tx_0, blk_1r, alice_acc, destinations, TESTS_DEFAULT_FEE, 0, 0, std::vector<attachment_v>({ado}));
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx_to_key failed");
|
||||
// get and store asset id
|
||||
r = get_type_in_variant_container(tx_0.extra, ado);
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_type_in_variant_container failed");
|
||||
r = get_or_calculate_asset_id(ado, nullptr, &m_asset_ids[0]);
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_or_calculate_asset_id failed");
|
||||
}
|
||||
ADD_CUSTOM_EVENT(events, tx_0);
|
||||
|
||||
transaction tx_1{};
|
||||
asset_descriptor_base adb_1{};
|
||||
{
|
||||
adb_1.total_max_supply = 2;
|
||||
adb_1.full_name = "I identify as invisible";
|
||||
adb_1.ticker = "WHOWHERE";
|
||||
adb_1.decimal_point = 0;
|
||||
asset_descriptor_operation ado{};
|
||||
fill_ado_version_based_onhardfork(ado, current_hardfork_id);
|
||||
ado.opt_descriptor = adb_1;
|
||||
fill_adb_version_based_onhardfork(*ado.opt_descriptor, current_hardfork_id);
|
||||
ado.operation_type = ASSET_DESCRIPTOR_OPERATION_REGISTER;
|
||||
if (current_hardfork_id >= ZANO_HARDFORK_05)
|
||||
ado.opt_asset_id_salt = crypto::rand<uint32_t>();
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.emplace_back(1, m_accounts[BOB_ACC_IDX].get_public_address(), null_pkey);
|
||||
destinations.emplace_back(1, m_accounts[BOB_ACC_IDX].get_public_address(), null_pkey);
|
||||
r = construct_tx_to_key(m_hardforks, events, tx_1, blk_1r, bob_acc, destinations, TESTS_DEFAULT_FEE, 0, 0, std::vector<attachment_v>({ado}));
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx_to_key failed");
|
||||
// get and store asset id
|
||||
r = get_type_in_variant_container(tx_1.extra, ado);
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_type_in_variant_container failed");
|
||||
r = get_or_calculate_asset_id(ado, nullptr, &m_asset_ids[1]);
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_or_calculate_asset_id failed");
|
||||
}
|
||||
ADD_CUSTOM_EVENT(events, tx_1);
|
||||
|
||||
// add both asset registering txs to a block
|
||||
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_acc, std::list<transaction>({tx_0, tx_1}));
|
||||
|
||||
// now make an alternative chain from blk_1r and switch to it -- tx_0 and tx_1 should be moved to the pool and both assets unregistered
|
||||
MAKE_NEXT_BLOCK(events, blk_2a, blk_1r, miner_acc);
|
||||
MAKE_NEXT_BLOCK(events, blk_3a, blk_2a, miner_acc);
|
||||
|
||||
// make sure chain switching occured
|
||||
DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(blk_3a));
|
||||
|
||||
// switch again (rewind blocks from blk_2)
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_2r, blk_2, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
MAKE_NEXT_BLOCK(events, blk_3, blk_2r, miner_acc);
|
||||
|
||||
// make sure we've succeeded
|
||||
DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(blk_3));
|
||||
|
||||
// check balances
|
||||
DO_CALLBACK(events, "c1");
|
||||
|
||||
// now update one asset
|
||||
transaction tx_2{};
|
||||
{
|
||||
asset_descriptor_operation ado{};
|
||||
fill_ado_version_based_onhardfork(ado, current_hardfork_id);
|
||||
ado.opt_descriptor = adb_1;
|
||||
ado.opt_descriptor->meta_info = "where is they?";
|
||||
ado.opt_descriptor->current_supply = 2;
|
||||
ado.operation_type = ASSET_DESCRIPTOR_OPERATION_UPDATE;
|
||||
ado.opt_asset_id = m_asset_ids[1];
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.emplace_back(TESTS_DEFAULT_FEE, m_accounts[BOB_ACC_IDX].get_public_address());
|
||||
r = construct_tx_to_key(m_hardforks, events, tx_2, blk_3, bob_acc, destinations, TESTS_DEFAULT_FEE, 0, 0, std::vector<attachment_v>({ado}));
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx_to_key failed");
|
||||
}
|
||||
ADD_CUSTOM_EVENT(events, tx_2);
|
||||
|
||||
// tx_3: transfer 1 WEEWOO from Alice to Bob
|
||||
//transaction tx_3{};
|
||||
//std::vector<tx_destination_entry> destinations;
|
||||
//destinations.emplace_back(1, m_accounts[BOB_ACC_IDX].get_public_address(), m_asset_ids[0]);
|
||||
//r = construct_tx_to_key(m_hardforks, events, tx_3, blk_2r, alice_acc, destinations);
|
||||
//CHECK_AND_ASSERT_MES(r, false, "construct_tx_to_key failed");
|
||||
//ADD_CUSTOM_EVENT(events, tx_2);
|
||||
|
||||
MAKE_NEXT_BLOCK_TX_LIST(events, blk_4, blk_3, miner_acc, std::list<transaction>({tx_2}));
|
||||
|
||||
// now make an alternative chain from blk_3 and switch to it -- tx_2 should be moved to the pool and update operation should be undone
|
||||
MAKE_NEXT_BLOCK(events, blk_4a, blk_3, miner_acc);
|
||||
MAKE_NEXT_BLOCK(events, blk_5a, blk_4a, miner_acc);
|
||||
|
||||
// make sure chain switching occured
|
||||
DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(blk_5a));
|
||||
|
||||
// switch again (rewind blocks from blk_4)
|
||||
REWIND_BLOCKS_N_WITH_TIME(events, blk_4r, blk_4, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
// make sure we've succeeded
|
||||
DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(blk_4r));
|
||||
|
||||
// check balances
|
||||
DO_CALLBACK(events, "c2");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asset_operations_and_chain_switching::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
bool r = false, stub = false;;
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, m_accounts[ALICE_ACC_IDX]);
|
||||
alice_wlt->refresh();
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, m_accounts[BOB_ACC_IDX]);
|
||||
bob_wlt->refresh();
|
||||
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", 2, 0, 2, 0, 0, m_asset_ids[0], 0), false, "");
|
||||
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt, "Bob", 2, 0, 2, 0, 0, m_asset_ids[1], 0), false, "");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool asset_operations_and_chain_switching::c2(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
bool r = false, stub = false;;
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, m_accounts[ALICE_ACC_IDX]);
|
||||
alice_wlt->refresh();
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, m_accounts[BOB_ACC_IDX]);
|
||||
bob_wlt->refresh();
|
||||
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", 2, 0, 2, 0, 0, m_asset_ids[0], 0), false, "");
|
||||
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt, "Bob", 2, 0, 2, 0, 0, m_asset_ids[1], 0), false, "");
|
||||
|
||||
asset_descriptor_base adb{};
|
||||
r = c.get_blockchain_storage().get_asset_info(m_asset_ids[1], adb);
|
||||
CHECK_AND_ASSERT_MES(r, false, "get_asset_info failed for id " << m_asset_ids[1]);
|
||||
|
||||
// make sure the update operation was successfull
|
||||
CHECK_AND_ASSERT_EQ(adb.meta_info, std::string("where is they?"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,3 +126,14 @@ struct assets_transfer_with_smallest_amount : public wallet_test
|
|||
|
||||
mutable uint64_t m_alice_initial_balance = 0;
|
||||
};
|
||||
|
||||
|
||||
struct asset_operations_and_chain_switching : public wallet_test
|
||||
{
|
||||
asset_operations_and_chain_switching();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool c2(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
mutable crypto::public_key m_asset_ids[4];
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue