forked from lthn/blockchain
Merge branch 'release'
This commit is contained in:
commit
734b726df1
28 changed files with 317 additions and 148 deletions
|
|
@ -35,11 +35,14 @@ namespace eos {
|
|||
|
||||
// version of the linked boost archive library
|
||||
const archive_version_type archive_version(
|
||||
#if BOOST_VERSION < 103700
|
||||
boost::archive::ARCHIVE_VERSION()
|
||||
#else
|
||||
boost::archive::BOOST_ARCHIVE_VERSION()
|
||||
#endif
|
||||
|
||||
100 // explicitly fix archive version to make it independent from Boost version
|
||||
|
||||
//#if BOOST_VERSION < 103700
|
||||
// boost::archive::ARCHIVE_VERSION()
|
||||
//#else
|
||||
// boost::archive::BOOST_ARCHIVE_VERSION()
|
||||
//#endif
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ namespace tools
|
|||
a << obj;
|
||||
|
||||
return !data_file.fail();
|
||||
CATCH_ENTRY_L0("serialize_obj_to_file", false);
|
||||
CATCH_ENTRY_L0("serialize_obj_to_file: could not serialize into " << file_path, false);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ namespace tools
|
|||
a << obj;
|
||||
|
||||
return !stream.fail();
|
||||
CATCH_ENTRY_L0("serialize_obj_to_file", false);
|
||||
CATCH_ENTRY_L0("portble_serialize_obj_to_stream", false);
|
||||
}
|
||||
|
||||
template<class t_object>
|
||||
|
|
@ -72,7 +72,7 @@ namespace tools
|
|||
|
||||
a >> obj;
|
||||
return !data_file.fail();
|
||||
CATCH_ENTRY_L0("unserialize_obj_from_file", false);
|
||||
CATCH_ENTRY_L0("unserialize_obj_from_file: could not load " << file_path, false);
|
||||
}
|
||||
|
||||
template<class t_object>
|
||||
|
|
@ -85,7 +85,7 @@ namespace tools
|
|||
|
||||
a >> obj;
|
||||
return !ss.fail();
|
||||
CATCH_ENTRY_L0("unserialize_obj_from_obj", false);
|
||||
CATCH_ENTRY_L0("unserialize_obj_from_buff", false);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -98,6 +98,6 @@ namespace tools
|
|||
|
||||
a >> obj;
|
||||
return !stream.fail();
|
||||
CATCH_ENTRY_L0("unserialize_obj_from_file", false);
|
||||
CATCH_ENTRY_L0("portable_unserialize_obj_from_stream", false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,5 +25,7 @@ namespace command_line
|
|||
const arg_descriptor<bool> arg_show_details = { "currency-details", "Display currency details" };
|
||||
const arg_descriptor<bool> arg_show_rpc_autodoc = { "show_rpc_autodoc", "Display rpc auto-generated documentation template" };
|
||||
|
||||
const arg_descriptor<bool> arg_disable_upnp = { "disable-upnp", "Disable UPnP (enhances local network privacy)", false, true };
|
||||
const arg_descriptor<bool> arg_disable_upnp = { "disable-upnp", "Disable UPnP (enhances local network privacy)", false, true };
|
||||
|
||||
const arg_descriptor<bool> arg_disable_stop_if_time_out_of_sync = { "disable-stop-if-time-out-of-sync", "Do not stop the daemon if serious time synchronization problem is detected", false, true };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,4 +185,5 @@ namespace command_line
|
|||
extern const arg_descriptor<bool> arg_show_details;
|
||||
extern const arg_descriptor<bool> arg_show_rpc_autodoc;
|
||||
extern const arg_descriptor<bool> arg_disable_upnp;
|
||||
extern const arg_descriptor<bool> arg_disable_stop_if_time_out_of_sync;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#define BUF_SIZE 1024
|
||||
|
||||
#define CHECK_AND_ASSERT_MESS_LMDB_DB(rc, ret, mess) CHECK_AND_ASSERT_MES(res == MDB_SUCCESS, ret, "[DB ERROR]:(" << rc << ")" << mdb_strerror(rc) << ", [message]: " << mess);
|
||||
#define CHECK_AND_ASSERT_THROW_MESS_LMDB_DB(rc, mess) CHECK_AND_ASSERT_THROW_MES(res == MDB_SUCCESS, "[DB ERROR]:(" << rc << ")" << mdb_strerror(rc) << ", [message]: " << mess);
|
||||
#define ASSERT_MES_AND_THROW_LMDB(rc, mess) ASSERT_MES_AND_THROW("[DB ERROR]:(" << rc << ")" << mdb_strerror(rc) << ", [message]: " << mess);
|
||||
|
||||
#undef LOG_DEFAULT_CHANNEL
|
||||
#define LOG_DEFAULT_CHANNEL "lmdb"
|
||||
|
|
@ -134,7 +136,13 @@ namespace tools
|
|||
|
||||
CHECK_AND_ASSERT_THROW_MES(m_penv, "m_penv==null, db closed");
|
||||
res = mdb_txn_begin(m_penv, pparent_tx, flags, &p_new_tx);
|
||||
CHECK_AND_ASSERT_MESS_LMDB_DB(res, false, "Unable to mdb_txn_begin");
|
||||
if(res != MDB_SUCCESS)
|
||||
{
|
||||
//Important: if mdb_txn_begin is failed need to unlock previously locked mutex
|
||||
CRITICAL_SECTION_UNLOCK(m_write_exclusive_lock);
|
||||
//throw exception to avoid regular code execution
|
||||
ASSERT_MES_AND_THROW_LMDB(res, "Unable to mdb_txn_begin");
|
||||
}
|
||||
|
||||
rtxlist.push_back(tx_entry());
|
||||
rtxlist.back().count = read_only ? 1 : 0;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ using namespace epee;
|
|||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
|
@ -588,4 +589,38 @@ std::string get_nix_version_display_string()
|
|||
return static_cast<uint64_t>(in.tellg());
|
||||
}
|
||||
|
||||
}
|
||||
int64_t get_ntp_time(const std::string& host_name)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::asio::io_service io_service;
|
||||
boost::asio::ip::udp::resolver resolver(io_service);
|
||||
boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), host_name, "ntp");
|
||||
boost::asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query);
|
||||
boost::asio::ip::udp::socket socket(io_service);
|
||||
socket.open(boost::asio::ip::udp::v4());
|
||||
|
||||
boost::array<unsigned char, 48> send_buf = { 010, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);
|
||||
|
||||
boost::array<unsigned long, 1024> recv_buf;
|
||||
boost::asio::ip::udp::endpoint sender_endpoint;
|
||||
size_t len = socket.receive_from(boost::asio::buffer(recv_buf), sender_endpoint);
|
||||
|
||||
time_t time_recv = ntohl((time_t)recv_buf[4]);
|
||||
time_recv -= 2208988800U; //Unix time starts from 01/01/1970 == 2208988800U
|
||||
return time_recv;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_PRINT_L2("get_ntp_time(): exception: " << e.what());
|
||||
return 0;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace tools
|
||||
|
|
|
|||
|
|
@ -333,4 +333,7 @@ namespace tools
|
|||
static std::function<void(void)> m_handler;
|
||||
static std::function<void(int, void*)> m_fatal_handler;
|
||||
};
|
||||
|
||||
|
||||
int64_t get_ntp_time(const std::string& host_name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,11 @@ using namespace currency;
|
|||
|
||||
#define TARGETDATA_CACHE_SIZE DIFFICULTY_WINDOW + 10
|
||||
|
||||
#ifndef TESTNET
|
||||
#define BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION 57000
|
||||
#else
|
||||
#define BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION 18000
|
||||
#endif
|
||||
|
||||
DISABLE_VS_WARNINGS(4267)
|
||||
|
||||
|
|
@ -1507,6 +1512,13 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
|
|||
if (abei.height >= m_core_runtime_config.pos_minimum_heigh)
|
||||
cumulative_diff_delta = correct_difficulty_with_sequence_factor(sequence_factor, cumulative_diff_delta);
|
||||
|
||||
if (abei.height > BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION && pos_block && sequence_factor > 20)
|
||||
{
|
||||
LOG_PRINT_RED_L0("Alternative block " << id << " @ " << abei.height << " has too big sequence factor: " << sequence_factor << ", rejected");
|
||||
bvc.m_verification_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
abei.cumulative_diff_adjusted += cumulative_diff_delta;
|
||||
|
||||
abei.cumulative_diff_precise = get_last_alt_x_block_cumulative_precise_difficulty(alt_chain, abei.height, pos_block);
|
||||
|
|
@ -4458,6 +4470,15 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
|
|||
if (bei.height >= m_core_runtime_config.pos_minimum_heigh)
|
||||
cumulative_diff_delta = correct_difficulty_with_sequence_factor(sequence_factor, cumulative_diff_delta);
|
||||
|
||||
if (bei.height > BLOCKCHAIN_HEIGHT_FOR_POS_STRICT_SEQUENCE_LIMITATION && is_pos_bl && sequence_factor > 20)
|
||||
{
|
||||
LOG_PRINT_L0("Block with id: " << id
|
||||
<< " has too big sequence_factor = " << sequence_factor);
|
||||
purge_block_data_from_blockchain(bl, tx_processed_count);
|
||||
bvc.m_verification_failed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bei.cumulative_diff_adjusted += cumulative_diff_delta;
|
||||
|
||||
//etc
|
||||
|
|
|
|||
|
|
@ -32,10 +32,12 @@ namespace currency
|
|||
m_blockchain_storage(m_mempool),
|
||||
m_miner(this, m_blockchain_storage),
|
||||
m_miner_address(boost::value_initialized<account_public_address>()),
|
||||
m_starter_message_showed(false)
|
||||
m_starter_message_showed(false),
|
||||
m_stop_handler(nullptr)
|
||||
{
|
||||
set_currency_protocol(pprotocol);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
void core::set_currency_protocol(i_currency_protocol* pprotocol)
|
||||
{
|
||||
if(pprotocol)
|
||||
|
|
@ -46,6 +48,11 @@ namespace currency
|
|||
m_mempool.set_protocol(m_pprotocol);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
void core::set_stop_handler(i_stop_handler *handler)
|
||||
{
|
||||
m_stop_handler = handler;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
bool core::set_checkpoints(checkpoints&& chk_pts)
|
||||
{
|
||||
return m_blockchain_storage.set_checkpoints(std::move(chk_pts));
|
||||
|
|
|
|||
|
|
@ -81,6 +81,8 @@ namespace currency
|
|||
size_t get_alternative_blocks_count();
|
||||
|
||||
void set_currency_protocol(i_currency_protocol* pprotocol);
|
||||
void set_stop_handler(i_stop_handler *handler);
|
||||
i_stop_handler* get_stop_handler() const { return m_stop_handler; }
|
||||
bool set_checkpoints(checkpoints&& chk_pts);
|
||||
|
||||
bool get_pool_transactions(std::list<transaction>& txs);
|
||||
|
|
@ -138,6 +140,7 @@ namespace currency
|
|||
blockchain_storage m_blockchain_storage;
|
||||
tx_memory_pool m_mempool;
|
||||
i_currency_protocol* m_pprotocol;
|
||||
i_stop_handler* m_stop_handler;
|
||||
critical_section m_incoming_tx_lock;
|
||||
miner m_miner;
|
||||
account_public_address m_miner_address;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,10 @@ namespace currency
|
|||
uint64_t get_max_seen_height();
|
||||
virtual size_t get_synchronized_connections_count();
|
||||
virtual size_t get_synchronizing_connections_count();
|
||||
|
||||
int64_t get_net_time_delta_median();
|
||||
bool add_time_delta_and_check_time_sync(int64_t delta);
|
||||
bool get_last_time_sync_difference(int64_t& last_median2local_time_difference, int64_t& last_ntp2local_time_difference); // returns true if differences in allowed bounds
|
||||
|
||||
private:
|
||||
//----------------- commands handlers ----------------------------------------------
|
||||
|
|
@ -108,6 +111,11 @@ namespace currency
|
|||
std::thread m_relay_que_thread;
|
||||
std::atomic<bool> m_want_stop;
|
||||
|
||||
std::deque<int64_t> m_time_deltas;
|
||||
std::mutex m_time_deltas_lock;
|
||||
int64_t m_last_median2local_time_difference;
|
||||
int64_t m_last_ntp2local_time_difference;
|
||||
|
||||
template<class t_parametr>
|
||||
bool post_notify(typename t_parametr::request& arg, currency_connection_context& context)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,26 +12,27 @@ namespace currency
|
|||
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
t_currency_protocol_handler<t_core>::t_currency_protocol_handler(t_core& rcore, nodetool::i_p2p_endpoint<connection_context>* p_net_layout):m_core(rcore),
|
||||
m_p2p(p_net_layout),
|
||||
m_syncronized_connections_count(0),
|
||||
m_synchronized(false),
|
||||
m_have_been_synchronized(false),
|
||||
m_max_height_seen(0),
|
||||
m_core_inital_height(0),
|
||||
m_want_stop(false)
|
||||
|
||||
|
||||
t_currency_protocol_handler<t_core>::t_currency_protocol_handler(t_core& rcore, nodetool::i_p2p_endpoint<connection_context>* p_net_layout)
|
||||
: m_core(rcore)
|
||||
, m_p2p(p_net_layout)
|
||||
, m_syncronized_connections_count(0)
|
||||
, m_synchronized(false)
|
||||
, m_have_been_synchronized(false)
|
||||
, m_max_height_seen(0)
|
||||
, m_core_inital_height(0)
|
||||
, m_want_stop(false)
|
||||
, m_last_median2local_time_difference(0)
|
||||
, m_last_ntp2local_time_difference(0)
|
||||
{
|
||||
if(!m_p2p)
|
||||
m_p2p = &m_p2p_stub;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
t_currency_protocol_handler<t_core>::~t_currency_protocol_handler()
|
||||
{
|
||||
deinit();
|
||||
}
|
||||
template<class t_core>
|
||||
t_currency_protocol_handler<t_core>::~t_currency_protocol_handler()
|
||||
{
|
||||
deinit();
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
bool t_currency_protocol_handler<t_core>::init(const boost::program_options::variables_map& vm)
|
||||
|
|
@ -121,7 +122,25 @@ namespace currency
|
|||
if(context.m_state == currency_connection_context::state_befor_handshake && !is_inital)
|
||||
return true;
|
||||
|
||||
context.m_time_delta = m_core.get_blockchain_storage().get_core_runtime_config().get_core_time() - hshd.core_time;
|
||||
uint64_t local_time = m_core.get_blockchain_storage().get_core_runtime_config().get_core_time();
|
||||
context.m_time_delta = local_time - hshd.core_time;
|
||||
|
||||
// for outgoing connections -- check time difference
|
||||
if (!context.m_is_income)
|
||||
{
|
||||
if (!add_time_delta_and_check_time_sync(context.m_time_delta))
|
||||
{
|
||||
// serious time sync problem detected
|
||||
i_stop_handler* ish(m_core.get_stop_handler());
|
||||
if (ish != nullptr)
|
||||
{
|
||||
// this is daemon -- stop immediately
|
||||
ish->stop_handling();
|
||||
LOG_ERROR(ENDL << ENDL << "Serious time sync problem detected, daemon will stop immediately" << ENDL << ENDL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(context.m_state == currency_connection_context::state_synchronizing)
|
||||
return true;
|
||||
|
|
@ -673,8 +692,7 @@ namespace currency
|
|||
{
|
||||
std::list<relay_que_entry> local_que;
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_relay_que_lock);
|
||||
//m_relay_que_cv.wait(lk);
|
||||
CRITICAL_REGION_LOCAL(m_relay_que_lock);
|
||||
local_que.swap(m_relay_que);
|
||||
}
|
||||
if (local_que.size())
|
||||
|
|
@ -751,6 +769,90 @@ namespace currency
|
|||
return epee::misc_utils::median(deltas);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
#define TIME_SYNC_DELTA_RING_BUFFER_SIZE 8
|
||||
#define TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE (60 * 5) // max acceptable difference between time delta median among peers and local time (seconds)
|
||||
#define TIME_SYNC_NTP_TO_LOCAL_MAX_DIFFERENCE (60 * 5) // max acceptable difference between NTP time and local time (seconds)
|
||||
#define TIME_SYNC_NTP_SERVERS { "time.google.com", "0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org" }
|
||||
#define TIME_SYNC_NTP_ATTEMPTS_COUNT 3 // max number of attempts when getting time from NTP server
|
||||
|
||||
static int64_t get_ntp_time()
|
||||
{
|
||||
static const std::vector<std::string> ntp_servers TIME_SYNC_NTP_SERVERS;
|
||||
|
||||
for (size_t att = 0; att < TIME_SYNC_NTP_ATTEMPTS_COUNT; ++att)
|
||||
{
|
||||
size_t i = 0;
|
||||
crypto::generate_random_bytes(sizeof(i), &i);
|
||||
const std::string& ntp_server = ntp_servers[i % ntp_servers.size()];
|
||||
LOG_PRINT_L3("NTP: trying to get time from " << ntp_server);
|
||||
int64_t time = tools::get_ntp_time(ntp_server);
|
||||
if (time > 0)
|
||||
{
|
||||
LOG_PRINT_L2("NTP: " << ntp_server << " responded with " << time << " (" << epee::misc_utils::get_time_str_v2(time) << ")");
|
||||
return time;
|
||||
}
|
||||
LOG_PRINT_L2("NTP: cannot get time from " << ntp_server);
|
||||
}
|
||||
|
||||
return 0; // smth went wrong
|
||||
}
|
||||
|
||||
template<class t_core>
|
||||
bool t_currency_protocol_handler<t_core>::add_time_delta_and_check_time_sync(int64_t time_delta)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_time_deltas_lock);
|
||||
|
||||
m_time_deltas.push_back(time_delta);
|
||||
while (m_time_deltas.size() > TIME_SYNC_DELTA_RING_BUFFER_SIZE)
|
||||
m_time_deltas.pop_front();
|
||||
|
||||
if (m_time_deltas.size() < TIME_SYNC_DELTA_RING_BUFFER_SIZE)
|
||||
return true; // not enough data
|
||||
|
||||
std::vector<int64_t> time_deltas_copy(m_time_deltas.begin(), m_time_deltas.end());
|
||||
|
||||
m_last_median2local_time_difference = epee::misc_utils::median(time_deltas_copy);
|
||||
LOG_PRINT_MAGENTA("TIME: network time difference is " << m_last_median2local_time_difference << " (max is " << TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE << ")", LOG_LEVEL_2);
|
||||
if (std::abs(m_last_median2local_time_difference) > TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE)
|
||||
{
|
||||
int64_t ntp_time = get_ntp_time();
|
||||
if (ntp_time == 0)
|
||||
{
|
||||
// error geting ntp time
|
||||
LOG_PRINT_RED("TIME: network time difference is " << m_last_median2local_time_difference << " (max is " << TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE << ") but NTP servers did not respond", LOG_LEVEL_0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// got ntp time correctly
|
||||
// update local time, because getting ntp time could be time consuming
|
||||
uint64_t local_time_2 = m_core.get_blockchain_storage().get_core_runtime_config().get_core_time();
|
||||
m_last_ntp2local_time_difference = local_time_2 - ntp_time;
|
||||
if (std::abs(m_last_ntp2local_time_difference) > TIME_SYNC_NTP_TO_LOCAL_MAX_DIFFERENCE)
|
||||
{
|
||||
// local time is out of sync
|
||||
LOG_PRINT_RED("TIME: network time difference is " << m_last_median2local_time_difference << " (max is " << TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE << "), NTP time difference is " <<
|
||||
m_last_ntp2local_time_difference << " (max is " << TIME_SYNC_NTP_TO_LOCAL_MAX_DIFFERENCE << ")", LOG_LEVEL_0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// NTP time is OK
|
||||
LOG_PRINT_YELLOW("TIME: network time difference is " << m_last_median2local_time_difference << " (max is " << TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE << "), NTP time difference is " <<
|
||||
m_last_ntp2local_time_difference << " (max is " << TIME_SYNC_NTP_TO_LOCAL_MAX_DIFFERENCE << ")", LOG_LEVEL_1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
bool t_currency_protocol_handler<t_core>::get_last_time_sync_difference(int64_t& last_median2local_time_difference, int64_t& last_ntp2local_time_difference)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_time_deltas_lock);
|
||||
last_median2local_time_difference = m_last_median2local_time_difference;
|
||||
last_ntp2local_time_difference = m_last_ntp2local_time_difference;
|
||||
|
||||
return !(std::abs(m_last_median2local_time_difference) > TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE && std::abs(m_last_ntp2local_time_difference) > TIME_SYNC_NTP_TO_LOCAL_MAX_DIFFERENCE);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_response_chain_entry(int command, NOTIFY_RESPONSE_CHAIN_ENTRY::request& arg, currency_connection_context& context)
|
||||
{
|
||||
|
|
@ -806,7 +908,7 @@ namespace currency
|
|||
{
|
||||
#ifdef ASYNC_RELAY_MODE
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(m_relay_que_lock);
|
||||
CRITICAL_REGION_LOCAL(m_relay_que_lock);
|
||||
m_relay_que.push_back(AUTO_VAL_INIT(relay_que_entry()));
|
||||
m_relay_que.back().first = arg;
|
||||
m_relay_que.back().second = exclude_context;
|
||||
|
|
|
|||
|
|
@ -36,4 +36,14 @@ namespace currency
|
|||
}
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
struct i_stop_handler
|
||||
{
|
||||
virtual void stop_handling() = 0;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_cmd_sett, command_line::arg_console);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_show_details);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_show_rpc_autodoc);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_disable_stop_if_time_out_of_sync);
|
||||
|
||||
|
||||
arg_market_disable.default_value = true;
|
||||
|
|
@ -167,6 +168,10 @@ int main(int argc, char* argv[])
|
|||
cprotocol.set_p2p_endpoint(&p2psrv);
|
||||
ccore.set_currency_protocol(&cprotocol);
|
||||
daemon_cmmands_handler dch(p2psrv, rpc_server);
|
||||
|
||||
if (!command_line::get_arg(vm, command_line::arg_disable_stop_if_time_out_of_sync))
|
||||
ccore.set_stop_handler(&dch);
|
||||
|
||||
//ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&offers_service);
|
||||
std::shared_ptr<currency::stratum_server> stratum_server_ptr;
|
||||
if (stratum_enabled)
|
||||
|
|
@ -304,7 +309,7 @@ int main(int argc, char* argv[])
|
|||
LOG_PRINT_L0("Deinitializing p2p...");
|
||||
p2psrv.deinit();
|
||||
|
||||
|
||||
ccore.set_stop_handler(nullptr);
|
||||
ccore.set_currency_protocol(NULL);
|
||||
cprotocol.set_p2p_endpoint(NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
PUSH_WARNINGS
|
||||
DISABLE_VS_WARNINGS(4100)
|
||||
|
||||
class daemon_cmmands_handler
|
||||
class daemon_cmmands_handler : public currency::i_stop_handler
|
||||
{
|
||||
typedef nodetool::node_server<currency::t_currency_protocol_handler<currency::core> > srv_type;
|
||||
srv_type& m_srv;
|
||||
|
|
@ -75,7 +75,8 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void stop_handling()
|
||||
// interface currency::i_stop_handler
|
||||
virtual void stop_handling() override
|
||||
{
|
||||
m_cmd_binder.stop_handling();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -461,7 +461,7 @@ bool daemon_backend::update_state_info()
|
|||
{
|
||||
view::daemon_status_info dsi = AUTO_VAL_INIT(dsi);
|
||||
currency::COMMAND_RPC_GET_INFO::request req = AUTO_VAL_INIT(req);
|
||||
req.flags = COMMAND_RPC_GET_INFO_FLAG_EXPIRATIONS_MEDIAN;
|
||||
req.flags = COMMAND_RPC_GET_INFO_FLAG_EXPIRATIONS_MEDIAN | COMMAND_RPC_GET_INFO_FLAG_NET_TIME_DELTA_MEDIAN;
|
||||
currency::COMMAND_RPC_GET_INFO::response inf = AUTO_VAL_INIT(inf);
|
||||
if (!m_rpc_proxy->call_COMMAND_RPC_GET_INFO(req, inf))
|
||||
{
|
||||
|
|
@ -1565,18 +1565,18 @@ void daemon_backend::wallet_vs_options::worker_func()
|
|||
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_PRINT_L0(w->get()->get_log_prefix() + "Failed to refresh wallet: " << e.what());
|
||||
LOG_ERROR(w->get()->get_log_prefix() + " Exception in wallet handler: " << e.what());
|
||||
wallet_state = wsi.wallet_state = view::wallet_status_info::wallet_state_error;
|
||||
pview->update_wallet_status(wsi);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
LOG_PRINT_L0(w->get()->get_log_prefix() + "Failed to refresh wallet, unknownk exception");
|
||||
LOG_ERROR(w->get()->get_log_prefix() + " Exception in wallet handler: unknownk exception");
|
||||
wallet_state = wsi.wallet_state = view::wallet_status_info::wallet_state_error;
|
||||
pview->update_wallet_status(wsi);
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -504,7 +504,8 @@ void MainWindow::load_file(const QString &fileName)
|
|||
{
|
||||
TRY_ENTRY();
|
||||
LOG_PRINT_L0("Loading html from path: " << fileName.toStdString());
|
||||
m_view->load(QUrl::fromLocalFile(QFileInfo(fileName).absoluteFilePath()));
|
||||
QUrl url = QUrl::fromLocalFile(QFileInfo(fileName).absoluteFilePath());
|
||||
m_view->load(url);
|
||||
CATCH_ENTRY2(void());
|
||||
}
|
||||
|
||||
|
|
@ -770,7 +771,8 @@ bool MainWindow::set_html_path(const std::string& path)
|
|||
TRY_ENTRY();
|
||||
//init_tray_icon(path);
|
||||
#ifdef _MSC_VER
|
||||
load_file(std::string(path + "/index.html").c_str());
|
||||
QString url = QString::fromUtf8(epee::string_encoding::convert_ansii_to_utf8(path).c_str()) + "/index.html";
|
||||
load_file(url);
|
||||
#else
|
||||
// load_file(QString((std::string("file://") + path + "/index.html").c_str()));
|
||||
load_file(QString((std::string("") + path + "/index.html").c_str()));
|
||||
|
|
@ -778,6 +780,7 @@ bool MainWindow::set_html_path(const std::string& path)
|
|||
return true;
|
||||
CATCH_ENTRY2(false);
|
||||
}
|
||||
|
||||
bool MainWindow::pos_block_found(const currency::block& block_found)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -19,7 +19,7 @@ export class VariablesService {
|
|||
public defaultCurrency = 'ZANO';
|
||||
public opening_wallet: Wallet;
|
||||
public exp_med_ts = 0;
|
||||
public ts_diff = 0;
|
||||
public net_time_delta_median = 0;
|
||||
public height_app = 0;
|
||||
public last_build_available = '';
|
||||
public last_build_displaymode = 0;
|
||||
|
|
@ -77,7 +77,6 @@ export class VariablesService {
|
|||
setExpMedTs(timestamp: number) {
|
||||
if (timestamp !== this.exp_med_ts) {
|
||||
this.exp_med_ts = timestamp;
|
||||
this.ts_diff = Math.abs(new Date().getTime() - (timestamp * 1000));
|
||||
this.getExpMedTsEvent.next(timestamp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,12 +24,6 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||
|
||||
needOpenWallets = [];
|
||||
|
||||
currenciesFromNet = {
|
||||
ZANO_bitmesh: null,
|
||||
ZANO_qtrade: null,
|
||||
BTC_bitmesh: null
|
||||
};
|
||||
|
||||
@ViewChild('allContextMenu') public allContextMenu: ContextMenuComponent;
|
||||
@ViewChild('onlyCopyContextMenu') public onlyCopyContextMenu: ContextMenuComponent;
|
||||
|
||||
|
|
@ -174,6 +168,7 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||
console.log(data);
|
||||
// this.variablesService.exp_med_ts = data['expiration_median_timestamp'] + 600 + 1;
|
||||
this.variablesService.setExpMedTs(data['expiration_median_timestamp'] + 600 + 1);
|
||||
this.variablesService.net_time_delta_median = data.net_time_delta_median;
|
||||
this.variablesService.last_build_available = data.last_build_available;
|
||||
this.variablesService.last_build_displaymode = data.last_build_displaymode;
|
||||
this.variablesService.setHeightApp(data.height);
|
||||
|
|
@ -552,54 +547,25 @@ export class AppComponent implements OnInit, OnDestroy {
|
|||
this.getMoneyEquivalent();
|
||||
}
|
||||
|
||||
recountMoneyEquivalent() {
|
||||
let sum = 0;
|
||||
let count = 0;
|
||||
if (this.currenciesFromNet.BTC_bitmesh) {
|
||||
if (this.currenciesFromNet.ZANO_qtrade) {
|
||||
sum += this.currenciesFromNet.ZANO_qtrade;
|
||||
count++;
|
||||
}
|
||||
if (this.currenciesFromNet.ZANO_bitmesh) {
|
||||
sum += this.currenciesFromNet.ZANO_bitmesh;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
this.variablesService.moneyEquivalent = (sum / count) / this.currenciesFromNet.BTC_bitmesh;
|
||||
}
|
||||
|
||||
getMoneyEquivalent() {
|
||||
this.http.get('https://blockchain.info/tobtc?currency=USD&value=1').subscribe(
|
||||
result1 => {
|
||||
this.currenciesFromNet.BTC_bitmesh = result1;
|
||||
this.http.get('https://api.qtrade.io/v1/ticker/ZANO_BTC').subscribe(
|
||||
result2 => {
|
||||
if (result2.hasOwnProperty('data')) {
|
||||
this.currenciesFromNet.ZANO_qtrade = (parseFloat(result2['data']['ask']) + parseFloat(result2['data']['bid'])) / 2;
|
||||
}
|
||||
this.recountMoneyEquivalent();
|
||||
this.http.get('https://api.coingecko.com/api/v3/ping').subscribe(
|
||||
() => {
|
||||
this.http.get('https://api.coingecko.com/api/v3/simple/price?ids=zano&vs_currencies=usd').subscribe(
|
||||
data => {
|
||||
this.variablesService.moneyEquivalent = data['zano']['usd'];
|
||||
},
|
||||
() => {
|
||||
}
|
||||
);
|
||||
this.http.get('https://api.bitmesh.com/?api=market.statistics¶ms={"market":"btc_zano"}').subscribe(
|
||||
result3 => {
|
||||
if (result3.hasOwnProperty('data')) {
|
||||
this.currenciesFromNet.ZANO_bitmesh = parseFloat(result3['data']['price']);
|
||||
}
|
||||
this.recountMoneyEquivalent();
|
||||
},
|
||||
() => {
|
||||
error => {
|
||||
console.warn('api.coingecko.com price error: ', error);
|
||||
}
|
||||
);
|
||||
},
|
||||
error => {
|
||||
console.warn('api.coingecko.com error: ', error);
|
||||
setTimeout(() => {
|
||||
this.getMoneyEquivalent();
|
||||
}, 60000);
|
||||
console.warn('Error', error);
|
||||
}
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
getAliases() {
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@
|
|||
<i class="icon update critical" tooltip="{{ 'SIDEBAR.UPDATE.CRITICAL_TOOLTIP' | translate }}" placement="right-bottom" tooltipClass="update-tooltip critical" [delay]="500"></i>
|
||||
</ng-container>
|
||||
</div>
|
||||
<div class="update-container" *ngIf="false">
|
||||
<div class="update-container" *ngIf="variablesService.daemon_state === 2 && variablesService.net_time_delta_median !== 0">
|
||||
<div class="update-text time">
|
||||
<span>{{ 'SIDEBAR.UPDATE.TIME' | translate }}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export class SidebarComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
getUpdate() {
|
||||
this.backend.openUrlInBrowser('docs.zano.org/docs/zano-wallet');
|
||||
this.backend.openUrlInBrowser('zano.org/downloads.html');
|
||||
}
|
||||
|
||||
logOut() {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,11 @@ namespace currency
|
|||
|
||||
//conditional values
|
||||
if (req.flags&COMMAND_RPC_GET_INFO_FLAG_NET_TIME_DELTA_MEDIAN)
|
||||
res.net_time_delta_median = m_p2p.get_payload_object().get_net_time_delta_median();
|
||||
{
|
||||
int64_t last_median2local_time_diff, last_ntp2local_time_diff;
|
||||
if (!m_p2p.get_payload_object().get_last_time_sync_difference(last_median2local_time_diff, last_ntp2local_time_diff))
|
||||
res.net_time_delta_median = 1;
|
||||
}
|
||||
if (req.flags&COMMAND_RPC_GET_INFO_FLAG_CURRENT_NETWORK_HASHRATE_50)
|
||||
res.current_network_hashrate_50 = m_core.get_blockchain_storage().get_current_hashrate(50);
|
||||
if (req.flags&COMMAND_RPC_GET_INFO_FLAG_CURRENT_NETWORK_HASHRATE_350)
|
||||
|
|
|
|||
|
|
@ -1224,18 +1224,18 @@ bool simple_wallet::integrated_address(const std::vector<std::string> &args)
|
|||
|
||||
if (args.size() == 1)
|
||||
{
|
||||
std::string addr_or_payment_id = args[0];
|
||||
std::string addr_or_payment_id_hex = args[0];
|
||||
currency::account_public_address addr = AUTO_VAL_INIT(addr);
|
||||
std::string embedded_payment_id;
|
||||
if (currency::get_account_address_and_payment_id_from_str(addr, embedded_payment_id, addr_or_payment_id))
|
||||
if (currency::get_account_address_and_payment_id_from_str(addr, embedded_payment_id, addr_or_payment_id_hex))
|
||||
{
|
||||
// address provided
|
||||
if (embedded_payment_id.empty())
|
||||
{
|
||||
success_msg_writer(false) << addr_or_payment_id << " is a standard address";
|
||||
success_msg_writer(false) << addr_or_payment_id_hex << " is a standard address";
|
||||
return true;
|
||||
}
|
||||
success_msg_writer(true ) << "integrated address: " << addr_or_payment_id;
|
||||
success_msg_writer(true ) << "integrated address: " << addr_or_payment_id_hex;
|
||||
success_msg_writer(false) << "standard address: " << get_account_address_as_str(addr);
|
||||
success_msg_writer(false) << "payment id (" << std::setw(3) << embedded_payment_id.size() << " bytes) : " << epee::string_tools::mask_non_ascii_chars(embedded_payment_id);
|
||||
success_msg_writer(false) << "payment id (hex-encoded): " << epee::string_tools::buff_to_hex_nodelimer(embedded_payment_id);
|
||||
|
|
@ -1243,15 +1243,22 @@ bool simple_wallet::integrated_address(const std::vector<std::string> &args)
|
|||
}
|
||||
|
||||
// seems like not a valid address, treat as payment id
|
||||
if (!currency::is_payment_id_size_ok(addr_or_payment_id))
|
||||
std::string payment_id;
|
||||
if (!epee::string_tools::parse_hexstr_to_binbuff(addr_or_payment_id_hex, payment_id))
|
||||
{
|
||||
fail_msg_writer() << "payment id is too long: " << addr_or_payment_id.size() << " bytes, max allowed: " << BC_PAYMENT_ID_SERVICE_SIZE_MAX << " bytes";
|
||||
fail_msg_writer() << "invalid payment id given: \'" << addr_or_payment_id_hex << "\', hex-encoded string was expected";
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!currency::is_payment_id_size_ok(payment_id))
|
||||
{
|
||||
fail_msg_writer() << "payment id is too long: " << payment_id.size() << " bytes, max allowed: " << BC_PAYMENT_ID_SERVICE_SIZE_MAX << " bytes";
|
||||
return true;
|
||||
}
|
||||
success_msg_writer(false) << "this wallet standard address: " << m_wallet->get_account().get_public_address_str();
|
||||
success_msg_writer(false) << "payment id: (" << std::setw(3) << addr_or_payment_id.size() << " bytes) : " << addr_or_payment_id;
|
||||
success_msg_writer(false) << "payment id (hex-encoded): " << epee::string_tools::buff_to_hex_nodelimer(addr_or_payment_id);
|
||||
success_msg_writer(true ) << "integrated address: " << get_account_address_and_payment_id_as_str(m_wallet->get_account().get_public_address(), addr_or_payment_id);
|
||||
success_msg_writer(false) << "payment id (" << std::setw(3) << payment_id.size() << " bytes) : " << epee::string_tools::mask_non_ascii_chars(payment_id);
|
||||
success_msg_writer(false) << "payment id (hex-encoded) : " << epee::string_tools::buff_to_hex_nodelimer(payment_id);
|
||||
success_msg_writer(true ) << "integrated address: " << get_account_address_and_payment_id_as_str(m_wallet->get_account().get_public_address(), payment_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1534,14 +1541,22 @@ int main(int argc, char* argv[])
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!command_line::has_arg(vm, arg_password) )
|
||||
tools::password_container pwd_container;
|
||||
if (command_line::has_arg(vm, arg_password))
|
||||
{
|
||||
LOG_ERROR("Wallet password is not set.");
|
||||
return EXIT_FAILURE;
|
||||
pwd_container.password(command_line::get_arg(vm, arg_password));
|
||||
}
|
||||
else
|
||||
{
|
||||
bool r = pwd_container.read_password();
|
||||
if (!r)
|
||||
{
|
||||
LOG_ERROR("failed to read wallet password");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
std::string wallet_file = command_line::get_arg(vm, arg_wallet_file);
|
||||
std::string wallet_password = command_line::get_arg(vm, arg_password);
|
||||
std::string daemon_address = command_line::get_arg(vm, arg_daemon_address);
|
||||
std::string daemon_host = command_line::get_arg(vm, arg_daemon_host);
|
||||
int daemon_port = command_line::get_arg(vm, arg_daemon_port);
|
||||
|
|
@ -1559,7 +1574,7 @@ int main(int argc, char* argv[])
|
|||
try
|
||||
{
|
||||
LOG_PRINT_L0("Loading wallet...");
|
||||
wal.load(epee::string_encoding::convert_to_unicode(wallet_file), wallet_password);
|
||||
wal.load(epee::string_encoding::convert_to_unicode(wallet_file), pwd_container.password());
|
||||
}
|
||||
catch (const tools::error::wallet_load_notice_wallet_restored& e)
|
||||
{
|
||||
|
|
@ -1621,7 +1636,8 @@ int main(int argc, char* argv[])
|
|||
LOG_ERROR("Failed to store wallet: " << e.what());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}else
|
||||
}
|
||||
else // if(command_line::has_arg(vm, tools::wallet_rpc_server::arg_rpc_bind_port))
|
||||
{
|
||||
//runs wallet with console interface
|
||||
sw->set_offline_mode(offline_mode);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
#define BUILD_COMMIT_ID "@VERSION@"
|
||||
#define PROJECT_VERSION "1.0"
|
||||
#define PROJECT_VERSION_BUILD_NO 39
|
||||
#define PROJECT_VERSION_BUILD_NO 40
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
1
utils/configure_macos_xcodeproj.sh
Normal file → Executable file
1
utils/configure_macos_xcodeproj.sh
Normal file → Executable file
|
|
@ -6,6 +6,7 @@ curr_path=${BASH_SOURCE%/*}
|
|||
: "${ZANO_BOOST_ROOT:?variable not set, see also macosx_build_config.command}"
|
||||
: "${ZANO_BOOST_LIBS_PATH:?variable not set, see also macosx_build_config.command}"
|
||||
: "${ZANO_BUILD_DIR:?variable not set, see also macosx_build_config.command}"
|
||||
: "${CMAKE_OSX_SYSROOT:?CMAKE_OSX_SYSROOT should be set to macOS SDK path, e.g.: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk}"
|
||||
|
||||
BUILD_DIR=$curr_path/../$ZANO_BUILD_DIR/macos_xcodeproj
|
||||
BUILD_TYPE=Release
|
||||
|
|
|
|||
1
utils/test_api_files/exec_getblocktemplate.bat
Normal file
1
utils/test_api_files/exec_getblocktemplate.bat
Normal file
|
|
@ -0,0 +1 @@
|
|||
curl --data @getblocktemplate.json http://127.0.0.1:11211/json_rpc
|
||||
Loading…
Add table
Reference in a new issue