forked from lthn/blockchain
Merge branch 'develop' into cryptoassets
# Conflicts: # CMakeLists.txt # README.md # contrib/epee/include/net/http_client.h # src/currency_core/blockchain_storage.cpp # src/currency_core/currency_core.cpp # src/currency_core/currency_format_utils.cpp # src/gui/qt-daemon/layout # src/rpc/core_rpc_server.cpp # src/rpc/core_rpc_server.h # src/rpc/core_rpc_server_commands_defs.h # src/version.h.in # src/wallet/wallet2.cpp # src/wallet/wallet2.h # src/wallet/wallet_public_structs_defs.h # src/wallet/wallet_rpc_server.h # tests/core_tests/chaingen.cpp # tests/core_tests/pos_validation.cpp # tests/core_tests/wallet_tests.cpp # tests/performance_tests/main.cpp
This commit is contained in:
commit
46a0db21ec
35 changed files with 831 additions and 132 deletions
|
|
@ -123,22 +123,22 @@ DISABLE_VS_WARNINGS(4100)
|
|||
|
||||
#if defined(ENABLE_LOGGING_INTERNAL)
|
||||
|
||||
#define LOG_PRINT_CHANNEL_NO_PREFIX2(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))\
|
||||
#define LOG_PRINT_CHANNEL_NO_PREFIX2(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________ << 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_CHANNEL_NO_PREFIX_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))\
|
||||
#define LOG_PRINT_CHANNEL_NO_PREFIX_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________ << 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_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))\
|
||||
#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_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))\
|
||||
#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_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))\
|
||||
#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))\
|
||||
#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_CB(log_name, x, cb) { \
|
||||
|
|
|
|||
|
|
@ -31,12 +31,20 @@
|
|||
#include "http_base.h"
|
||||
#include "net/net_utils_base.h"
|
||||
|
||||
|
||||
|
||||
template<typename typename_t>
|
||||
typename_t get_documentation_json_struct()
|
||||
{
|
||||
return AUTO_VAL_INIT_T(typename_t);
|
||||
}
|
||||
|
||||
template<typename request_t, typename response_t>
|
||||
bool auto_doc_t(const std::string& prefix_name, std::string& generate_reference)
|
||||
{
|
||||
if (!generate_reference.size()) return true;
|
||||
request_t req = AUTO_VAL_INIT(req);
|
||||
response_t res = AUTO_VAL_INIT(res);
|
||||
request_t req = get_documentation_json_struct<request_t>();
|
||||
response_t res = get_documentation_json_struct<response_t>();
|
||||
std::stringstream ss;
|
||||
ss << prefix_name << ENDL
|
||||
<< "REQUEST: " << ENDL << epee::serialization::store_t_to_json(req) << ENDL << "--------------------------------" << ENDL
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ namespace epee
|
|||
bool res = m_net_server.init_server(bind_port, bind_ip);
|
||||
if(!res)
|
||||
{
|
||||
LOG_ERROR("Failed to bind server");
|
||||
LOG_ERROR("Failed to bind to " << bind_ip << ":" << bind_port);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -74,14 +74,14 @@ namespace epee
|
|||
bool run(size_t threads_count, bool wait = true)
|
||||
{
|
||||
//go to loop
|
||||
LOG_PRINT("Run net_service loop( " << threads_count << " threads)...", LOG_LEVEL_0);
|
||||
LOG_PRINT("Run net_service loop (" << threads_count << " threads)...", LOG_LEVEL_1);
|
||||
if(!m_net_server.run_server(threads_count, wait))
|
||||
{
|
||||
LOG_ERROR("Failed to run net tcp server!");
|
||||
}
|
||||
|
||||
if(wait)
|
||||
LOG_PRINT("net_service loop stopped.", LOG_LEVEL_0);
|
||||
LOG_PRINT("net_service loop stopped.", LOG_LEVEL_1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,8 +77,7 @@ namespace epee
|
|||
bool insert_next_section(harray hSecArray, hsection& hinserted_childsection);
|
||||
//------------------------------------------------------------------------
|
||||
//delete entry (section, value or array)
|
||||
bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
|
||||
|
||||
bool delete_entry(const std::string& pentry_name, hsection hparent_section = nullptr);
|
||||
//-------------------------------------------------------------------------------
|
||||
bool store_to_binary(binarybuffer& target);
|
||||
bool load_from_binary(const binarybuffer& target);
|
||||
|
|
@ -87,6 +86,8 @@ namespace epee
|
|||
bool dump_as_json(std::string& targetObj, size_t indent = 0, end_of_line_t eol = eol_crlf);
|
||||
bool load_from_json(const std::string& source);
|
||||
|
||||
template<typename cb_t>
|
||||
bool enum_entries(hsection hparent_section, cb_t cb);
|
||||
private:
|
||||
section m_root;
|
||||
hsection get_root_section() {return &m_root;}
|
||||
|
|
@ -384,6 +385,20 @@ namespace epee
|
|||
CATCH_ENTRY("portable_storage::insert_first_value", nullptr);
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<typename cb_t>
|
||||
bool portable_storage::enum_entries(hsection hparent_section, cb_t cb)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
if (!hparent_section) hparent_section = &m_root;
|
||||
for (const auto& e : hparent_section->m_entries)
|
||||
{
|
||||
if (!cb(e.first, e.second))
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
CATCH_ENTRY("portable_storage::enum_entries", false);
|
||||
}
|
||||
|
||||
template<class t_value>
|
||||
bool portable_storage::insert_next_value(harray hval_array, const t_value& target)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <cctype>
|
||||
#include "warnings.h"
|
||||
|
||||
|
||||
|
|
@ -310,7 +311,14 @@ namespace string_encoding
|
|||
return get_md5_as_hexstring(src.data(), src.size());
|
||||
}
|
||||
#endif
|
||||
|
||||
inline
|
||||
std::string toupper(std::string s)
|
||||
{
|
||||
std::transform(s.begin(), s.end(), s.begin(),
|
||||
[](unsigned char c) { return std::toupper(c); } // correct
|
||||
);
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ namespace tools
|
|||
};
|
||||
|
||||
#ifndef TESTNET
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_1569000.pak", "c2aff6fb65c2d7a40492738c75d1d04f2f35388d3c1a664aeb77420f2d90d644", 1740147926, 3221176320 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_1569000.pak", "f673636638b666b36c976168a3c64b2fd1fcf071c41b5d9cf01ed58a5924f80a", 2244905636, 3216977920 };
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_2200000.pak", "c3bd64c62495c3f266759750952519f13f32fc161b59547beaa8202b6e26d516", 2628767033, 5100195840 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_2200000.pak", "fcbf0ab3b23836e1a51fa675e719900fb94110cfb74790b3323cebce7fb9f5bd", 3426025872, 4954472448 };
|
||||
#else
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "", "", 0, 0 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "", "", 0, 0 };
|
||||
|
|
|
|||
|
|
@ -2646,7 +2646,7 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO
|
|||
}
|
||||
if (result_outs.outs.size() < req.decoys_count)
|
||||
{
|
||||
LOG_PRINT_RED_L0("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.decoys_count << ", added " << result_outs.outs.size() << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total");
|
||||
LOG_PRINT_YELLOW("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.decoys_count << ", added " << result_outs.outs.size() << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total", LOG_LEVEL_0);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2654,7 +2654,7 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO
|
|||
size_t added = 0;
|
||||
for (size_t i = 0; i != up_index_limit; i++)
|
||||
added += add_out_to_get_random_outs(result_outs, amount, i, req.decoys_count, req.use_forced_mix_outs, req.height_upper_limit) ? 1 : 0;
|
||||
LOG_PRINT_RED_L0("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.decoys_count << ", added " << added << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total - respond with all good outs");
|
||||
LOG_PRINT_YELLOW("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.decoys_count << ", added " << added << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total - respond with all good outs", LOG_LEVEL_0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
@ -2889,6 +2889,51 @@ size_t blockchain_storage::get_current_sequence_factor_for_alt(alt_chain_type& a
|
|||
return n;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::get_pos_votes(uint64_t start_index, uint64_t end_index, vote_results& r)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
if (start_index >= m_db_blocks.size() || start_index >= end_index)
|
||||
{
|
||||
//LOG_PRINT_L0("Wrong starter or end index set: start_index = " << start_index << ", end_index=" << end_index << ", expected max index " << m_db_blocks.size() - 1);
|
||||
return true;
|
||||
}
|
||||
std::map<std::string, vote_on_proposal> summary;
|
||||
|
||||
for (size_t i = start_index; i < m_db_blocks.size() && i < end_index; i++)
|
||||
{
|
||||
auto block_ptr = m_db_blocks[i];
|
||||
//only coin holders can vote
|
||||
if(!is_pos_block(block_ptr->bl))
|
||||
continue;
|
||||
r.total_pos_blocks++;
|
||||
|
||||
extra_user_data eud = AUTO_VAL_INIT(eud);
|
||||
if (!get_type_in_variant_container(block_ptr->bl.miner_tx.extra, eud))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
std::list<std::pair<std::string, bool>> votes;
|
||||
if (!currency::parse_vote(eud.buff, votes))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for (const auto& v : votes)
|
||||
{
|
||||
if (v.second)
|
||||
summary[v.first].yes++;
|
||||
else
|
||||
summary[v.first].no++;
|
||||
}
|
||||
}
|
||||
for (const auto s_entry : summary)
|
||||
{
|
||||
r.votes.push_back(s_entry.second);
|
||||
r.votes.back().proposal_id = s_entry.first;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
std::string blockchain_storage::get_blockchain_string(uint64_t start_index, uint64_t end_index) const
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
|
|||
|
|
@ -457,6 +457,7 @@ namespace currency
|
|||
void serialize(archive_t & ar, const unsigned int version);
|
||||
bool get_est_height_from_date(uint64_t date, uint64_t& res_h)const;
|
||||
|
||||
bool get_pos_votes(uint64_t start_h, uint64_t end_h, vote_results& r);
|
||||
|
||||
//debug functions
|
||||
bool validate_blockchain_prev_links(size_t last_n_blocks_to_check = 10) const;
|
||||
|
|
|
|||
|
|
@ -159,6 +159,28 @@ namespace currency
|
|||
transactions_map onboard_transactions;
|
||||
};
|
||||
|
||||
struct vote_on_proposal
|
||||
{
|
||||
std::string proposal_id;
|
||||
uint64_t yes;
|
||||
uint64_t no;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(proposal_id)
|
||||
KV_SERIALIZE(yes)
|
||||
KV_SERIALIZE(no)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct vote_results
|
||||
{
|
||||
uint64_t total_pos_blocks; //total pos blocks in a given range
|
||||
std::list<vote_on_proposal> votes;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(total_pos_blocks)
|
||||
KV_SERIALIZE(votes)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
} // namespace currency
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ namespace currency
|
|||
ADD_CHECKPOINT(900000, "2205b73cd79d4937b087b02a8b001171b73c34464bc4a952834eaf7c2bd63e86");
|
||||
ADD_CHECKPOINT(1161000, "96990d851b484e30190678756ba2a4d3a2f92b987e2470728ac1e38b2bf35908");
|
||||
ADD_CHECKPOINT(1480000, "5dd3381eec35e8b4eba4518bfd8eec682a4292761d92218fd59b9f0ffedad3fe");
|
||||
ADD_CHECKPOINT(2000000, "7b6698a8cc279aa78d6263f01fef186bd16f5b1ea263a7f4714abc1d506b9cb3");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#define HF3_BLOCK_MINOR_VERSION 0
|
||||
#define CURRENT_BLOCK_MAJOR_VERSION 3
|
||||
|
||||
#define CURRENCY_DEFAULT_DECOY_SET_SIZE 10
|
||||
|
||||
#define CURRENT_BLOCK_MINOR_VERSION 0
|
||||
#define CURRENCY_BLOCK_FUTURE_TIME_LIMIT 60*60*2
|
||||
#define CURRENCY_POS_BLOCK_FUTURE_TIME_LIMIT 60*20
|
||||
|
|
@ -230,6 +232,7 @@
|
|||
#define GUI_INTERNAL_CONFIG2 "gui_internal_config.json"
|
||||
#define GUI_IPC_MESSAGE_CHANNEL_NAME CURRENCY_NAME_BASE "_message_que"
|
||||
|
||||
#define CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME "voting_config.json"
|
||||
|
||||
|
||||
#define CURRENT_TRANSACTION_CHAIN_ENTRY_ARCHIVE_VER 3
|
||||
|
|
|
|||
|
|
@ -504,6 +504,15 @@ namespace currency
|
|||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::add_new_block(const block& b, block_verification_context& bvc)
|
||||
{
|
||||
uint64_t h = m_blockchain_storage.get_top_block_height();
|
||||
if (m_stop_after_height != 0 && h >= m_stop_after_height)
|
||||
{
|
||||
LOG_PRINT_YELLOW("Blockchain top block height is " << h << ", the daemon will now stop as requested", LOG_LEVEL_0);
|
||||
if (m_critical_error_handler)
|
||||
return m_critical_error_handler->on_immediate_stop_requested();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool r = m_blockchain_storage.add_new_block(b, bvc);
|
||||
if (r && bvc.m_added_to_main_chain)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2751,6 +2751,35 @@ namespace currency
|
|||
return timestamp;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_vote(const std::string& json_, std::list<std::pair<std::string, bool>>& votes)
|
||||
{
|
||||
//do preliminary check of text if it looks like json
|
||||
std::string::size_type pos = json_.find('{');
|
||||
if (pos == std::string::npos)
|
||||
return false;
|
||||
std::string json = json_.substr(pos);
|
||||
|
||||
epee::serialization::portable_storage ps;
|
||||
bool rs = ps.load_from_json(json);
|
||||
if (!rs)
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
auto cb = [&](const std::string& name, const epee::serialization::storage_entry& entry) {
|
||||
if (entry.type() == typeid(uint64_t))
|
||||
{
|
||||
bool vote = boost::get<uint64_t>(entry) ? true : false;
|
||||
votes.push_back(std::make_pair(epee::string_encoding::toupper(name), vote));
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
ps.enum_entries(nullptr, cb);
|
||||
return true;
|
||||
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool sign_multisig_input_in_tx(currency::transaction& tx, size_t ms_input_index, const currency::account_keys& keys, const currency::transaction& source_tx, bool *p_is_input_fully_signed /* = nullptr */)
|
||||
{
|
||||
#define LOC_CHK(cond, msg) CHECK_AND_ASSERT_MES(cond, false, msg << ", ms input index: " << ms_input_index << ", tx: " << get_transaction_hash(tx) << ", source tx: " << get_transaction_hash(source_tx))
|
||||
|
|
|
|||
|
|
@ -446,7 +446,10 @@ namespace currency
|
|||
bool fill_block_rpc_details(block_rpc_extended_info& pei_rpc, const block_extended_info& bei_chain, const crypto::hash& h);
|
||||
void append_per_block_increments_for_tx(const transaction& tx, std::unordered_map<uint64_t, uint32_t>& gindices);
|
||||
std::string get_word_from_timstamp(uint64_t timestamp, bool use_password);
|
||||
uint64_t get_timstamp_from_word(std::string word, bool& password_used, const std::string& buff);
|
||||
uint64_t get_timstamp_from_word(std::string word, bool& password_used);
|
||||
bool parse_vote(const std::string& buff, std::list<std::pair<std::string, bool>>& votes);
|
||||
|
||||
std::string generate_origin_for_htlc(const txout_htlc& htlc, const account_keys& acc_keys);
|
||||
bool validate_ado_update_allowed(const asset_descriptor_base& a, const asset_descriptor_base& b);
|
||||
|
||||
|
|
|
|||
|
|
@ -669,6 +669,18 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_get_votes(const COMMAND_RPC_GET_VOTES::request& req, COMMAND_RPC_GET_VOTES::response& res, connection_context& cntx)
|
||||
{
|
||||
if (!m_core.get_blockchain_storage().get_pos_votes(req.h_start, req.h_end, res.votes))
|
||||
{
|
||||
res.status = API_RETURN_CODE_INTERNAL_ERROR;
|
||||
res.error_code = "Internal error";
|
||||
return true;
|
||||
}
|
||||
res.status = API_RETURN_CODE_OK;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_get_asset_info(const COMMAND_RPC_GET_ASSET_INFO::request& req, COMMAND_RPC_GET_ASSET_INFO::response& res, connection_context& cntx)
|
||||
{
|
||||
if (!m_core.get_blockchain_storage().get_asset_info(req.asset_id, res.asset_descriptor))
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ namespace currency
|
|||
bool on_get_pool_txs_brief_details(const COMMAND_RPC_GET_POOL_TXS_BRIEF_DETAILS::request& req, COMMAND_RPC_GET_POOL_TXS_BRIEF_DETAILS::response& res, connection_context& cntx);
|
||||
bool on_get_all_pool_tx_list(const COMMAND_RPC_GET_ALL_POOL_TX_LIST::request& req, COMMAND_RPC_GET_ALL_POOL_TX_LIST::response& res, connection_context& cntx);
|
||||
bool on_get_pool_info(const COMMAND_RPC_GET_POOL_INFO::request& req, COMMAND_RPC_GET_POOL_INFO::response& res, connection_context& cntx);
|
||||
bool on_get_votes(const COMMAND_RPC_GET_VOTES::request& req, COMMAND_RPC_GET_VOTES::response& res, connection_context& cntx);
|
||||
bool on_get_asset_info(const COMMAND_RPC_GET_ASSET_INFO::request& req, COMMAND_RPC_GET_ASSET_INFO::response& res, connection_context& cntx);
|
||||
|
||||
bool on_get_main_block_details(const COMMAND_RPC_GET_BLOCK_DETAILS::request& req, COMMAND_RPC_GET_BLOCK_DETAILS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
|
||||
|
|
@ -139,6 +140,7 @@ namespace currency
|
|||
MAP_JON_RPC ("get_pool_txs_brief_details", on_get_pool_txs_brief_details, COMMAND_RPC_GET_POOL_TXS_BRIEF_DETAILS)
|
||||
MAP_JON_RPC ("get_all_pool_tx_list", on_get_all_pool_tx_list, COMMAND_RPC_GET_ALL_POOL_TX_LIST)
|
||||
MAP_JON_RPC ("get_pool_info", on_get_pool_info, COMMAND_RPC_GET_POOL_INFO)
|
||||
MAP_JON_RPC ("get_votes", on_get_votes, COMMAND_RPC_GET_VOTES)
|
||||
//assets api
|
||||
MAP_JON_RPC ("get_asset_info", on_get_asset_info, COMMAND_RPC_GET_ASSET_INFO)
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,33 @@ namespace currency
|
|||
};
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_GET_VOTES
|
||||
{
|
||||
struct request
|
||||
{
|
||||
uint64_t h_start;
|
||||
uint64_t h_end;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(h_start)
|
||||
KV_SERIALIZE(h_end)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string status;
|
||||
std::string error_code;
|
||||
vote_results votes;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(status)
|
||||
KV_SERIALIZE(error_code)
|
||||
KV_SERIALIZE(votes)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
struct asset_id_kv
|
||||
{
|
||||
crypto::public_key asset_id;
|
||||
|
|
|
|||
|
|
@ -130,14 +130,16 @@ namespace
|
|||
const command_line::arg_descriptor<bool> arg_dont_refresh ( "no-refresh", "Do not refresh after load");
|
||||
const command_line::arg_descriptor<bool> arg_dont_set_date ( "no-set-creation-date", "Do not set wallet creation date", false);
|
||||
const command_line::arg_descriptor<int> arg_daemon_port ("daemon-port", "Use daemon instance at port <arg> instead of default", 0);
|
||||
const command_line::arg_descriptor<uint32_t> arg_log_level ("set-log", "");
|
||||
//const command_line::arg_descriptor<uint32_t> arg_log_level ("set-log", "");
|
||||
const command_line::arg_descriptor<bool> arg_do_pos_mining ( "do-pos-mining", "Do PoS mining", false);
|
||||
const command_line::arg_descriptor<std::string> arg_pos_mining_reward_address ( "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" );
|
||||
const command_line::arg_descriptor<std::string> arg_restore_wallet ( "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to <arg>", "" );
|
||||
const command_line::arg_descriptor<bool> arg_offline_mode ( "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)");
|
||||
const command_line::arg_descriptor<std::string> arg_scan_for_wallet ( "scan-for-wallet", "");
|
||||
const command_line::arg_descriptor<std::string> arg_addr_to_compare ( "addr-to-compare", "");
|
||||
const command_line::arg_descriptor<bool> arg_disable_tor_relay ( "disable-tor-relay", "Do PoS mining", false);
|
||||
const command_line::arg_descriptor<bool> arg_disable_tor_relay ( "disable-tor-relay", "Disable TOR relay", false);
|
||||
const command_line::arg_descriptor<unsigned int> arg_set_timeout("set-timeout", "Set timeout for the wallet");
|
||||
const command_line::arg_descriptor<std::string> arg_voting_config_file("voting-config-file", "Set voting config instead of getting if from daemon", "");
|
||||
|
||||
const command_line::arg_descriptor< std::vector<std::string> > arg_command ("command", "");
|
||||
|
||||
|
|
@ -239,6 +241,26 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
void display_vote_info(tools::wallet2& w)
|
||||
{
|
||||
const tools::wallet_public::wallet_vote_config& votes = w.get_current_votes();
|
||||
if (votes.entries.size())
|
||||
{
|
||||
message_writer(epee::log_space::console_color_magenta, true) << "VOTING SET LOADED:";
|
||||
for (const auto& e : votes.entries)
|
||||
{
|
||||
epee::log_space::console_colors color = epee::log_space::console_color_green;
|
||||
if (e.h_end < w.get_top_block_height())
|
||||
{
|
||||
color = epee::log_space::console_color_white;
|
||||
}
|
||||
|
||||
message_writer(color, true) << "\t\t" << e.proposal_id << "\t\t" << (e.vote ? "1" : "0") << "\t\t(" << e.h_start << " - " << e.h_end << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string simple_wallet::get_commands_str()
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
|
@ -264,7 +286,8 @@ simple_wallet::simple_wallet()
|
|||
m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, ph::_1), "start_mining <threads_count> - Start mining in daemon");
|
||||
m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, ph::_1), "Stop mining in daemon");
|
||||
m_cmd_binder.set_handler("refresh", boost::bind(&simple_wallet::refresh, this, ph::_1), "Resynchronize transactions and balance");
|
||||
m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, ph::_1), "Show current wallet balance");
|
||||
m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, ph::_1), "Show current wallet balance");
|
||||
m_cmd_binder.set_handler("show_staking_history", boost::bind(&simple_wallet::show_staking_history, this, ph::_1), "show_staking_history [2] - Show staking transfers, if option provided - number of days for history to display");
|
||||
m_cmd_binder.set_handler("incoming_transfers", boost::bind(&simple_wallet::show_incoming_transfers, this, ph::_1), "incoming_transfers [available|unavailable] - Show incoming transfers - all of them or filter them by availability");
|
||||
m_cmd_binder.set_handler("incoming_counts", boost::bind(&simple_wallet::show_incoming_transfers_counts, this, ph::_1), "incoming_transfers counts");
|
||||
m_cmd_binder.set_handler("list_recent_transfers", boost::bind(&simple_wallet::list_recent_transfers, this, ph::_1), "list_recent_transfers [offset] [count] - Show recent maximum 1000 transfers, offset default = 0, count default = 100 ");
|
||||
|
|
@ -355,6 +378,29 @@ bool simple_wallet::set_log(const std::vector<std::string> &args)
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void process_wallet_command_line_params(const po::variables_map& vm, tools::wallet2& wal, bool is_server_mode = true)
|
||||
{
|
||||
if (command_line::has_arg(vm, arg_disable_tor_relay))
|
||||
{
|
||||
wal.set_disable_tor_relay(command_line::get_arg(vm, arg_disable_tor_relay));
|
||||
message_writer(epee::log_space::console_color_default, true, std::string(), LOG_LEVEL_0) << "Notice: Relaying transactions over TOR disabled with command line parameter";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_server_mode)
|
||||
{
|
||||
//disable TOR by default for server-mode, to avoid potential sporadic errors due to TOR connectivity fails
|
||||
wal.set_disable_tor_relay(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (command_line::has_arg(vm, arg_set_timeout))
|
||||
{
|
||||
wal.set_connectivity_options(command_line::get_arg(vm, arg_set_timeout));
|
||||
}
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
||||
{
|
||||
handle_command_line(vm);
|
||||
|
|
@ -399,7 +445,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
|||
m_do_refresh_after_load = false;
|
||||
}
|
||||
|
||||
|
||||
bool was_open = false;
|
||||
if (!m_generate_new.empty())
|
||||
{
|
||||
bool r = new_wallet(m_generate_new, pwd_container.password(), false);
|
||||
|
|
@ -450,12 +496,14 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
|||
{
|
||||
bool r = open_wallet(m_wallet_file, pwd_container.password());
|
||||
CHECK_AND_ASSERT_MES(r, false, "could not open account");
|
||||
was_open = true;
|
||||
}
|
||||
if (m_disable_tor)
|
||||
{
|
||||
m_wallet->set_disable_tor_relay(true);
|
||||
message_writer(epee::log_space::console_color_default, true, std::string(), LOG_LEVEL_0) << "Notice: Relaying transactions over TOR disabled with command line parameter";
|
||||
}
|
||||
process_wallet_command_line_params(vm, *m_wallet, false);
|
||||
|
||||
m_wallet->init(m_daemon_address);
|
||||
|
||||
if (was_open && (m_do_refresh_after_load && !m_offline_mode))
|
||||
refresh(std::vector<std::string>());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -480,6 +528,7 @@ void simple_wallet::handle_command_line(const boost::program_options::variables_
|
|||
m_do_pos_mining = command_line::get_arg(vm, arg_do_pos_mining);
|
||||
m_restore_wallet = command_line::get_arg(vm, arg_restore_wallet);
|
||||
m_disable_tor = command_line::get_arg(vm, arg_disable_tor_relay);
|
||||
m_voting_config_file = command_line::get_arg(vm, arg_voting_config_file);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::try_connect_to_daemon()
|
||||
|
|
@ -500,18 +549,21 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
|||
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet->callback(this->shared_from_this());
|
||||
if (!m_voting_config_file.empty())
|
||||
m_wallet->set_votes_config_path(m_voting_config_file);
|
||||
|
||||
m_wallet->set_do_rise_transfer(false);
|
||||
try
|
||||
{
|
||||
m_wallet->generate(epee::string_encoding::utf8_to_wstring(m_wallet_file), password, create_auditable_wallet);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Generated new " << (create_auditable_wallet ? "AUDITABLE" : "") << " wallet: " << m_wallet->get_account().get_public_address_str();
|
||||
display_vote_info(*m_wallet);
|
||||
std::cout << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().view_secret_key) << std::endl << std::flush;
|
||||
if (m_wallet->is_auditable())
|
||||
std::cout << "tracking seed: " << std::endl << m_wallet->get_account().get_tracking_seed() << std::endl << std::flush;
|
||||
if (m_do_not_set_date)
|
||||
m_wallet->reset_creation_time(0);
|
||||
|
||||
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
|
@ -519,9 +571,6 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
|||
return false;
|
||||
}
|
||||
|
||||
m_wallet->init(m_daemon_address);
|
||||
|
||||
|
||||
success_msg_writer() <<
|
||||
"**********************************************************************\n" <<
|
||||
"Your wallet has been generated.\n" <<
|
||||
|
|
@ -535,6 +584,9 @@ bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::st
|
|||
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet->callback(this->shared_from_this());
|
||||
if (!m_voting_config_file.empty())
|
||||
m_wallet->set_votes_config_path(m_voting_config_file);
|
||||
|
||||
m_wallet->set_do_rise_transfer(true);
|
||||
try
|
||||
{
|
||||
|
|
@ -553,6 +605,7 @@ bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::st
|
|||
if (m_wallet->is_auditable())
|
||||
std::cout << "tracking seed: " << std::endl << m_wallet->get_account().get_tracking_seed() << std::endl << std::flush;
|
||||
}
|
||||
display_vote_info(*m_wallet);
|
||||
if (m_do_not_set_date)
|
||||
m_wallet->reset_creation_time(0);
|
||||
}
|
||||
|
|
@ -566,7 +619,6 @@ bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::st
|
|||
fail_msg_writer() << "failed to restore wallet, check your " << (tracking_wallet ? "tracking seed!" : "seed phrase!") << ENDL;
|
||||
return false;
|
||||
}
|
||||
m_wallet->init(m_daemon_address);
|
||||
|
||||
success_msg_writer() <<
|
||||
"**********************************************************************\n" <<
|
||||
|
|
@ -580,11 +632,15 @@ bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::st
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
bool simple_wallet::open_wallet(const string &wallet_file, const std::string& password)
|
||||
{
|
||||
m_wallet_file = wallet_file;
|
||||
m_wallet.reset(new tools::wallet2());
|
||||
m_wallet->callback(shared_from_this());
|
||||
if (!m_voting_config_file.empty())
|
||||
m_wallet->set_votes_config_path(m_voting_config_file);
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
|
@ -592,6 +648,7 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa
|
|||
{
|
||||
m_wallet->load(epee::string_encoding::utf8_to_wstring(m_wallet_file), password);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Opened" << (m_wallet->is_auditable() ? " auditable" : "") << (m_wallet->is_watch_only() ? " watch-only" : "") << " wallet: " << m_wallet->get_account().get_public_address_str();
|
||||
display_vote_info(*m_wallet);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -608,12 +665,6 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
m_wallet->init(m_daemon_address);
|
||||
|
||||
if (m_do_refresh_after_load && !m_offline_mode)
|
||||
refresh(std::vector<std::string>());
|
||||
|
||||
success_msg_writer() <<
|
||||
"**********************************************************************\n" <<
|
||||
"Use \"help\" command to see the list of available commands.\n" <<
|
||||
|
|
@ -986,15 +1037,13 @@ bool simple_wallet::list_recent_transfers(const std::vector<std::string>& args)
|
|||
success_msg_writer() << "Unconfirmed transfers: ";
|
||||
for (auto & wti : unconfirmed)
|
||||
{
|
||||
if (!wti.fee)
|
||||
wti.fee = currency::get_tx_fee(wti.tx);
|
||||
wti.fee = currency::get_tx_fee(wti.tx);
|
||||
print_wti(wti);
|
||||
}
|
||||
success_msg_writer() << "Recent transfers: ";
|
||||
for (auto & wti : recent)
|
||||
{
|
||||
if (!wti.fee)
|
||||
wti.fee = currency::get_tx_fee(wti.tx);
|
||||
wti.fee = currency::get_tx_fee(wti.tx);
|
||||
print_wti(wti);
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1066,6 +1115,70 @@ bool simple_wallet::dump_key_images(const std::vector<std::string>& args)
|
|||
success_msg_writer() << "Storing text to dump_keyimages.txt....";
|
||||
file_io_utils::save_string_to_file(log_space::log_singletone::get_default_log_folder() + "/dump_keyimages.txt", ss.str());
|
||||
success_msg_writer() << "Done....";
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::show_staking_history(const std::vector<std::string>& args)
|
||||
{
|
||||
uint64_t n_days = 0;
|
||||
if (!args.empty())
|
||||
{
|
||||
if (!epee::string_tools::get_xtype_from_string(n_days, args[0]))
|
||||
{
|
||||
fail_msg_writer() << "Unknown amount of days to list";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
tools::wallet2::transfer_container transfers;
|
||||
m_wallet->get_transfers(transfers);
|
||||
|
||||
uint64_t timestamp = 0;
|
||||
|
||||
if (n_days)
|
||||
timestamp = static_cast<uint64_t>(time(nullptr)) - (n_days * 60 * 60 * 24);
|
||||
|
||||
uint64_t amount_total_staked = 0;
|
||||
bool transfers_found = false;
|
||||
for (auto it = transfers.rbegin(); it != transfers.rend(); it++)
|
||||
{
|
||||
const auto& td = *it;
|
||||
|
||||
if (timestamp && td.m_ptx_wallet_info->m_block_timestamp < timestamp)
|
||||
break;
|
||||
|
||||
if (!(td.m_flags&WALLET_TRANSFER_DETAIL_FLAG_MINED_TRANSFER))
|
||||
continue;
|
||||
|
||||
bool pos_coinbase = false;
|
||||
is_coinbase(td.m_ptx_wallet_info->m_tx, pos_coinbase);
|
||||
if (!pos_coinbase)
|
||||
continue;
|
||||
|
||||
if (!transfers_found)
|
||||
{
|
||||
message_writer() << " amount \tspent\tglobal index\t tx id";
|
||||
transfers_found = true;
|
||||
}
|
||||
amount_total_staked += td.amount();
|
||||
message_writer(static_cast<bool>(td.m_flags&WALLET_TRANSFER_DETAIL_FLAG_SPENT) ? epee::log_space::console_color_magenta : epee::log_space::console_color_green, false) <<
|
||||
std::setw(21) << print_money(td.amount()) << '\t' <<
|
||||
std::setw(3) << (static_cast<bool>(td.m_flags&WALLET_TRANSFER_DETAIL_FLAG_SPENT) ? 'T' : 'F') << " \t" <<
|
||||
std::setw(12) << td.m_global_output_index << '\t' <<
|
||||
get_transaction_hash(td.m_ptx_wallet_info->m_tx) << "[" << td.m_ptx_wallet_info->m_block_height << "] unlocked: " << (m_wallet->is_transfer_unlocked(td) ? 'T' : 'F');
|
||||
}
|
||||
|
||||
if (!transfers_found)
|
||||
{
|
||||
success_msg_writer() << "No staking transactions";
|
||||
}
|
||||
else
|
||||
{
|
||||
success_msg_writer() << "Total staked: " << print_money(amount_total_staked);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -2447,6 +2560,7 @@ bool search_for_wallet_file(const std::wstring &search_here/*, const std::string
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
#ifdef WIN32
|
||||
int wmain( int argc, wchar_t* argv_w[ ], wchar_t* envp[ ] )
|
||||
|
|
@ -2495,7 +2609,7 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_params, arg_daemon_host);
|
||||
command_line::add_arg(desc_params, arg_daemon_port);
|
||||
command_line::add_arg(desc_params, arg_command);
|
||||
command_line::add_arg(desc_params, arg_log_level);
|
||||
//command_line::add_arg(desc_params, arg_log_level);
|
||||
command_line::add_arg(desc_params, arg_dont_refresh);
|
||||
command_line::add_arg(desc_params, arg_dont_set_date);
|
||||
command_line::add_arg(desc_params, arg_do_pos_mining);
|
||||
|
|
@ -2507,6 +2621,9 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_params, arg_scan_for_wallet);
|
||||
command_line::add_arg(desc_params, arg_addr_to_compare);
|
||||
command_line::add_arg(desc_params, arg_disable_tor_relay);
|
||||
command_line::add_arg(desc_params, arg_set_timeout);
|
||||
command_line::add_arg(desc_params, arg_voting_config_file);
|
||||
|
||||
|
||||
|
||||
tools::wallet_rpc_server::init_options(desc_params);
|
||||
|
|
@ -2544,7 +2661,7 @@ int main(int argc, char* argv[])
|
|||
return EXIT_FAILURE;
|
||||
|
||||
//set up logging options
|
||||
log_space::get_set_log_detalisation_level(true, LOG_LEVEL_2);
|
||||
log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0);
|
||||
boost::filesystem::path log_file_path(command_line::get_arg(vm, command_line::arg_log_file));
|
||||
if (log_file_path.empty())
|
||||
log_file_path = log_space::log_singletone::get_default_log_file();
|
||||
|
|
@ -2553,15 +2670,13 @@ int main(int argc, char* argv[])
|
|||
log_space::log_singletone::add_logger(LOGGER_FILE, log_file_path.filename().string().c_str(), log_dir.c_str(), LOG_LEVEL_4);
|
||||
message_writer(epee::log_space::console_color_white, true) << CURRENCY_NAME << " wallet v" << PROJECT_VERSION_LONG;
|
||||
|
||||
if (command_line::has_arg(vm, arg_log_level))
|
||||
{
|
||||
LOG_PRINT_L0("Setting log level = " << command_line::get_arg(vm, arg_log_level));
|
||||
log_space::get_set_log_detalisation_level(true, command_line::get_arg(vm, arg_log_level));
|
||||
}
|
||||
if (command_line::has_arg(vm, command_line::arg_log_level))
|
||||
{
|
||||
LOG_PRINT_L0("Setting log level = " << command_line::get_arg(vm, command_line::arg_log_level));
|
||||
log_space::get_set_log_detalisation_level(true, command_line::get_arg(vm, command_line::arg_log_level));
|
||||
int old_log_level = log_space::get_set_log_detalisation_level(false);
|
||||
int new_log_level = command_line::get_arg(vm, command_line::arg_log_level);
|
||||
log_space::get_set_log_detalisation_level(true, new_log_level);
|
||||
LOG_PRINT_L0("Log level changed: " << old_log_level << " -> " << new_log_level);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Log level changed: " << old_log_level << " -> " << new_log_level;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2582,7 +2697,7 @@ int main(int argc, char* argv[])
|
|||
// runs wallet as RPC server
|
||||
log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2);
|
||||
sw->set_offline_mode(offline_mode);
|
||||
LOG_PRINT_L0("Starting wallet RPC server...");
|
||||
LOG_PRINT_L0("Starting in RPC server mode...");
|
||||
|
||||
if (!command_line::has_arg(vm, arg_wallet_file) || command_line::get_arg(vm, arg_wallet_file).empty())
|
||||
{
|
||||
|
|
@ -2649,7 +2764,9 @@ int main(int argc, char* argv[])
|
|||
try
|
||||
{
|
||||
LOG_PRINT_L0("Initializing wallet...");
|
||||
process_wallet_command_line_params(vm, wal);
|
||||
wal.init(daemon_address);
|
||||
display_vote_info(wal);
|
||||
if (command_line::get_arg(vm, arg_generate_new_wallet).size() || command_line::get_arg(vm, arg_generate_new_auditable_wallet).size())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
|
|
@ -2680,6 +2797,8 @@ int main(int argc, char* argv[])
|
|||
LOG_PRINT_YELLOW("PoS reward will be sent to another address: " << arg_pos_mining_reward_address_str, LOG_LEVEL_0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
tools::wallet_rpc_server wrpc(wallet_ptr);
|
||||
bool r = wrpc.init(vm);
|
||||
|
|
@ -2708,7 +2827,7 @@ int main(int argc, char* argv[])
|
|||
if (command_line::get_arg(vm, arg_do_pos_mining))
|
||||
{
|
||||
// PoS mining can be turned on only in RPC server mode, please provide --rpc-bind-port to make this
|
||||
fail_msg_writer() << "PoS mining can be turned on only in RPC server mode, please provide --rpc-bind-port=PORT_NO to enable staking in simplewallet";
|
||||
fail_msg_writer() << "PoS mining can only be started in RPC server mode, please use command-line option --rpc-bind-port=<PORT_NUM> along with --do-pos-mining to enable staking";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ namespace currency
|
|||
bool dump_trunsfers(const std::vector<std::string>& args);
|
||||
bool dump_key_images(const std::vector<std::string>& args);
|
||||
bool show_incoming_transfers(const std::vector<std::string> &args);
|
||||
bool show_staking_history(const std::vector<std::string>& args);
|
||||
bool show_incoming_transfers_counts(const std::vector<std::string> &args);
|
||||
bool list_outputs(const std::vector<std::string> &args);
|
||||
bool show_payments(const std::vector<std::string> &args);
|
||||
|
|
@ -187,6 +188,7 @@ namespace currency
|
|||
bool m_offline_mode;
|
||||
bool m_disable_tor;
|
||||
std::string m_restore_wallet;
|
||||
std::string m_voting_config_file;
|
||||
|
||||
epee::console_handlers_binder m_cmd_binder;
|
||||
|
||||
|
|
|
|||
|
|
@ -184,11 +184,10 @@ namespace tools
|
|||
// m_plast_daemon_is_disconnected = plast_daemon_is_disconnected ? plast_daemon_is_disconnected : &m_last_daemon_is_disconnected_stub;
|
||||
// }
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool default_http_core_proxy::set_connectivity(unsigned int connection_timeout, size_t repeats_count)
|
||||
void default_http_core_proxy::set_connectivity(unsigned int connection_timeout, size_t repeats_count)
|
||||
{
|
||||
m_connection_timeout = connection_timeout;
|
||||
m_attempts_count = repeats_count;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
default_http_core_proxy::default_http_core_proxy(): //:m_plast_daemon_is_disconnected(&m_last_daemon_is_disconnected_stub),
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ namespace tools
|
|||
|
||||
|
||||
bool set_connection_addr(const std::string& url) override;
|
||||
bool set_connectivity(unsigned int connection_timeout, size_t repeats_count);
|
||||
void set_connectivity(unsigned int connection_timeout, size_t repeats_count);
|
||||
bool call_COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES(const currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& rqt, currency::COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& rsp) override;
|
||||
bool call_COMMAND_RPC_GET_BLOCKS_FAST(const currency::COMMAND_RPC_GET_BLOCKS_FAST::request& rqt, currency::COMMAND_RPC_GET_BLOCKS_FAST::response& rsp) override;
|
||||
bool call_COMMAND_RPC_GET_BLOCKS_DIRECT(const currency::COMMAND_RPC_GET_BLOCKS_DIRECT::request& rqt, currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& rsp) override;
|
||||
|
|
@ -56,7 +56,7 @@ namespace tools
|
|||
bool check_connection() override;
|
||||
bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id) override;
|
||||
|
||||
void set_plast_daemon_is_disconnected(std::atomic<bool> *plast_daemon_is_disconnected);
|
||||
void set_plast_daemon_is_disconnected(std::atomic<bool> *plast_daemon_is_disconnected);
|
||||
default_http_core_proxy();
|
||||
private:
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ namespace tools
|
|||
std::shared_ptr<const proxy_diagnostic_info> get_proxy_diagnostic_info() const { return m_pdiganostic_info; }
|
||||
std::shared_ptr<proxy_diagnostic_info> get_editable_proxy_diagnostic_info() { return m_pdiganostic_info; }
|
||||
virtual bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id){ return false; }
|
||||
virtual void set_connectivity(unsigned int connection_timeout, size_t repeats_count) {}
|
||||
protected:
|
||||
std::shared_ptr<proxy_diagnostic_info> m_pdiganostic_info;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ using namespace epee;
|
|||
#include "currency_core/bc_offers_service_basic.h"
|
||||
#include "rpc/core_rpc_server_commands_defs.h"
|
||||
#include "misc_language.h"
|
||||
#include "common/util.h"
|
||||
|
||||
#include "common/boost_serialization_helper.h"
|
||||
#include "crypto/crypto.h"
|
||||
|
|
@ -70,6 +71,7 @@ namespace tools
|
|||
, m_do_rise_transfer(false)
|
||||
, m_log_prefix("???")
|
||||
, m_watch_only(false)
|
||||
, m_required_decoys_count(CURRENCY_DEFAULT_DECOY_SET_SIZE)
|
||||
, m_min_utxo_count_for_defragmentation_tx(WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX)
|
||||
, m_max_utxo_count_for_defragmentation_tx(WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX)
|
||||
, m_decoys_count_for_defragmentation_tx(WALLET_DEFAULT_DECOYS_COUNT_FOR_DEFRAGMENTATION_TX)
|
||||
|
|
@ -79,6 +81,7 @@ namespace tools
|
|||
#else
|
||||
, m_disable_tor_relay(false)
|
||||
#endif
|
||||
, m_votes_config_path(tools::get_default_data_dir() + "/" + CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME)
|
||||
{
|
||||
m_core_runtime_config = currency::get_default_core_runtime_config();
|
||||
}
|
||||
|
|
@ -135,9 +138,22 @@ std::string wallet2::transfer_flags_to_str(uint32_t flags)
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::init(const std::string& daemon_address)
|
||||
{
|
||||
m_miner_text_info = PROJECT_VERSION_LONG;
|
||||
//m_miner_text_info = PROJECT_VERSION_LONG;
|
||||
m_core_proxy->set_connection_addr(daemon_address);
|
||||
m_core_proxy->check_connection();
|
||||
|
||||
std::stringstream ss;
|
||||
const tools::wallet_public::wallet_vote_config& votes = this->get_current_votes();
|
||||
if (votes.entries.size())
|
||||
{
|
||||
ss << "VOTING SET LOADED:";
|
||||
for (const auto& e : votes.entries)
|
||||
{
|
||||
ss << "\t\t" << e.proposal_id << "\t\t" << (e.vote ? "1" : "0") << "\t\t(" << e.h_start << " - " << e.h_end << ")";
|
||||
}
|
||||
}
|
||||
WLT_LOG_L0(ss.str());
|
||||
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy)
|
||||
|
|
@ -1734,7 +1750,7 @@ void wallet2::process_new_blockchain_entry(const currency::block& b, const curre
|
|||
|
||||
//optimization: seeking only for blocks that are not older then the wallet creation time plus 1 day. 1 day is for possible user incorrect time setup
|
||||
const std::vector<uint64_t>* pglobal_index = nullptr;
|
||||
if (b.timestamp + 60 * 60 * 24 > m_account.get_createtime())
|
||||
if (get_block_height(b) > get_wallet_minimum_height()) // b.timestamp + 60 * 60 * 24 > m_account.get_createtime())
|
||||
{
|
||||
pglobal_index = nullptr;
|
||||
if (bche.coinbase_ptr.get())
|
||||
|
|
@ -2996,6 +3012,19 @@ bool wallet2::check_connection()
|
|||
return m_core_proxy->check_connection();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::set_votes_config_path(const std::string& path_to_config_file/* = tools::get_default_data_dir() + "\voting_config.json"*/)
|
||||
{
|
||||
m_votes_config_path = path_to_config_file;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::load_votes_config()
|
||||
{
|
||||
if (boost::filesystem::exists(m_votes_config_path))
|
||||
{
|
||||
epee::serialization::load_t_from_json_file(m_votes_config, m_votes_config_path);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::load(const std::wstring& wallet_, const std::string& password)
|
||||
{
|
||||
clear();
|
||||
|
|
@ -3034,7 +3063,7 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password)
|
|||
{
|
||||
// old WALLET_FILE_BINARY_HEADER_VERSION version means no encryption
|
||||
need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, data_file);
|
||||
WLT_LOG_L0("Detected format: WALLET_FILE_BINARY_HEADER_VERSION_INITAL(need_to_resync=" << need_to_resync << ")");
|
||||
WLT_LOG_L1("Detected format: WALLET_FILE_BINARY_HEADER_VERSION_INITAL (need_to_resync=" << need_to_resync << ")");
|
||||
}
|
||||
else if (wbh.m_ver == WALLET_FILE_BINARY_HEADER_VERSION_2)
|
||||
{
|
||||
|
|
@ -3043,7 +3072,7 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password)
|
|||
in.push(decrypt_filter);
|
||||
in.push(data_file);
|
||||
need_to_resync = !tools::portable_unserialize_obj_from_stream(*this, in);
|
||||
WLT_LOG_L0("Detected format: WALLET_FILE_BINARY_HEADER_VERSION_2(need_to_resync=" << need_to_resync << ")");
|
||||
WLT_LOG_L1("Detected format: WALLET_FILE_BINARY_HEADER_VERSION_2 (need_to_resync=" << need_to_resync << ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -3064,10 +3093,11 @@ void wallet2::load(const std::wstring& wallet_, const std::string& password)
|
|||
<< ", file_size=" << m_current_wallet_file_size
|
||||
<< ", blockchain_size: " << m_chain.get_blockchain_current_size()
|
||||
);
|
||||
WLT_LOG_L0("[LOADING]Blockchain shortener state: " << ENDL << m_chain.get_internal_state_text());
|
||||
WLT_LOG_L1("[LOADING]Blockchain shortener state: " << ENDL << m_chain.get_internal_state_text());
|
||||
|
||||
load_votes_config();
|
||||
|
||||
WLT_LOG_L0("(after loading: pending_key_images: " << m_pending_key_images.size() << ", pki file elements: " << m_pending_key_images_file_container.size() << ", tx_keys: " << m_tx_keys.size() << ")");
|
||||
WLT_LOG_L1("(after loading: pending_key_images: " << m_pending_key_images.size() << ", pki file elements: " << m_pending_key_images_file_container.size() << ", tx_keys: " << m_tx_keys.size() << ")");
|
||||
|
||||
if (need_to_resync)
|
||||
{
|
||||
|
|
@ -3139,7 +3169,7 @@ void wallet2::store(const std::wstring& path_to_save, const std::string& passwor
|
|||
boost::uintmax_t tmp_file_size = boost::filesystem::file_size(tmp_file_path);
|
||||
WLT_LOG_L0("Stored successfully to temporary file " << tmp_file_path.string() << ", file size=" << tmp_file_size);
|
||||
|
||||
WLT_LOG_L0("[LOADING]Blockchain shortener state: " << ENDL << m_chain.get_internal_state_text());
|
||||
WLT_LOG_L1("[LOADING]Blockchain shortener state: " << ENDL << m_chain.get_internal_state_text());
|
||||
|
||||
// for the sake of safety perform a double-renaming: wallet file -> old tmp, new tmp -> wallet file, remove old tmp
|
||||
|
||||
|
|
@ -3941,7 +3971,11 @@ void wallet2::wti_to_json_line(std::ostream& ss, const wallet_public::wallet_tra
|
|||
ss << epee::serialization::store_t_to_json(wti, 4) << ",";
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::set_connectivity_options(unsigned int timeout)
|
||||
{
|
||||
m_core_proxy->set_connectivity(timeout, WALLET_RCP_COUNT_ATTEMNTS);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::export_transaction_history(std::ostream& ss, const std::string& format, bool include_pos_transactions)
|
||||
{
|
||||
|
|
@ -4113,26 +4147,100 @@ bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, uint64_t ful
|
|||
txin_to_key& stake_input = boost::get<txin_to_key>(b.miner_tx.vin[1]);
|
||||
const txout_to_key& stake_out_target = boost::get<txout_to_key>(stake_out.target);
|
||||
|
||||
// fill stake input
|
||||
// partially fill stake input
|
||||
stake_input.k_image = pe.keyimage;
|
||||
stake_input.amount = pe.amount;
|
||||
stake_input.key_offsets.push_back(pe.g_index);
|
||||
|
||||
// get decoys outputs and construct miner tx
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response decoys_resp = AUTO_VAL_INIT(decoys_resp);
|
||||
std::vector<const crypto::public_key*> ring;
|
||||
uint64_t secret_index = 0; // index of the real stake output
|
||||
if (m_required_decoys_count > 0)
|
||||
{
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request decoys_req = AUTO_VAL_INIT(decoys_req);
|
||||
decoys_req.height_upper_limit = 0; // TODO @#@# maybe use m_last_pow_block_h like Zarcanum?
|
||||
decoys_req.use_forced_mix_outs = false;
|
||||
decoys_req.decoys_count = m_required_decoys_count + 1; // one more to be able to skip a decoy in case it hits the real output
|
||||
decoys_req.amounts.push_back(pe.amount); // request one batch of decoys
|
||||
|
||||
r = m_core_proxy->call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS(decoys_req, decoys_resp);
|
||||
// TODO @#@# do we need these exceptions?
|
||||
THROW_IF_FALSE_WALLET_EX(r, error::no_connection_to_daemon, "getrandom_outs.bin");
|
||||
THROW_IF_FALSE_WALLET_EX(decoys_resp.status != API_RETURN_CODE_BUSY, error::daemon_busy, "getrandom_outs.bin");
|
||||
THROW_IF_FALSE_WALLET_EX(decoys_resp.status == API_RETURN_CODE_OK, error::get_random_outs_error, decoys_resp.status);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(decoys_resp.outs.size() == 1, "got wrong number of decoys batches: " << decoys_resp.outs.size());
|
||||
|
||||
// we expect that less decoys can be returned than requested, we will use them all anyway
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(decoys_resp.outs[0].outs.size() <= m_required_decoys_count + 1, "for PoS stake tx got greater decoys to mix than requested: " << decoys_resp.outs[0].outs.size() << " < " << m_required_decoys_count + 1);
|
||||
|
||||
auto& ring_candidates = decoys_resp.outs[0].outs;
|
||||
ring_candidates.emplace_front(td.m_global_output_index, stake_out_target.key);
|
||||
|
||||
std::unordered_set<uint64_t> used_gindices;
|
||||
size_t good_outs_count = 0;
|
||||
for(auto it = ring_candidates.begin(); it != ring_candidates.end(); )
|
||||
{
|
||||
if (used_gindices.count(it->global_amount_index) != 0)
|
||||
{
|
||||
it = ring_candidates.erase(it);
|
||||
continue;
|
||||
}
|
||||
used_gindices.insert(it->global_amount_index);
|
||||
if (++good_outs_count == m_required_decoys_count + 1)
|
||||
{
|
||||
ring_candidates.erase(++it, ring_candidates.end());
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
// won't assert that ring_candidates.size() == m_required_decoys_count + 1 here as we will use all the decoys anyway
|
||||
if (ring_candidates.size() < m_required_decoys_count + 1)
|
||||
LOG_PRINT_YELLOW("PoS: using " << ring_candidates.size() - 1 << " decoys for mining tx, while " << m_required_decoys_count << " are required", LOG_LEVEL_1);
|
||||
|
||||
ring_candidates.sort([](auto& l, auto& r){ return l.global_amount_index < r.global_amount_index; }); // sort them now (note absolute_sorted_output_offsets_to_relative_in_place() below)
|
||||
|
||||
uint64_t i = 0;
|
||||
for(auto& el : ring_candidates)
|
||||
{
|
||||
uint64_t gindex = el.global_amount_index;
|
||||
if (gindex == td.m_global_output_index)
|
||||
secret_index = i;
|
||||
++i;
|
||||
ring.emplace_back(&el.stealth_address);
|
||||
stake_input.key_offsets.push_back(el.global_amount_index);
|
||||
}
|
||||
r = absolute_sorted_output_offsets_to_relative_in_place(stake_input.key_offsets);
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(r, "absolute_sorted_output_offsets_to_relative_in_place failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
// no decoys, the ring consist of one element -- the real stake output
|
||||
ring.emplace_back(&stake_out_target.key);
|
||||
stake_input.key_offsets.push_back(td.m_global_output_index);
|
||||
}
|
||||
|
||||
// sign block actually in coinbase transaction
|
||||
crypto::hash block_hash = currency::get_block_hash(b);
|
||||
|
||||
// get stake output pub key (stealth address) for ring signature generation
|
||||
std::vector<const crypto::public_key*> keys_ptrs;
|
||||
keys_ptrs.push_back(&stake_out_target.key);
|
||||
|
||||
// generate sring signature
|
||||
sig.s.resize(1);
|
||||
crypto::generate_ring_signature(block_hash, stake_input.k_image, keys_ptrs, secret_x, 0, sig.s.data());
|
||||
sig.s.resize(ring.size());
|
||||
crypto::generate_ring_signature(block_hash, stake_input.k_image, ring, secret_x, secret_index, sig.s.data());
|
||||
|
||||
WLT_LOG_L4("GENERATED RING SIGNATURE for PoS block coinbase: block_id " << block_hash
|
||||
<< "txin.k_image" << stake_input.k_image
|
||||
<< "key_ptr:" << *keys_ptrs[0]
|
||||
<< "signature:" << sig.s);
|
||||
if (epee::log_space::get_set_log_detalisation_level() >= LOG_LEVEL_4)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "GENERATED RING SIGNATURE for PoS block coinbase:" << ENDL <<
|
||||
" block hash: " << block_hash << ENDL <<
|
||||
" key image: " << stake_input.k_image << ENDL <<
|
||||
" ring:" << ENDL;
|
||||
for(auto el: ring)
|
||||
ss << " " << *el << ENDL;
|
||||
ss << " signature:" << ENDL;
|
||||
for(auto el: sig.s)
|
||||
ss << " " << el << ENDL;
|
||||
WLT_LOG_L4(ss.str());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -4308,7 +4416,7 @@ bool wallet2::try_mint_pos(const currency::account_public_address& miner_address
|
|||
{
|
||||
TIME_MEASURE_START_MS(mining_duration_ms);
|
||||
mining_context ctx = AUTO_VAL_INIT(ctx);
|
||||
WLT_LOG_L1("Starting PoS mining iteration");
|
||||
WLT_LOG_L2("Starting PoS mining iteration");
|
||||
fill_mining_context(ctx);
|
||||
|
||||
if (!ctx.is_pos_allowed)
|
||||
|
|
@ -4380,7 +4488,31 @@ bool wallet2::build_minted_block(const mining_context& cxt)
|
|||
{
|
||||
return build_minted_block(cxt, m_account.get_public_address());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
std::string wallet2::get_extra_text_for_block(uint64_t new_block_expected_height)
|
||||
{
|
||||
size_t entries_voted = 0;
|
||||
std::string extra_text = "{";
|
||||
for (const auto& e : m_votes_config.entries)
|
||||
{
|
||||
if (e.h_start <= new_block_expected_height && e.h_end >= new_block_expected_height)
|
||||
{
|
||||
//do vote for/against this
|
||||
if (entries_voted != 0)
|
||||
extra_text += ",";
|
||||
extra_text += "\"";
|
||||
extra_text += e.proposal_id;
|
||||
extra_text += "\":";
|
||||
extra_text += e.vote ? "1" : "0";
|
||||
entries_voted++;
|
||||
}
|
||||
}
|
||||
extra_text += "}";
|
||||
if (!entries_voted)
|
||||
extra_text = "";
|
||||
return extra_text;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool wallet2::build_minted_block(const mining_context& cxt, const currency::account_public_address& miner_address)
|
||||
{
|
||||
//found a block, construct it, sign and push to daemon
|
||||
|
|
@ -4394,7 +4526,7 @@ bool wallet2::build_minted_block(const mining_context& cxt, const currency::acco
|
|||
tmpl_req.wallet_address = get_account_address_as_str(miner_address);
|
||||
tmpl_req.stakeholder_address = get_account_address_as_str(m_account.get_public_address());
|
||||
tmpl_req.pos_block = true;
|
||||
tmpl_req.extra_text = m_miner_text_info;
|
||||
tmpl_req.extra_text = get_extra_text_for_block(m_chain.get_top_block_height());
|
||||
|
||||
tmpl_req.pe = AUTO_VAL_INIT(tmpl_req.pe);
|
||||
tmpl_req.pe.amount = td.amount();
|
||||
|
|
|
|||
|
|
@ -392,6 +392,7 @@ namespace tools
|
|||
bool set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy);
|
||||
void set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs); // don't create UTXO defrag. tx if there are less than 'min_outs' outs; don't put more than 'max_outs' outs
|
||||
void set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count);
|
||||
void set_pos_required_decoys_count(size_t v) { m_required_decoys_count = v; }
|
||||
void set_minimum_height(uint64_t h);
|
||||
std::shared_ptr<i_core_proxy> get_core_proxy();
|
||||
uint64_t balance() const;
|
||||
|
|
@ -591,6 +592,7 @@ namespace tools
|
|||
|
||||
bool build_minted_block(const mining_context& cxt);
|
||||
bool build_minted_block(const mining_context& cxt, const currency::account_public_address& miner_address);
|
||||
std::string get_extra_text_for_block(uint64_t new_block_expected_height);
|
||||
bool reset_history();
|
||||
bool is_transfer_unlocked(const transfer_details& td) const;
|
||||
bool is_transfer_unlocked(const transfer_details& td, bool for_pos_mining, uint64_t& stake_lock_time) const;
|
||||
|
|
@ -648,6 +650,8 @@ namespace tools
|
|||
bool load_whitelisted_tokens_if_not_loaded() const;
|
||||
bool load_whitelisted_tokens() const;
|
||||
|
||||
void set_connectivity_options(unsigned int timeout);
|
||||
|
||||
/*
|
||||
create_htlc_proposal: if htlc_hash == null_hash, then this wallet is originator of the atomic process, and
|
||||
we use deterministic origin, if given some particular htlc_hash, then we use this hash, and this means that
|
||||
|
|
@ -659,6 +663,9 @@ namespace tools
|
|||
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);
|
||||
|
||||
void set_votes_config_path(const std::string& path_to_config_file);
|
||||
const tools::wallet_public::wallet_vote_config& get_current_votes() { return m_votes_config; }
|
||||
|
||||
// ionic swaps:
|
||||
bool create_ionic_swap_proposal(const wallet_public::ionic_swap_proposal_info& proposal_details, const currency::account_public_address& destination_addr, wallet_public::ionic_swap_proposal& proposal);
|
||||
bool build_ionic_swap_template(const wallet_public::ionic_swap_proposal_info& proposal_detais, const currency::account_public_address& destination_addr,
|
||||
|
|
@ -685,6 +692,7 @@ namespace tools
|
|||
|
||||
protected:
|
||||
epee::misc_utils::events_dispatcher m_debug_events_dispatcher;
|
||||
|
||||
private:
|
||||
|
||||
// -------- t_transport_state_notifier ------------------------------------------------
|
||||
|
|
@ -765,6 +773,7 @@ private:
|
|||
uint64_t get_current_tx_version();
|
||||
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const wallet_public::wallet_transfer_info& wti) const;
|
||||
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const std::string& reason = "internal intention") const;
|
||||
void load_votes_config();
|
||||
bool is_need_to_split_outputs();
|
||||
template<typename input_t>
|
||||
bool process_input_t(const input_t& in_t, wallet2::process_transaction_context& ptc, const currency::transaction& tx);
|
||||
|
|
@ -860,6 +869,7 @@ private:
|
|||
uint64_t m_min_utxo_count_for_defragmentation_tx;
|
||||
uint64_t m_max_utxo_count_for_defragmentation_tx;
|
||||
size_t m_decoys_count_for_defragmentation_tx;
|
||||
size_t m_required_decoys_count;
|
||||
pending_ki_file_container_t m_pending_key_images_file_container;
|
||||
uint64_t m_upper_transaction_size_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value
|
||||
|
||||
|
|
@ -879,6 +889,10 @@ private:
|
|||
bool m_disable_tor_relay;
|
||||
bool m_use_assets_whitelisting = true;
|
||||
mutable current_operation_context m_current_context;
|
||||
|
||||
std::string m_votes_config_path;
|
||||
tools::wallet_public::wallet_vote_config m_votes_config;
|
||||
|
||||
//this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions
|
||||
friend class test_generator;
|
||||
}; // class wallet2
|
||||
|
|
@ -906,6 +920,38 @@ namespace boost
|
|||
// }
|
||||
|
||||
|
||||
/*template <class Archive>
|
||||
inline void serialize(Archive& a, tools::wallet_public::wallet_transfer_info_details& x, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & x.rcv;
|
||||
a & x.spn;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive& a, tools::wallet_public::wallet_transfer_info& x, const boost::serialization::version_type ver)
|
||||
{
|
||||
|
||||
a & x.amount;
|
||||
a & x.timestamp;
|
||||
a & x.tx_hash;
|
||||
a & x.height;
|
||||
a & x.tx_blob_size;
|
||||
a & x.payment_id;
|
||||
a & x.remote_addresses;
|
||||
a & x.is_income;
|
||||
a & x.td;
|
||||
a & x.tx;
|
||||
a & x.remote_aliases;
|
||||
a & x.comment;
|
||||
a & x.contract;
|
||||
a & x.selected_indicies;
|
||||
a & x.marketplace_entries;
|
||||
a & x.unlock_time;
|
||||
if (ver < 10)
|
||||
return;
|
||||
a & x.service_entries;
|
||||
}*/
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive& a, tools::wallet_public::escrow_contract_details_basic& x, const boost::serialization::version_type ver)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1308,6 +1308,30 @@ namespace wallet_public
|
|||
};
|
||||
|
||||
|
||||
struct wallet_vote_config_entry
|
||||
{
|
||||
std::string proposal_id;
|
||||
uint64_t h_start;
|
||||
uint64_t h_end;
|
||||
bool vote;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(proposal_id)
|
||||
KV_SERIALIZE(h_start)
|
||||
KV_SERIALIZE(h_end)
|
||||
KV_SERIALIZE(vote)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
|
||||
};
|
||||
|
||||
struct wallet_vote_config
|
||||
{
|
||||
std::vector<wallet_vote_config_entry> entries;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(entries)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct asset_funds
|
||||
{
|
||||
|
|
|
|||
|
|
@ -94,6 +94,8 @@ namespace tools
|
|||
static const uint64_t wallet_rpc_idle_work_period_ms = 2000;
|
||||
|
||||
m_do_mint = do_mint;
|
||||
if (m_do_mint)
|
||||
LOG_PRINT_CYAN("PoS mining is ON", LOG_LEVEL_0);
|
||||
|
||||
if (!offline_mode)
|
||||
{
|
||||
|
|
@ -171,6 +173,7 @@ namespace tools
|
|||
{
|
||||
w.get_wallet()->set_miner_text_info(command_line::get_arg(vm, arg_miner_text_info));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -90,61 +90,61 @@ namespace tools
|
|||
bool handle_http_request(const epee::net_utils::http::http_request_info& query_info, epee::net_utils::http::http_response_info& response, connection_context& m_conn_context);
|
||||
|
||||
BEGIN_URI_MAP2_VIRTUAL()
|
||||
BEGIN_JSON_RPC_MAP("/json_rpc")
|
||||
MAP_JON_RPC_WE("getbalance", on_getbalance, wallet_public::COMMAND_RPC_GET_BALANCE)
|
||||
MAP_JON_RPC_WE("getaddress", on_getaddress, wallet_public::COMMAND_RPC_GET_ADDRESS)
|
||||
MAP_JON_RPC_WE("get_wallet_info", on_getwallet_info, wallet_public::COMMAND_RPC_GET_WALLET_INFO)
|
||||
MAP_JON_RPC_WE("get_recent_txs_and_info", on_get_recent_txs_and_info, wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO)
|
||||
MAP_JON_RPC_WE("transfer", on_transfer, wallet_public::COMMAND_RPC_TRANSFER)
|
||||
MAP_JON_RPC_WE("store", on_store, wallet_public::COMMAND_RPC_STORE)
|
||||
MAP_JON_RPC_WE("get_payments", on_get_payments, wallet_public::COMMAND_RPC_GET_PAYMENTS)
|
||||
MAP_JON_RPC_WE("get_bulk_payments", on_get_bulk_payments, wallet_public::COMMAND_RPC_GET_BULK_PAYMENTS)
|
||||
MAP_JON_RPC_WE("make_integrated_address", on_make_integrated_address, wallet_public::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS)
|
||||
MAP_JON_RPC_WE("split_integrated_address", on_split_integrated_address, wallet_public::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS)
|
||||
MAP_JON_RPC_WE("sweep_below", on_sweep_below, wallet_public::COMMAND_SWEEP_BELOW)
|
||||
MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_public::COMMAND_SIGN_TRANSFER)
|
||||
MAP_JON_RPC_WE("submit_transfer", on_submit_transfer, wallet_public::COMMAND_SUBMIT_TRANSFER)
|
||||
MAP_JON_RPC_WE("search_for_transactions", on_search_for_transactions, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS)
|
||||
MAP_JON_RPC_WE("get_restore_info", on_getwallet_restore_info, wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO)
|
||||
MAP_JON_RPC_WE("get_seed_phrase_info", on_get_seed_phrase_info, wallet_public::COMMAND_RPC_GET_SEED_PHRASE_INFO)
|
||||
MAP_JON_RPC_WE("get_mining_history", on_get_mining_history, wallet_public::COMMAND_RPC_GET_MINING_HISTORY)
|
||||
MAP_JON_RPC_WE("register_alias", on_register_alias, wallet_public::COMMAND_RPC_REGISTER_ALIAS)
|
||||
//contracts API
|
||||
MAP_JON_RPC_WE("contracts_send_proposal", on_contracts_send_proposal, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL)
|
||||
MAP_JON_RPC_WE("contracts_accept_proposal", on_contracts_accept_proposal, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL)
|
||||
MAP_JON_RPC_WE("contracts_get_all", on_contracts_get_all, wallet_public::COMMAND_CONTRACTS_GET_ALL)
|
||||
MAP_JON_RPC_WE("contracts_release", on_contracts_release, wallet_public::COMMAND_CONTRACTS_RELEASE)
|
||||
MAP_JON_RPC_WE("contracts_request_cancel", on_contracts_request_cancel, wallet_public::COMMAND_CONTRACTS_REQUEST_CANCEL)
|
||||
MAP_JON_RPC_WE("contracts_accept_cancel", on_contracts_accept_cancel, wallet_public::COMMAND_CONTRACTS_ACCEPT_CANCEL)
|
||||
//marketplace API
|
||||
MAP_JON_RPC_WE("marketplace_get_offers_ex", on_marketplace_get_my_offers, wallet_public::COMMAND_MARKETPLACE_GET_MY_OFFERS)
|
||||
MAP_JON_RPC_WE("marketplace_push_offer", on_marketplace_push_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_OFFER)
|
||||
MAP_JON_RPC_WE("marketplace_push_update_offer", on_marketplace_push_update_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_UPDATE_OFFER)
|
||||
MAP_JON_RPC_WE("marketplace_cancel_offer", on_marketplace_cancel_offer, wallet_public::COMMAND_MARKETPLACE_CANCEL_OFFER)
|
||||
//HTLC API
|
||||
MAP_JON_RPC_WE("atomics_create_htlc_proposal", on_create_htlc_proposal, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL)
|
||||
MAP_JON_RPC_WE("atomics_get_list_of_active_htlc", on_get_list_of_active_htlc, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC)
|
||||
MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC)
|
||||
MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED)
|
||||
BEGIN_JSON_RPC_MAP("/json_rpc")
|
||||
MAP_JON_RPC_WE("getbalance", on_getbalance, wallet_public::COMMAND_RPC_GET_BALANCE)
|
||||
MAP_JON_RPC_WE("getaddress", on_getaddress, wallet_public::COMMAND_RPC_GET_ADDRESS)
|
||||
MAP_JON_RPC_WE("get_wallet_info", on_getwallet_info, wallet_public::COMMAND_RPC_GET_WALLET_INFO)
|
||||
MAP_JON_RPC_WE("get_recent_txs_and_info", on_get_recent_txs_and_info, wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO)
|
||||
MAP_JON_RPC_WE("transfer", on_transfer, wallet_public::COMMAND_RPC_TRANSFER)
|
||||
MAP_JON_RPC_WE("store", on_store, wallet_public::COMMAND_RPC_STORE)
|
||||
MAP_JON_RPC_WE("get_payments", on_get_payments, wallet_public::COMMAND_RPC_GET_PAYMENTS)
|
||||
MAP_JON_RPC_WE("get_bulk_payments", on_get_bulk_payments, wallet_public::COMMAND_RPC_GET_BULK_PAYMENTS)
|
||||
MAP_JON_RPC_WE("make_integrated_address", on_make_integrated_address, wallet_public::COMMAND_RPC_MAKE_INTEGRATED_ADDRESS)
|
||||
MAP_JON_RPC_WE("split_integrated_address", on_split_integrated_address, wallet_public::COMMAND_RPC_SPLIT_INTEGRATED_ADDRESS)
|
||||
MAP_JON_RPC_WE("sweep_below", on_sweep_below, wallet_public::COMMAND_SWEEP_BELOW)
|
||||
MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_public::COMMAND_SIGN_TRANSFER)
|
||||
MAP_JON_RPC_WE("submit_transfer", on_submit_transfer, wallet_public::COMMAND_SUBMIT_TRANSFER)
|
||||
MAP_JON_RPC_WE("search_for_transactions", on_search_for_transactions, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS)
|
||||
MAP_JON_RPC_WE("get_restore_info", on_getwallet_restore_info, wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO)
|
||||
MAP_JON_RPC_WE("get_seed_phrase_info", on_get_seed_phrase_info, wallet_public::COMMAND_RPC_GET_SEED_PHRASE_INFO)
|
||||
MAP_JON_RPC_WE("get_mining_history", on_get_mining_history, wallet_public::COMMAND_RPC_GET_MINING_HISTORY)
|
||||
MAP_JON_RPC_WE("register_alias", on_register_alias, wallet_public::COMMAND_RPC_REGISTER_ALIAS)
|
||||
//contracts API
|
||||
MAP_JON_RPC_WE("contracts_send_proposal", on_contracts_send_proposal, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL)
|
||||
MAP_JON_RPC_WE("contracts_accept_proposal", on_contracts_accept_proposal, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL)
|
||||
MAP_JON_RPC_WE("contracts_get_all", on_contracts_get_all, wallet_public::COMMAND_CONTRACTS_GET_ALL)
|
||||
MAP_JON_RPC_WE("contracts_release", on_contracts_release, wallet_public::COMMAND_CONTRACTS_RELEASE)
|
||||
MAP_JON_RPC_WE("contracts_request_cancel", on_contracts_request_cancel, wallet_public::COMMAND_CONTRACTS_REQUEST_CANCEL)
|
||||
MAP_JON_RPC_WE("contracts_accept_cancel", on_contracts_accept_cancel, wallet_public::COMMAND_CONTRACTS_ACCEPT_CANCEL)
|
||||
//marketplace API
|
||||
MAP_JON_RPC_WE("marketplace_get_offers_ex", on_marketplace_get_my_offers, wallet_public::COMMAND_MARKETPLACE_GET_MY_OFFERS)
|
||||
MAP_JON_RPC_WE("marketplace_push_offer", on_marketplace_push_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_OFFER)
|
||||
MAP_JON_RPC_WE("marketplace_push_update_offer", on_marketplace_push_update_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_UPDATE_OFFER)
|
||||
MAP_JON_RPC_WE("marketplace_cancel_offer", on_marketplace_cancel_offer, wallet_public::COMMAND_MARKETPLACE_CANCEL_OFFER)
|
||||
//HTLC API
|
||||
MAP_JON_RPC_WE("atomics_create_htlc_proposal", on_create_htlc_proposal, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL)
|
||||
MAP_JON_RPC_WE("atomics_get_list_of_active_htlc", on_get_list_of_active_htlc, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC)
|
||||
MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC)
|
||||
MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED)
|
||||
|
||||
//IONIC_SWAPS API
|
||||
MAP_JON_RPC_WE("ionic_swap_generate_proposal", on_ionic_swap_generate_proposal, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL)
|
||||
MAP_JON_RPC_WE("ionic_swap_get_proposal_info", on_ionic_swap_get_proposal_info, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO)
|
||||
MAP_JON_RPC_WE("ionic_swap_accept_proposal", on_ionic_swap_accept_proposal, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL)
|
||||
//IONIC_SWAPS API
|
||||
MAP_JON_RPC_WE("ionic_swap_generate_proposal", on_ionic_swap_generate_proposal, wallet_public::COMMAND_IONIC_SWAP_GENERATE_PROPOSAL)
|
||||
MAP_JON_RPC_WE("ionic_swap_get_proposal_info", on_ionic_swap_get_proposal_info, wallet_public::COMMAND_IONIC_SWAP_GET_PROPOSAL_INFO)
|
||||
MAP_JON_RPC_WE("ionic_swap_accept_proposal", on_ionic_swap_accept_proposal, wallet_public::COMMAND_IONIC_SWAP_ACCEPT_PROPOSAL)
|
||||
|
||||
//MULTIWALLET APIs
|
||||
MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS)
|
||||
MAP_JON_RPC_WE("mw_select_wallet", on_mw_select_wallet, wallet_public::COMMAND_MW_SELECT_WALLET)
|
||||
//MULTIWALLET APIs
|
||||
MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS)
|
||||
MAP_JON_RPC_WE("mw_select_wallet", on_mw_select_wallet, wallet_public::COMMAND_MW_SELECT_WALLET)
|
||||
|
||||
//basic crypto operations
|
||||
MAP_JON_RPC_WE("sign_message", on_sign_message, wallet_public::COMMAND_SIGN_MESSAGE)
|
||||
MAP_JON_RPC_WE("encrypt_data", on_encrypt_data, wallet_public::COMMAND_ENCRYPT_DATA)
|
||||
MAP_JON_RPC_WE("decrypt_data", on_decrypt_data, wallet_public::COMMAND_DECRYPT_DATA)
|
||||
//basic crypto operations
|
||||
MAP_JON_RPC_WE("sign_message", on_sign_message, wallet_public::COMMAND_SIGN_MESSAGE)
|
||||
MAP_JON_RPC_WE("encrypt_data", on_encrypt_data, wallet_public::COMMAND_ENCRYPT_DATA)
|
||||
MAP_JON_RPC_WE("decrypt_data", on_decrypt_data, wallet_public::COMMAND_DECRYPT_DATA)
|
||||
END_JSON_RPC_MAP()
|
||||
END_URI_MAP2()
|
||||
|
||||
//json_rpc
|
||||
bool on_getbalance(const wallet_public::COMMAND_RPC_GET_BALANCE::request& req, wallet_public::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
//json_rpc
|
||||
bool on_getbalance(const wallet_public::COMMAND_RPC_GET_BALANCE::request& req, wallet_public::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_getaddress(const wallet_public::COMMAND_RPC_GET_ADDRESS::request& req, wallet_public::COMMAND_RPC_GET_ADDRESS::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_getwallet_info(const wallet_public::COMMAND_RPC_GET_WALLET_INFO::request& req, wallet_public::COMMAND_RPC_GET_WALLET_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_getwallet_restore_info(const wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO::request& req, wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
|
|
@ -162,8 +162,8 @@ namespace tools
|
|||
bool on_search_for_transactions(const wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::request& req, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_get_mining_history(const wallet_public::COMMAND_RPC_GET_MINING_HISTORY::request& req, wallet_public::COMMAND_RPC_GET_MINING_HISTORY::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_register_alias(const wallet_public::COMMAND_RPC_REGISTER_ALIAS::request& req, wallet_public::COMMAND_RPC_REGISTER_ALIAS::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
|
||||
|
||||
|
||||
|
||||
bool on_contracts_send_proposal(const wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_contracts_accept_proposal(const wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_contracts_get_all(const wallet_public::COMMAND_CONTRACTS_GET_ALL::request& req, wallet_public::COMMAND_CONTRACTS_GET_ALL::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
|
|
|
|||
|
|
@ -1037,6 +1037,9 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st
|
|||
LOG_ERROR("Unexpected location reached");
|
||||
#endif
|
||||
}
|
||||
|
||||
w->set_votes_config_path(m_data_dir + "/" + CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME);
|
||||
|
||||
|
||||
std::string return_code = API_RETURN_CODE_OK;
|
||||
while (true)
|
||||
|
|
@ -1051,6 +1054,7 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st
|
|||
//w->get_unconfirmed_transfers(owr.recent_history.unconfirmed);
|
||||
w->get_unconfirmed_transfers(owr.recent_history.history, exclude_mining_txs);
|
||||
owr.wallet_local_bc_size = w->get_blockchain_current_size();
|
||||
|
||||
//workaround for missed fee
|
||||
//owr.seed = w->get_account().get_seed_phrase();
|
||||
break;
|
||||
|
|
@ -1142,6 +1146,7 @@ std::string wallets_manager::generate_wallet(const std::wstring& path, const std
|
|||
{
|
||||
std::shared_ptr<tools::wallet2> w(new tools::wallet2());
|
||||
w->set_use_deffered_global_outputs(m_use_deffered_global_outputs);
|
||||
w->set_votes_config_path(m_data_dir + "/" + CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME);
|
||||
owr.wallet_id = m_wallet_id_counter++;
|
||||
w->callback(std::shared_ptr<tools::i_wallet2_callback>(new i_wallet_to_i_backend_adapter(this, owr.wallet_id)));
|
||||
if (m_remote_node_mode)
|
||||
|
|
@ -1248,6 +1253,7 @@ std::string wallets_manager::restore_wallet(const std::wstring& path, const std:
|
|||
{
|
||||
std::shared_ptr<tools::wallet2> w(new tools::wallet2());
|
||||
w->set_use_deffered_global_outputs(m_use_deffered_global_outputs);
|
||||
w->set_votes_config_path(m_data_dir + "/" + CURRENCY_VOTING_CONFIG_DEFAULT_FILENAME);
|
||||
owr.wallet_id = m_wallet_id_counter++;
|
||||
w->callback(std::shared_ptr<tools::i_wallet2_callback>(new i_wallet_to_i_backend_adapter(this, owr.wallet_id)));
|
||||
if (m_remote_node_mode)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ target_link_libraries(coretests rpc wallet currency_core common crypto zlibstati
|
|||
target_link_libraries(functional_tests rpc wallet currency_core crypto common zlibstatic ethash libminiupnpc-static ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(hash-tests crypto ethash)
|
||||
target_link_libraries(hash-target-tests crypto currency_core ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(performance_tests currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(performance_tests wallet currency_core common crypto zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(unit_tests wallet currency_core common crypto gtest_main zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(net_load_tests_clt currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(net_load_tests_srv currency_core common crypto gtest_main ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
|
|
|
|||
|
|
@ -516,6 +516,8 @@ bool test_generator::build_wallets(const blockchain_vector& blockchain,
|
|||
wallets.back().wallet->assign_account(a);
|
||||
wallets.back().wallet->get_account().set_createtime(0);
|
||||
wallets.back().wallet->set_core_proxy(tmp_proxy);
|
||||
wallets.back().wallet->set_minimum_height(0);
|
||||
wallets.back().wallet->set_pos_required_decoys_count(0);
|
||||
|
||||
currency::core_runtime_config pc = cc;
|
||||
pc.min_coinstake_age = TESTS_POS_CONFIG_MIN_COINSTAKE_AGE;
|
||||
|
|
|
|||
|
|
@ -1104,6 +1104,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(pos_wallet_big_block_test);
|
||||
//GENERATE_AND_PLAY(block_template_against_txs_size); // Long test! by demand only
|
||||
GENERATE_AND_PLAY(pos_altblocks_validation);
|
||||
GENERATE_AND_PLAY(pos_mining_with_decoys);
|
||||
|
||||
// alternative blocks and generic chain-switching tests
|
||||
GENERATE_AND_PLAY(gen_chain_switch_pow_pos);
|
||||
|
|
|
|||
|
|
@ -139,3 +139,121 @@ bool gen_pos_basic_tests::check_exchange_1(currency::core& c, size_t ev_index, c
|
|||
CHECK_EQ(offers.size(), 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
pos_mining_with_decoys::pos_mining_with_decoys()
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(pos_mining_with_decoys, c1);
|
||||
}
|
||||
|
||||
bool pos_mining_with_decoys::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
uint64_t ts = test_core_time::get_time();
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
currency::account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate(); miner_acc.set_createtime(ts);
|
||||
currency::account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.set_createtime(ts);
|
||||
currency::account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(); bob_acc.set_createtime(ts);
|
||||
currency::account_base& carol_acc = m_accounts[CAROL_ACC_IDX]; carol_acc.generate(); carol_acc.set_createtime(ts);
|
||||
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, ts);
|
||||
DO_CALLBACK(events, "configure_core"); // default configure_core callback will initialize core runtime config with m_hardforks
|
||||
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1);
|
||||
|
||||
bool r = false;
|
||||
std::vector<tx_source_entry> sources;
|
||||
r = fill_tx_sources(sources, events, blk_0r, miner_acc.get_keys(), 2 * COIN, 0);
|
||||
CHECK_AND_ASSERT_MES(r, false, "fill_tx_sources failed");
|
||||
std::vector<tx_destination_entry> destinations;
|
||||
destinations.emplace_back(47 * TESTS_DEFAULT_FEE, alice_acc.get_public_address());
|
||||
destinations.emplace_back(47 * TESTS_DEFAULT_FEE, miner_acc.get_public_address()); // as a decoy for Alice
|
||||
destinations.emplace_back(5 * TESTS_DEFAULT_FEE, bob_acc.get_public_address());
|
||||
destinations.emplace_back(COIN, carol_acc.get_public_address());
|
||||
|
||||
transaction tx_0{};
|
||||
r = construct_tx(miner_acc.get_keys(), sources, destinations, empty_attachment, tx_0, get_tx_version_from_events(events), 0);
|
||||
CHECK_AND_ASSERT_MES(r, false, "construct_tx failed");
|
||||
events.push_back(tx_0);
|
||||
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
|
||||
|
||||
REWIND_BLOCKS_N(events, blk_1r, blk_1, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
DO_CALLBACK(events, "c1");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pos_mining_with_decoys::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
bool r = false;
|
||||
CHECK_AND_ASSERT_MES(!c.get_blockchain_storage().get_core_runtime_config().is_hardfork_active_for_height(4, c.get_top_block_height()), false, "HF4 should not be active");
|
||||
|
||||
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, m_accounts[MINER_ACC_IDX]);
|
||||
miner_wlt->refresh();
|
||||
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, m_accounts[ALICE_ACC_IDX]);
|
||||
alice_wlt->refresh();
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*alice_wlt, "Alice", 47 * TESTS_DEFAULT_FEE, INVALID_BALANCE_VAL, 47 * TESTS_DEFAULT_FEE), false, "");
|
||||
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, m_accounts[BOB_ACC_IDX]);
|
||||
bob_wlt->refresh();
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*bob_wlt, "Bob", 5 * TESTS_DEFAULT_FEE, INVALID_BALANCE_VAL, 5 * TESTS_DEFAULT_FEE), false, "");
|
||||
|
||||
std::shared_ptr<tools::wallet2> carol_wlt = init_playtime_test_wallet(events, c, m_accounts[CAROL_ACC_IDX]);
|
||||
carol_wlt->refresh();
|
||||
CHECK_AND_ASSERT_MES(check_balance_via_wallet(*carol_wlt, "Carol", COIN, INVALID_BALANCE_VAL, COIN), false, "");
|
||||
|
||||
|
||||
// 1. Alice should be able to mine a PoS block with 1 decoys (ring size == 2)
|
||||
size_t top_block_height = c.get_top_block_height();
|
||||
|
||||
r = alice_wlt->try_mint_pos(m_accounts[ALICE_ACC_IDX].get_public_address());
|
||||
CHECK_AND_ASSERT_MES(r, false, "try_mint_pos failed");
|
||||
|
||||
{
|
||||
block b{};
|
||||
CHECK_AND_ASSERT_MES(c.get_blockchain_storage().get_top_block(b), false, "");
|
||||
CHECK_AND_ASSERT_MES(get_block_height(b) == top_block_height + 1, false, "unexpected top block height");
|
||||
|
||||
txin_to_key& intk = boost::get<txin_to_key>(b.miner_tx.vin[1]);
|
||||
CHECK_AND_ASSERT_MES(intk.amount == 47 * TESTS_DEFAULT_FEE, false, "incorrect amount: " << intk.amount);
|
||||
CHECK_AND_ASSERT_MES(intk.key_offsets.size() == 2, false, "unexpected ring size: " << intk.key_offsets.size());
|
||||
}
|
||||
|
||||
|
||||
// 2. Bob should only be able to mine a PoS block with zero decoys (ring size == 1)
|
||||
top_block_height = c.get_top_block_height();
|
||||
|
||||
r = bob_wlt->try_mint_pos(m_accounts[BOB_ACC_IDX].get_public_address());
|
||||
CHECK_AND_ASSERT_MES(r, false, "try_mint_pos failed");
|
||||
|
||||
{
|
||||
block b{};
|
||||
CHECK_AND_ASSERT_MES(c.get_blockchain_storage().get_top_block(b), false, "");
|
||||
CHECK_AND_ASSERT_MES(get_block_height(b) == top_block_height + 1, false, "unexpected top block height");
|
||||
|
||||
txin_to_key& intk = boost::get<txin_to_key>(b.miner_tx.vin[1]);
|
||||
CHECK_AND_ASSERT_MES(intk.amount == 5 * TESTS_DEFAULT_FEE, false, "incorrect amount: " << intk.amount);
|
||||
CHECK_AND_ASSERT_MES(intk.key_offsets.size() == 1, false, "unexpected ring size: " << intk.key_offsets.size());
|
||||
}
|
||||
|
||||
|
||||
// 3. Carol should only be able to mine a PoS block with CURRENCY_DEFAULT_DECOY_SET_SIZE decoys (ring size == CURRENCY_DEFAULT_DECOY_SET_SIZE + 1)
|
||||
top_block_height = c.get_top_block_height();
|
||||
|
||||
r = carol_wlt->try_mint_pos(m_accounts[CAROL_ACC_IDX].get_public_address());
|
||||
CHECK_AND_ASSERT_MES(r, false, "try_mint_pos failed");
|
||||
|
||||
{
|
||||
block b{};
|
||||
CHECK_AND_ASSERT_MES(c.get_blockchain_storage().get_top_block(b), false, "");
|
||||
CHECK_AND_ASSERT_MES(get_block_height(b) == top_block_height + 1, false, "unexpected top block height");
|
||||
|
||||
txin_to_key& intk = boost::get<txin_to_key>(b.miner_tx.vin[1]);
|
||||
CHECK_AND_ASSERT_MES(intk.amount == COIN, false, "incorrect amount: " << intk.amount);
|
||||
CHECK_AND_ASSERT_MES(intk.key_offsets.size() == CURRENCY_DEFAULT_DECOY_SET_SIZE + 1, false, "unexpected ring size: " << intk.key_offsets.size());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
#include "chaingen.h"
|
||||
#include "wallet_tests_basic.h"
|
||||
|
||||
struct gen_pos_basic_tests : public test_chain_unit_base
|
||||
{
|
||||
|
|
@ -22,3 +23,12 @@ struct gen_pos_basic_tests : public test_chain_unit_base
|
|||
bool check_exchange_1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct pos_mining_with_decoys : public wallet_test
|
||||
{
|
||||
pos_mining_with_decoys();
|
||||
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);
|
||||
};
|
||||
|
|
|
|||
25
tests/performance_tests/api_test.cpp
Normal file
25
tests/performance_tests/api_test.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
#include "wallet/core_rpc_proxy.h"
|
||||
#include "wallet/core_default_rpc_proxy.h"
|
||||
|
||||
int test_get_rand_outs()
|
||||
{
|
||||
currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request req = AUTO_VAL_INIT(req);
|
||||
currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response rsp = AUTO_VAL_INIT(rsp);
|
||||
req.use_forced_mix_outs = false;
|
||||
req.outs_count = 10 + 1;
|
||||
for (size_t i = 0; i != 50; i++)
|
||||
req.amounts.push_back(COIN);
|
||||
|
||||
std::shared_ptr<tools::i_core_proxy> m_core_proxy(new tools::default_http_core_proxy());
|
||||
m_core_proxy->set_connection_addr("127.0.0.1:11211");
|
||||
m_core_proxy->check_connection();
|
||||
|
||||
bool r = m_core_proxy->call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS(req, rsp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
26
tests/unit_tests/votes_tests.cpp
Normal file
26
tests/unit_tests/votes_tests.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright (c) 2012-2014 The Zano developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "misc_language.h"
|
||||
#include "currency_core/currency_format_utils.h"
|
||||
|
||||
|
||||
TEST(governance_testig, governance_tests_1)
|
||||
{
|
||||
std::string vote = "{\"ZGP11\":1,\"ZGP23\":0}";
|
||||
|
||||
std::list<std::pair<std::string, bool>> votes;
|
||||
currency::parse_vote(vote, votes);
|
||||
ASSERT_TRUE(votes.size() == 2);
|
||||
ASSERT_TRUE(votes.begin()->first == "ZGP11");
|
||||
ASSERT_TRUE(votes.begin()->second == true);
|
||||
ASSERT_TRUE((++votes.begin())->first == "ZGP23");
|
||||
ASSERT_TRUE((++votes.begin())->second == false);
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue