Merge branch 'develop' into release

This commit is contained in:
sowle 2025-02-04 12:58:03 +01:00
commit 337ce00b77
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
86 changed files with 2992 additions and 424 deletions

View file

@ -81,7 +81,7 @@ namespace epee
m_run.store(false, std::memory_order_relaxed);
#if defined(WIN32)
::CloseHandle(::GetStdHandle(STD_INPUT_HANDLE));
// ::CloseHandle(::GetStdHandle(STD_INPUT_HANDLE)); -- commented out by sowle, I belive we don't need to close this handle here
#endif
m_request_cv.notify_one();

View file

@ -260,6 +260,10 @@ namespace net_utils
m_pcb.reset(new abstract_callback<callback_t>(cb));
return content_encoding_gzip::update_in(piece_of_transfer);
}
virtual void stop(std::string& OUT collect_remains) override
{}
template<class callback_t>
bool stop(callback_t cb)
{return true;}

View file

@ -200,8 +200,26 @@ namespace epee
namespace http
{
struct i_http_client
{
virtual void set_host_name(const std::string& name) = 0;
virtual boost::asio::ip::tcp::socket& get_socket() = 0;
virtual bool connect(const std::string& host, int port, unsigned int timeout) = 0;
virtual bool set_timeouts(unsigned int connection_timeout, unsigned int recv_timeout) = 0;
virtual bool connect(const std::string& host, std::string port) = 0;
virtual bool connect(const std::string& host, const std::string& port, unsigned int timeout) = 0;
virtual bool disconnect() = 0;
virtual bool is_connected() = 0;
virtual bool invoke_get(const std::string& uri, const std::string& body = std::string(), const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
virtual bool invoke(const std::string& uri, const std::string& method, const std::string& body, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
virtual bool invoke_post(const std::string& uri, const std::string& body, const http_response_info** ppresponse_info = NULL, const fields_list& additional_params = fields_list()) = 0;
};
template<bool is_ssl>
class http_simple_client_t : public i_target_handler
class http_simple_client_t : public i_target_handler,
public i_http_client
{
public:
@ -893,25 +911,90 @@ namespace epee
typedef http_simple_client_t<true> https_simple_client;
//suitable for both http and https
class http_universal_client: public i_http_client
{
public:
http_universal_client(): m_pclient(new http_simple_client())
{}
// Forward all calls to m_pclient
void set_host_name(const std::string& name) override
{
m_pclient->set_host_name(name);
}
bool connect(const std::string& host, int port, unsigned int timeout) override
{
return m_pclient->connect(host, port, timeout);
}
boost::asio::ip::tcp::socket& get_socket() override { return m_pclient->get_socket(); }
bool set_timeouts(unsigned int connection_timeout, unsigned int recv_timeout) override { return m_pclient->set_timeouts(connection_timeout, recv_timeout); }
bool connect(const std::string& host, std::string port) override { return m_pclient->connect(host, port); }
bool connect(const std::string& host, const std::string& port, unsigned int timeout) override { return m_pclient->connect(host, port, timeout); }
bool disconnect() override { return m_pclient->disconnect(); }
bool is_connected() override { return m_pclient->is_connected(); }
bool invoke_get(const std::string& uri, const std::string& body = std::string(), const http_response_info** ppresponse_info = nullptr, const fields_list& additional_params = fields_list()) override { return m_pclient->invoke_get(uri, body, ppresponse_info, additional_params); }
bool invoke(const std::string& uri, const std::string& method, const std::string& body, const http_response_info** ppresponse_info = nullptr, const fields_list& additional_params = fields_list()) override { return m_pclient->invoke(uri, method, body, ppresponse_info, additional_params); }
bool invoke_post(const std::string& uri, const std::string& body, const http_response_info** ppresponse_info = nullptr, const fields_list& additional_params = fields_list()) override { return m_pclient->invoke_post(uri, body, ppresponse_info, additional_params); }
void set_is_ssl(bool is_ssl)
{
if (m_is_ssl != is_ssl)
{
if (is_ssl)
{
m_pclient.reset(new https_simple_client());
}
else
{
m_pclient.reset(new http_simple_client());
}
m_is_ssl = is_ssl;
}
}
private:
bool m_is_ssl = false;
std::shared_ptr<i_http_client> m_pclient;
};
template<typename transport>
void configure_transport(const std::string schema, transport& tr)
{}
inline void configure_transport(const std::string schema, http_universal_client& tr)
{
if (schema == "https")
tr.set_is_ssl(true);
else
tr.set_is_ssl(false);
}
/************************************************************************/
/* */
/************************************************************************/
template<class t_transport>
bool invoke_request(const std::string& url, t_transport& tr, unsigned int timeout, const http_response_info** ppresponse_info, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list())
{
http::url_content u_c;
bool res = parse_url(url, u_c);
http::url_content u_c{};
bool r = parse_url(url, u_c);
CHECK_AND_ASSERT_MES(tr.is_connected() || u_c.host.empty() || r, false, "failed to parse url: " << url);
r = invoke_request(u_c, tr, timeout, ppresponse_info, method, body, additional_params);
return r;
}
template<class t_transport>
bool invoke_request(const http::url_content& u_c, t_transport& tr, unsigned int timeout, const http_response_info** ppresponse_info, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list())
{
if (!tr.is_connected() && !u_c.host.empty())
{
CHECK_AND_ASSERT_MES(res, false, "failed to parse url: " << url);
int port = static_cast<int>(u_c.port);
if (!port)
port = 80;//default for http
if (!u_c.port)
u_c.port = 80;//default for http
if (!tr.connect(u_c.host, static_cast<int>(u_c.port), timeout))
configure_transport(u_c.schema, tr);
if (!tr.connect(u_c.host, port, timeout))
{
LOG_PRINT_L2("invoke_request: cannot connect to " << u_c.host << ":" << u_c.port);
LOG_PRINT_L2("invoke_request: cannot connect to " << u_c.host << ":" << port);
return false;
}
}
@ -937,28 +1020,67 @@ namespace epee
}
};
class interruptible_http_client : public http_simple_client
{
std::shared_ptr<idle_handler_base> m_pcb;
bool m_permanent_error = false;
virtual bool handle_target_data(std::string& piece_of_transfer)
class http_https_simple_client_wrapper : virtual public http_simple_client, virtual public https_simple_client
{
public:
http_https_simple_client_wrapper(bool is_ssl, std::shared_ptr<idle_handler_base> ihb_cb)
: m_ssl(is_ssl)
, m_ihb_cb(ihb_cb)
{}
bool invoke_request(const http::url_content& u_c, unsigned int timeout, const http_response_info** ppresponse_info, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list())
{
bool r = m_pcb->do_call(piece_of_transfer, m_len_in_summary, m_len_in_summary - m_len_in_remain);
bool r = false;
if (m_ssl)
r = epee::net_utils::http::invoke_request(u_c, static_cast<https_simple_client&>(*this), timeout, ppresponse_info, method, body, additional_params);
else
r = epee::net_utils::http::invoke_request(u_c, static_cast<http_simple_client&>(*this), timeout, ppresponse_info, method, body, additional_params);
return r;
}
private:
// class i_target_handler
virtual bool handle_target_data(std::string& piece_of_transfer) override
{
bool r = false;
if (m_ssl)
r = m_ihb_cb->do_call(piece_of_transfer, https_simple_client::m_len_in_summary, https_simple_client::m_len_in_summary - https_simple_client::m_len_in_remain);
else
r = m_ihb_cb->do_call(piece_of_transfer, http_simple_client::m_len_in_summary, http_simple_client::m_len_in_summary - http_simple_client::m_len_in_remain);
piece_of_transfer.clear();
return r;
}
bool m_ssl;
std::shared_ptr<idle_handler_base> m_ihb_cb;
};
class interruptible_http_client
{
bool m_permanent_error = false;
public:
template<typename callback_t>
bool invoke_cb(callback_t cb, const std::string& url, uint64_t timeout, const std::string& method = "GET", const std::string& body = std::string(), const fields_list& additional_params = fields_list())
{
m_pcb.reset(new idle_handler<callback_t>(cb));
http::url_content uc{};
if (!parse_url(url, uc))
{
LOG_PRINT_L0("HTTP request to " << url << " failed because the URL couldn't be parsed.");
m_permanent_error = true;
return false;
}
bool is_ssl = uc.schema == "https";
http_https_simple_client_wrapper wrapper(is_ssl, std::make_shared<idle_handler<callback_t>>(cb));
const http_response_info* p_hri = nullptr;
bool r = invoke_request(url, *this, timeout, &p_hri, method, body, additional_params);
bool r = wrapper.invoke_request(uc, timeout, &p_hri, method, body, additional_params);
if (p_hri && !(p_hri->m_response_code >= 200 && p_hri->m_response_code < 300))
{
LOG_PRINT_L0("HTTP request to " << url << " failed with code: " << p_hri->m_response_code);
LOG_PRINT_L0(boost::to_upper_copy(uc.schema) << " request to " << url << " failed with code: " << p_hri->m_response_code);
m_permanent_error = true;
return false;
}

View file

@ -117,7 +117,7 @@ namespace epee
static bool unserialize_stl_container_t_val(stl_container& container, t_storage& stg, typename t_storage::hsection hparent_section, const char* pname)
{
container.clear();
typename stl_container::value_type exchange_val;
typename stl_container::value_type exchange_val{};
typename t_storage::harray hval_array = stg.get_first_value(pname, exchange_val, hparent_section);
if(!hval_array) return false;
container.push_back(std::move(exchange_val));

View file

@ -23,10 +23,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#include <algorithm>
namespace epee
{

@ -1 +1 @@
Subproject commit b589edb1906dccb387cfeded6ed12286c5f0405f
Subproject commit 1be2073ed3da5e9e6e94e8362548df26a22b1bd2

View file

@ -22,7 +22,7 @@ namespace tools
#ifndef TESTNET
static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_2892700.pak", "68e819cd119e4af1b81f1852e42978d662f1e6355124352f3e835db32b5a8230", 6414724487, 10468823040 };
static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_2892700.pak", "605eb4eb0903aa7b3a2a046514ef349d45c7de31d2702fd9dc104ca65705d6eb", 7860127140, 10204872704 };
static constexpr pre_download_entry c_pre_download_lmdb = { "https://f005.backblazeb2.com/file/zano-predownload/zano_lmdb_95_2892700.pak", "605eb4eb0903aa7b3a2a046514ef349d45c7de31d2702fd9dc104ca65705d6eb", 7860127140, 10204872704 };
#else
static constexpr pre_download_entry c_pre_download_mdbx = { "", "", 0, 0 };
static constexpr pre_download_entry c_pre_download_lmdb = { "", "", 0, 0 };

View file

@ -414,7 +414,7 @@ bool generate_genesis(const std::string& path_config, uint64_t premine_split_amo
std::cout << ENDL << "PROOF PHRASE: " << gcp.proof_string << ENDL;
uint64_t block_reward_without_fee = 0;
uint64_t block_reward = 0;
construct_miner_tx(0, 0, 0, 0, 0, dummy_address, dummy_address, bl.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, gcp.proof_string, CURRENCY_MINER_TX_MAX_OUTS, false, pos_entry(), nullptr, nullptr, destinations);
construct_miner_tx(0, 0, 0, 0, 0, dummy_address, dummy_address, bl.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0, gcp.proof_string, CURRENCY_MINER_TX_MAX_OUTS, false, pos_entry(), nullptr, nullptr, destinations);
currency::blobdata txb = tx_to_blob(bl.miner_tx);
//self validate block

View file

@ -81,7 +81,7 @@ namespace currency
{
blobdata bd = get_block_hashing_blob(b);
access_nonce_in_block_blob(bd) = 0;
set_nonce_to_blockblob(bd, 0);
return crypto::cn_fast_hash(bd.data(), bd.size());
}
//---------------------------------------------------------------

View file

@ -34,13 +34,17 @@ namespace currency
void get_block_longhash(const block& b, crypto::hash& res);
crypto::hash get_block_longhash(const block& b);
inline uint64_t& access_nonce_in_block_blob(blobdata& bd)
inline uint64_t get_nonce_from_blockblob(const blobdata& bd)
{
return *reinterpret_cast<uint64_t*>(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]);
uint64_t nonce = 0;
CHECK_AND_ASSERT_MES(bd.size() >= CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET + sizeof(nonce), 0, "Unexpected block buffer size = " << bd.size());
std::memcpy(&nonce, &bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET], sizeof(nonce));
return nonce;
}
inline const uint64_t& access_nonce_in_block_blob(const blobdata& bd)
inline void set_nonce_to_blockblob(blobdata& bd, const uint64_t nonce)
{
return *reinterpret_cast<const uint64_t*>(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET]);
CHECK_AND_ASSERT_MES(bd.size() >= CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET + sizeof(nonce), void(), "Unexpected block buffer size = " << bd.size());
std::memcpy(&bd[CURRENCY_MINER_BLOCK_BLOB_NONCE_OFFSET], &nonce, sizeof(nonce));
}
}

View file

@ -30,7 +30,6 @@
#include "common/boost_serialization_helper.h"
#include "warnings.h"
#include "crypto/hash.h"
#include "miner_common.h"
#include "storages/portable_storage_template_helper.h"
#include "basic_pow_helpers.h"
#include "version.h"
@ -973,6 +972,57 @@ bool blockchain_storage::get_block_by_hash(const crypto::hash &h, block &blk) c
return false;
}
//------------------------------------------------------------------
bool blockchain_storage::get_block_reward_by_main_chain_height(const uint64_t height, uint64_t& reward_with_fee) const
{
CRITICAL_REGION_LOCAL(m_read_lock);
static const boost::multiprecision::uint128_t amount_max_mp = UINT64_MAX;
if (height >= m_db_blocks.size())
return false;
boost::multiprecision::uint128_t reward_with_fee_mp{};
if (height != 0)
reward_with_fee_mp = m_db_blocks[height]->already_generated_coins - m_db_blocks[height - 1]->already_generated_coins;
else
reward_with_fee_mp = m_db_blocks[height]->already_generated_coins;
if (reward_with_fee_mp > amount_max_mp)
return false;
reward_with_fee = reward_with_fee_mp.convert_to<uint64_t>();
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::get_block_reward_by_hash(const crypto::hash &h, uint64_t& reward_with_fee) const
{
CRITICAL_REGION_LOCAL(m_read_lock);
static const boost::multiprecision::uint128_t amount_max_mp = UINT64_MAX;
block_extended_info bei{};
if (!get_block_extended_info_by_hash(h, bei))
return false;
boost::multiprecision::uint128_t reward_with_fee_mp{};
if (bei.height != 0)
{
block_extended_info bei_prev{};
if (!get_block_extended_info_by_hash(bei.bl.prev_id, bei_prev))
return false;
reward_with_fee_mp = bei.already_generated_coins - bei_prev.already_generated_coins;
}
else
{
reward_with_fee_mp = bei.already_generated_coins;
}
if (reward_with_fee_mp > amount_max_mp)
return false;
reward_with_fee = reward_with_fee_mp.convert_to<uint64_t>();
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::is_tx_related_to_altblock(crypto::hash tx_id) const
{
CRITICAL_REGION_LOCAL1(m_alternative_chains_lock);
@ -1589,6 +1639,9 @@ bool blockchain_storage::create_block_template(const create_block_template_param
resp.txs_fee = fee;
size_t tx_hardfork_id = 0;
size_t tx_version = get_tx_version_and_hardfork_id(height, m_core_runtime_config.hard_forks, tx_hardfork_id);
/*
instead of complicated two-phase template construction and adjustment of cumulative size with block reward we
use CURRENCY_COINBASE_BLOB_RESERVED_SIZE as penalty-free coinbase transaction reservation.
@ -1601,7 +1654,8 @@ bool blockchain_storage::create_block_template(const create_block_template_param
b.miner_tx,
resp.block_reward_without_fee,
resp.block_reward,
get_tx_version(height, m_core_runtime_config.hard_forks),
tx_version,
tx_hardfork_id,
ex_nonce,
CURRENCY_MINER_TX_MAX_OUTS,
pos,
@ -6080,6 +6134,7 @@ struct visitor_proxy : public boost::static_visitor<const x_type*>
bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transaction& tx, const crypto::hash& tx_id, uint64_t block_height) const
{
size_t most_recent_hardfork_id_for_height = m_core_runtime_config.hard_forks.get_the_most_recent_hardfork_id_for_height(block_height);
bool var_is_after_hardfork_1_zone = m_core_runtime_config.is_hardfork_active_for_height(1, block_height);
bool var_is_after_hardfork_2_zone = m_core_runtime_config.is_hardfork_active_for_height(2, block_height);
bool var_is_after_hardfork_3_zone = m_core_runtime_config.is_hardfork_active_for_height(3, block_height);
@ -6218,7 +6273,9 @@ bool blockchain_storage::validate_tx_for_hardfork_specific_terms(const transacti
if (var_is_after_hardfork_5_zone)
{
// additional checks here
CHECK_AND_ASSERT_MES(tx.version >= TRANSACTION_VERSION_POST_HF5, false, "HF5: tx with version " << tx.version << " is not allowed");
// starting from HF5 each tx must have hardfork_id corresponding to the current active hardfork
CHECK_AND_ASSERT_MES(tx.hardfork_id == most_recent_hardfork_id_for_height, false, "tx's hardfork_id is " << (int)tx.hardfork_id << ", but the current hardfork is " << most_recent_hardfork_id_for_height << ", rejected");
}
else
{

View file

@ -233,6 +233,8 @@ namespace currency
size_t get_alternative_blocks_count() const;
crypto::hash get_block_id_by_height(uint64_t height) const;
bool get_block_by_hash(const crypto::hash &h, block &blk) const;
bool get_block_reward_by_main_chain_height(const uint64_t height, uint64_t& reward_with_fee) const; // only for main chain blocks
bool get_block_reward_by_hash(const crypto::hash &h, uint64_t& reward_with_fee) const; // works for main chain and alt chain blocks
bool get_block_extended_info_by_height(uint64_t h, block_extended_info &blk) const;
bool get_block_extended_info_by_hash(const crypto::hash &h, block_extended_info &blk) const;
bool get_block_by_height(uint64_t h, block &blk) const;

View file

@ -1032,6 +1032,7 @@ namespace currency
{
public:
uint64_t version = 0;
uint8_t hardfork_id = 0;
std::vector<txin_v> vin;
std::vector<extra_v> extra;
std::vector<tx_out_v> vout;
@ -1044,6 +1045,8 @@ namespace currency
FIELD(vin)
FIELD(extra)
FIELD(vout)
if(version < TRANSACTION_VERSION_POST_HF5) return true;
FIELD(hardfork_id)
END_SERIALIZE()
};

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2024 Zano Project
// Copyright (c) 2014-2025 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -10,7 +10,7 @@
#ifndef TESTNET
#define CURRENCY_FORMATION_VERSION 84
#else
#define CURRENCY_FORMATION_VERSION 99
#define CURRENCY_FORMATION_VERSION 100
#endif
#define CURRENCY_GENESIS_NONCE (CURRENCY_FORMATION_VERSION + 101011010121) //bender's nightmare
@ -28,10 +28,11 @@
#define CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX 0x98c8 // auditable addresses start with 'aZx'
#define CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX 0x8a49 // auditable integrated addresses start with 'aiZX'
#define CURRENCY_MINED_MONEY_UNLOCK_WINDOW 10
#define CURRENT_TRANSACTION_VERSION 2
#define CURRENT_TRANSACTION_VERSION 3
#define TRANSACTION_VERSION_INITAL 0
#define TRANSACTION_VERSION_PRE_HF4 1
#define TRANSACTION_VERSION_POST_HF4 2
#define TRANSACTION_VERSION_POST_HF4 2
#define TRANSACTION_VERSION_POST_HF5 3
#define HF1_BLOCK_MAJOR_VERSION 1
#define HF3_BLOCK_MAJOR_VERSION 2
#define HF3_BLOCK_MINOR_VERSION 0
@ -278,9 +279,9 @@
#define ZANO_HARDFORK_02_AFTER_HEIGHT 0
#define ZANO_HARDFORK_03_AFTER_HEIGHT 0
#define ZANO_HARDFORK_04_AFTER_HEIGHT 100
#define ZANO_HARDFORK_04_TIMESTAMP_ACTUAL 1712800000ull // block 100, 2024-00-00 00:00:00 UTC
#define ZANO_HARDFORK_04_TIMESTAMP_ACTUAL 1738659600ull // block 100, 2025-00-00 00:00:00 UTC
#define ZANO_HARDFORK_05_AFTER_HEIGHT 200
#define ZANO_HARDFORK_05_MIN_BUILD_VER 356
#define ZANO_HARDFORK_05_MIN_BUILD_VER 379
#endif

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2025 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Copyright (c) 2012-2013 The Boolberry developers
@ -34,8 +34,10 @@ namespace currency
core::core(i_currency_protocol* pprotocol)
: m_mempool(m_blockchain_storage, pprotocol)
, m_blockchain_storage(m_mempool)
#ifdef CPU_MINING_ENABLED
, m_miner(this, m_blockchain_storage)
, m_miner_address(boost::value_initialized<account_public_address>())
#endif
//, m_miner_address(boost::value_initialized<account_public_address>())
, m_starter_message_showed(false)
, m_critical_error_handler(nullptr)
, m_stop_after_height(0)
@ -165,8 +167,10 @@ namespace currency
m_mempool.remove_incompatible_txs();
#ifdef CPU_MINING_ENABLED
r = m_miner.init(vm);
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize miner");
#endif
//check if tx_pool module synchronized with blockchaine storage
// if (m_blockchain_storage.get_top_block_id() != m_mempool.get_last_core_hash())
@ -193,8 +197,10 @@ namespace currency
{
//m_mempool.set_last_core_hash(m_blockchain_storage.get_top_block_id());
#ifdef CPU_MINING_ENABLED
m_miner.stop();
m_miner.deinit();
#endif
m_mempool.deinit();
m_blockchain_storage.deinit();
return true;
@ -274,7 +280,9 @@ namespace currency
//-----------------------------------------------------------------------------------------------
bool core::get_stat_info(const core_stat_info::params& pr, core_stat_info& st_inf)
{
#ifdef CPU_MINING_ENABLED
st_inf.mining_speed = m_miner.get_speed();
#endif
st_inf.alternative_blocks = m_blockchain_storage.get_alternative_blocks_count();
st_inf.blockchain_height = m_blockchain_storage.get_current_blockchain_size();
st_inf.tx_pool_size = m_mempool.get_transactions_count();
@ -405,12 +413,16 @@ namespace currency
//-----------------------------------------------------------------------------------------------
void core::pause_mine()
{
#ifdef CPU_MINING_ENABLED
m_miner.pause();
#endif
}
//-----------------------------------------------------------------------------------------------
void core::resume_mine()
{
#ifdef CPU_MINING_ENABLED
m_miner.resume();
#endif
}
//-----------------------------------------------------------------------------------------------
bool core::handle_block_found(const block& b, block_verification_context* p_verification_result, bool need_update_miner_block_template)
@ -422,10 +434,10 @@ namespace currency
if (!p_verification_result)
p_verification_result = &bvc;
m_miner.pause();
pause_mine();
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([this]()
{
m_miner.resume();
resume_mine();
});
TIME_MEASURE_START_MS(time_add_new_block_ms);
@ -520,7 +532,9 @@ namespace currency
//-----------------------------------------------------------------------------------------------
void core::on_synchronized()
{
#ifdef CPU_MINING_ENABLED
m_miner.on_synchronized();
#endif
}
bool core::get_backward_blocks_sizes(uint64_t from_height, std::vector<size_t>& sizes, size_t count)
{
@ -685,7 +699,9 @@ namespace currency
bool core::update_miner_block_template()
{
notify_blockchain_update_listeners();
#ifdef CPU_MINING_ENABLED
m_miner.on_block_chain_update();
#endif
return true;
}
//-----------------------------------------------------------------------------------------------
@ -708,7 +724,9 @@ namespace currency
m_prune_alt_blocks_interval.do_call([this](){return m_blockchain_storage.prune_aged_alt_blocks();});
m_check_free_space_interval.do_call([this](){ check_free_space(); return true; });
#ifdef CPU_MINING_ENABLED
m_miner.on_idle();
#endif
m_mempool.on_idle();
return true;
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2025 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Copyright (c) 2012-2013 The Boolberry developers
@ -57,7 +57,9 @@ namespace currency
virtual bool get_block_template(const create_block_template_params& params, create_block_template_response& resp);
bool get_block_template(block& b, const account_public_address& adr, const account_public_address& stakeholder_address, wide_difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce, bool pos = false, const pos_entry& pe = pos_entry());
#ifdef CPU_MINING_ENABLED
miner& get_miner(){ return m_miner; }
#endif
static void init_options(boost::program_options::options_description& desc);
bool init(const boost::program_options::variables_map& vm);
bool set_genesis_block(const block& b);
@ -66,7 +68,7 @@ namespace currency
uint64_t get_current_tx_version() const;
uint64_t get_top_block_height() const;
std::string get_config_folder();
bool get_blockchain_top(uint64_t& heeight, crypto::hash& top_id) const;
bool get_blockchain_top(uint64_t& height, crypto::hash& top_id) const;
bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs);
bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks);
template<class t_ids_container, class t_blocks_container, class t_missed_container>
@ -136,13 +138,15 @@ namespace currency
void check_free_space();
blockchain_storage m_blockchain_storage;
tx_memory_pool m_mempool;
blockchain_storage m_blockchain_storage;
i_currency_protocol* m_pprotocol;
i_critical_error_handler* m_critical_error_handler;
epee::critical_section m_incoming_tx_lock;
#ifdef CPU_MINING_ENABLED
miner m_miner;
account_public_address m_miner_address;
#endif
//account_public_address m_miner_address;
std::string m_config_folder;
uint64_t m_stop_after_height;
currency_protocol_stub m_protocol_stub;

View file

@ -393,6 +393,7 @@ namespace currency
uint64_t& block_reward_without_fee,
uint64_t& block_reward,
uint64_t tx_version,
size_t tx_hadrfork_id,
const blobdata& extra_nonce /* = blobdata() */,
size_t max_outs /* = CURRENCY_MINER_TX_MAX_OUTS */,
bool pos /* = false */,
@ -476,6 +477,8 @@ namespace currency
CHECK_AND_ASSERT_MES(destinations.size() <= CURRENCY_TX_MAX_ALLOWED_OUTS || height == 0, false, "Too many outs (" << destinations.size() << ")! Miner tx can't be constructed.");
// tx is not cleared intentionally to allow passing additional args in the extra/attachments
tx.version = tx_version;
if (tx.version >= TRANSACTION_VERSION_POST_HF5)
tx.hardfork_id = tx_hadrfork_id;
tx_generation_context tx_gen_context{};
tx_gen_context.set_tx_key(tx_one_time_key_to_use ? *tx_one_time_key_to_use : keypair::generate());
@ -1439,12 +1442,13 @@ namespace currency
const std::vector<attachment_v>& attachments,
transaction& tx,
uint64_t tx_version,
size_t tx_hardfork_id,
uint64_t unlock_time,
uint8_t tx_outs_attr,
bool shuffle)
{
crypto::secret_key one_time_secret_key = AUTO_VAL_INIT(one_time_secret_key);
return construct_tx(sender_account_keys, sources, destinations, std::vector<extra_v>(), attachments, tx, tx_version, one_time_secret_key, unlock_time, tx_outs_attr, shuffle);
crypto::secret_key one_time_secret_key{};
return construct_tx(sender_account_keys, sources, destinations, std::vector<extra_v>(), attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, unlock_time, tx_outs_attr, shuffle);
}
//---------------------------------------------------------------
@ -1964,6 +1968,7 @@ namespace currency
const std::vector<attachment_v>& attachments,
transaction& tx,
uint64_t tx_version,
size_t tx_hardfork_id,
crypto::secret_key& one_time_secret_key,
uint64_t unlock_time,
uint8_t tx_outs_attr,
@ -1976,7 +1981,7 @@ namespace currency
//in case if there is no real targets we use sender credentials to encrypt attachments
account_public_address crypt_destination_addr = get_crypt_address_from_destinations(sender_account_keys, destinations);
return construct_tx(sender_account_keys, sources, destinations, extra, attachments, tx, tx_version, one_time_secret_key, unlock_time,
return construct_tx(sender_account_keys, sources, destinations, extra, attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, unlock_time,
crypt_destination_addr,
0,
tx_outs_attr,
@ -1990,6 +1995,7 @@ namespace currency
const std::vector<attachment_v>& attachments,
transaction& tx,
uint64_t tx_version,
size_t tx_hardfork_id,
crypto::secret_key& one_time_secret_key,
uint64_t unlock_time,
const account_public_address& crypt_destination_addr,
@ -1999,8 +2005,9 @@ namespace currency
uint64_t flags)
{
//extra copy operation, but creating transaction is not sensitive to this
finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
finalize_tx_param ftp{};
ftp.tx_version = tx_version;
ftp.tx_hardfork_id = tx_hardfork_id;
ftp.sources = sources;
ftp.prepared_destinations = destinations;
ftp.extra = extra;
@ -2012,7 +2019,7 @@ namespace currency
ftp.shuffle = shuffle;
ftp.flags = flags;
finalized_tx ft = AUTO_VAL_INIT(ft);
finalized_tx ft{};
ft.tx = tx;
ft.one_time_key = one_time_secret_key;
bool r = construct_tx(sender_account_keys, ftp, ft);
@ -2402,6 +2409,9 @@ namespace currency
tx.signatures.clear();
tx.version = ftp.tx_version;
if (tx.version >= TRANSACTION_VERSION_POST_HF5)
tx.hardfork_id = ftp.tx_hardfork_id;
if (unlock_time != 0)
set_tx_unlock_time(tx, unlock_time);
@ -2819,15 +2829,26 @@ namespace currency
//---------------------------------------------------------------
uint64_t get_tx_version(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd)
uint64_t get_tx_version_and_hardfork_id(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd, size_t& tx_hardfork_id)
{
tx_hardfork_id = hfd.get_the_most_recent_hardfork_id_for_height(tx_expected_block_height);
if (!hfd.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, tx_expected_block_height))
{
return TRANSACTION_VERSION_PRE_HF4;
}
if (!hfd.is_hardfork_active_for_height(ZANO_HARDFORK_05, tx_expected_block_height))
{
return TRANSACTION_VERSION_POST_HF4;
}
return CURRENT_TRANSACTION_VERSION;
}
//---------------------------------------------------------------
uint64_t get_tx_version(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd)
{
[[maybe_unused]] size_t tx_hardfork_id{};
return get_tx_version_and_hardfork_id(tx_expected_block_height, hfd, tx_hardfork_id);
}
//---------------------------------------------------------------
// TODO @#@# this function is obsolete and needs to be re-written
uint64_t get_reward_from_miner_tx(const transaction& tx)
{

View file

@ -163,6 +163,7 @@ namespace currency
uint64_t expiration_time;
crypto::public_key spend_pub_key; // only for validations
uint64_t tx_version;
size_t tx_hardfork_id = 0;
uint64_t mode_separate_fee = 0;
epee::misc_utils::events_dispatcher* pevents_dispatcher = nullptr;
@ -187,6 +188,7 @@ namespace currency
FIELD(expiration_time)
FIELD(spend_pub_key)
FIELD(tx_version)
FIELD(tx_hardfork_id)
FIELD(mode_separate_fee)
if (flags & TX_FLAG_SIGNATURE_MODE_SEPARATE)
{
@ -295,6 +297,7 @@ namespace currency
uint64_t& block_reward_without_fee,
uint64_t& block_reward,
uint64_t tx_version,
size_t tx_hadrfork_id,
const blobdata& extra_nonce = blobdata(),
size_t max_outs = CURRENCY_MINER_TX_MAX_OUTS,
bool pos = false,
@ -317,9 +320,11 @@ namespace currency
const std::vector<attachment_v>& attachments,
transaction& tx,
uint64_t tx_version,
size_t tx_hardfork_id,
uint64_t unlock_time,
uint8_t tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED,
bool shuffle = true);
bool construct_tx(const account_keys& sender_account_keys,
const std::vector<tx_source_entry>& sources,
const std::vector<tx_destination_entry>& destinations,
@ -327,6 +332,7 @@ namespace currency
const std::vector<attachment_v>& attachments,
transaction& tx,
uint64_t tx_version,
size_t tx_hardfork_id,
crypto::secret_key& one_time_secret_key,
uint64_t unlock_time,
uint8_t tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED,
@ -340,6 +346,7 @@ namespace currency
const std::vector<attachment_v>& attachments,
transaction& tx,
uint64_t tx_version,
size_t tx_hardfork_id,
crypto::secret_key& one_time_secret_key,
uint64_t unlock_time,
const account_public_address& crypt_account,
@ -348,6 +355,7 @@ namespace currency
bool shuffle = true,
uint64_t flags = 0);
uint64_t get_tx_version_and_hardfork_id(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd, size_t& tx_hardfork_id); // returns tx version and tx hardfork id based on the height of the block where the transaction is expected to be
uint64_t get_tx_version(uint64_t tx_expected_block_height, const hard_forks_descriptor& hfd); // returns tx version based on the height of the block where the transaction is expected to be
bool construct_tx(const account_keys& sender_account_keys, const finalize_tx_param& param, finalized_tx& result);
bool get_or_calculate_asset_id(const asset_descriptor_operation& ado, crypto::point_t* p_result_point, crypto::public_key* p_result_pub_key);

View file

@ -31,6 +31,64 @@ using namespace epee;
namespace currency
{
#ifndef CPU_MINING_ENABLED
// CPU mining disabled
// currency::miner stub implementation
/*
miner::miner(i_miner_handler* phandler, blockchain_storage& bc)
{}
miner::~miner()
{}
bool miner::init(const boost::program_options::variables_map& vm)
{
return true;
}
bool miner::deinit()
{
return true;
}
void miner::init_options(boost::program_options::options_description& desc)
{}
bool miner::start(const account_public_address& adr, size_t threads_count)
{
return false;
}
bool miner::stop()
{
return false;
}
bool miner::is_mining()
{
return false;
}
void miner::do_print_hashrate(bool do_hr)
{}
void miner::pause()
{}
void miner::resume()
{}
bool miner::on_block_chain_update()
{
return false;
}
uint64_t miner::get_speed()
{
return 0;
}
void miner::on_synchronized()
{}
bool miner::on_idle()
{
return false;
}
// end of currency::miner stub implementation
*/
#else
namespace
{
const command_line::arg_descriptor<std::string> arg_extra_messages ("extra-messages-file", "Specify file for extra messages to include into coinbase transactions");
@ -379,5 +437,8 @@ namespace currency
return true;
}
//-----------------------------------------------------------------------------------------------------
}
#endif // #ifndef CPU_MINING_ENABLED
} // namespace currency

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2025 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Copyright (c) 2012-2013 The Boolberry developers
@ -7,6 +7,10 @@
#pragma once
#ifdef TESTNET
#define CPU_MINING_ENABLED // disable CPU mining capabilities in mainnet
#endif // #ifndef TESTNET
#include <boost/atomic.hpp>
#include <boost/program_options.hpp>
#include <atomic>
@ -30,6 +34,29 @@ namespace currency
~i_miner_handler(){};
};
inline
static bool find_nonce_for_given_block(block& bl, const wide_difficulty_type& diffic, uint64_t height)
{
bl.nonce = 0;
blobdata bd = get_block_hashing_blob(bl);
crypto::hash bd_hash = crypto::cn_fast_hash(bd.data(), bd.size());
//uint64_t& nonce_ref = access_nonce_in_block_blob(bd);
//nonce_ref = 0;
for(; bl.nonce != std::numeric_limits<uint64_t>::max(); bl.nonce++)
{
crypto::hash h = get_block_longhash(height, bd_hash, bl.nonce);
if(check_hash(h, diffic))
{
LOG_PRINT_L1("Found nonce for block: " << get_block_hash(bl) << "[" << height << "]: PoW:" << h << " (diff:" << diffic << "), ts: " << bl.timestamp);
return true;
}
}
return false;
}
#ifdef CPU_MINING_ENABLED
/************************************************************************/
/* */
/************************************************************************/
@ -54,27 +81,6 @@ namespace currency
void resume();
void do_print_hashrate(bool do_hr);
inline
static bool find_nonce_for_given_block(block& bl, const wide_difficulty_type& diffic, uint64_t height)
{
bl.nonce = 0;
blobdata bd = get_block_hashing_blob(bl);
crypto::hash bd_hash = crypto::cn_fast_hash(bd.data(), bd.size());
//uint64_t& nonce_ref = access_nonce_in_block_blob(bd);
//nonce_ref = 0;
for(; bl.nonce != std::numeric_limits<uint64_t>::max(); bl.nonce++)
{
crypto::hash h = get_block_longhash(height, bd_hash, bl.nonce);
if(check_hash(h, diffic))
{
LOG_PRINT_L1("Found nonce for block: " << get_block_hash(bl) << "[" << height << "]: PoW:" << h << " (diff:" << diffic << "), ts: " << bl.timestamp);
return true;
}
}
return false;
}
private:
bool set_block_template(const block& bl, const wide_difficulty_type& diffic, uint64_t height);
bool worker_thread();
@ -122,7 +128,7 @@ namespace currency
bool m_do_mining;
};
}
#endif // #ifdef CPU_MINING_ENABLED
} // namespace currency

View file

@ -1,8 +0,0 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Boolberry developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once

View file

@ -229,7 +229,8 @@ namespace currency
template<class t_core>
uint64_t t_currency_protocol_handler<t_core>::get_max_seen_height()
{
return m_max_height_seen;
uint64_t max_seen = m_max_height_seen;
return std::max(max_seen, m_core.get_blockchain_storage().get_top_block_height());
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>

View file

@ -126,7 +126,6 @@ int main(int argc, char* argv[])
log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0);
log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
log_space::log_singletone::enable_channels("core,currency_protocol,tx_pool,wallet", false);
LOG_PRINT_L0("Starting...");
tools::signal_handler::install_fatal([](int sig_number, void* address) {
LOG_ERROR("\n\nFATAL ERROR\nsig: " << sig_number << ", address: " << address);
@ -175,7 +174,9 @@ int main(int argc, char* argv[])
currency::core_rpc_server::init_options(desc_cmd_sett);
typedef nodetool::node_server<currency::t_currency_protocol_handler<currency::core> > p2psrv_t;
p2psrv_t::init_options(desc_cmd_sett);
#ifdef CPU_MINING_ENABLED
currency::miner::init_options(desc_cmd_sett);
#endif
bc_services::bc_offers_service::init_options(desc_cmd_sett);
currency::stratum_server::init_options(desc_cmd_sett);
tools::db::db_backend_selector::init_options(desc_cmd_sett);
@ -184,6 +185,7 @@ int main(int argc, char* argv[])
desc_options.add(desc_cmd_only).add(desc_cmd_sett);
po::variables_map vm;
bool exit_requested = false;
bool r = command_line::handle_error_helper(desc_options, [&]()
{
po::store(po::parse_command_line(argc, argv, desc_options), vm);
@ -192,7 +194,14 @@ int main(int argc, char* argv[])
{
std::cout << CURRENCY_NAME << " v" << PROJECT_VERSION_LONG << ENDL << ENDL;
std::cout << desc_options << std::endl;
return false;
exit_requested = true;
return true;
}
else if (command_line::get_arg(vm, command_line::arg_version))
{
std::cout << CURRENCY_NAME << " v" << PROJECT_VERSION_LONG << ENDL << ENDL;
exit_requested = true;
return true;
}
std::string data_dir = command_line::get_arg(vm, command_line::arg_data_dir);
@ -214,9 +223,13 @@ int main(int argc, char* argv[])
return true;
});
if (!r)
return EXIT_FAILURE;
if (exit_requested)
return EXIT_SUCCESS;
//set up logging options
std::string log_dir;
std::string log_file_name = log_space::log_singletone::get_default_log_file();
@ -238,6 +251,7 @@ int main(int argc, char* argv[])
return EXIT_SUCCESS;
}
LOG_PRINT_L0("Starting...");
// stratum server is enabled if any of its options present
bool stratum_enabled = currency::stratum_server::should_start(vm);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2018 Zano Project
// Copyright (c) 2014-2024 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -49,12 +49,14 @@ public:
m_cmd_binder.set_handler("print_tx", boost::bind(&daemon_commands_handler::print_tx, this, ph::_1), "Print transaction, print_tx <transaction_hash>");
m_cmd_binder.set_handler("print_asset_info", boost::bind(&daemon_commands_handler::print_asset_info, this, ph::_1), "Print information about the given asset by its id");
m_cmd_binder.set_handler("print_blocked_ips", boost::bind(&daemon_commands_handler::print_blocked_ips, this, ph::_1), "Print ip address blacklists");
#ifdef CPU_MINING_ENABLED
m_cmd_binder.set_handler("start_mining", boost::bind(&daemon_commands_handler::start_mining, this, ph::_1), "Start mining for specified address, start_mining <addr> [threads=1]");
m_cmd_binder.set_handler("stop_mining", boost::bind(&daemon_commands_handler::stop_mining, this, ph::_1), "Stop mining");
m_cmd_binder.set_handler("print_pool", boost::bind(&daemon_commands_handler::print_pool, this, ph::_1), "Print transaction pool (long format)");
m_cmd_binder.set_handler("print_pool_sh", boost::bind(&daemon_commands_handler::print_pool_sh, this, ph::_1), "Print transaction pool (short format)");
m_cmd_binder.set_handler("show_hr", boost::bind(&daemon_commands_handler::show_hr, this, ph::_1), "Start showing hash rate");
m_cmd_binder.set_handler("hide_hr", boost::bind(&daemon_commands_handler::hide_hr, this, ph::_1), "Stop showing hash rate");
#endif
m_cmd_binder.set_handler("print_pool", boost::bind(&daemon_commands_handler::print_pool, this, ph::_1), "Print transaction pool (long format)");
m_cmd_binder.set_handler("print_pool_sh", boost::bind(&daemon_commands_handler::print_pool_sh, this, ph::_1), "Print transaction pool (short format)");
m_cmd_binder.set_handler("save", boost::bind(&daemon_commands_handler::save, this, ph::_1), "Save blockchain");
m_cmd_binder.set_handler("print_daemon_stat", boost::bind(&daemon_commands_handler::print_daemon_stat, this, ph::_1), "Print daemon stat");
m_cmd_binder.set_handler("print_debug_stat", boost::bind(&daemon_commands_handler::print_debug_stat, this, ph::_1), "Print debug stat info");
@ -184,25 +186,6 @@ private:
return true;
}
//--------------------------------------------------------------------------------
bool show_hr(const std::vector<std::string>& args)
{
if (!m_srv.get_payload_object().get_core().get_miner().is_mining())
{
std::cout << "Mining is not started. You need start mining before you can see hash rate." << ENDL;
}
else
{
m_srv.get_payload_object().get_core().get_miner().do_print_hashrate(true);
}
return true;
}
//--------------------------------------------------------------------------------
bool hide_hr(const std::vector<std::string>& args)
{
m_srv.get_payload_object().get_core().get_miner().do_print_hashrate(false);
return true;
}
//--------------------------------------------------------------------------------
bool print_bc_outs(const std::vector<std::string>& args)
{
@ -910,7 +893,9 @@ private:
{
LOG_PRINT_L0("Pool state: " << ENDL << m_srv.get_payload_object().get_core().print_pool(true));
return true;
} //--------------------------------------------------------------------------------
}
//--------------------------------------------------------------------------------
#ifdef CPU_MINING_ENABLED
bool start_mining(const std::vector<std::string>& args)
{
if (!args.size())
@ -941,6 +926,26 @@ private:
m_srv.get_payload_object().get_core().get_miner().stop();
return true;
}
//--------------------------------------------------------------------------------
bool show_hr(const std::vector<std::string>& args)
{
if (!m_srv.get_payload_object().get_core().get_miner().is_mining())
{
std::cout << "Mining is not started. You need start mining before you can see hash rate." << ENDL;
}
else
{
m_srv.get_payload_object().get_core().get_miner().do_print_hashrate(true);
}
return true;
}
//--------------------------------------------------------------------------------
bool hide_hr(const std::vector<std::string>& args)
{
m_srv.get_payload_object().get_core().get_miner().do_print_hashrate(false);
return true;
}
#endif // #ifdef CPU_MINING_ENABLED
//--------------------------------------------------------------------------------
bool forecast_difficulty(const std::vector<std::string>& args)
{

View file

@ -959,7 +959,12 @@ bool MainWindow::init_backend(int argc, char* argv[])
QString MainWindow::is_remnotenode_mode_preconfigured(const QString& param)
{
TRY_ENTRY();
return API_RETURN_CODE_FALSE;
view::api_response ar{};
if (m_backend.is_remote_node_mode())
ar.error_code = API_RETURN_CODE_TRUE;
else
ar.error_code = API_RETURN_CODE_FALSE;
return MAKE_RESPONSE(ar);
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
}

@ -1 +1 @@
Subproject commit 7cd0e5e54a0d692ea819b9653f60a1cd5512dc2b
Subproject commit dbca694737496434ef9c7da765ee6aafd7f90158

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2022 Zano Project
// Copyright (c) 2014-2024 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -925,6 +925,7 @@ namespace currency
return call_res;
}
//------------------------------------------------------------------------------------------------------------------------------
#ifdef CPU_MINING_ENABLED
bool core_rpc_server::on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res, connection_context& cntx)
{
CHECK_CORE_READY();
@ -955,6 +956,7 @@ namespace currency
res.status = API_RETURN_CODE_OK;
return true;
}
#endif // #ifdef CPU_MINING_ENABLED
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, connection_context& cntx)
{
@ -1156,16 +1158,22 @@ namespace currency
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
uint64_t core_rpc_server::get_block_reward(const block& blk)
uint64_t core_rpc_server::get_block_reward(const block& blk, const crypto::hash& h)
{
if (blk.miner_tx.version >= TRANSACTION_VERSION_POST_HF4)
{
uint64_t reward_with_fee = 0;
m_core.get_blockchain_storage().get_block_reward_by_hash(h, reward_with_fee);
return reward_with_fee;
}
// legacy version, pre HF4
uint64_t reward = 0;
BOOST_FOREACH(const auto& out, blk.miner_tx.vout)
{
VARIANT_SWITCH_BEGIN(out);
VARIANT_CASE_CONST(tx_out_bare, out)
reward += out.amount;
VARIANT_CASE_CONST(tx_out_zarcanum, out)
//@#@
VARIANT_SWITCH_END();
}
return reward;
@ -1173,6 +1181,7 @@ namespace currency
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::fill_block_header_response(const block& blk, bool orphan_status, block_header_response& response)
{
crypto::hash block_hash = get_block_hash(blk);
response.major_version = blk.major_version;
response.minor_version = blk.minor_version;
response.timestamp = blk.timestamp;
@ -1181,9 +1190,9 @@ namespace currency
response.orphan_status = orphan_status;
response.height = get_block_height(blk);
response.depth = m_core.get_current_blockchain_size() - response.height - 1;
response.hash = string_tools::pod_to_hex(get_block_hash(blk));
response.hash = string_tools::pod_to_hex(block_hash);
response.difficulty = m_core.get_blockchain_storage().block_difficulty(response.height).convert_to<std::string>();
response.reward = get_block_reward(blk);
response.reward = get_block_reward(blk, block_hash);
return true;
}
//------------------------------------------------------------------------------------------------------------------------------

View file

@ -45,9 +45,11 @@ namespace currency
bool on_get_blocks(const COMMAND_RPC_GET_BLOCKS_FAST::request& req, COMMAND_RPC_GET_BLOCKS_FAST::response& res, connection_context& cntx);
bool on_get_transactions(const COMMAND_RPC_GET_TRANSACTIONS::request& req, COMMAND_RPC_GET_TRANSACTIONS::response& res, connection_context& cntx);
bool on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res, connection_context& cntx);
bool on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res, connection_context& cntx);
bool on_send_raw_tx(const COMMAND_RPC_SEND_RAW_TX::request& req, COMMAND_RPC_SEND_RAW_TX::response& res, connection_context& cntx);
#ifdef CPU_MINING_ENABLED
bool on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res, connection_context& cntx);
bool on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res, connection_context& cntx);
#endif
bool on_get_random_outs(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY::response& res, connection_context& cntx);
bool on_get_random_outs1(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res, connection_context& cntx);
bool on_get_random_outs3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res, connection_context& cntx);
@ -56,7 +58,7 @@ namespace currency
bool on_get_tx_pool(const COMMAND_RPC_GET_TX_POOL::request& req, COMMAND_RPC_GET_TX_POOL::response& res, connection_context& cntx);
bool on_check_keyimages(const COMMAND_RPC_CHECK_KEYIMAGES::request& req, COMMAND_RPC_CHECK_KEYIMAGES::response& res, connection_context& cntx);
bool on_rpc_get_blocks_details(const COMMAND_RPC_GET_BLOCKS_DETAILS::request& req, COMMAND_RPC_GET_BLOCKS_DETAILS::response& res, connection_context& cntx);
bool on_force_relaey_raw_txs(const COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& req, COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& res, connection_context& cntx);
bool on_force_relaey_raw_txs(const COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& req, COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& res, connection_context& cntx);
bool on_get_offers_ex(const COMMAND_RPC_GET_OFFERS_EX::request& req, COMMAND_RPC_GET_OFFERS_EX::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
@ -107,9 +109,11 @@ namespace currency
MAP_URI_AUTO_JON2("/getheight", on_get_height, COMMAND_RPC_GET_HEIGHT)
MAP_URI_AUTO_JON2("/gettransactions", on_get_transactions, COMMAND_RPC_GET_TRANSACTIONS)
MAP_URI_AUTO_JON2("/sendrawtransaction", on_send_raw_tx, COMMAND_RPC_SEND_RAW_TX)
MAP_URI_AUTO_JON2("/force_relay", on_force_relaey_raw_txs, COMMAND_RPC_FORCE_RELAY_RAW_TXS)
MAP_URI_AUTO_JON2("/force_relay", on_force_relaey_raw_txs, COMMAND_RPC_FORCE_RELAY_RAW_TXS)
#ifdef CPU_MINING_ENABLED
MAP_URI_AUTO_JON2("/start_mining", on_start_mining, COMMAND_RPC_START_MINING)
MAP_URI_AUTO_JON2("/stop_mining", on_stop_mining, COMMAND_RPC_STOP_MINING)
#endif
MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO)
// binary RPCs
MAP_URI_AUTO_BIN2("/getblocks.bin", on_get_blocks, COMMAND_RPC_GET_BLOCKS_FAST)
@ -182,7 +186,7 @@ namespace currency
bool check_core_ready_(const std::string& calling_method);
//utils
uint64_t get_block_reward(const block& blk);
uint64_t get_block_reward(const block& blk, const crypto::hash& h);
bool fill_block_header_response(const block& blk, bool orphan_status, block_header_response& response);
void set_session_blob(const std::string& session_id, const currency::block& blob);
bool get_session_blob(const std::string& session_id, currency::block& blob);

View file

@ -288,8 +288,10 @@ simple_wallet::simple_wallet()
m_refresh_progress_reporter(*this),
m_offline_mode(false)
{
#ifdef CPU_MINING_ENABLED
m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, ph::_1), "start_mining <threads_count> - Start mining in daemon");
m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, ph::_1), "Stop mining in daemon");
#endif // #ifdef CPU_MINING_ENABLED
m_cmd_binder.set_handler("refresh", boost::bind(&simple_wallet::refresh, this, ph::_1), "Resynchronize transactions and balance");
m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, ph::_1), "[raw] Show current wallet balance, with 'raw' param it displays all assets without filtering against whitelists");
m_cmd_binder.set_handler("show_staking_history", boost::bind(&simple_wallet::show_staking_history, this, ph::_1), "show_staking_history [2] - Show staking transfers, if option provided - number of days for history to display");
@ -761,6 +763,7 @@ bool simple_wallet::save(const std::vector<std::string> &args)
return true;
}
//----------------------------------------------------------------------------------------------------
#ifdef CPU_MINING_ENABLED
bool simple_wallet::start_mining(const std::vector<std::string>& args)
{
if (!try_connect_to_daemon())
@ -815,6 +818,7 @@ bool simple_wallet::stop_mining(const std::vector<std::string>& args)
fail_msg_writer() << "mining has NOT been stopped: " << err;
return true;
}
#endif // #ifdef CPU_MINING_ENABLED
//----------------------------------------------------------------------------------------------------
void simple_wallet::on_new_block(uint64_t height, const currency::block& block)
{
@ -3227,20 +3231,23 @@ int main(int argc, char* argv[])
po::options_description desc_all;
desc_all.add(desc_general).add(desc_params);
po::variables_map vm;
bool exit_requested = false;
bool r = command_line::handle_error_helper(desc_all, [&]()
{
po::store(command_line::parse_command_line(argc, argv, desc_general, true), vm);
if (command_line::get_arg(vm, command_line::arg_help))
{
success_msg_writer() << "Usage: simplewallet [--wallet-file=<file>|--generate-new-wallet=<file>] [--daemon-address=<host>:<port>] [<COMMAND>]";
success_msg_writer() << "Usage: simplewallet [--wallet-file=<file>|--generate-new[-auditable]-wallet=<file>] [--daemon-address=<host>:<port>] [<COMMAND>]";
success_msg_writer() << desc_all << '\n' << sw->get_commands_str();
return false;
exit_requested = true;
return true;
}
else if (command_line::get_arg(vm, command_line::arg_version))
{
success_msg_writer() << CURRENCY_NAME << " wallet v" << PROJECT_VERSION_LONG;
return false;
exit_requested = true;
return true;
}
auto parser = po::command_line_parser(argc, argv).options(desc_params).positional(positional_options);
@ -3248,8 +3255,13 @@ int main(int argc, char* argv[])
po::notify(vm);
return true;
});
if (!r)
return EXIT_FAILURE;
if (exit_requested)
return EXIT_SUCCESS;
//set up logging options
log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0);

View file

@ -50,8 +50,10 @@ namespace currency
bool close_wallet();
bool help(const std::vector<std::string> &args = std::vector<std::string>());
#ifdef CPU_MINING_ENABLED
bool start_mining(const std::vector<std::string> &args);
bool stop_mining(const std::vector<std::string> &args);
#endif // #ifdef CPU_MINING_ENABLED
bool refresh(const std::vector<std::string> &args);
bool show_balance(const std::vector<std::string> &args = std::vector<std::string>());
bool list_recent_transfers(const std::vector<std::string>& args);

View file

@ -402,11 +402,11 @@ namespace
#endif
m_blockchain_last_block_id = top_block_id;
m_block_template_hash_blob = get_block_hashing_blob(m_block_template);
if (access_nonce_in_block_blob(m_block_template_hash_blob) != 0)
m_block_template_hash_blob = get_block_hashing_blob(m_block_template);
if (get_nonce_from_blockblob(m_block_template_hash_blob) != 0)
{
LOG_PRINT_RED("non-zero nonce in generated block template", LOG_LEVEL_0);
access_nonce_in_block_blob(m_block_template_hash_blob) = 0;
set_nonce_to_blockblob(m_block_template_hash_blob, 0);
}
m_prev_block_template_ethash = m_block_template_ethash;
m_block_template_ethash = crypto::cn_fast_hash(m_block_template_hash_blob.data(), m_block_template_hash_blob.size());

View file

@ -4,10 +4,10 @@
#define BUILD_COMMIT_ID "@VERSION@"
#define PROJECT_MAJOR_VERSION "2"
#define PROJECT_MINOR_VERSION "0"
#define PROJECT_REVISION "1"
#define PROJECT_MINOR_VERSION "1"
#define PROJECT_REVISION "0"
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
#define PROJECT_VERSION_BUILD_NO 367
#define PROJECT_VERSION_BUILD_NO 379
#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 "]"

View file

@ -167,6 +167,15 @@ namespace tools
epee::net_utils::parse_url(m_daemon_address, u);
if (!u.port)
u.port = 8081;
if (u.schema == "https")
{
m_http_client.set_is_ssl(true);
}
else
{
m_http_client.set_is_ssl(false);
}
bool r = m_http_client.connect(u.host, std::to_string(u.port), m_connection_timeout);
if (r)
{

View file

@ -134,7 +134,7 @@ namespace tools
}
epee::critical_section m_lock;
epee::net_utils::http::http_simple_client m_http_client;
epee::net_utils::http::http_universal_client m_http_client;
std::string m_daemon_address;
unsigned int m_connection_timeout;

View file

@ -484,12 +484,14 @@ public:
bool is_online;
bool last_daemon_is_disconnected;
bool is_server_busy;
bool is_remote_node_mode;
uint64_t last_proxy_communicate_timestamp;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(is_online)
KV_SERIALIZE(is_server_busy)
KV_SERIALIZE(last_daemon_is_disconnected)
KV_SERIALIZE(is_server_busy)
KV_SERIALIZE(is_remote_node_mode)
KV_SERIALIZE(last_proxy_communicate_timestamp)
END_KV_SERIALIZE_MAP()
};

View file

@ -1162,7 +1162,7 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept
//build transaction
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
prepare_transaction(construct_param, ftp, msc);
mark_transfers_as_spent(ftp.selected_transfers, std::string("contract <") + epee::string_tools::pod_to_hex(contract_id) + "> has been accepted with tx <" + epee::string_tools::pod_to_hex(get_transaction_hash(tx)) + ">");
@ -1182,10 +1182,10 @@ void wallet2::accept_proposal(const crypto::hash& contract_id, uint64_t b_accept
*p_acceptance_tx = tx;
}
//---------------------------------------------------------------------------------
uint64_t wallet2::get_current_tx_version()
uint64_t wallet2::get_current_tx_version_and_hardfork_id(size_t& tx_hardfork_id)
{
uint64_t tx_expected_block_height = get_top_block_height() + 1;
return currency::get_tx_version(tx_expected_block_height, this->m_core_runtime_config.hard_forks);
return currency::get_tx_version_and_hardfork_id(tx_expected_block_height, this->m_core_runtime_config.hard_forks, tx_hardfork_id);
}
//---------------------------------------------------------------------------------
void wallet2::finish_contract(const crypto::hash& contract_id, const std::string& release_type, currency::transaction* p_release_tx /* = nullptr */)
@ -1299,7 +1299,7 @@ void wallet2::request_cancel_contract(const crypto::hash& contract_id, uint64_t
construct_param.split_strategy_id = get_current_split_strategy();
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
prepare_transaction(construct_param, ftp);
currency::transaction tx = AUTO_VAL_INIT(tx);
crypto::secret_key sk = AUTO_VAL_INIT(sk);
@ -2116,6 +2116,12 @@ void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop
}
else
{
//if first synchronized block in the wallet accidently became orphaned we need to force wallet to resync
if(this->m_minimum_height == height)
{
full_reset_needed = true;
}
//this should happen ONLY after block been matched, if not then is internal error
if (full_reset_needed)
{
@ -2393,7 +2399,7 @@ bool wallet2::sweep_bare_unspent_outputs(const currency::account_public_address&
currency::finalized_tx ftx{};
currency::finalize_tx_param ftp{};
ftp.pevents_dispatcher = &m_debug_events_dispatcher;
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
if (!prepare_tx_sources(decoys_count, /*use_all_decoys_if_found_less_than_required*/ true, ftp.sources, group.tids))
{
@ -3756,6 +3762,10 @@ bool wallet2::balance(std::unordered_map<crypto::public_key, wallet_public::asse
if (!td.is_zc())
m_has_bare_unspent_outputs = true;
e.outs_amount_min = (e.outs_count == 0) ? td.amount() : std::min(e.outs_amount_min, td.amount());
e.outs_amount_max = (e.outs_count == 0) ? td.amount() : std::max(e.outs_amount_max, td.amount());
e.outs_count += 1;
}
}
@ -5920,7 +5930,7 @@ void wallet2::build_escrow_release_templates(crypto::hash multisig_id,
construct_params.extra.push_back(tsa);
{
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
prepare_transaction(construct_params, ftp);
crypto::secret_key sk = AUTO_VAL_INIT(sk);
finalize_transaction(ftp, tx_release_template, sk, false);
@ -5937,7 +5947,7 @@ void wallet2::build_escrow_release_templates(crypto::hash multisig_id,
construct_params.extra.push_back(tsa);
{
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
prepare_transaction(construct_params, ftp);
crypto::secret_key sk = AUTO_VAL_INIT(sk);
finalize_transaction(ftp, tx_burn_template, sk, false);
@ -5958,7 +5968,7 @@ void wallet2::build_escrow_cancel_template(crypto::hash multisig_id,
construct_tx_param construct_params = AUTO_VAL_INIT(construct_params);
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
construct_params.fee = it->second.amount() - (ecrow_details.amount_a_pledge + ecrow_details.amount_to_pay + ecrow_details.amount_b_pledge);
construct_params.multisig_id = multisig_id;
construct_params.split_strategy_id = get_current_split_strategy();
@ -6041,7 +6051,7 @@ void wallet2::build_escrow_template(const bc_services::contract_private_details&
}
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
prepare_transaction(ctp, ftp);
selected_transfers = ftp.selected_transfers;
@ -6177,7 +6187,7 @@ void wallet2::send_escrow_proposal(const bc_services::contract_private_details&
ctp.unlock_time = unlock_time;
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
try
{
prepare_transaction(ctp, ftp);
@ -6351,7 +6361,7 @@ bool wallet2::build_ionic_swap_template(const wallet_public::ionic_swap_proposal
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.mode_separate_fee = ctp.fee;
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
prepare_transaction(ctp, ftp);
selected_transfers = ftp.selected_transfers;
@ -6580,7 +6590,7 @@ bool wallet2::accept_ionic_swap_proposal(const wallet_public::ionic_swap_proposa
//build transaction
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
ftp.gen_context = ionic_context.gen_context;
prepare_transaction(construct_param, ftp, msc);
@ -8149,7 +8159,7 @@ void wallet2::transfer(construct_tx_param& ctp,
TIME_MEASURE_START(prepare_transaction_time);
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.pevents_dispatcher = &m_debug_events_dispatcher;
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
if (!prepare_transaction(ctp, ftp))
{
result.was_not_prepared = true;
@ -8276,7 +8286,7 @@ void wallet2::sweep_below(size_t fake_outs_count, const currency::account_public
}
currency::finalize_tx_param ftp = AUTO_VAL_INIT(ftp);
ftp.tx_version = this->get_current_tx_version();
ftp.tx_version = get_current_tx_version_and_hardfork_id(ftp.tx_hardfork_id);
bool is_hf4 = this->is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM);
if (!payment_id.empty())
set_payment_id_to_tx(ftp.attachments, payment_id, is_hf4);

View file

@ -857,7 +857,7 @@ private:
bool handle_cancel_proposal(wallet_public::wallet_transfer_info& wti, const bc_services::escrow_cancel_templates_body& ectb, const std::vector<currency::payload_items_v>& decrypted_attach);
bool handle_expiration_list(uint64_t tx_expiration_ts_median);
void handle_contract_expirations(uint64_t tx_expiration_ts_median);
uint64_t get_current_tx_version();
uint64_t get_current_tx_version_and_hardfork_id(size_t& tx_hardfork_id);
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const wallet_public::wallet_transfer_info& wti) const;
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const std::string& reason = "internal intention") const;
void load_votes_config();

View file

@ -217,7 +217,7 @@ void wallet_chain_shortener::check_if_block_matched(uint64_t i, const crypto::ha
}
return;
}
if (!m_last_20_blocks.empty() && i > m_last_20_blocks.begin()->first)
if (!m_last_20_blocks.empty() && i >= m_last_20_blocks.begin()->first)
{
//must be in short sequence (m_last_20_blocks)
//self check

View file

@ -321,13 +321,21 @@ namespace wallet_public
uint64_t unlocked = 0;
uint64_t awaiting_in = 0;
uint64_t awaiting_out = 0;
uint64_t outs_count = 0;
uint64_t outs_amount_min = 0;
uint64_t outs_amount_max = 0;
//v2
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(total) DOC_DSCR("Total coins available(including locked)") DOC_EXMP(100000000000000) DOC_END
KV_SERIALIZE(unlocked) DOC_DSCR("Unlocked coins available(the ones that could be used right now)") DOC_EXMP(50000000000000) DOC_END
KV_SERIALIZE(awaiting_in) DOC_DSCR("Unconfirmed amount for receive") DOC_EXMP(1000000000000) DOC_END
KV_SERIALIZE(awaiting_out) DOC_DSCR("Unconfirmed amount for send") DOC_EXMP(2000000000000) DOC_END
KV_SERIALIZE(total) DOC_DSCR("Total coins available(including locked)") DOC_EXMP(100000000000000) DOC_END
KV_SERIALIZE(unlocked) DOC_DSCR("Unlocked coins available(the ones that could be used right now)") DOC_EXMP(50000000000000) DOC_END
KV_SERIALIZE(awaiting_in) DOC_DSCR("Unconfirmed amount for receive") DOC_EXMP(1000000000000) DOC_END
KV_SERIALIZE(awaiting_out) DOC_DSCR("Unconfirmed amount for send") DOC_EXMP(2000000000000) DOC_END
KV_SERIALIZE(outs_count) DOC_DSCR("Number of total unspent outputs (including locked)") DOC_EXMP(7) DOC_END
KV_SERIALIZE(outs_amount_min) DOC_DSCR("Output's minimum amount") DOC_EXMP(2000000000000) DOC_END
KV_SERIALIZE(outs_amount_max) DOC_DSCR("Output's maximum amount") DOC_EXMP(2000000000000) DOC_END
END_KV_SERIALIZE_MAP()
};

View file

@ -201,7 +201,9 @@ bool wallets_manager::init_command_line(int argc, char* argv[], std::string& fai
currency::core::init_options(desc_cmd_sett);
currency::core_rpc_server::init_options(desc_cmd_sett);
nodetool::node_server<currency::t_currency_protocol_handler<currency::core> >::init_options(desc_cmd_sett);
#ifdef CPU_MINING_ENABLED
currency::miner::init_options(desc_cmd_sett);
#endif
bc_services::bc_offers_service::init_options(desc_cmd_sett);
tools::db::db_backend_selector::init_options(desc_cmd_sett);
#endif
@ -1635,10 +1637,11 @@ bool wallets_manager::get_is_remote_daemon_connected()
std::string wallets_manager::get_connectivity_status()
{
view::general_connectivity_info gci = AUTO_VAL_INIT(gci);
view::general_connectivity_info gci{};
gci.is_online = get_is_remote_daemon_connected();
gci.last_daemon_is_disconnected = m_pproxy_diganostic_info->last_daemon_is_disconnected;
gci.is_server_busy = m_pproxy_diganostic_info->is_busy;
gci.is_remote_node_mode = m_remote_node_mode;
gci.last_proxy_communicate_timestamp = m_rpc_proxy->get_last_success_interract_time();
return epee::serialization::store_t_to_json(gci);
}

View file

@ -178,6 +178,7 @@ public:
std::string add_custom_asset_id(uint64_t wallet_id, const crypto::public_key& asset_id, currency::asset_descriptor_base& asset_descriptor);
std::string delete_custom_asset_id(uint64_t wallet_id, const crypto::public_key& asset_id);
bool is_core_initialized() { return m_core_initialized;}
bool is_remote_node_mode() const { return m_remote_node_mode; }
private:
void main_worker(const po::variables_map& vm);

View file

@ -381,7 +381,7 @@ bool gen_alias_tests::check_too_many_aliases_registration(currency::core& c, siz
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == total_alias_to_gen, false, "Unexpected number of txs in the pool: " << c.get_pool_transactions_count() << ", expected: " << total_alias_to_gen);
// complete block template and try to process it
r = miner::find_nonce_for_given_block(b, diff, height);
r = find_nonce_for_given_block(b, diff, height);
CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed");
currency::block_verification_context bvc = AUTO_VAL_INIT(bvc);
@ -975,7 +975,9 @@ bool gen_alias_too_much_reward::generate(std::vector<test_event_entry>& events)
d.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask;
transaction tx_0{};
crypto::secret_key sk{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<currency::extra_v>({ ai }), empty_attachment, tx_0, get_tx_version_from_events(events), sk, 0);
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id);
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<currency::extra_v>({ ai }), empty_attachment, tx_0, tx_version, tx_hardfork_id, sk, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
if (tx_0.version <= TRANSACTION_VERSION_PRE_HF4)
@ -1166,8 +1168,9 @@ bool gen_alias_too_small_reward::make_tx_reg_alias(std::vector<test_event_entry>
destinations.push_back(tx_destination_entry(sources_amount - (alias_reward + TESTS_DEFAULT_FEE), miner_acc.get_public_address())); // change
crypto::secret_key stub = AUTO_VAL_INIT(stub);
uint64_t tx_version = get_tx_version(get_block_height(prev_block), m_hardforks);
r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx, tx_version, stub, uint64_t(0));
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(prev_block), m_hardforks, tx_hardfork_id);
r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx, tx_version, tx_hardfork_id, stub, uint64_t(0));
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
PRINT_EVENT_N_TEXT(events, "make_tx_reg_alias -> construct_tx()");
events.push_back(tx);
@ -1317,7 +1320,7 @@ bool gen_alias_switch_and_check_block_template::add_block_from_template(currency
bool r = c.get_block_template(b, acc.get_public_address(), acc.get_public_address(), diff, height, extra);
CHECK_AND_ASSERT_MES(r, false, "get_block_template failed");
r = miner::find_nonce_for_given_block(b, diff, height);
r = find_nonce_for_given_block(b, diff, height);
CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed");
currency::block_verification_context bvc = AUTO_VAL_INIT(bvc);
@ -1382,8 +1385,9 @@ bool gen_alias_too_many_regs_in_block_template::generate(std::vector<test_event_
destinations.push_back(tx_destination_entry(sources_amount - total_alias_cost, preminer_acc.get_public_address())); // return the change in order to keep median_fee low
transaction tx_1 = AUTO_VAL_INIT(tx_1);
uint64_t tx_version = get_tx_version(get_block_height(blk_0r), m_hardforks);
r = construct_tx(preminer_acc.get_keys(), sources, destinations, empty_attachment, tx_1, tx_version, 0);
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_0r), m_hardforks, tx_hardfork_id);
r = construct_tx(preminer_acc.get_keys(), sources, destinations, empty_attachment, tx_1, tx_version, tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_1);
@ -1439,7 +1443,7 @@ bool gen_alias_too_many_regs_in_block_template::add_block_from_template(currency
bool r = c.get_block_template(b, acc.get_public_address(), acc.get_public_address(), diff, height, extra);
CHECK_AND_ASSERT_MES(r, false, "get_block_template failed");
r = miner::find_nonce_for_given_block(b, diff, height);
r = find_nonce_for_given_block(b, diff, height);
CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed");
currency::block_verification_context bvc = AUTO_VAL_INIT(bvc);
@ -1494,9 +1498,10 @@ bool gen_alias_update_for_free::generate(std::vector<test_event_entry>& events)
}
transaction tx{};
uint64_t tx_version = currency::get_tx_version(get_block_height(blk_0r) + 1, generator.get_hardforks());
size_t tx_hardfork_id{};
uint64_t tx_version = currency::get_tx_version_and_hardfork_id(get_block_height(blk_0r) + 1, generator.get_hardforks(), tx_hardfork_id);
crypto::secret_key sk{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<extra_v>({ ai }), empty_attachment, tx, tx_version, sk, 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<extra_v>({ ai }), empty_attachment, tx, tx_version, tx_hardfork_id, sk, 0);
/*tx_builder tb;
tb.step1_init();

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2023 Zano Project
// Copyright (c) 2014-2025 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -321,10 +321,9 @@ bool gen_block_miner_tx_has_2_in::generate(std::vector<test_event_entry>& events
destinations.push_back(de);
transaction tmp_tx;
std::vector<currency::attachment_v> attachments;
uint64_t tx_version = get_tx_version(get_block_height(blk_0r), m_hardforks);
if (!construct_tx(miner_account.get_keys(), sources, destinations, attachments, tmp_tx, tx_version, 0))
if (!construct_tx(miner_account.get_keys(), sources, destinations, empty_extra, empty_attachment, tmp_tx, tx_version))
return false;
MAKE_MINER_TX_MANUALLY(miner_tx, blk_0);
@ -369,9 +368,8 @@ bool gen_block_miner_tx_with_txin_to_key::generate(std::vector<test_event_entry>
destinations.push_back(de);
transaction tmp_tx = AUTO_VAL_INIT(tmp_tx);
std::vector<currency::attachment_v> attachments;
uint64_t tx_version = get_tx_version(get_block_height(blk_1r), m_hardforks);
if (!construct_tx(miner_account.get_keys(), sources, destinations, attachments, tmp_tx, tx_version, 0))
if (!construct_tx(miner_account.get_keys(), sources, destinations, empty_extra, empty_attachment, tmp_tx, tx_version))
return false;
MAKE_MINER_TX_MANUALLY(miner_tx, blk_1);
@ -692,4 +690,515 @@ bool gen_block_wrong_version_agains_hardfork::generate(std::vector<test_event_en
BLOCK_VALIDATION_INIT_GENERATE();
DO_CALLBACK(events, "c1");
return true;
}
}
block_with_correct_prev_id_on_wrong_height::block_with_correct_prev_id_on_wrong_height()
{
REGISTER_CALLBACK_METHOD(block_with_correct_prev_id_on_wrong_height, assert_blk_2_has_wrong_height);
}
bool block_with_correct_prev_id_on_wrong_height::generate(std::vector<test_event_entry>& events) const
{
// Test idea: make sure that a block with correct previous block identifier that is at the wrong height won't be accepted by the core.
GENERATE_ACCOUNT(miner);
MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time());
DO_CALLBACK(events, "configure_core");
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
MAKE_TX(events, tx_0, miner, miner, MK_TEST_COINS(2), blk_0r);
MAKE_NEXT_BLOCK(events, blk_1, blk_0r, miner);
block blk_2{};
blk_2.prev_id = currency::get_block_hash(blk_1);
blk_2.miner_tx = blk_0r.miner_tx;
blk_2.major_version = blk_0r.major_version;
CHECK_AND_ASSERT_EQ(currency::get_block_height(blk_1), 11);
CHECK_AND_ASSERT_EQ(currency::get_block_height(blk_2), 10);
// blk_1 is the previous for blk_2, but height(blk_2) < height(blk_1).
DO_CALLBACK_PARAMS_STR(events, "assert_blk_2_has_wrong_height", t_serializable_object_to_blob(blk_2));
return true;
}
bool block_with_correct_prev_id_on_wrong_height::assert_blk_2_has_wrong_height(currency::core& c, [[maybe_unused]] size_t ev_index, [[maybe_unused]] const std::vector<test_event_entry>& events) const
{
block blk_2{};
{
const auto serialized_block{boost::get<callback_entry>(events.at(ev_index)).callback_params};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(blk_2, serialized_block), true);
}
{
currency::block_verification_context context_blk_2{};
CHECK_AND_ASSERT_EQ(boost::get<txin_gen>(blk_2.miner_tx.vin.front()).height, 10);
// Make sure, that it's impossible to insert blk_2.
CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().add_new_block(blk_2, context_blk_2), false);
}
return true;
}
struct block_reward_in_main_chain_basic::argument_assert
{
uint64_t m_height{}, m_balance{};
std::list<uint64_t> m_rewards{};
argument_assert() = default;
template<typename test>
argument_assert(const test* instance, uint64_t height, const std::list<uint64_t>& blk_tx_fees = {}, const argument_assert previous = {}) : m_height{height}
{
CHECK_AND_ASSERT_THROW(instance, std::runtime_error{"Pointer to an instance of the test equals to the nullptr."});
CHECK_AND_ASSERT_THROW(m_height >= previous.m_height, std::runtime_error{"A height specified in the previous argument is greather than current height."});
if (height == 0)
{
m_rewards.push_back(PREMINE_AMOUNT);
m_balance = m_rewards.back();
}
else
{
m_balance = previous.m_balance;
for (auto fee_iterator{blk_tx_fees.rbegin()}; fee_iterator != blk_tx_fees.rend(); ++fee_iterator)
{
if (height != 0)
{
m_rewards.push_back(COIN);
if (const auto& fee{*fee_iterator}; fee <= m_rewards.back())
{
if (instance->m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, height))
{
m_rewards.back() -= fee;
}
}
m_balance += m_rewards.back();
}
else
{
m_balance += PREMINE_AMOUNT;
}
--height;
}
}
CHECK_AND_ASSERT_THROW(m_rewards.size() > 0, std::runtime_error{"A list of the rewards is empty."});
}
BEGIN_SERIALIZE()
FIELD(m_height)
FIELD(m_balance)
FIELD(m_rewards)
END_SERIALIZE()
};
block_reward_in_main_chain_basic::block_reward_in_main_chain_basic()
{
REGISTER_CALLBACK_METHOD(block_reward_in_main_chain_basic, assert_balance);
REGISTER_CALLBACK_METHOD(block_reward_in_main_chain_basic, assert_reward);
}
bool block_reward_in_main_chain_basic::generate(std::vector<test_event_entry>& events) const
{
// The test idea: make sure that receiving rewards for block insertion is counted correctly.
const auto assert_balance{[&events](const argument_assert& argument) -> void
{
DO_CALLBACK_PARAMS_STR(events, "assert_balance", t_serializable_object_to_blob(argument));
}
};
const auto assert_reward{[&events](const argument_assert& argument) -> void
{
DO_CALLBACK_PARAMS_STR(events, "assert_reward", t_serializable_object_to_blob(argument));
}
};
GENERATE_ACCOUNT(miner);
MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time());
argument_assert argument{this, get_block_height(blk_0)};
m_accounts.push_back(miner);
assert_reward(argument);
// Make sure the balance equals to the PREMINE_AMOUNT.
assert_balance(argument);
DO_CALLBACK(events, "configure_core");
MAKE_NEXT_BLOCK(events, blk_1, blk_0, miner);
argument = argument_assert{this, get_block_height(blk_1), {0}, argument};
assert_balance(argument);
assert_reward(argument);
REWIND_BLOCKS_N(events, blk_1r, blk_1, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW - 1);
argument = argument_assert{this, get_block_height(blk_1r), std::list<uint64_t>(CURRENCY_MINED_MONEY_UNLOCK_WINDOW - 1), argument};
assert_balance(argument);
assert_reward(argument);
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(1), TESTS_DEFAULT_FEE, blk_1r);
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner, tx_0);
argument = {this, get_block_height(blk_2), {TESTS_DEFAULT_FEE}, argument};
assert_reward(argument);
// Make sure in the balance change in the case of a transaction with the default fee.
assert_balance(argument);
MAKE_TX_FEE(events, tx_1, miner, miner, MK_TEST_COINS(3), 2 * TESTS_DEFAULT_FEE, blk_2);
MAKE_TX_FEE(events, tx_2, miner, miner, MK_TEST_COINS(2), 3 * TESTS_DEFAULT_FEE, blk_2);
const std::list txs{tx_1, tx_2};
MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2, miner, txs);
argument = argument_assert{this, get_block_height(blk_3), {(2 + 3) * TESTS_DEFAULT_FEE}, argument};
assert_reward(argument);
// A case of one inserted block with a several transactions with a non default fees.
assert_balance(argument);
MAKE_TX_FEE(events, tx_3, miner, miner, MK_TEST_COINS(1), COIN + TESTS_DEFAULT_FEE, blk_3);
MAKE_NEXT_BLOCK(events, blk_4, blk_3, miner);
argument = argument_assert{this, get_block_height(blk_4), {COIN + TESTS_DEFAULT_FEE}, argument};
assert_reward(argument);
// A transaction inside blk_4 has a fee greater than a block reward. blk_4 includes only one transaction.
assert_balance(argument);
MAKE_TX_FEE(events, tx_4, miner, miner, MK_TEST_COINS(1), 76 * COIN + 14 * TESTS_DEFAULT_FEE, blk_4);
MAKE_NEXT_BLOCK(events, blk_5, blk_4, miner);
argument = argument_assert{this, get_block_height(blk_5), {76 * COIN + 14 * TESTS_DEFAULT_FEE}, argument};
assert_reward(argument);
// A transaction inside blk_5 has a fee greater than a block reward. blk_5 includes only one transaction.
assert_balance(argument);
REWIND_BLOCKS_N(events, blk_5r, blk_5, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
argument = argument_assert{this, get_block_height(blk_5r), std::list<uint64_t>(CURRENCY_MINED_MONEY_UNLOCK_WINDOW), argument};
assert_reward(argument);
assert_balance(argument);
return true;
}
bool block_reward_in_main_chain_basic::assert_balance(currency::core& core, size_t event_index, const std::vector<test_event_entry>& events) const
{
argument_assert argument{};
{
const auto serialized_argument{boost::get<callback_entry>(events.at(event_index)).callback_params};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(argument, serialized_argument), true);
}
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_top_block_height(), argument.m_height);
const auto wallet{init_playtime_test_wallet(events, core, m_accounts.front())};
CHECK_AND_ASSERT(wallet, false);
wallet->refresh();
CHECK_AND_ASSERT_EQ(wallet->balance(), argument.m_balance);
return true;
}
bool block_reward_in_main_chain_basic::assert_reward(currency::core& core, size_t event_index, const std::vector<test_event_entry>& events) const
{
argument_assert argument{};
{
const auto serialized_argument{boost::get<callback_entry>(events.at(event_index)).callback_params};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(argument, serialized_argument), true);
}
for (const auto expected_reward : argument.m_rewards)
{
uint64_t reward{};
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_block_reward_by_main_chain_height(argument.m_height, reward), true);
CHECK_AND_ASSERT_EQ(reward, expected_reward);
--argument.m_height;
}
return true;
}
struct block_reward_in_alt_chain_basic::argument_assert
{
uint64_t m_height{}, m_balance{};
crypto::hash blk_id{};
std::list<uint64_t> m_rewards{};
argument_assert() = default;
template<typename test>
argument_assert(const test* instance, const block& block, const std::list<uint64_t>& blk_tx_fees = {}, const argument_assert previous = {}) : blk_id{get_block_hash(block)}
{
CHECK_AND_ASSERT_THROW(instance, std::runtime_error{"Pointer to an instance of the test equals to the nullptr."});
auto height{get_block_height(block)};
m_height = height;
if (height == 0)
{
m_rewards.push_back(PREMINE_AMOUNT);
m_balance = m_rewards.back();
return;
}
m_balance = previous.m_balance;
for (auto fee_iterator{blk_tx_fees.rbegin()}; fee_iterator != blk_tx_fees.rend(); ++fee_iterator)
{
if (height != 0)
{
m_rewards.push_back(COIN);
if (const auto& fee{*fee_iterator}; fee <= m_rewards.back())
{
if (instance->m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, height))
{
m_rewards.back() -= fee;
}
}
m_balance += m_rewards.back();
}
else
{
m_balance += PREMINE_AMOUNT;
}
--height;
}
CHECK_AND_ASSERT_THROW(m_rewards.size() > 0, std::runtime_error{"A list of the rewards is empty."});
}
BEGIN_SERIALIZE()
FIELD(m_height)
FIELD(m_balance)
FIELD(m_rewards)
FIELD(blk_id)
END_SERIALIZE()
};
block_reward_in_alt_chain_basic::block_reward_in_alt_chain_basic()
{
REGISTER_CALLBACK_METHOD(block_reward_in_alt_chain_basic, assert_balance);
REGISTER_CALLBACK_METHOD(block_reward_in_alt_chain_basic, assert_reward);
}
bool block_reward_in_alt_chain_basic::generate(std::vector<test_event_entry>& events) const
{
// The test idea: make sure that receiving rewards for block insertion is counted correctly.
const auto assert_balance{[&events](const argument_assert& argument) -> void
{
DO_CALLBACK_PARAMS_STR(events, "assert_balance", t_serializable_object_to_blob(argument));
}
};
const auto assert_reward{[&events](const argument_assert& argument) -> void
{
DO_CALLBACK_PARAMS_STR(events, "assert_reward", t_serializable_object_to_blob(argument));
}
};
GENERATE_ACCOUNT(miner);
MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time());
argument_assert argument{this, blk_0}, argument_alt{};
/* 0
(blk_0) */
m_accounts.push_back(miner);
// Make sure a reward for the blk_0 equals to PREMINE_AMOUNT.
assert_reward(argument);
// Make sure the balance equals to the PREMINE_AMOUNT.
assert_balance(argument);
DO_CALLBACK(events, "configure_core");
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
/* 0 10
(blk_0) - ... - (blk_0r) */
// A case of a 10 sequentally inserted empty sblocks.
argument_alt = argument = argument_assert{this, blk_0r, std::list<uint64_t>(CURRENCY_MINED_MONEY_UNLOCK_WINDOW), argument};
// Miner inserted 10 empty blocks. A sum of the rewards for them equals to 10 coins.
assert_reward(argument);
// Make sure the balance equals to PREMINE_AMOUNT + 10 * COIN.
assert_balance(argument);
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(1), TESTS_DEFAULT_FEE, blk_0r);
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner, tx_0);
/* 0 10 11
(blk_0) - ... - (blk_0r) - (blk_1)
{tx_0} */
MAKE_TX_FEE(events, tx_1, miner, miner, MK_TEST_COINS(1), 33 * TESTS_DEFAULT_FEE, blk_0r);
MAKE_NEXT_BLOCK_TX1(events, blk_1a, blk_0r, miner, tx_1);
/* 0 10 11
(blk_0) - ... - (blk_0r) - (blk_1a)
| {tx_1}
|
\ 11
- (blk_1)
{tx_0}
height(blk_1a) = height(blk_1)
fee(tx_1) > fee(tx_0). */
CHECK_AND_ASSERT_EQ(get_block_height(blk_1), get_block_height(blk_1a));
// Case of an alt block on the height 11 with greater total fee than total fee of blk_1 - the top of the main chain.
argument_alt = argument_assert{this, blk_1a, {33 * TESTS_DEFAULT_FEE}, argument_alt};
argument = argument_assert{this, blk_1, {TESTS_DEFAULT_FEE}, argument};
if (m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, get_block_height(blk_1)))
{
// Make sure that a reward for blk_1 equals to COIN.
assert_reward(argument_alt);
// Make sure that the balance equals to PREMINE_AMOUNT + 11 * COIN - 33 * TESTS_DEFAULT_FEE.
assert_balance(argument_alt);
}
else
{
// Make sure that a reward for blk_1a equals to COIN.
assert_reward(argument);
// Make sure that the balance equals to PREMINE_AMOUNT + 11 * COIN.
assert_balance(argument);
}
MAKE_TX_FEE(events, tx_2, miner, miner, MK_TEST_COINS(1), 8 * TESTS_DEFAULT_FEE, blk_1);
MAKE_TX_FEE(events, tx_3, miner, miner, MK_TEST_COINS(1), 57 * TESTS_DEFAULT_FEE, blk_1);
const std::list txs_0{tx_2, tx_3};
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1, miner, txs_0);
/* 0 10 11 12
(blk_0) - ... - (blk_0r) - (blk_1) - (blk_2)
| {tx_0} {tx_2, tx_3}
|
\ 11
- (blk_1a)
{tx_1}
height(blk_2) > height(blk_1a). */
// A case of block on the height 12 in the main chain.
argument = argument_assert{this, blk_2, {(8 + 57) * TESTS_DEFAULT_FEE}, argument};
// A reward of blk_2 equals to coin.
assert_reward(argument);
/* HF3: The balance equals to PREMINE_AMOUNT + 12 * COIN.
HF4: The balance equals to PREMINE_AMOUNT + 12 * COIN - 65 * TESTS_DEFAULT_FEE. */
assert_balance(argument);
const auto& head_blk_for_txs_on_height_12{m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, get_block_height(blk_2)) ? blk_1a : blk_0r};
MAKE_TX_FEE(events, tx_4, miner, miner, MK_TEST_COINS(2), 15 * TESTS_DEFAULT_FEE, head_blk_for_txs_on_height_12);
MAKE_TX_FEE(events, tx_5, miner, miner, MK_TEST_COINS(5), 29 * TESTS_DEFAULT_FEE, head_blk_for_txs_on_height_12);
MAKE_TX_FEE(events, tx_6, miner, miner, MK_TEST_COINS(7), 22 * TESTS_DEFAULT_FEE, head_blk_for_txs_on_height_12);
const std::list txs_1{tx_4, tx_5, tx_6};
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2a, blk_1a, miner, txs_1);
CHECK_AND_ASSERT_EQ(get_block_height(blk_2a), get_block_height(blk_2));
/* 0 10 11 12
(blk_0) - ... - (blk_0r) - (blk_1a) - (blk_2a)
| {tx_1} {tx_4, tx_5, tx_6}
|
\ 11 12
- (blk_1) - (blk_2)
{tx_0} {tx_2, tx_3}
height(blk_2a) = height(blk_2) = 12
fee(tx_2) + fee(tx_3) = (8 + 57) * TESTS_DEFAULT_FEE = 65 * TESTS_DEFAULT_FEE
fee(tx_4) + fee(tx_5) + fee(tx_6) = (15 + 29 + 22) * TESTS_DEFAULT_FEE = 66 * TESTS_DEFAULT_FEE
66 > 65. */
if (m_hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, get_block_height(blk_2)))
{
// Case of an alt block on the height 12 with greater total fee than total fee of blk_2 - the top of the main chain.
argument_alt = argument_assert{this, blk_2a, {(15 + 29 + 22) * TESTS_DEFAULT_FEE}, argument_alt};
// Make sure a reward for blk_2a is equals to COIN.
assert_reward(argument_alt);
// Make sure the balance equals to PREMINE_AMOUNT + 12 * COIN - 99 * TESTS_DEFAULT_FEE.
assert_balance(argument_alt);
}
else
{
// Make sure a reward for blk_2 is equals to COIN.
assert_reward(argument);
// Make sure the balance equals to PREMINE_AMOUNT + 12 * COIN.
assert_balance(argument);
}
return true;
}
bool block_reward_in_alt_chain_basic::assert_balance(currency::core& core, size_t event_index, const std::vector<test_event_entry>& events) const
{
argument_assert argument{};
{
const auto serialized_argument{boost::get<callback_entry>(events.at(event_index)).callback_params};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(argument, serialized_argument), true);
}
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_top_block_height(), argument.m_height);
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_top_block_id(), argument.blk_id);
const auto wallet{init_playtime_test_wallet(events, core, m_accounts.front())};
CHECK_AND_ASSERT(wallet, false);
wallet->refresh();
CHECK_AND_ASSERT_EQ(wallet->balance(), argument.m_balance);
return true;
}
bool block_reward_in_alt_chain_basic::assert_reward(currency::core& core, size_t event_index, const std::vector<test_event_entry>& events) const
{
argument_assert argument{};
{
const auto serialized_argument{boost::get<callback_entry>(events.at(event_index)).callback_params};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(argument, serialized_argument), true);
}
{
auto blk_id{argument.blk_id};
for (const auto expected_reward : argument.m_rewards)
{
uint64_t reward{};
block blk{};
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_block_reward_by_hash(blk_id, reward), true);
CHECK_AND_ASSERT_EQ(reward, expected_reward);
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().get_block_by_hash(blk_id, blk), true);
blk_id = blk.prev_id;
}
}
return true;
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2023 Zano Project
// Copyright (c) 2014-2025 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
@ -6,6 +6,7 @@
#pragma once
#include "chaingen.h"
#include "wallet_tests_basic.h"
template<size_t invalid_block_idx = 0>
class gen_block_verification_base : public test_chain_unit_enchanced
@ -187,3 +188,32 @@ struct gen_block_invalid_binary_format : public test_chain_unit_base
private:
size_t m_corrupt_blocks_begin_idx;
};
struct block_with_correct_prev_id_on_wrong_height : public gen_block_verification_base<1 + CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3>
{
block_with_correct_prev_id_on_wrong_height();
bool generate(std::vector<test_event_entry>& events) const;
bool assert_blk_2_has_wrong_height(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events) const;
};
struct block_reward_in_main_chain_basic : wallet_test
{
block_reward_in_main_chain_basic();
bool generate(std::vector<test_event_entry>& events) const;
private:
bool assert_balance(currency::core& core, size_t event_index, const std::vector<test_event_entry>& events) const;
bool assert_reward(currency::core& core, size_t event_index, const std::vector<test_event_entry>& events) const;
struct argument_assert;
};
struct block_reward_in_alt_chain_basic : wallet_test
{
block_reward_in_alt_chain_basic();
bool generate(std::vector<test_event_entry>& events) const;
private:
bool assert_balance(currency::core& core, size_t event_index, const std::vector<test_event_entry>& events) const;
bool assert_reward(currency::core& core, size_t event_index, const std::vector<test_event_entry>& events) const;
struct argument_assert;
};

View file

@ -532,9 +532,10 @@ bool alt_blocks_validation_and_same_new_amount_in_two_txs::generate(std::vector<
std::vector<tx_destination_entry> destinations;
destinations.push_back(tx_destination_entry(new_amount, miner_acc.get_public_address()));
destinations.push_back(tx_destination_entry(TESTS_DEFAULT_FEE, miner_acc.get_public_address())); //just to make two outputs (to please HF4 rules)
transaction tx_1 = AUTO_VAL_INIT(tx_1);
uint64_t tx_version = get_tx_version(get_block_height(blk_3), m_hardforks);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, tx_version, 0);
transaction tx_1{};
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_3), m_hardforks, tx_hardfork_id);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, tx_version, tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_1);
@ -544,8 +545,8 @@ bool alt_blocks_validation_and_same_new_amount_in_two_txs::generate(std::vector<
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
transaction tx_2 = AUTO_VAL_INIT(tx_2);
// use the same destinations
tx_version = get_tx_version(get_block_height(blk_3), m_hardforks);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_2, tx_version, 0);
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_3), m_hardforks, tx_hardfork_id);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_2, tx_version, tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_2);
@ -913,16 +914,10 @@ bool alt_chain_and_block_tx_fee_median::generate(
CHECK_AND_ASSERT_MES(success, false, "fail to fill sources, destinations");
tx_version = get_tx_version(get_block_height(blk_1r),
m_hardforks);
size_t tx_hardfork_id{};
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id);
success = construct_tx(miner.get_keys(),
sources,
destinations,
empty_attachment,
tx_0,
tx_version,
0);
success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version, tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(success, false, "fail to construct tx_0");
@ -934,8 +929,7 @@ bool alt_chain_and_block_tx_fee_median::generate(
// Transaction tx_1 is constructed and placed in block blk_2a.
tx_version = get_tx_version(get_block_height(blk_1r),
m_hardforks);
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id);
success = fill_tx_sources_and_destinations(
events,
@ -950,13 +944,7 @@ bool alt_chain_and_block_tx_fee_median::generate(
CHECK_AND_ASSERT_MES(success, false, "fail to fill sources, destinations");
success = construct_tx(miner.get_keys(),
sources,
destinations,
empty_attachment,
tx_1,
tx_version,
0);
success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_1, tx_version, tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(success, false, "fail to construct tx_1");

View file

@ -299,6 +299,8 @@ bool test_generator::construct_block(currency::block& blk,
tx_generation_context miner_tx_tgc{};
uint64_t block_reward_without_fee = 0;
uint64_t block_reward = 0;
size_t tx_hardfork_id = 0;
uint64_t tx_version = get_tx_version_and_hardfork_id(height, m_hardforks, tx_hardfork_id);
while (true)
{
r = construct_miner_tx(height, misc_utils::median(block_sizes),
@ -310,7 +312,8 @@ bool test_generator::construct_block(currency::block& blk,
blk.miner_tx,
block_reward_without_fee,
block_reward,
get_tx_version(height, m_hardforks),
tx_version,
tx_hardfork_id,
blobdata(),
test_generator::get_test_gentime_settings().miner_tx_max_outs,
static_cast<bool>(coin_stake_sources.size()),
@ -836,7 +839,7 @@ bool test_generator::find_nounce(currency::block& blk, std::vector<const block_i
if(height != blocks.size())
throw std::runtime_error("wrong height in find_nounce");
return miner::find_nonce_for_given_block(blk, dif, height);
return find_nonce_for_given_block(blk, dif, height);
}
bool test_generator::construct_genesis_block(currency::block& blk, const currency::account_base& miner_acc, uint64_t timestamp)
@ -956,10 +959,12 @@ bool test_generator::construct_block(int64_t manual_timestamp_adjustment,
{
uint64_t base_block_reward = 0;
uint64_t block_reward = 0;
size_t tx_hardfork_id = 0;
uint64_t tx_version = get_tx_version_and_hardfork_id(height, m_hardforks, tx_hardfork_id);
size_t current_block_size = txs_sizes + get_object_blobsize(blk.miner_tx);
// TODO: This will work, until size of constructed block is less then CURRENCY_BLOCK_GRANTED_FULL_REWARD_ZONE
if (!construct_miner_tx(height, misc_utils::median(block_sizes), already_generated_coins, current_block_size, 0,
miner_acc.get_public_address(), miner_acc.get_public_address(), blk.miner_tx, base_block_reward, block_reward, get_tx_version(height, m_hardforks), blobdata(), 1))
miner_acc.get_public_address(), miner_acc.get_public_address(), blk.miner_tx, base_block_reward, block_reward, tx_version, tx_hardfork_id, blobdata(), 1))
return false;
}
@ -1647,7 +1652,7 @@ bool fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
void fill_nonce(currency::block& blk, const wide_difficulty_type& diffic, uint64_t height)
{
blk.nonce = 0;
while (!miner::find_nonce_for_given_block(blk, diffic, height))
while (!find_nonce_for_given_block(blk, diffic, height))
blk.timestamp++;
}*/
@ -1745,8 +1750,9 @@ bool construct_tx_to_key(const currency::hard_forks_descriptor& hf,
std::vector<tx_destination_entry> destinations;
if (!fill_tx_sources_and_destinations(events, blk_head, from.get_keys(), to.get_public_address(), amount, fee, nmix, sources, destinations, check_for_spends, check_for_unlocktime))
return false;
uint64_t tx_version = currency::get_tx_version(get_block_height(blk_head) + 1, hf); // assuming the tx will be in the next block (blk_head + 1)
return construct_tx(from.get_keys(), sources, destinations, extr, att, tx, tx_version, sk, 0, mix_attr);
size_t tx_hardfork_id = 0;
uint64_t tx_version = currency::get_tx_version_and_hardfork_id(get_block_height(blk_head) + 1, hf, tx_hardfork_id); // assuming the tx will be in the next block (blk_head + 1)
return construct_tx(from.get_keys(), sources, destinations, extr, att, tx, tx_version, tx_hardfork_id, sk, 0, mix_attr);
}
bool construct_tx_to_key(const currency::hard_forks_descriptor& hf,
@ -1774,16 +1780,17 @@ bool construct_tx_to_key(const currency::hard_forks_descriptor& hf,
return false;
uint64_t tx_expected_block_height = get_block_height(blk_head) + 1;
uint64_t tx_version = currency::get_tx_version(tx_expected_block_height, hf);
size_t tx_hardfork_id = 0;
uint64_t tx_version = currency::get_tx_version_and_hardfork_id(tx_expected_block_height, hf, tx_hardfork_id);
boost::multiprecision::int128_t change = get_sources_total_amount(sources);
change -= spending_amount;
if (change < 0)
return false; // should never happen if fill_tx_sources succeded
if (change == 0)
return construct_tx(from.get_keys(), sources, destinations, extr, att, tx, tx_version, sk, 0, mix_attr);
return construct_tx(from.get_keys(), sources, destinations, extr, att, tx, tx_version, tx_hardfork_id, sk, 0, mix_attr);
std::vector<tx_destination_entry> local_dst = destinations;
local_dst.push_back(tx_destination_entry(change.convert_to<uint64_t>(), from.get_public_address()));
return construct_tx(from.get_keys(), sources, local_dst, extr, att, tx, tx_version, sk, 0, mix_attr);
return construct_tx(from.get_keys(), sources, local_dst, extr, att, tx, tx_version, tx_hardfork_id, sk, 0, mix_attr);
}
@ -1812,8 +1819,53 @@ bool construct_tx_with_many_outputs(const currency::hard_forks_descriptor& hf, s
uint64_t sources_amount = get_sources_total_amount(sources);
if (sources_amount > total_amount + fee)
destinations.push_back(tx_destination_entry(sources_amount - (total_amount + fee), keys_from.account_address)); // change
uint64_t tx_version = currency::get_tx_version(currency::get_block_height(blk_head), hf);
return construct_tx(keys_from, sources, destinations, empty_attachment, tx, tx_version, 0);
size_t tx_hardfork_id = 0;
uint64_t tx_version = currency::get_tx_version_and_hardfork_id(currency::get_block_height(blk_head), hf, tx_hardfork_id);
return construct_tx(keys_from, sources, destinations, empty_attachment, tx, tx_version, tx_hardfork_id, 0);
}
bool construct_tx(const account_keys& sender_account_keys,
const std::vector<tx_source_entry>& sources,
const std::vector<tx_destination_entry>& destinations,
const std::vector<extra_v>& extra,
const std::vector<attachment_v>& attachments,
transaction& tx,
uint64_t tx_version,
size_t tx_hardfork_id,
crypto::secret_key& one_time_secret_key,
uint64_t unlock_time,
uint64_t expiration_time,
uint8_t tx_outs_attr,
bool shuffle,
uint64_t flags,
uint64_t explicit_consolidated_tx_fee,
tx_generation_context& gen_context)
{
// extra copy operation, but creating transaction is not sensitive to this
finalize_tx_param ftp {};
ftp.tx_version = tx_version;
ftp.tx_hardfork_id = tx_hardfork_id;
ftp.sources = sources;
ftp.prepared_destinations = destinations;
ftp.extra = extra;
ftp.attachments = attachments;
ftp.unlock_time = unlock_time;
// ftp.crypt_address = crypt_destination_addr;
ftp.expiration_time = expiration_time;
ftp.tx_outs_attr = tx_outs_attr;
ftp.shuffle = shuffle;
ftp.flags = flags;
ftp.mode_separate_fee = explicit_consolidated_tx_fee;
finalized_tx ft{};
ft.tx = tx;
ft.one_time_key = one_time_secret_key;
ftp.gen_context = gen_context; // ftp, not ft here, this is UGLY -- sowle
bool r = construct_tx(sender_account_keys, ftp, ft);
tx = ft.tx;
one_time_secret_key = ft.one_time_key;
gen_context = ft.ftp.gen_context;
return r;
}
bool construct_tx(const account_keys& sender_account_keys,
@ -1835,6 +1887,9 @@ bool construct_tx(const account_keys& sender_account_keys,
// extra copy operation, but creating transaction is not sensitive to this
finalize_tx_param ftp {};
ftp.tx_version = tx_version;
if (tx_version >= TRANSACTION_VERSION_POST_HF5)
LOG_PRINT_YELLOW("warning: tx_hardfork_id not set for tx, while it seems to be HF5", LOG_LEVEL_0);
ftp.tx_hardfork_id = 0;
ftp.sources = sources;
ftp.prepared_destinations = destinations;
ftp.extra = extra;
@ -1847,7 +1902,7 @@ bool construct_tx(const account_keys& sender_account_keys,
ftp.flags = flags;
ftp.mode_separate_fee = explicit_consolidated_tx_fee;
finalized_tx ft = AUTO_VAL_INIT(ft);
finalized_tx ft{};
ft.tx = tx;
ft.one_time_key = one_time_secret_key;
ftp.gen_context = gen_context; // ftp, not ft here, this is UGLY -- sowle
@ -1858,6 +1913,63 @@ bool construct_tx(const account_keys& sender_account_keys,
return r;
}
bool construct_tx(const currency::account_keys& sender_account_keys,
const std::vector<currency::tx_source_entry>& sources,
const std::vector<currency::tx_destination_entry>& destinations,
const std::vector<currency::extra_v>& extra,
const std::vector<currency::attachment_v>& attachments,
currency::transaction& tx,
uint64_t tx_version,
crypto::secret_key& one_time_secret_key,
uint64_t unlock_time)
{
[[maybe_unused]] tx_generation_context gen_context{};
return construct_tx(sender_account_keys,
sources,
destinations,
extra,
attachments,
tx,
tx_version,
one_time_secret_key,
unlock_time,
0, /* expiration_time */
CURRENCY_TO_KEY_OUT_RELAXED, /* tx_outs_attr */
true, /* shuffle */
0, /* flags */
0, /* explicit_consolidated_tx_fee */
gen_context /* tx_generation_context */
);
}
bool construct_tx(const currency::account_keys& sender_account_keys,
const std::vector<currency::tx_source_entry>& sources,
const std::vector<currency::tx_destination_entry>& destinations,
const std::vector<currency::extra_v>& extra,
const std::vector<currency::attachment_v>& attachments,
currency::transaction& tx,
uint64_t tx_version)
{
[[maybe_unused]] tx_generation_context gen_context{};
[[maybe_unused]] crypto::secret_key tx_sec_key{};
return construct_tx(sender_account_keys,
sources,
destinations,
extra,
attachments,
tx,
tx_version,
tx_sec_key, /* one_time_secret_key */
0, /* unlock_time */
0, /* expiration_time */
CURRENCY_TO_KEY_OUT_RELAXED, /* tx_outs_attr */
true, /* shuffle */
0, /* flags */
0, /* explicit_consolidated_tx_fee */
gen_context /* tx_generation_context */
);
}
uint64_t get_balance(const currency::account_keys& addr, const std::vector<currency::block>& blockchain, const map_hash2tx_t& mtx, bool dbg_log)
{
uint64_t res = 0;
@ -2560,19 +2672,26 @@ void test_chain_unit_base::register_callback(const std::string& cb_name, verify_
m_callbacks[cb_name] = cb;
}
uint64_t test_chain_unit_base::get_tx_version_from_events(const std::vector<test_event_entry> &events)const
uint64_t test_chain_unit_base::get_tx_version_from_events(const std::vector<test_event_entry> &events) const
{
[[maybe_unused]] size_t tx_hardfork_id{};
return get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id);
}
uint64_t test_chain_unit_base::get_tx_version_and_harfork_id_from_events(const std::vector<test_event_entry> &events, size_t& tx_hardfork_id) const
{
for (auto it = events.rbegin(); it!= events.rend(); it++)
{
if(it->type() == typeid(currency::block))
{
const currency::block& b = boost::get<currency::block>(*it);
return currency::get_tx_version(get_block_height(b), m_hardforks);
return currency::get_tx_version_and_hardfork_id(get_block_height(b), m_hardforks, tx_hardfork_id);
}
}
return currency::get_tx_version(0, m_hardforks);
return currency::get_tx_version_and_hardfork_id(0, m_hardforks, tx_hardfork_id);
}
bool test_chain_unit_base::verify(const std::string& cb_name, currency::core& c, size_t ev_index, const std::vector<test_event_entry> &events)
{
auto cb_it = m_callbacks.find(cb_name);

View file

@ -257,6 +257,7 @@ public:
bool need_core_proxy() const { return false; } // tests can override this in order to obtain core proxy (e.g. for wallet)
void set_core_proxy(std::shared_ptr<tools::i_core_proxy>) { /* do nothing */ }
uint64_t get_tx_version_from_events(const std::vector<test_event_entry> &events) const;
uint64_t get_tx_version_and_harfork_id_from_events(const std::vector<test_event_entry> &events, size_t& tx_hardfork_id) const;
virtual void on_test_constructed() {} // called right after test class is constructed by the chaingen
void on_test_generator_created(test_generator& generator) const; // tests can override this for special initialization
@ -691,6 +692,41 @@ bool construct_tx(const currency::account_keys& sender_account_keys,
uint64_t explicit_consolidated_tx_fee,
currency::tx_generation_context& gen_context);
bool construct_tx(const currency::account_keys& sender_account_keys,
const std::vector<currency::tx_source_entry>& sources,
const std::vector<currency::tx_destination_entry>& destinations,
const std::vector<currency::extra_v>& extra,
const std::vector<currency::attachment_v>& attachments,
currency::transaction& tx,
uint64_t tx_version,
size_t tx_hardfork_id,
crypto::secret_key& one_time_secret_key,
uint64_t unlock_time,
uint64_t expiration_time,
uint8_t tx_outs_attr,
bool shuffle,
uint64_t flags,
uint64_t explicit_consolidated_tx_fee,
currency::tx_generation_context& gen_context);
bool construct_tx(const currency::account_keys& sender_account_keys,
const std::vector<currency::tx_source_entry>& sources,
const std::vector<currency::tx_destination_entry>& destinations,
const std::vector<currency::extra_v>& extra,
const std::vector<currency::attachment_v>& attachments,
currency::transaction& tx,
uint64_t tx_version,
crypto::secret_key& one_time_secret_key,
uint64_t unlock_time);
bool construct_tx(const currency::account_keys& sender_account_keys,
const std::vector<currency::tx_source_entry>& sources,
const std::vector<currency::tx_destination_entry>& destinations,
const std::vector<currency::extra_v>& extra,
const std::vector<currency::attachment_v>& attachments,
currency::transaction& tx,
uint64_t tx_version);
void get_confirmed_txs(const std::vector<currency::block>& blockchain, const map_hash2tx_t& mtx, map_hash2tx_t& confirmed_txs);
bool find_block_chain(const std::vector<test_event_entry>& events, std::vector<currency::block>& blockchain, map_hash2tx_t& mtx, const crypto::hash& head);
bool fill_tx_sources(std::vector<currency::tx_source_entry>& sources, const std::vector<test_event_entry>& events,
@ -994,10 +1030,12 @@ bool test_generator::construct_block_gentime_with_coinbase_cb(const currency::bl
uint64_t block_reward_without_fee = 0;
uint64_t block_reward = 0;
size_t tx_hardfork_id = 0;
uint64_t tx_version = get_tx_version_and_hardfork_id(height, m_hardforks, tx_hardfork_id);
currency::keypair tx_sec_key = currency::keypair::generate();
r = construct_miner_tx(height, epee::misc_utils::median(block_sizes), already_generated_coins, 0 /* current_block_size !HACK! */, 0,
acc.get_public_address(), acc.get_public_address(), miner_tx, block_reward_without_fee, block_reward, get_tx_version(height, m_hardforks), currency::blobdata(), /* max outs: */ 1,
acc.get_public_address(), acc.get_public_address(), miner_tx, block_reward_without_fee, block_reward, tx_version, tx_hardfork_id, currency::blobdata(), /* max outs: */ 1,
/* pos: */ false, currency::pos_entry(), /* ogc_ptr: */ nullptr, &tx_sec_key);
CHECK_AND_ASSERT_MES(r, false, "construct_miner_tx failed");

View file

@ -33,7 +33,7 @@ inline bool mine_next_pow_block_in_playtime(const currency::account_public_addre
test_core_time::adjust(b.timestamp);
modify_block_cb(b);
r = currency::miner::find_nonce_for_given_block(b, cbtr.diffic, cbtr.height);
r = currency::find_nonce_for_given_block(b, cbtr.diffic, cbtr.height);
CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed");
currency::block_verification_context bvc{};
@ -119,7 +119,7 @@ inline bool mine_next_pow_block_in_playtime_with_given_txs(const currency::accou
height = cbtr.height;
}
r = currency::miner::find_nonce_for_given_block(b, cbtr.diffic, cbtr.height);
r = currency::find_nonce_for_given_block(b, cbtr.diffic, cbtr.height);
CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed");
currency::block_verification_context bvc{};
@ -313,9 +313,10 @@ inline bool put_alias_via_tx_to_list(const currency::hard_forks_descriptor& hf,
el.flags |= currency::tx_destination_entry_flags::tdef_explicit_native_asset_id | currency::tx_destination_entry_flags::tdef_zero_amount_blinding_mask; // all alias-burn outputs must have explicit native asset id and zero amount mask
}
uint64_t tx_version = currency::get_tx_version(get_block_height(head_block) + 1, generator.get_hardforks()); // assuming the tx will be in the next block (head_block + 1)
size_t tx_hardfork_id{};
uint64_t tx_version = currency::get_tx_version_and_hardfork_id(get_block_height(head_block) + 1, generator.get_hardforks(), tx_hardfork_id); // assuming the tx will be in the next block (head_block + 1)
tx_set.emplace_back();
r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx_set.back(), tx_version, generator.last_tx_generated_secret_key, 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, extra, empty_attachment, tx_set.back(), tx_version, tx_hardfork_id, generator.last_tx_generated_secret_key, 0);
PRINT_EVENT_N_TEXT(events, "put_alias_via_tx_to_list()");
events.push_back(tx_set.back());

View file

@ -387,7 +387,7 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_
#define GENERATE_AND_PLAY(genclass) \
if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string::npos != std::string(#genclass).find(run_single_test)))) \
if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string(#genclass) == run_single_test))) \
{ \
TIME_MEASURE_START_MS(t); \
++tests_count; \
@ -422,7 +422,7 @@ bool gen_and_play_intermitted_by_blockchain_saveload(const char* const genclass_
}
#define GENERATE_AND_PLAY_HF(genclass, hardfork_str_mask) \
if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string::npos != std::string(#genclass).find(run_single_test)))) \
if (!skip_all_till_the_end && ((!postponed_tests.count(#genclass) && run_single_test.empty()) || (!run_single_test.empty() && std::string(#genclass) == run_single_test))) \
{ \
std::vector<size_t> hardforks = parse_hardfork_str_mask(hardfork_str_mask); \
CHECK_AND_ASSERT_MES(!hardforks.empty(), false, "invalid hardforks mask: " << hardfork_str_mask); \
@ -1154,6 +1154,7 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(one_block);
GENERATE_AND_PLAY(gen_ring_signature_1);
GENERATE_AND_PLAY(gen_ring_signature_2);
GENERATE_AND_PLAY(fill_tx_rpc_inputs);
//GENERATE_AND_PLAY(gen_ring_signature_big); // Takes up to XXX hours (if CURRENCY_MINED_MONEY_UNLOCK_WINDOW == 10)
// tests for outputs mixing in
@ -1177,6 +1178,9 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY_HF(gen_block_unlock_time_is_timestamp_in_future, "0,3");
GENERATE_AND_PLAY_HF(gen_block_height_is_low, "0,3");
GENERATE_AND_PLAY_HF(gen_block_height_is_high, "0,3");
GENERATE_AND_PLAY_HF(block_with_correct_prev_id_on_wrong_height, "3-*");
GENERATE_AND_PLAY_HF(block_reward_in_main_chain_basic, "3-*");
GENERATE_AND_PLAY_HF(block_reward_in_alt_chain_basic, "3-*");
GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_2_tx_gen_in, "0,3");
GENERATE_AND_PLAY_HF(gen_block_miner_tx_has_2_in, "0,3");
GENERATE_AND_PLAY_HF(gen_block_miner_tx_with_txin_to_key, "0,3");
@ -1221,6 +1225,7 @@ int main(int argc, char* argv[])
/* To execute the check of bare balance (function "check_tx_bare_balance") we need to run the test "tx_pool_semantic_validation" on the HF 3. By default behaviour bare outputs are disallowed on
the heights >= 10. */
GENERATE_AND_PLAY_HF(tx_pool_semantic_validation, "3");
GENERATE_AND_PLAY(input_refers_to_incompatible_by_type_output);
// Double spend
GENERATE_AND_PLAY(gen_double_spend_in_tx<false>);
@ -1271,6 +1276,9 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(hardfork_4_wallet_sweep_bare_outs);
GENERATE_AND_PLAY_HF(hardfork_4_pop_tx_from_global_index, "4-*");
// HF5
GENERATE_AND_PLAY_HF(hard_fork_5_tx_version, "5-*");
// atomics
GENERATE_AND_PLAY(atomic_simple_test);
GENERATE_AND_PLAY(atomic_test_wrong_redeem_wrong_refund);

View file

@ -39,10 +39,12 @@
#include "hard_fork_1.h"
#include "hard_fork_2.h"
#include "hard_fork_4.h"
#include "hard_fork_5.h"
#include "atomic_tests.h"
#include "isolate_auditable_and_proof.h"
#include "zarcanum_test.h"
#include "multiassets_test.h"
#include "ionic_swap_tests.h"
#include "attachment_isolation_encryption_test.h"
#include "pos_fuse_test.h"
#include "pos_fuse_test.h"
#include "daemon_rpc.h"

View file

@ -930,8 +930,8 @@ bool gen_checkpoints_and_invalid_tx_to_pool::generate(std::vector<test_event_ent
r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc, miner_acc, MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_0 = AUTO_VAL_INIT(tx_0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
transaction tx_0{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_0, get_tx_version_from_events(events));
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
// invalidate tx_0 signature

View file

@ -0,0 +1,580 @@
// 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.
#include "chaingen.h"
#include "daemon_rpc.h"
fill_tx_rpc_inputs::fill_tx_rpc_inputs()
{
REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c1);
REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c2);
REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c3);
REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c4);
REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c5);
REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c6);
REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c7);
REGISTER_CALLBACK_METHOD(fill_tx_rpc_inputs, c8);
}
bool fill_tx_rpc_inputs::generate(std::vector<test_event_entry>& events) const
{
// Test idea: make sure that the function "blockchain_storage::fill_tx_rpc_inputs" works as expected.
GENERATE_ACCOUNT(miner);
MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time());
DO_CALLBACK(events, "configure_core");
// A transaction in the default state.
DO_CALLBACK_PARAMS_STR(events, "c1", t_serializable_object_to_blob(currency::transaction{}));
// A transaction with an input of the type "txin_to_key" in the default state.
{
currency::transaction tx{};
tx.vin.push_back(std::move(currency::txin_to_key{}));
DO_CALLBACK_PARAMS_STR(events, "c2", t_serializable_object_to_blob(tx));
}
// A transaction with an input of the type "txin_zc_input".
{
currency::transaction tx{};
{
currency::txin_zc_input input{};
input.k_image = {};
tx.vin.push_back(std::move(input));
}
DO_CALLBACK_PARAMS_STR(events, "c3", t_serializable_object_to_blob(tx));
}
// A transaction with several "txin_to_key" inputs those have different .amount values.
{
currency::transaction tx{};
tx.vin.reserve(3);
{
currency::txin_to_key input{};
CHECK_AND_ASSERT_EQ(input.amount, 0);
tx.vin.push_back(std::move(input));
}
{
currency::txin_to_key input{};
input.amount = UINT64_MAX;
tx.vin.push_back(std::move(input));
}
{
currency::txin_to_key input{};
input.amount = 16730018105294876523ull;
tx.vin.push_back(std::move(input));
}
DO_CALLBACK_PARAMS_STR(events, "c4", t_serializable_object_to_blob(tx));
}
// A transaction with inputs of all possible types.
{
currency::transaction tx{};
tx.vin.reserve(5);
tx.vin.push_back(std::move(currency::txin_gen{}));
tx.vin.push_back(std::move(currency::txin_to_key{}));
tx.vin.push_back(std::move(currency::txin_htlc{}));
{
currency::txin_zc_input input{};
input.k_image = {};
tx.vin.push_back(std::move(input));
}
tx.vin.push_back(std::move(currency::txin_multisig{}));
DO_CALLBACK_PARAMS_STR(events, "c5", t_serializable_object_to_blob(tx));
}
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, blk_0r);
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner, tx_0);
// A transaction with inputs of all possible types.
{
currency::transaction tx{};
tx.vin.reserve(5);
tx.vin.push_back(std::move(currency::txin_gen{/* .height = */ 7137406440025745250}));
{
currency::txin_to_key input{};
input.key_offsets.push_back(5350230927837587142ull);
input.key_offsets.push_back(std::move(currency::ref_by_id{currency::get_transaction_hash(tx_0), 0u}));
input.amount = 2341818593703234797ull;
input.k_image = crypto::point_t{{0x62, 0xd9, 0xa0, 0xff, 0xb1, 0x89, 0x06, 0xbe, 0xbd, 0xe9, 0xce, 0xd5, 0xc2, 0x04, 0x5b, 0x6b, 0xb4, 0x5f, 0x9c, 0x3b, 0x31, 0xcc, 0x72, 0xc7, 0x55, 0x25, 0x0f,
0xa2, 0xb2, 0xbf, 0xb1, 0x0c}}.to_key_image();
input.etc_details.push_back(std::move(currency::signed_parts{/* .n_outs = */ 2613407258u, /* .n_extras = */ 347754399u}));
input.etc_details.push_back(std::move(currency::extra_attachment_info{/* .sz = */ 5559118977069213037ull, /* .hsh = */ currency::null_hash, /* cnt = */ 8106306627691316520ull}));
tx.vin.push_back(std::move(input));
}
{
currency::txin_htlc input{};
input.key_offsets.push_back(9536097715806449708ull);
input.key_offsets.push_back(std::move(currency::ref_by_id{/* .tx_id = */ currency::get_transaction_hash(tx_0), /* .n = */ 9u}));
input.amount = 11357119244607763967ull;
input.k_image = crypto::point_t{{0xcb, 0xec, 0xfb, 0x36, 0x02, 0x1c, 0xe5, 0x64, 0xee, 0x6a, 0xb8, 0x67, 0xb2, 0x8e, 0xe9, 0xef, 0x80, 0x17, 0x34, 0x6f, 0xa8, 0x67, 0x3e, 0x45, 0x3a, 0xe0, 0xd4,
0x8b, 0x1a, 0x13, 0x75, 0xe2}}.to_key_image();
input.etc_details.push_back(std::move(currency::signed_parts{/* .n_outs = */ 517318753u, /* .n_extras = */ 1367922888u}));
input.etc_details.push_back(std::move(currency::extra_attachment_info{/* .sz = */ 10987762797757012676ull, /* .hsh = */ currency::null_hash, /* .cnt = */ 10767056422067827733ull}));
input.hltc_origin = "htlc-origin";
tx.vin.push_back(std::move(input));
}
{
currency::txin_zc_input input{};
input.key_offsets.push_back(16540286509618649069ull);
input.key_offsets.push_back(std::move(currency::ref_by_id{/* .tx_id = */ currency::get_transaction_hash(tx_0), /* .n = */ 4}));
input.k_image = crypto::point_t{{0x53, 0xcf, 0xaf, 0x48, 0x4d, 0xf8, 0xfb, 0x09, 0x4c, 0x01, 0x59, 0x9f, 0xe2, 0x2d, 0x3c, 0x23, 0x96, 0x2d, 0x8c, 0x24, 0x09, 0xf9, 0xd3, 0xe6, 0xf3, 0x27, 0xe8,
0x7c, 0x7a, 0x90, 0x9c, 0xab}}.to_key_image();
input.etc_details.push_back(std::move(currency::signed_parts{/* .n_outs = */ 517318753u, /* .n_extras = */ 1367922888u}));
input.etc_details.push_back(std::move(currency::extra_attachment_info{/* .sz = */ 10987762797757012676ull, /* .hsh = */ currency::null_hash, /* .cnt = */ 10767056422067827733ull}));
tx.vin.push_back(std::move(input));
}
{
currency::txin_multisig input{};
input.amount = 14073369620052150183ull;
input.multisig_out_id = crypto::cn_fast_hash("multisig-out-id", 15);
input.sigs_count = 3497547654u;
input.etc_details.push_back(std::move(currency::signed_parts{/* .n_outs = */ 1801772931u, /* .n_extras = */ 167800219u}));
input.etc_details.push_back(std::move(currency::extra_attachment_info{/* .sz = */ 12438971857615319230ull, /* .hsh = */ currency::null_hash, /* .cnt = */ 13515222808659969031ull}));
tx.vin.push_back(std::move(input));
}
DO_CALLBACK_PARAMS_STR(events, "c6", t_serializable_object_to_blob(tx));
}
/* A wrong reference by an object of the type "ref_by_id": a value of the attribute ".n" representing an offset is greater than a length of a container of outputs.The function "fill_tx_rpc_inputs"
returns false. */
{
currency::transaction tx{};
{
currency::txin_to_key input{};
CHECK_AND_ASSERT_GREATER(1968482779, tx_0.vout.size() - 1);
input.key_offsets.push_back(std::move(currency::ref_by_id{currency::get_transaction_hash(tx_0), 1968482779u}));
tx.vin.push_back(std::move(input));
}
DO_CALLBACK_PARAMS_STR(events, "c7", t_serializable_object_to_blob(tx));
}
// A wrong reference by an object of the type "ref_by_id": hashcode of non-existent transaction is specified. The function "fill_tx_rpc_inputs" returns false.
{
currency::transaction tx{};
{
currency::txin_to_key input{};
input.key_offsets.push_back(std::move(currency::ref_by_id{currency::null_hash, 0u}));
tx.vin.push_back(std::move(input));
}
DO_CALLBACK_PARAMS_STR(events, "c8", t_serializable_object_to_blob(tx));
}
return true;
}
bool fill_tx_rpc_inputs::c1(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const
{
currency::transaction tx{};
currency::tx_rpc_extended_info info{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(event_position)).callback_params), true);
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true);
CHECK_AND_ASSERT_EQ(info.blob.empty(), true);
CHECK_AND_ASSERT_EQ(info.blob_size, 0);
CHECK_AND_ASSERT_EQ(info.fee, 0);
CHECK_AND_ASSERT_EQ(info.amount, 0);
CHECK_AND_ASSERT_EQ(info.timestamp, 0);
CHECK_AND_ASSERT_EQ(info.keeper_block, 0);
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true);
CHECK_AND_ASSERT_EQ(info.outs.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.empty(), true);
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.extra.empty(), true);
CHECK_AND_ASSERT_EQ(info.attachments.empty(), true);
CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true);
return true;
}
bool fill_tx_rpc_inputs::c2(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const
{
currency::transaction tx{};
currency::tx_rpc_extended_info info{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(event_position)).callback_params), true);
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true);
CHECK_AND_ASSERT_EQ(info.blob.empty(), true);
CHECK_AND_ASSERT_EQ(info.blob_size, 0);
CHECK_AND_ASSERT_EQ(info.fee, 0);
CHECK_AND_ASSERT_EQ(info.amount, 0);
CHECK_AND_ASSERT_EQ(info.timestamp, 0);
CHECK_AND_ASSERT_EQ(info.keeper_block, 0);
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true);
CHECK_AND_ASSERT_EQ(info.outs.empty(), true);
{
CHECK_AND_ASSERT_EQ(info.ins.size(), 1);
{
CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0);
CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0);
CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki));
CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true);
}
}
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.extra.empty(), true);
CHECK_AND_ASSERT_EQ(info.attachments.empty(), true);
CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true);
return true;
}
bool fill_tx_rpc_inputs::c3(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const
{
currency::transaction tx{};
currency::tx_rpc_extended_info info{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(event_position)).callback_params), true);
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true);
CHECK_AND_ASSERT_EQ(info.blob.empty(), true);
CHECK_AND_ASSERT_EQ(info.blob_size, 0);
CHECK_AND_ASSERT_EQ(info.fee, 0);
CHECK_AND_ASSERT_EQ(info.amount, 0);
CHECK_AND_ASSERT_EQ(info.timestamp, 0);
CHECK_AND_ASSERT_EQ(info.keeper_block, 0);
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true);
CHECK_AND_ASSERT_EQ(info.outs.empty(), true);
{
CHECK_AND_ASSERT_EQ(info.ins.size(), 1);
{
CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0);
CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0);
CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki));
CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true);
}
}
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.extra.empty(), true);
CHECK_AND_ASSERT_EQ(info.attachments.empty(), true);
CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true);
return true;
}
bool fill_tx_rpc_inputs::c4(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const
{
currency::transaction tx{};
currency::tx_rpc_extended_info info{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(event_position)).callback_params), true);
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true);
CHECK_AND_ASSERT_EQ(info.blob.empty(), true);
CHECK_AND_ASSERT_EQ(info.blob_size, 0);
CHECK_AND_ASSERT_EQ(info.fee, 0);
CHECK_AND_ASSERT_EQ(info.amount, 0);
CHECK_AND_ASSERT_EQ(info.timestamp, 0);
CHECK_AND_ASSERT_EQ(info.keeper_block, 0);
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true);
CHECK_AND_ASSERT_EQ(info.outs.empty(), true);
{
CHECK_AND_ASSERT_EQ(info.ins.size(), 3);
{
CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0);
CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0);
CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki));
CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true);
}
{
CHECK_AND_ASSERT_EQ(info.ins.at(1).amount, UINT64_MAX);
CHECK_AND_ASSERT_EQ(info.ins.at(1).multisig_count, 0);
CHECK_AND_ASSERT_EQ(info.ins.at(1).htlc_origin.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.at(1).kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki));
CHECK_AND_ASSERT_EQ(info.ins.at(1).global_indexes.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.at(1).etc_options.empty(), true);
}
{
CHECK_AND_ASSERT_EQ(info.ins.back().amount, 16730018105294876523ull);
CHECK_AND_ASSERT_EQ(info.ins.back().multisig_count, 0);
CHECK_AND_ASSERT_EQ(info.ins.back().htlc_origin.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.back().kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki));
CHECK_AND_ASSERT_EQ(info.ins.back().global_indexes.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.back().etc_options.empty(), true);
}
}
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.extra.empty(), true);
CHECK_AND_ASSERT_EQ(info.attachments.empty(), true);
CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true);
return true;
}
bool fill_tx_rpc_inputs::c5(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const
{
currency::transaction tx{};
currency::tx_rpc_extended_info info{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(event_position)).callback_params), true);
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true);
CHECK_AND_ASSERT_EQ(info.blob.empty(), true);
CHECK_AND_ASSERT_EQ(info.blob_size, 0);
CHECK_AND_ASSERT_EQ(info.fee, 0);
CHECK_AND_ASSERT_EQ(info.amount, 0);
CHECK_AND_ASSERT_EQ(info.timestamp, 0);
CHECK_AND_ASSERT_EQ(info.keeper_block, 0);
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true);
CHECK_AND_ASSERT_EQ(info.outs.empty(), true);
{
CHECK_AND_ASSERT_EQ(info.ins.size(), 5);
for (size_t position{}; position < info.ins.size(); ++position)
{
CHECK_AND_ASSERT_EQ(info.ins.at(position).amount, 0);
CHECK_AND_ASSERT_EQ(info.ins.at(position).multisig_count, 0);
CHECK_AND_ASSERT_EQ(info.ins.at(position).htlc_origin.empty(), true);
if (position == 0)
{
CHECK_AND_ASSERT_EQ(info.ins.at(position).kimage_or_ms_id.empty(), true);
}
else
{
CHECK_AND_ASSERT_EQ(info.ins.at(position).kimage_or_ms_id, epee::string_tools::pod_to_hex(currency::null_ki));
}
CHECK_AND_ASSERT_EQ(info.ins.at(position).global_indexes.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.at(position).etc_options.empty(), true);
}
}
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.extra.empty(), true);
CHECK_AND_ASSERT_EQ(info.attachments.empty(), true);
CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true);
return true;
}
bool fill_tx_rpc_inputs::c6(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const
{
currency::transaction tx{};
currency::tx_rpc_extended_info info{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(event_position)).callback_params), true);
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), true);
CHECK_AND_ASSERT_EQ(info.blob.empty(), true);
CHECK_AND_ASSERT_EQ(info.blob_size, 0);
CHECK_AND_ASSERT_EQ(info.fee, 0);
CHECK_AND_ASSERT_EQ(info.amount, 0);
CHECK_AND_ASSERT_EQ(info.timestamp, 0);
CHECK_AND_ASSERT_EQ(info.keeper_block, 0);
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.pub_key.empty(), true);
CHECK_AND_ASSERT_EQ(info.outs.empty(), true);
{
CHECK_AND_ASSERT_EQ(info.ins.size(), 5);
{
CHECK_AND_ASSERT_EQ(info.ins.front().amount, 0ull);
CHECK_AND_ASSERT_EQ(info.ins.front().multisig_count, 0ull);
CHECK_AND_ASSERT_EQ(info.ins.front().htlc_origin.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.front().kimage_or_ms_id.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.front().global_indexes.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.front().etc_options.empty(), true);
}
{
CHECK_AND_ASSERT_EQ(info.ins.at(1).amount, 2341818593703234797ull);
CHECK_AND_ASSERT_EQ(info.ins.at(1).multisig_count, 0ull);
CHECK_AND_ASSERT_EQ(info.ins.at(1).htlc_origin.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.at(1).kimage_or_ms_id, "8172e80b8da3bcbce2ee7df42466627bb3559b80bb504f1fd56b460eedbc2ce9");
CHECK_AND_ASSERT_EQ(info.ins.at(1).global_indexes.size(), 2ull);
{
CHECK_AND_ASSERT_EQ(info.ins.at(1).global_indexes.front(), 5350230927837587142ull);
CHECK_AND_ASSERT_EQ(info.ins.at(1).global_indexes.back(), 0ull);
}
CHECK_AND_ASSERT_EQ(info.ins.at(1).etc_options.size(), 2ull);
{
CHECK_AND_ASSERT_EQ(info.ins.at(1).etc_options.front(), "n_outs: 2613407258, n_extras: 347754399");
CHECK_AND_ASSERT_EQ(info.ins.at(1).etc_options.back(), "cnt: 8106306627691316520, sz: 5559118977069213037, hsh: " + std::string(64, '0'));
}
}
{
CHECK_AND_ASSERT_EQ(info.ins.at(2).amount, 11357119244607763967ull);
CHECK_AND_ASSERT_EQ(info.ins.at(2).multisig_count, 0ull);
CHECK_AND_ASSERT_EQ(info.ins.at(2).htlc_origin, epee::string_tools::buff_to_hex_nodelimer(std::string{"htlc-origin"}));
CHECK_AND_ASSERT_EQ(info.ins.at(2).kimage_or_ms_id, "f15201980333d6ca8fda90c73814baea0864eb56597e40c38061ec77644585ea");
CHECK_AND_ASSERT_EQ(info.ins.at(2).global_indexes.size(), 2ull);
{
CHECK_AND_ASSERT_EQ(info.ins.at(2).global_indexes.front(), 9536097715806449708ull);
CHECK_AND_ASSERT_EQ(info.ins.at(2).global_indexes.back(), 0ull);
}
CHECK_AND_ASSERT_EQ(info.ins.at(2).etc_options.size(), 2ull);
{
CHECK_AND_ASSERT_EQ(info.ins.at(2).etc_options.front(), "n_outs: 517318753, n_extras: 1367922888");
CHECK_AND_ASSERT_EQ(info.ins.at(2).etc_options.back(), "cnt: 10767056422067827733, sz: 10987762797757012676, hsh: " + std::string(64, '0'));
}
}
{
CHECK_AND_ASSERT_EQ(info.ins.at(3).amount, 0ull);
CHECK_AND_ASSERT_EQ(info.ins.at(3).multisig_count, 0ull);
CHECK_AND_ASSERT_EQ(info.ins.at(3).htlc_origin.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.at(3).kimage_or_ms_id, "c08b36a7f77185f31a570a7f51aa550122026985e5de7941218510a1e973202e");
CHECK_AND_ASSERT_EQ(info.ins.at(3).global_indexes.size(), 2ull);
{
CHECK_AND_ASSERT_EQ(info.ins.at(3).global_indexes.front(), 16540286509618649069ull);
CHECK_AND_ASSERT_EQ(info.ins.at(3).global_indexes.back(), 0ull);
}
CHECK_AND_ASSERT_EQ(info.ins.at(3).etc_options.size(), 2ull);
{
CHECK_AND_ASSERT_EQ(info.ins.at(3).etc_options.front(), "n_outs: 517318753, n_extras: 1367922888");
CHECK_AND_ASSERT_EQ(info.ins.at(3).etc_options.back(), "cnt: 10767056422067827733, sz: 10987762797757012676, hsh: " + std::string(64, '0'));
}
}
{
CHECK_AND_ASSERT_EQ(info.ins.at(4).amount, 14073369620052150183ull);
CHECK_AND_ASSERT_EQ(info.ins.at(4).multisig_count, 0ull);
CHECK_AND_ASSERT_EQ(info.ins.at(4).htlc_origin.empty(), true);
CHECK_AND_ASSERT_EQ(info.ins.at(4).kimage_or_ms_id, "aacdff6018af0aae84d7a836a7f0b4309b51a28bfc4f566657c67b903a3ccba5");
CHECK_AND_ASSERT_EQ(info.ins.at(4).global_indexes.size(), 0ull);
CHECK_AND_ASSERT_EQ(info.ins.at(4).etc_options.size(), 2ull);
{
CHECK_AND_ASSERT_EQ(info.ins.at(4).etc_options.front(), "n_outs: 1801772931, n_extras: 167800219");
CHECK_AND_ASSERT_EQ(info.ins.at(4).etc_options.back(), "cnt: 13515222808659969031, sz: 12438971857615319230, hsh: " + std::string(64, '0'));
}
}
}
CHECK_AND_ASSERT_EQ(info.id.empty(), true);
CHECK_AND_ASSERT_EQ(info.extra.empty(), true);
CHECK_AND_ASSERT_EQ(info.attachments.empty(), true);
CHECK_AND_ASSERT_EQ(info.object_in_json.empty(), true);
return true;
}
bool fill_tx_rpc_inputs::c7(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const
{
currency::transaction tx{};
currency::tx_rpc_extended_info info{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(event_position)).callback_params), true);
CHECK_AND_ASSERT_EQ(tx.vin.size(), 1);
{
const auto& input{boost::get<currency::txin_to_key>(tx.vin.front())};
CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1);
{
const auto& reference{boost::get<currency::ref_by_id>(input.key_offsets.front())};
CHECK_AND_ASSERT_EQ(reference.n, 1968482779u);
{
const auto pointer_entry{core.get_blockchain_storage().get_tx_chain_entry(reference.tx_id)};
CHECK_AND_ASSERT(pointer_entry, false);
CHECK_AND_ASSERT(reference.n >= pointer_entry->m_global_output_indexes.size(), false);
}
}
}
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), false);
return true;
}
bool fill_tx_rpc_inputs::c8(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const
{
currency::transaction tx{};
currency::tx_rpc_extended_info info{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(event_position)).callback_params), true);
CHECK_AND_ASSERT_EQ(tx.vin.size(), 1);
{
const auto& input{boost::get<currency::txin_to_key>(tx.vin.front())};
CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1);
{
const auto& reference{boost::get<currency::ref_by_id>(input.key_offsets.front())};
CHECK_AND_ASSERT_EQ(reference.tx_id, currency::null_hash);
CHECK_AND_ASSERT_EQ(reference.n, 0u);
const auto pointer_entry{core.get_blockchain_storage().get_tx_chain_entry(reference.tx_id)};
CHECK_AND_ASSERT(pointer_entry == nullptr, false);
}
}
CHECK_AND_ASSERT_EQ(core.get_blockchain_storage().fill_tx_rpc_inputs(info, tx), false);
return true;
}

View file

@ -0,0 +1,22 @@
// Copyright (c) 2024 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 <vector>
#include "chaingen.h"
struct fill_tx_rpc_inputs : public test_chain_unit_enchanced
{
fill_tx_rpc_inputs();
bool generate(std::vector<test_event_entry>& events) const;
bool c1(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const;
bool c2(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const;
bool c3(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const;
bool c4(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const;
bool c5(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const;
bool c6(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const;
bool c7(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const;
bool c8(const currency::core& core, const size_t event_position, const std::vector<test_event_entry>& events) const;
};

View file

@ -95,7 +95,9 @@ bool gen_double_spend_in_tx<txs_kept_by_block>::generate(std::vector<test_event_
currency::transaction tx_1 = AUTO_VAL_INIT(tx_1);
std::vector<currency::attachment_v> attachments;
if (!construct_tx(bob_account.get_keys(), sources, destinations, attachments, tx_1, this->get_tx_version_from_events(events), uint64_t(0)))
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_from_events(events);
if (!construct_tx(bob_account.get_keys(), sources, destinations, attachments, tx_1, tx_version, tx_hardfork_id, uint64_t(0)))
return false;
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_kept_by_block, txs_kept_by_block);

View file

@ -69,7 +69,7 @@ bool emission_test::c1(currency::core& c, size_t ev_index, const std::vector<tes
uint64_t height_from_template = 0;
r = c.get_block_template(b, m_miner_acc.get_public_address(), m_miner_acc.get_public_address(), difficulty, height_from_template, extra);
CHECK_AND_ASSERT_MES(r || height_from_template != height, false, "get_block_template failed");
r = miner::find_nonce_for_given_block(b, difficulty, height);
r = find_nonce_for_given_block(b, difficulty, height);
CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed");
c.handle_incoming_block(t_serializable_object_to_blob(b), bvc);
CHECK_AND_NO_ASSERT_MES(!bvc.m_verification_failed && !bvc.m_marked_as_orphaned && !bvc.m_already_exists, false, "block verification context check failed");
@ -181,8 +181,9 @@ bool pos_emission_test::generate(std::vector<test_event_entry> &events)
for (size_t i = 0; i < m_pos_entries_to_generate; ++i)
destinations.push_back(tx_destination_entry(pos_entry_amount, alice_acc.get_public_address()));
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(preminer_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0);
transaction tx_1{};
size_t tx_hardfork_id{};
r = construct_tx(preminer_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_1);
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_1);

View file

@ -167,6 +167,7 @@ inline bool build_custom_escrow_template(const std::vector<test_event_entry>& ev
bc_services::contract_private_details& cpd, uint64_t unlock_time, uint64_t expiration_time, size_t nmix, uint64_t b_fee_release,
uint64_t custom_config_mask,
uint64_t tx_version,
size_t tx_hardfork_id,
transaction& escrow_template_tx, /* OUT */
crypto::secret_key& tx_key_sec, /* OUT */
std::vector<tx_source_entry>& used_sources /* IN/OUT */)
@ -231,7 +232,7 @@ inline bool build_custom_escrow_template(const std::vector<test_event_entry>& ev
if (custom_config_mask & eccf_template_additional_attach)
attachments.push_back(tx_comment({ get_random_text(1024) }));
r = construct_tx(a_keys, sources, destinations, extra, attachments, escrow_template_tx, tx_version, tx_key_sec, unlock_time, crypt_addr, expiration_time, CURRENCY_TO_KEY_OUT_RELAXED, true, flags);
r = construct_tx(a_keys, sources, destinations, extra, attachments, escrow_template_tx, tx_version, tx_hardfork_id, tx_key_sec, unlock_time, crypt_addr, expiration_time, CURRENCY_TO_KEY_OUT_RELAXED, true, flags);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
if (custom_config_mask & eccf_template_no_tx_flags)
@ -266,6 +267,7 @@ inline bool build_custom_escrow_proposal(const std::vector<test_event_entry>& ev
uint64_t a_fee_proposal, uint64_t b_fee_release,
uint64_t custom_config_mask,
uint64_t tx_version,
size_t tx_hardfork_id,
transaction& escrow_proposal_tx, /* OUT */
std::vector<tx_source_entry>& used_sources,/* IN/OUT */
bc_services::proposal_body* p_pb = nullptr /* OUT */ )
@ -283,7 +285,7 @@ inline bool build_custom_escrow_proposal(const std::vector<test_event_entry>& ev
p_pb = &local_pb;
if (~custom_config_mask & eccf_proposal_sa_empty_body)
{
r = build_custom_escrow_template(events, head, a_keys, cpd, template_unlock_time, template_expiration_time, nmix, b_fee_release, custom_config_mask, tx_version, p_pb->tx_template, p_pb->tx_onetime_secret_key, used_sources);
r = build_custom_escrow_template(events, head, a_keys, cpd, template_unlock_time, template_expiration_time, nmix, b_fee_release, custom_config_mask, tx_version, tx_hardfork_id, p_pb->tx_template, p_pb->tx_onetime_secret_key, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_template failed");
}
@ -309,7 +311,7 @@ inline bool build_custom_escrow_proposal(const std::vector<test_event_entry>& ev
account_public_address crypt_addr = cpd.b_addr;
crypto::secret_key tx_key_sec; // stub, not used
r = construct_tx(a_keys, sources, destinations, empty_extra, attachments, escrow_proposal_tx, tx_version, tx_key_sec, unlock_time, crypt_addr, expiration_time, 0, true, (~custom_config_mask & eccf_proposal_inv_flags) ? 0 : TX_FLAG_SIGNATURE_MODE_SEPARATE);
r = construct_tx(a_keys, sources, destinations, empty_extra, attachments, escrow_proposal_tx, tx_version, tx_hardfork_id, tx_key_sec, unlock_time, crypt_addr, expiration_time, 0, true, (~custom_config_mask & eccf_proposal_inv_flags) ? 0 : TX_FLAG_SIGNATURE_MODE_SEPARATE);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
append_vector_by_another_vector(used_sources, sources);
@ -321,7 +323,8 @@ inline bool build_custom_escrow_release_template(
const account_keys& b_keys,
const bc_services::contract_private_details& cpd,
uint64_t unlock_time, uint64_t expiration_time,
uint64_t tx_version,
uint64_t tx_version,
size_t tx_hardfork_id,
const transaction& escrow_template_tx, /* IN (needed for ms output, tx pub key) */
uint64_t custom_config_mask, /* IN */
transaction& tx /* OUT */
@ -420,7 +423,7 @@ inline bool build_custom_escrow_release_template(
crypto::secret_key one_time_secret_key = AUTO_VAL_INIT(one_time_secret_key);
account_public_address crypt_address = AUTO_VAL_INIT(crypt_address);
bool r = construct_tx(b_keys, sources, destinations, extra, attachments, tx, tx_version, one_time_secret_key, unlock_time, crypt_address, expiration_time, 0, true, tx_flags);
bool r = construct_tx(b_keys, sources, destinations, extra, attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, unlock_time, crypt_address, expiration_time, 0, true, tx_flags);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
bool tx_fully_signed = false;
r = sign_multisig_input_in_tx(tx, 0, b_keys, escrow_template_tx, &tx_fully_signed);
@ -470,6 +473,7 @@ inline bool build_custom_escrow_accept_proposal(
uint64_t custom_config_mask, /* IN */
crypto::secret_key one_time_secret_key, /* IN */
uint64_t tx_version, /* IN */
size_t tx_hardfork_id, /* IN */
transaction& tx, /* IN (escrow template), OUT */
std::vector<tx_source_entry>& used_sources /* IN/OUT */
)
@ -496,9 +500,9 @@ inline bool build_custom_escrow_accept_proposal(
// generate release templates
bc_services::escrow_relese_templates_body rtb = AUTO_VAL_INIT(rtb);
r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_NORMAL, b_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx, custom_config_mask, rtb.tx_normal_template);
r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_NORMAL, b_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx_hardfork_id, tx, custom_config_mask, rtb.tx_normal_template);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_release_template(normal) failed");
r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_BURN, b_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx, custom_config_mask, rtb.tx_burn_template);
r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_BURN, b_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx_hardfork_id, tx, custom_config_mask, rtb.tx_burn_template);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_release_template(burn) failed");
// put release templates into the extra
@ -529,7 +533,7 @@ inline bool build_custom_escrow_accept_proposal(
sources.back().separately_signed_tx_complete = true;
account_public_address crypt_address = AUTO_VAL_INIT(crypt_address);
r = construct_tx(b_keys, sources, destinations, extra, attachments, tx, tx_version, one_time_secret_key, 0, crypt_address, 0, 0, true, tx_flags); // see comment above regarding unlock_time and expiration_time
r = construct_tx(b_keys, sources, destinations, extra, attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, 0, crypt_address, 0, 0, true, tx_flags); // see comment above regarding unlock_time and expiration_time
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
return true;
@ -545,6 +549,7 @@ inline bool build_custom_escrow_cancel_proposal(
uint64_t custom_config_mask, /* IN */
const transaction& escrow_template_tx, /* IN */
uint64_t tx_version, /* IN */
size_t tx_hardfork_id, /* IN */
transaction& tx, /* OUT */
std::vector<tx_source_entry>& used_sources /* IN/OUT */
)
@ -568,7 +573,7 @@ inline bool build_custom_escrow_cancel_proposal(
// generate cancel release template
bc_services::escrow_cancel_templates_body ctb = AUTO_VAL_INIT(ctb);
r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_CANCEL, a_keys, cpd, release_unlock_time, release_expiration_time, tx_version, escrow_template_tx, custom_config_mask, ctb.tx_cancel_template);
r = build_custom_escrow_release_template(BC_ESCROW_SERVICE_INSTRUCTION_RELEASE_CANCEL, a_keys, cpd, release_unlock_time, release_expiration_time, tx_version, tx_hardfork_id, escrow_template_tx, custom_config_mask, ctb.tx_cancel_template);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_release_template(cancel) failed");
// put release templates into the extra
@ -593,7 +598,7 @@ inline bool build_custom_escrow_cancel_proposal(
if (~custom_config_mask & eccf_cancellation_inv_crypt_address)
crypt_address = cpd.b_addr;
crypto::secret_key one_time_secret_key = AUTO_VAL_INIT(one_time_secret_key);
r = construct_tx(a_keys, sources, destinations, extra, attachments, tx, tx_version, one_time_secret_key, unlock_time, crypt_address, expiration_time, 0, true, tx_flags);
r = construct_tx(a_keys, sources, destinations, extra, attachments, tx, tx_version, tx_hardfork_id, one_time_secret_key, unlock_time, crypt_address, expiration_time, 0, true, tx_flags);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
return true;

View file

@ -503,10 +503,11 @@ bool escrow_incorrect_proposal::generate(std::vector<test_event_entry>& events)
// 1. create normal proposal and make sure it goes correctly through out the whole mechanism (test self-check)
// if it fails, it means build_custom_escrow_proposal() produced incorrect proposal
uint64_t tx_version = get_tx_version(get_block_height(blk_1r), m_hardforks);
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id);
uint64_t normal_escrow_mask = eccf_proposal_additional_attach | eccf_template_additional_extra | eccf_template_additional_attach;
transaction normal_escrow_proposal_tx = AUTO_VAL_INIT(normal_escrow_proposal_tx);
r = build_custom_escrow_proposal(events, blk_1r, miner_acc.get_keys(), cpd, 0, 0, 0, blk_1r.timestamp + 3600, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, normal_escrow_mask, tx_version, normal_escrow_proposal_tx, used_sources);
r = build_custom_escrow_proposal(events, blk_1r, miner_acc.get_keys(), cpd, 0, 0, 0, blk_1r.timestamp + 3600, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, normal_escrow_mask, tx_version, tx_hardfork_id, normal_escrow_proposal_tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
events.push_back(normal_escrow_proposal_tx);
@ -550,9 +551,9 @@ bool escrow_incorrect_proposal::generate(std::vector<test_event_entry>& events)
uint64_t config_mask = custom_config_masks[i].mask;
cpd.comment = "#" + std::to_string(i) + " " + custom_config_masks[i].name;
tx_version = get_tx_version(get_block_height(top_block), m_hardforks);
transaction escrow_proposal_tx = AUTO_VAL_INIT(escrow_proposal_tx);
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, 0, 0, top_block.timestamp + 3600, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, config_mask, tx_version, escrow_proposal_tx, used_sources);
tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id);
transaction escrow_proposal_tx{};
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, 0, 0, top_block.timestamp + 3600, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, config_mask, tx_version, tx_hardfork_id, escrow_proposal_tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(escrow_proposal_tx) << " is built for mask: " << cpd.comment, LOG_LEVEL_0);
@ -579,10 +580,10 @@ bool escrow_incorrect_proposal::generate(std::vector<test_event_entry>& events)
{
cpd.comment = "incorrect unlock time (past)";
transaction tx = AUTO_VAL_INIT(tx);
tx_version = get_tx_version(get_block_height(top_block), m_hardforks);
transaction tx{};
tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id);
// set unlock time to the past (suppose it's incorrect for escrow proposals)
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, top_block.timestamp, 0, top_block.timestamp, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx, used_sources);
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, top_block.timestamp, 0, top_block.timestamp, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx_hardfork_id, tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(tx) << " is built for " << cpd.comment, LOG_LEVEL_0);
events.push_back(tx);
@ -592,11 +593,11 @@ bool escrow_incorrect_proposal::generate(std::vector<test_event_entry>& events)
{
cpd.comment = "incorrect unlock time (future)";
transaction tx = AUTO_VAL_INIT(tx);
tx_version = get_tx_version(get_block_height(top_block), m_hardforks);
transaction tx{};
tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id);
// set unlock time to the future (suppose it's incorrect for escrow proposals)
uint64_t unlock_time = top_block.timestamp + 365 * 24 * 60 * 60;
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, unlock_time, 0, unlock_time, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx, used_sources);
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, unlock_time, 0, unlock_time, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx_hardfork_id, tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(tx) << " is built for " << cpd.comment, LOG_LEVEL_0);
events.push_back(tx);
@ -606,9 +607,9 @@ bool escrow_incorrect_proposal::generate(std::vector<test_event_entry>& events)
{
cpd.comment = "template zero expiration time";
transaction tx = AUTO_VAL_INIT(tx);
tx_version = get_tx_version(get_block_height(top_block), m_hardforks);
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, 0, 0, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx, used_sources);
transaction tx{};
tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id);
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, 0, 0, 0, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx_hardfork_id, tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(tx) << " is built for " << cpd.comment, LOG_LEVEL_0);
events.push_back(tx);
@ -618,11 +619,11 @@ bool escrow_incorrect_proposal::generate(std::vector<test_event_entry>& events)
{
cpd.comment = "proposal non-zero expiration time";
transaction tx = AUTO_VAL_INIT(tx);
tx_version = get_tx_version(get_block_height(top_block), m_hardforks);
transaction tx{};
tx_version = get_tx_version_and_hardfork_id(get_block_height(top_block), m_hardforks, tx_hardfork_id);
uint64_t proposal_expiration_time = top_block.timestamp + 12 * 60 * 60;
uint64_t template_expiration_time = top_block.timestamp + 12 * 60 * 60;
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, proposal_expiration_time, 0, template_expiration_time, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx, used_sources);
r = build_custom_escrow_proposal(events, top_block, miner_acc.get_keys(), cpd, 0, proposal_expiration_time, 0, template_expiration_time, 0, TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, eccf_normal, tx_version, tx_hardfork_id, tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
LOG_PRINT_YELLOW("proposal tx: " << get_transaction_hash(tx) << " is built for " << cpd.comment, LOG_LEVEL_0);
events.push_back(tx);
@ -1149,17 +1150,18 @@ bool escrow_incorrect_proposal_acceptance::generate(std::vector<test_event_entry
// create escrow proposal
bc_services::proposal_body prop = AUTO_VAL_INIT(prop);
transaction escrow_proposal_tx = AUTO_VAL_INIT(escrow_proposal_tx);
uint64_t tx_version = get_tx_version(get_block_height(blk_1r), m_hardforks);
r = build_custom_escrow_proposal(events, blk_1r, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_1r.timestamp + 36000, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, eccf_normal, tx_version, escrow_proposal_tx, used_sources, &prop);
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id);
r = build_custom_escrow_proposal(events, blk_1r, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_1r.timestamp + 36000, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, eccf_normal, tx_version, tx_hardfork_id, escrow_proposal_tx, used_sources, &prop);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
events.push_back(escrow_proposal_tx);
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, escrow_proposal_tx);
// create normal acceptance
tx_version = get_tx_version(get_block_height(blk_2), m_hardforks);
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_2), m_hardforks, tx_hardfork_id);
transaction escrow_normal_acceptance_tx = prop.tx_template;
uint64_t normal_acceptance_mask = eccf_acceptance_no_tsa_compression;
r = build_custom_escrow_accept_proposal(events, blk_2, 0, bob_acc.get_keys(), m_cpd, 0, 0, 0, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, normal_acceptance_mask, prop.tx_onetime_secret_key, tx_version, escrow_normal_acceptance_tx, used_sources);
r = build_custom_escrow_accept_proposal(events, blk_2, 0, bob_acc.get_keys(), m_cpd, 0, 0, 0, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, normal_acceptance_mask, prop.tx_onetime_secret_key, tx_version, tx_hardfork_id, escrow_normal_acceptance_tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_accept_proposal failed");
events.push_back(escrow_normal_acceptance_tx);
@ -1258,10 +1260,10 @@ bool escrow_incorrect_proposal_acceptance::generate(std::vector<test_event_entry
const auto &ccm_el = custom_config_masks[i];
uint64_t mask = ccm_el.mask;
tx_version = get_tx_version(get_block_height(prev_block), m_hardforks);
tx_version = get_tx_version_and_hardfork_id(get_block_height(prev_block), m_hardforks, tx_hardfork_id);
transaction incorrect_acceptance_tx = prop.tx_template;
r = build_custom_escrow_accept_proposal(events, prev_block, 0, bob_acc.get_keys(), m_cpd, ccm_el.unlock_time, ccm_el.expiration_time, ccm_el.release_unlock_time, ccm_el.release_expiration_time,
bob_fee_acceptance, m_bob_fee_release, mask, prop.tx_onetime_secret_key, tx_version, incorrect_acceptance_tx, used_sources);
bob_fee_acceptance, m_bob_fee_release, mask, prop.tx_onetime_secret_key, tx_version, tx_hardfork_id, incorrect_acceptance_tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_accept_proposal failed");
// In order to use the same escrow proposal to test different invalid acceptance we need to switch chains after each try
@ -1494,8 +1496,9 @@ bool escrow_custom_test::generate(std::vector<test_event_entry>& events) const
destinations.push_back(tx_destination_entry(chunk_amount, bob_acc.get_public_address()));
}
// no change back to the miner - it will become a fee
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0);
transaction tx_1{};
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_1);
@ -1949,7 +1952,8 @@ bool escrow_incorrect_cancel_proposal::generate(std::vector<test_event_entry>& e
}
// no change back to the miner - it will become a fee
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0);
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_1);
@ -1969,27 +1973,27 @@ bool escrow_incorrect_cancel_proposal::generate(std::vector<test_event_entry>& e
// create normal escrow proposal
bc_services::proposal_body prop = AUTO_VAL_INIT(prop);
uint64_t tx_version = get_tx_version(get_block_height(blk_1r), m_hardforks);
uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id);
transaction escrow_proposal_tx = AUTO_VAL_INIT(escrow_proposal_tx);
r = build_custom_escrow_proposal(events, blk_1r, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_1r.timestamp + 36000, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, eccf_normal, tx_version, escrow_proposal_tx, used_sources, &prop);
r = build_custom_escrow_proposal(events, blk_1r, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_1r.timestamp + 36000, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, eccf_normal, tx_version, tx_hardfork_id, escrow_proposal_tx, used_sources, &prop);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
events.push_back(escrow_proposal_tx);
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, escrow_proposal_tx);
// create normal escrow proposal acceptance
transaction escrow_normal_acceptance_tx = prop.tx_template;
tx_version = get_tx_version(get_block_height(blk_2), m_hardforks);
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_2), m_hardforks, tx_hardfork_id);
uint64_t normal_acceptance_mask = eccf_acceptance_no_tsa_compression;
r = build_custom_escrow_accept_proposal(events, blk_2, 0, bob_acc.get_keys(), m_cpd, 0, 0, 0, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, normal_acceptance_mask, prop.tx_onetime_secret_key, tx_version, escrow_normal_acceptance_tx, used_sources);
r = build_custom_escrow_accept_proposal(events, blk_2, 0, bob_acc.get_keys(), m_cpd, 0, 0, 0, 0, TESTS_DEFAULT_FEE, m_bob_fee_release, normal_acceptance_mask, prop.tx_onetime_secret_key, tx_version, tx_hardfork_id, escrow_normal_acceptance_tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_accept_proposal failed");
events.push_back(escrow_normal_acceptance_tx);
MAKE_NEXT_BLOCK_TX1(events, blk_3, blk_2, miner_acc, escrow_normal_acceptance_tx);
// create normal cancel proposal
tx_version = get_tx_version(get_block_height(blk_3), m_hardforks);
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_3), m_hardforks, tx_hardfork_id);
transaction escrow_normal_cancel_proposal_tx = AUTO_VAL_INIT(escrow_normal_cancel_proposal_tx);
r = build_custom_escrow_cancel_proposal(events, blk_3, 0, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_3.timestamp + 3600, TESTS_DEFAULT_FEE, eccf_normal, prop.tx_template, tx_version, escrow_normal_cancel_proposal_tx, used_sources);
r = build_custom_escrow_cancel_proposal(events, blk_3, 0, alice_acc.get_keys(), m_cpd, 0, 0, 0, blk_3.timestamp + 3600, TESTS_DEFAULT_FEE, eccf_normal, prop.tx_template, tx_version, tx_hardfork_id, escrow_normal_cancel_proposal_tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_cancel_proposal failed");
events.push_back(escrow_normal_cancel_proposal_tx);
@ -2057,9 +2061,9 @@ bool escrow_incorrect_cancel_proposal::generate(std::vector<test_event_entry>& e
uint64_t mask = ccm_el.mask;
transaction incorrect_cancellation_proposal_tx = prop.tx_template;
uint64_t tx_version = get_tx_version(get_block_height(blk_3), m_hardforks);
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_3), m_hardforks, tx_hardfork_id);
r = build_custom_escrow_cancel_proposal(events, prev_block, 0, alice_acc.get_keys(), m_cpd, ccm_el.unlock_time, ccm_el.expiration_time, ccm_el.release_unlock_time, ccm_el.release_expiration_time,
TESTS_DEFAULT_FEE, mask, prop.tx_template, tx_version, incorrect_cancellation_proposal_tx, used_sources);
TESTS_DEFAULT_FEE, mask, prop.tx_template, tx_version, tx_hardfork_id, incorrect_cancellation_proposal_tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_cancel_proposal failed");
// In order to use the same escrow proposal to test different invalid cancellations we need to switch chains after each try
@ -2985,9 +2989,10 @@ bool escrow_proposal_acceptance_in_alt_chain::generate(std::vector<test_event_en
// escrow proposal
bc_services::proposal_body prop = AUTO_VAL_INIT(prop);
uint64_t tx_version = get_tx_version(get_block_height(blk_1), m_hardforks);
size_t tx_hardfork_tx{};
uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1), m_hardforks, tx_hardfork_tx);
transaction escrow_proposal_tx = AUTO_VAL_INIT(escrow_proposal_tx);
r = build_custom_escrow_proposal(events, blk_1, alice_acc.get_keys(), cpd, 0, 0, 0, blk_1.timestamp + 36000, 0, TESTS_DEFAULT_FEE, bob_fee_release, eccf_normal, tx_version, escrow_proposal_tx, used_sources, &prop);
r = build_custom_escrow_proposal(events, blk_1, alice_acc.get_keys(), cpd, 0, 0, 0, blk_1.timestamp + 36000, 0, TESTS_DEFAULT_FEE, bob_fee_release, eccf_normal, tx_version, tx_hardfork_tx, escrow_proposal_tx, used_sources, &prop);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_proposal failed");
events.push_back(escrow_proposal_tx);
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1, miner_acc, escrow_proposal_tx);
@ -2995,10 +3000,10 @@ bool escrow_proposal_acceptance_in_alt_chain::generate(std::vector<test_event_en
MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_acc);
// escrow proposal acceptance
tx_version = get_tx_version(get_block_height(blk_2), m_hardforks);
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_2), m_hardforks, tx_hardfork_tx);
transaction escrow_normal_acceptance_tx = prop.tx_template;
uint64_t normal_acceptance_mask = eccf_normal; //eccf_acceptance_no_tsa_compression;
r = build_custom_escrow_accept_proposal(events, blk_2, 0, bob_acc.get_keys(), cpd, 0, 0, 0, 0, TESTS_DEFAULT_FEE, bob_fee_release, normal_acceptance_mask, prop.tx_onetime_secret_key, tx_version, escrow_normal_acceptance_tx, used_sources);
r = build_custom_escrow_accept_proposal(events, blk_2, 0, bob_acc.get_keys(), cpd, 0, 0, 0, 0, TESTS_DEFAULT_FEE, bob_fee_release, normal_acceptance_mask, prop.tx_onetime_secret_key, tx_version, tx_hardfork_tx, escrow_normal_acceptance_tx, used_sources);
CHECK_AND_ASSERT_MES(r, false, "build_custom_escrow_accept_proposal failed");
events.push_back(escrow_normal_acceptance_tx);

View file

@ -98,8 +98,9 @@ bool random_outs_and_burnt_coins::generate(std::vector<test_event_entry>& events
r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), m_amount * m_fake_amounts_count + TESTS_DEFAULT_FEE, 0);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
transaction tx_0 = AUTO_VAL_INIT(tx_0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
transaction tx_0{};
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
uint64_t burned_tx_amount_total = get_burned_amount(tx_0);

View file

@ -239,7 +239,7 @@ bool hard_fork_1_unlock_time_2_in_coinbase::generate(std::vector<test_event_entr
ut2.unlock_time_array.resize(blk_5.miner_tx.vout.size());
ut2.unlock_time_array[0] = get_block_height(blk_5) + CURRENCY_MINED_MONEY_UNLOCK_WINDOW;
blk_5.miner_tx.extra.push_back(ut2);
miner::find_nonce_for_given_block(blk_5, diff, get_block_height(blk_5));
find_nonce_for_given_block(blk_5, diff, get_block_height(blk_5));
// add blk_5 with modified miner tx
events.push_back(blk_5);
@ -437,7 +437,7 @@ bool hard_fork_1_checkpoint_basic_test::generate(std::vector<test_event_entry>&
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(alice_acc.get_keys(), sources, std::vector<tx_destination_entry>{ tx_destination_entry(MK_TEST_COINS(90) - TESTS_DEFAULT_FEE, miner_acc.get_public_address()) },
empty_attachment, tx_1, get_tx_version_from_events(events), stake_lock_time /* try to use stake unlock time -- should not work as it is not a coinbase */);
empty_attachment, tx_1, get_tx_version_from_events(events), 0, stake_lock_time /* try to use stake unlock time -- should not work as it is not a coinbase */);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
DO_CALLBACK(events, "mark_invalid_tx");
@ -882,7 +882,7 @@ bool hard_fork_1_pos_locked_height_vs_time::generate(std::vector<test_event_entr
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(alice_acc.get_keys(), sources, std::vector<tx_destination_entry>{ tx_destination_entry(stake_amount / 2, miner_acc.get_public_address()) },
empty_attachment, tx_1, get_tx_version_from_events(events), stake_unlock_time /* try to use stake unlock time -- should not work as it is not a coinbase */);
empty_attachment, tx_1, get_tx_version_from_events(events), 0, stake_unlock_time /* try to use stake unlock time -- should not work as it is not a coinbase */);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
DO_CALLBACK(events, "mark_invalid_tx");

View file

@ -82,7 +82,9 @@ bool hard_fork_4_consolidated_txs::generate(std::vector<test_event_entry>& event
destinations.push_back(tx_destination_entry(m_bob_amount, bob_acc.get_public_address()));
add_flags_to_all_destination_entries(tx_destination_entry_flags::tdef_explicit_native_asset_id, destinations);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_1, get_tx_version_from_events(events), one_time_secret_key,
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_1, tx_version, tx_hardfork_id, one_time_secret_key,
0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, TX_DEFAULT_FEE, gen_context);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
@ -119,7 +121,9 @@ bool hard_fork_4_consolidated_txs::generate(std::vector<test_event_entry>& event
std::vector<tx_destination_entry> destinations;
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_1, get_tx_version_from_events(events), one_time_secret_key,
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_1, tx_version, tx_hardfork_id, one_time_secret_key,
0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, 0 /* note zero fee here */, gen_context);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");

View file

@ -0,0 +1,93 @@
// Copyright (c) 2024 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chaingen.h"
#include "hard_fork_5.h"
#include "random_helper.h"
using namespace currency;
hard_fork_5_tx_version::hard_fork_5_tx_version()
{
REGISTER_CALLBACK_METHOD(hard_fork_5_tx_version, c1);
}
bool hard_fork_5_tx_version::generate(std::vector<test_event_entry>& events) const
{
//
// Test idea: ensure that the correct tx.hardfork_id is required after HF5.
//
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);
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks
REWIND_BLOCKS_N_WITH_TIME(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3);
// make a simple tx just to check HF5 tx.hardfork_id rule basic validity
MAKE_TX(events, tx_1, miner_acc, alice_acc, MK_TEST_COINS(1), blk_0r);
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_1);
//
// construct a tx with an incorrect hardfork_id and make sure it won't be accepted by either the tx pool or the core
//
std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations;
r = fill_tx_sources_and_destinations(events, blk_1, miner_acc, alice_acc, MK_TEST_COINS(7), TX_DEFAULT_FEE, 4, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_2{};
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1) + 1, m_hardforks, tx_hardfork_id);
size_t incorrect_tx_hardfork_id = 0;
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_2, tx_version, incorrect_tx_hardfork_id, 0); // note using incorrect hardfork id here
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
// mark as invalid, shouldn't be accepted by the tx pool
DO_CALLBACK(events, "mark_invalid_tx");
ADD_CUSTOM_EVENT(events, tx_2);
// now add tx_2 as 'kept_by_block', with tx pool checks turned off
ADD_CUSTOM_EVENT(events, event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true));
events.push_back(tx_2); // now tx should be accepted by the pool
ADD_CUSTOM_EVENT(events, event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, false));
// the block shouldn't be accepted, because of invalid tx_2
DO_CALLBACK(events, "mark_invalid_block");
MAKE_NEXT_BLOCK_TX1(events, blk_2_bad, blk_1, miner_acc, tx_2);
//
// reconstruct the same tx, now using the correct tx_hardfork_id, and make sure it will be accepted
//
tx_2 = transaction{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_2, tx_version, tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_2);
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1, miner_acc, tx_2);
REWIND_BLOCKS_N_WITH_TIME(events, blk_2r, blk_2, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
// epilogue
DO_CALLBACK(events, "c1");
return true;
}
bool hard_fork_5_tx_version::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry> &events)
{
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool");
size_t blocks_fetched = 0;
alice_wlt->refresh(blocks_fetched);
CHECK_AND_ASSERT_EQ(blocks_fetched, 2 * CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt.get(), "alice_wlt", MK_TEST_COINS(8)), false, "");
return true;
}

View file

@ -0,0 +1,14 @@
// Copyright (c) 2024 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 "chaingen.h"
#include "wallet_tests_basic.h"
struct hard_fork_5_tx_version : public wallet_test
{
hard_fork_5_tx_version();
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);
};

View file

@ -157,9 +157,10 @@ bool gen_uint_overflow_2::generate(std::vector<test_event_entry>& events) const
// sources.front().amount = destinations[0].amount + destinations[2].amount + destinations[3].amount + TESTS_DEFAULT_FEE
destinations.push_back(tx_destination_entry(sources.front().amount - TX_MAX_TRANSFER_AMOUNT - TX_MAX_TRANSFER_AMOUNT + 1 - TESTS_DEFAULT_FEE, bob_addr));
currency::transaction tx_1;
currency::transaction tx_1{};
std::vector<currency::attachment_v> attachments;
if (!construct_tx(miner_account.get_keys(), sources, destinations, attachments, tx_1, get_tx_version_from_events(events), 0))
size_t tx_hardfork_id{};
if (!construct_tx(miner_account.get_keys(), sources, destinations, attachments, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0))
return false;
events.push_back(tx_1);
@ -186,7 +187,7 @@ bool gen_uint_overflow_2::generate(std::vector<test_event_entry>& events) const
currency::transaction tx_2;
std::vector<currency::attachment_v> attachments2;
if (!construct_tx(bob_account.get_keys(), sources, destinations, attachments2, tx_2, get_tx_version_from_events(events), 0))
if (!construct_tx(bob_account.get_keys(), sources, destinations, attachments2, tx_2, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0))
return false;
events.push_back(tx_2);

View file

@ -237,8 +237,9 @@ bool block_template_vs_invalid_txs_from_pool::generate(std::vector<test_event_en
std::vector<tx_source_entry> sources;
r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), de.amount + TESTS_DEFAULT_FEE, 0);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
transaction tx_1m = AUTO_VAL_INIT(tx_1m);
r = construct_tx(miner_acc.get_keys(), sources, std::vector<tx_destination_entry>({ de }), empty_attachment, tx_1m, get_tx_version_from_events(events), 0);
transaction tx_1m;
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, std::vector<tx_destination_entry>({ de }), empty_attachment, tx_1m, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_1m);
@ -269,18 +270,18 @@ bool block_template_vs_invalid_txs_from_pool::generate(std::vector<test_event_en
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_1m);
se.ms_keys_count = boost::get<txout_multisig>(boost::get<currency::tx_out_bare>(tx_1m.vout[se.real_output_in_tx_index]).target).keys.size();
se.ms_sigs_count = 1;
transaction tx_2m = AUTO_VAL_INIT(tx_2m);
transaction tx_2m{};
r = construct_tx(bob_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, miner_acc.get_public_address()) }),
empty_attachment, tx_2m, get_tx_version_from_events(events), 0);
empty_attachment, tx_2m, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
bool input_fully_signed = false;
r = sign_multisig_input_in_tx(tx_2m, 0, bob_acc.get_keys(), tx_1m, &input_fully_signed);
CHECK_AND_ASSERT_MES(r && input_fully_signed, false, "sign_multisig_input_in_tx failed, input_fully_signed=" << input_fully_signed);
events.push_back(tx_2m);
transaction tx_2ma = AUTO_VAL_INIT(tx_2ma);
transaction tx_2ma{};
r = construct_tx(bob_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, miner_acc.get_public_address()) }),
empty_attachment, tx_2ma, get_tx_version_from_events(events), 0);
empty_attachment, tx_2ma, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
input_fully_signed = false;
r = sign_multisig_input_in_tx(tx_2ma, 0, bob_acc.get_keys(), tx_1m, &input_fully_signed);
@ -436,8 +437,9 @@ bool test_blockchain_vs_spent_multisig_outs::generate(std::vector<test_event_ent
r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), ms_addr_list, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, 0,
sources, destinations, true, true, 1);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_0 = AUTO_VAL_INIT(tx_0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
transaction tx_0{};
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_0);
@ -457,8 +459,8 @@ bool test_blockchain_vs_spent_multisig_outs::generate(std::vector<test_event_ent
sources.push_back(se);
destinations.clear();
destinations.push_back(tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, miner_acc.get_public_address()));
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0);
transaction tx_1{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
bool is_fully_signed = false;
r = sign_multisig_input_in_tx(tx_1, 0, miner_acc.get_keys(), tx_0, &is_fully_signed);

View file

@ -1,4 +1,4 @@
// Copyright (c) 2014-2024 Zano Project
// Copyright (c) 2014-2025 Zano Project
// Copyright (c) 2014-2018 The Louisdor Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -495,7 +495,8 @@ bool assets_and_explicit_native_coins_in_outs::generate(std::vector<test_event_e
std::vector<tx_destination_entry> destinations;
r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc, alice_acc, m_alice_initial_balance, TESTS_DEFAULT_FEE, 0, sources, destinations, true /* spends */, false /* unlock time */);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_0);
@ -701,7 +702,8 @@ bool asset_depoyment_and_few_zc_utxos::generate(std::vector<test_event_entry>& e
m_alice_initial_balance = TESTS_DEFAULT_FEE * 100;
r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), m_alice_initial_balance + TESTS_DEFAULT_FEE, 0);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_0);
@ -1017,16 +1019,10 @@ bool asset_operation_and_hardfork_checks::generate(
CHECK_AND_ASSERT_MES(success, false, "fail to fill sources, destinations");
tx_version = get_tx_version(get_block_height(blk_0r),
m_hardforks);
size_t tx_hardfork_id{};
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_0r), m_hardforks, tx_hardfork_id);
success = construct_tx(miner.get_keys(),
sources,
destinations,
empty_attachment,
tx_0,
tx_version,
0);
success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version, tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(success, false, "fail to construct tx_0");
@ -1058,7 +1054,7 @@ bool asset_operation_and_hardfork_checks::generate(
/* to = */ alice.get_public_address(),
/* asset_id = */ currency::null_pkey);
tx_version = get_tx_version(get_block_height(blk_1r), m_hardforks);
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_1r), m_hardforks, tx_hardfork_id);
size_t hf_n = m_hardforks.get_the_most_recent_hardfork_id_for_height(get_block_height(blk_1r));
fill_ado_version_based_onhardfork(m_ado_hello, hf_n);
fill_adb_version_based_onhardfork(*m_ado_hello.opt_descriptor, hf_n);
@ -1069,6 +1065,7 @@ bool asset_operation_and_hardfork_checks::generate(
empty_attachment,
tx_1,
tx_version,
tx_hardfork_id,
stub,
0);
@ -1105,8 +1102,7 @@ bool asset_operation_and_hardfork_checks::generate(
CHECK_AND_ASSERT_MES(success, false, "fail to fill sources, destinations");
tx_version = get_tx_version(get_block_height(blk_2r),
m_hardforks);
tx_version = get_tx_version_and_hardfork_id(get_block_height(blk_2r), m_hardforks, tx_hardfork_id);
hf_n = m_hardforks.get_the_most_recent_hardfork_id_for_height(get_block_height(blk_2r));
fill_ado_version_based_onhardfork(m_ado_hello, hf_n);
@ -1118,6 +1114,7 @@ bool asset_operation_and_hardfork_checks::generate(
empty_attachment,
tx_2,
tx_version,
tx_hardfork_id,
stub,
0);
@ -1159,6 +1156,7 @@ bool asset_operation_and_hardfork_checks::generate(
/* attachments = */ {m_ado_bye},
tx_3,
tx_version,
hf_n,
0);
CHECK_AND_ASSERT_MES(success, false, "fail to construct tx_3");
@ -1199,6 +1197,7 @@ bool asset_operation_and_hardfork_checks::generate(
/* attachments = */ {m_ado_bye},
tx_4,
tx_version,
hf_n,
stub,
0);
@ -1270,18 +1269,6 @@ bool asset_operation_and_hardfork_checks::c2(
asset_operation_in_consolidated_tx::asset_operation_in_consolidated_tx()
{
m_adb_alice_currency.version = ASSET_DESCRIPTOR_BASE_HF4_VER;
m_adb_alice_currency.total_max_supply = 1'000'000'000'000'000'000;
m_adb_alice_currency.current_supply = 1'000'000'000'000'000'000;
m_adb_alice_currency.ticker = "ALC";
m_adb_alice_currency.full_name = "ALICE";
m_adb_alice_currency.meta_info = "Currency created by Alice";
m_adb_alice_currency.hidden_supply = false;
m_ado_alice_currency.operation_type = ASSET_DESCRIPTOR_OPERATION_REGISTER;
m_ado_alice_currency.opt_asset_id = currency::null_pkey;
m_ado_alice_currency.version = ASSET_DESCRIPTOR_OPERATION_HF4_VER;
REGISTER_CALLBACK_METHOD(asset_operation_in_consolidated_tx, assert_balances);
REGISTER_CALLBACK_METHOD(asset_operation_in_consolidated_tx, assert_alice_currency_not_registered);
}
@ -1289,11 +1276,13 @@ asset_operation_in_consolidated_tx::asset_operation_in_consolidated_tx()
bool asset_operation_in_consolidated_tx::generate(std::vector<test_event_entry>& events) const
{
// Test idea: make sure that the core rule prohibiting operations with assets in TX_FLAG_SIGNATURE_MODE_SEPARATE transactions works.
bool success {};
transaction tx_2 {};
uint64_t tx_version {};
crypto::secret_key one_time {};
tx_generation_context context_tx_2 {};
bool success{};
transaction tx_2{};
uint64_t tx_version{};
crypto::secret_key one_time{};
tx_generation_context context_tx_2{};
asset_descriptor_base adb_alice_currency{};
asset_descriptor_operation ado_alice_currency{};
GENERATE_ACCOUNT(miner);
GENERATE_ACCOUNT(alice);
GENERATE_ACCOUNT(bob);
@ -1301,8 +1290,19 @@ bool asset_operation_in_consolidated_tx::generate(std::vector<test_event_entry>&
m_accounts.push_back(miner);
m_accounts.push_back(alice);
m_accounts.push_back(bob);
m_adb_alice_currency.owner = m_accounts.at(ALICE_ACC_IDX).get_public_address().spend_public_key;
m_ado_alice_currency.opt_descriptor = m_adb_alice_currency;
adb_alice_currency.version = ASSET_DESCRIPTOR_BASE_HF4_VER;
adb_alice_currency.total_max_supply = 1'000'000'000'000'000'000;
adb_alice_currency.current_supply = 1'000'000'000'000'000'000;
adb_alice_currency.ticker = "ALC";
adb_alice_currency.full_name = "ALICE";
adb_alice_currency.meta_info = "Currency created by Alice";
adb_alice_currency.hidden_supply = false;
adb_alice_currency.owner = m_accounts.at(ALICE_ACC_IDX).get_public_address().spend_public_key;
ado_alice_currency.opt_descriptor = adb_alice_currency;
ado_alice_currency.operation_type = ASSET_DESCRIPTOR_OPERATION_REGISTER;
ado_alice_currency.opt_asset_id = currency::null_pkey;
ado_alice_currency.version = ASSET_DESCRIPTOR_OPERATION_HF4_VER;
MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time());
DO_CALLBACK(events, "configure_core");
@ -1317,16 +1317,16 @@ bool asset_operation_in_consolidated_tx::generate(std::vector<test_event_entry>&
DO_CALLBACK(events, "assert_balances");
{
std::vector<tx_source_entry> sources {};
std::vector<tx_destination_entry> destinations {};
std::vector<tx_source_entry> sources{};
std::vector<tx_destination_entry> destinations{};
success = fill_tx_sources(sources, events, blk_2r, alice.get_keys(), MK_TEST_COINS(5), 1);
CHECK_AND_ASSERT_MES(success, false, "failed to fill transaction sources on step 1");
destinations.emplace_back(MK_TEST_COINS(5), bob.get_public_address());
destinations.emplace_back(MK_TEST_COINS(/* 10 - 5 - 1 = */ 4), alice.get_public_address());
tx_version = get_tx_version(get_block_height(blk_2r), m_hardforks);
success = construct_tx(alice.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_2, tx_version, one_time, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, TESTS_DEFAULT_FEE,
context_tx_2);
success = construct_tx(alice.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_2, tx_version, one_time, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE, TESTS_DEFAULT_FEE,
context_tx_2);
CHECK_AND_ASSERT_MES(success, false, "failed to construct transaction tx_2 on step 1");
}
@ -1335,26 +1335,26 @@ bool asset_operation_in_consolidated_tx::generate(std::vector<test_event_entry>&
ADD_CUSTOM_EVENT(events, tx_2);
{
std::vector<tx_source_entry> sources {};
std::vector<tx_destination_entry> destinations {};
std::vector<tx_source_entry> sources{};
std::vector<tx_destination_entry> destinations{};
success = fill_tx_sources(sources, events, blk_2r, bob.get_keys(), MK_TEST_COINS(5), 0);
CHECK_AND_ASSERT_MES(success, false, "failed to fill transaction sources on step 2");
for(tx_source_entry& source : sources)
for (tx_source_entry& source : sources)
{
source.separately_signed_tx_complete = true;
}
destinations.emplace_back(MK_TEST_COINS(5), alice.get_public_address());
destinations.emplace_back(MK_TEST_COINS(/* 10 - 5 - 0 = */ 5), bob.get_public_address());
destinations.emplace_back(m_adb_alice_currency.current_supply, alice.get_public_address(), null_pkey);
destinations.emplace_back(adb_alice_currency.current_supply, alice.get_public_address(), null_pkey);
tx_version = get_tx_version(get_block_height(blk_2r), m_hardforks);
size_t hf_n = m_hardforks.get_the_most_recent_hardfork_id_for_height(get_block_height(blk_2r));
fill_ado_version_based_onhardfork(m_ado_alice_currency, hf_n);
fill_adb_version_based_onhardfork(*m_ado_alice_currency.opt_descriptor, hf_n);
success = construct_tx(bob.get_keys(), sources, destinations, { m_ado_alice_currency }, empty_attachment, tx_2, tx_version, one_time, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE,
/* fee = */ 0, context_tx_2);
fill_ado_version_based_onhardfork(ado_alice_currency, hf_n);
fill_adb_version_based_onhardfork(*ado_alice_currency.opt_descriptor, hf_n);
success = construct_tx(bob.get_keys(), sources, destinations, {ado_alice_currency}, empty_attachment, tx_2, tx_version, one_time, 0, 0, 0, true, TX_FLAG_SIGNATURE_MODE_SEPARATE,
/* fee = */ 0, context_tx_2);
CHECK_AND_ASSERT_MES(success, false, "failed to construct transaction tx_2 on step 2");
}
@ -1363,15 +1363,15 @@ bool asset_operation_in_consolidated_tx::generate(std::vector<test_event_entry>&
// Core rejects transaction tx_2. The balances of Alice, Bob haven't changed: Alice has 10 coins, Bob has 10 coins.
DO_CALLBACK(events, "assert_balances");
// Alice's asset hasn't registered, because transaction tx_2 was rejected.
DO_CALLBACK(events, "assert_alice_currency_not_registered");
DO_CALLBACK_PARAMS_STR(events, "assert_alice_currency_not_registered", t_serializable_object_to_blob(ado_alice_currency));
return true;
}
bool asset_operation_in_consolidated_tx::assert_balances(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
bool asset_operation_in_consolidated_tx::assert_balances(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events) const
{
std::shared_ptr<tools::wallet2> alice_wallet{init_playtime_test_wallet(events, c, ALICE_ACC_IDX)};
std::shared_ptr<tools::wallet2> bob_wallet{init_playtime_test_wallet(events, c, BOB_ACC_IDX)};
const auto alice_wallet{init_playtime_test_wallet_t<tools::wallet2>(events, c, ALICE_ACC_IDX)};
const auto bob_wallet{init_playtime_test_wallet_t<tools::wallet2>(events, c, BOB_ACC_IDX)};
alice_wallet->refresh();
bob_wallet->refresh();
@ -1382,14 +1382,28 @@ bool asset_operation_in_consolidated_tx::assert_balances(currency::core& c, size
return true;
}
bool asset_operation_in_consolidated_tx::assert_alice_currency_not_registered(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
bool asset_operation_in_consolidated_tx::assert_alice_currency_not_registered(const currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events) const
{
crypto::point_t asset_id_point{};
crypto::public_key asset_id{};
currency::asset_descriptor_base stub{};
asset_descriptor_operation ado{};
CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(m_ado_alice_currency, &asset_id_point, &asset_id), false, "fail to calculate asset id");
CHECK_AND_ASSERT_MES(!c.get_blockchain_storage().get_asset_info(asset_id, stub), false, "unregistered asset has info");
{
const auto serialized_ado{boost::get<callback_entry>(events.at(ev_index)).callback_params};
CHECK_AND_ASSERT_MES(t_unserializable_object_from_blob(ado, serialized_ado), false, "ADO deserialization failed");
}
{
crypto::point_t point_asset_id{};
CHECK_AND_ASSERT_MES(get_or_calculate_asset_id(ado, &point_asset_id, &asset_id), false, "fail to calculate asset id");
}
{
currency::asset_descriptor_base adb_stub{};
CHECK_AND_ASSERT_MES(!c.get_blockchain_storage().get_asset_info(asset_id, adb_stub), false, "unregistered asset has info");
}
return true;
}
@ -2068,6 +2082,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec
GENERATE_ACCOUNT(miner);
GENERATE_ACCOUNT(alice);
transaction tx_0{}, tx_1{}, tx_2{}, tx_3{}, tx_4{};
size_t tx_hardfork_id{};
m_accounts.push_back(miner);
m_accounts.push_back(alice);
@ -2091,7 +2106,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec
success = fill_tx_sources_and_destinations(events, top, miner.get_keys(), alice.get_public_address(), MK_TEST_COINS(8), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_EQ(success, true);
success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version(get_block_height(top), m_hardforks), 0);
success = construct_tx(miner.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_hardfork_id(get_block_height(top), m_hardforks, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_EQ(success, true);
}
@ -2115,7 +2130,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec
destinations.emplace_back(ado.opt_descriptor->current_supply, alice.get_public_address(), null_pkey);
CHECK_AND_ASSERT_EQ(ado.opt_descriptor->total_max_supply, 0);
CHECK_AND_ASSERT_EQ(ado.opt_descriptor->total_max_supply, ado.opt_descriptor->current_supply);
success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_1, get_tx_version(get_block_height(top), m_hardforks), one_time, 0);
success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_1, get_tx_version_and_hardfork_id(get_block_height(top), m_hardforks, tx_hardfork_id), tx_hardfork_id, one_time, 0);
CHECK_AND_ASSERT_EQ(success, true);
}
@ -2140,7 +2155,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec
CHECK_AND_ASSERT_EQ(success, true);
destinations.emplace_back(ado.opt_descriptor->current_supply, alice.get_public_address(), null_pkey);
CHECK_AND_ASSERT_MES(ado.opt_descriptor->current_supply > ado.opt_descriptor->total_max_supply, false, "current_supply <= total_max_supply");
success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_2, get_tx_version(get_block_height(top), m_hardforks), one_time, 0);
success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_2, get_tx_version_and_hardfork_id(get_block_height(top), m_hardforks, tx_hardfork_id), tx_hardfork_id, one_time, 0);
CHECK_AND_ASSERT_EQ(success, true);
}
@ -2165,7 +2180,7 @@ bool asset_current_and_total_supplies_comparative_constraints::generate(std::vec
CHECK_AND_ASSERT_EQ(success, true);
destinations.emplace_back(ado.opt_descriptor->current_supply, alice.get_public_address(), null_pkey);
CHECK_AND_ASSERT(ado.opt_descriptor->current_supply <= ado.opt_descriptor->total_max_supply, false);
success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_3, get_tx_version(get_block_height(top), m_hardforks), one_time, 0);
success = construct_tx(alice.get_keys(), sources, destinations, {ado}, empty_attachment, tx_3, get_tx_version_and_hardfork_id(get_block_height(top), m_hardforks, tx_hardfork_id), tx_hardfork_id, one_time, 0);
CHECK_AND_ASSERT_EQ(success, true);
}

View file

@ -74,12 +74,8 @@ struct asset_operation_in_consolidated_tx : public wallet_test
public:
asset_operation_in_consolidated_tx();
bool generate(std::vector<test_event_entry>& events) const;
bool assert_balances(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
bool assert_alice_currency_not_registered(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
private:
mutable currency::asset_descriptor_base m_adb_alice_currency{};
mutable currency::asset_descriptor_operation m_ado_alice_currency{};
bool assert_balances(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events) const;
bool assert_alice_currency_not_registered(const currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events) const;
};
struct eth_signed_asset_basics : public wallet_test

View file

@ -880,7 +880,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), ms_addr_list, amount, TESTS_DEFAULT_FEE, 0, sources, destinations, true, true, 4);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx = AUTO_VAL_INIT(tx);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r == false, false, "construct_tx was expected to fail, but successed");
@ -893,7 +893,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_1);
@ -917,7 +917,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
// Transaction should be successfully created, but rejected by the core
transaction tx_2 = AUTO_VAL_INIT(tx_2);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ de }), empty_attachment, tx_2, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ de }), empty_attachment, tx_2, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
bool tx_fully_signed = false;
r = sign_multisig_input_in_tx(tx_2, 0, bob_acc.get_keys(), tx_1, &tx_fully_signed);
@ -947,7 +947,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
se.ms_sigs_count = 2;
transaction tx_3 = AUTO_VAL_INIT(tx_3);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address()) }), empty_attachment, tx_3, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address()) }), empty_attachment, tx_3, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
r = sign_multisig_input_in_tx(tx_3, 0, bob_acc.get_keys(), tx_1, &tx_fully_signed);
CHECK_AND_ASSERT_MES(r && !tx_fully_signed, false, "sign_multisig_input_in_tx failed, tx_fully_signed : " << tx_fully_signed);
@ -966,7 +966,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_4 = AUTO_VAL_INIT(tx_4);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_4, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_4, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_4);
@ -984,7 +984,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
se.ms_sigs_count = 3;
transaction tx_5 = AUTO_VAL_INIT(tx_5);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_5, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_5, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
// use sign_multisig_input_in_tx_custom to create tx with more signatures (3) than minimum_sigs (1)
@ -1009,7 +1009,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_6 = AUTO_VAL_INIT(tx_6);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_6, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_6, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_6);
@ -1028,7 +1028,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
se.ms_sigs_count = 4;
transaction tx_7 = AUTO_VAL_INIT(tx_7);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_7, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_7, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
// use sign_multisig_input_in_tx_custom to create tx with more signatures (4) than minimum_sigs (1)
@ -1051,7 +1051,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_8 = AUTO_VAL_INIT(tx_8);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_8, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_8, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_8);
@ -1071,7 +1071,7 @@ bool multisig_minimum_sigs::generate(std::vector<test_event_entry>& events) cons
se.ms_sigs_count = redundant_keys_count;
transaction tx_9 = AUTO_VAL_INIT(tx_9);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_9, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }), empty_attachment, tx_9, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
boost::get<currency::NLSAG_sig>(tx_9.signatures[0]).s.resize(redundant_keys_count, invalid_signature);
@ -1202,7 +1202,7 @@ bool multisig_and_unlock_time::generate(std::vector<test_event_entry>& events) c
uint64_t unlock_time_2 = blk_0r.timestamp + DIFFICULTY_TOTAL_TARGET * 6 + CURRENCY_LOCKED_TX_ALLOWED_DELTA_SECONDS;
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), unlock_time, CURRENCY_TO_KEY_OUT_RELAXED, true);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0, unlock_time, CURRENCY_TO_KEY_OUT_RELAXED, true);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
CHECK_AND_ASSERT_MES(get_tx_max_unlock_time(tx_1) == unlock_time, false, "Unlock time was not correctly set");
events.push_back(tx_1);
@ -1232,7 +1232,7 @@ bool multisig_and_unlock_time::generate(std::vector<test_event_entry>& events) c
// tx_2 should be created ok, but rejected by the core, as one of input refers to a locked tx
// Note: tx_2 has unlock_time_2 specified
transaction tx_2 = AUTO_VAL_INIT(tx_2);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_2, get_tx_version_from_events(events), unlock_time_2, CURRENCY_TO_KEY_OUT_RELAXED, true);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_2, get_tx_version_from_events(events), 0, unlock_time_2, CURRENCY_TO_KEY_OUT_RELAXED, true);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
bool tx_fully_signed = false;
@ -1256,7 +1256,7 @@ bool multisig_and_unlock_time::generate(std::vector<test_event_entry>& events) c
r = fill_tx_sources_and_destinations(events, blk_2, alice_acc, bob_acc, amount - TESTS_DEFAULT_FEE * 2, TESTS_DEFAULT_FEE, 0 /*nmix*/, sources, destinations, true, false /* check_for_unlocktime */);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_3{};
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_from_events(events), 0);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_from_events(events), 0, 0 /* unlock time */, 0 /* mix attib */);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_3);
@ -1281,7 +1281,7 @@ bool multisig_and_unlock_time::generate(std::vector<test_event_entry>& events) c
crypto::secret_key stub_key = AUTO_VAL_INIT(stub_key);
etc_tx_details_expiration_time extra_expiration_time = AUTO_VAL_INIT(extra_expiration_time);
extra_expiration_time.v = expiration_time;
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<extra_v>({ extra_expiration_time }), empty_attachment, tx_4, get_tx_version_from_events(events), stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true);
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<extra_v>({ extra_expiration_time }), empty_attachment, tx_4, get_tx_version_from_events(events), 0, stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
CHECK_AND_ASSERT_MES(get_tx_expiration_time(tx_4) == expiration_time, false, "Expiration time was not correctly set");
DO_CALLBACK(events, "mark_invalid_tx");
@ -1289,7 +1289,7 @@ bool multisig_and_unlock_time::generate(std::vector<test_event_entry>& events) c
// add similar tx (same sources and destinations) with no expiration_time - should be accepted by the core
transaction tx_5 = AUTO_VAL_INIT(tx_5);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_5, get_tx_version_from_events(events), stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_extra, empty_attachment, tx_5, get_tx_version_from_events(events), 0, stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_5);
@ -1316,7 +1316,7 @@ bool multisig_and_unlock_time::generate(std::vector<test_event_entry>& events) c
extra_expiration_time = AUTO_VAL_INIT(extra_expiration_time);
extra_expiration_time.v = expiration_time;
transaction tx_6 = AUTO_VAL_INIT(tx_6);
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<extra_v>({ extra_expiration_time }), empty_attachment, tx_6, get_tx_version_from_events(events), stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true);
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<extra_v>({ extra_expiration_time }), empty_attachment, tx_6, get_tx_version_from_events(events), 0, stub_key, 0, CURRENCY_TO_KEY_OUT_RELAXED, true);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
CHECK_AND_ASSERT_MES(get_tx_expiration_time(tx_6) == expiration_time, false, "Expiration time was not correctly set");
r = sign_multisig_input_in_tx(tx_6, tx_5_ms_out_idx, miner_acc.get_keys(), tx_5, &tx_fully_signed);
@ -1429,7 +1429,7 @@ bool multisig_and_coinbase::generate(std::vector<test_event_entry>& events) cons
destinations.assign({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, bob_acc.get_public_address()) });
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
bool fully_signed_tx = false;
r = sign_multisig_input_in_tx(tx_1, 0, alice_acc.get_keys(), blk_1.miner_tx, &fully_signed_tx);
@ -1459,7 +1459,7 @@ bool multisig_and_coinbase::generate(std::vector<test_event_entry>& events) cons
r = fill_tx_sources_and_destinations(events, prev_block, miner_acc.get_keys(), ms_addr_list, blk_2_reward, TESTS_DEFAULT_FEE, 0, sources, destinations, false, false, 1);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction miner_tx = AUTO_VAL_INIT(miner_tx);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, miner_tx, get_tx_version_from_events(events), height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW, CURRENCY_TO_KEY_OUT_RELAXED, true);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, miner_tx, get_tx_version_from_events(events), 0, height + CURRENCY_MINED_MONEY_UNLOCK_WINDOW, CURRENCY_TO_KEY_OUT_RELAXED, true);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
// replace vin with coinbase input
@ -1477,7 +1477,7 @@ bool multisig_and_coinbase::generate(std::vector<test_event_entry>& events) cons
r = generator.construct_block_manually(b, prev_block, miner_acc, test_generator::bf_miner_tx, 0, 0, 0, null_hash, 1, miner_tx);
CHECK_AND_ASSERT_MES(r, false, "construct_block_manually failed");
}
events.push_back(blk_3);
ADD_CUSTOM_EVENT(events, blk_3);
// rewind blocks to be able to spend mined money
REWIND_BLOCKS_N(events, blk_3r, blk_3, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
@ -1493,7 +1493,7 @@ bool multisig_and_coinbase::generate(std::vector<test_event_entry>& events) cons
transaction tx_2 = AUTO_VAL_INIT(tx_2);
r = construct_tx(alice_acc.get_keys(), std::vector<tx_source_entry>({ se }), std::vector<tx_destination_entry>({ tx_destination_entry(se.amount - TESTS_DEFAULT_FEE, alice_acc.get_public_address()) }),
empty_attachment, tx_2, get_tx_version_from_events(events), 0);
empty_attachment, tx_2, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
r = sign_multisig_input_in_tx(tx_2, 0, alice_acc.get_keys(), blk_3.miner_tx, &fully_signed_tx);
@ -1638,7 +1638,7 @@ multisig_and_checkpoints::multisig_and_checkpoints()
bool multisig_and_checkpoints::set_cp(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
currency::checkpoints checkpoints;
checkpoints.add_checkpoint(15, "fda3e645fbfd0f4852aa68e6ad021c9005c9faf2d7ba6b1b3c8e24efb9c0e8d0");
checkpoints.add_checkpoint(15, "a78fa870608991aa773d5d5aaf684ac77fea30c3e103b00d3c05c15912215c31");
c.set_checkpoints(std::move(checkpoints));
return true;
@ -2259,7 +2259,7 @@ bool multisig_n_participants_seq_signing::generate(std::vector<test_event_entry>
r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), ms_addr_list, ms_amount, TESTS_DEFAULT_FEE, 0, sources, destinations, true, true, m_minimum_signs_to_spend);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0, 0);
events.push_back(tx_1);
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_1);
@ -2289,7 +2289,7 @@ bool multisig_n_participants_seq_signing::generate(std::vector<test_event_entry>
// construct a transaction (no participants keys are provided, thus no signs for ms input are created)
transaction tx = AUTO_VAL_INIT(tx);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx, get_tx_version_from_events(events), 0);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
// sign the transaction by (m_minimum_signs_to_spend) participants in random order

View file

@ -633,7 +633,7 @@ bool offer_removing_and_selected_output::generate(std::vector<test_event_entry>&
std::vector<tx_source_entry> sources;
r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), destinations_amount + TESTS_DEFAULT_FEE, 0);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_0);
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);

View file

@ -174,7 +174,8 @@ bool pos_mining_with_decoys::generate(std::vector<test_event_entry>& events) con
destinations.emplace_back(COIN, carol_acc.get_public_address());
transaction tx_0{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_0);
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);

View file

@ -28,6 +28,7 @@ void pos_block_builder::step1_init_header(const hard_forks_descriptor& hardforks
m_height = block_height;
m_context.zarcanum = hardforks.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, m_height);
m_miner_tx_version = get_tx_version_and_hardfork_id(m_height, hardforks, m_miner_tx_hardfork_id);
m_step = 1;
}
@ -160,7 +161,6 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
{
CHECK_AND_ASSERT_THROW_MES(m_step == 3, "pos_block_builder: incorrect step sequence");
uint64_t tx_version = m_context.zarcanum ? TRANSACTION_VERSION_POST_HF4 : TRANSACTION_VERSION_PRE_HF4;
pos_entry pe{};
pe.stake_unlock_time = 0; // TODO
pe.amount = m_context.stake_amount;
@ -171,7 +171,8 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
size_t estimated_block_size = m_txs_total_size;
m_block.miner_tx = transaction{};
bool r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee,
reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use);
reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, m_miner_tx_version, m_miner_tx_hardfork_id,
extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use);
CHECK_AND_ASSERT_THROW_MES(r, "construct_miner_tx failed");
estimated_block_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx);
@ -180,7 +181,8 @@ void pos_block_builder::step4_generate_coinbase_tx(size_t median_size,
{
m_block.miner_tx = transaction{};
r = construct_miner_tx(m_height, median_size, already_generated_coins, estimated_block_size, m_total_fee,
reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, tx_version, extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use);
reward_receiver_address, stakeholder_address, m_block.miner_tx, block_reward_without_fee, m_block_reward, m_miner_tx_version, m_miner_tx_hardfork_id,
extra_nonce, max_outs, true, pe, &m_miner_tx_tgc, tx_one_time_key_to_use);
CHECK_AND_ASSERT_THROW_MES(r, "construct_homemade_pos_miner_tx failed");
cumulative_size = m_txs_total_size + get_object_blobsize(m_block.miner_tx);

View file

@ -76,6 +76,8 @@ struct pos_block_builder
uint64_t m_total_fee = 0;
//currency::stake_kernel m_stake_kernel {};
size_t m_height = 0;
size_t m_miner_tx_hardfork_id = 0;
uint64_t m_miner_tx_version = 0;
size_t m_pos_stake_output_gindex = 0;
uint64_t m_block_reward = 0;
currency::tx_generation_context m_miner_tx_tgc {};

View file

@ -42,17 +42,17 @@ bool test_transaction_generation_and_ring_signature()
account_base rv_acc2;
rv_acc2.generate();
transaction tx_mine_1;
construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().account_address, miner_acc1.get_keys().account_address, tx_mine_1, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4);
construct_miner_tx(0, 0, 0, 10, 0, miner_acc1.get_keys().account_address, miner_acc1.get_keys().account_address, tx_mine_1, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0);
transaction tx_mine_2;
construct_miner_tx(0, 0, 0, 0, 0, miner_acc2.get_keys().account_address, miner_acc2.get_keys().account_address, tx_mine_2, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4);
construct_miner_tx(0, 0, 0, 0, 0, miner_acc2.get_keys().account_address, miner_acc2.get_keys().account_address, tx_mine_2, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0);
transaction tx_mine_3;
construct_miner_tx(0, 0, 0, 0, 0, miner_acc3.get_keys().account_address, miner_acc3.get_keys().account_address, tx_mine_3, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4);
construct_miner_tx(0, 0, 0, 0, 0, miner_acc3.get_keys().account_address, miner_acc3.get_keys().account_address, tx_mine_3, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0);
transaction tx_mine_4;
construct_miner_tx(0, 0, 0, 0, 0, miner_acc4.get_keys().account_address, miner_acc4.get_keys().account_address, tx_mine_4, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4);
construct_miner_tx(0, 0, 0, 0, 0, miner_acc4.get_keys().account_address, miner_acc4.get_keys().account_address, tx_mine_4, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0);
transaction tx_mine_5;
construct_miner_tx(0, 0, 0, 0, 0, miner_acc5.get_keys().account_address, miner_acc5.get_keys().account_address, tx_mine_5, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4);
construct_miner_tx(0, 0, 0, 0, 0, miner_acc5.get_keys().account_address, miner_acc5.get_keys().account_address, tx_mine_5, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0);
transaction tx_mine_6;
construct_miner_tx(0, 0, 0, 0, 0, miner_acc6.get_keys().account_address, miner_acc6.get_keys().account_address, tx_mine_6, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4);
construct_miner_tx(0, 0, 0, 0, 0, miner_acc6.get_keys().account_address, miner_acc6.get_keys().account_address, tx_mine_6, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0);
//fill inputs entry
typedef tx_source_entry::output_entry tx_output_entry;
@ -101,7 +101,7 @@ bool test_transaction_generation_and_ring_signature()
transaction tx_rc1;
std::vector<currency::attachment_v> attachments;
bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, attachments, tx_rc1, get_tx_version(0, hf), 0);
bool r = construct_tx(miner_acc2.get_keys(), sources, destinations, attachments, tx_rc1, get_tx_version(0, hf), 0, 0);
CHECK_AND_ASSERT_MES(r, false, "failed to construct transaction");
crypto::hash pref_hash = get_transaction_prefix_hash(tx_rc1);
@ -139,7 +139,7 @@ bool test_block_creation()
uint64_t block_reward_without_fee = 0;
uint64_t block_reward = 0;
block b;
r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4);
r = construct_miner_tx(90, epee::misc_utils::median(szs), 3553616528562147, 33094, 10000000, adr, adr, b.miner_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0);
return r;
}

View file

@ -1239,8 +1239,9 @@ bool tx_expiration_time::generate(std::vector<test_event_entry>& events) const
std::vector<tx_destination_entry> destinations;
r = fill_tx_sources_and_destinations(events, blk_2, alice_acc.get_keys(), bob_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_2 = AUTO_VAL_INIT(tx_2);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_2, get_tx_version_from_events(events), 0);
transaction tx_2{};
size_t tx_hardfork_id{};
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_2, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
set_tx_expiration_time(tx_2, ts_median + TX_EXPIRATION_MEDIAN_SHIFT + 1); // one second greather than minimum allowed
r = resign_tx(alice_acc.get_keys(), sources, tx_2);
@ -1258,7 +1259,7 @@ bool tx_expiration_time::generate(std::vector<test_event_entry>& events) const
r = fill_tx_sources_and_destinations(events, blk_3, alice_acc.get_keys(), bob_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_3 = AUTO_VAL_INIT(tx_3);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_from_events(events), 0);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
set_tx_expiration_time(tx_3, ts_median + TX_EXPIRATION_MEDIAN_SHIFT + 0); // exact expiration time, should not pass (see core condition above)
r = resign_tx(alice_acc.get_keys(), sources, tx_3);
@ -1322,8 +1323,9 @@ bool tx_expiration_time_and_block_template::generate(std::vector<test_event_entr
std::vector<tx_destination_entry> destinations;
bool r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), miner_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_1 = AUTO_VAL_INIT(tx_1);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_from_events(events), 0);
transaction tx_1{};
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_1, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
uint64_t tx_1_expiration_time = ts_median + TX_EXPIRATION_MEDIAN_SHIFT + 1; // one second greather than minimum allowed
set_tx_expiration_time(tx_1, tx_1_expiration_time);
@ -1394,8 +1396,9 @@ bool tx_expiration_time_and_chain_switching::generate(std::vector<test_event_ent
std::vector<tx_destination_entry> destinations;
r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), miner_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_0 = AUTO_VAL_INIT(tx_0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
transaction tx_0{};
size_t tx_hardfork_id{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
uint64_t tx_0_expiration_time = ts_median + TX_EXPIRATION_MEDIAN_SHIFT + 0; // one second less than minimum allowed (see condition above)
set_tx_expiration_time(tx_0, tx_0_expiration_time);
@ -1515,8 +1518,9 @@ bool tx_key_image_pool_conflict::generate(std::vector<test_event_entry>& events)
std::vector<tx_destination_entry> destinations;
r = fill_tx_sources_and_destinations(events, blk_0r, m_miner_acc.get_keys(), bob_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_0 = AUTO_VAL_INIT(tx_0);
r = construct_tx(m_miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
transaction tx_0{};
size_t tx_hardfork_id{};
r = construct_tx(m_miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
LOG_PRINT_YELLOW("tx_0 = " << get_transaction_hash(tx_0), LOG_LEVEL_0);
// do not push tx_0 into events yet
@ -1643,15 +1647,18 @@ bool tx_version_against_hardfork::generate(std::vector<test_event_entry>& events
// tx_1 tx_1 is accepted
uint64_t tx_version_good = 0, tx_version_bad = 0;
size_t tx_hardfork_id = 0;
// select good and bad tx versions based on active hardfork
size_t most_recent_hardfork_id = m_hardforks.get_the_most_recent_hardfork_id_for_height(get_block_height(blk_0r));
switch(most_recent_hardfork_id)
{
case ZANO_HARDFORK_04_ZARCANUM:
tx_hardfork_id = 0;
case ZANO_HARDFORK_05:
tx_version_good = TRANSACTION_VERSION_POST_HF4;
tx_version_bad = TRANSACTION_VERSION_PRE_HF4;
tx_hardfork_id = ZANO_HARDFORK_05;
break;
default:
LOG_ERROR("hardfork " << most_recent_hardfork_id << " is not supported by this test");
@ -1667,7 +1674,7 @@ bool tx_version_against_hardfork::generate(std::vector<test_event_entry>& events
r = fill_tx_sources_and_destinations(events, blk_0r, miner_acc.get_keys(), miner_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_0{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version_good, 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version_good, tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
events.push_back(tx_0);
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
@ -1681,7 +1688,7 @@ bool tx_version_against_hardfork::generate(std::vector<test_event_entry>& events
r = fill_tx_sources_and_destinations(events, blk_0, miner_acc.get_keys(), miner_acc.get_public_address(), MK_TEST_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources_and_destinations failed");
transaction tx_1{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version_bad, 0);
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, tx_version_bad, tx_hardfork_id, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
// check tx pool rejection
DO_CALLBACK(events, "mark_invalid_tx");
@ -2121,3 +2128,481 @@ bool tx_pool_semantic_validation::generate(std::vector<test_event_entry>& events
return true;
}
input_refers_to_incompatible_by_type_output::input_refers_to_incompatible_by_type_output()
{
REGISTER_CALLBACK_METHOD(input_refers_to_incompatible_by_type_output, assert_htlc_input_refers_to_key_output_is_wrong);
REGISTER_CALLBACK_METHOD(input_refers_to_incompatible_by_type_output, assert_to_key_input_refers_zarcanum_output_is_wrong);
REGISTER_CALLBACK_METHOD(input_refers_to_incompatible_by_type_output, assert_htlc_input_refers_zarcanum_output_is_wrong);
REGISTER_CALLBACK_METHOD(input_refers_to_incompatible_by_type_output, assert_zc_input_refers_bare_output_is_wrong);
m_hardforks.set_hardfork_height(ZANO_HARDFORK_04_ZARCANUM, 14);
}
bool input_refers_to_incompatible_by_type_output::generate(std::vector<test_event_entry>& events) const
{
// Test idea: ensure that input and output compatibility checks work.
GENERATE_ACCOUNT(miner);
MAKE_GENESIS_BLOCK(events, blk_0, miner, test_core_time::get_time());
DO_CALLBACK(events, "configure_core");
REWIND_BLOCKS(events, blk_0r, blk_0, miner);
block& top{blk_0r};
MAKE_TX_FEE(events, tx_00, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
{
MAKE_NEXT_BLOCK_TX1(events, blk_1, top, miner, tx_00);
top = blk_1;
}
// An input of the type "txin_htlc" refers by a "ref_by_id" object to an output with a target of the type "txout_to_key".
{
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0);
transaction tx_1{};
top = blk;
{
txin_htlc input{};
{
ref_by_id reference{};
reference.tx_id = get_transaction_hash(tx_0);
reference.n = get_tx_out_index_by_amount(tx_0, MK_TEST_COINS(7));
CHECK_AND_ASSERT_NEQ(reference.n, UINT64_MAX);
input.key_offsets.push_back(reference);
CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1);
}
input.k_image = crypto::point_t{{0x59, 0x01, 0xed, 0xcc, 0x3a, 0xe7, 0xaa, 0x83, 0x6c, 0x79, 0xfb, 0xed, 0x5d, 0x60, 0x02, 0xc5, 0xd0, 0xbf, 0x65, 0x85, 0x7b, 0x65, 0x25, 0x0e, 0x22, 0xcb, 0x63,
0x64, 0x3b, 0x3b, 0x47, 0x30}}.to_key_image();
input.amount = MK_TEST_COINS(7);
tx_1.vin.push_back(input);
CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1);
}
{
tx_out_bare output_bare{};
txout_to_key output_to_key{};
output_bare.amount = MK_TEST_COINS(2);
output_to_key.key = crypto::point_t{{0x2c, 0xdc, 0xc4, 0x7c, 0x38, 0x69, 0xe5, 0xe2, 0x4c, 0x5e, 0x10, 0xb2, 0xbe, 0x57, 0xe9, 0x42, 0x72, 0xd8, 0xf8, 0xb5, 0x97, 0xb9, 0x02, 0x41, 0xba, 0xea,
0x82, 0xb3, 0xaf, 0x0c, 0xf0, 0x09}}.to_public_key();
output_bare.target = output_to_key;
tx_1.vout.push_back(output_bare);
CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 1);
}
DO_CALLBACK(events, "mark_invalid_tx");
ADD_CUSTOM_EVENT(events, tx_1);
DO_CALLBACK_PARAMS_STR(events, "assert_htlc_input_refers_to_key_output_is_wrong", t_serializable_object_to_blob(tx_1));
}
// An input of the type "txin_htlc" refers by a global output index to an output with a target of the type "txout_to_key".
{
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0);
transaction tx_1{};
top = blk;
{
txin_htlc input{};
{
uint64_t global_output_index{};
CHECK_AND_ASSERT_EQ(find_global_index_for_output(events, get_block_hash(top), tx_0, get_tx_out_index_by_amount(tx_0, MK_TEST_COINS(7)), global_output_index), true);
CHECK_AND_ASSERT_NEQ(global_output_index, UINT64_MAX);
input.key_offsets.push_back(global_output_index);
CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1);
}
input.k_image = crypto::point_t{{0xc6, 0x1c, 0xda, 0xf7, 0x9e, 0xb7, 0xd9, 0xc2, 0x46, 0x90, 0x29, 0xc8, 0x8a, 0x8f, 0xb4, 0x3e, 0x8e, 0xa8, 0x3b, 0x33, 0x4c, 0x75, 0xdf, 0xcb, 0x8b, 0x77, 0xf7,
0x39, 0xa7, 0x17, 0xc9, 0xb4}}.to_key_image();
input.amount = MK_TEST_COINS(7);
tx_1.vin.push_back(input);
CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1);
}
{
tx_out_bare output_bare{};
txout_to_key output_to_key{};
output_bare.amount = MK_TEST_COINS(2);
output_to_key.key = crypto::point_t{{0xc4, 0x17, 0xc7, 0x7f, 0xb2, 0x5d, 0xcb, 0x4b, 0x29, 0xdf, 0xea, 0x53, 0x70, 0x11, 0xbb, 0x42, 0x33, 0x0d, 0xf1, 0x22, 0x2d, 0xe4, 0x84, 0x24, 0x36, 0xc0,
0x06, 0xd5, 0x8c, 0xf8, 0x23, 0x62}}.to_public_key();
output_bare.target = output_to_key;
tx_1.vout.push_back(output_bare);
}
tx_1.signatures.push_back(NLSAG_sig{{crypto::signature{}}});
DO_CALLBACK(events, "mark_invalid_tx");
ADD_CUSTOM_EVENT(events, tx_1);
DO_CALLBACK_PARAMS_STR(events, "assert_htlc_input_refers_to_key_output_is_wrong", t_serializable_object_to_blob(tx_1));
}
DO_CALLBACK_PARAMS(events, "check_hardfork_inactive", size_t{ZANO_HARDFORK_04_ZARCANUM});
{
REWIND_BLOCKS_N(events, blk, top, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
top = blk;
}
DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM});
MAKE_TX_FEE(events, tx_01, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
{
MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_01);
top = blk;
}
MAKE_TX_FEE(events, tx_02, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
{
MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_02);
top = blk;
}
// An input of the type "txin_to_key" refers by a "ref_by_id" object to an output of the type "tx_out_zarcanum".
{
DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM});
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
{
MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0);
top = blk;
}
{
REWIND_BLOCKS(events, blk_r, top, miner);
top = blk_r;
}
transaction tx_1{};
tx_1.version = 2;
{
txin_to_key input{};
input.key_offsets.emplace_back(ref_by_id{get_transaction_hash(tx_0), 0});
CHECK_AND_ASSERT_EQ(tx_0.vout.at(boost::get<ref_by_id>(input.key_offsets.front()).n).type(), typeid(tx_out_zarcanum));
CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1);
input.k_image = crypto::point_t({0x59,0x01, 0xed, 0xcc, 0x3a, 0xe7, 0xaa, 0x83, 0x6c, 0x79, 0xfb, 0xed, 0x5d, 0x60, 0x02, 0xc5, 0xd0, 0xbf, 0x65, 0x85, 0x7b, 0x65, 0x25, 0x0e, 0x22, 0xcb, 0x63,
0x64, 0x3b, 0x3b, 0x47, 0x30}).to_key_image();
input.amount = MK_TEST_COINS(2);
tx_1.vin.push_back(input);
CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1);
}
tx_1.vout.push_back(tx_out_zarcanum{});
tx_1.vout.push_back(tx_out_zarcanum{});
CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2);
tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE});
CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1);
DO_CALLBACK(events, "mark_invalid_tx");
ADD_CUSTOM_EVENT(events, tx_1);
DO_CALLBACK_PARAMS_STR(events, "assert_to_key_input_refers_zarcanum_output_is_wrong", t_serializable_object_to_blob(tx_1));
}
// An input of the type "txin_to_key" refers by a global output index to an output of the type "tx_out_zarcanum".
{
DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM});
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
{
MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0);
top = blk;
}
{
REWIND_BLOCKS(events, blk_r, top, miner);
top = blk_r;
}
transaction tx_1{};
tx_1.version = 2;
{
txin_to_key input{};
{
uint64_t global_output_index{};
CHECK_AND_ASSERT_EQ(tx_0.vout.front().type(), typeid(tx_out_zarcanum));
CHECK_AND_ASSERT_EQ(find_global_index_for_output(events, get_block_hash(top), tx_0, 0, global_output_index), true);
input.key_offsets.push_back(global_output_index);
}
CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1);
input.k_image = crypto::point_t{{0xbc, 0x2d, 0xdc, 0xc5, 0x93, 0x03, 0x9f, 0x0e, 0xce, 0x76, 0xee, 0xef, 0xd9, 0x1c, 0x2c, 0x3e, 0x8c, 0x4a, 0xca, 0x87, 0x9b, 0x6e, 0x3a, 0xda, 0xaf, 0x0c,
0x92, 0x88, 0xda, 0x88, 0xc0, 0xf0}}.to_key_image();
// A container is selected by an amount specified in an input. ZC outputs have .amount equals to 0. Thus, the input has .amount equals to 0.
input.amount = 0;
tx_1.vin.push_back(input);
CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1);
}
tx_1.vout.push_back(tx_out_zarcanum{});
tx_1.vout.push_back(tx_out_zarcanum{});
CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2);
tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE});
CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1);
DO_CALLBACK(events, "mark_invalid_tx");
ADD_CUSTOM_EVENT(events, tx_1);
DO_CALLBACK_PARAMS_STR(events, "assert_to_key_input_refers_zarcanum_output_is_wrong", t_serializable_object_to_blob(tx_1));
}
// An input of the type "txin_zc_input" refers by a "ref_by_id" object to an output with a target of the type "txout_to_key".
{
DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM});
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
{
MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0);
top = blk;
}
{
REWIND_BLOCKS(events, blk_r, top, miner);
top = blk_r;
}
transaction tx_1{};
tx_1.version = 2;
{
txin_zc_input input{};
input.key_offsets.emplace_back(ref_by_id{get_transaction_hash(tx_00), 0});
{
const auto& output{tx_00.vout.at(boost::get<ref_by_id>(input.key_offsets.front()).n)};
CHECK_AND_ASSERT_EQ(output.type(), typeid(tx_out_bare));
CHECK_AND_ASSERT_EQ(boost::get<tx_out_bare>(output).target.type(), typeid(txout_to_key));
}
CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1);
input.key_offsets.emplace_back(ref_by_id{get_transaction_hash(tx_01), 0});
{
const auto& output{tx_01.vout.at(boost::get<ref_by_id>(input.key_offsets.at(1)).n)};
CHECK_AND_ASSERT_EQ(output.type(), typeid(tx_out_zarcanum));
}
CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 2);
input.k_image = crypto::point_t{{0x31, 0x31, 0xd0, 0xf7, 0x13, 0x73, 0xff, 0x21, 0x14, 0xe8, 0x17, 0x4d, 0x18, 0x20, 0x12, 0x2d, 0x80, 0x31, 0xd5, 0x11, 0x82, 0xc0, 0x37, 0xad, 0xd2, 0x7b, 0x8c,
0xf2, 0xdd, 0xd4, 0x34, 0x9a}}.to_key_image();
tx_1.vin.push_back(input);
CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1);
}
tx_1.vout.push_back(tx_out_zarcanum{});
tx_1.vout.push_back(tx_out_zarcanum{});
CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2);
tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE});
CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1);
DO_CALLBACK(events, "mark_invalid_tx");
ADD_CUSTOM_EVENT(events, tx_1);
DO_CALLBACK_PARAMS_STR(events, "assert_zc_input_refers_bare_output_is_wrong", t_serializable_object_to_blob(tx_1));
}
// An input of the type "txin_htlc" refers by a "ref_by_id" object to an output of the type "tx_out_zarcanum".
{
DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM});
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
{
MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0);
top = blk;
}
{
REWIND_BLOCKS_N_WITH_TIME(events, blk_r, top, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
top = blk_r;
}
transaction tx_1{};
tx_1.version = 2;
{
txin_htlc input{};
input.key_offsets.push_back(ref_by_id{get_transaction_hash(tx_0), 0});
CHECK_AND_ASSERT_EQ(tx_0.vout.at(boost::get<ref_by_id>(input.key_offsets.front()).n).type(), typeid(tx_out_zarcanum));
input.k_image = crypto::point_t{{0x7b, 0xf5, 0x28, 0x09, 0xe8, 0x7e, 0x9c, 0x71, 0x0b, 0xad, 0x24, 0xa1, 0x9d, 0xb4, 0xc8, 0xd7, 0x96, 0x72, 0x18, 0xe6, 0x4b, 0x8f, 0x31, 0x01, 0xb0, 0x43, 0xa0,
0xcc, 0xce, 0x72, 0x8c, 0x7e}}.to_key_image();
input.amount = MK_TEST_COINS(2);
tx_1.vin.push_back(input);
CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1);
}
tx_1.vout.push_back(tx_out_zarcanum{});
tx_1.vout.push_back(tx_out_zarcanum{});
CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2);
tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE});
CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1);
DO_CALLBACK(events, "mark_invalid_tx");
ADD_CUSTOM_EVENT(events, tx_1);
DO_CALLBACK_PARAMS_STR(events, "assert_htlc_input_refers_zarcanum_output_is_wrong", t_serializable_object_to_blob(tx_1));
}
// An input of the type "txin_htlc" refers by a global output index to an output of the type "tx_out_zarcanum".
{
MAKE_TX_FEE(events, tx_0, miner, miner, MK_TEST_COINS(2), TESTS_DEFAULT_FEE, top);
{
MAKE_NEXT_BLOCK_TX1(events, blk, top, miner, tx_0);
top = blk;
}
DO_CALLBACK_PARAMS(events, "check_hardfork_active", size_t{ZANO_HARDFORK_04_ZARCANUM});
{
REWIND_BLOCKS_N_WITH_TIME(events, blk_r, top, miner, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
top = blk_r;
}
transaction tx_1{};
tx_1.version = 2;
{
txin_htlc input{};
uint64_t global_output_index{};
CHECK_AND_ASSERT_EQ(tx_0.vout.front().type(), typeid(tx_out_zarcanum));
CHECK_AND_ASSERT_EQ(find_global_index_for_output(events, get_block_hash(top), tx_0, 0, global_output_index), true);
input.key_offsets.push_back(global_output_index);
CHECK_AND_ASSERT_EQ(input.key_offsets.size(), 1);
input.k_image = crypto::point_t{{0xbc, 0x2d, 0xdc, 0xc5, 0x93, 0x03, 0x9f, 0x0e, 0xce, 0x76, 0xee, 0xef, 0xd9, 0x1c, 0x2c, 0x3e, 0x8c, 0x4a, 0xca, 0x87, 0x9b, 0x6e, 0x3a, 0xda, 0xaf, 0x0c, 0x92,
0x88, 0xda, 0x88, 0xc0, 0xf0}}.to_key_image();
// A container is selected by an amount specified in an input. ZC outputs have .amount equals to 0. Thus, the input has .amount equals to 0.
input.amount = 0;
tx_1.vin.push_back(input);
CHECK_AND_ASSERT_EQ(tx_1.vin.size(), 1);
}
tx_1.vout.push_back(tx_out_zarcanum{});
tx_1.vout.push_back(tx_out_zarcanum{});
CHECK_AND_ASSERT_EQ(tx_1.vout.size(), 2);
tx_1.extra.push_back(zarcanum_tx_data_v1{TESTS_DEFAULT_FEE});
CHECK_AND_ASSERT_EQ(tx_1.extra.size(), 1);
DO_CALLBACK(events, "mark_invalid_tx");
ADD_CUSTOM_EVENT(events, tx_1);
DO_CALLBACK_PARAMS_STR(events, "assert_htlc_input_refers_zarcanum_output_is_wrong", t_serializable_object_to_blob(tx_1));
}
return true;
}
bool input_refers_to_incompatible_by_type_output::assert_htlc_input_refers_to_key_output_is_wrong(const currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events) const
{
transaction tx{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(ev_index)).callback_params), true);
CHECK_AND_ASSERT_EQ(tx.vin.front().type(), typeid(txin_htlc));
{
uint64_t max_related_block_height{};
CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().check_tx_input(tx, 0, boost::get<const txin_htlc>(tx.vin.front()), get_transaction_hash(tx), max_related_block_height), false);
}
{
std::vector<public_key> keys{};
uint64_t max_related_block_height{};
uint64_t source_max_unlock_time_for_pos_coinbase{};
CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().get_output_keys_for_input_with_checks(tx, tx.vin.front(), keys, max_related_block_height, source_max_unlock_time_for_pos_coinbase), false);
}
return true;
}
bool input_refers_to_incompatible_by_type_output::assert_to_key_input_refers_zarcanum_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector<test_event_entry>& events) const
{
transaction tx{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(ev_index)).callback_params), true);
CHECK_AND_ASSERT_EQ(tx.vin.front().type(), typeid(txin_to_key));
{
uint64_t max_related_block_height{};
uint64_t source_max_unlock_time_for_pos_coinbase{};
CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().check_tx_input(tx, 0, boost::get<const txin_to_key>(tx.vin.front()), get_transaction_hash(tx), max_related_block_height,
source_max_unlock_time_for_pos_coinbase), false);
}
{
std::vector<public_key> keys{};
uint64_t max_related_block_height{};
uint64_t source_max_unlock_time_for_pos_coinbase{};
CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().get_output_keys_for_input_with_checks(tx, tx.vin.front(), keys, max_related_block_height, source_max_unlock_time_for_pos_coinbase), false);
}
return true;
}
bool input_refers_to_incompatible_by_type_output::assert_zc_input_refers_bare_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector<test_event_entry>& events) const
{
transaction tx{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(ev_index)).callback_params), true);
CHECK_AND_ASSERT_EQ(tx.vin.front().type(), typeid(txin_zc_input));
{
std::vector<public_key> keys{};
uint64_t max_related_block_height{};
uint64_t source_max_unlock_time_for_pos_coinbase{};
CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().get_output_keys_for_input_with_checks(tx, tx.vin.front(), keys, max_related_block_height, source_max_unlock_time_for_pos_coinbase), true);
}
{
bool all_inputs_have_explicit_native_asset_id{};
uint64_t max_related_block_height{};
CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().check_tx_input(tx, 0, boost::get<const txin_zc_input>(tx.vin.front()), get_transaction_hash(tx), max_related_block_height,
all_inputs_have_explicit_native_asset_id), false);
}
return true;
}
bool input_refers_to_incompatible_by_type_output::assert_htlc_input_refers_zarcanum_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector<test_event_entry>& events) const
{
transaction tx{};
CHECK_AND_ASSERT_EQ(t_unserializable_object_from_blob(tx, boost::get<const callback_entry>(events.at(ev_index)).callback_params), true);
CHECK_AND_ASSERT_EQ(tx.vin.front().type(), typeid(txin_htlc));
{
uint64_t max_related_block_height{};
uint64_t source_max_unlock_time_for_pos_coinbase{};
CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().check_tx_input(tx, 0, boost::get<const txin_htlc>(tx.vin.front()), get_transaction_hash(tx), max_related_block_height,
source_max_unlock_time_for_pos_coinbase), false);
}
{
std::vector<public_key> keys{};
uint64_t max_related_block_height{};
uint64_t source_max_unlock_time_for_pos_coinbase{};
CHECK_AND_ASSERT_EQ(c.get_blockchain_storage().get_output_keys_for_input_with_checks(tx, tx.vin.front(), keys, max_related_block_height, source_max_unlock_time_for_pos_coinbase), false);
}
return true;
}

View file

@ -165,3 +165,13 @@ struct tx_pool_semantic_validation : public test_chain_unit_enchanced
{
bool generate(std::vector<test_event_entry>& events) const;
};
struct input_refers_to_incompatible_by_type_output : public test_chain_unit_enchanced
{
input_refers_to_incompatible_by_type_output();
bool generate(std::vector<test_event_entry>& events) const;
bool assert_htlc_input_refers_to_key_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector<test_event_entry>& events) const;
bool assert_to_key_input_refers_zarcanum_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector<test_event_entry>& events) const;
bool assert_zc_input_refers_bare_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector<test_event_entry>& events) const;
bool assert_htlc_input_refers_zarcanum_output_is_wrong(const currency::core& c, const size_t ev_index, const std::vector<test_event_entry>& events) const;
};

View file

@ -1661,7 +1661,9 @@ bool gen_wallet_alias_and_unconfirmed_txs::generate(std::vector<test_event_entry
d.flags |= tx_destination_entry_flags::tdef_explicit_native_asset_id | tx_destination_entry_flags::tdef_zero_amount_blinding_mask;
transaction tx_alice_alias{};
crypto::secret_key sk{};
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<currency::extra_v>({ ai }), empty_attachment, tx_alice_alias, get_tx_version_from_events(events), sk, 0);
size_t tx_hardfork_id{};
uint64_t tx_version = get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id);
r = construct_tx(miner_acc.get_keys(), sources, destinations, std::vector<currency::extra_v>({ ai }), empty_attachment, tx_alice_alias, tx_version, tx_hardfork_id, sk, 0);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_alice_alias);
@ -2306,7 +2308,7 @@ bool generate_oversized_offer(size_t min_size, size_t max_size, bc_services::off
// construct fake tx to estimate it's size
transaction tx = AUTO_VAL_INIT(tx);
crypto::secret_key one_time_secret_key;
if (!construct_tx(account_keys(), std::vector<tx_source_entry>(), std::vector<tx_destination_entry>(), empty_extra, att_container, tx, tx_version, one_time_secret_key, 0, 0, true, 0))
if (!construct_tx(account_keys(), std::vector<tx_source_entry>(), std::vector<tx_destination_entry>(), empty_extra, att_container, tx, tx_version, 0, one_time_secret_key, 0, 0, true, 0))
return false;
size_t sz = get_object_blobsize(tx);

View file

@ -520,7 +520,8 @@ bool zarcanum_txs_with_big_shuffled_decoy_set_shuffled::generate(std::vector<tes
CHECK_AND_ASSERT_MES(shuffle_source_entries(sources), false, "shuffle_source_entries failed");
transaction tx_1_a{};
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_1_a, get_tx_version_from_events(events), 0 /* unlock time */);
size_t tx_hardfork_id{};
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_1_a, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0 /* unlock time */);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_1_a);
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, tx_1_a);
@ -532,7 +533,7 @@ bool zarcanum_txs_with_big_shuffled_decoy_set_shuffled::generate(std::vector<tes
CHECK_AND_ASSERT_MES(fill_tx_sources_and_destinations(events, blk_2, alice_acc, miner_acc, alice_amount - TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, nmix, sources, destinations), false, "");
CHECK_AND_ASSERT_MES(shuffle_source_entries(sources), false, "shuffle_source_entries failed");
transaction tx_1_b{};
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_1_b, get_tx_version_from_events(events), 0 /* unlock time */);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_1_b, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0 /* unlock time */);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_1_b);
MAKE_NEXT_BLOCK_TX1(events, blk_3, blk_2, miner_acc, tx_1_b);
@ -571,7 +572,7 @@ bool zarcanum_txs_with_big_shuffled_decoy_set_shuffled::generate(std::vector<tes
CHECK_AND_ASSERT_MES(fill_tx_sources_and_destinations(events, blk_5r, alice_acc, miner_acc, alice_amount - TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, nmix, sources, destinations), false, "");
CHECK_AND_ASSERT_MES(shuffle_source_entries(sources), false, "shuffle_source_entries failed");
transaction tx_3_a{};
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3_a, get_tx_version_from_events(events), 0 /* unlock time */);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3_a, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0 /* unlock time */);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_3_a);
MAKE_NEXT_BLOCK_TX1(events, blk_6, blk_5r, miner_acc, tx_3_a);
@ -583,7 +584,7 @@ bool zarcanum_txs_with_big_shuffled_decoy_set_shuffled::generate(std::vector<tes
CHECK_AND_ASSERT_MES(fill_tx_sources_and_destinations(events, blk_6, alice_acc, miner_acc, alice_amount - TESTS_DEFAULT_FEE, TESTS_DEFAULT_FEE, nmix, sources, destinations), false, "");
CHECK_AND_ASSERT_MES(shuffle_source_entries(sources), false, "shuffle_source_entries failed");
transaction tx_3_b{};
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3_b, get_tx_version_from_events(events), 0 /* unlock time */);
r = construct_tx(alice_acc.get_keys(), sources, destinations, empty_attachment, tx_3_b, get_tx_version_and_harfork_id_from_events(events, tx_hardfork_id), tx_hardfork_id, 0 /* unlock time */);
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
ADD_CUSTOM_EVENT(events, tx_3_b);
MAKE_NEXT_BLOCK_TX1(events, blk_7, blk_6, miner_acc, tx_3_b);

View file

@ -77,7 +77,8 @@ bool create_block_template_manually(const currency::block& prev_block, boost::mu
result.miner_tx,
block_reward_without_fee,
block_reward,
TRANSACTION_VERSION_PRE_HF4);
TRANSACTION_VERSION_PRE_HF4,
0);
CHECK_AND_ASSERT_MES(r, false, "construct_miner_tx failed");
size_t coinbase_size = get_object_blobsize(result.miner_tx);
@ -155,7 +156,7 @@ bool generate_events(currency::core& c, cct_events_t& events, const cct_wallets_
test_core_time::adjust(b.timestamp);
currency::wide_difficulty_type diff = 0;
r = currency::miner::find_nonce_for_given_block(b, diff, height);
r = currency::find_nonce_for_given_block(b, diff, height);
CHECK_AND_ASSERT_MES(r, false, "find_nonce_for_given_block failed");
currency::block_verification_context bvc = AUTO_VAL_INIT(bvc);

View file

@ -23,6 +23,7 @@
// SOFTWARE.
#include <iostream>
#include <iomanip>
#include <cstdint>
using namespace std;
#ifndef KECCAKF_ROUNDS

View file

@ -56,6 +56,8 @@ void test_plain_wallet()
epee::misc_utils::sleep_no_w(2000);
res = plain_wallet::sync_call("reset_connection_url", 0, "195.201.107.230:33336");
//res = plain_wallet::sync_call("reset_connection_url", 0, "https://node.zano.org:443");
r = plain_wallet::sync_call("run_wallet", instance_id, "");
while(true)

View file

@ -20,7 +20,7 @@ public:
uint64_t block_reward_without_fee = 0;
uint64_t block_reward = 0;
if(!construct_miner_tx(0, 0, 0, 2, 0, m_bob.get_keys().account_address, m_bob.get_keys().account_address, m_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, blobdata(), CURRENCY_MINER_TX_MAX_OUTS))
if(!construct_miner_tx(0, 0, 0, 2, 0, m_bob.get_keys().account_address, m_bob.get_keys().account_address, m_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0, blobdata(), CURRENCY_MINER_TX_MAX_OUTS))
return false;
m_tx_pub_key = get_tx_pub_key_from_extra(m_tx);
return true;

View file

@ -151,10 +151,10 @@ TEST_neg(int16_t, "+32768"); // 2^15
TEST_neg(int16_t, "-32769"); // -2^15 - 1
TEST_neg(int16_t, "");
TEST_pos(int32_t, 2'147'483'647, "2147483647"); // 2^31 - 1
TEST_pos(int32_t, -2'147'483'648, "-2147483648"); // -2^31
TEST_pos(int32_t, 0, "-0");
TEST_pos(int32_t, 0, "+0");
TEST_pos(int32_t, 2'147'483'647, "2147483647"); // 2^31 - 1
TEST_pos(int32_t, -2'147'483'647 - 1, "-2147483648"); // -2^31
TEST_pos(int32_t, 0, "-0");
TEST_pos(int32_t, 0, "+0");
TEST_neg(int32_t, "-2147483649");
TEST_neg(int32_t, "2147483648");

View file

@ -245,7 +245,7 @@ static std::optional<asset_operation_descriptor> deserialize(serialization_metho
return {};
}
static std::string get_string_presentation(const std::string& data)
[[maybe_unused]] static std::string get_string_presentation(const std::string& data)
{
std::string presentation{};

View file

@ -1,3 +1,4 @@
// Copyright (c) 2014-2024 Zano Project
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -16,7 +17,7 @@ TEST(parse_and_validate_tx_extra, is_correct_parse_and_validate_tx_extra)
currency::blobdata b = "dsdsdfsdfsf";
uint64_t block_reward_without_fee = 0, block_reward = 0;
bool r = currency::construct_miner_tx(0, 0, 10000000000000, 1000, TESTS_DEFAULT_FEE, acc.get_keys().account_address, acc.get_keys().account_address, tx,
block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, b, 1);
block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0, b, 1);
ASSERT_TRUE(r);
crypto::public_key tx_pub_key;
r = currency::parse_and_validate_tx_extra(tx, tx_pub_key);
@ -30,7 +31,7 @@ TEST(parse_and_validate_tx_extra, is_correct_extranonce_too_big)
currency::blobdata b(260, 0);
uint64_t block_reward_without_fee = 0, block_reward = 0;
bool r = currency::construct_miner_tx(0, 0, 10000000000000, 1000, TESTS_DEFAULT_FEE, acc.get_keys().account_address, acc.get_keys().account_address, tx,
block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, b, 1);
block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, 0, b, 1);
ASSERT_FALSE(r);
}

View file

@ -0,0 +1,160 @@
###########################################################################################
## zanod Dockerfile
###########################################################################################
#
# Usage:
# (make sure you have correct permission for /var/data/zano-data prior to run!)
#
# docker run --restart=always -v /var/data/zano-data:/home/zano/.Zano -p 11121:11121 -p 11211:11211 --name=zanod -dit zanoproject/remote-note
#
# To get into container and interact with the daemon:
# docker attach zanod
#
# To detach from container and left it running:
# Ctrl+P, Ctrl+Q
#
# To stop container:
# docker stop zanod
#
# To build with different lib versions, pass through --build-arg's
# docker build --build-arg OPENSSL_VERSION_DOT=1.1.1n --build-arg OPENSSL_HASH=40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a -f utils/docker/Dockerfile .
#
# Available Build Args
# - CMake Version: CMAKE_VERSION_DOT, CMAKE_HASH
# - Boost Version: BOOST_VERSION, BOOST_VERSION_DOT, BOOST_HASH
# - OpenSSL Version: OPENSSL_VERSION_DOT, OPENSSL_HASH
#
# Build Zano
#
FROM ubuntu:18.04 as build-prep
ENV DEBIAN_FRONTEND noninteractive
RUN apt update && \
apt install -y build-essential \
libicu-dev \
libz-dev \
curl \
gcc-8 \
g++-8 \
git
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 700 --slave /usr/bin/g++ g++ /usr/bin/g++-7 && \
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800 --slave /usr/bin/g++ g++ /usr/bin/g++-8
WORKDIR /root
# Lib Settings
ARG CMAKE_VERSION_DOT=3.16.9
ARG CMAKE_HASH=d71eda07d6ecf3964de65a0e36d0b171565e1aced56ba9f53ca3783406b5cacf
ARG BOOST_VERSION=1_84_0
ARG BOOST_VERSION_DOT=1.84.0
ARG BOOST_HASH=cc4b893acf645c9d4b698e9a0f08ca8846aa5d6c68275c14c3e7949c24109454
ARG OPENSSL_VERSION_DOT=1.1.1w
ARG OPENSSL_HASH=cf3098950cb4d853ad95c0841f1f9c6d3dc102dccfcacd521d93925208b76ac8
# Environment Variables
ENV BOOST_ROOT /root/boost_${BOOST_VERSION}
ENV OPENSSL_ROOT_DIR=/root/openssl
##########################################################
# Split download & compile to use dockers caching layers #
##########################################################
# Download CMake
RUN set -ex \
&& curl https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION_DOT}/cmake-${CMAKE_VERSION_DOT}-Linux-x86_64.sh -OL\
&& echo "${CMAKE_HASH} cmake-${CMAKE_VERSION_DOT}-Linux-x86_64.sh" | sha256sum -c
# Download Boost
RUN set -ex \
&& curl -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
&& sha256sum boost_${BOOST_VERSION}.tar.bz2 \
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c\
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2
# Download OpenSSL
RUN curl https://www.openssl.org/source/openssl-${OPENSSL_VERSION_DOT}.tar.gz -OL \
&& sha256sum openssl-${OPENSSL_VERSION_DOT}.tar.gz \
&& echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION_DOT}.tar.gz" | sha256sum -c
# Compile CMake
RUN set -ex \
&& mkdir /opt/cmake \
&& sh cmake-3.16.9-Linux-x86_64.sh --prefix=/opt/cmake --skip-license\
&& ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake\
&& cmake --version\
&& rm cmake-3.16.9-Linux-x86_64.sh
# Compile Boost
RUN set -ex \
&& cd boost_${BOOST_VERSION} \
&& ./bootstrap.sh --with-libraries=system,filesystem,thread,date_time,chrono,regex,serialization,atomic,program_options,locale,timer,log \
&& ./b2
# Compile OpenSSL
RUN set -ex \
&& tar xaf openssl-${OPENSSL_VERSION_DOT}.tar.gz \
&& rm openssl-${OPENSSL_VERSION_DOT}.tar.gz \
&& cd openssl-${OPENSSL_VERSION_DOT} \
&& ./config --prefix=/root/openssl --openssldir=/root/openssl shared zlib \
&& make \
&& make test \
&& make install \
&& cd .. \
&& rm -rf openssl-${OPENSSL_VERSION_DOT}
FROM build-prep as build
# Zano
RUN pwd && mem_avail_gb=$(( $(getconf _AVPHYS_PAGES) * $(getconf PAGE_SIZE) / (1024 * 1024 * 1024) )) &&\
make_job_slots=$(( $mem_avail_gb < 4 ? 1 : $mem_avail_gb / 4)) &&\
echo make_job_slots=$make_job_slots &&\
set -x &&\
git clone --single-branch --recursive https://github.com/hyle-team/zano.git &&\
cd zano &&\
mkdir build && cd build &&\
cmake -D STATIC=TRUE .. &&\
make -j $make_job_slots daemon simplewallet
#
# Run Zano
#
FROM ubuntu:18.04
# Install dependencies and Nginx
RUN apt update && apt install -y \
nginx \
curl \
&& apt clean
RUN useradd -ms /bin/bash zano &&\
mkdir -p /home/zano/.Zano &&\
chown -R zano:zano /home/zano/.Zano
USER zano:zano
WORKDIR /home/zano
COPY --chown=zano:zano --from=build /root/zano/build/src/zanod .
COPY --chown=zano:zano --from=build /root/zano/build/src/simplewallet .
# Copy Nginx configuration
USER root
COPY nginx.conf /etc/nginx/nginx.conf
# blockchain loaction
VOLUME /home/zano/.Zano
EXPOSE 11121 11211 33340
CMD service nginx start && ./zanod --disable-upnp --log-level=0

View file

@ -0,0 +1,73 @@
events {}
http {
##
# Basic Settings
##
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_req_zone $binary_remote_addr zone=global_limit:10m rate=10r/s;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
#mainnet
server {
listen 33340;
listen [::]:33340;
# Apply globally to all locations
limit_req zone=global_limit burst=20 nodelay;
limit_conn addr 30;
access_log /var/log/nginx/reverse-access.log;
error_log /var/log/nginx/reverse-error.log;
location /general_info
{
root /home/mobile_app_config;
add_header Cache-Control no-cache;
# set the Expires header to 31 December 2037 23:59:59 GMT, and the Cache-Control max-age to 10 years
expires 1s;
}
location ~ ^/(json_rpc|getheight|gettransactions|sendrawtransaction|force_relay|getinfo|getblocks\.bin|get_o_indexes\.bin|get_o_indexes\.bin|getrandom_outs\.bin|getrandom_outs1\.bin|getrandom_outs2\.bin|getrandom_outs3\.bin|set_maintainers_info\.bin|get_tx_pool\.bin|check_keyimages\.bin|get_pos_details\.bin) {
proxy_pass http://127.0.0.1:11211$uri;
}
}
}