fixed
This commit is contained in:
parent
f046b1490d
commit
0cafd79fd7
42 changed files with 1678 additions and 302 deletions
6
index.js
6
index.js
|
|
@ -1 +1,7 @@
|
|||
module.exports = require('bindings')('cryptonote.node')
|
||||
|
||||
const bignum = require('bignum');
|
||||
|
||||
module.exports.baseDiff = function() {
|
||||
return bignum('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16);
|
||||
};
|
||||
|
|
@ -12,7 +12,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"bindings": "*",
|
||||
"nan" : "^2.0.0"
|
||||
"nan": "^2.14.2",
|
||||
"bignum": "^0.13.1"
|
||||
},
|
||||
"keywords": [
|
||||
"cryptonight",
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
|
||||
|
||||
|
||||
#define CHECK_PROJECT_NAME() std::string project_name = CURRENCY_NAME; ar & project_name; if(!(project_name == CURRENCY_NAME) ) {throw std::runtime_error(std::string("wrong storage file: project name in file: ") + project_name + ", expected: " + CURRENCY_NAME );}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ namespace command_line
|
|||
}
|
||||
|
||||
template<typename F>
|
||||
bool handle_error_helper(const boost::program_options::options_description& desc, F parser)
|
||||
bool handle_error_helper(const boost::program_options::options_description& desc, std::string& err, F parser)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -159,6 +159,7 @@ namespace command_line
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
err = e.what();
|
||||
std::cerr << "Failed to parse arguments: " << e.what() << std::endl;
|
||||
std::cerr << desc << std::endl;
|
||||
return false;
|
||||
|
|
@ -171,6 +172,13 @@ namespace command_line
|
|||
}
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
bool handle_error_helper(const boost::program_options::options_description& desc, F parser)
|
||||
{
|
||||
std::string stub_err;
|
||||
return handle_error_helper(desc, stub_err, parser);
|
||||
}
|
||||
|
||||
template<typename T, bool required>
|
||||
bool has_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required>& arg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,20 +15,20 @@ bool parse_hash256(const std::string str_hash, crypto::hash& hash);
|
|||
template <class T>
|
||||
std::ostream &print_t(std::ostream &o, const T &v)
|
||||
{
|
||||
return o << "<" << epee::string_tools::pod_to_hex(v) << ">";
|
||||
return o << "" << epee::string_tools::pod_to_hex(v) << "";
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
std::ostream &print16(std::ostream &o, const T &v)
|
||||
{
|
||||
return o << "<" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..>";
|
||||
return o << "" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..";
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::string print16(const T &v)
|
||||
{
|
||||
return std::string("<") + epee::string_tools::pod_to_hex(v).substr(0, 5) + "..>";
|
||||
return std::string("") + epee::string_tools::pod_to_hex(v).substr(0, 5) + "..";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -143,9 +143,10 @@ namespace tools
|
|||
else
|
||||
{
|
||||
int res = 0;
|
||||
//MDBX_txn_flags_t flags = MDBX_txn_flags_t();
|
||||
unsigned int flags = 0;
|
||||
if (read_only)
|
||||
flags += MDBX_RDONLY;
|
||||
flags = MDBX_RDONLY;//flags = MDBX_TXN_RDONLY;
|
||||
|
||||
//don't use parent tx in write transactions if parent tx was read-only (restriction in mdbx)
|
||||
//see "Nested transactions: Max 1 child, write txns only, no writemap"
|
||||
|
|
@ -340,7 +341,9 @@ namespace tools
|
|||
data[0].iov_base = (void*)v;
|
||||
data[0].iov_len = vs;
|
||||
|
||||
res = mdbx_put(get_current_tx(), static_cast<MDBX_dbi>(h), &key, data, 0);
|
||||
//MDBX_put_flags_t flags = MDBX_put_flags_t();
|
||||
unsigned flags = 0;
|
||||
res = mdbx_put(get_current_tx(), static_cast<MDBX_dbi>(h), &key, data, flags);
|
||||
CHECK_AND_ASSERT_MESS_MDBX_DB(res, false, "Unable to mdbx_put");
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,3 +40,4 @@
|
|||
#define API_RETURN_CODE_TX_IS_TOO_BIG "TX_IS_TOO_BIG"
|
||||
#define API_RETURN_CODE_TX_REJECTED "TX_REJECTED"
|
||||
#define API_RETURN_CODE_HTLC_ORIGIN_HASH_MISSMATCHED "HTLC_ORIGIN_HASH_MISSMATCHED"
|
||||
#define API_RETURN_CODE_WRAP "WRAP"
|
||||
40
src/common/general_purpose_commands_defs.h
Normal file
40
src/common/general_purpose_commands_defs.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2014-2018 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 "serialization/keyvalue_hexemizer.h"
|
||||
#include "currency_core/currency_basic.h"
|
||||
#include "storages/portable_storage_base.h"
|
||||
#include "currency_core/basic_api_response_codes.h"
|
||||
#include "common/error_codes.h"
|
||||
namespace currency
|
||||
{
|
||||
//-----------------------------------------------
|
||||
|
||||
|
||||
struct tx_cost_struct
|
||||
{
|
||||
std::string usd_needed_for_erc20;
|
||||
std::string zano_needed_for_erc20;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(usd_needed_for_erc20)
|
||||
KV_SERIALIZE(zano_needed_for_erc20)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct rpc_get_wrap_info_response
|
||||
{
|
||||
std::string unwraped_coins_left;
|
||||
tx_cost_struct tx_cost;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(unwraped_coins_left)
|
||||
KV_SERIALIZE(tx_cost)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -21,8 +21,8 @@ namespace tools
|
|||
};
|
||||
|
||||
#ifndef TESTNET
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.43.225/pre-download/zano_mdbx_95_1000000.pak", "6b0bbba85bc420eaae5ec68373e528f70bffaa17fb111c796e951d06ad71e4fe", 1104150892, 2147450880 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.43.225/pre-download/zano_lmdb_95_1000000.pak", "b4d45c727dbf1b92671f9fd1a9624e79019e890bd3d33cb71e011ab4bcb0d21e", 1450748151, 2114449408 };
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_1161000.pak", "26660ffcdaf80a43a586e64a1a6da042dcb9ff3b58e14ce1ec9a775b995dc146", 1330022593, 2684313600 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_1161000.pak", "9dd03f08dea396fe32e6483a8221b292be35fa41c29748f119f11c3275956cdc", 1787475468, 2600247296 };
|
||||
#else
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "", "", 0, 0 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "", "", 0, 0 };
|
||||
|
|
@ -50,7 +50,8 @@ namespace tools
|
|||
|
||||
boost::system::error_code ec;
|
||||
uint64_t sz = boost::filesystem::file_size(db_main_file_path, ec);
|
||||
if (pre_download.unpacked_size == 0 || !(ec || (pre_download.unpacked_size > sz && pre_download.unpacked_size - sz > pre_download_min_size_difference) || command_line::has_arg(vm, command_line::arg_force_predownload)) )
|
||||
bool flag_force_predownload = command_line::has_arg(vm, command_line::arg_force_predownload);
|
||||
if (pre_download.unpacked_size == 0 || !(ec || (pre_download.unpacked_size > sz && pre_download.unpacked_size - sz > pre_download_min_size_difference) || flag_force_predownload) )
|
||||
{
|
||||
LOG_PRINT_MAGENTA("Pre-downloading not needed (db file size = " << sz << ")", LOG_LEVEL_0);
|
||||
return true;
|
||||
|
|
@ -92,15 +93,15 @@ namespace tools
|
|||
r = cl.download_and_unzip(cb, downloading_file_path, url, 5000 /* timout */, "GET", std::string(), 30 /* fails count */);
|
||||
if (!r)
|
||||
{
|
||||
LOG_PRINT_RED("Download failed", LOG_LEVEL_0);
|
||||
return false;
|
||||
LOG_PRINT_RED("Downloading failed", LOG_LEVEL_0);
|
||||
return !flag_force_predownload; // fatal error only if force-predownload
|
||||
}
|
||||
|
||||
crypto::hash data_hash = hash_stream.calculate_hash();
|
||||
if (epee::string_tools::pod_to_hex(data_hash) != pre_download.hash)
|
||||
{
|
||||
LOG_ERROR("hash missmatch in downloaded file, got: " << epee::string_tools::pod_to_hex(data_hash) << ", expected: " << pre_download.hash);
|
||||
return false;
|
||||
return !flag_force_predownload; // fatal error only if force-predownload
|
||||
}
|
||||
|
||||
LOG_PRINT_GREEN("Download succeeded, hash " << pre_download.hash << " is correct" , LOG_LEVEL_0);
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ namespace epee
|
|||
bool run_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
|
||||
{
|
||||
async_console_handler console_handler;
|
||||
return console_handler.run(ptsrv, boost::bind<bool>(no_srv_param_adapter<t_server, t_handler>, _1, _2, handlr), prompt, usage);
|
||||
return console_handler.run(ptsrv, boost::bind<bool>(no_srv_param_adapter<t_server, t_handler>, boost::placeholders::_1, boost::placeholders::_2, handlr), prompt, usage);
|
||||
}
|
||||
|
||||
template<class t_server, class t_handler>
|
||||
|
|
@ -460,7 +460,7 @@ namespace epee
|
|||
/*template<class t_srv>
|
||||
bool start_handling(t_srv& srv, const std::string& usage_string = "")
|
||||
{
|
||||
start_default_console_handler_no_srv_param(&srv, boost::bind(&console_handlers_binder::process_command_str, this, _1));
|
||||
start_default_console_handler_no_srv_param(&srv, boost::bind(&console_handlers_binder::process_command_str, this, boost::placeholders::_1));
|
||||
return true;
|
||||
}*/
|
||||
|
||||
|
|
@ -489,7 +489,7 @@ namespace epee
|
|||
/*template<class t_srv>
|
||||
bool run_handling(t_srv& srv, const std::string& usage_string)
|
||||
{
|
||||
return run_default_console_handler_no_srv_param(&srv, boost::bind<bool>(&console_handlers_binder::process_command_str, this, _1), usage_string);
|
||||
return run_default_console_handler_no_srv_param(&srv, boost::bind<bool>(&console_handlers_binder::process_command_str, this, boost::placeholders::_1), usage_string);
|
||||
}*/
|
||||
};
|
||||
|
||||
|
|
@ -510,7 +510,7 @@ namespace epee
|
|||
|
||||
bool run_handling(t_server* psrv, const std::string& prompt, const std::string& usage_string)
|
||||
{
|
||||
return m_console_handler.run(psrv, boost::bind(&srv_console_handlers_binder<t_server>::process_command_str, this, _1, _2), prompt, usage_string);
|
||||
return m_console_handler.run(psrv, boost::bind(&srv_console_handlers_binder<t_server>::process_command_str, this, boost::placeholders::_1, boost::placeholders::_2), prompt, usage_string);
|
||||
}
|
||||
|
||||
void stop_handling()
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ namespace epee
|
|||
}
|
||||
|
||||
|
||||
#define STD_TRY_CATCH_LOCATION(return_val) STD_TRY_CATCH(LOCATION_SS, return_val)
|
||||
|
||||
/* helper class, to make able get namespace via decltype()::*/
|
||||
template<class base_class>
|
||||
class namespace_accessor: public base_class{};
|
||||
|
|
|
|||
|
|
@ -132,17 +132,21 @@ DISABLE_VS_WARNINGS(4100)
|
|||
#define LOG_PRINT_CHANNEL_NO_POSTFIX2(log_channel, log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
|
||||
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x; epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);CATCH_ALL_DO_NOTHING();}}
|
||||
|
||||
#define LOG_PRINT_CHANNEL2(log_channel, log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
|
||||
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);CATCH_ALL_DO_NOTHING();}}
|
||||
#define LOG_PRINT_CHANNEL2_CB(log_channel, log_name, x, y, cb) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
|
||||
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);cb(ss________.str());CATCH_ALL_DO_NOTHING();}}
|
||||
|
||||
#define LOG_PRINT_CHANNEL_COLOR2(log_channel, log_name, x, y, color) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
|
||||
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, color, false, log_name);CATCH_ALL_DO_NOTHING();}}
|
||||
#define LOG_PRINT_CHANNEL_COLOR2_CB(log_channel, log_name, x, y, color, cb) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
|
||||
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, color, false, log_name); cb(ss________.str());CATCH_ALL_DO_NOTHING();}}
|
||||
|
||||
#define LOG_PRINT_CHANNEL_2_JORNAL(log_channel, log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
|
||||
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, true, log_name);CATCH_ALL_DO_NOTHING();}}
|
||||
|
||||
#define LOG_ERROR2(log_name, x) { \
|
||||
TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << "[ERROR] Location: " << std::endl << LOCATION_SS << epee::misc_utils::get_callstack() << " Message:" << std::endl << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str(), LOG_LEVEL_0, epee::log_space::console_color_red, true, log_name); LOCAL_ASSERT(0); epee::log_space::increase_error_count(LOG_DEFAULT_CHANNEL);CATCH_ALL_DO_NOTHING();}
|
||||
#define LOG_ERROR2_CB(log_name, x, cb) { \
|
||||
TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << "[ERROR] Location: " << std::endl << LOCATION_SS << epee::misc_utils::get_callstack() << " Message:" << std::endl << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str(), LOG_LEVEL_0, epee::log_space::console_color_red, true, log_name); LOCAL_ASSERT(0); epee::log_space::increase_error_count(LOG_DEFAULT_CHANNEL); cb(ss________.str()); CATCH_ALL_DO_NOTHING();}
|
||||
|
||||
#define LOG_ERROR2(log_name, x) LOG_ERROR2_CB(log_name, x, epee::log_space::log_stub)
|
||||
#define LOG_PRINT_CHANNEL2(log_channel, log_name, x, y) LOG_PRINT_CHANNEL2_CB(log_channel, log_name, x, y, epee::log_space::log_stub)
|
||||
#define LOG_PRINT_CHANNEL_COLOR2(log_channel, log_name, x, y, color) LOG_PRINT_CHANNEL_COLOR2_CB(log_channel, log_name, x, y, color, epee::log_space::log_stub)
|
||||
|
||||
#define LOG_FRAME2(log_name, x, y) epee::log_space::log_frame frame(x, y, log_name)
|
||||
|
||||
|
|
@ -163,7 +167,9 @@ DISABLE_VS_WARNINGS(4100)
|
|||
#define LOG_PRINT_NO_PREFIX_NO_POSTFIX2(log_name, x, y) LOG_PRINT_CHANNEL_NO_PREFIX_NO_POSTFIX2(LOG_DEFAULT_CHANNEL, log_name, x, y)
|
||||
#define LOG_PRINT_NO_POSTFIX2(log_name, x, y) LOG_PRINT_CHANNEL_NO_POSTFIX2(LOG_DEFAULT_CHANNEL, log_name, x, y)
|
||||
#define LOG_PRINT2(log_name, x, y) LOG_PRINT_CHANNEL2(LOG_DEFAULT_CHANNEL, log_name, x, y)
|
||||
#define LOG_PRINT2_CB(log_name, x, y, cb) LOG_PRINT_CHANNEL2_CB(LOG_DEFAULT_CHANNEL, log_name, x, y, cb)
|
||||
#define LOG_PRINT_COLOR2(log_name, x, y, color) LOG_PRINT_CHANNEL_COLOR2(LOG_DEFAULT_CHANNEL, log_name, x, y, color)
|
||||
#define LOG_PRINT_COLOR2_CB(log_name, x, y, color, cb) LOG_PRINT_CHANNEL_COLOR2_CB(LOG_DEFAULT_CHANNEL, log_name, x, y, color, cb)
|
||||
#define LOG_PRINT2_JORNAL(log_name, x, y) LOG_PRINT_CHANNEL_2_JORNAL(LOG_DEFAULT_CHANNEL, log_name, x, y)
|
||||
|
||||
#ifndef LOG_DEFAULT_TARGET
|
||||
|
|
@ -173,17 +179,28 @@ DISABLE_VS_WARNINGS(4100)
|
|||
#define LOG_PRINT_NO_POSTFIX(mess, level) LOG_PRINT_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level)
|
||||
#define LOG_PRINT_NO_PREFIX(mess, level) LOG_PRINT_NO_PREFIX2(LOG_DEFAULT_TARGET, mess, level)
|
||||
#define LOG_PRINT_NO_PREFIX_NO_POSTFIX(mess, level) LOG_PRINT_NO_PREFIX_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level)
|
||||
|
||||
#define LOG_PRINT(mess, level) LOG_PRINT2(LOG_DEFAULT_TARGET, mess, level)
|
||||
#define LOG_PRINT_CB(mess, level, cb) LOG_PRINT2_CB(LOG_DEFAULT_TARGET, mess, level, cb)
|
||||
#define LOG_PRINT_COLOR_CB(mess, level, color, cb) LOG_PRINT_COLOR2_CB(LOG_DEFAULT_TARGET, mess, level, color, cb)
|
||||
|
||||
#define LOG_COLOR_RED epee::log_space::console_color_red
|
||||
#define LOG_COLOR_GREEN epee::log_space::console_color_green
|
||||
#define LOG_COLOR_BLUE epee::log_space::console_color_blue
|
||||
#define LOG_COLOR_YELLOW epee::log_space::console_color_yellow
|
||||
#define LOG_COLOR_CYAN epee::log_space::console_color_cyan
|
||||
#define LOG_COLOR_MAGENTA epee::log_space::console_color_magenta
|
||||
|
||||
#define LOG_PRINT_COLOR(mess, level, color) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, color)
|
||||
#define LOG_PRINT_RED(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_red)
|
||||
#define LOG_PRINT_GREEN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_green)
|
||||
#define LOG_PRINT_BLUE(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_blue)
|
||||
#define LOG_PRINT_YELLOW(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_yellow)
|
||||
#define LOG_PRINT_CYAN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_cyan)
|
||||
#define LOG_PRINT_MAGENTA(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_magenta)
|
||||
#define LOG_PRINT_RED(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_RED)
|
||||
#define LOG_PRINT_GREEN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_GREEN)
|
||||
#define LOG_PRINT_BLUE(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_BLUE)
|
||||
#define LOG_PRINT_YELLOW(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_YELLOW)
|
||||
#define LOG_PRINT_CYAN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_CYAN)
|
||||
#define LOG_PRINT_MAGENTA(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_MAGENTA)
|
||||
|
||||
#define LOG_PRINT_RED_L0(mess) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, LOG_LEVEL_0, epee::log_space::console_color_red)
|
||||
#define LOG_PRINT_GREEN_L0(mess) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, LOG_LEVEL_0, epee::log_space::console_color_green)
|
||||
|
||||
#define LOG_PRINT_L0(mess) LOG_PRINT(mess, LOG_LEVEL_0)
|
||||
#define LOG_PRINT_L1(mess) LOG_PRINT(mess, LOG_LEVEL_1)
|
||||
|
|
@ -193,6 +210,7 @@ DISABLE_VS_WARNINGS(4100)
|
|||
#define LOG_PRINT_J(mess, level) LOG_PRINT2_JORNAL(LOG_DEFAULT_TARGET, mess, level)
|
||||
|
||||
#define LOG_ERROR(mess) LOG_ERROR2(LOG_DEFAULT_TARGET, mess)
|
||||
#define LOG_ERROR_CB(mess, cb) LOG_ERROR2_CB(LOG_DEFAULT_TARGET, mess, cb)
|
||||
#define LOG_FRAME(mess, level) LOG_FRAME2(LOG_DEFAULT_TARGET, mess, level)
|
||||
#define LOG_VALUE(mess, level) LOG_VALUE2(LOG_DEFAULT_TARGET, mess, level)
|
||||
#define LOG_ARRAY(mess, level) LOG_ARRAY2(LOG_DEFAULT_TARGET, mess, level)
|
||||
|
|
@ -334,6 +352,7 @@ namespace log_space
|
|||
/************************************************************************/
|
||||
#define CONSOLE_DEFAULT_STREAM std::cout
|
||||
|
||||
inline void log_stub(const std::string& /**/) {}
|
||||
|
||||
struct delete_ptr
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2006-2021, Andrey N. Sabelnikov, www.sabelnikov.net
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the Andrey N. Sabelnikov nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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
|
||||
|
||||
namespace epee
|
||||
{
|
||||
|
||||
template<class _Ty1, class _Ty2>
|
||||
struct kvserializable_pair : public std::pair<_Ty1, _Ty2>
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(first)
|
||||
KV_SERIALIZE(second)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
}
|
||||
|
|
@ -115,7 +115,7 @@ public: \
|
|||
template<t_uint mask>
|
||||
inline static bool get_value_of_flag_by_mask(const t_uint& given_flags)
|
||||
{
|
||||
return given_flags&mask == 0 ? false : true;
|
||||
return (given_flags&mask) == 0 ? false : true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <deque>
|
||||
|
||||
namespace epee
|
||||
|
|
|
|||
|
|
@ -94,6 +94,25 @@ namespace epee
|
|||
return serialization::load_t_from_binary(result_struct, pri->m_body);
|
||||
}
|
||||
|
||||
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_json_rpc(const std::string& url, const std::string& method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, epee::json_rpc::error& err, unsigned int timeout = 5000, const std::string& http_method = "GET", const std::string& req_id = "0")
|
||||
{
|
||||
epee::json_rpc::request<t_request> req_t = AUTO_VAL_INIT(req_t);
|
||||
req_t.jsonrpc = "2.0";
|
||||
req_t.id = req_id;
|
||||
req_t.method = method_name;
|
||||
req_t.params = out_struct;
|
||||
epee::json_rpc::response<t_response, epee::json_rpc::error> resp_t = AUTO_VAL_INIT(resp_t);
|
||||
if (!epee::net_utils::invoke_http_json_remote_command2(url, req_t, resp_t, transport, timeout, http_method))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
err = resp_t.error;
|
||||
result_struct = resp_t.result;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class t_request, class t_response, class t_transport>
|
||||
bool invoke_http_json_rpc(const std::string& url, const std::string& method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& http_method = "GET", const std::string& req_id = "0")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include "misc_language.h"
|
||||
#include "portable_storage_base.h"
|
||||
#include "portable_storage_to_bin.h"
|
||||
|
|
|
|||
|
|
@ -284,12 +284,19 @@ POP_GCC_WARNINGS
|
|||
typedef std::map<std::wstring, std::wstring> command_line_params_w;
|
||||
|
||||
template<typename t_pod_data>
|
||||
void apped_pod_to_strbuff(std::string& buff, const t_pod_data& pod)
|
||||
void append_pod_to_strbuff(std::string& buff, const t_pod_data& pod)
|
||||
{
|
||||
buff.append(reinterpret_cast<const char*>(&pod), sizeof(pod));
|
||||
}
|
||||
|
||||
|
||||
template<typename pod_t>
|
||||
bool get_pod_from_strbuff(const std::string& buff, pod_t& output)
|
||||
{
|
||||
if (buff.size() != sizeof(pod_t))
|
||||
return false;
|
||||
output = *reinterpret_cast<const pod_t*>(buff.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class t_string>
|
||||
bool parse_commandline(std::map<t_string, t_string>& res, int argc, char** argv)
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ DISABLE_VS_WARNINGS(4996)
|
|||
POP_VS_WARNINGS
|
||||
|
||||
if(pt)
|
||||
strftime( tmpbuf, 199, "%Y_%m_%d %H_%M_%S", pt );
|
||||
strftime( tmpbuf, 199, "%Y-%m-%d %H-%M-%S", pt );
|
||||
else
|
||||
{
|
||||
std::stringstream strs;
|
||||
|
|
|
|||
|
|
@ -315,6 +315,13 @@ namespace crypto
|
|||
return *this;
|
||||
}
|
||||
|
||||
// returns this = a * b
|
||||
scalar_t& assign_mul(const scalar_t& a, const scalar_t& b)
|
||||
{
|
||||
sc_mul(m_s, a.m_s, b.m_s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*
|
||||
I think it has bad symantic (operator-like), consider rename/reimplement -- sowle
|
||||
*/
|
||||
|
|
@ -426,6 +433,17 @@ namespace crypto
|
|||
|
||||
}; // struct scalar_t
|
||||
|
||||
//
|
||||
// Global constants
|
||||
//
|
||||
|
||||
extern const scalar_t c_scalar_1;
|
||||
extern const scalar_t c_scalar_L;
|
||||
extern const scalar_t c_scalar_Lm1;
|
||||
extern const scalar_t c_scalar_P;
|
||||
extern const scalar_t c_scalar_Pm1;
|
||||
extern const scalar_t c_scalar_256m1;
|
||||
extern const scalar_t c_scalar_1div8;
|
||||
|
||||
//
|
||||
//
|
||||
|
|
@ -479,6 +497,7 @@ namespace crypto
|
|||
zero();
|
||||
}
|
||||
|
||||
// as we're using additive notation, zero means identity group element here and after
|
||||
void zero()
|
||||
{
|
||||
ge_p3_0(&m_p3);
|
||||
|
|
@ -490,6 +509,11 @@ namespace crypto
|
|||
return fe_isnonzero(m_p3.X) * fe_cmp(m_p3.Y, m_p3.Z) == 0;
|
||||
}
|
||||
|
||||
bool is_in_main_subgroup() const
|
||||
{
|
||||
return (c_scalar_L * *this).is_zero();
|
||||
}
|
||||
|
||||
bool from_public_key(const crypto::public_key& pk)
|
||||
{
|
||||
return ge_frombytes_vartime(&m_p3, reinterpret_cast<const unsigned char*>(&pk)) == 0;
|
||||
|
|
@ -710,20 +734,152 @@ namespace crypto
|
|||
}; // struct point_g_t
|
||||
|
||||
|
||||
//
|
||||
// vector of scalars
|
||||
//
|
||||
struct scalar_vec_t : public std::vector<scalar_t>
|
||||
{
|
||||
typedef std::vector<scalar_t> super_t;
|
||||
|
||||
scalar_vec_t() {}
|
||||
scalar_vec_t(size_t n) : super_t(n) {}
|
||||
scalar_vec_t(std::initializer_list<scalar_t> init_list) : super_t(init_list) {}
|
||||
|
||||
bool is_reduced() const
|
||||
{
|
||||
for (auto& el : *this)
|
||||
if (!el.is_reduced())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// add a scalar rhs to each element
|
||||
scalar_vec_t operator+(const scalar_t& rhs) const
|
||||
{
|
||||
scalar_vec_t result(size());
|
||||
for (size_t i = 0, n = size(); i < n; ++i)
|
||||
result[i] = at(i) + rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
// subtract a scalar rhs to each element
|
||||
scalar_vec_t operator-(const scalar_t& rhs) const
|
||||
{
|
||||
scalar_vec_t result(size());
|
||||
for (size_t i = 0, n = size(); i < n; ++i)
|
||||
result[i] = at(i) - rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
// multiply each element of the vector by a scalar
|
||||
scalar_vec_t operator*(const scalar_t& rhs) const
|
||||
{
|
||||
scalar_vec_t result(size());
|
||||
for (size_t i = 0, n = size(); i < n; ++i)
|
||||
result[i] = at(i) * rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
// component-wise multiplication (a.k.a the Hadamard product) (only if their sizes match)
|
||||
scalar_vec_t operator*(const scalar_vec_t& rhs) const
|
||||
{
|
||||
scalar_vec_t result;
|
||||
const size_t n = size();
|
||||
if (n != rhs.size())
|
||||
return result;
|
||||
|
||||
result.resize(size());
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
result[i] = at(i) * rhs[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
// add each element of two vectors, but only if their sizes match
|
||||
scalar_vec_t operator+(const scalar_vec_t& rhs) const
|
||||
{
|
||||
scalar_vec_t result;
|
||||
const size_t n = size();
|
||||
if (n != rhs.size())
|
||||
return result;
|
||||
|
||||
result.resize(size());
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
result[i] = at(i) + rhs[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
// zeroes all elements
|
||||
void zero()
|
||||
{
|
||||
size_t size_bytes = sizeof(scalar_t) * size();
|
||||
memset(data(), 0, size_bytes);
|
||||
}
|
||||
|
||||
// invert all elements in-place efficiently: 4*N muptiplications + 1 inversion
|
||||
void invert()
|
||||
{
|
||||
// muls muls_rev
|
||||
// 0: 1 2 3 .. n-1
|
||||
// 1: 0 2 3 .. n-1
|
||||
// 2: 0 1 3 .. n-1
|
||||
//
|
||||
// n-1: 0 1 2 3 .. n-2
|
||||
|
||||
const size_t size = this->size();
|
||||
|
||||
if (size < 2)
|
||||
{
|
||||
if (size == 1)
|
||||
at(0) = at(0).reciprocal();
|
||||
return;
|
||||
}
|
||||
|
||||
scalar_vec_t muls(size), muls_rev(size);
|
||||
muls[0] = 1;
|
||||
for (size_t i = 0; i < size - 1; ++i)
|
||||
muls[i + 1] = at(i) * muls[i];
|
||||
|
||||
muls_rev[size - 1] = 1;
|
||||
for (size_t i = size - 1; i != 0; --i)
|
||||
muls_rev[i - 1] = at(i) * muls_rev[i];
|
||||
|
||||
scalar_t inv = (muls[size - 1] * at(size - 1)).reciprocal();
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
at(i) = muls[i] * inv * muls_rev[i];
|
||||
}
|
||||
|
||||
scalar_t calc_hs() const;
|
||||
|
||||
}; // scalar_vec_t
|
||||
|
||||
|
||||
// treats vector of scalars as an M x N matrix just for convenience
|
||||
template<size_t N>
|
||||
struct scalar_mat_t : public scalar_vec_t
|
||||
{
|
||||
typedef scalar_vec_t super_t;
|
||||
static_assert(N > 0, "invalid N value");
|
||||
|
||||
scalar_mat_t() {}
|
||||
scalar_mat_t(size_t n) : super_t(n) {}
|
||||
scalar_mat_t(std::initializer_list<scalar_t> init_list) : super_t(init_list) {}
|
||||
|
||||
// matrix accessor M rows x N cols
|
||||
scalar_t& operator()(size_t row, size_t col)
|
||||
{
|
||||
return at(row * N + col);
|
||||
}
|
||||
}; // scalar_mat_t
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Global constants
|
||||
//
|
||||
|
||||
extern const point_g_t c_point_G;
|
||||
|
||||
extern const scalar_t c_scalar_1;
|
||||
extern const scalar_t c_scalar_L;
|
||||
extern const scalar_t c_scalar_Lm1;
|
||||
extern const scalar_t c_scalar_P;
|
||||
extern const scalar_t c_scalar_Pm1;
|
||||
extern const scalar_t c_scalar_256m1;
|
||||
extern const scalar_t c_scalar_1div8;
|
||||
|
||||
extern const point_t c_point_H;
|
||||
extern const point_t c_point_0;
|
||||
|
||||
|
|
@ -901,4 +1057,11 @@ namespace crypto
|
|||
}; // hash_helper_t struct
|
||||
|
||||
|
||||
inline scalar_t scalar_vec_t::calc_hs() const
|
||||
{
|
||||
// hs won't touch memory if size is 0, so it's safe
|
||||
return hash_helper_t::hs(data(), sizeof(scalar_t) * size());
|
||||
}
|
||||
|
||||
|
||||
} // namespace crypto
|
||||
|
|
|
|||
12
src/crypto/range_proofs.cpp
Normal file
12
src/crypto/range_proofs.cpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2021 Zano Project (https://zano.org/)
|
||||
// Copyright (c) 2021 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#include "range_proofs.h"
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
const point_t& bpp_crypto_trait_zano::bpp_H = c_point_H;
|
||||
|
||||
|
||||
}
|
||||
823
src/crypto/range_proofs.h
Normal file
823
src/crypto/range_proofs.h
Normal file
|
|
@ -0,0 +1,823 @@
|
|||
// Copyright (c) 2021 Zano Project (https://zano.org/)
|
||||
// Copyright (c) 2021 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// This file contains the implementation of range proof protocol.
|
||||
// Namely, Bulletproofs+ https://eprint.iacr.org/2020/735.pdf
|
||||
//
|
||||
|
||||
#include "epee/include/misc_log_ex.h"
|
||||
#include "crypto-sugar.h"
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
|
||||
// returns x + x^2 + x^3 + ... + x^(2^f)
|
||||
// == x * (x + 1) * (x^2 + 1) * (x^4 + 1) * ...(x^(f+1) + 1)
|
||||
inline scalar_t sum_of_powers(scalar_t x, size_t f)
|
||||
{
|
||||
scalar_t result = x;
|
||||
for (size_t i = 0; i < f; ++i)
|
||||
{
|
||||
result.assign_muladd(result, x, result);
|
||||
x *= x;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr size_t c_bpp_log2_n = 6;
|
||||
constexpr size_t c_bpp_n = 64; // 2^64 is the upper bound for the witness's range
|
||||
constexpr size_t c_bpp_values_max = 16; // maximum number of elements in BP+ proof, i.e. max allowed BP+ outputs
|
||||
constexpr size_t c_bpp_mn_max = c_bpp_n * c_bpp_values_max;
|
||||
|
||||
// returns smallest k, s.t. v <= 2**k
|
||||
inline size_t calc_exp_power_of_2_upper_bound(size_t v)
|
||||
{
|
||||
constexpr size_t max_v = (SIZE_MAX >> 1) + 1;
|
||||
//if (v > max_v)
|
||||
// return 0;
|
||||
|
||||
size_t pow = 1, result = 0;
|
||||
while (v > pow)
|
||||
{
|
||||
pow <<= 1;
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// returns least significant bit uing de Bruijn sequence
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html
|
||||
inline uint8_t calc_lsb_32(uint32_t v)
|
||||
{
|
||||
static const uint8_t multiply_de_bruijn_bit_position[32] =
|
||||
{
|
||||
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
||||
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
|
||||
};
|
||||
return multiply_de_bruijn_bit_position[((uint32_t)((v & -(int32_t)v) * 0x077CB531U)) >> 27];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// crypto trait for Zano
|
||||
////////////////////////////////////////
|
||||
struct bpp_crypto_trait_zano
|
||||
{
|
||||
static void calc_pedersen_commitment(const scalar_t& value, const scalar_t& mask, point_t& commitment)
|
||||
{
|
||||
commitment = value * c_point_G + mask * c_point_H;
|
||||
}
|
||||
|
||||
static const scalar_t& get_initial_transcript()
|
||||
{
|
||||
static scalar_t value = hash_helper_t::hs("Zano BP+ initial transcript");
|
||||
return value;
|
||||
}
|
||||
|
||||
// assumes hsc is cleared
|
||||
static void update_transcript(hash_helper_t::hs_t& hsc, scalar_t& e, const std::vector<point_t>& points)
|
||||
{
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_points_array(points);
|
||||
e = hsc.calc_hash();
|
||||
}
|
||||
|
||||
static const point_t& get_generator(bool select_H, size_t index)
|
||||
{
|
||||
if (index >= c_bpp_mn_max)
|
||||
return c_point_0; // out of bound
|
||||
|
||||
static std::vector<point_t> generators(2 * c_bpp_mn_max);
|
||||
static bool calculated = false;
|
||||
if (!calculated)
|
||||
{
|
||||
scalar_t hash_buf[2] = { hash_helper_t::hs("Zano BP+ generator"), 0 };
|
||||
for (size_t i = 0; i < 2 * c_bpp_mn_max; ++i)
|
||||
{
|
||||
hash_buf[1].m_u64[0] = i;
|
||||
ge_bytes_hash_to_ec(&generators[i].m_p3, &hash_buf, sizeof hash_buf);
|
||||
}
|
||||
calculated = true;
|
||||
}
|
||||
|
||||
return generators[2 * index + (select_H ? 1 : 0)];
|
||||
}
|
||||
|
||||
static const point_t& bpp_H;
|
||||
};
|
||||
|
||||
|
||||
struct bpp_signature
|
||||
{
|
||||
std::vector<public_key> L; // size = log_2(m * n)
|
||||
std::vector<public_key> R;
|
||||
public_key A0;
|
||||
public_key A;
|
||||
public_key B;
|
||||
scalar_t r;
|
||||
scalar_t s;
|
||||
scalar_t delta;
|
||||
};
|
||||
|
||||
#define DBG_VAL_PRINT(x) std::cout << #x ": " << x << ENDL
|
||||
#define DBG_PRINT(x) std::cout << x << ENDL
|
||||
|
||||
template<typename CT>
|
||||
bool bpp_gen(const std::vector<uint64_t>& values, const scalar_vec_t& masks, bpp_signature& sig, std::vector<point_t>& commitments, uint8_t* p_err = nullptr)
|
||||
{
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("bpp_gen: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(values.size() > 0 && values.size() <= c_bpp_values_max && values.size() == masks.size(), 1);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(masks.is_reduced(), 3);
|
||||
|
||||
const size_t c_bpp_log2_m = calc_exp_power_of_2_upper_bound(values.size());
|
||||
const size_t c_bpp_m = 1ull << c_bpp_log2_m;
|
||||
const size_t c_bpp_mn = c_bpp_m * c_bpp_n;
|
||||
const size_t c_bpp_log2_mn = c_bpp_log2_m + c_bpp_log2_n;
|
||||
|
||||
// pre-multiply all output points by c_scalar_1div8
|
||||
// in order to enforce these points to be in the prime-order subgroup (after mul by 8 in bpp_verify())
|
||||
|
||||
// calc commitments vector as commitments[i] = 1/8 * values[i] * G + 1/8 * masks[i] * H
|
||||
commitments.resize(values.size());
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
CT::calc_pedersen_commitment(scalar_t(values[i]) * c_scalar_1div8, masks[i] * c_scalar_1div8, commitments[i]);
|
||||
|
||||
|
||||
// s.a. BP+ paper, page 15, eq. 11
|
||||
// decompose v into aL and aR:
|
||||
// v = aL o (1, 2, 2^2, ..., 2^n-1), o - component-wise product aka Hadamard product
|
||||
// aR = aL - (1, 1, ... 1)
|
||||
// aR o aL = 0
|
||||
|
||||
// aLs = (aL_0, aL_1, ..., aL_m-1) -- `bit` matrix of c_bpp_m x c_bpp_n, each element is a scalar
|
||||
|
||||
scalar_mat_t<c_bpp_n> aLs(c_bpp_mn), aRs(c_bpp_mn);
|
||||
aLs.zero();
|
||||
aRs.zero();
|
||||
// m >= values.size, first set up [0..values.size-1], then -- [values.size..m-1] (padding area)
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
{
|
||||
uint64_t v = values[i];
|
||||
for (size_t j = 0; j < c_bpp_n; ++j)
|
||||
{
|
||||
if (v & 1)
|
||||
aLs(i, j) = c_scalar_1; // aL = 1, aR = 0
|
||||
else
|
||||
aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1
|
||||
v >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = values.size(); i < c_bpp_m; ++i)
|
||||
for (size_t j = 0; j < c_bpp_n; ++j)
|
||||
aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1
|
||||
|
||||
|
||||
// using e as Fiat-Shamir transcript
|
||||
scalar_t e = CT::get_initial_transcript();
|
||||
DBG_PRINT("initial transcript: " << e);
|
||||
|
||||
hash_helper_t::hs_t hsc;
|
||||
CT::update_transcript(hsc, e, commitments);
|
||||
|
||||
// BP+ paper, page 15: The prover begins with sending A = g^aL h^aR h^alpha (group element)
|
||||
// so we calculate A0 = alpha * H + SUM(aL_i * G_i) + SUM(aR_i * H_i)
|
||||
|
||||
scalar_t alpha = scalar_t::random();
|
||||
point_t A0 = alpha * CT::bpp_H;
|
||||
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
A0 += aLs[i] * CT::get_generator(false, i) + aRs[i] * CT::get_generator(true, i);
|
||||
|
||||
// part of 1/8 defense scheme
|
||||
A0 *= c_scalar_1div8;
|
||||
A0.to_public_key(sig.A0);
|
||||
|
||||
DBG_VAL_PRINT(alpha);
|
||||
DBG_VAL_PRINT(A0);
|
||||
|
||||
// calculate scalar challenges y and z
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A0);
|
||||
scalar_t y = hsc.calc_hash();
|
||||
scalar_t z = hash_helper_t::hs(y);
|
||||
e = z; // transcript for further steps
|
||||
DBG_VAL_PRINT(y);
|
||||
DBG_VAL_PRINT(z);
|
||||
|
||||
// Computing vector d for aggregated version of the protocol (BP+ paper, page 17)
|
||||
// (note: elements is stored column-by-column in memory)
|
||||
// d = | 1 * z^(2*1), 1 * z^(2*2), 1 * z^(2*3), ..., 1 * z^(2*m) |
|
||||
// | 2 * z^(2*1), 2 * z^(2*2), 2 * z^(2*3), ..., 2 * z^(2*m) |
|
||||
// | 4 * z^(2*1), 4 * z^(2*2), 4 * z^(2*3), ..., 4 * z^(2*m) |
|
||||
// | ....................................................................................... |
|
||||
// | 2^(n-1) * z^(2*1), 2^(n-1) * z^(2*2), 2^(n-1) * z^(2*3), ..., 2^(n-1) * z^(2*m)) |
|
||||
// Note: sum(d_i) = (2^n - 1) * ((z^2)^1 + (z^2)^2 + ... (z^2)^m)) = (2^n-1) * sum_of_powers(x^2, log(m))
|
||||
|
||||
scalar_t z_sq = z * z;
|
||||
scalar_mat_t<c_bpp_n> d(c_bpp_mn);
|
||||
d(0, 0) = z_sq;
|
||||
// first row
|
||||
for (size_t i = 1; i < c_bpp_m; ++i)
|
||||
d(i, 0) = d(i - 1, 0) * z_sq;
|
||||
// all rows
|
||||
for (size_t j = 1; j < c_bpp_n; ++j)
|
||||
for (size_t i = 0; i < c_bpp_m; ++i)
|
||||
d(i, j) = d(i, j - 1) + d(i, j - 1);
|
||||
|
||||
DBG_PRINT("Hs(d): " << d.calc_hs());
|
||||
|
||||
// calculate extended Vandermonde vector y = (1, y, y^2, ..., y^(mn+1)) (BP+ paper, page 18, Fig. 3)
|
||||
// (calculate two more elements (1 and y^(mn+1)) for convenience)
|
||||
scalar_vec_t y_powers(c_bpp_mn + 2);
|
||||
y_powers[0] = 1;
|
||||
for (size_t i = 1; i <= c_bpp_mn + 1; ++i)
|
||||
y_powers[i] = y_powers[i - 1] * y;
|
||||
|
||||
const scalar_t& y_mn_p1 = y_powers[c_bpp_mn + 1];
|
||||
|
||||
DBG_PRINT("Hs(y_powers): " << y_powers.calc_hs());
|
||||
|
||||
// aL_hat = aL - 1*z
|
||||
scalar_vec_t aLs_hat = aLs - z;
|
||||
// aL_hat = aR + d o y^leftarr + 1*z where y^leftarr = (y^n, y^(n-1), ..., y) (BP+ paper, page 18, Fig. 3)
|
||||
scalar_vec_t aRs_hat = aRs + z;
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
aRs_hat[i] += d[i] * y_powers[c_bpp_mn - i];
|
||||
|
||||
DBG_PRINT("Hs(aLs_hat): " << aLs_hat.calc_hs());
|
||||
DBG_PRINT("Hs(aRs_hat): " << aRs_hat.calc_hs());
|
||||
|
||||
// calculate alpha_hat
|
||||
// alpha_hat = alpha + SUM(z^(2j) * gamma_j * y^(mn+1)) for j = 1..m
|
||||
// i.e. \hat{\alpha} = \alpha + y^{m n+1} \sum_{j = 1}^{m} z^{2j} \gamma_j
|
||||
scalar_t alpha_hat = 0;
|
||||
for (size_t i = 0; i < masks.size(); ++i)
|
||||
alpha_hat += d(i, 0) * masks[i];
|
||||
alpha_hat = alpha + y_mn_p1 * alpha_hat;
|
||||
|
||||
DBG_VAL_PRINT(alpha_hat);
|
||||
|
||||
// calculate y^-1, y^-2, ...
|
||||
const scalar_t y_inverse = y.reciprocal();
|
||||
scalar_vec_t y_inverse_powers(c_bpp_mn / 2 + 1); // the greatest power we need is c_bpp_mn/2 (at the first reduction round)
|
||||
y_inverse_powers[0] = 1;
|
||||
for (size_t i = 1, size = y_inverse_powers.size(); i < size; ++i)
|
||||
y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inverse;
|
||||
|
||||
// prepare generator's vector
|
||||
std::vector<point_t> g(c_bpp_mn), h(c_bpp_mn);
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
{
|
||||
g[i] = CT::get_generator(false, i);
|
||||
h[i] = CT::get_generator(true, i);
|
||||
}
|
||||
|
||||
// WIP zk-argument called with zk-WIP(g, h, G, H, A_hat, aL_hat, aR_hat, alpha_hat)
|
||||
|
||||
scalar_vec_t& a = aLs_hat;
|
||||
scalar_vec_t& b = aRs_hat;
|
||||
|
||||
sig.L.resize(c_bpp_log2_mn);
|
||||
sig.R.resize(c_bpp_log2_mn);
|
||||
|
||||
// zk-WIP reduction rounds (s.a. the preprint page 13 Fig. 1)
|
||||
for (size_t n = c_bpp_mn / 2, ni = 0; n >= 1; n /= 2, ++ni)
|
||||
{
|
||||
DBG_PRINT(ENDL << "#" << ni);
|
||||
|
||||
// zk-WIP(g, h, G, H, P, a, b, alpha)
|
||||
|
||||
scalar_t dL = scalar_t::random();
|
||||
DBG_VAL_PRINT(dL);
|
||||
scalar_t dR = scalar_t::random();
|
||||
DBG_VAL_PRINT(dR);
|
||||
|
||||
// a = (a1, a2), b = (b1, b2) -- vectors of scalars
|
||||
// cL = <a1, ((y, y^2, ...) o b2)> -- scalar
|
||||
scalar_t cL = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
cL += a[i] * y_powers[i + 1] * b[n + i];
|
||||
|
||||
DBG_VAL_PRINT(cL);
|
||||
|
||||
// cR = <a2, ((y, y^2, ...) o b1)> * y^n -- scalar
|
||||
scalar_t cR = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
cR += a[n + i] * y_powers[i + 1] * b[i];
|
||||
cR *= y_powers[n];
|
||||
|
||||
DBG_VAL_PRINT(cR);
|
||||
|
||||
// L = y^-n * a1 * g2 + b2 * h1 + cL * G + dL * H -- point
|
||||
point_t sum = c_point_0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
sum += a[i] * g[n + i];
|
||||
point_t L;
|
||||
CT::calc_pedersen_commitment(cL, dL, L);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
L += b[n + i] * h[i];
|
||||
L += y_inverse_powers[n] * sum;
|
||||
L *= c_scalar_1div8;
|
||||
DBG_VAL_PRINT(L);
|
||||
|
||||
// R = y^n * a2 * g1 + b1 * h2 + cR * G + dR * H -- point
|
||||
sum.zero();
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
sum += a[n + i] * g[i];
|
||||
point_t R;
|
||||
CT::calc_pedersen_commitment(cR, dR, R);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
R += b[i] * h[n + i];
|
||||
R += y_powers[n] * sum;
|
||||
R *= c_scalar_1div8;
|
||||
DBG_VAL_PRINT(R);
|
||||
|
||||
// put L, R to the sig
|
||||
L.to_public_key(sig.L[ni]);
|
||||
R.to_public_key(sig.R[ni]);
|
||||
|
||||
// update the transcript
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.L[ni]);
|
||||
hsc.add_pub_key(sig.R[ni]);
|
||||
e = hsc.calc_hash();
|
||||
DBG_VAL_PRINT(e);
|
||||
|
||||
// recalculate arguments for the next round
|
||||
scalar_t e_squared = e * e;
|
||||
scalar_t e_inverse = e.reciprocal();
|
||||
scalar_t e_inverse_squared = e_inverse * e_inverse;
|
||||
scalar_t e_y_inv_n = e * y_inverse_powers[n];
|
||||
scalar_t e_inv_y_n = e_inverse * y_powers[n];
|
||||
|
||||
// g_hat = e^-1 * g1 + (e * y^-n) * g2 -- vector of points
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
g[i] = e_inverse * g[i] + e_y_inv_n * g[n + i];
|
||||
|
||||
// h_hat = e * h1 + e^-1 * h2 -- vector of points
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
h[i] = e * h[i] + e_inverse * h[n + i];
|
||||
|
||||
// P_hat = e^2 * L + P + e^-2 * R -- point
|
||||
|
||||
// a_hat = e * a1 + e^-1 * y^n * a2 -- vector of scalars
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
a[i] = e * a[i] + e_inv_y_n * a[n + i];
|
||||
|
||||
// b_hat = e^-1 * b1 + e * b2 -- vector of scalars
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
b[i] = e_inverse * b[i] + e * b[n + i];
|
||||
|
||||
// alpha_hat = e^2 * dL + alpha + e^-2 * dR -- scalar
|
||||
alpha_hat += e_squared * dL + e_inverse_squared * dR;
|
||||
|
||||
// run next iteraton zk-WIP(g_hat, h_hat, G, H, P_hat, a_hat, b_hat, alpha_hat)
|
||||
}
|
||||
DBG_PRINT("");
|
||||
|
||||
// zk-WIP last round
|
||||
scalar_t r = scalar_t::random();
|
||||
scalar_t s = scalar_t::random();
|
||||
scalar_t delta = scalar_t::random();
|
||||
scalar_t eta = scalar_t::random();
|
||||
DBG_VAL_PRINT(r);
|
||||
DBG_VAL_PRINT(s);
|
||||
DBG_VAL_PRINT(delta);
|
||||
DBG_VAL_PRINT(eta);
|
||||
|
||||
// A = r * g + s * h + (r y b + s y a) * G + delta * H -- point
|
||||
point_t A = c_point_0;
|
||||
CT::calc_pedersen_commitment(y * (r * b[0] + s * a[0]), delta, A);
|
||||
A += r * g[0] + s * h[0];
|
||||
A *= c_scalar_1div8;
|
||||
A.to_public_key(sig.A);
|
||||
DBG_VAL_PRINT(A);
|
||||
|
||||
// B = (r * y * s) * G + eta * H
|
||||
point_t B = c_point_0;
|
||||
CT::calc_pedersen_commitment(r * y * s, eta, B);
|
||||
B *= c_scalar_1div8;
|
||||
B.to_public_key(sig.B);
|
||||
DBG_VAL_PRINT(B);
|
||||
|
||||
// update the transcript
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A);
|
||||
hsc.add_pub_key(sig.B);
|
||||
e = hsc.calc_hash();
|
||||
DBG_VAL_PRINT(e);
|
||||
|
||||
// finalize the signature
|
||||
sig.r = r + e * a[0];
|
||||
sig.s = s + e * b[0];
|
||||
sig.delta = eta + e * delta + e * e * alpha_hat;
|
||||
DBG_VAL_PRINT(sig.r);
|
||||
DBG_VAL_PRINT(sig.s);
|
||||
DBG_VAL_PRINT(sig.delta);
|
||||
|
||||
return true;
|
||||
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
|
||||
} // bpp_gen()
|
||||
|
||||
|
||||
// efficient multiexponentiation (naive stub implementation atm, TODO)
|
||||
template<typename CT>
|
||||
bool multiexp_and_check_being_zero(const scalar_vec_t& g_scalars, const scalar_vec_t& h_scalars, const point_t& summand)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(g_scalars.size() < c_bpp_mn_max, false, "g_scalars oversized");
|
||||
CHECK_AND_ASSERT_MES(h_scalars.size() < c_bpp_mn_max, false, "h_scalars oversized");
|
||||
|
||||
point_t result = summand;
|
||||
|
||||
for (size_t i = 0; i < g_scalars.size(); ++i)
|
||||
result += g_scalars[i] * CT::get_generator(false, i);
|
||||
|
||||
for (size_t i = 0; i < h_scalars.size(); ++i)
|
||||
result += h_scalars[i] * CT::get_generator(true, i);
|
||||
|
||||
if (!result.is_zero())
|
||||
{
|
||||
LOG_PRINT_L0("multiexp result is non zero: " << result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
struct bpp_sig_commit_ref_t
|
||||
{
|
||||
bpp_sig_commit_ref_t(const bpp_signature& sig, const std::vector<point_t>& commitments)
|
||||
: sig(sig)
|
||||
, commitments(commitments)
|
||||
{}
|
||||
const bpp_signature& sig;
|
||||
const std::vector<point_t>& commitments;
|
||||
};
|
||||
|
||||
|
||||
template<typename CT>
|
||||
bool bpp_verify(const std::vector<bpp_sig_commit_ref_t>& sigs, uint8_t* p_err = nullptr)
|
||||
{
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("bpp_verify: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
DBG_PRINT(ENDL << " . . . . bpp_verify() . . . . ");
|
||||
|
||||
const size_t kn = sigs.size();
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(kn > 0, 1);
|
||||
|
||||
struct intermediate_element_t
|
||||
{
|
||||
scalar_t y;
|
||||
scalar_t z;
|
||||
scalar_t z_sq;
|
||||
scalar_vec_t e;
|
||||
scalar_vec_t e_sq;
|
||||
scalar_t e_final;
|
||||
scalar_t e_final_sq;
|
||||
size_t inv_e_offset; // offset in batch_for_inverse
|
||||
size_t inv_y_offset; // offset in batch_for_inverse
|
||||
size_t c_bpp_log2_m;
|
||||
size_t c_bpp_m;
|
||||
size_t c_bpp_mn;
|
||||
point_t A;
|
||||
point_t A0;
|
||||
point_t B;
|
||||
std::vector<point_t> L;
|
||||
std::vector<point_t> R;
|
||||
};
|
||||
std::vector<intermediate_element_t> interms(kn);
|
||||
|
||||
size_t c_bpp_log2_m_max = 0;
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
const bpp_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bpp_signature& sig = bsc.sig;
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(bsc.commitments.size() > 0, 2);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() > 0 && sig.L.size() == sig.R.size(), 3);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.r.is_reduced() && sig.s.is_reduced() && sig.delta.is_reduced(), 4);
|
||||
|
||||
intermediate_element_t& interm = interms[k];
|
||||
interm.c_bpp_log2_m = calc_exp_power_of_2_upper_bound(bsc.commitments.size());
|
||||
if (c_bpp_log2_m_max < interm.c_bpp_log2_m)
|
||||
c_bpp_log2_m_max = interm.c_bpp_log2_m;
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() == interm.c_bpp_log2_m + c_bpp_log2_n, 5);
|
||||
|
||||
interm.c_bpp_m = 1ull << interm.c_bpp_log2_m;
|
||||
interm.c_bpp_mn = interm.c_bpp_m * c_bpp_n;
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A0.from_public_key(sig.A0), 6);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A.from_public_key(sig.A), 7);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.B.from_public_key(sig.B), 8);
|
||||
interm.L.resize(sig.L.size());
|
||||
interm.R.resize(sig.R.size());
|
||||
for (size_t i = 0; i < interm.L.size(); ++i)
|
||||
{
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.L[i].from_public_key(sig.L[i]), 9);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.R[i].from_public_key(sig.R[i]), 10);
|
||||
}
|
||||
}
|
||||
const size_t c_bpp_m_max = 1ull << c_bpp_log2_m_max;
|
||||
const size_t c_bpp_mn_max = c_bpp_m_max * c_bpp_n;
|
||||
const size_t c_bpp_LR_size_max = c_bpp_log2_m_max + c_bpp_log2_n;
|
||||
|
||||
|
||||
//
|
||||
// prepare stuff
|
||||
//
|
||||
/*
|
||||
std::vector<point_t> g(c_bpp_mn_max), h(c_bpp_mn_max);
|
||||
for (size_t i = 0; i < c_bpp_mn_max; ++i)
|
||||
{
|
||||
g[i] = CT::get_generator(false, i);
|
||||
h[i] = CT::get_generator(true, i);
|
||||
}
|
||||
*/
|
||||
|
||||
scalar_vec_t batch_for_inverse;
|
||||
batch_for_inverse.reserve(kn + kn * c_bpp_LR_size_max);
|
||||
|
||||
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
DBG_PRINT(ENDL << "SIG #" << k);
|
||||
const bpp_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bpp_signature& sig = bsc.sig;
|
||||
intermediate_element_t& interm = interms[k];
|
||||
|
||||
// restore y and z
|
||||
// using e as Fiat-Shamir transcript
|
||||
scalar_t e = CT::get_initial_transcript();
|
||||
DBG_PRINT("initial transcript: " << e);
|
||||
hash_helper_t::hs_t hsc;
|
||||
CT::update_transcript(hsc, e, bsc.commitments);
|
||||
// calculate scalar challenges y and z
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A0);
|
||||
hsc.assign_calc_hash(interm.y);
|
||||
interm.z = hash_helper_t::hs(interm.y);
|
||||
interm.z_sq = interm.z * interm.z;
|
||||
DBG_VAL_PRINT(interm.y);
|
||||
DBG_VAL_PRINT(interm.z);
|
||||
e = interm.z; // transcript for further steps
|
||||
|
||||
interm.inv_y_offset = batch_for_inverse.size();
|
||||
batch_for_inverse.push_back(interm.y);
|
||||
interm.inv_e_offset = batch_for_inverse.size();
|
||||
|
||||
interm.e.resize(sig.L.size());
|
||||
interm.e_sq.resize(sig.L.size());
|
||||
|
||||
for (size_t i = 0; i < sig.L.size(); ++i)
|
||||
{
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.L[i]);
|
||||
hsc.add_pub_key(sig.R[i]);
|
||||
hsc.assign_calc_hash(e);
|
||||
interm.e[i] = e;
|
||||
interm.e_sq[i] = e * e;
|
||||
DBG_PRINT("e[" << i << "]: " << e);
|
||||
batch_for_inverse.push_back(e);
|
||||
}
|
||||
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A);
|
||||
hsc.add_pub_key(sig.B);
|
||||
hsc.assign_calc_hash(interm.e_final);
|
||||
interm.e_final_sq = interm.e_final * interm.e_final;
|
||||
DBG_VAL_PRINT(interm.e_final);
|
||||
}
|
||||
|
||||
batch_for_inverse.invert();
|
||||
|
||||
// Notation:
|
||||
// 1_vec ^ n = (1, 1, 1, ..., 1)
|
||||
// 2_vec ^ n = (2^0, 2^1, 2^2, ..., 2^(n-1))
|
||||
// -1_vec ^ n = ((-1)^0, (-1)^1, (-1)^2, ... (-1)^(n-1)) = (1, -1, 1, -1, ...)
|
||||
// y<^n = (y^n, y^(n-1), ..., y^1)
|
||||
// y>^n = (y^1, y^2, ..., y^n)
|
||||
|
||||
// from page 13, Fig 1:
|
||||
// Verifier outputs Accept IFF the following equality holds (single proof):
|
||||
// P^e^2 * A^e * B == g ^ (r' e) * h ^ (s' e) * G ^ (r' y s') * H ^ delta'
|
||||
// (where g and h are calculated in each round)
|
||||
// The same equation in additive notation:
|
||||
// e^2 * P + e * A + B == (r' * e) * g + (s' * e) * h + (r' y s') * G + delta' * H
|
||||
// <=>
|
||||
// (r' * e) * g + (s' * e) * h + (r' y s') * G + delta' * H - e^2 * P - e * A - B == 0 (*)
|
||||
// where A, B, r', s', delta' is taken from the signature
|
||||
// and P_{k+1} = e^2 * L_k + P_k + e^-2 * R_k for all rounds
|
||||
//
|
||||
// from page 18, Fig 3:
|
||||
// P and V computes:
|
||||
// A_hat = A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h +
|
||||
// + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) +
|
||||
// + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G
|
||||
// (calculated once)
|
||||
//
|
||||
// As suggested in Section 6.1 "Practical Optimizations":
|
||||
// 1) g and h exponentianions can be optimized in order not to be calculated at each round as the following (page 20):
|
||||
//
|
||||
// (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta' * H -
|
||||
// - e^2 * A_hat
|
||||
// - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j)
|
||||
// - e * A - B = 0 (**)
|
||||
//
|
||||
// where:
|
||||
// g, h - vector of fixed generators
|
||||
// s_vec_i = y^(1-i) * PROD{j=1..log(n)}(e_j ^ b(i,j))
|
||||
// s'_vec_i = PROD{j=1..log(n)}(e_j ^ -b(i,j))
|
||||
// b(i, j) = { 2 * ((1<<(j-1)) & (i-1)) - 1) (counting both from 1) (page 20)
|
||||
// b(i, j) = { 2 * ((1<<j) & i) - 1) (counting both from 0)
|
||||
//
|
||||
// 2) we gonna aggregate all (**) for each round by multiplying them to a random weights and then sum up
|
||||
// insert A_hat into (**) =>
|
||||
|
||||
// (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta' * H -
|
||||
// - e^2 * (A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h +
|
||||
// + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) +
|
||||
// + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G
|
||||
// )
|
||||
// - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j)
|
||||
// - e * A - B = 0
|
||||
|
||||
// =>
|
||||
|
||||
// (for single signature)
|
||||
//
|
||||
// (r' * e * s_vec - e^2 * (- 1_vec^(mn) * z)) * g | these are
|
||||
// + (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z)) * h | fixed generators
|
||||
// + (r' y s' - e^2 * ((z - z^2)*SUM(y^>mn) - z*y^(mn+1)*SUM(d)) * G | across all
|
||||
// + delta' * H | the signatures
|
||||
//
|
||||
// - e^2 * A0
|
||||
// - e^2 * y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j))
|
||||
// - e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j)
|
||||
// - e * A - B = 0 (***)
|
||||
//
|
||||
// All (***) will be muptiplied by random weightning factor and then summed up.
|
||||
|
||||
// Calculate cummulative sclalar multiplicand for fixed generators across all the sigs.
|
||||
scalar_vec_t g_scalars;
|
||||
g_scalars.resize(c_bpp_mn_max, 0);
|
||||
scalar_vec_t h_scalars;
|
||||
h_scalars.resize(c_bpp_mn_max, 0);
|
||||
scalar_t G_scalar = 0;
|
||||
scalar_t H_scalar = 0;
|
||||
point_t summand = c_point_0;
|
||||
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
DBG_PRINT(ENDL << "SIG #" << k);
|
||||
const bpp_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bpp_signature& sig = bsc.sig;
|
||||
intermediate_element_t& interm = interms[k];
|
||||
|
||||
// random weightning factor for speed-optimized batch verification (preprint page 20)
|
||||
const scalar_t rwf = scalar_t::random();
|
||||
DBG_PRINT("rwf: " << rwf);
|
||||
|
||||
// prepare d vector (see also d structure description in proof function)
|
||||
scalar_mat_t<c_bpp_n> d(interm.c_bpp_mn);
|
||||
d(0, 0) = interm.z_sq;
|
||||
// first row
|
||||
for (size_t i = 1; i < interm.c_bpp_m; ++i)
|
||||
d(i, 0) = d(i - 1, 0) * interm.z_sq;
|
||||
// all rows
|
||||
for (size_t j = 1; j < c_bpp_n; ++j)
|
||||
for (size_t i = 0; i < interm.c_bpp_m; ++i)
|
||||
d(i, j) = d(i, j - 1) + d(i, j - 1);
|
||||
// sum(d) (see also note in proof function for this)
|
||||
static const scalar_t c_scalar_2_power_n_minus_1 = { 0xffffffffffffffff, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 };
|
||||
const scalar_t sum_d = c_scalar_2_power_n_minus_1 * sum_of_powers(interm.z_sq, interm.c_bpp_log2_m);
|
||||
|
||||
DBG_PRINT("Hs(d): " << d.calc_hs());
|
||||
DBG_PRINT("sum(d): " << sum_d);
|
||||
|
||||
const scalar_t& y_inv = batch_for_inverse[interm.inv_y_offset];
|
||||
auto get_e_inv = [&](size_t i) { return batch_for_inverse[interm.inv_e_offset + i]; }; // i belongs to [0; L.size()-1]
|
||||
|
||||
// prepare s_vec (unlike the paper here we moved y-component out of s_vec for convenience, so s_vec'[x] = s_vec[~x & (MN-1)])
|
||||
// complexity (sc_mul's): MN+2*log2(MN)-2
|
||||
// the idea is the following:
|
||||
// s_vec[00000b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^-1 * (e_1)^-1 * (e_0)^-1
|
||||
// s_vec[00101b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^+1 * (e_1)^-1 * (e_0)^+1
|
||||
const size_t log2_mn = sig.L.size(); // at the beginning we made sure that sig.L.size() == c_bpp_log2_m + c_bpp_log2_n
|
||||
scalar_vec_t s_vec(interm.c_bpp_mn);
|
||||
s_vec[0] = get_e_inv(0);
|
||||
for (size_t i = 1; i < log2_mn; ++i)
|
||||
s_vec[0] *= get_e_inv(i); // s_vec[0] = (e_0)^-1 * (e_1)^-1 * .. (e_{log2_mn-1})^-1
|
||||
DBG_PRINT("[0] " << s_vec[0]);
|
||||
for (size_t i = 1; i < interm.c_bpp_mn; ++i)
|
||||
{
|
||||
size_t base_el_index = i & (i - 1); // base element index: 0, 0, 2, 0, 4, 4, 6, 0, 8, 8, 10... base element differs in one bit (0) from the current one (1)
|
||||
size_t bit_index = log2_mn - calc_lsb_32((uint32_t)i) - 1; // the bit index where current element has the difference with the base
|
||||
s_vec[i] = s_vec[base_el_index] * interm.e_sq[bit_index]; // (e_j)^-1 * (e_j)^2 = (e_j)^+1
|
||||
DBG_PRINT("[" << i << "] " << " " << base_el_index << ", " << bit_index << " : " << s_vec[i]);
|
||||
}
|
||||
|
||||
// prepare y_inv vector
|
||||
scalar_vec_t y_inverse_powers(interm.c_bpp_mn);
|
||||
y_inverse_powers[0] = 1;
|
||||
for (size_t i = 1; i < interm.c_bpp_mn; ++i)
|
||||
y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inv;
|
||||
|
||||
// y^(mn+1)
|
||||
scalar_t y_power_mnp1 = interm.y;
|
||||
for (size_t i = 0; i < log2_mn; ++i)
|
||||
y_power_mnp1 *= y_power_mnp1;
|
||||
y_power_mnp1 *= interm.y;
|
||||
DBG_VAL_PRINT(y_power_mnp1);
|
||||
|
||||
// now calculate all multiplicands for common generators
|
||||
|
||||
// g vector multiplicands:
|
||||
// rwf * (r' * e * (1, y^-1, y^-2, ...) o s_vec + e^2 * z) =
|
||||
// rwf * r' * e * ((1, y^-1, ...) o s_vec) + rwf * e^2 * z * (1, 1, ...)
|
||||
scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z;
|
||||
scalar_t rwf_r_e = rwf * interm.e_final * sig.r;
|
||||
for (size_t i = 0; i < interm.c_bpp_mn; ++i)
|
||||
g_scalars[i] += rwf_r_e * y_inverse_powers[i] * s_vec[i] + rwf_e_sq_z;
|
||||
|
||||
DBG_PRINT("Hs(g_scalars): " << g_scalars.calc_hs());
|
||||
|
||||
// h vector multiplicands:
|
||||
// rwf * (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z))
|
||||
// rwf * s' * e * s'_vec - rwf * e^2 * z * (1, 1...) - rwf * e^2 * (d o y<^(mn))
|
||||
//scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z;
|
||||
scalar_t rwf_s_e = rwf * sig.s * interm.e_final;
|
||||
scalar_t rwf_e_sq_y = rwf * interm.e_final_sq * interm.y;
|
||||
for (size_t i = interm.c_bpp_mn - 1; i != SIZE_MAX; --i)
|
||||
{
|
||||
h_scalars[i] += rwf_s_e * s_vec[interm.c_bpp_mn - 1 - i] - rwf_e_sq_z - rwf_e_sq_y * d[i];
|
||||
rwf_e_sq_y *= interm.y;
|
||||
}
|
||||
|
||||
DBG_PRINT("Hs(h_scalars): " << h_scalars.calc_hs());
|
||||
|
||||
// G point multiplicands:
|
||||
// rwf * (r' y s' - e ^ 2 * ((z - z ^ 2)*SUM(y^>mn) - z * y^(mn+1) * SUM(d)) =
|
||||
// = rwf * r' y s' - rwf * e^2 * (z - z ^ 2)*SUM(y^>mn) + rwf * e^2 * z * y^(mn+1) * SUM(d)
|
||||
G_scalar += rwf * sig.r * interm.y * sig.s + rwf_e_sq_y * sum_d * interm.z;
|
||||
G_scalar -= rwf * interm.e_final_sq * (interm.z - interm.z_sq) * sum_of_powers(interm.y, log2_mn);
|
||||
DBG_PRINT("sum_y: " << sum_of_powers(interm.y, log2_mn));
|
||||
DBG_PRINT("G_scalar: " << G_scalar);
|
||||
|
||||
// H point multiplicands:
|
||||
// rwf * delta
|
||||
H_scalar += rwf * sig.delta;
|
||||
DBG_PRINT("H_scalar: " << H_scalar);
|
||||
|
||||
// uncommon generators' multiplicands
|
||||
point_t summand_8 = c_point_0; // this summand to be multiplied by 8 before adding to the main summand
|
||||
// - rwf * e^2 * A0
|
||||
summand_8 -= rwf * interm.e_final_sq * interm.A0;
|
||||
DBG_PRINT("A0_scalar: " << c_scalar_Lm1 * interm.e_final_sq * rwf);
|
||||
|
||||
// - rwf * e^2 * y^(mn+1) * (SUM{j=1..m} (z^2)^j * V_j))
|
||||
scalar_t e_sq_y_mn1_z_sq_power = rwf * interm.e_final_sq * y_power_mnp1;
|
||||
for (size_t j = 0; j < bsc.commitments.size(); ++j)
|
||||
{
|
||||
e_sq_y_mn1_z_sq_power *= interm.z_sq;
|
||||
summand_8 -= e_sq_y_mn1_z_sq_power * bsc.commitments[j];
|
||||
DBG_PRINT("V_scalar[" << j << "]: " << c_scalar_Lm1 * e_sq_y_mn1_z_sq_power);
|
||||
}
|
||||
|
||||
// - rwf * e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j)
|
||||
scalar_t rwf_e_sq = rwf * interm.e_final_sq;
|
||||
for (size_t j = 0; j < log2_mn; ++j)
|
||||
{
|
||||
summand_8 -= rwf_e_sq * (interm.e_sq[j] * interm.L[j] + get_e_inv(j) * get_e_inv(j) * interm.R[j]);
|
||||
DBG_PRINT("L_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * interm.e_sq[j]);
|
||||
DBG_PRINT("R_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * get_e_inv(j) * get_e_inv(j));
|
||||
}
|
||||
|
||||
// - rwf * e * A - rwf * B = 0
|
||||
summand_8 -= rwf * interm.e_final * interm.A + rwf * interm.B;
|
||||
DBG_PRINT("A_scalar: " << c_scalar_Lm1 * rwf * interm.e_final);
|
||||
DBG_PRINT("B_scalar: " << c_scalar_Lm1 * rwf);
|
||||
|
||||
summand_8.modify_mul8();
|
||||
summand += summand_8;
|
||||
}
|
||||
|
||||
point_t GH_exponents = c_point_0;
|
||||
CT::calc_pedersen_commitment(G_scalar, H_scalar, GH_exponents);
|
||||
bool result = multiexp_and_check_being_zero<CT>(g_scalars, h_scalars, summand + GH_exponents);
|
||||
if (result)
|
||||
DBG_PRINT(ENDL << " . . . . bpp_verify() -- SUCCEEDED!!!" << ENDL);
|
||||
return result;
|
||||
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
|
||||
}
|
||||
|
||||
} // namespace crypto
|
||||
|
|
@ -70,8 +70,7 @@ namespace currency
|
|||
iv = *((crypto::chacha8_iv*)&pass_hash);
|
||||
crypto::chacha8(scr_data, src_length, key, iv, (char*)dst_data);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
std::string account_base::get_seed_phrase(const std::string& password) const
|
||||
{
|
||||
if (m_keys_seed_binary.empty())
|
||||
|
|
|
|||
|
|
@ -16,13 +16,15 @@
|
|||
#define SEED_PHRASE_V2_WORDS_COUNT 26
|
||||
|
||||
|
||||
|
||||
#ifndef FORCE_HEADER_ONLY
|
||||
#define KV_SERIALIZE_ADDRESS_AS_TEXT_N(varialble, val_name) \
|
||||
KV_SERIALIZE_CUSTOM_N(varialble, std::string, currency::transform_addr_to_str, currency::transform_str_to_addr, val_name)
|
||||
|
||||
#define KV_SERIALIZE_ADDRESS_AS_TEXT(varialble) KV_SERIALIZE_ADDRESS_AS_TEXT_N(varialble, #varialble)
|
||||
|
||||
|
||||
#else
|
||||
#define KV_SERIALIZE_ADDRESS_AS_TEXT_N(varialble, val_name)
|
||||
#define KV_SERIALIZE_ADDRESS_AS_TEXT(varialble)
|
||||
#endif
|
||||
namespace currency
|
||||
{
|
||||
|
||||
|
|
@ -97,6 +99,7 @@ namespace currency
|
|||
std::vector<unsigned char> m_keys_seed_binary;
|
||||
};
|
||||
|
||||
const static account_keys null_acc_keys = AUTO_VAL_INIT(null_acc_keys);
|
||||
|
||||
std::string transform_addr_to_str(const account_public_address& addr);
|
||||
account_public_address transform_str_to_addr(const std::string& str);
|
||||
|
|
|
|||
7
src/currency_core/bc_block_datetime_service.h
Normal file
7
src/currency_core/bc_block_datetime_service.h
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
// Copyright (c) 2014-2021 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
|
||||
|
||||
#define BC_BLOCK_DATETIME_SERVICE_ID "d"
|
||||
#define BC_BLOCK_DATETIME_INSTRUCTION_DEFAULT ""
|
||||
|
|
@ -578,13 +578,13 @@ bool blockchain_storage::set_checkpoints(checkpoints&& chk_pts)
|
|||
catch (const std::exception& ex)
|
||||
{
|
||||
m_db.abort_transaction();
|
||||
LOG_ERROR("UNKNOWN EXCEPTION WHILE ADDINIG NEW BLOCK: " << ex.what());
|
||||
LOG_ERROR("UNKNOWN EXCEPTION WHILE SETTING CHECKPOINTS: " << ex.what());
|
||||
return false;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
m_db.abort_transaction();
|
||||
LOG_ERROR("UNKNOWN EXCEPTION WHILE ADDINIG NEW BLOCK.");
|
||||
LOG_ERROR("UNKNOWN EXCEPTION WHILE SETTING CHECKPOINTS.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -594,7 +594,7 @@ bool blockchain_storage::prune_ring_signatures_and_attachments(uint64_t height,
|
|||
{
|
||||
CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
|
||||
CHECK_AND_ASSERT_MES(height < m_db_blocks.size(), false, "prune_ring_signatures called with wrong parameter: " << height << ", m_blocks.size() " << m_db_blocks.size());
|
||||
CHECK_AND_ASSERT_MES(height < m_db_blocks.size(), false, "prune_ring_signatures called with wrong parameter: " << height << ", m_blocks.size() = " << m_db_blocks.size());
|
||||
auto vptr = m_db_blocks[height];
|
||||
CHECK_AND_ASSERT_MES(vptr.get(), false, "Failed to get block on height");
|
||||
|
||||
|
|
@ -626,23 +626,21 @@ bool blockchain_storage::prune_ring_signatures_and_attachments_if_need()
|
|||
{
|
||||
CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
|
||||
if (m_db_blocks.size() > 1 && m_checkpoints.get_top_checkpoint_height() && m_checkpoints.get_top_checkpoint_height() > m_db_current_pruned_rs_height)
|
||||
uint64_t top_block_height = get_top_block_height();
|
||||
uint64_t pruning_end_height = m_checkpoints.get_checkpoint_before_height(top_block_height);
|
||||
if (pruning_end_height > m_db_current_pruned_rs_height)
|
||||
{
|
||||
uint64_t pruning_last_height = std::min(m_db_blocks.size() - 1, m_checkpoints.get_top_checkpoint_height());
|
||||
if (pruning_last_height > m_db_current_pruned_rs_height)
|
||||
{
|
||||
LOG_PRINT_CYAN("Starting pruning ring signatues and attachments from height " << m_db_current_pruned_rs_height + 1 << " to height " << pruning_last_height
|
||||
<< " (" << pruning_last_height - m_db_current_pruned_rs_height << " blocks)", LOG_LEVEL_0);
|
||||
LOG_PRINT_CYAN("Starting pruning ring signatues and attachments from height " << m_db_current_pruned_rs_height + 1 << " to height " << pruning_end_height
|
||||
<< " (" << pruning_end_height - m_db_current_pruned_rs_height << " blocks), top block height is " << top_block_height, LOG_LEVEL_0);
|
||||
uint64_t tx_count = 0, sig_count = 0, attach_count = 0;
|
||||
for(uint64_t height = m_db_current_pruned_rs_height + 1; height <= pruning_last_height; height++)
|
||||
for(uint64_t height = m_db_current_pruned_rs_height + 1; height <= pruning_end_height; height++)
|
||||
{
|
||||
bool res = prune_ring_signatures_and_attachments(height, tx_count, sig_count, attach_count);
|
||||
CHECK_AND_ASSERT_MES(res, false, "failed to prune_ring_signatures_and_attachments for height = " << height);
|
||||
}
|
||||
m_db_current_pruned_rs_height = pruning_last_height;
|
||||
m_db_current_pruned_rs_height = pruning_end_height;
|
||||
LOG_PRINT_CYAN("Transaction pruning finished: " << sig_count << " signatures and " << attach_count << " attachments released in " << tx_count << " transactions.", LOG_LEVEL_0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
|
@ -1036,7 +1034,9 @@ void blockchain_storage::purge_alt_block_txs_hashs(const block& b)
|
|||
//------------------------------------------------------------------
|
||||
void blockchain_storage::do_erase_altblock(alt_chain_container::iterator it)
|
||||
{
|
||||
purge_altblock_keyimages_from_big_heap(it->second.bl, get_block_hash(it->second.bl));
|
||||
crypto::hash id = get_block_hash(it->second.bl);
|
||||
LOG_PRINT_L1("erasing alt block " << print16(id) << " @ " << get_block_height(it->second.bl));
|
||||
purge_altblock_keyimages_from_big_heap(it->second.bl, id);
|
||||
purge_alt_block_txs_hashs(it->second.bl);
|
||||
m_alternative_chains.erase(it);
|
||||
}
|
||||
|
|
@ -2114,7 +2114,7 @@ bool blockchain_storage::get_tx_rpc_details(const crypto::hash& h, tx_rpc_extend
|
|||
|
||||
if (tx_ptr && !timestamp)
|
||||
{
|
||||
timestamp = get_actual_timestamp(m_db_blocks[tx_ptr->m_keeper_block_height]->bl);
|
||||
timestamp = get_block_datetime(m_db_blocks[tx_ptr->m_keeper_block_height]->bl);
|
||||
}
|
||||
tei.keeper_block = static_cast<int64_t>(tx_ptr->m_keeper_block_height);
|
||||
fill_tx_rpc_details(tei, tx_ptr->tx, &(*tx_ptr), h, timestamp, is_short);
|
||||
|
|
@ -2203,11 +2203,11 @@ bool blockchain_storage::get_main_block_rpc_details(uint64_t i, block_rpc_extend
|
|||
crypto::hash coinbase_id = get_transaction_hash(core_bei_ptr->bl.miner_tx);
|
||||
//load transactions details
|
||||
bei.transactions_details.push_back(tx_rpc_extended_info());
|
||||
get_tx_rpc_details(coinbase_id, bei.transactions_details.back(), get_actual_timestamp(core_bei_ptr->bl), true);
|
||||
get_tx_rpc_details(coinbase_id, bei.transactions_details.back(), get_block_datetime(core_bei_ptr->bl), true);
|
||||
for (auto& h : core_bei_ptr->bl.tx_hashes)
|
||||
{
|
||||
bei.transactions_details.push_back(tx_rpc_extended_info());
|
||||
get_tx_rpc_details(h, bei.transactions_details.back(), get_actual_timestamp(core_bei_ptr->bl), true);
|
||||
get_tx_rpc_details(h, bei.transactions_details.back(), get_block_datetime(core_bei_ptr->bl), true);
|
||||
bei.total_fee += bei.transactions_details.back().fee;
|
||||
bei.total_txs_size += bei.transactions_details.back().blob_size;
|
||||
}
|
||||
|
|
@ -2288,13 +2288,13 @@ bool blockchain_storage::get_alt_block_rpc_details(const block_extended_info& be
|
|||
crypto::hash coinbase_id = get_transaction_hash(bei_core.bl.miner_tx);
|
||||
//load transactions details
|
||||
bei.transactions_details.push_back(tx_rpc_extended_info());
|
||||
fill_tx_rpc_details(bei.transactions_details.back(), bei_core.bl.miner_tx, nullptr, coinbase_id, get_actual_timestamp(bei_core.bl));
|
||||
fill_tx_rpc_details(bei.transactions_details.back(), bei_core.bl.miner_tx, nullptr, coinbase_id, get_block_datetime(bei_core.bl));
|
||||
|
||||
bei.total_fee = 0;
|
||||
for (auto& h : bei_core.bl.tx_hashes)
|
||||
{
|
||||
bei.transactions_details.push_back(tx_rpc_extended_info());
|
||||
if (!get_tx_rpc_details(h, bei.transactions_details.back(), get_actual_timestamp(bei_core.bl), true))
|
||||
if (!get_tx_rpc_details(h, bei.transactions_details.back(), get_block_datetime(bei_core.bl), true))
|
||||
{
|
||||
//tx not in blockchain, supposed to be in tx pool
|
||||
m_tx_pool.get_transaction_details(h, bei.transactions_details.back());
|
||||
|
|
@ -2407,8 +2407,8 @@ uint64_t blockchain_storage::get_seconds_between_last_n_block(size_t n) const
|
|||
if (m_db_blocks.size() <= n)
|
||||
return 0;
|
||||
|
||||
uint64_t top_block_ts = get_actual_timestamp(m_db_blocks[m_db_blocks.size() - 1]->bl);
|
||||
uint64_t n_block_ts = get_actual_timestamp(m_db_blocks[m_db_blocks.size() - 1 - n]->bl);
|
||||
uint64_t top_block_ts = get_block_datetime(m_db_blocks[m_db_blocks.size() - 1]->bl);
|
||||
uint64_t n_block_ts = get_block_datetime(m_db_blocks[m_db_blocks.size() - 1 - n]->bl);
|
||||
|
||||
return top_block_ts > n_block_ts ? top_block_ts - n_block_ts : 0;
|
||||
}
|
||||
|
|
@ -3816,12 +3816,14 @@ namespace currency
|
|||
const crypto::hash& m_tx_id;
|
||||
const crypto::hash& m_bl_id;
|
||||
const uint64_t m_bl_height;
|
||||
add_transaction_input_visitor(blockchain_storage& bcs, blockchain_storage::key_images_container& m_db_spent_keys, const crypto::hash& tx_id, const crypto::hash& bl_id, const uint64_t bl_height) :
|
||||
uint64_t &m_mixins_count;
|
||||
add_transaction_input_visitor(blockchain_storage& bcs, blockchain_storage::key_images_container& m_db_spent_keys, const crypto::hash& tx_id, const crypto::hash& bl_id, const uint64_t bl_height, uint64_t& mixins_count) :
|
||||
m_bcs(bcs),
|
||||
m_db_spent_keys(m_db_spent_keys),
|
||||
m_tx_id(tx_id),
|
||||
m_bl_id(bl_id),
|
||||
m_bl_height(bl_height)
|
||||
m_bl_height(bl_height),
|
||||
m_mixins_count(mixins_count)
|
||||
{}
|
||||
bool operator()(const txin_to_key& in) const
|
||||
{
|
||||
|
|
@ -3846,7 +3848,8 @@ namespace currency
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_mixins_count < in.key_offsets.size())
|
||||
m_mixins_count = in.key_offsets.size();
|
||||
return true;
|
||||
}
|
||||
bool operator()(const txin_htlc& in) const
|
||||
|
|
@ -3896,11 +3899,11 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const
|
|||
process_blockchain_tx_attachments(tx, bl_height, bl_id, timestamp);
|
||||
TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_process_attachment);
|
||||
|
||||
|
||||
uint64_t mixins_count = 0;
|
||||
TIME_MEASURE_START_PD(tx_process_inputs);
|
||||
for(const txin_v& in : tx.vin)
|
||||
{
|
||||
if(!boost::apply_visitor(add_transaction_input_visitor(*this, m_db_spent_keys, tx_id, bl_id, bl_height), in))
|
||||
if(!boost::apply_visitor(add_transaction_input_visitor(*this, m_db_spent_keys, tx_id, bl_id, bl_height, mixins_count), in))
|
||||
{
|
||||
LOG_ERROR("critical internal error: add_transaction_input_visitor failed. but key_images should be already checked");
|
||||
purge_transaction_keyimages_from_blockchain(tx, false);
|
||||
|
|
@ -3913,6 +3916,13 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const
|
|||
}
|
||||
}
|
||||
TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_process_inputs);
|
||||
if (need_to_profile && mixins_count > 0)
|
||||
{
|
||||
m_performance_data.tx_mixin_count.push(mixins_count);
|
||||
#ifdef _DEBUG
|
||||
LOG_PRINT_L0("[TX_MIXINS]: " << mixins_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
//check if there is already transaction with this hash
|
||||
TIME_MEASURE_START_PD(tx_check_exist);
|
||||
|
|
@ -4895,7 +4905,7 @@ void blockchain_storage::get_pos_mining_estimate(uint64_t amount_coins,
|
|||
auto bei = m_db_blocks[h];
|
||||
if (!is_pos_block(bei->bl))
|
||||
continue;
|
||||
uint64_t ts = get_actual_timestamp(bei->bl);
|
||||
uint64_t ts = get_block_datetime(bei->bl);
|
||||
pos_ts_min = min(pos_ts_min, ts);
|
||||
pos_ts_max = max(pos_ts_max, ts);
|
||||
pos_total_minted_money += get_reward_from_miner_tx(bei->bl.miner_tx);
|
||||
|
|
@ -5050,7 +5060,8 @@ bool blockchain_storage::validate_pos_block(const block& b,
|
|||
}
|
||||
|
||||
|
||||
//check actual time if it there
|
||||
// the following check is de-facto not applicable since 2021-10, but left intact to avoid consensus issues
|
||||
// PoS blocks don't use etc_tx_time anymore to store actual timestamp; instead, they use tx_service_attachment in mining tx extra
|
||||
uint64_t actual_ts = get_actual_timestamp(b);
|
||||
if ((actual_ts > b.timestamp && actual_ts - b.timestamp > POS_MAX_ACTUAL_TIMESTAMP_TO_MINED) ||
|
||||
(actual_ts < b.timestamp && b.timestamp - actual_ts > POS_MAX_ACTUAL_TIMESTAMP_TO_MINED)
|
||||
|
|
@ -5369,7 +5380,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
block_fees.reserve(bl.tx_hashes.size());
|
||||
//process transactions
|
||||
TIME_MEASURE_START_PD(all_txs_insert_time_5);
|
||||
if (!add_transaction_from_block(bl.miner_tx, get_transaction_hash(bl.miner_tx), id, get_current_blockchain_size(), get_actual_timestamp(bl)))
|
||||
if (!add_transaction_from_block(bl.miner_tx, get_transaction_hash(bl.miner_tx), id, get_current_blockchain_size(), get_block_datetime(bl)))
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id << " failed to add transaction to blockchain storage");
|
||||
bvc.m_verification_failed = true;
|
||||
|
|
@ -5444,7 +5455,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
|
||||
TIME_MEASURE_START_PD(tx_prapare_append);
|
||||
uint64_t current_bc_size = get_current_blockchain_size();
|
||||
uint64_t actual_timestamp = get_actual_timestamp(bl);
|
||||
uint64_t actual_timestamp = get_block_datetime(bl);
|
||||
TIME_MEASURE_FINISH_PD(tx_prapare_append);
|
||||
TIME_MEASURE_START_PD(tx_append_time);
|
||||
if(!add_transaction_from_block(tx, tx_id, id, current_bc_size, actual_timestamp))
|
||||
|
|
@ -5612,7 +5623,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
stringstream powpos_str_entry, timestamp_str_entry;
|
||||
if (is_pos_bl)
|
||||
{ // PoS
|
||||
int64_t actual_ts = get_actual_timestamp(bei.bl); // signed int is intentionally used here
|
||||
int64_t actual_ts = get_block_datetime(bei.bl); // signed int is intentionally used here
|
||||
int64_t ts_diff = actual_ts - m_core_runtime_config.get_core_time();
|
||||
powpos_str_entry << "PoS:\t" << proof_hash << ", stake amount: " << print_money_brief(pos_coinstake_amount) << ", final_difficulty: " << this_coin_diff;
|
||||
timestamp_str_entry << ", actual ts: " << actual_ts << " (diff: " << std::showpos << ts_diff << "s) block ts: " << std::noshowpos << bei.bl.timestamp << " (shift: " << std::showpos << static_cast<int64_t>(bei.bl.timestamp) - actual_ts << ")";
|
||||
|
|
|
|||
|
|
@ -73,33 +73,35 @@ namespace currency
|
|||
epee::math_helper::average<uint64_t, 5> target_calculating_calc;
|
||||
|
||||
//tx processing zone
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_time;
|
||||
epee::math_helper::average<uint64_t, 5> tx_add_one_tx_time;
|
||||
epee::math_helper::average<uint64_t, 5> tx_process_extra;
|
||||
epee::math_helper::average<uint64_t, 5> tx_process_attachment;
|
||||
epee::math_helper::average<uint64_t, 5> tx_process_inputs ;
|
||||
epee::math_helper::average<uint64_t, 5> tx_push_global_index;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_exist;
|
||||
epee::math_helper::average<uint64_t, 5> tx_print_log;
|
||||
epee::math_helper::average<uint64_t, 5> tx_prapare_append;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_time;
|
||||
epee::math_helper::average<uint64_t, 1> tx_add_one_tx_time;
|
||||
epee::math_helper::average<uint64_t, 1> tx_process_extra;
|
||||
epee::math_helper::average<uint64_t, 1> tx_process_attachment;
|
||||
epee::math_helper::average<uint64_t, 1> tx_process_inputs ;
|
||||
epee::math_helper::average<uint64_t, 1> tx_push_global_index;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_exist;
|
||||
epee::math_helper::average<uint64_t, 1> tx_print_log;
|
||||
epee::math_helper::average<uint64_t, 1> tx_prapare_append;
|
||||
|
||||
epee::math_helper::average<uint64_t, 5> tx_append_time;
|
||||
epee::math_helper::average<uint64_t, 5> tx_append_rl_wait;
|
||||
epee::math_helper::average<uint64_t, 5> tx_append_is_expired;
|
||||
epee::math_helper::average<uint64_t, 1> tx_append_time;
|
||||
epee::math_helper::average<uint64_t, 1> tx_append_rl_wait;
|
||||
epee::math_helper::average<uint64_t, 1> tx_append_is_expired;
|
||||
|
||||
epee::math_helper::average<uint64_t, 5> tx_store_db;
|
||||
epee::math_helper::average<uint64_t, 1> tx_store_db;
|
||||
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_prefix_hash;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_attachment_check;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_kimage_check;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_ch_in_val_sig;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_get_item_size;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_relative_to_absolute;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_loop;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_loop_get_subitem;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_loop_find_tx;
|
||||
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_loop_handle_output;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_prefix_hash;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_attachment_check;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_kimage_check;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_ch_in_val_sig;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_get_item_size;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_relative_to_absolute;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_loop;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_loop_get_subitem;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_loop_find_tx;
|
||||
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_loop_handle_output;
|
||||
|
||||
epee::math_helper::average<uint64_t, 1> tx_mixin_count;
|
||||
|
||||
|
||||
//TODO: move this to suitable place or remove it all
|
||||
|
|
@ -394,7 +396,7 @@ namespace currency
|
|||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(*block_ind_ptr < m_db_blocks.size(), false, "Internal error: bl_id=" << string_tools::pod_to_hex(bl_id)
|
||||
<< " have index record with offset=" << *block_ind_ptr << ", bigger then m_blocks.size()=" << m_db_blocks.size());
|
||||
<< " have index record with offset=" << *block_ind_ptr << ", bigger then m_db_blocks.size()=" << m_db_blocks.size());
|
||||
blocks.push_back(m_db_blocks[*block_ind_ptr]->bl);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,11 +36,11 @@ namespace currency
|
|||
if(height > blockchain_last_block_height)
|
||||
return false;
|
||||
|
||||
auto it = m_points.lower_bound(height);
|
||||
auto it = m_points.lower_bound(height); // if found, it->first >= height
|
||||
if(it == m_points.end())
|
||||
return false;
|
||||
if(it->first <= blockchain_last_block_height)
|
||||
return true;
|
||||
return true; // this is the case only if height <= it->first <= blockchain_last_block_height
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
@ -68,4 +68,27 @@ namespace currency
|
|||
return false;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
uint64_t checkpoints::get_checkpoint_before_height(uint64_t height) const
|
||||
{
|
||||
// returns height of the leftmost CP with height that is LESS than the given height
|
||||
// ex:
|
||||
// If there are two CP at 11 and 15:
|
||||
// get_checkpoint_before_height(10) = 0
|
||||
// get_checkpoint_before_height(11) = 0
|
||||
// get_checkpoint_before_height(12) = 11
|
||||
// get_checkpoint_before_height(13) = 11
|
||||
// get_checkpoint_before_height(14) = 11
|
||||
// get_checkpoint_before_height(15) = 11
|
||||
// get_checkpoint_before_height(16) = 15
|
||||
|
||||
uint64_t top_cp = get_top_checkpoint_height();
|
||||
if (height > top_cp)
|
||||
return top_cp;
|
||||
|
||||
auto it = m_points.lower_bound(height); // if found, it->first >= height
|
||||
if (it == m_points.end() || it == m_points.begin())
|
||||
return 0;
|
||||
return (--it)->first;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ namespace currency
|
|||
bool is_height_passed_zone(uint64_t height, uint64_t blockchain_last_block_height) const;
|
||||
bool check_block(uint64_t height, const crypto::hash& h) const;
|
||||
uint64_t get_top_checkpoint_height() const;
|
||||
|
||||
uint64_t get_checkpoint_before_height(uint64_t height) const;
|
||||
private:
|
||||
std::map<uint64_t, crypto::hash> m_points;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -17,13 +17,14 @@ namespace currency
|
|||
inline bool create_checkpoints(currency::checkpoints& checkpoints)
|
||||
{
|
||||
#ifdef TESTNET
|
||||
//ADD_CHECKPOINT(50000, "492ef71f5d722a8a182d65eb0ff731b740e023a2d64881f43db9af7b39ba7988");
|
||||
|
||||
#else
|
||||
// MAINNET
|
||||
ADD_CHECKPOINT(425000, "46a6c36d5dec2d484d5e4845a8525ca322aafc06915ed9c8da2a241b51b7d1e8");
|
||||
ADD_CHECKPOINT(525000, "8c1ac57e67448130207a224b2d6e33ccdc64d6dd1c59dbcf9ad2361dc0d07d51");
|
||||
ADD_CHECKPOINT(600000, "d9fe316086e1aaea07d94082973ec764eff5fc5a05ed6e1eca273cee59daeeb4");
|
||||
ADD_CHECKPOINT(900000, "2205b73cd79d4937b087b02a8b001171b73c34464bc4a952834eaf7c2bd63e86");
|
||||
ADD_CHECKPOINT(1161000, "96990d851b484e30190678756ba2a4d3a2f92b987e2470728ac1e38b2bf35908");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -383,11 +383,25 @@ namespace currency
|
|||
FIELD(security)
|
||||
FIELD(flags)
|
||||
END_SERIALIZE()
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(service_id)
|
||||
KV_SERIALIZE(instruction)
|
||||
KV_SERIALIZE_BLOB_AS_HEX_STRING(body)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(security)
|
||||
KV_SERIALIZE(flags)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
// applicable flags for tx_service_attachment::flags, can be combined using bitwise OR
|
||||
#define TX_SERVICE_ATTACHMENT_ENCRYPT_BODY static_cast<uint8_t>(1 << 0)
|
||||
#define TX_SERVICE_ATTACHMENT_DEFLATE_BODY static_cast<uint8_t>(1 << 1)
|
||||
|
||||
// with this flag enabled body encrypted/decrypted with the key created as a derivation from onetime key and "spend keys" of receiver
|
||||
#define TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE static_cast<uint8_t>(1 << 2)
|
||||
// add proof of content, without revealing secrete
|
||||
#define TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF static_cast<uint8_t>(1 << 3)
|
||||
|
||||
//,
|
||||
|
||||
|
||||
|
|
@ -690,6 +704,7 @@ namespace currency
|
|||
return k;
|
||||
}
|
||||
};
|
||||
const static keypair null_keypair = AUTO_VAL_INIT(null_keypair);
|
||||
//---------------------------------------------------------------
|
||||
//PoS
|
||||
//based from ppcoin/novacoin approach
|
||||
|
|
|
|||
|
|
@ -148,7 +148,9 @@
|
|||
|
||||
#define WALLET_FILE_SIGNATURE_OLD 0x1111012101101011LL // Bender's nightmare
|
||||
#define WALLET_FILE_SIGNATURE_V2 0x1111011201101011LL // another Bender's nightmare
|
||||
#define WALLET_FILE_BINARY_HEADER_VERSION 1001
|
||||
#define WALLET_FILE_BINARY_HEADER_VERSION_INITAL 1000
|
||||
#define WALLET_FILE_BINARY_HEADER_VERSION_2 1001
|
||||
//#define WALLET_FILE_BINARY_HEADER_VERSION_3 1002
|
||||
|
||||
#define WALLET_FILE_MAX_KEYS_SIZE 10000 //
|
||||
#define WALLET_BRAIN_DATE_OFFSET 1543622400
|
||||
|
|
@ -209,7 +211,7 @@
|
|||
#define MINER_CONFIG_FILENAME "miner_conf.json"
|
||||
#define GUI_SECURE_CONFIG_FILENAME "gui_secure_conf.bin"
|
||||
#define GUI_CONFIG_FILENAME "gui_settings.json"
|
||||
#define GUI_INTERNAL_CONFIG "gui_internal_config.bin"
|
||||
#define GUI_INTERNAL_CONFIG2 "gui_internal_config.json"
|
||||
|
||||
|
||||
|
||||
|
|
@ -223,9 +225,11 @@
|
|||
#define BC_OFFERS_CURRENT_OFFERS_SERVICE_ARCHIVE_VER CURRENCY_FORMATION_VERSION + BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION + 9
|
||||
#define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin"
|
||||
|
||||
|
||||
#ifndef TESTNET
|
||||
#define WALLET_FILE_SERIALIZATION_VERSION 153
|
||||
#else
|
||||
#define WALLET_FILE_SERIALIZATION_VERSION (CURRENCY_FORMATION_VERSION+69)
|
||||
|
||||
#endif
|
||||
|
||||
#define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31)
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ using namespace epee;
|
|||
#include "bc_payments_id_service.h"
|
||||
#include "bc_escrow_service.h"
|
||||
#include "bc_attachments_helpers.h"
|
||||
#include "bc_block_datetime_service.h"
|
||||
#include "genesis.h"
|
||||
#include "genesis_acc.h"
|
||||
#include "common/mnemonic-encoding.h"
|
||||
|
|
@ -64,11 +65,6 @@ namespace currency
|
|||
pos_entry());
|
||||
}*/
|
||||
//---------------------------------------------------------------
|
||||
uint64_t get_coinday_weight(uint64_t amount)
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
wide_difficulty_type correct_difficulty_with_sequence_factor(size_t sequence_factor, wide_difficulty_type diff)
|
||||
{
|
||||
//delta=delta*(0.75^n)
|
||||
|
|
@ -594,12 +590,12 @@ namespace currency
|
|||
std::string generate_origin_for_htlc(const txout_htlc& htlc, const account_keys& acc_keys)
|
||||
{
|
||||
std::string blob;
|
||||
string_tools::apped_pod_to_strbuff(blob, htlc.pkey_redeem);
|
||||
string_tools::apped_pod_to_strbuff(blob, htlc.pkey_refund);
|
||||
string_tools::apped_pod_to_strbuff(blob, acc_keys.spend_secret_key);
|
||||
string_tools::append_pod_to_strbuff(blob, htlc.pkey_redeem);
|
||||
string_tools::append_pod_to_strbuff(blob, htlc.pkey_refund);
|
||||
string_tools::append_pod_to_strbuff(blob, acc_keys.spend_secret_key);
|
||||
crypto::hash origin_hs = crypto::cn_fast_hash(blob.data(), blob.size());
|
||||
std::string origin_blob;
|
||||
string_tools::apped_pod_to_strbuff(origin_blob, origin_hs);
|
||||
string_tools::append_pod_to_strbuff(origin_blob, origin_hs);
|
||||
return origin_blob;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
|
@ -759,8 +755,12 @@ namespace currency
|
|||
struct encrypt_attach_visitor : public boost::static_visitor<void>
|
||||
{
|
||||
bool& m_was_crypted_entries;
|
||||
const keypair& m_onetime_keypair;
|
||||
const account_public_address& m_destination_addr;
|
||||
const crypto::key_derivation& m_key;
|
||||
encrypt_attach_visitor(bool& was_crypted_entries, const crypto::key_derivation& key) :m_was_crypted_entries(was_crypted_entries), m_key(key)
|
||||
|
||||
encrypt_attach_visitor(bool& was_crypted_entries, const crypto::key_derivation& key, const keypair& onetime_keypair = null_keypair, const account_public_address& destination_addr = null_pub_addr) :
|
||||
m_was_crypted_entries(was_crypted_entries), m_key(key), m_onetime_keypair(onetime_keypair), m_destination_addr(destination_addr)
|
||||
{}
|
||||
void operator()(tx_comment& comment)
|
||||
{
|
||||
|
|
@ -789,6 +789,7 @@ namespace currency
|
|||
}
|
||||
void operator()(tx_service_attachment& sa)
|
||||
{
|
||||
const std::string original_body = sa.body;
|
||||
if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY)
|
||||
{
|
||||
zlib_helper::pack(sa.body);
|
||||
|
|
@ -796,7 +797,28 @@ namespace currency
|
|||
|
||||
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY)
|
||||
{
|
||||
crypto::chacha_crypt(sa.body, m_key);
|
||||
crypto::key_derivation derivation_local = m_key;
|
||||
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(m_destination_addr.spend_public_key != currency::null_pkey && m_onetime_keypair.sec != currency::null_skey, "tx_service_attachment with TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE: keys uninitialized");
|
||||
//encrypt with "spend keys" only, to prevent auditable watchers decrypt it
|
||||
bool r = crypto::generate_key_derivation(m_destination_addr.spend_public_key, m_onetime_keypair.sec, derivation_local);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "tx_service_attachment with TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE: Failed to make derivation");
|
||||
crypto::chacha_crypt(sa.body, derivation_local);
|
||||
}
|
||||
else
|
||||
{
|
||||
crypto::chacha_crypt(sa.body, derivation_local);
|
||||
}
|
||||
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF)
|
||||
{
|
||||
//take hash from derivation and use it as a salt
|
||||
crypto::hash derivation_hash = crypto::cn_fast_hash(&derivation_local, sizeof(derivation_local));
|
||||
std::string salted_body = original_body;
|
||||
string_tools::append_pod_to_strbuff(salted_body, derivation_hash);
|
||||
crypto::hash proof_hash = crypto::cn_fast_hash(salted_body.data(), salted_body.size());
|
||||
sa.security.push_back(*(crypto::public_key*)&proof_hash);
|
||||
}
|
||||
m_was_crypted_entries = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -808,12 +830,18 @@ namespace currency
|
|||
|
||||
struct decrypt_attach_visitor : public boost::static_visitor<void>
|
||||
{
|
||||
const account_keys& m_acc_keys;
|
||||
const crypto::public_key& m_tx_onetime_pubkey;
|
||||
const crypto::key_derivation& rkey;
|
||||
std::vector<payload_items_v>& rdecrypted_att;
|
||||
decrypt_attach_visitor(const crypto::key_derivation& key,
|
||||
std::vector<payload_items_v>& decrypted_att) :
|
||||
std::vector<payload_items_v>& decrypted_att,
|
||||
const account_keys& acc_keys = null_acc_keys,
|
||||
const crypto::public_key& tx_onetime_pubkey = null_pkey) :
|
||||
rkey(key),
|
||||
rdecrypted_att(decrypted_att)
|
||||
rdecrypted_att(decrypted_att),
|
||||
m_acc_keys(acc_keys),
|
||||
m_tx_onetime_pubkey(tx_onetime_pubkey)
|
||||
{}
|
||||
void operator()(const tx_comment& comment)
|
||||
{
|
||||
|
|
@ -825,15 +853,44 @@ namespace currency
|
|||
void operator()(const tx_service_attachment& sa)
|
||||
{
|
||||
tx_service_attachment local_sa = sa;
|
||||
crypto::key_derivation derivation_local = rkey;
|
||||
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY)
|
||||
{
|
||||
crypto::chacha_crypt(local_sa.body, rkey);
|
||||
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE)
|
||||
{
|
||||
if (m_acc_keys.spend_secret_key == null_skey)
|
||||
{
|
||||
//this watch only wallet, decrypting supposed to be impossible
|
||||
return;
|
||||
}
|
||||
CHECK_AND_ASSERT_THROW_MES(m_acc_keys.spend_secret_key != currency::null_skey && m_tx_onetime_pubkey != currency::null_pkey, "tx_service_attachment with TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE: keys uninitialized");
|
||||
bool r = crypto::generate_key_derivation(m_tx_onetime_pubkey, m_acc_keys.spend_secret_key, derivation_local);
|
||||
CHECK_AND_ASSERT_THROW_MES(r, "Failed to generate_key_derivation at TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE");
|
||||
crypto::chacha_crypt(local_sa.body, derivation_local);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
crypto::chacha_crypt(local_sa.body, derivation_local);
|
||||
}
|
||||
}
|
||||
|
||||
if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY)
|
||||
{
|
||||
zlib_helper::unpack(local_sa.body);
|
||||
}
|
||||
|
||||
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY && sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(sa.security.size() == 1, void(), "Unexpected key in tx_service_attachment with TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE");
|
||||
//take hash from derivation and use it as a salt
|
||||
crypto::hash derivation_hash = crypto::cn_fast_hash(&derivation_local, sizeof(derivation_local));
|
||||
std::string salted_body = local_sa.body;
|
||||
string_tools::append_pod_to_strbuff(salted_body, derivation_hash);
|
||||
crypto::hash proof_hash = crypto::cn_fast_hash(salted_body.data(), salted_body.size()); // proof_hash = Hs(local_sa.body || Hs(s * R)), s - spend secret, R - tx pub
|
||||
CHECK_AND_ASSERT_MES(*(crypto::public_key*)&proof_hash == sa.security.front(), void(), "Proof hash missmatch on decrypting with TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF");
|
||||
}
|
||||
|
||||
rdecrypted_att.push_back(local_sa);
|
||||
}
|
||||
|
||||
|
|
@ -870,9 +927,10 @@ namespace currency
|
|||
|
||||
//---------------------------------------------------------------
|
||||
template<class items_container_t>
|
||||
bool decrypt_payload_items(const crypto::key_derivation& derivation, const items_container_t& items_to_decrypt, std::vector<payload_items_v>& decrypted_att)
|
||||
bool decrypt_payload_items(const crypto::key_derivation& derivation, const items_container_t& items_to_decrypt, std::vector<payload_items_v>& decrypted_att, const account_keys& acc_keys = null_acc_keys,
|
||||
const crypto::public_key& tx_onetime_pubkey = null_pkey)
|
||||
{
|
||||
decrypt_attach_visitor v(derivation, decrypted_att);
|
||||
decrypt_attach_visitor v(derivation, decrypted_att, acc_keys, tx_onetime_pubkey);
|
||||
for (auto& a : items_to_decrypt)
|
||||
boost::apply_visitor(v, a);
|
||||
|
||||
|
|
@ -955,8 +1013,8 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
|
||||
decrypt_payload_items(derivation, tx.extra, decrypted_items);
|
||||
decrypt_payload_items(derivation, tx.attachment, decrypted_items);
|
||||
decrypt_payload_items(derivation, tx.extra, decrypted_items, is_income ? acc_keys: account_keys(), get_tx_pub_key_from_extra(tx));
|
||||
decrypt_payload_items(derivation, tx.attachment, decrypted_items, is_income ? acc_keys : account_keys(), get_tx_pub_key_from_extra(tx));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -969,11 +1027,11 @@ namespace currency
|
|||
bool was_attachment_crypted_entries = false;
|
||||
bool was_extra_crypted_entries = false;
|
||||
|
||||
encrypt_attach_visitor v(was_attachment_crypted_entries, derivation);
|
||||
encrypt_attach_visitor v(was_attachment_crypted_entries, derivation, tx_random_key, destination_addr);
|
||||
for (auto& a : tx.attachment)
|
||||
boost::apply_visitor(v, a);
|
||||
|
||||
encrypt_attach_visitor v2(was_extra_crypted_entries, derivation);
|
||||
encrypt_attach_visitor v2(was_extra_crypted_entries, derivation, tx_random_key, destination_addr);
|
||||
for (auto& a : tx.extra)
|
||||
boost::apply_visitor(v2, a);
|
||||
|
||||
|
|
@ -994,26 +1052,26 @@ namespace currency
|
|||
}
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
void load_wallet_transfer_info_flags(tools::wallet_public::wallet_transfer_info& x)
|
||||
{
|
||||
x.is_service = currency::is_service_tx(x.tx);
|
||||
x.is_mixing = currency::does_tx_have_only_mixin_inputs(x.tx);
|
||||
x.is_mining = currency::is_coinbase(x.tx);
|
||||
if (!x.is_mining)
|
||||
x.fee = currency::get_tx_fee(x.tx);
|
||||
else
|
||||
x.fee = 0;
|
||||
x.show_sender = currency::is_showing_sender_addres(x.tx);
|
||||
tx_out htlc_out = AUTO_VAL_INIT(htlc_out);
|
||||
txin_htlc htlc_in = AUTO_VAL_INIT(htlc_in);
|
||||
// void load_wallet_transfer_info_flags(tools::wallet_public::wallet_transfer_info& x)
|
||||
// {
|
||||
// x.is_service = currency::is_service_tx(x.tx);
|
||||
// x.is_mixing = currency::does_tx_have_only_mixin_inputs(x.tx);
|
||||
// x.is_mining = currency::is_coinbase(x.tx);
|
||||
// if (!x.is_mining)
|
||||
// x.fee = currency::get_tx_fee(x.tx);
|
||||
// else
|
||||
// x.fee = 0;
|
||||
// x.show_sender = currency::is_showing_sender_addres(x.tx);
|
||||
// tx_out htlc_out = AUTO_VAL_INIT(htlc_out);
|
||||
// txin_htlc htlc_in = AUTO_VAL_INIT(htlc_in);
|
||||
|
||||
x.tx_type = get_tx_type_ex(x.tx, htlc_out, htlc_in);
|
||||
if(x.tx_type == GUI_TX_TYPE_HTLC_DEPOSIT && x.is_income == true)
|
||||
{
|
||||
//need to override amount
|
||||
x.amount = htlc_out.amount;
|
||||
}
|
||||
}
|
||||
// x.tx_type = get_tx_type_ex(x.tx, htlc_out, htlc_in);
|
||||
// if(x.tx_type == GUI_TX_TYPE_HTLC_DEPOSIT && x.is_income == true)
|
||||
// {
|
||||
// //need to override amount
|
||||
// x.amount = htlc_out.amount;
|
||||
// }
|
||||
// }
|
||||
|
||||
//---------------------------------------------------------------
|
||||
uint64_t get_tx_type_ex(const transaction& tx, tx_out& htlc_out, txin_htlc& htlc_in)
|
||||
|
|
@ -2000,8 +2058,8 @@ namespace currency
|
|||
crypto::hash hash_together(const pod_operand_a& a, const pod_operand_b& b)
|
||||
{
|
||||
std::string blob;
|
||||
string_tools::apped_pod_to_strbuff(blob, a);
|
||||
string_tools::apped_pod_to_strbuff(blob, b);
|
||||
string_tools::append_pod_to_strbuff(blob, a);
|
||||
string_tools::append_pod_to_strbuff(blob, b);
|
||||
return crypto::cn_fast_hash(blob.data(), blob.size());
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
|
@ -2051,6 +2109,8 @@ namespace currency
|
|||
return median_fee * 10;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// NOTE: this function is obsolete and depricated
|
||||
// PoS block real timestamp is set using a service attachment in mining tx extra since 2021-10
|
||||
uint64_t get_actual_timestamp(const block& b)
|
||||
{
|
||||
uint64_t tes_ts = b.timestamp;
|
||||
|
|
@ -2062,6 +2122,41 @@ namespace currency
|
|||
}
|
||||
return tes_ts;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
// returns timestamp from BC_BLOCK_DATETIME_SERVICE_ID via tx_service_attachment in extra
|
||||
// fallbacks to old-style actual timestamp via etc_tx_time, then to block timestamp
|
||||
uint64_t get_block_datetime(const block& b)
|
||||
{
|
||||
// first try BC_BLOCK_DATETIME_SERVICE_ID
|
||||
tx_service_attachment sa = AUTO_VAL_INIT(sa);
|
||||
if (get_type_in_variant_container(b.miner_tx.extra, sa))
|
||||
{
|
||||
if (sa.service_id == BC_BLOCK_DATETIME_SERVICE_ID && sa.instruction == BC_BLOCK_DATETIME_INSTRUCTION_DEFAULT)
|
||||
{
|
||||
uint64_t ts;
|
||||
if (epee::string_tools::get_pod_from_strbuff(sa.body, ts))
|
||||
return ts;
|
||||
}
|
||||
}
|
||||
|
||||
// next try etc_tx_time
|
||||
etc_tx_time t = AUTO_VAL_INIT(t);
|
||||
if (get_type_in_variant_container(b.miner_tx.extra, t))
|
||||
return t.v;
|
||||
|
||||
// otherwise return default: block.ts
|
||||
return b.timestamp;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
void set_block_datetime(uint64_t datetime, block& b)
|
||||
{
|
||||
tx_service_attachment sa = AUTO_VAL_INIT(sa);
|
||||
sa.service_id = BC_BLOCK_DATETIME_SERVICE_ID;
|
||||
sa.instruction = BC_BLOCK_DATETIME_INSTRUCTION_DEFAULT;
|
||||
sa.flags = 0;
|
||||
epee::string_tools::append_pod_to_strbuff(sa.body, datetime);
|
||||
b.miner_tx.extra.push_back(sa);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool validate_alias_name(const std::string& al)
|
||||
{
|
||||
|
|
@ -2720,7 +2815,7 @@ namespace currency
|
|||
pei_rpc.timestamp = bei_chain.bl.timestamp;
|
||||
pei_rpc.id = epee::string_tools::pod_to_hex(h);
|
||||
pei_rpc.prev_id = epee::string_tools::pod_to_hex(bei_chain.bl.prev_id);
|
||||
pei_rpc.actual_timestamp = get_actual_timestamp(bei_chain.bl);
|
||||
pei_rpc.actual_timestamp = get_block_datetime(bei_chain.bl);
|
||||
pei_rpc.type = is_pos_block(bei_chain.bl) ? 0 : 1;
|
||||
pei_rpc.already_generated_coins = boost::lexical_cast<std::string>(bei_chain.already_generated_coins);
|
||||
pei_rpc.this_block_fee_median = bei_chain.this_block_tx_fee_median;
|
||||
|
|
@ -2888,6 +2983,13 @@ namespace currency
|
|||
return tools::base58::encode_addr(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr)); // new format Zano address (normal)
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
bool is_address_like_wrapped(const std::string& addr)
|
||||
{
|
||||
if (addr.length() == 42 && addr.substr(0, 2) == "0x")
|
||||
return true;
|
||||
else return false;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
std::string get_account_address_and_payment_id_as_str(const account_public_address& addr, const payment_id_t& payment_id)
|
||||
{
|
||||
if (addr.flags == 0)
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
#include "currency_format_utils_blocks.h"
|
||||
#include "currency_format_utils_transactions.h"
|
||||
#include "core_runtime_config.h"
|
||||
#include "wallet/wallet_public_structs_defs.h"
|
||||
// #include "wallet/wallet_public_structs_defs.h"
|
||||
|
||||
|
||||
// ------ get_tx_type_definition -------------
|
||||
|
|
@ -289,7 +289,8 @@ namespace currency
|
|||
bool decrypt_payload_items(bool is_income, const transaction& tx, const account_keys& acc_keys, std::vector<payload_items_v>& decrypted_items);
|
||||
void encrypt_attachments(transaction& tx, const account_keys& sender_keys, const account_public_address& destination_addr, const keypair& tx_random_key);
|
||||
bool is_derivation_used_to_encrypt(const transaction& tx, const crypto::key_derivation& derivation);
|
||||
void load_wallet_transfer_info_flags(tools::wallet_public::wallet_transfer_info& x);
|
||||
bool is_address_like_wrapped(const std::string& addr);
|
||||
// void load_wallet_transfer_info_flags(tools::wallet_public::wallet_transfer_info& x);
|
||||
uint64_t get_tx_type(const transaction& tx);
|
||||
uint64_t get_tx_type_ex(const transaction& tx, tx_out& htlc_out, txin_htlc& htlc_in);
|
||||
size_t get_multisig_out_index(const std::vector<tx_out>& outs);
|
||||
|
|
@ -328,7 +329,9 @@ namespace currency
|
|||
|
||||
// prints amount in format "3.14", "0.0"
|
||||
std::string print_money_brief(uint64_t amount);
|
||||
uint64_t get_actual_timestamp(const block& b);
|
||||
uint64_t get_actual_timestamp(const block& b); // obsolete and depricated, use get_block_datetime
|
||||
uint64_t get_block_datetime(const block& b);
|
||||
void set_block_datetime(uint64_t datetime, block& b);
|
||||
|
||||
bool addendum_to_hexstr(const std::vector<crypto::hash>& add, std::string& hex_buff);
|
||||
bool hexstr_to_addendum(const std::string& hex_buff, std::vector<crypto::hash>& add);
|
||||
|
|
@ -345,7 +348,6 @@ namespace currency
|
|||
//PoS
|
||||
bool is_pos_block(const block& b);
|
||||
bool is_pos_block(const transaction& tx);
|
||||
uint64_t get_coinday_weight(uint64_t amount);
|
||||
wide_difficulty_type correct_difficulty_with_sequence_factor(size_t sequence_factor, wide_difficulty_type diff);
|
||||
void print_currency_details();
|
||||
std::string print_reward_change_first_blocks(size_t n_of_first_blocks);
|
||||
|
|
|
|||
|
|
@ -97,8 +97,8 @@ namespace bc_services
|
|||
inline currency::blobdata make_offer_sig_blob(const update_offer& uo)
|
||||
{
|
||||
currency::blobdata bd;
|
||||
epee::string_tools::apped_pod_to_strbuff(bd, uo.tx_id);
|
||||
epee::string_tools::apped_pod_to_strbuff(bd, uo.offer_index);
|
||||
epee::string_tools::append_pod_to_strbuff(bd, uo.tx_id);
|
||||
epee::string_tools::append_pod_to_strbuff(bd, uo.offer_index);
|
||||
bd += epee::serialization::store_t_to_binary(uo.of);
|
||||
return bd;
|
||||
}
|
||||
|
|
@ -106,8 +106,8 @@ namespace bc_services
|
|||
inline currency::blobdata make_offer_sig_blob(const cancel_offer& co)
|
||||
{
|
||||
currency::blobdata bd;
|
||||
epee::string_tools::apped_pod_to_strbuff(bd, co.tx_id);
|
||||
epee::string_tools::apped_pod_to_strbuff(bd, co.offer_index);
|
||||
epee::string_tools::append_pod_to_strbuff(bd, co.tx_id);
|
||||
epee::string_tools::append_pod_to_strbuff(bd, co.offer_index);
|
||||
return bd;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -914,7 +914,8 @@ namespace currency
|
|||
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_CHAIN_ENTRY, with \r\nm_total_height=" << arg.total_height
|
||||
<< "\r\nm_start_height=" << arg.start_height
|
||||
<< "\r\nm_block_ids.size()=" << arg.m_block_ids.size());
|
||||
//m_p2p->drop_connection(context);
|
||||
m_p2p->drop_connection(context);
|
||||
m_p2p->add_ip_fail(context.m_remote_ip);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(auto& bl_details, arg.m_block_ids)
|
||||
|
|
|
|||
95
src/main.cc
95
src/main.cc
|
|
@ -38,14 +38,21 @@ blobdata uint64be_to_blob(uint64_t num) {
|
|||
return res;
|
||||
}
|
||||
|
||||
const size_t MM_NONCE_SIZE = 1 + 2 + sizeof(crypto::hash);
|
||||
|
||||
NAN_METHOD(get_merged_mining_nonce_size) {
|
||||
Local<Integer> returnValue = Nan::New(static_cast<uint32_t>(MM_NONCE_SIZE));
|
||||
info.GetReturnValue().Set(returnValue);
|
||||
}
|
||||
|
||||
NAN_METHOD(convert_blob) {
|
||||
|
||||
if (info.Length() < 1)
|
||||
return THROW_ERROR_EXCEPTION("You must provide one argument.");
|
||||
|
||||
Local<Object> target = info[0]->ToObject();
|
||||
//Local<Object> target = info[0]->ToObject();
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
Local<Object> target = info[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
if (!Buffer::HasInstance(target))
|
||||
return THROW_ERROR_EXCEPTION("Argument should be a buffer object.");
|
||||
|
|
@ -72,7 +79,9 @@ void address_decode(const Nan::FunctionCallbackInfo<v8::Value>& info) {
|
|||
if (info.Length() < 1)
|
||||
return THROW_ERROR_EXCEPTION("You must provide one argument.");
|
||||
|
||||
Local<Object> target = info[0]->ToObject();
|
||||
//Local<Object> target = info[0]->ToObject();
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
Local<Object> target = info[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
if (!Buffer::HasInstance(target))
|
||||
return THROW_ERROR_EXCEPTION("Argument should be a buffer object.");
|
||||
|
|
@ -89,7 +98,7 @@ void address_decode(const Nan::FunctionCallbackInfo<v8::Value>& info) {
|
|||
|
||||
|
||||
account_public_address adr;
|
||||
if (!::serialization::parse_binary(data, adr) || !crypto::check_key(adr.m_spend_public_key) || !crypto::check_key(adr.m_view_public_key))
|
||||
if (!::serialization::parse_binary(data, adr) || !crypto::check_key(adr.spend_public_key) || !crypto::check_key(adr.view_public_key))
|
||||
{
|
||||
if(data.length())
|
||||
{
|
||||
|
|
@ -111,24 +120,26 @@ void address_decode(const Nan::FunctionCallbackInfo<v8::Value>& info) {
|
|||
}
|
||||
}
|
||||
|
||||
#define SET_BUFFER_RETURN(x, len) \
|
||||
v8::Isolate* isolate = args.GetIsolate(); \
|
||||
args.GetReturnValue().Set(Buffer::Copy(isolate, x, len).ToLocalChecked());
|
||||
|
||||
/*
|
||||
Arguments:
|
||||
1: block_header_hash - 32-byte buffer
|
||||
2: nonce - 8-byte buffer
|
||||
2: height - 8-byte buffer
|
||||
*/
|
||||
void get_pow_hash(const Nan::FunctionCallbackInfo<v8::Value>& args) {
|
||||
void get_pow_hash(const Nan::FunctionCallbackInfo<v8::Value>& info) {
|
||||
|
||||
if (args.Length() < 3)
|
||||
if (info.Length() < 3)
|
||||
return THROW_ERROR_EXCEPTION("You must provide 3 arguments.");
|
||||
|
||||
Local<Object> block_header_hash = args[0]->ToObject();
|
||||
Local<Object> nonce = args[1]->ToObject();
|
||||
Local<Object> height = args[2]->ToObject();
|
||||
//Local<Object> block_header_hash = args[0]->ToObject();
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
Local<Object> block_header_hash = info[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
//Local<Object> nonce = args[1]->ToObject();
|
||||
Local<Object> nonce = info[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
//Local<Object> height = args[2]->ToObject();
|
||||
Local<Object> height = info[2]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
if(!Buffer::HasInstance(block_header_hash))
|
||||
return THROW_ERROR_EXCEPTION("Argument 1 should be a buffer object.");
|
||||
|
|
@ -159,7 +170,10 @@ void get_pow_hash(const Nan::FunctionCallbackInfo<v8::Value>& args) {
|
|||
|
||||
crypto::hash h = currency::get_block_longhash(height_val, block_header_hash_val, nonce_val);
|
||||
|
||||
SET_BUFFER_RETURN((const char*)&h, 32);
|
||||
//SET_BUFFER_RETURN((const char*)&h, 32);
|
||||
char *cstr = reinterpret_cast<char*>(&h);
|
||||
v8::Local<v8::Value> returnValue = Nan::CopyBuffer(cstr, 32).ToLocalChecked();
|
||||
info.GetReturnValue().Set(returnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -167,13 +181,17 @@ Arguments:
|
|||
1: block_template_buffer - n-byte buffer
|
||||
2: extra_data - n-byte buffer(job identification)
|
||||
*/
|
||||
void get_hash_from_block_template_with_extra(const Nan::FunctionCallbackInfo<v8::Value>& args) {
|
||||
void get_hash_from_block_template_with_extra(const Nan::FunctionCallbackInfo<v8::Value>& info) {
|
||||
|
||||
if (args.Length() < 2)
|
||||
if (info.Length() < 2)
|
||||
return THROW_ERROR_EXCEPTION("You must provide 2 arguments.");
|
||||
|
||||
Local<Object> block_template_buffer = args[0]->ToObject();
|
||||
Local<Object> extra_data = args[1]->ToObject();
|
||||
//Local<Object> block_template_buffer = args[0]->ToObject();
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
Local<Object> block_template_buffer = info[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
//Local<Object> extra_data = args[1]->ToObject();
|
||||
Local<Object> extra_data = info[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
|
||||
if (!Buffer::HasInstance(block_template_buffer))
|
||||
|
|
@ -201,7 +219,10 @@ void get_hash_from_block_template_with_extra(const Nan::FunctionCallbackInfo<v8:
|
|||
|
||||
crypto::hash h = currency::get_block_header_mining_hash(b);
|
||||
|
||||
SET_BUFFER_RETURN((const char*)&h, 32);
|
||||
//SET_BUFFER_RETURN((const char*)&h, 32);
|
||||
char *cstr = reinterpret_cast<char*>(&h);
|
||||
v8::Local<v8::Value> returnValue = Nan::CopyBuffer(cstr, 32).ToLocalChecked();
|
||||
info.GetReturnValue().Set(returnValue);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -210,14 +231,20 @@ Arguments:
|
|||
2: extra_data - n-byte buffer(job identification)
|
||||
3: nonce - 8-byte buffer - nonce
|
||||
*/
|
||||
void get_blob_from_block_template(const Nan::FunctionCallbackInfo<v8::Value>& args) {
|
||||
void get_blob_from_block_template(const Nan::FunctionCallbackInfo<v8::Value>& info) {
|
||||
|
||||
if (args.Length() < 3)
|
||||
if (info.Length() < 3)
|
||||
return THROW_ERROR_EXCEPTION("You must provide 3 arguments.");
|
||||
|
||||
Local<Object> block_template_buffer = args[0]->ToObject();
|
||||
Local<Object> extra_data = args[1]->ToObject();
|
||||
Local<Object> nonce = args[2]->ToObject();
|
||||
//Local<Object> block_template_buffer = args[0]->ToObject();
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
Local<Object> block_template_buffer = info[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
//Local<Object> extra_data = args[1]->ToObject();
|
||||
Local<Object> extra_data = info[1]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
//Local<Object> nonce = args[2]->ToObject();
|
||||
Local<Object> nonce = info[2]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
|
||||
if (!Buffer::HasInstance(block_template_buffer))
|
||||
|
|
@ -258,17 +285,19 @@ void get_blob_from_block_template(const Nan::FunctionCallbackInfo<v8::Value>& ar
|
|||
|
||||
crypto::hash h = currency::get_block_hash(b);
|
||||
|
||||
SET_BUFFER_RETURN(result_blob.data(), result_blob.size());
|
||||
//SET_BUFFER_RETURN(result_blob.data(), result_blob.size());
|
||||
v8::Local<v8::Value> returnValue = Nan::CopyBuffer((char*)result_blob.data(), result_blob.size()).ToLocalChecked();
|
||||
info.GetReturnValue().Set(returnValue);
|
||||
}
|
||||
|
||||
|
||||
void get_id_hash(const Nan::FunctionCallbackInfo<v8::Value>& args) {
|
||||
void get_id_hash(const Nan::FunctionCallbackInfo<v8::Value>& info) {
|
||||
|
||||
if (args.Length() < 1)
|
||||
if (info.Length() < 1)
|
||||
return THROW_ERROR_EXCEPTION("You must provide 2 arguments.");
|
||||
|
||||
Local<Object> block_buffer = args[0]->ToObject();
|
||||
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
Local<Object> block_buffer = info[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
if (!Buffer::HasInstance(block_buffer))
|
||||
return THROW_ERROR_EXCEPTION("Argument 1 should be a buffer object.");
|
||||
|
|
@ -285,7 +314,10 @@ void get_id_hash(const Nan::FunctionCallbackInfo<v8::Value>& args) {
|
|||
|
||||
crypto::hash h = currency::get_block_hash(b);
|
||||
|
||||
SET_BUFFER_RETURN((const char*)&h, 32);
|
||||
//SET_BUFFER_RETURN((const char*)&h, 32);
|
||||
char *cstr = reinterpret_cast<char*>(&h);
|
||||
v8::Local<v8::Value> returnValue = Nan::CopyBuffer(cstr, 32).ToLocalChecked();
|
||||
info.GetReturnValue().Set(returnValue);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -295,7 +327,9 @@ void is_address_valid(const Nan::FunctionCallbackInfo<v8::Value>& info)
|
|||
|
||||
if (info.Length() < 1)
|
||||
return THROW_ERROR_EXCEPTION("You must provide one argument.");
|
||||
Local<Object> target = info[0]->ToObject();
|
||||
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
Local<Object> target = info[0]->ToObject(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
|
||||
if (!Buffer::HasInstance(target))
|
||||
return THROW_ERROR_EXCEPTION("Argument should be a buffer object.");
|
||||
|
|
@ -324,6 +358,7 @@ NAN_MODULE_INIT(init) {
|
|||
Nan::Set(target, Nan::New("get_blob_from_block_template").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(get_blob_from_block_template)).ToLocalChecked());
|
||||
Nan::Set(target, Nan::New("get_id_hash").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(get_id_hash)).ToLocalChecked());
|
||||
Nan::Set(target, Nan::New("is_address_valid").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(is_address_valid)).ToLocalChecked());
|
||||
Nan::Set(target, Nan::New("get_merged_mining_nonce_size").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(get_merged_mining_nonce_size)).ToLocalChecked());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,8 @@ namespace nodetool
|
|||
m_last_stat_request_time{},
|
||||
m_use_only_priority_peers(false),
|
||||
m_peer_livetime{},
|
||||
m_debug_requests_enabled(false)
|
||||
m_debug_requests_enabled(false),
|
||||
m_ip_auto_blocking_enabled(false)
|
||||
{}
|
||||
|
||||
static void init_options(boost::program_options::options_description& desc);
|
||||
|
|
@ -215,6 +216,8 @@ namespace nodetool
|
|||
bool urgent_alert_worker();
|
||||
bool critical_alert_worker();
|
||||
bool remove_dead_connections();
|
||||
bool is_ip_good_for_adding_to_peerlist(uint32_t adress);
|
||||
bool is_ip_in_blacklist(uint32_t adress);
|
||||
|
||||
|
||||
//debug functions
|
||||
|
|
@ -245,6 +248,7 @@ namespace nodetool
|
|||
bool m_hide_my_port;
|
||||
bool m_offline_mode;
|
||||
bool m_debug_requests_enabled;
|
||||
bool m_ip_auto_blocking_enabled;
|
||||
uint64_t m_startup_time;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ namespace nodetool
|
|||
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port = {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_offline_mode = { "offline-mode", "Don't connect to any node and reject any connections", false, true };
|
||||
const command_line::arg_descriptor<bool> arg_p2p_disable_debug_reqs = { "disable-debug-p2p-requests", "Disable p2p debug requests", false, true };
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_ip_auto_blocking = { "p2p-ip-auto-blocking", "Enable (1) or disable (0) peers auto-blocking by IP <0|1>. Default: 0", 0, false };
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
|
@ -54,6 +55,7 @@ namespace nodetool
|
|||
command_line::add_arg(desc, arg_p2p_offline_mode);
|
||||
command_line::add_arg(desc, arg_p2p_disable_debug_reqs);
|
||||
command_line::add_arg(desc, arg_p2p_use_only_priority_nodes);
|
||||
command_line::add_arg(desc, arg_p2p_ip_auto_blocking);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
|
|
@ -65,7 +67,14 @@ namespace nodetool
|
|||
CHECK_AND_ASSERT_MES(r, false, "Failed to parse P2P_MAINTAINERS_PUB_KEY = " << P2P_MAINTAINERS_PUB_KEY);
|
||||
|
||||
std::string state_file_path = m_config_folder + "/" + P2P_NET_DATA_FILENAME;
|
||||
boost::system::error_code ec = AUTO_VAL_INIT(ec);
|
||||
std::time_t last_update_time = boost::filesystem::last_write_time(state_file_path, ec);
|
||||
//let's assume that if p2p peer list file stored more then 2 weeks ago,
|
||||
//then it outdated and we need to fetch peerlist from seed nodes
|
||||
if (!ec && time(nullptr) - last_update_time < 86400 * 14)
|
||||
{
|
||||
tools::unserialize_obj_from_file(*this, state_file_path);
|
||||
}
|
||||
|
||||
//always use new id, to be able differ cloned computers
|
||||
m_config.m_peer_id = crypto::rand<uint64_t>();
|
||||
|
|
@ -100,21 +109,39 @@ namespace nodetool
|
|||
if (m_offline_mode)
|
||||
return false;
|
||||
|
||||
//@#@ temporary workaround
|
||||
if (!m_ip_auto_blocking_enabled)
|
||||
return true;
|
||||
#if 0
|
||||
|
||||
return !is_ip_in_blacklist(addr);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_ip_good_for_adding_to_peerlist(uint32_t addr)
|
||||
{
|
||||
if (m_offline_mode)
|
||||
return false;
|
||||
|
||||
// even if IP auto blocking is disabled, bad peers should not be added to peerlists and be shared with other nodes
|
||||
|
||||
return !is_ip_in_blacklist(addr);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::is_ip_in_blacklist(uint32_t addr)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
|
||||
auto it = m_blocked_ips.find(addr);
|
||||
if (it == m_blocked_ips.end())
|
||||
return true;
|
||||
return false;
|
||||
|
||||
if (time(nullptr) - it->second > P2P_IP_BLOCKTIME)
|
||||
{
|
||||
m_blocked_ips.erase(it);
|
||||
LOG_PRINT_CYAN("Ip " << string_tools::get_ip_string_from_int32(addr) << "is unblocked.", LOG_LEVEL_0);
|
||||
return true;
|
||||
}
|
||||
LOG_PRINT_CYAN("IP " << string_tools::get_ip_string_from_int32(addr) << " is unblocked due to blocking expiration.", LOG_LEVEL_0);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
|
|
@ -122,7 +149,8 @@ namespace nodetool
|
|||
{
|
||||
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
|
||||
m_blocked_ips[addr] = time(nullptr);
|
||||
LOG_PRINT_CYAN("Ip " << string_tools::get_ip_string_from_int32(addr) << " blocked.", LOG_LEVEL_0);
|
||||
m_peerlist.remove_peers_by_ip_from_all(addr);
|
||||
LOG_PRINT_CYAN("IP " << string_tools::get_ip_string_from_int32(addr) << " blocked and removed from peerlist", LOG_LEVEL_0);
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
|
@ -138,6 +166,10 @@ namespace nodetool
|
|||
it->second = P2P_IP_FAILS_BEFOR_BLOCK/2;
|
||||
block_ip(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_PRINT_CYAN("IP " << string_tools::get_ip_string_from_int32(address) << ": fail recorded, total fails count: " << fails, LOG_LEVEL_2);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
|
@ -162,6 +194,9 @@ namespace nodetool
|
|||
m_allow_local_ip = command_line::get_arg(vm, arg_p2p_allow_local_ip);
|
||||
m_offline_mode = command_line::get_arg(vm, arg_p2p_offline_mode);
|
||||
m_debug_requests_enabled = !command_line::get_arg(vm, arg_p2p_disable_debug_reqs);
|
||||
m_ip_auto_blocking_enabled = (command_line::get_arg(vm, arg_p2p_ip_auto_blocking) != 0);
|
||||
|
||||
LOG_PRINT_L0("p2p peers auto-blocking is " << (m_ip_auto_blocking_enabled ? "enabled" : "disabled"));
|
||||
|
||||
if (m_offline_mode)
|
||||
{
|
||||
|
|
@ -679,7 +714,6 @@ namespace nodetool
|
|||
<< string_tools::get_ip_string_from_int32(na.ip)
|
||||
<< ":" << string_tools::num_to_string_fast(na.port)
|
||||
/*<< ", try " << try_count*/);
|
||||
//m_peerlist.set_peer_unreachable(pe);
|
||||
return false;
|
||||
}
|
||||
peerid_type pi = AUTO_VAL_INIT(pi);
|
||||
|
|
@ -701,12 +735,15 @@ namespace nodetool
|
|||
return true;
|
||||
}
|
||||
|
||||
if (is_ip_good_for_adding_to_peerlist(na.ip)) // additional check to avoid IP shown up in peers in the case of non-blocking incoming connections
|
||||
{
|
||||
//update last seen and push it to peerlist manager
|
||||
peerlist_entry pe_local = AUTO_VAL_INIT(pe_local);
|
||||
pe_local.adr = na;
|
||||
pe_local.id = pi;
|
||||
time(&pe_local.last_seen);
|
||||
m_peerlist.append_with_peer_white(pe_local);
|
||||
//update last seen and push it to peerlist manager
|
||||
}
|
||||
|
||||
LOG_PRINT_CC_GREEN(con, "CONNECTION HANDSHAKED OK with peer " << string_tools::get_ip_string_from_int32(na.ip) << ":" << string_tools::num_to_string_fast(na.port), LOG_LEVEL_2);
|
||||
return true;
|
||||
|
|
@ -1373,7 +1410,8 @@ namespace nodetool
|
|||
//associate peer_id with this connection
|
||||
context.peer_id = arg.node_data.peer_id;
|
||||
|
||||
if(arg.node_data.peer_id != m_config.m_peer_id && arg.node_data.my_port)
|
||||
if(arg.node_data.peer_id != m_config.m_peer_id && arg.node_data.my_port
|
||||
&& is_ip_good_for_adding_to_peerlist(context.m_remote_ip))
|
||||
{
|
||||
peerid_type peer_id_l = arg.node_data.peer_id;
|
||||
uint32_t port_l = arg.node_data.my_port;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) 2014-2019 Zano Project
|
||||
// Copyright (c) 2014-2021 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
|
||||
|
|
@ -11,8 +11,6 @@
|
|||
#include <map>
|
||||
#include <iterator>
|
||||
#include <boost/foreach.hpp>
|
||||
//#include <boost/bimap.hpp>
|
||||
//#include <boost/bimap/multiset_of.hpp>
|
||||
#include <boost/archive/binary_oarchive.hpp>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
#include <boost/serialization/version.hpp>
|
||||
|
|
@ -55,10 +53,10 @@ namespace nodetool
|
|||
bool append_with_peer_gray(const peerlist_entry& pr);
|
||||
bool set_peer_just_seen(peerid_type peer, uint32_t ip, uint32_t port);
|
||||
bool set_peer_just_seen(peerid_type peer, const net_address& addr);
|
||||
bool set_peer_unreachable(const peerlist_entry& pr);
|
||||
bool is_ip_allowed(uint32_t ip);
|
||||
void trim_white_peerlist();
|
||||
void trim_gray_peerlist();
|
||||
bool remove_peers_by_ip_from_all(const uint32_t ip);
|
||||
|
||||
|
||||
private:
|
||||
|
|
@ -110,17 +108,6 @@ namespace nodetool
|
|||
>
|
||||
> peers_indexed;
|
||||
|
||||
typedef boost::multi_index_container<
|
||||
peerlist_entry,
|
||||
boost::multi_index::indexed_by<
|
||||
// access by peerlist_entry::id<
|
||||
boost::multi_index::ordered_unique<boost::multi_index::tag<by_id>, boost::multi_index::member<peerlist_entry,uint64_t,&peerlist_entry::id> >,
|
||||
// access by peerlist_entry::net_adress
|
||||
boost::multi_index::ordered_unique<boost::multi_index::tag<by_addr>, boost::multi_index::member<peerlist_entry,net_address,&peerlist_entry::adr> >,
|
||||
// sort by peerlist_entry::last_seen<
|
||||
boost::multi_index::ordered_non_unique<boost::multi_index::tag<by_time>, boost::multi_index::member<peerlist_entry,time_t,&peerlist_entry::last_seen> >
|
||||
>
|
||||
> peers_indexed_old;
|
||||
public:
|
||||
|
||||
template <class Archive, class t_version_type>
|
||||
|
|
@ -135,8 +122,6 @@ namespace nodetool
|
|||
}
|
||||
|
||||
private:
|
||||
bool peers_indexed_from_old(const peers_indexed_old& pio, peers_indexed& pi);
|
||||
|
||||
friend class boost::serialization::access;
|
||||
epee::critical_section m_peerlist_lock;
|
||||
std::string m_config_folder;
|
||||
|
|
@ -188,21 +173,6 @@ namespace nodetool
|
|||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::peers_indexed_from_old(const peers_indexed_old& pio, peers_indexed& pi)
|
||||
{
|
||||
for(auto x: pio)
|
||||
{
|
||||
auto by_addr_it = pi.get<by_addr>().find(x.adr);
|
||||
if(by_addr_it == pi.get<by_addr>().end())
|
||||
{
|
||||
pi.insert(x);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline void peerlist_manager::trim_white_peerlist()
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
|
|
@ -393,6 +363,33 @@ namespace nodetool
|
|||
return true;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
inline
|
||||
bool peerlist_manager::remove_peers_by_ip_from_all(const uint32_t ip)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
|
||||
for (auto it = m_peers_white.begin(); it != m_peers_white.end();)
|
||||
{
|
||||
if (it->adr.ip == ip)
|
||||
it = m_peers_white.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for (auto it = m_peers_gray.begin(); it != m_peers_gray.end();)
|
||||
{
|
||||
if (it->adr.ip == ip)
|
||||
it = m_peers_gray.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
return true;
|
||||
CATCH_ENTRY_L0("peerlist_manager::remove_peers_by_ip_from_all()", false);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
BOOST_CLASS_VERSION(nodetool::peerlist_manager, CURRENT_PEERLIST_STORAGE_ARCHIVE_VER)
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ namespace currency
|
|||
res.pos_block_ts_shift_vs_actual = 0;
|
||||
auto last_pos_block_ptr = m_core.get_blockchain_storage().get_last_block_of_type(true);
|
||||
if (last_pos_block_ptr)
|
||||
res.pos_block_ts_shift_vs_actual = last_pos_block_ptr->bl.timestamp - get_actual_timestamp(last_pos_block_ptr->bl);
|
||||
res.pos_block_ts_shift_vs_actual = last_pos_block_ptr->bl.timestamp - get_block_datetime(last_pos_block_ptr->bl);
|
||||
}
|
||||
if (req.flags&COMMAND_RPC_GET_INFO_FLAG_OUTS_STAT)
|
||||
m_core.get_blockchain_storage().get_outs_index_stat(res.outs_stat);
|
||||
|
|
@ -210,6 +210,7 @@ namespace currency
|
|||
res.performance_data.tx_append_time = pd.tx_append_time.get_avg();
|
||||
res.performance_data.tx_append_rl_wait = pd.tx_append_rl_wait.get_avg();
|
||||
res.performance_data.tx_append_is_expired = pd.tx_append_is_expired.get_avg();
|
||||
res.performance_data.tx_mixin_count = pd.tx_mixin_count.get_avg();
|
||||
|
||||
|
||||
res.performance_data.tx_store_db = pd.tx_store_db.get_avg();
|
||||
|
|
@ -915,17 +916,6 @@ namespace currency
|
|||
error_resp.message = "Block not accepted";
|
||||
return false;
|
||||
}
|
||||
//@#@
|
||||
//temporary double check timestamp
|
||||
if (time(NULL) - static_cast<int64_t>(get_actual_timestamp(b)) > 5)
|
||||
{
|
||||
LOG_PRINT_RED_L0("Found block (" << get_block_hash(b) << ") timestamp (" << get_actual_timestamp(b)
|
||||
<< ") is suspiciously less (" << time(NULL) - static_cast<int64_t>(get_actual_timestamp(b)) << ") than current time ( " << time(NULL) << ")");
|
||||
//mark node to make it easier to find it via scanner
|
||||
m_core.get_blockchain_storage().get_performnce_data().epic_failure_happend = true;
|
||||
}
|
||||
//
|
||||
|
||||
|
||||
res.status = "OK";
|
||||
return true;
|
||||
|
|
@ -972,17 +962,6 @@ namespace currency
|
|||
error_resp.message = "Block not accepted";
|
||||
return false;
|
||||
}
|
||||
//@#@
|
||||
//temporary double check timestamp
|
||||
if (time(NULL) - static_cast<int64_t>(get_actual_timestamp(b)) > 5)
|
||||
{
|
||||
LOG_PRINT_RED_L0("Found block (" << get_block_hash(b) << ") timestamp (" << get_actual_timestamp(b)
|
||||
<< ") is suspiciously less (" << time(NULL) - static_cast<int64_t>(get_actual_timestamp(b)) << ") than current time ( " << time(NULL) << ")");
|
||||
//mark node to make it easier to find it via scanner
|
||||
m_core.get_blockchain_storage().get_performnce_data().epic_failure_happend = true;
|
||||
}
|
||||
//
|
||||
|
||||
|
||||
res.status = "OK";
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -500,6 +500,8 @@ namespace currency
|
|||
uint64_t tx_print_log;
|
||||
uint64_t tx_prapare_append;
|
||||
|
||||
uint64_t tx_mixin_count;
|
||||
|
||||
|
||||
uint64_t tx_store_db;
|
||||
|
||||
|
|
@ -547,6 +549,7 @@ namespace currency
|
|||
KV_SERIALIZE(tx_store_db)
|
||||
KV_SERIALIZE(tx_print_log)
|
||||
KV_SERIALIZE(tx_prapare_append)
|
||||
KV_SERIALIZE(tx_mixin_count)
|
||||
|
||||
KV_SERIALIZE(tx_check_inputs_prefix_hash)
|
||||
KV_SERIALIZE(tx_check_inputs_attachment_check)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue