1
0
Fork 0
forked from lthn/blockchain

Merge branch 'develop' of github.com:hyle-team/zano into develop

This commit is contained in:
cryptozoidberg 2019-10-11 16:23:00 +02:00
commit 80a0da7b27
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
9 changed files with 213 additions and 29 deletions

View file

@ -658,4 +658,41 @@ std::string get_nix_version_display_string()
return static_cast<uint64_t>(in.tellg());
}
bool check_remote_client_version(const std::string& client_ver)
{
std::string v = client_ver.substr(0, client_ver.find('[')); // remove commit id
v = v.substr(0, v.rfind('.')); // remove build number
int v_major = 0, v_minor = 0, v_revision = 0;
size_t dot_pos = v.find('.');
if (dot_pos == std::string::npos || !epee::string_tools::string_to_num_fast(v.substr(0, dot_pos), v_major))
return false;
v = v.substr(dot_pos + 1);
dot_pos = v.find('.');
if (!epee::string_tools::string_to_num_fast(v.substr(0, dot_pos), v_minor))
return false;
if (dot_pos != std::string::npos)
{
// revision
v = v.substr(dot_pos + 1);
if (!epee::string_tools::string_to_num_fast(v, v_revision))
return false;
}
// got v_major, v_minor, v_revision
// allow 1.1.x and greater
if (v_major < 1)
return false;
if (v_major == 1 && v_minor < 1)
return false;
return true;
}
} // namespace tools

View file

@ -30,6 +30,8 @@ namespace tools
std::string get_default_user_dir();
std::string get_current_username();
std::string get_os_version_string();
bool check_remote_client_version(const std::string& client_ver);
bool create_directories_if_necessary(const std::string& path);
std::error_code replace_file(const std::string& replacement_name, const std::string& replaced_name);

View file

@ -363,13 +363,16 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro
//------------------------------------------------------------------
bool blockchain_storage::set_lost_tx_unmixable_for_height(uint64_t height)
{
#ifndef TESTNET
if (height == 75738)
return set_lost_tx_unmixable();
#endif
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::set_lost_tx_unmixable()
{
#ifndef TESTNET
if (m_db_blocks.size() > 75738)
{
crypto::hash tx_id_1 = epee::string_tools::parse_tpod_from_hex_string<crypto::hash>("c2a2229d614e7c026433efbcfdbd0be1f68d9b419220336df3e2c209f5d57314");
@ -393,11 +396,13 @@ bool blockchain_storage::set_lost_tx_unmixable()
}
m_db_transactions.set(tx_id_2, tx2_local_entry);
}
#endif
return true;
}
//------------------------------------------------------------------
void blockchain_storage::patch_out_if_needed(txout_to_key& out, const crypto::hash& tx_id, uint64_t n) const
{
#ifndef TESTNET
static crypto::hash tx_id_1 = epee::string_tools::parse_tpod_from_hex_string<crypto::hash>("c2a2229d614e7c026433efbcfdbd0be1f68d9b419220336df3e2c209f5d57314");
static crypto::hash tx_id_2 = epee::string_tools::parse_tpod_from_hex_string<crypto::hash>("647f936c6ffbd136f5c95d9a90ad554bdb4c01541c6eb5755ad40b984d80da67");
@ -408,6 +413,7 @@ void blockchain_storage::patch_out_if_needed(txout_to_key& out, const crypto::h
{
out.mix_attr = CURRENCY_TO_KEY_OUT_FORCED_NO_MIX;
}
#endif
}
//------------------------------------------------------------------
void blockchain_storage::store_db_solo_options_values()

View file

@ -174,7 +174,8 @@ namespace currency
"That means that current software is outdated, please updated it." <<
"Current heigh lay under checkpoints on remote host, so it is not possible validate this transactions on local host, disconnecting.", LOG_LEVEL_0);
return false;
}else if (m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() < hshd.last_checkpoint_height)
}
else if (m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() < hshd.last_checkpoint_height)
{
LOG_PRINT_MAGENTA("Remote node have longer checkpoints zone( " << hshd.last_checkpoint_height << ") " <<
"that local (" << m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() << ")" <<

View file

@ -483,6 +483,12 @@ namespace nodetool
return;
}
if (!tools::check_remote_client_version(rsp.payload_data.client_version))
{
LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong client version: " << rsp.payload_data.client_version << ", closing connection.");
return;
}
if(!handle_maintainers_entry(rsp.maintrs_entry))
{
LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong maintainers entry!, closing connection.");
@ -1304,6 +1310,14 @@ namespace nodetool
return 1;
}
if (!tools::check_remote_client_version(arg.payload_data.client_version))
{
LOG_PRINT_CCONTEXT_L2("COMMAND_HANDSHAKE: wrong client version: " << arg.payload_data.client_version << ", closing connection.");
drop_connection(context);
add_ip_fail(context.m_remote_ip);
return 1;
}
if(!handle_maintainers_entry(arg.maintrs_entry))
{
LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong maintainers entry!, closing connection.");

View file

@ -1,3 +1,4 @@
#pragma once
#include "misc_language.h"
#define BUILD_COMMIT_ID "@VERSION@"
@ -7,6 +8,6 @@
#define PROJECT_REVISION "2"
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
#define PROJECT_VERSION_BUILD_NO 66
#define PROJECT_VERSION_BUILD_NO 67
#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

@ -28,6 +28,8 @@ using namespace epee;
#include "version.h"
using namespace currency;
#define MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES (100*1024*1024) // 100 MB
#undef LOG_DEFAULT_CHANNEL
#define LOG_DEFAULT_CHANNEL "wallet"
ENABLE_CHANNEL_BY_DEFAULT("wallet")
@ -1965,6 +1967,9 @@ void wallet2::generate(const std::wstring& path, const std::string& pass)
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(validate_password(pass), "new wallet generation failed: password contains forbidden characters")
clear();
prepare_file_names(path);
check_for_free_space_and_throw_if_it_lacks(m_wallet_file);
m_password = pass;
m_account.generate();
init_log_prefix();
@ -2000,6 +2005,9 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password)
{
clear();
prepare_file_names(wallet_);
check_for_free_space_and_throw_if_it_lacks(m_wallet_file);
m_password = password;
std::string keys_buff;
@ -2058,35 +2066,55 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor
{
LOG_PRINT_L0("(before storing: pending_key_images: " << m_pending_key_images.size() << ", pki file elements: " << m_pending_key_images_file_container.size() << ", tx_keys: " << m_tx_keys.size() << ")");
check_for_free_space_and_throw_if_it_lacks(path_to_save);
std::string ascii_path_to_save = epee::string_encoding::convert_to_ansii(path_to_save);
//prepare data
std::string keys_buff;
bool r = store_keys(keys_buff, password);
CHECK_AND_ASSERT_THROW_MES(r, "failed to store_keys for wallet " << epee::string_encoding::convert_to_ansii(m_wallet_file));
wallet_file_binary_header wbh = AUTO_VAL_INIT(wbh);
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(r, "failed to store_keys for wallet " << ascii_path_to_save);
//store data
wallet_file_binary_header wbh = AUTO_VAL_INIT(wbh);
wbh.m_signature = WALLET_FILE_SIGNATURE;
wbh.m_cb_keys = keys_buff.size();
//@#@ change it to proper
wbh.m_cb_body = 1000;
std::string header_buff((const char*)&wbh, sizeof(wbh));
uint64_t ts = m_core_runtime_config.get_core_time();
// save to tmp file, then rename
boost::filesystem::path tmp_file_path = boost::filesystem::path(path_to_save);
tmp_file_path += L".newtmp_" + std::to_wstring(ts);
//std::ofstream data_file;
boost::filesystem::ofstream data_file;
data_file.open(path_to_save, std::ios_base::binary | std::ios_base::out | std::ios::trunc);
CHECK_AND_ASSERT_THROW_MES(!data_file.fail(), "failed to open binary wallet file for saving: " << epee::string_encoding::convert_to_ansii(m_wallet_file));
data_file.open(tmp_file_path, std::ios_base::binary | std::ios_base::out | std::ios::trunc);
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(!data_file.fail(), "failed to open binary wallet file for saving: " << tmp_file_path.string());
data_file << header_buff << keys_buff;
WLT_LOG_L0("Storing to file...");
WLT_LOG_L0("Storing to " << tmp_file_path.string() << " ...");
r = tools::portble_serialize_obj_to_stream(*this, data_file);
CHECK_AND_ASSERT_THROW_MES(r, "failed to portble_serialize_obj_to_stream for wallet " << epee::string_encoding::convert_to_ansii(m_wallet_file));
if (!r)
{
boost::filesystem::remove(tmp_file_path); // remove tmp file if smth went wrong
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "portble_serialize_obj_to_stream failed for wallet " << tmp_file_path.string());
}
data_file.flush();
data_file.close();
// for the sake of safety perform a double-renaming: wallet file -> old tmp, new tmp -> wallet file, remove old tmp
boost::filesystem::path tmp_old_file_path = boost::filesystem::path(path_to_save);
tmp_old_file_path += L".oldtmp_" + std::to_wstring(ts);
if (boost::filesystem::is_regular_file(path_to_save))
boost::filesystem::rename(path_to_save, tmp_old_file_path);
boost::filesystem::rename(tmp_file_path, path_to_save);
boost::filesystem::remove(tmp_old_file_path);
}
//----------------------------------------------------------------------------------------------------
void wallet2::store_watch_only(const std::wstring& path_to_save, const std::string& password) const
@ -2134,6 +2162,47 @@ void wallet2::store_watch_only(const std::wstring& path_to_save, const std::stri
wo.store(path_to_save, password);
}
//----------------------------------------------------------------------------------------------------
void wallet2::check_for_free_space_and_throw_if_it_lacks(const std::wstring& wallet_filename, uint64_t exact_size_needed_if_known /* = UINT64_MAX */)
{
namespace fs = boost::filesystem;
try
{
fs::path wallet_file_path(wallet_filename);
fs::path base_path = wallet_file_path.parent_path();
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(fs::is_directory(base_path), "directory does not exist: " << base_path.string());
uint64_t min_free_size = exact_size_needed_if_known;
if (min_free_size == UINT64_MAX)
{
// if exact size needed is unknown -- determine it as
// twice the original wallet file size or MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES, which one is bigger
min_free_size = MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES;
if (fs::is_regular_file(wallet_file_path))
min_free_size = std::max(min_free_size, 2 * fs::file_size(wallet_file_path));
}
else
{
min_free_size += 1024 * 1024 * 10; // add a little for FS overhead and so
}
fs::space_info si = fs::space(base_path);
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(si.available > min_free_size, "free space at " << base_path.string() << " is too low: " << si.available << ", required minimum is: " << min_free_size);
}
catch (tools::error::wallet_common_error&)
{
throw;
}
catch (std::exception& e)
{
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "failed to determine free space: " << e.what());
}
catch (...)
{
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, "failed to determine free space: unknown exception");
}
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::unlocked_balance() const
{
uint64_t stub = 0;

View file

@ -47,22 +47,22 @@
ENABLE_CHANNEL_BY_DEFAULT("wallet");
// wallet-specific logging functions
#define WLT_LOG_L0(msg) LOG_PRINT_L0("[W:" << m_log_prefix << "]" << msg)
#define WLT_LOG_L1(msg) LOG_PRINT_L1("[W:" << m_log_prefix << "]" << msg)
#define WLT_LOG_L2(msg) LOG_PRINT_L2("[W:" << m_log_prefix << "]" << msg)
#define WLT_LOG_L3(msg) LOG_PRINT_L3("[W:" << m_log_prefix << "]" << msg)
#define WLT_LOG_L4(msg) LOG_PRINT_L4("[W:" << m_log_prefix << "]" << msg)
#define WLT_LOG_ERROR(msg) LOG_ERROR("[W:" << m_log_prefix << "]" << msg)
#define WLT_LOG_BLUE(msg, log_level) LOG_PRINT_BLUE("[W:" << m_log_prefix << "]" << msg, log_level)
#define WLT_LOG_CYAN(msg, log_level) LOG_PRINT_CYAN("[W:" << m_log_prefix << "]" << msg, log_level)
#define WLT_LOG_GREEN(msg, log_level) LOG_PRINT_GREEN("[W:" << m_log_prefix << "]" << msg, log_level)
#define WLT_LOG_MAGENTA(msg, log_level) LOG_PRINT_MAGENTA("[W:" << m_log_prefix << "]" << msg, log_level)
#define WLT_LOG_RED(msg, log_level) LOG_PRINT_RED("[W:" << m_log_prefix << "]" << msg, log_level)
#define WLT_LOG_YELLOW(msg, log_level) LOG_PRINT_YELLOW("[W:" << m_log_prefix << "]" << msg, log_level)
#define WLT_CHECK_AND_ASSERT_MES(expr, ret, msg) CHECK_AND_ASSERT_MES(expr, ret, "[W:" << m_log_prefix << "]" << msg)
#define WLT_CHECK_AND_ASSERT_MES_NO_RET(expr, msg) CHECK_AND_ASSERT_MES_NO_RET(expr, "[W:" << m_log_prefix << "]" << msg)
#define WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(cond, msg) THROW_IF_FALSE_WALLET_INT_ERR_EX(cond, "[W:" << m_log_prefix << "]" << msg)
#define WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(cond, msg) THROW_IF_FALSE_WALLET_CMN_ERR_EX(cond, "[W:" << m_log_prefix << "]" << msg)
#define WLT_LOG_L0(msg) LOG_PRINT_L0("[W:" << m_log_prefix << "] " << msg)
#define WLT_LOG_L1(msg) LOG_PRINT_L1("[W:" << m_log_prefix << "] " << msg)
#define WLT_LOG_L2(msg) LOG_PRINT_L2("[W:" << m_log_prefix << "] " << msg)
#define WLT_LOG_L3(msg) LOG_PRINT_L3("[W:" << m_log_prefix << "] " << msg)
#define WLT_LOG_L4(msg) LOG_PRINT_L4("[W:" << m_log_prefix << "] " << msg)
#define WLT_LOG_ERROR(msg) LOG_ERROR("[W:" << m_log_prefix << "] " << msg)
#define WLT_LOG_BLUE(msg, log_level) LOG_PRINT_BLUE("[W:" << m_log_prefix << "] " << msg, log_level)
#define WLT_LOG_CYAN(msg, log_level) LOG_PRINT_CYAN("[W:" << m_log_prefix << "] " << msg, log_level)
#define WLT_LOG_GREEN(msg, log_level) LOG_PRINT_GREEN("[W:" << m_log_prefix << "] " << msg, log_level)
#define WLT_LOG_MAGENTA(msg, log_level) LOG_PRINT_MAGENTA("[W:" << m_log_prefix << "] " << msg, log_level)
#define WLT_LOG_RED(msg, log_level) LOG_PRINT_RED("[W:" << m_log_prefix << "] " << msg, log_level)
#define WLT_LOG_YELLOW(msg, log_level) LOG_PRINT_YELLOW("[W:" << m_log_prefix << "] " << msg, log_level)
#define WLT_CHECK_AND_ASSERT_MES(expr, ret, msg) CHECK_AND_ASSERT_MES(expr, ret, "[W:" << m_log_prefix << "] " << msg)
#define WLT_CHECK_AND_ASSERT_MES_NO_RET(expr, msg) CHECK_AND_ASSERT_MES_NO_RET(expr, "[W:" << m_log_prefix << "] " << msg)
#define WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(cond, msg) THROW_IF_FALSE_WALLET_INT_ERR_EX(cond, "[W:" << m_log_prefix << "] " << msg)
#define WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(cond, msg) THROW_IF_FALSE_WALLET_CMN_ERR_EX(cond, "[W:" << m_log_prefix << "] " << msg)
class test_generator;
@ -729,6 +729,7 @@ namespace tools
std::string get_log_prefix() const { return m_log_prefix; }
static uint64_t get_max_unlock_time_from_receive_indices(const currency::transaction& tx, const money_transfer2_details& td);
private:
void add_transfers_to_expiration_list(const std::vector<uint64_t>& selected_transfers, uint64_t expiration, uint64_t change_amount, const crypto::hash& related_tx_id);
void remove_transfer_from_expiration_list(uint64_t transfer_index);
@ -840,7 +841,7 @@ private:
void exception_handler();
void exception_handler() const;
uint64_t get_minimum_allowed_fee_for_contract(const crypto::hash& ms_id);
void check_for_free_space_and_throw_if_it_lacks(const std::wstring& path, uint64_t exact_size_needed_if_known = UINT64_MAX);

View file

@ -0,0 +1,53 @@
// Copyright (c) 2019 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gtest/gtest.h"
#include "common/util.h"
TEST(p2p_client_version, test_1)
{
using namespace tools;
// good
ASSERT_TRUE(check_remote_client_version("10.101.999.28391[deadbeef31337-dirty]"));
ASSERT_TRUE(check_remote_client_version("1.1.9.237[aabcd]"));
ASSERT_TRUE(check_remote_client_version("3.0.2.7[aa00bcd]"));
ASSERT_TRUE(check_remote_client_version("1.4.2.7[aabcd]"));
ASSERT_TRUE(check_remote_client_version("1.1.2.67[88f868c]"));
ASSERT_TRUE(check_remote_client_version("1.1.2.67[88f868c]"));
ASSERT_TRUE(check_remote_client_version("1.1.2.67[26c00a8]"));
ASSERT_TRUE(check_remote_client_version("1.1.2.67[26c00a8-dirty]"));
ASSERT_TRUE(check_remote_client_version("1.1.0.65[40ba8cd]"));
ASSERT_TRUE(check_remote_client_version("1.1.0.63[b0f376b]"));
ASSERT_TRUE(check_remote_client_version("1.1.0.58[14bd668]"));
ASSERT_TRUE(check_remote_client_version("1.1.0.58[9920eb7]"));
ASSERT_TRUE(check_remote_client_version("1.1.0.58[e0d4ad8]"));
ASSERT_TRUE(check_remote_client_version("1.1.0.57[b77b915]"));
ASSERT_TRUE(check_remote_client_version("1.1.0.57[7dd61ae]"));
ASSERT_TRUE(check_remote_client_version("1.1.0.57[7dd61ae-dirty]"));
ASSERT_TRUE(check_remote_client_version("1.1.0.57"));
// bad
ASSERT_FALSE(check_remote_client_version(""));
ASSERT_FALSE(check_remote_client_version(" "));
ASSERT_FALSE(check_remote_client_version("1.0.999"));
ASSERT_FALSE(check_remote_client_version("1.0.40[f77f0d7]"));
ASSERT_FALSE(check_remote_client_version("1.0.40[734b726]"));
ASSERT_FALSE(check_remote_client_version("1.0.41[488e369]"));
ASSERT_FALSE(check_remote_client_version("1.0.40[469]"));
ASSERT_FALSE(check_remote_client_version("1.0.39[f77f0d7]"));
ASSERT_FALSE(check_remote_client_version("1.0.38[f77f0d7-dirty]"));
ASSERT_FALSE(check_remote_client_version("1.0.37[7dd61ae-dirty]"));
ASSERT_FALSE(check_remote_client_version("0.0.500[000]"));
}