forked from lthn/blockchain
Merge branch 'develop' into develop_mobile
This commit is contained in:
commit
fbc50419db
39 changed files with 628 additions and 253 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
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 ""
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -4905,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);
|
||||
|
|
@ -5060,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)
|
||||
|
|
@ -5379,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;
|
||||
|
|
@ -5454,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))
|
||||
|
|
@ -5622,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 << ")";
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
|
@ -819,7 +815,7 @@ namespace currency
|
|||
//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::apped_pod_to_strbuff(salted_body, derivation_hash);
|
||||
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);
|
||||
}
|
||||
|
|
@ -890,8 +886,8 @@ namespace currency
|
|||
//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::apped_pod_to_strbuff(salted_body, derivation_hash);
|
||||
crypto::hash proof_hash = crypto::cn_fast_hash(salted_body.data(), salted_body.size());
|
||||
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");
|
||||
}
|
||||
|
||||
|
|
@ -2062,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());
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
|
@ -2113,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;
|
||||
|
|
@ -2124,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)
|
||||
{
|
||||
|
|
@ -2782,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;
|
||||
|
|
|
|||
|
|
@ -329,8 +329,10 @@ 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);
|
||||
bool set_payment_id_to_tx(std::vector<attachment_v>& att, const std::string& payment_id);
|
||||
|
|
@ -346,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)
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ private:
|
|||
currency::block_extended_info bei = AUTO_VAL_INIT(bei);
|
||||
CHECK_AND_ASSERT_MES(bcs.get_block_extended_info_by_height(tx_chain_entry->m_keeper_block_height, bei), false, "cannot find block by height " << tx_chain_entry->m_keeper_block_height);
|
||||
|
||||
LOG_PRINT_L0("Key image found in tx: " << tx_id << " height " << tx_chain_entry->m_keeper_block_height << " (ts: " << epee::misc_utils::get_time_str_v2(currency::get_actual_timestamp(bei.bl)) << ")" << ENDL
|
||||
LOG_PRINT_L0("Key image found in tx: " << tx_id << " height " << tx_chain_entry->m_keeper_block_height << " (ts: " << epee::misc_utils::get_time_str_v2(currency::get_block_datetime(bei.bl)) << ")" << ENDL
|
||||
<< obj_to_json_str(tx_chain_entry->tx));
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -643,6 +643,7 @@ bool MainWindow::show_inital()
|
|||
restore_pos(true);
|
||||
else
|
||||
{
|
||||
m_config = AUTO_VAL_INIT(m_config);
|
||||
this->show();
|
||||
QSize sz;
|
||||
sz.setHeight(770);
|
||||
|
|
@ -651,6 +652,7 @@ bool MainWindow::show_inital()
|
|||
store_window_pos();
|
||||
m_config.is_maximazed = false;
|
||||
m_config.is_showed = true;
|
||||
m_config.disable_notifications = false;
|
||||
}
|
||||
return true;
|
||||
CATCH_ENTRY2(false);
|
||||
|
|
@ -727,14 +729,26 @@ void qt_log_message_handler(QtMsgType type, const QMessageLogContext &context, c
|
|||
bool MainWindow::init_backend(int argc, char* argv[])
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if (!m_backend.init_command_line(argc, argv))
|
||||
std::string command_line_fail_details;
|
||||
if (!m_backend.init_command_line(argc, argv, command_line_fail_details))
|
||||
{
|
||||
this->show_msg_box(command_line_fail_details);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!init_window())
|
||||
{
|
||||
this->show_msg_box("Failed to main screen launch, check logs for the more detais.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_backend.init(this))
|
||||
{
|
||||
this->show_msg_box("Failed to initialize backend, check debug logs for more details.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (m_backend.is_qt_logs_enabled())
|
||||
{
|
||||
|
|
@ -811,8 +825,25 @@ bool MainWindow::nativeEventFilter(const QByteArray &eventType, void *message, l
|
|||
CATCH_ENTRY2(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool MainWindow::get_is_disabled_notifications()
|
||||
{
|
||||
return m_config.disable_notifications;
|
||||
}
|
||||
bool MainWindow::set_is_disabled_notifications(const bool& param)
|
||||
{
|
||||
m_config.disable_notifications = param;
|
||||
return m_config.disable_notifications;
|
||||
}
|
||||
QString MainWindow::export_wallet_history(const QString& param)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
LOG_API_TIMING();
|
||||
PREPARE_ARG_FROM_JSON(view::export_wallet_info, ewi);
|
||||
PREPARE_RESPONSE(view::api_response, ar);
|
||||
ar.error_code = m_backend.export_wallet_history(ewi);
|
||||
return MAKE_RESPONSE(ar);
|
||||
CATCH_ENTRY2(false);
|
||||
}
|
||||
bool MainWindow::update_wallets_info(const view::wallets_summary_info& wsi)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
|
@ -834,6 +865,10 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei)
|
|||
LOG_PRINT_L0(get_wallet_log_prefix(tei.wallet_id) + "SENDING SIGNAL -> [money_transfer]" << std::endl << json_str);
|
||||
//this->money_transfer(json_str.c_str());
|
||||
QMetaObject::invokeMethod(this, "money_transfer", Qt::QueuedConnection, Q_ARG(QString, json_str.c_str()));
|
||||
if (m_config.disable_notifications)
|
||||
return true;
|
||||
|
||||
|
||||
if (!m_tray_icon)
|
||||
return true;
|
||||
if (!tei.ti.is_income)
|
||||
|
|
@ -852,7 +887,7 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei)
|
|||
return true;
|
||||
}
|
||||
|
||||
auto amount_str = currency::print_money(tei.ti.amount);
|
||||
auto amount_str = currency::print_money_brief(tei.ti.amount);
|
||||
std::string title, msg;
|
||||
if (tei.ti.height == 0) // unconfirmed trx
|
||||
{
|
||||
|
|
@ -869,6 +904,7 @@ bool MainWindow::money_transfer(const view::transfer_event_info& tei)
|
|||
else if (tei.ti.unlock_time)
|
||||
msg += m_localization[localization_id_locked];
|
||||
|
||||
|
||||
show_notification(title, msg);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ public:
|
|||
std::pair<int64_t, int64_t> m_window_size;
|
||||
bool is_maximazed;
|
||||
bool is_showed;
|
||||
bool disable_notifications;
|
||||
};
|
||||
|
||||
protected slots:
|
||||
|
|
@ -150,6 +151,10 @@ public:
|
|||
QString get_default_fee();
|
||||
QString get_options();
|
||||
void bool_toggle_icon(const QString& param);
|
||||
|
||||
bool get_is_disabled_notifications();
|
||||
bool set_is_disabled_notifications(const bool& param);
|
||||
QString export_wallet_history(const QString& param);
|
||||
QString get_log_file();
|
||||
QString check_available_sources(const QString& param);
|
||||
QString open_url_in_browser(const QString& param);
|
||||
|
|
@ -176,6 +181,7 @@ signals:
|
|||
void do_dispatch(const QString status, const QString params); //general function
|
||||
void on_core_event(const QString method_name); //general function
|
||||
void set_options(const QString str); //general function
|
||||
void get_wallet_name();
|
||||
|
||||
private:
|
||||
//-------------------- i_core_event_handler --------------------
|
||||
|
|
@ -254,7 +260,7 @@ private:
|
|||
|
||||
enum localization_string_indices
|
||||
{
|
||||
// order is surprizingly important here! (see also updateLocalisation in AppController.js)
|
||||
// order is surprisingly important here! (see also updateLocalisation in AppController.js)
|
||||
localization_id_quit = 0,
|
||||
localization_id_is_received,
|
||||
localization_id_is_confirmed,
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit fd506b5669624c8deeab901347228c400d9dc89d
|
||||
Subproject commit b028252d30a32e80c12fa890c306d3c5842e937a
|
||||
|
|
@ -64,9 +64,9 @@ int main(int argc, char *argv[])
|
|||
MainWindow viewer;
|
||||
if (!viewer.init_backend(argc, argv))
|
||||
{
|
||||
static_cast<view::i_view*>(&viewer)->show_msg_box("Failed to initialize backend, check debug logs for more details.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
app.installNativeEventFilter(&viewer);
|
||||
viewer.setWindowTitle(CURRENCY_NAME_BASE);
|
||||
viewer.show_inital();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,18 +26,19 @@ namespace nodetool
|
|||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_ip = {"p2p-bind-ip", "Interface for p2p network protocol", "0.0.0.0"};
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_port = {"p2p-bind-port", "Port for p2p network protocol", boost::to_string(P2P_DEFAULT_PORT)};
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_external_port = {"p2p-external-port", "External port for p2p network protocol (if port forwarding used with NAT)", 0};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip = {"allow-local-ip", "Allow local ip add to peer list, mostly in debug purposes"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer = {"add-peer", "Manually add peer to local peerlist"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_priority_node = {"add-priority-node", "Specify list of peers to connect to and attempt to keep the connection open"};
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_ip = {"p2p-bind-ip", "Interface for p2p network protocol", "0.0.0.0"};
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_port = {"p2p-bind-port", "Port for p2p network protocol", boost::to_string(P2P_DEFAULT_PORT)};
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_external_port = {"p2p-external-port", "External port for p2p network protocol (if port forwarding used with NAT)", 0};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip = {"allow-local-ip", "Allow local ip add to peer list, mostly in debug purposes"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer = {"add-peer", "Manually add peer to local peerlist"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_priority_node = {"add-priority-node", "Specify list of peers to connect to and attempt to keep the connection open"};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_use_only_priority_nodes = {"use-only-priority-nodes", "Try to connect only to priority nodes"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_seed_node = {"seed-node", "Connect to a node to retrieve peer addresses, and disconnect"};
|
||||
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<std::vector<std::string> > arg_p2p_seed_node = {"seed-node", "Connect to a node to retrieve peer addresses, and disconnect"};
|
||||
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 };
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
|
|
@ -53,7 +54,8 @@ namespace nodetool
|
|||
command_line::add_arg(desc, arg_p2p_hide_my_port);
|
||||
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_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;
|
||||
tools::unserialize_obj_from_file(*this, state_file_path);
|
||||
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
|
||||
return true;
|
||||
#if 0
|
||||
if (!m_ip_auto_blocking_enabled)
|
||||
return true;
|
||||
|
||||
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;
|
||||
if(time(nullptr) - it->second > P2P_IP_BLOCKTIME )
|
||||
if (it == m_blocked_ips.end())
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
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>
|
||||
|
|
@ -134,9 +121,7 @@ namespace nodetool
|
|||
ar & m_peers_gray;
|
||||
}
|
||||
|
||||
private:
|
||||
bool peers_indexed_from_old(const peers_indexed_old& pio, peers_indexed& pi);
|
||||
|
||||
private:
|
||||
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);
|
||||
|
|
@ -916,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;
|
||||
|
|
@ -973,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;
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ simple_wallet::simple_wallet()
|
|||
|
||||
m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), "sign_transfer <unsgined_tx_file> <signed_tx_file> - sign unsigned tx from a watch-only wallet");
|
||||
m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), "submit_transfer <signed_tx_file> - broadcast signed tx");
|
||||
m_cmd_binder.set_handler("export_history", boost::bind(&simple_wallet::submit_transfer, this, _1), "Export transaction history in CSV file");
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
simple_wallet::~simple_wallet()
|
||||
|
|
@ -798,12 +799,7 @@ bool simple_wallet::list_recent_transfers(const std::vector<std::string>& args)
|
|||
std::string wti_to_text_line(const tools::wallet_public::wallet_transfer_info& wti)
|
||||
{
|
||||
stringstream ss;
|
||||
ss << (wti.is_income ? "[INC]" : "[OUT]") << "\t"
|
||||
<< epee::misc_utils::get_time_str(wti.timestamp) << "\t"
|
||||
<< print_money(wti.amount) << "\t"
|
||||
<< print_money(wti.fee) << "\t"
|
||||
<< wti.remote_addresses << "\t"
|
||||
<< wti.comment << "\t";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -811,58 +807,37 @@ bool simple_wallet::export_recent_transfers(const std::vector<std::string>& args
|
|||
{
|
||||
bool export_to_json = true;
|
||||
bool ignore_pos = false;
|
||||
if (args.size())
|
||||
{
|
||||
if (args[0] == "json")
|
||||
export_to_json = true;
|
||||
else if (args[0] == "txt")
|
||||
export_to_json = false;
|
||||
}
|
||||
if (args.size() > 1)
|
||||
{
|
||||
if (args[1] == "ignore-pos")
|
||||
ignore_pos = true;
|
||||
}
|
||||
|
||||
std::vector<tools::wallet_public::wallet_transfer_info> unconfirmed;
|
||||
std::vector<tools::wallet_public::wallet_transfer_info> recent;
|
||||
uint64_t total = 0;
|
||||
uint64_t last_index = 0;
|
||||
m_wallet->get_recent_transfers_history(recent, 0, 0, total, last_index, false);
|
||||
m_wallet->get_unconfirmed_transfers(unconfirmed, false);
|
||||
//workaround for missed fee
|
||||
stringstream ss;
|
||||
LOG_PRINT_GREEN("Generating text....", LOG_LEVEL_0);
|
||||
ss << "Unconfirmed transfers: " << ENDL;
|
||||
for (auto & wti : unconfirmed)
|
||||
std::string format = "csv";
|
||||
if (args.size() > 0)
|
||||
{
|
||||
if(ignore_pos && wti.is_mining)
|
||||
continue;
|
||||
if (!wti.fee)
|
||||
wti.fee = currency::get_tx_fee(wti.tx);
|
||||
if(export_to_json)
|
||||
ss << epee::serialization::store_t_to_json(wti) << ENDL;
|
||||
if (args[0] == "json" || args[0] == "csv" || args[0] == "text")
|
||||
{
|
||||
format = args[0];
|
||||
}
|
||||
else
|
||||
ss << wti_to_text_line(wti) << ENDL;
|
||||
|
||||
{
|
||||
fail_msg_writer() << "Unknown format: \"" << args[0] << "\", only \"csv\"(default), \"json\" and \"text\" supported";
|
||||
}
|
||||
}
|
||||
ss << "Recent transfers: " << ENDL;
|
||||
for (auto & wti : recent)
|
||||
|
||||
try {
|
||||
boost::filesystem::ofstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(log_space::log_singletone::get_default_log_folder() + "/wallet_recent_transfers.txt", std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
|
||||
m_wallet->export_transaction_history(fstream, format, !ignore_pos);
|
||||
fstream.close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (ignore_pos && wti.is_mining)
|
||||
continue;
|
||||
if (!wti.fee)
|
||||
wti.fee = currency::get_tx_fee(wti.tx);
|
||||
|
||||
if (export_to_json)
|
||||
ss << epee::serialization::store_t_to_json(wti) << ENDL;
|
||||
else
|
||||
ss << wti_to_text_line(wti) << ENDL;
|
||||
success_msg_writer() << "Failed";
|
||||
return false;
|
||||
}
|
||||
LOG_PRINT_GREEN("Storing text to wallet_recent_transfers.txt....", LOG_LEVEL_0);
|
||||
file_io_utils::save_string_to_file(log_space::log_singletone::get_default_log_folder() + "/wallet_recent_transfers.txt", ss.str());
|
||||
LOG_PRINT_GREEN("Done", LOG_LEVEL_0);
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -1183,7 +1158,7 @@ bool simple_wallet::validate_wrap_status(uint64_t amount)
|
|||
|
||||
currency::void_struct req = AUTO_VAL_INIT(req);
|
||||
currency::rpc_get_wrap_info_response res = AUTO_VAL_INIT(res);
|
||||
bool r = epee::net_utils::invoke_http_json_remote_command2("http://wrapped.zano.org/api/get_wrap_info", req, res, http_client, 10000);
|
||||
bool r = epee::net_utils::invoke_http_json_remote_command2("http://wrapped.zano.org/api2/get_wrap_info", req, res, http_client, 10000);
|
||||
if (!r)
|
||||
{
|
||||
fail_msg_writer() << "Failed to request wrap status from server, check internet connection";
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
#define PROJECT_MAJOR_VERSION "1"
|
||||
#define PROJECT_MINOR_VERSION "3"
|
||||
#define PROJECT_REVISION "0"
|
||||
#define PROJECT_REVISION "1"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 132
|
||||
#define PROJECT_VERSION_BUILD_NO 134
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
|
|
@ -201,7 +201,8 @@ namespace plain_wallet
|
|||
args[1] = const_cast<char*>(argss_1.c_str());
|
||||
args[2] = const_cast<char*>(argss_2.c_str());
|
||||
args[3] = nullptr;
|
||||
if (!(ptr->gwm.init_command_line(3, args) && ptr->gwm.init(nullptr)))
|
||||
std::string command_line_fail_details;
|
||||
if (!(ptr->gwm.init_command_line(3, args, command_line_fail_details) && ptr->gwm.init(nullptr)))
|
||||
{
|
||||
LOG_ERROR("Failed to init wallets_manager");
|
||||
return GENERAL_INTERNAL_ERRROR_INIT;
|
||||
|
|
|
|||
|
|
@ -284,6 +284,20 @@ public:
|
|||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct export_wallet_info
|
||||
{
|
||||
uint64_t wallet_id;
|
||||
bool include_pos_transactions;
|
||||
std::string path;
|
||||
std::string format;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(wallet_id)
|
||||
KV_SERIALIZE(include_pos_transactions)
|
||||
KV_SERIALIZE(path)
|
||||
KV_SERIALIZE(format)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response_mining_estimate
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1281,7 +1281,7 @@ void wallet2::handle_money_received2(const currency::block& b, const currency::t
|
|||
m_transfer_history.push_back(AUTO_VAL_INIT(wallet_public::wallet_transfer_info()));
|
||||
wallet_public::wallet_transfer_info& wti = m_transfer_history.back();
|
||||
wti.is_income = true;
|
||||
prepare_wti(wti, get_block_height(b), get_actual_timestamp(b), tx, amount, td);
|
||||
prepare_wti(wti, get_block_height(b), get_block_datetime(b), tx, amount, td);
|
||||
WLT_LOG_L1("[MONEY RECEIVED]: " << epee::serialization::store_t_to_json(wti));
|
||||
rise_on_transfer2(wti);
|
||||
}
|
||||
|
|
@ -1311,7 +1311,7 @@ void wallet2::handle_money_spent2(const currency::block& b,
|
|||
|
||||
wti.remote_addresses = recipients;
|
||||
wti.recipients_aliases = recipients_aliases;
|
||||
prepare_wti(wti, get_block_height(b), get_actual_timestamp(b), in_tx, amount, td);
|
||||
prepare_wti(wti, get_block_height(b), get_block_datetime(b), in_tx, amount, td);
|
||||
WLT_LOG_L1("[MONEY SPENT]: " << epee::serialization::store_t_to_json(wti));
|
||||
rise_on_transfer2(wti);
|
||||
}
|
||||
|
|
@ -3254,6 +3254,87 @@ void wallet2::get_recent_transfers_history(std::vector<wallet_public::wallet_tra
|
|||
|
||||
total = m_transfer_history.size();
|
||||
|
||||
}
|
||||
|
||||
void wallet2::wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index) {
|
||||
ss << index << ",";
|
||||
ss << epee::misc_utils::get_time_str_v2(wti.timestamp) << ",";
|
||||
ss << print_money(wti.amount) << ",";
|
||||
ss << "\"" << wti.comment << "\",";
|
||||
ss << "[";
|
||||
std::copy(wti.remote_addresses.begin(), wti.remote_addresses.end(), std::ostream_iterator<std::string>(ss, " "));
|
||||
ss << "]" << ",";
|
||||
ss << wti.tx_hash << ",";
|
||||
ss << wti.height << ",";
|
||||
ss << wti.unlock_time << ",";
|
||||
ss << wti.tx_blob_size << ",";
|
||||
ss << epee::string_tools::buff_to_hex_nodelimer(wti.payment_id) << ",";
|
||||
ss << "[";
|
||||
std::copy(wti.recipients_aliases.begin(), wti.recipients_aliases.end(), std::ostream_iterator<std::string>(ss, " "));
|
||||
ss << "]" << ",";
|
||||
ss << (wti.is_income ? "in" : "out") << ",";
|
||||
ss << (wti.is_service ? "[SERVICE]" : "") << (wti.is_mixing ? "[MIXINS]" : "") << (wti.is_mining ? "[MINING]" : "") << ",";
|
||||
ss << wti.tx_type << ",";
|
||||
ss << wti.fee << ENDL;
|
||||
};
|
||||
|
||||
void wallet2::wti_to_txt_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index)
|
||||
{
|
||||
ss << (wti.is_income ? "[INC]" : "[OUT]") << "\t"
|
||||
<< epee::misc_utils::get_time_str(wti.timestamp) << "\t"
|
||||
<< print_money(wti.amount) << "\t"
|
||||
<< print_money(wti.fee) << "\t"
|
||||
<< wti.remote_addresses << "\t"
|
||||
<< wti.comment << ENDL;
|
||||
};
|
||||
|
||||
void wallet2::wti_to_json_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index)
|
||||
{
|
||||
ss << epee::serialization::store_t_to_json(wti, 4) << ",";
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::export_transaction_history(std::ostream& ss, const std::string& format, bool include_pos_transactions)
|
||||
{
|
||||
//typedef int(*t_somefunc)(int, int);
|
||||
typedef void(*playout_cb_type)(std::ostream&, const wallet_public::wallet_transfer_info&, size_t);
|
||||
playout_cb_type cb_csv = &wallet2::wti_to_csv_entry;
|
||||
playout_cb_type cb_json = &wallet2::wti_to_json_line;
|
||||
playout_cb_type cb_plain_text = &wallet2::wti_to_txt_line;
|
||||
|
||||
playout_cb_type cb = cb_csv;
|
||||
if (format == "json")
|
||||
{
|
||||
ss << "{ \"history\": [";
|
||||
cb = cb_json;
|
||||
}
|
||||
else if (format == "text")
|
||||
{
|
||||
cb = cb_plain_text;
|
||||
}
|
||||
else
|
||||
{
|
||||
//csv by default
|
||||
ss << "N, Date, Amount, Comment, Address, ID, Height, Unlock timestamp, Tx size, Alias, In/Out, Flags, Type, Fee" << ENDL;
|
||||
}
|
||||
|
||||
|
||||
enum_container(m_transfer_history.begin(), m_transfer_history.end(), [&](wallet_public::wallet_transfer_info& wti, size_t index) {
|
||||
if (!include_pos_transactions)
|
||||
{
|
||||
if (currency::is_coinbase(wti.tx))
|
||||
return true;
|
||||
}
|
||||
cb(ss, wti, index);
|
||||
return true;
|
||||
});
|
||||
|
||||
if (format == "json")
|
||||
{
|
||||
ss << "{}]}";
|
||||
}
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id)
|
||||
|
|
@ -3377,16 +3458,13 @@ bool wallet2::prepare_and_sign_pos_block(currency::block& b,
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool wallet2::build_kernel(const pos_entry& pe, const stake_modifier_type& stake_modifier, stake_kernel& kernel, uint64_t& coindays_weight, uint64_t timestamp)
|
||||
bool wallet2::build_kernel(const pos_entry& pe, const stake_modifier_type& stake_modifier, const uint64_t timestamp, stake_kernel& kernel)
|
||||
{
|
||||
PROFILE_FUNC("build_kernel");
|
||||
coindays_weight = 0;
|
||||
kernel = stake_kernel();
|
||||
kernel.kimage = pe.keyimage;
|
||||
kernel.stake_modifier = stake_modifier;
|
||||
kernel.block_timestamp = timestamp;
|
||||
|
||||
coindays_weight = get_coinday_weight(pe.amount);
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -3457,7 +3535,7 @@ bool wallet2::try_mint_pos(const currency::account_public_address& miner_address
|
|||
build_minted_block(ctx.sp, ctx.rsp, miner_address);
|
||||
}
|
||||
|
||||
WLT_LOG_L0("PoS mining iteration finished, status: " << ctx.rsp.status << ", used " << ctx.sp.pos_entries.size() << " entries with total amount: " << print_money_brief(pos_entries_amount));
|
||||
WLT_LOG_L0("PoS mining: " << ctx.rsp.iterations_processed << " iterations finished, status: " << ctx.rsp.status << ", used " << ctx.sp.pos_entries.size() << " entries with total amount: " << print_money_brief(pos_entries_amount));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3533,12 +3611,11 @@ bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request&
|
|||
const currency::txout_to_key& txtokey = boost::get<currency::txout_to_key>(target);
|
||||
keys_ptrs.push_back(&txtokey.key);
|
||||
|
||||
//put actual time for tx block
|
||||
// set a real timestamp
|
||||
b.timestamp = rsp.block_timestamp;
|
||||
currency::etc_tx_time tt = AUTO_VAL_INIT(tt);
|
||||
tt.v = m_core_runtime_config.get_core_time();
|
||||
b.miner_tx.extra.push_back(tt);
|
||||
WLT_LOG_MAGENTA("Applying actual timestamp: " << epee::misc_utils::get_time_str(tt.v), LOG_LEVEL_0);
|
||||
uint64_t current_timestamp = m_core_runtime_config.get_core_time();
|
||||
set_block_datetime(current_timestamp, b);
|
||||
WLT_LOG_MAGENTA("Applying actual timestamp: " << current_timestamp, LOG_LEVEL_0);
|
||||
|
||||
//sign block
|
||||
res = prepare_and_sign_pos_block(b,
|
||||
|
|
@ -3564,14 +3641,7 @@ bool wallet2::build_minted_block(const currency::COMMAND_RPC_SCAN_POS::request&
|
|||
}
|
||||
WLT_LOG_GREEN("POS block generated and accepted, congrats!", LOG_LEVEL_0);
|
||||
m_wcallback->on_pos_block_found(b);
|
||||
//@#@
|
||||
//double check timestamp
|
||||
if (time(NULL) - static_cast<int64_t>(get_actual_timestamp(b)) > 5)
|
||||
{
|
||||
WLT_LOG_RED("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) << ")", LOG_LEVEL_0);
|
||||
}
|
||||
//
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -861,6 +861,8 @@ namespace tools
|
|||
uint64_t get_wallet_file_size()const;
|
||||
void set_use_deffered_global_outputs(bool use);
|
||||
construct_tx_param get_default_construct_tx_param_inital();
|
||||
|
||||
void export_transaction_history(std::ostream& ss, const std::string& format, bool include_pos_transactions = true);
|
||||
|
||||
/*
|
||||
create_htlc_proposal: if htlc_hash == null_hash, then this wallet is originator of the atomic process, and
|
||||
|
|
@ -872,7 +874,6 @@ namespace tools
|
|||
void redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin, currency::transaction& result_tx);
|
||||
void redeem_htlc(const crypto::hash& htlc_tx_id, const std::string& origin);
|
||||
bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id);
|
||||
|
||||
private:
|
||||
|
||||
void add_transfers_to_expiration_list(const std::vector<uint64_t>& selected_transfers, uint64_t expiration, uint64_t change_amount, const crypto::hash& related_tx_id);
|
||||
|
|
@ -920,7 +921,7 @@ private:
|
|||
void handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop,
|
||||
currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& blocks);
|
||||
std::string get_alias_for_address(const std::string& addr);
|
||||
static bool build_kernel(const currency::pos_entry& pe, const currency::stake_modifier_type& stake_modifier, currency::stake_kernel& kernel, uint64_t& coindays_weight, uint64_t timestamp);
|
||||
static bool build_kernel(const currency::pos_entry& pe, const currency::stake_modifier_type& stake_modifier, const uint64_t timestamp, currency::stake_kernel& kernel);
|
||||
bool is_connected_to_net();
|
||||
bool is_transfer_okay_for_pos(const transfer_details& tr, uint64_t& stake_unlock_time);
|
||||
bool scan_unconfirmed_outdate_tx();
|
||||
|
|
@ -1006,6 +1007,10 @@ private:
|
|||
void push_alias_info_to_extra_according_to_hf_status(const currency::extra_alias_entry& ai, std::vector<currency::extra_v>& extra);
|
||||
void remove_transfer_from_amount_gindex_map(uint64_t tid);
|
||||
|
||||
static void wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);
|
||||
static void wti_to_txt_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);
|
||||
static void wti_to_json_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);
|
||||
|
||||
currency::account_base m_account;
|
||||
bool m_watch_only;
|
||||
std::string m_log_prefix; // part of pub address, prefix for logging functions
|
||||
|
|
@ -1203,16 +1208,20 @@ namespace tools
|
|||
const currency::core_runtime_config &runtime_config)
|
||||
{
|
||||
cxt.rsp.status = API_RETURN_CODE_NOT_FOUND;
|
||||
uint64_t timstamp_start = runtime_config.get_core_time();
|
||||
uint64_t timstamp_last_idle_call = runtime_config.get_core_time();
|
||||
cxt.rsp.iterations_processed = 0;
|
||||
|
||||
uint64_t ts_from = cxt.rsp.starter_timestamp; // median ts of last BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW blocks
|
||||
ts_from = ts_from - (ts_from % POS_SCAN_STEP) + POS_SCAN_STEP;
|
||||
uint64_t ts_to = runtime_config.get_core_time() + CURRENCY_POS_BLOCK_FUTURE_TIME_LIMIT - 5;
|
||||
ts_to = ts_to - (ts_to % POS_SCAN_STEP);
|
||||
CHECK_AND_ASSERT_MES(ts_to > ts_from, false, "scan_pos: ts_to <= ts_from: " << ts_to << ", " << ts_from);
|
||||
uint64_t ts_middle = (ts_to + ts_from) / 2;
|
||||
ts_middle -= ts_middle % POS_SCAN_STEP;
|
||||
uint64_t ts_window = std::min(ts_middle - ts_from, ts_to - ts_middle);
|
||||
|
||||
for (size_t i = 0; i != cxt.sp.pos_entries.size(); i++)
|
||||
{
|
||||
//set timestamp starting from timestamp%POS_SCAN_STEP = 0
|
||||
uint64_t adjusted_starter_timestamp = timstamp_start - POS_SCAN_STEP;
|
||||
adjusted_starter_timestamp = POS_SCAN_STEP * 2 - (adjusted_starter_timestamp%POS_SCAN_STEP) + adjusted_starter_timestamp;
|
||||
|
||||
bool go_past = true;
|
||||
uint64_t step = 0;
|
||||
|
||||
|
|
@ -1232,7 +1241,7 @@ namespace tools
|
|||
}
|
||||
};
|
||||
|
||||
while(step <= POS_SCAN_WINDOW)
|
||||
while(step <= ts_window)
|
||||
{
|
||||
|
||||
//check every WALLET_POS_MINT_CHECK_HEIGHT_INTERVAL seconds if top block changes, in case - break loop
|
||||
|
|
@ -1248,8 +1257,8 @@ namespace tools
|
|||
}
|
||||
|
||||
|
||||
uint64_t ts = go_past ? adjusted_starter_timestamp - step : adjusted_starter_timestamp + step;
|
||||
if (ts < cxt.rsp.starter_timestamp)
|
||||
uint64_t ts = go_past ? ts_middle - step : ts_middle + step;
|
||||
if (ts < ts_from || ts > ts_to)
|
||||
{
|
||||
next_turn();
|
||||
continue;
|
||||
|
|
@ -1258,27 +1267,27 @@ namespace tools
|
|||
if (stop)
|
||||
return false;
|
||||
currency::stake_kernel sk = AUTO_VAL_INIT(sk);
|
||||
uint64_t coindays_weight = 0;
|
||||
build_kernel(cxt.sp.pos_entries[i], cxt.sm, sk, coindays_weight, ts);
|
||||
const uint64_t& stake_amount = cxt.sp.pos_entries[i].amount;
|
||||
build_kernel(cxt.sp.pos_entries[i], cxt.sm, ts, sk);
|
||||
crypto::hash kernel_hash;
|
||||
{
|
||||
PROFILE_FUNC("calc_hash");
|
||||
kernel_hash = crypto::cn_fast_hash(&sk, sizeof(sk));
|
||||
}
|
||||
|
||||
currency::wide_difficulty_type this_coin_diff = cxt.basic_diff / coindays_weight;
|
||||
currency::wide_difficulty_type final_diff = cxt.basic_diff / stake_amount;
|
||||
bool check_hash_res;
|
||||
{
|
||||
PROFILE_FUNC("check_hash");
|
||||
check_hash_res = currency::check_hash(kernel_hash, this_coin_diff);
|
||||
check_hash_res = currency::check_hash(kernel_hash, final_diff);
|
||||
++cxt.rsp.iterations_processed;
|
||||
}
|
||||
if (check_hash_res)
|
||||
{
|
||||
//found kernel
|
||||
LOG_PRINT_GREEN("Found kernel: amount=" << currency::print_money(cxt.sp.pos_entries[i].amount) << ENDL
|
||||
<< "difficulty_basic=" << cxt.basic_diff << ", diff for this coin: " << this_coin_diff << ENDL
|
||||
<< "index=" << cxt.sp.pos_entries[i].index << ENDL
|
||||
LOG_PRINT_GREEN("Found kernel: amount: " << currency::print_money(stake_amount) << ENDL
|
||||
<< "difficulty: " << cxt.basic_diff << ", final_diff: " << final_diff << ENDL
|
||||
<< "index: " << cxt.sp.pos_entries[i].index << ENDL
|
||||
<< "kernel info: " << ENDL
|
||||
<< print_stake_kernel_info(sk) << ENDL
|
||||
<< "kernel_hash(proof): " << kernel_hash,
|
||||
|
|
|
|||
|
|
@ -56,7 +56,11 @@ namespace tools
|
|||
command_line::add_arg(desc, arg_deaf_mode);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
wallet_rpc_server::wallet_rpc_server(wallet2& w):m_wallet(w), m_do_mint(false), m_deaf(false)
|
||||
wallet_rpc_server::wallet_rpc_server(wallet2& w)
|
||||
: m_wallet(w)
|
||||
, m_do_mint(false)
|
||||
, m_deaf(false)
|
||||
, m_last_wallet_store_height(0)
|
||||
{}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::run(bool do_mint, bool offline_mode, const currency::account_public_address& miner_address)
|
||||
|
|
@ -91,6 +95,18 @@ namespace tools
|
|||
LOG_PRINT_L2("wallet RPC idle: trying to do PoS iteration...");
|
||||
m_wallet.try_mint_pos(miner_address);
|
||||
}
|
||||
|
||||
//auto-store wallet in server mode, let's do it every 24-hour
|
||||
if (m_wallet.get_top_block_height() < m_last_wallet_store_height)
|
||||
{
|
||||
LOG_ERROR("Unexpected m_last_wallet_store_height = " << m_last_wallet_store_height << " or " << m_wallet.get_top_block_height());
|
||||
}
|
||||
else if (m_wallet.get_top_block_height() - m_last_wallet_store_height > CURRENCY_BLOCKS_PER_DAY)
|
||||
{
|
||||
//store wallet
|
||||
m_wallet.store();
|
||||
m_last_wallet_store_height = m_wallet.get_top_block_height();
|
||||
}
|
||||
}
|
||||
catch (error::no_connection_to_daemon&)
|
||||
{
|
||||
|
|
@ -132,6 +148,7 @@ namespace tools
|
|||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::init(const boost::program_options::variables_map& vm)
|
||||
{
|
||||
m_last_wallet_store_height = m_wallet.get_top_block_height();
|
||||
m_net_server.set_threads_prefix("RPC");
|
||||
bool r = handle_command_line(vm);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to process command line in core_rpc_server");
|
||||
|
|
@ -296,7 +313,7 @@ namespace tools
|
|||
else
|
||||
{
|
||||
//put it to attachments
|
||||
ctp.attachments.insert(ctp.extra.end(), req.service_entries.begin(), req.service_entries.end());
|
||||
ctp.attachments.insert(ctp.attachments.end(), req.service_entries.begin(), req.service_entries.end());
|
||||
}
|
||||
bool wrap = false;
|
||||
std::vector<currency::tx_destination_entry>& dsts = ctp.dsts;
|
||||
|
|
@ -384,7 +401,7 @@ namespace tools
|
|||
currency::finalized_tx result = AUTO_VAL_INIT(result);
|
||||
std::string unsigned_tx_blob_str;
|
||||
ctp.fee = req.fee;
|
||||
ctp.fake_outputs_count = 0;
|
||||
ctp.fake_outputs_count = req.mixin;
|
||||
m_wallet.transfer(ctp, result, true, &unsigned_tx_blob_str);
|
||||
if (m_wallet.is_watch_only())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -118,6 +118,7 @@ namespace tools
|
|||
std::string m_bind_ip;
|
||||
bool m_do_mint;
|
||||
bool m_deaf;
|
||||
uint64_t m_last_wallet_store_height;
|
||||
};
|
||||
|
||||
} // namespace tools
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ bool wallets_manager::do_exception_safe_call(guarded_code_t guarded_code, error_
|
|||
}
|
||||
|
||||
|
||||
bool wallets_manager::init_command_line(int argc, char* argv[])
|
||||
bool wallets_manager::init_command_line(int argc, char* argv[], std::string& fail_message)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
po::options_description desc_cmd_only("Command line options");
|
||||
|
|
@ -197,9 +197,8 @@ bool wallets_manager::init_command_line(int argc, char* argv[])
|
|||
po::options_description desc_options("Allowed options");
|
||||
desc_options.add(desc_cmd_only).add(desc_cmd_sett);
|
||||
|
||||
|
||||
|
||||
bool coomand_line_parsed = command_line::handle_error_helper(desc_options, [&]()
|
||||
std::string err_str;
|
||||
bool command_line_parsed = command_line::handle_error_helper(desc_options, err_str, [&]()
|
||||
{
|
||||
po::store(po::parse_command_line(argc, argv, desc_options), m_vm);
|
||||
|
||||
|
|
@ -230,23 +229,29 @@ bool wallets_manager::init_command_line(int argc, char* argv[])
|
|||
return true;
|
||||
});
|
||||
|
||||
if (!coomand_line_parsed)
|
||||
if (!command_line_parsed)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Command line has wrong arguments: " << std::endl;
|
||||
for (int i = 0; i != argc; i++)
|
||||
ss << "[" << i << "] " << argv[i] << std::endl;
|
||||
std::cerr << ss.str() << std::endl << std::flush;
|
||||
|
||||
fail_message = "Error parsing arguments.\n";
|
||||
fail_message += err_str + "\n";
|
||||
std::stringstream s;
|
||||
desc_options.print(s);
|
||||
fail_message += s.str();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_qt_logs_enbaled = command_line::get_arg(m_vm, arg_enable_qt_logs);
|
||||
m_qt_dev_tools = command_line::get_arg(m_vm, arg_qt_dev_tools);
|
||||
|
||||
return true;
|
||||
CATCH_ENTRY2(false);
|
||||
}
|
||||
|
||||
|
||||
void terminate_handler_func()
|
||||
{
|
||||
LOG_ERROR("\n\nTERMINATE HANDLER\n"); // should print callstack
|
||||
|
|
@ -798,6 +803,24 @@ std::string wallets_manager::get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INF
|
|||
}
|
||||
|
||||
|
||||
std::string wallets_manager::export_wallet_history(const view::export_wallet_info& ewi)
|
||||
{
|
||||
GET_WALLET_OPT_BY_ID(ewi.wallet_id, wo);
|
||||
try {
|
||||
|
||||
boost::filesystem::ofstream fstream;
|
||||
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fstream.open(ewi.path, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
|
||||
wo.w->get()->export_transaction_history(fstream, ewi.format, ewi.include_pos_transactions);
|
||||
fstream.close();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return API_RETURN_CODE_FAIL;
|
||||
}
|
||||
return API_RETURN_CODE_OK;
|
||||
}
|
||||
|
||||
uint64_t wallets_manager::get_default_fee()
|
||||
{
|
||||
return TX_DEFAULT_FEE;
|
||||
|
|
@ -1802,7 +1825,10 @@ void wallets_manager::on_transfer2(size_t wallet_id, const tools::wallet_public:
|
|||
|
||||
GET_WALLET_OPTIONS_BY_ID_VOID_RET(wallet_id, w);
|
||||
tei.is_wallet_in_sync_process = w.long_refresh_in_progress;
|
||||
m_pview->money_transfer(tei);
|
||||
if (!(w.w->get()->is_watch_only()))
|
||||
{
|
||||
m_pview->money_transfer(tei);
|
||||
}
|
||||
}
|
||||
void wallets_manager::on_pos_block_found(size_t wallet_id, const currency::block& b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public:
|
|||
|
||||
wallets_manager();
|
||||
~wallets_manager();
|
||||
bool init_command_line(int argc, char* argv[]);
|
||||
bool init_command_line(int argc, char* argv[], std::string& fail_message);
|
||||
bool init(view::i_view* pview_handler);
|
||||
bool start();
|
||||
bool stop();
|
||||
|
|
@ -139,6 +139,7 @@ public:
|
|||
std::string get_my_offers(const bc_services::core_offers_filter& filter, std::list<bc_services::offer_details_ex>& offers);
|
||||
std::string get_fav_offers(const std::list<bc_services::offer_id>& hashes, const bc_services::core_offers_filter& filter, std::list<bc_services::offer_details_ex>& offers);
|
||||
std::string get_tx_pool_info(currency::COMMAND_RPC_GET_POOL_INFO::response& res);
|
||||
std::string export_wallet_history(const view::export_wallet_info& ewi);
|
||||
uint64_t get_default_fee();
|
||||
std::string get_mining_estimate(uint64_t amuont_coins,
|
||||
uint64_t time,
|
||||
|
|
|
|||
|
|
@ -563,17 +563,15 @@ bool test_generator::find_kernel(const std::list<currency::account_base>& accs,
|
|||
{
|
||||
|
||||
stake_kernel sk = AUTO_VAL_INIT(sk);
|
||||
uint64_t coindays_weight = 0;
|
||||
build_kernel(scan_pos_entries.pos_entries[i].amount,
|
||||
scan_pos_entries.pos_entries[i].index,
|
||||
scan_pos_entries.pos_entries[i].keyimage,
|
||||
sk,
|
||||
coindays_weight,
|
||||
blck_chain,
|
||||
indexes,
|
||||
ts);
|
||||
crypto::hash kernel_hash = crypto::cn_fast_hash(&sk, sizeof(sk));
|
||||
wide_difficulty_type this_coin_diff = basic_diff / coindays_weight;
|
||||
wide_difficulty_type this_coin_diff = basic_diff / scan_pos_entries.pos_entries[i].amount;
|
||||
if (!check_hash(kernel_hash, this_coin_diff))
|
||||
continue;
|
||||
else
|
||||
|
|
@ -672,12 +670,10 @@ bool test_generator::build_kernel(uint64_t amount,
|
|||
uint64_t global_index,
|
||||
const crypto::key_image& ki,
|
||||
stake_kernel& kernel,
|
||||
uint64_t& coindays_weight,
|
||||
const test_generator::blockchain_vector& blck_chain,
|
||||
const test_generator::outputs_index& indexes,
|
||||
uint64_t timestamp)
|
||||
{
|
||||
coindays_weight = 0;
|
||||
kernel = stake_kernel();
|
||||
kernel.kimage = ki;
|
||||
|
||||
|
|
@ -701,7 +697,6 @@ bool test_generator::build_kernel(uint64_t amount,
|
|||
|
||||
kernel.block_timestamp = timestamp;
|
||||
|
||||
coindays_weight = get_coinday_weight(amount);
|
||||
build_stake_modifier(kernel.stake_modifier, blck_chain);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2058,6 +2053,25 @@ bool check_ring_signature_at_gen_time(const std::vector<test_event_entry>& event
|
|||
return true;
|
||||
}
|
||||
|
||||
bool check_mixin_value_for_each_input(size_t mixin, const crypto::hash& tx_id, currency::core& c)
|
||||
{
|
||||
std::shared_ptr<const currency::transaction_chain_entry> ptce = c.get_blockchain_storage().get_tx_chain_entry(tx_id);
|
||||
if (!ptce)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < ptce->tx.vin.size(); ++i)
|
||||
{
|
||||
auto& input = ptce->tx.vin[i];
|
||||
if (input.type() == typeid(txin_to_key))
|
||||
{
|
||||
auto& intk = boost::get<txin_to_key>(input);
|
||||
CHECK_AND_ASSERT_MES(intk.key_offsets.size() == mixin + 1, false, "for input #" << i << " mixin count is " << intk.key_offsets.size() - 1 << ", expected is " << mixin);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void test_chain_unit_base::register_callback(const std::string& cb_name, verify_callback cb)
|
||||
|
|
|
|||
|
|
@ -410,7 +410,6 @@ public:
|
|||
uint64_t global_index,
|
||||
const crypto::key_image& ki,
|
||||
currency::stake_kernel& kernel,
|
||||
uint64_t& coindays_weight,
|
||||
const blockchain_vector& blck_chain,
|
||||
const outputs_index& indexes,
|
||||
uint64_t timestamp);
|
||||
|
|
@ -680,6 +679,7 @@ bool generate_pos_block_with_given_coinstake(test_generator& generator, const st
|
|||
bool check_ring_signature_at_gen_time(const std::vector<test_event_entry>& events, const crypto::hash& last_block_id, const currency::txin_to_key& in_t_k,
|
||||
const crypto::hash& hash_for_sig, const std::vector<crypto::signature> &sig);
|
||||
|
||||
bool check_mixin_value_for_each_input(size_t mixin, const crypto::hash& tx_id, currency::core& c);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
template<class t_test_class>
|
||||
|
|
|
|||
|
|
@ -867,6 +867,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
GENERATE_AND_PLAY(wallet_rpc_integrated_address);
|
||||
GENERATE_AND_PLAY(wallet_rpc_integrated_address_transfer);
|
||||
GENERATE_AND_PLAY(wallet_rpc_transfer);
|
||||
GENERATE_AND_PLAY(wallet_chain_switch_with_spending_the_same_ki);
|
||||
GENERATE_AND_PLAY(wallet_sending_to_integrated_address);
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ bool emission_test::c1(currency::core& c, size_t ev_index, const std::vector<tes
|
|||
pb.step2_set_txs(std::vector<transaction>());
|
||||
pb.step3_build_stake_kernel(stake_output_amount, stake_output_gidx, stake_output_key_image, difficulty, prev_id, null_hash, timestamp);
|
||||
pb.step4_generate_coinbase_tx(0, already_generated_coins, m_miner_acc.get_public_address());
|
||||
pb.m_block.miner_tx.extra.push_back(currency::etc_tx_time({ timestamp })); // actual timestamp
|
||||
set_block_datetime(timestamp, pb.m_block);
|
||||
pb.step5_sign(stake_tx_pub_key, stake_output_idx, stake_output_pubkey, m_miner_acc);
|
||||
|
||||
c.handle_incoming_block(t_serializable_object_to_blob(pb.m_block), bvc);
|
||||
|
|
|
|||
|
|
@ -634,7 +634,7 @@ bool hard_fork_1_pos_and_locked_coins::generate(std::vector<test_event_entry>& e
|
|||
{
|
||||
MAKE_NEXT_POS_BLOCK(events, b, prev, miner_acc, std::list<currency::account_base>{miner_acc});
|
||||
prev = b;
|
||||
events.push_back(event_core_time(get_actual_timestamp(b) + 100));
|
||||
events.push_back(event_core_time(get_block_datetime(b) + 100));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@ isolate_auditable_and_proof::isolate_auditable_and_proof()
|
|||
|
||||
bool isolate_auditable_and_proof::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
// Test outline: this test makes sure:
|
||||
// 1) that only owner of the secret spend key can decode the attachment (TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE)
|
||||
// 2) TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF -- add public hash of original info
|
||||
|
||||
random_state_test_restorer::reset_random(0); // to make the test deterministic
|
||||
m_genesis_timestamp = 1450000000;
|
||||
test_core_time::adjust(m_genesis_timestamp);
|
||||
|
|
@ -87,7 +91,7 @@ bool isolate_auditable_and_proof::c1(currency::core& c, size_t ev_index, const s
|
|||
tx_service_attachment sa = AUTO_VAL_INIT(sa);
|
||||
sa.service_id = BC_WRAP_SERVICE_ID;
|
||||
sa.instruction = BC_WRAP_SERVICE_INSTRUCTION_ERC20;
|
||||
sa.flags = TX_SERVICE_ATTACHMENT_ENCRYPT_BODY | TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE| TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF;
|
||||
sa.flags = TX_SERVICE_ATTACHMENT_ENCRYPT_BODY | TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE | TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF;
|
||||
sa.body = "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B";
|
||||
extra.push_back(sa);
|
||||
|
||||
|
|
@ -122,4 +126,3 @@ bool isolate_auditable_and_proof::c1(currency::core& c, size_t ev_index, const s
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ bool wallet_rpc_integrated_address_transfer::c1(currency::core& c, size_t ev_ind
|
|||
alice_wlt->get_payments(payment_id, payments);
|
||||
CHECK_AND_ASSERT_MES(payments.size() == 1, false, "Invalid payments count: " << payments.size());
|
||||
CHECK_AND_ASSERT_MES(payments.front().m_amount == MK_TEST_COINS(3), false, "Invalid payment");
|
||||
CHECK_AND_ASSERT_MES(check_mixin_value_for_each_input(0, payments.front().m_tx_hash, c), false, ""); // make sure number of decoys is correct
|
||||
|
||||
|
||||
// 3. standard address + invalid external payment id => fail
|
||||
|
|
@ -181,9 +182,127 @@ bool wallet_rpc_integrated_address_transfer::c1(currency::core& c, size_t ev_ind
|
|||
alice_wlt->get_payments(payment_id, payments);
|
||||
CHECK_AND_ASSERT_MES(payments.size() == 1, false, "Invalid payments count: " << payments.size());
|
||||
CHECK_AND_ASSERT_MES(payments.front().m_amount == MK_TEST_COINS(7), false, "Invalid payment");
|
||||
CHECK_AND_ASSERT_MES(check_mixin_value_for_each_input(0, payments.front().m_tx_hash, c), false, ""); // make sure number of decoys is correct
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
wallet_rpc_transfer::wallet_rpc_transfer()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(wallet_rpc_transfer, configure_core);
|
||||
REGISTER_CALLBACK_METHOD(wallet_rpc_transfer, c1);
|
||||
}
|
||||
|
||||
bool wallet_rpc_transfer::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate();
|
||||
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate();
|
||||
account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate();
|
||||
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time());
|
||||
DO_CALLBACK(events, "configure_core");
|
||||
set_hard_fork_heights_to_generator(generator);
|
||||
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 6);
|
||||
|
||||
DO_CALLBACK(events, "c1");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wallet_rpc_transfer::configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
currency::core_runtime_config pc = c.get_blockchain_storage().get_core_runtime_config();
|
||||
pc.hard_fork_01_starts_after_height = 1;
|
||||
pc.hard_fork_02_starts_after_height = 1;
|
||||
pc.hard_fork_03_starts_after_height = 1;
|
||||
c.get_blockchain_storage().set_core_runtime_config(pc);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wallet_rpc_transfer::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
bool r = false;
|
||||
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX);
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
|
||||
|
||||
miner_wlt->refresh();
|
||||
|
||||
// wallet RPC server
|
||||
tools::wallet_rpc_server miner_wlt_rpc(*miner_wlt);
|
||||
epee::json_rpc::error je;
|
||||
tools::wallet_rpc_server::connection_context ctx;
|
||||
|
||||
// 1. Check non-zero mixin and default settings
|
||||
tools::wallet_public::COMMAND_RPC_TRANSFER::request req = AUTO_VAL_INIT(req);
|
||||
req.fee = TESTS_DEFAULT_FEE;
|
||||
req.mixin = 2;
|
||||
tools::wallet_public::transfer_destination tds = AUTO_VAL_INIT(tds);
|
||||
tds.address = m_accounts[ALICE_ACC_IDX].get_public_address_str();
|
||||
tds.amount = MK_TEST_COINS(3);
|
||||
req.destinations.push_back(tds);
|
||||
|
||||
tools::wallet_public::COMMAND_RPC_TRANSFER::response res = AUTO_VAL_INIT(res);
|
||||
|
||||
r = miner_wlt_rpc.on_transfer(req, res, je, ctx);
|
||||
CHECK_AND_ASSERT_MES(r, false, "RPC call failed, code: " << je.code << ", msg: " << je.message);
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "enexpected pool txs count: " << c.get_pool_transactions_count());
|
||||
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Tx pool is not empty: " << c.get_pool_transactions_count());
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt, tds.amount), false, "");
|
||||
|
||||
// check the transfer has been received
|
||||
tools::wallet2::transfer_details td = AUTO_VAL_INIT(td);
|
||||
CHECK_AND_ASSERT_MES(alice_wlt->get_transfer_info_by_index(0, td), false, "");
|
||||
CHECK_AND_ASSERT_MES(td.amount() == MK_TEST_COINS(3), false, "Invalid payment");
|
||||
CHECK_AND_ASSERT_MES(check_mixin_value_for_each_input(2, td.tx_hash(), c), false, "");
|
||||
|
||||
// make sure tx_received is set by default, but tx_payer is not
|
||||
std::shared_ptr<const transaction_chain_entry> pche = c.get_blockchain_storage().get_tx_chain_entry(td.tx_hash());
|
||||
CHECK_AND_ASSERT_MES(currency::count_type_in_variant_container<tx_receiver>(pche->tx.extra) == 1, false, "tx_receiver: incorrect count of items");
|
||||
CHECK_AND_ASSERT_MES(currency::count_type_in_variant_container<tx_payer>(pche->tx.extra) == 0, false, "tx_payer: incorrect count of items");
|
||||
|
||||
|
||||
// 2. check tx_receiver and tx_payer non-default
|
||||
req.mixin = 1;
|
||||
req.hide_receiver = true;
|
||||
req.push_payer = true;
|
||||
tds.amount = MK_TEST_COINS(5);
|
||||
req.destinations.clear();
|
||||
req.destinations.push_back(tds);
|
||||
|
||||
res = AUTO_VAL_INIT(res);
|
||||
|
||||
r = miner_wlt_rpc.on_transfer(req, res, je, ctx);
|
||||
CHECK_AND_ASSERT_MES(r, false, "RPC call failed, code: " << je.code << ", msg: " << je.message);
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 1, false, "enexpected pool txs count: " << c.get_pool_transactions_count());
|
||||
|
||||
r = mine_next_pow_block_in_playtime(m_accounts[MINER_ACC_IDX].get_public_address(), c);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime failed");
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Tx pool is not empty: " << c.get_pool_transactions_count());
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt, MK_TEST_COINS(3 + 5)), false, "");
|
||||
|
||||
td = AUTO_VAL_INIT(td);
|
||||
CHECK_AND_ASSERT_MES(alice_wlt->get_transfer_info_by_index(1, td), false, "");
|
||||
CHECK_AND_ASSERT_MES(td.amount() == MK_TEST_COINS(5), false, "Invalid payment");
|
||||
CHECK_AND_ASSERT_MES(check_mixin_value_for_each_input(1, td.tx_hash(), c), false, "");
|
||||
|
||||
// make sure tx_received is set by default, but tx_payer is not
|
||||
pche = c.get_blockchain_storage().get_tx_chain_entry(td.tx_hash());
|
||||
CHECK_AND_ASSERT_MES(currency::count_type_in_variant_container<tx_receiver>(pche->tx.extra) == 0, false, "tx_receiver: incorrect count of items");
|
||||
CHECK_AND_ASSERT_MES(currency::count_type_in_variant_container<tx_payer>(pche->tx.extra) == 1, false, "tx_payer: incorrect count of items");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,3 +21,11 @@ struct wallet_rpc_integrated_address_transfer : public wallet_test
|
|||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
|
||||
struct wallet_rpc_transfer : public wallet_test
|
||||
{
|
||||
wallet_rpc_transfer();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1365,7 +1365,7 @@ bool gen_wallet_transfers_and_chain_switch::generate(std::vector<test_event_entr
|
|||
CHECK_AND_ASSERT_MES(trs.size() == 2 && trs[0].is_spent() && trs[1].is_spent(), false, "Wrong transfers state");
|
||||
|
||||
// fast forward time to make tx_1 and tx_2 outdated (blk_3 is the block where tx_2 came with)
|
||||
test_core_time::adjust(get_actual_timestamp(blk_3) + CURRENCY_MEMPOOL_TX_LIVETIME + 1);
|
||||
test_core_time::adjust(get_block_datetime(blk_3) + CURRENCY_MEMPOOL_TX_LIVETIME + 1);
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_5a, blk_4a, miner_acc);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue