2015-01-05 20:30:17 +01:00
/// @file
/// @author rfree (current maintainer/user in monero.cc project - most of code is from CryptoNote)
2018-01-19 08:54:14 +01:00
/// @brief This is the original cryptonote protocol network-events handler, modified by us
2015-01-05 20:30:17 +01:00
2019-04-12 06:36:43 +02:00
// Copyright (c) 2014-2019, The Monero Project
2018-04-10 06:49:20 +02:00
// Copyright (c) 2018, The Loki Project
2015-12-14 05:54:39 +01:00
//
2014-07-23 15:03:52 +02:00
// All rights reserved.
2015-12-14 05:54:39 +01:00
//
2014-07-23 15:03:52 +02:00
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
2015-12-14 05:54:39 +01:00
//
2014-07-23 15:03:52 +02:00
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
2015-12-14 05:54:39 +01:00
//
2014-07-23 15:03:52 +02:00
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
2015-12-14 05:54:39 +01:00
//
2014-07-23 15:03:52 +02:00
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
2015-12-14 05:54:39 +01:00
//
2014-07-23 15:03:52 +02:00
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2015-12-14 05:54:39 +01:00
//
2014-07-23 15:03:52 +02:00
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
2014-03-03 23:07:58 +01:00
2015-01-05 20:30:17 +01:00
// (may contain code and/or modifications by other developers)
// developer rfree: this code is caller of our new network code, and is modded; e.g. for rate limiting
2014-03-03 23:07:58 +01:00
#include <boost/interprocess/detail/atomic.hpp>
2014-07-19 01:33:03 +02:00
#include <list>
2017-11-29 23:53:58 +01:00
#include <ctime>
2014-07-19 01:33:03 +02:00
2017-01-26 16:07:23 +01:00
#include "cryptonote_basic/cryptonote_format_utils.h"
2014-03-03 23:07:58 +01:00
#include "profile_tools.h"
2017-11-29 20:30:06 +01:00
#include "net/network_throttle-detail.hpp"
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
#include "common/pruning.h"
2019-11-06 07:28:33 +01:00
#include "common/random.h"
Change logging to easylogging++
This replaces the epee and data_loggers logging systems with
a single one, and also adds filename:line and explicit severity
levels. Categories may be defined, and logging severity set
by category (or set of categories). epee style 0-4 log level
maps to a sensible severity configuration. Log files now also
rotate when reaching 100 MB.
To select which logs to output, use the MONERO_LOGS environment
variable, with a comma separated list of categories (globs are
supported), with their requested severity level after a colon.
If a log matches more than one such setting, the last one in
the configuration string applies. A few examples:
This one is (mostly) silent, only outputting fatal errors:
MONERO_LOGS=*:FATAL
This one is very verbose:
MONERO_LOGS=*:TRACE
This one is totally silent (logwise):
MONERO_LOGS=""
This one outputs all errors and warnings, except for the
"verify" category, which prints just fatal errors (the verify
category is used for logs about incoming transactions and
blocks, and it is expected that some/many will fail to verify,
hence we don't want the spam):
MONERO_LOGS=*:WARNING,verify:FATAL
Log levels are, in decreasing order of priority:
FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
Subcategories may be added using prefixes and globs. This
example will output net.p2p logs at the TRACE level, but all
other net* logs only at INFO:
MONERO_LOGS=*:ERROR,net*:INFO,net.p2p:TRACE
Logs which are intended for the user (which Monero was using
a lot through epee, but really isn't a nice way to go things)
should use the "global" category. There are a few helper macros
for using this category, eg: MGINFO("this shows up by default")
or MGINFO_RED("this is red"), to try to keep a similar look
and feel for now.
Existing epee log macros still exist, and map to the new log
levels, but since they're used as a "user facing" UI element
as much as a logging system, they often don't map well to log
severities (ie, a log level 0 log may be an error, or may be
something we want the user to see, such as an important info).
In those cases, I tried to use the new macros. In other cases,
I left the existing macros in. When modifying logs, it is
probably best to switch to the new macros with explicit levels.
The --log-level options and set_log commands now also accept
category settings, in addition to the epee style log levels.
2017-01-01 17:34:23 +01:00
2018-04-10 06:49:20 +02:00
#undef LOKI_DEFAULT_LOG_CATEGORY
#define LOKI_DEFAULT_LOG_CATEGORY "net.cn"
2015-01-05 20:30:17 +01:00
2017-01-22 11:14:45 +01:00
#define MLOG_P2P_MESSAGE(x) MCINFO("net.p2p.msg", context << x)
2019-03-27 21:38:42 +01:00
#define MLOGIF_P2P_MESSAGE(init, test, x) \
do { \
const auto level = el::Level::Info; \
const char *cat = "net.p2p.msg"; \
if (ELPP->vRegistry()->allowed(level, cat)) { \
init; \
if (test) \
el::base::Writer(level, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::NormalLog).construct(cat) << x; \
} \
} while(0)
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
#define MLOG_PEER_STATE(x) \
2019-01-30 02:04:20 +01:00
MCINFO(LOKI_DEFAULT_LOG_CATEGORY, context << "[" << epee::string_tools::to_string_hex(context.m_pruning_seed) << "] state: " << x << " in state " << cryptonote::get_protocol_state_string(context.m_state))
2017-01-22 11:14:45 +01:00
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
#define BLOCK_QUEUE_NSPANS_THRESHOLD 10 // chunks of N blocks
2017-07-02 23:41:15 +02:00
#define BLOCK_QUEUE_SIZE_THRESHOLD (100*1024*1024) // MB
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
#define BLOCK_QUEUE_FORCE_DOWNLOAD_NEAR_BLOCKS 1000
#define REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY (5 * 1000000) // microseconds
#define REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD (30 * 1000000) // microseconds
2017-10-04 22:53:06 +02:00
#define IDLE_PEER_KICK_TIME (600 * 1000000) // microseconds
2017-10-19 16:48:46 +02:00
#define PASSIVE_PEER_KICK_TIME (60 * 1000000) // microseconds
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
#define DROP_ON_SYNC_WEDGE_THRESHOLD (30 * 1000000000ull) // nanoseconds
#define LAST_ACTIVITY_STALL_THRESHOLD (2.0f) // seconds
2017-07-02 23:41:15 +02:00
2014-03-03 23:07:58 +01:00
namespace cryptonote
{
2015-01-05 20:30:17 +01:00
2015-12-14 05:54:39 +01:00
//-----------------------------------------------------------------------------------------------------------------------
2014-03-03 23:07:58 +01:00
template<class t_core>
2018-01-25 14:35:17 +01:00
t_cryptonote_protocol_handler<t_core>::t_cryptonote_protocol_handler(t_core& rcore, nodetool::i_p2p_endpoint<connection_context>* p_net_layout, bool offline):m_core(rcore),
2014-03-03 23:07:58 +01:00
m_p2p(p_net_layout),
m_syncronized_connections_count(0),
2018-01-25 14:35:17 +01:00
m_synchronized(offline),
2019-02-25 02:31:45 +01:00
m_stopping(false),
m_no_sync(false)
2014-03-03 23:07:58 +01:00
{
if(!m_p2p)
m_p2p = &m_p2p_stub;
}
//-----------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2014-03-03 23:07:58 +01:00
bool t_cryptonote_protocol_handler<t_core>::init(const boost::program_options::variables_map& vm)
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
m_sync_timer.pause();
m_sync_timer.reset();
m_add_timer.pause();
m_add_timer.reset();
m_last_add_end_time = 0;
m_sync_spans_downloaded = 0;
m_sync_old_spans_downloaded = 0;
m_sync_bad_spans_downloaded = 0;
m_sync_download_chain_size = 0;
m_sync_download_objects_size = 0;
m_block_download_max_size = command_line::get_arg(vm, cryptonote::arg_block_download_max_size);
2014-03-03 23:07:58 +01:00
return true;
}
2015-12-14 05:54:39 +01:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2014-03-03 23:07:58 +01:00
bool t_cryptonote_protocol_handler<t_core>::deinit()
{
return true;
}
2015-12-14 05:54:39 +01:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2014-03-03 23:07:58 +01:00
void t_cryptonote_protocol_handler<t_core>::set_p2p_endpoint(nodetool::i_p2p_endpoint<connection_context>* p2p)
{
if(p2p)
m_p2p = p2p;
else
m_p2p = &m_p2p_stub;
}
2015-12-14 05:54:39 +01:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2014-03-03 23:07:58 +01:00
bool t_cryptonote_protocol_handler<t_core>::on_callback(cryptonote_connection_context& context)
{
LOG_PRINT_CCONTEXT_L2("callback fired");
CHECK_AND_ASSERT_MES_CC( context.m_callback_request_count > 0, false, "false callback fired, but context.m_callback_request_count=" << context.m_callback_request_count);
--context.m_callback_request_count;
if(context.m_state == cryptonote_connection_context::state_synchronizing)
{
2019-10-31 23:26:58 +01:00
NOTIFY_REQUEST_CHAIN::request r{};
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
context.m_needed_objects.clear();
2019-11-18 23:18:41 +01:00
m_core.get_blockchain_storage().get_short_chain_history(r.block_ids);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
2014-03-03 23:07:58 +01:00
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_PEER_STATE("requesting chain");
2014-03-03 23:07:58 +01:00
}
2017-08-18 21:14:23 +02:00
else if(context.m_state == cryptonote_connection_context::state_standby)
{
context.m_state = cryptonote_connection_context::state_synchronizing;
try_add_next_blocks(context);
}
2014-03-03 23:07:58 +01:00
2019-11-18 23:18:41 +01:00
if (context.m_need_blink_sync)
{
NOTIFY_REQUEST_BLOCK_BLINKS::request r{};
auto curr_height = m_core.get_current_blockchain_height();
auto my_blink_hashes = m_core.get_pool().get_blink_checksums();
const uint64_t immutable_height = m_core.get_blockchain_storage().get_immutable_height();
2019-11-20 01:24:48 +01:00
// Delete any irrelevant heights > 0 (the mempool) and <= the immutable height
context.m_blink_state.erase(context.m_blink_state.lower_bound(1), context.m_blink_state.lower_bound(immutable_height + 1));
2019-11-18 23:18:41 +01:00
// m_blink_state: HEIGHT => {CHECKSUM, NEEDED}
for (auto &i : context.m_blink_state)
{
if (!i.second.second) continue;
// We thought we needed it when we last got some data; check whether we still do:
auto my_it = my_blink_hashes.find(i.first);
if (my_it == my_blink_hashes.end() || i.second.first != my_it->second)
r.heights.push_back(i.first);
else
i.second.second = false; // checksum is now equal, don't need it anymore
}
context.m_need_blink_sync = false;
if (!r.heights.empty())
{
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_BLOCK_BLINKS: requesting blink tx lists for " << r.heights.size() << " blocks");
post_notify<NOTIFY_REQUEST_BLOCK_BLINKS>(r, context);
MLOG_PEER_STATE("requesting block blinks");
}
}
2014-03-03 23:07:58 +01:00
return true;
}
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2014-03-03 23:07:58 +01:00
bool t_cryptonote_protocol_handler<t_core>::get_stat_info(core_stat_info& stat_inf)
{
return m_core.get_stat_info(stat_inf);
}
2015-12-14 05:54:39 +01:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2014-03-20 12:46:11 +01:00
void t_cryptonote_protocol_handler<t_core>::log_connections()
{
std::stringstream ss;
2015-02-12 20:59:39 +01:00
ss.precision(1);
2015-12-14 05:54:39 +01:00
double down_sum = 0.0;
double down_curr_sum = 0.0;
double up_sum = 0.0;
double up_curr_sum = 0.0;
2014-03-20 12:46:11 +01:00
2015-01-05 20:30:17 +01:00
ss << std::setw(30) << std::left << "Remote Host"
2014-03-20 12:46:11 +01:00
<< std::setw(20) << "Peer id"
2016-10-26 21:00:08 +02:00
<< std::setw(20) << "Support Flags"
2015-02-12 20:59:39 +01:00
<< std::setw(30) << "Recv/Sent (inactive,sec)"
2014-03-20 12:46:11 +01:00
<< std::setw(25) << "State"
2015-02-12 20:59:39 +01:00
<< std::setw(20) << "Livetime(sec)"
<< std::setw(12) << "Down (kB/s)"
<< std::setw(14) << "Down(now)"
2015-12-14 05:54:39 +01:00
<< std::setw(10) << "Up (kB/s)"
2015-02-12 20:59:39 +01:00
<< std::setw(13) << "Up(now)"
<< ENDL;
2014-03-20 12:46:11 +01:00
2016-10-26 21:00:08 +02:00
m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id, uint32_t support_flags)
2014-03-20 12:46:11 +01:00
{
2017-05-27 12:35:54 +02:00
bool local_ip = cntxt.m_remote_address.is_local();
2015-12-14 05:54:39 +01:00
auto connection_time = time(NULL) - cntxt.m_started;
2015-01-05 20:30:17 +01:00
ss << std::setw(30) << std::left << std::string(cntxt.m_is_income ? " [INC]":"[OUT]") +
2017-05-27 12:35:54 +02:00
cntxt.m_remote_address.str()
2014-03-20 12:46:11 +01:00
<< std::setw(20) << std::hex << peer_id
2016-10-26 21:00:08 +02:00
<< std::setw(20) << std::hex << support_flags
2015-02-12 20:59:39 +01:00
<< std::setw(30) << std::to_string(cntxt.m_recv_cnt)+ "(" + std::to_string(time(NULL) - cntxt.m_last_recv) + ")" + "/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(time(NULL) - cntxt.m_last_send) + ")"
2014-03-20 12:46:11 +01:00
<< std::setw(25) << get_protocol_state_string(cntxt.m_state)
2015-01-05 20:30:17 +01:00
<< std::setw(20) << std::to_string(time(NULL) - cntxt.m_started)
2015-02-12 20:59:39 +01:00
<< std::setw(12) << std::fixed << (connection_time == 0 ? 0.0 : cntxt.m_recv_cnt / connection_time / 1024)
<< std::setw(14) << std::fixed << cntxt.m_current_speed_down / 1024
<< std::setw(10) << std::fixed << (connection_time == 0 ? 0.0 : cntxt.m_send_cnt / connection_time / 1024)
<< std::setw(13) << std::fixed << cntxt.m_current_speed_up / 1024
<< (local_ip ? "[LAN]" : "")
2017-05-27 12:35:54 +02:00
<< std::left << (cntxt.m_remote_address.is_loopback() ? "[LOCALHOST]" : "") // 127.0.0.1
2015-02-12 20:59:39 +01:00
<< ENDL;
2015-12-14 05:54:39 +01:00
if (connection_time > 1)
{
down_sum += (cntxt.m_recv_cnt / connection_time / 1024);
up_sum += (cntxt.m_send_cnt / connection_time / 1024);
}
down_curr_sum += (cntxt.m_current_speed_down / 1024);
up_curr_sum += (cntxt.m_current_speed_up / 1024);
2014-03-20 12:46:11 +01:00
return true;
});
2015-12-14 05:54:39 +01:00
ss << ENDL
<< std::setw(125) << " "
<< std::setw(12) << down_sum
<< std::setw(14) << down_curr_sum
<< std::setw(10) << up_sum
<< std::setw(13) << up_curr_sum
<< ENDL;
LOG_PRINT_L0("Connections: " << ENDL << ss.str());
2014-03-20 12:46:11 +01:00
}
2015-12-14 05:54:39 +01:00
//------------------------------------------------------------------------------------------------------------------------
2014-07-19 01:33:03 +02:00
// Returns a list of connection_info objects describing each open p2p connection
2015-12-14 05:54:39 +01:00
//------------------------------------------------------------------------------------------------------------------------
2014-07-19 01:33:03 +02:00
template<class t_core>
std::list<connection_info> t_cryptonote_protocol_handler<t_core>::get_connections()
{
std::list<connection_info> connections;
2016-10-26 21:00:08 +02:00
m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id, uint32_t support_flags)
2014-07-19 01:33:03 +02:00
{
connection_info cnx;
auto timestamp = time(NULL);
cnx.incoming = cntxt.m_is_income ? true : false;
2017-05-27 12:35:54 +02:00
cnx.address = cntxt.m_remote_address.str();
cnx.host = cntxt.m_remote_address.host_str();
cnx.ip = "";
cnx.port = "";
2019-04-09 10:07:13 +02:00
if (cntxt.m_remote_address.get_type_id() == epee::net_utils::ipv4_network_address::get_type_id())
2017-05-27 12:35:54 +02:00
{
cnx.ip = cnx.host;
cnx.port = std::to_string(cntxt.m_remote_address.as<epee::net_utils::ipv4_network_address>().port());
}
2019-02-24 09:47:49 +01:00
cnx.rpc_port = cntxt.m_rpc_port;
2014-07-19 01:33:03 +02:00
std::stringstream peer_id_str;
2017-08-16 11:56:55 +02:00
peer_id_str << std::hex << std::setw(16) << peer_id;
2014-07-19 01:33:03 +02:00
peer_id_str >> cnx.peer_id;
2016-10-26 21:00:08 +02:00
cnx.support_flags = support_flags;
2014-07-19 01:33:03 +02:00
cnx.recv_count = cntxt.m_recv_cnt;
2017-08-09 22:22:05 +02:00
cnx.recv_idle_time = timestamp - std::max(cntxt.m_started, cntxt.m_last_recv);
2014-07-19 01:33:03 +02:00
cnx.send_count = cntxt.m_send_cnt;
2017-08-09 22:22:05 +02:00
cnx.send_idle_time = timestamp - std::max(cntxt.m_started, cntxt.m_last_send);
2014-07-19 01:33:03 +02:00
cnx.state = get_protocol_state_string(cntxt.m_state);
cnx.live_time = timestamp - cntxt.m_started;
2015-12-14 05:54:39 +01:00
2017-05-27 12:35:54 +02:00
cnx.localhost = cntxt.m_remote_address.is_loopback();
cnx.local_ip = cntxt.m_remote_address.is_local();
2015-12-14 05:54:39 +01:00
auto connection_time = time(NULL) - cntxt.m_started;
if (connection_time == 0)
{
cnx.avg_download = 0;
cnx.avg_upload = 0;
}
else
{
cnx.avg_download = cntxt.m_recv_cnt / connection_time / 1024;
cnx.avg_upload = cntxt.m_send_cnt / connection_time / 1024;
}
cnx.current_download = cntxt.m_current_speed_down / 1024;
cnx.current_upload = cntxt.m_current_speed_up / 1024;
2017-11-18 00:52:50 +01:00
cnx.connection_id = epee::string_tools::pod_to_hex(cntxt.m_connection_id);
epee: add SSL support
RPC connections now have optional tranparent SSL.
An optional private key and certificate file can be passed,
using the --{rpc,daemon}-ssl-private-key and
--{rpc,daemon}-ssl-certificate options. Those have as
argument a path to a PEM format private private key and
certificate, respectively.
If not given, a temporary self signed certificate will be used.
SSL can be enabled or disabled using --{rpc}-ssl, which
accepts autodetect (default), disabled or enabled.
Access can be restricted to particular certificates using the
--rpc-ssl-allowed-certificates, which takes a list of
paths to PEM encoded certificates. This can allow a wallet to
connect to only the daemon they think they're connected to,
by forcing SSL and listing the paths to the known good
certificates.
To generate long term certificates:
openssl genrsa -out /tmp/KEY 4096
openssl req -new -key /tmp/KEY -out /tmp/REQ
openssl x509 -req -days 999999 -sha256 -in /tmp/REQ -signkey /tmp/KEY -out /tmp/CERT
/tmp/KEY is the private key, and /tmp/CERT is the certificate,
both in PEM format. /tmp/REQ can be removed. Adjust the last
command to set expiration date, etc, as needed. It doesn't
make a whole lot of sense for monero anyway, since most servers
will run with one time temporary self signed certificates anyway.
SSL support is transparent, so all communication is done on the
existing ports, with SSL autodetection. This means you can start
using an SSL daemon now, but you should not enforce SSL yet or
nothing will talk to you.
2018-06-15 00:44:48 +02:00
cnx.ssl = cntxt.m_ssl;
2017-07-02 23:41:15 +02:00
2017-08-12 11:59:54 +02:00
cnx.height = cntxt.m_remote_blockchain_height;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
cnx.pruning_seed = cntxt.m_pruning_seed;
2017-08-12 11:59:54 +02:00
2014-07-19 01:33:03 +02:00
connections.push_back(cnx);
return true;
});
return connections;
}
2014-03-20 12:46:11 +01:00
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2019-11-06 07:28:33 +01:00
bool t_cryptonote_protocol_handler<t_core>::process_payload_sync_data(CORE_SYNC_DATA&& hshd, cryptonote_connection_context& context, bool is_inital)
2014-03-03 23:07:58 +01:00
{
2017-08-13 04:04:55 +02:00
if(context.m_state == cryptonote_connection_context::state_before_handshake && !is_inital)
2014-03-03 23:07:58 +01:00
return true;
if(context.m_state == cryptonote_connection_context::state_synchronizing)
return true;
2017-08-09 10:31:00 +02:00
// from v6, if the peer advertises a top block version, reject if it's not what it should be (will only work if no voting)
2017-12-07 22:39:48 +01:00
if (hshd.current_height > 0)
2017-08-09 10:31:00 +02:00
{
2017-12-07 22:39:48 +01:00
const uint8_t version = m_core.get_ideal_hard_fork_version(hshd.current_height - 1);
if (version >= 6 && version != hshd.top_version)
{
2018-04-16 04:02:26 +02:00
if (version < hshd.top_version && version == m_core.get_ideal_hard_fork_version())
2017-12-07 22:39:48 +01:00
MCLOG_RED(el::Level::Warning, "global", context << " peer claims higher version that we think (" <<
2017-12-31 18:32:57 +01:00
(unsigned)hshd.top_version << " for " << (hshd.current_height - 1) << " instead of " << (unsigned)version <<
2017-12-07 22:39:48 +01:00
") - we may be forked from the network and a software upgrade may be needed");
return false;
}
2017-08-09 10:31:00 +02:00
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
// reject weird pruning schemes
if (hshd.pruning_seed)
{
const uint32_t log_stripes = tools::get_pruning_log_stripes(hshd.pruning_seed);
if (log_stripes != CRYPTONOTE_PRUNING_LOG_STRIPES || tools::get_pruning_stripe(hshd.pruning_seed) > (1u << log_stripes))
{
MWARNING(context << " peer claim unexpected pruning seed " << epee::string_tools::to_string_hex(hshd.pruning_seed) << ", disconnecting");
return false;
}
}
2017-08-12 11:59:54 +02:00
context.m_remote_blockchain_height = hshd.current_height;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
context.m_pruning_seed = hshd.pruning_seed;
#ifdef CRYPTONOTE_PRUNING_DEBUG_SPOOF_SEED
context.m_pruning_seed = tools::make_pruning_seed(1 + (context.m_remote_address.as<epee::net_utils::ipv4_network_address>().ip()) % (1 << CRYPTONOTE_PRUNING_LOG_STRIPES), CRYPTONOTE_PRUNING_LOG_STRIPES);
LOG_INFO_CC(context, "New connection posing as pruning seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) << ", seed address " << &context.m_pruning_seed);
#endif
2017-08-12 11:59:54 +02:00
2019-11-18 23:18:41 +01:00
// No chain synchronization over hidden networks (tor, i2p, etc.)
if(context.m_remote_address.get_zone() != epee::net_utils::zone::public_)
{
context.m_state = cryptonote_connection_context::state_normal;
return true;
}
auto curr_height = m_core.get_current_blockchain_height();
context.m_need_blink_sync = false;
2019-11-06 07:28:33 +01:00
// Check for any blink txes being advertised that we don't know about
2019-11-18 23:38:16 +01:00
if (m_core.get_blockchain_storage().get_current_hard_fork_version() >= HF_VERSION_BLINK)
2019-11-06 07:28:33 +01:00
{
2019-11-18 23:18:41 +01:00
if (hshd.blink_blocks.size() != hshd.blink_hash.size())
{
MWARNING(context << " peer sent illegal mismatched blink heights/hashes; disconnecting");
return false;
}
else if (hshd.blink_blocks.size() > 1000)
{
MWARNING(context << " peer sent too many post-checkpoint blink blocks; disconnecting");
return false;
}
// Peer sends us HEIGHT -> HASH pairs, where the HASH is the xor'ed tx hashes of all blink
// txes mined at the given HEIGHT. If the HASH is different than our hash for the same height
// *and* different than the last height the peer sent then we will request the blink txes for
// that height.
const uint64_t immutable_height = m_core.get_blockchain_storage().get_immutable_height();
2019-11-20 01:24:48 +01:00
// Delete any irrelevant heights > 0 (the mempool) and <= the immutable height
context.m_blink_state.erase(context.m_blink_state.lower_bound(1), context.m_blink_state.lower_bound(immutable_height + 1));
2019-11-18 23:18:41 +01:00
auto our_blink_hashes = m_core.get_pool().get_blink_checksums();
uint64_t last_height;
2019-11-20 01:24:48 +01:00
MDEBUG("Peer sent " << hshd.blink_blocks.size() << " blink hashes");
2019-11-18 23:18:41 +01:00
for (size_t i = 0; i < hshd.blink_blocks.size(); i++) {
auto &height = hshd.blink_blocks[i];
if (i == 0 || height > last_height)
last_height = height;
else {
2019-11-06 07:28:33 +01:00
MWARNING(context << " peer sent blink tx heights out of order, which is not valid; disconnecting");
return false;
}
2019-11-18 23:18:41 +01:00
if (height > 0 && (height < immutable_height || height >= curr_height))
{
// We're either past the immutable height (in which case we don't care about the blink
// signatures), or we don't know about the advertised block yet (we'll get the blink info
// when we get the block). Skip it but don't disconnect because this isn't invalid.
continue;
2019-11-06 07:28:33 +01:00
}
2019-11-18 23:18:41 +01:00
auto &hash = hshd.blink_hash[i];
2019-11-06 07:28:33 +01:00
2019-11-18 23:18:41 +01:00
auto it = our_blink_hashes.find(height);
if (it != our_blink_hashes.end() && it->second == hash)
{ // Matches our hash already, great
context.m_blink_state.erase(height);
continue;
}
2019-11-06 07:28:33 +01:00
2019-11-18 23:18:41 +01:00
auto ctx_it = context.m_blink_state.lower_bound(height);
if (ctx_it == context.m_blink_state.end() || ctx_it->first != height) // Height not found in peer context
2019-11-20 01:24:48 +01:00
context.m_blink_state.emplace_hint(ctx_it, height, std::make_pair(hash, true));
2019-11-18 23:18:41 +01:00
else if (ctx_it->second.first != hash) // Hash changed, update and request
{
ctx_it->second.first = hash;
ctx_it->second.second = true;
}
else
continue;
2019-11-06 07:28:33 +01:00
2019-11-18 23:18:41 +01:00
context.m_need_blink_sync = true;
}
2017-02-24 01:29:47 +01:00
2019-11-18 23:18:41 +01:00
if (context.m_need_blink_sync)
MINFO(context << "Need to synchronized blink signatures");
2014-03-03 23:07:58 +01:00
}
2019-11-18 23:18:41 +01:00
uint64_t target = m_core.get_target_blockchain_height();
if (target == 0)
target = curr_height;
2019-04-09 10:07:13 +02:00
2017-02-15 15:38:38 +01:00
if (hshd.current_height > target)
{
2015-12-14 05:54:39 +01:00
/* As I don't know if accessing hshd from core could be a good practice,
2014-06-04 22:50:13 +02:00
I prefer pushing target height to the core at the same time it is pushed to the user.
Nz. */
2019-11-18 23:18:41 +01:00
int64_t diff = static_cast<int64_t>(hshd.current_height) - static_cast<int64_t>(curr_height);
2017-08-22 18:16:57 +02:00
uint64_t abs_diff = std::abs(diff);
2019-11-18 23:18:41 +01:00
uint64_t max_block_height = std::max(hshd.current_height, curr_height);
MCLOG(is_inital ? el::Level::Info : el::Level::Debug, "global", context << "Sync data returned a new top block candidate: " << curr_height << " -> " << hshd.current_height
2018-08-20 09:14:06 +02:00
<< " [Your node is " << abs_diff << " blocks (" << (abs_diff / (24 * 60 * 60 / DIFFICULTY_TARGET_V2)) << " days) "
2014-05-25 19:06:40 +02:00
<< (0 <= diff ? std::string("behind") : std::string("ahead"))
Change logging to easylogging++
This replaces the epee and data_loggers logging systems with
a single one, and also adds filename:line and explicit severity
levels. Categories may be defined, and logging severity set
by category (or set of categories). epee style 0-4 log level
maps to a sensible severity configuration. Log files now also
rotate when reaching 100 MB.
To select which logs to output, use the MONERO_LOGS environment
variable, with a comma separated list of categories (globs are
supported), with their requested severity level after a colon.
If a log matches more than one such setting, the last one in
the configuration string applies. A few examples:
This one is (mostly) silent, only outputting fatal errors:
MONERO_LOGS=*:FATAL
This one is very verbose:
MONERO_LOGS=*:TRACE
This one is totally silent (logwise):
MONERO_LOGS=""
This one outputs all errors and warnings, except for the
"verify" category, which prints just fatal errors (the verify
category is used for logs about incoming transactions and
blocks, and it is expected that some/many will fail to verify,
hence we don't want the spam):
MONERO_LOGS=*:WARNING,verify:FATAL
Log levels are, in decreasing order of priority:
FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
Subcategories may be added using prefixes and globs. This
example will output net.p2p logs at the TRACE level, but all
other net* logs only at INFO:
MONERO_LOGS=*:ERROR,net*:INFO,net.p2p:TRACE
Logs which are intended for the user (which Monero was using
a lot through epee, but really isn't a nice way to go things)
should use the "global" category. There are a few helper macros
for using this category, eg: MGINFO("this shows up by default")
or MGINFO_RED("this is red"), to try to keep a similar look
and feel for now.
Existing epee log macros still exist, and map to the new log
levels, but since they're used as a "user facing" UI element
as much as a logging system, they often don't map well to log
severities (ie, a log level 0 log may be an error, or may be
something we want the user to see, such as an important info).
In those cases, I tried to use the new macros. In other cases,
I left the existing macros in. When modifying logs, it is
probably best to switch to the new macros with explicit levels.
The --log-level options and set_log commands now also accept
category settings, in addition to the epee style log levels.
2017-01-01 17:34:23 +01:00
<< "] " << ENDL << "SYNCHRONIZATION started");
2019-11-18 23:18:41 +01:00
if (hshd.current_height >= curr_height + 5) // don't switch to unsafe mode just for a few blocks
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
{
2018-05-28 13:14:11 +02:00
m_core.safesyncmode(false);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
}
if (m_core.get_target_blockchain_height() == 0) // only when sync starts
{
m_sync_timer.resume();
m_sync_timer.reset();
m_add_timer.pause();
m_add_timer.reset();
m_last_add_end_time = 0;
m_sync_spans_downloaded = 0;
m_sync_old_spans_downloaded = 0;
m_sync_bad_spans_downloaded = 0;
m_sync_download_chain_size = 0;
m_sync_download_objects_size = 0;
}
2019-11-18 23:18:41 +01:00
m_core.set_target_blockchain_height((hshd.current_height));
2017-02-15 15:38:38 +01:00
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MINFO(context << "Remote blockchain height: " << hshd.current_height << ", id: " << hshd.top_id);
2019-02-25 02:31:45 +01:00
if (m_no_sync)
{
context.m_state = cryptonote_connection_context::state_normal;
return true;
}
2019-11-18 23:18:41 +01:00
if(m_core.have_block(hshd.top_id))
{
context.m_state = cryptonote_connection_context::state_normal;
if(is_inital && target == curr_height)
on_connection_synchronized();
}
else
{
context.m_state = cryptonote_connection_context::state_synchronizing;
}
if (context.m_need_blink_sync || context.m_state == cryptonote_connection_context::state_synchronizing)
{
//let the socket to send response to handshake, but request callback, to let send request data after response
LOG_PRINT_CCONTEXT_L2("requesting callback");
++context.m_callback_request_count;
m_p2p->request_callback(context);
MLOG_PEER_STATE("requesting callback");
}
2014-03-03 23:07:58 +01:00
return true;
}
2015-12-14 05:54:39 +01:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2014-03-03 23:07:58 +01:00
bool t_cryptonote_protocol_handler<t_core>::get_payload_sync_data(CORE_SYNC_DATA& hshd)
{
m_core.get_blockchain_top(hshd.current_height, hshd.top_id);
2017-08-23 02:22:12 +02:00
hshd.top_version = m_core.get_ideal_hard_fork_version(hshd.current_height);
2017-08-12 16:24:39 +02:00
hshd.cumulative_difficulty = m_core.get_block_cumulative_difficulty(hshd.current_height);
2014-03-03 23:07:58 +01:00
hshd.current_height +=1;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
hshd.pruning_seed = m_core.get_blockchain_pruning_seed();
2019-11-20 01:24:48 +01:00
auto our_blink_hashes = m_core.get_pool().get_blink_checksums();
hshd.blink_blocks.reserve(our_blink_hashes.size());
hshd.blink_hash.reserve(our_blink_hashes.size());
for (auto &h : our_blink_hashes)
{
hshd.blink_blocks.push_back(h.first);
hshd.blink_hash.push_back(h.second);
}
2014-03-03 23:07:58 +01:00
return true;
}
2015-12-14 05:54:39 +01:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2014-03-03 23:07:58 +01:00
bool t_cryptonote_protocol_handler<t_core>::get_payload_sync_data(blobdata& data)
{
2019-10-31 23:26:58 +01:00
CORE_SYNC_DATA hsd{};
2014-03-03 23:07:58 +01:00
get_payload_sync_data(hsd);
epee::serialization::store_t_to_binary(hsd, data);
return true;
}
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2016-10-26 21:00:08 +02:00
int t_cryptonote_protocol_handler<t_core>::handle_notify_new_fluffy_block(int command, NOTIFY_NEW_FLUFFY_BLOCK::request& arg, cryptonote_connection_context& context)
{
2019-03-27 21:38:42 +01:00
MLOGIF_P2P_MESSAGE(crypto::hash hash; cryptonote::block b; bool ret = cryptonote::parse_and_validate_block_from_blob(arg.b.block, b, &hash);, ret, "Received NOTIFY_NEW_FLUFFY_BLOCK " << hash << " (height " << arg.current_blockchain_height << ", " << arg.b.txs.size() << " txes)");
2016-10-26 21:00:08 +02:00
if(context.m_state != cryptonote_connection_context::state_normal)
return 1;
2017-07-02 23:41:15 +02:00
if(!is_synchronized()) // can happen if a peer connection goes to normal but another thread still hasn't finished adding queued blocks
{
LOG_DEBUG_CC(context, "Received new block while syncing, ignored");
return 1;
}
2016-10-26 21:00:08 +02:00
m_core.pause_mine();
block new_block;
transaction miner_tx;
if(parse_and_validate_block_from_blob(arg.b.block, new_block))
{
2017-02-11 20:38:18 +01:00
// This is a second notification, we must have asked for some missing tx
2016-10-26 21:00:08 +02:00
if(!context.m_requested_objects.empty())
{
// What we asked for != to what we received ..
if(context.m_requested_objects.size() != arg.b.txs.size())
{
LOG_ERROR_CCONTEXT
(
"NOTIFY_NEW_FLUFFY_BLOCK -> request/response mismatch, "
<< "block = " << epee::string_tools::pod_to_hex(get_blob_hash(arg.b.block))
<< ", requested = " << context.m_requested_objects.size()
<< ", received = " << new_block.tx_hashes.size()
<< ", dropping connection"
);
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2016-10-26 21:00:08 +02:00
m_core.resume_mine();
return 1;
}
}
2018-04-16 01:16:02 +02:00
std::vector<blobdata> have_tx;
2016-10-26 21:00:08 +02:00
// Instead of requesting missing transactions by hash like BTC,
// we do it by index (thanks to a suggestion from moneromooo) because
// we're way cooler .. and also because they're smaller than hashes.
//
// Also, remember to pepper some whitespace changes around to bother
// moneromooo ... only because I <3 him.
2018-01-26 11:13:06 +01:00
std::vector<uint64_t> need_tx_indices;
2016-10-26 21:00:08 +02:00
transaction tx;
crypto::hash tx_hash;
2017-01-22 21:38:10 +01:00
for(auto& tx_blob: arg.b.txs)
2016-10-26 21:00:08 +02:00
{
if(parse_and_validate_tx_from_blob(tx_blob, tx))
{
try
{
if(!get_transaction_hash(tx, tx_hash))
{
LOG_PRINT_CCONTEXT_L1
(
"NOTIFY_NEW_FLUFFY_BLOCK: get_transaction_hash failed"
<< ", dropping connection"
);
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2016-10-26 21:00:08 +02:00
m_core.resume_mine();
return 1;
}
}
catch(...)
{
LOG_PRINT_CCONTEXT_L1
(
"NOTIFY_NEW_FLUFFY_BLOCK: get_transaction_hash failed"
<< ", exception thrown"
<< ", dropping connection"
);
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2016-10-26 21:00:08 +02:00
m_core.resume_mine();
return 1;
}
// hijacking m_requested objects in connection context to patch up
// a possible DOS vector pointed out by @monero-moo where peers keep
// sending (0...n-1) transactions.
// If requested objects is not empty, then we must have asked for
// some missing transacionts, make sure that they're all there.
//
// Can I safely re-use this field? I think so, but someone check me!
if(!context.m_requested_objects.empty())
{
auto req_tx_it = context.m_requested_objects.find(tx_hash);
if(req_tx_it == context.m_requested_objects.end())
{
LOG_ERROR_CCONTEXT
(
"Peer sent wrong transaction (NOTIFY_NEW_FLUFFY_BLOCK): "
<< "transaction with id = " << tx_hash << " wasn't requested, "
<< "dropping connection"
);
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2016-10-26 21:00:08 +02:00
m_core.resume_mine();
return 1;
}
context.m_requested_objects.erase(req_tx_it);
}
// we might already have the tx that the peer
// sent in our pool, so don't verify again..
2019-11-06 07:14:06 +01:00
if(!m_core.get_pool().have_tx(tx_hash))
2016-10-26 21:00:08 +02:00
{
2017-02-11 20:38:18 +01:00
MDEBUG("Incoming tx " << tx_hash << " not in pool, adding");
2019-10-31 23:26:58 +01:00
cryptonote::tx_verification_context tvc{};
Generic burn fee checking + blink burn fee checking
This adds the ability for check_fee() to also check the burn amount.
This requires passing extra info through `add_tx()` (and the various
things that call it), so I took the:
bool keeped_by_block, bool relayed, bool do_not_relay
argument triplet, moved it into a struct in tx_pool.h, then added the other fee
options there (along with some static factory functions for generating the
typical sets of option).
The majority of this commit is chasing that change through the codebase and
test suite.
This is used by blink but should also help LNS and other future burn
transactions to verify a burn amount simply when adding the transation to the
mempool. It supports a fixed burn amount, a burn amount as a multiple of the
minimum tx fee, and also allows you to increase the minimum tx fee (so that,
for example, we could require blink txes to pay miners 250% of the usual
minimum (unimportant) priority tx fee.
- Removed a useless core::add_new_tx() overload that wasn't used anywhere.
Blink-specific changes:
(I'd normally separate these into a separate commit, but they got interwoven
fairly heavily with the above change).
- changed the way blink burning is specified so that we have three knobs for
fee adjustment (fixed burn fee; base fee multiple; and required miner tx fee).
The fixed amount is currently 0, base fee is 400%, and require miner tx fee is
simply 100% (i.e. no different than a normal transaction). This is the same as
before this commit, but is changing how they are being specified in
cryptonote_config.h.
- blink tx fee, burn amount, and miner tx fee (if > 100%) now get checked
before signing a blink tx. (These fee checks don't apply to anyone else --
when propagating over the network only the miner tx fee is checked).
- Added a couple of checks for blink quorums: 1) make sure they have reached
the blink hf; 2) make sure the submitted tx version conforms to the current hf
min/max tx version.
- print blink fee information in simplewallet's `fee` output
- add "typical" fee calculations in the `fee` output:
[wallet T6SCwL (has locked stakes)]: fee
Current fee is 0.000000850 loki per byte + 0.020000000 loki per output
No backlog at priority 1
No backlog at priority 2
No backlog at priority 3
No backlog at priority 4
Current blink fee is 0.000004250 loki per byte + 0.100000000 loki per output
Estimated typical small transaction fees: 0.042125000 (unimportant), 0.210625000 (normal), 1.053125000 (elevated), 5.265625000 (priority), 0.210625000 (blink)
where "small" here is the same tx size (2500 bytes + 2 outputs) used to
estimate backlogs.
2019-11-09 04:14:15 +01:00
if(!m_core.handle_incoming_tx(tx_blob, tvc, tx_pool_options::from_block()) || tvc.m_verifivation_failed)
2016-10-26 21:00:08 +02:00
{
LOG_PRINT_CCONTEXT_L1("Block verification failed: transaction verification failed, dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2016-10-26 21:00:08 +02:00
m_core.resume_mine();
return 1;
}
//
// future todo:
// tx should only not be added to pool if verification failed, but
// maybe in the future could not be added for other reasons
// according to monero-moo so keep track of these separately ..
//
}
}
else
{
LOG_ERROR_CCONTEXT
(
2017-02-11 20:38:18 +01:00
"sent wrong tx: failed to parse and validate transaction: "
2016-10-26 21:00:08 +02:00
<< epee::string_tools::buff_to_hex_nodelimer(tx_blob)
2017-02-11 20:38:18 +01:00
<< ", dropping connection"
2016-10-26 21:00:08 +02:00
);
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2016-10-26 21:00:08 +02:00
m_core.resume_mine();
return 1;
}
}
// The initial size equality check could have been fooled if the sender
// gave us the number of transactions we asked for, but not the right
// ones. This check make sure the transactions we asked for were the
// ones we received.
if(context.m_requested_objects.size())
{
Change logging to easylogging++
This replaces the epee and data_loggers logging systems with
a single one, and also adds filename:line and explicit severity
levels. Categories may be defined, and logging severity set
by category (or set of categories). epee style 0-4 log level
maps to a sensible severity configuration. Log files now also
rotate when reaching 100 MB.
To select which logs to output, use the MONERO_LOGS environment
variable, with a comma separated list of categories (globs are
supported), with their requested severity level after a colon.
If a log matches more than one such setting, the last one in
the configuration string applies. A few examples:
This one is (mostly) silent, only outputting fatal errors:
MONERO_LOGS=*:FATAL
This one is very verbose:
MONERO_LOGS=*:TRACE
This one is totally silent (logwise):
MONERO_LOGS=""
This one outputs all errors and warnings, except for the
"verify" category, which prints just fatal errors (the verify
category is used for logs about incoming transactions and
blocks, and it is expected that some/many will fail to verify,
hence we don't want the spam):
MONERO_LOGS=*:WARNING,verify:FATAL
Log levels are, in decreasing order of priority:
FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
Subcategories may be added using prefixes and globs. This
example will output net.p2p logs at the TRACE level, but all
other net* logs only at INFO:
MONERO_LOGS=*:ERROR,net*:INFO,net.p2p:TRACE
Logs which are intended for the user (which Monero was using
a lot through epee, but really isn't a nice way to go things)
should use the "global" category. There are a few helper macros
for using this category, eg: MGINFO("this shows up by default")
or MGINFO_RED("this is red"), to try to keep a similar look
and feel for now.
Existing epee log macros still exist, and map to the new log
levels, but since they're used as a "user facing" UI element
as much as a logging system, they often don't map well to log
severities (ie, a log level 0 log may be an error, or may be
something we want the user to see, such as an important info).
In those cases, I tried to use the new macros. In other cases,
I left the existing macros in. When modifying logs, it is
probably best to switch to the new macros with explicit levels.
The --log-level options and set_log commands now also accept
category settings, in addition to the epee style log levels.
2017-01-01 17:34:23 +01:00
MERROR
2016-10-26 21:00:08 +02:00
(
"NOTIFY_NEW_FLUFFY_BLOCK: peer sent the number of transaction requested"
<< ", but not the actual transactions requested"
<< ", context.m_requested_objects.size() = " << context.m_requested_objects.size()
Change logging to easylogging++
This replaces the epee and data_loggers logging systems with
a single one, and also adds filename:line and explicit severity
levels. Categories may be defined, and logging severity set
by category (or set of categories). epee style 0-4 log level
maps to a sensible severity configuration. Log files now also
rotate when reaching 100 MB.
To select which logs to output, use the MONERO_LOGS environment
variable, with a comma separated list of categories (globs are
supported), with their requested severity level after a colon.
If a log matches more than one such setting, the last one in
the configuration string applies. A few examples:
This one is (mostly) silent, only outputting fatal errors:
MONERO_LOGS=*:FATAL
This one is very verbose:
MONERO_LOGS=*:TRACE
This one is totally silent (logwise):
MONERO_LOGS=""
This one outputs all errors and warnings, except for the
"verify" category, which prints just fatal errors (the verify
category is used for logs about incoming transactions and
blocks, and it is expected that some/many will fail to verify,
hence we don't want the spam):
MONERO_LOGS=*:WARNING,verify:FATAL
Log levels are, in decreasing order of priority:
FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
Subcategories may be added using prefixes and globs. This
example will output net.p2p logs at the TRACE level, but all
other net* logs only at INFO:
MONERO_LOGS=*:ERROR,net*:INFO,net.p2p:TRACE
Logs which are intended for the user (which Monero was using
a lot through epee, but really isn't a nice way to go things)
should use the "global" category. There are a few helper macros
for using this category, eg: MGINFO("this shows up by default")
or MGINFO_RED("this is red"), to try to keep a similar look
and feel for now.
Existing epee log macros still exist, and map to the new log
levels, but since they're used as a "user facing" UI element
as much as a logging system, they often don't map well to log
severities (ie, a log level 0 log may be an error, or may be
something we want the user to see, such as an important info).
In those cases, I tried to use the new macros. In other cases,
I left the existing macros in. When modifying logs, it is
probably best to switch to the new macros with explicit levels.
The --log-level options and set_log commands now also accept
category settings, in addition to the epee style log levels.
2017-01-01 17:34:23 +01:00
<< ", dropping connection"
2016-10-26 21:00:08 +02:00
);
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2016-10-26 21:00:08 +02:00
m_core.resume_mine();
return 1;
}
size_t tx_idx = 0;
2017-01-22 21:38:10 +01:00
for(auto& tx_hash: new_block.tx_hashes)
2016-10-26 21:00:08 +02:00
{
2017-05-14 15:06:55 +02:00
cryptonote::blobdata txblob;
2019-11-06 07:14:06 +01:00
if(m_core.get_pool().get_transaction(tx_hash, txblob))
2016-10-26 21:00:08 +02:00
{
2017-05-14 15:06:55 +02:00
have_tx.push_back(txblob);
2016-10-26 21:00:08 +02:00
}
else
{
2017-02-11 20:38:18 +01:00
std::vector<crypto::hash> tx_ids;
2018-04-16 01:16:02 +02:00
std::vector<transaction> txes;
std::vector<crypto::hash> missing;
2017-02-11 20:38:18 +01:00
tx_ids.push_back(tx_hash);
if (m_core.get_transactions(tx_ids, txes, missing) && missing.empty())
{
2017-03-13 20:16:25 +01:00
if (txes.size() == 1)
{
have_tx.push_back(tx_to_blob(txes.front()));
}
else
{
MERROR("1 tx requested, none not found, but " << txes.size() << " returned");
m_core.resume_mine();
return 1;
}
2017-02-11 20:38:18 +01:00
}
else
{
MDEBUG("Tx " << tx_hash << " not found in pool");
need_tx_indices.push_back(tx_idx);
}
2016-10-26 21:00:08 +02:00
}
++tx_idx;
}
if(!need_tx_indices.empty()) // drats, we don't have everything..
{
// request non-mempool txs
2017-02-11 20:38:18 +01:00
MDEBUG("We are missing " << need_tx_indices.size() << " txes for this fluffy block");
for (auto txidx: need_tx_indices)
MDEBUG(" tx " << new_block.tx_hashes[txidx]);
2016-10-26 21:00:08 +02:00
NOTIFY_REQUEST_FLUFFY_MISSING_TX::request missing_tx_req;
2017-02-11 20:38:18 +01:00
missing_tx_req.block_hash = get_block_hash(new_block);
2016-10-26 21:00:08 +02:00
missing_tx_req.current_blockchain_height = arg.current_blockchain_height;
missing_tx_req.missing_tx_indices = std::move(need_tx_indices);
m_core.resume_mine();
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_FLUFFY_MISSING_TX: missing_tx_indices.size()=" << missing_tx_req.missing_tx_indices.size() );
2016-10-26 21:00:08 +02:00
post_notify<NOTIFY_REQUEST_FLUFFY_MISSING_TX>(missing_tx_req, context);
}
else // whoo-hoo we've got em all ..
{
2017-02-11 20:38:18 +01:00
MDEBUG("We have all needed txes for this fluffy block");
2019-06-26 06:00:05 +02:00
block_complete_entry b = {};
b.block = arg.b.block;
b.txs = have_tx;
2016-10-26 21:00:08 +02:00
2018-04-16 01:16:02 +02:00
std::vector<block_complete_entry> blocks;
2016-10-26 21:00:08 +02:00
blocks.push_back(b);
2019-06-04 05:50:31 +02:00
2018-11-23 12:15:04 +01:00
std::vector<block> pblocks;
2019-06-26 06:00:05 +02:00
if (!m_core.prepare_handle_incoming_blocks(blocks, pblocks))
2018-11-23 14:05:48 +01:00
{
LOG_PRINT_CCONTEXT_L0("Failure in prepare_handle_incoming_blocks");
m_core.resume_mine();
return 1;
}
2016-10-26 21:00:08 +02:00
2019-10-31 23:26:58 +01:00
block_verification_context bvc{};
2019-06-26 06:00:05 +02:00
m_core.handle_incoming_block(arg.b.block, pblocks.empty() ? NULL : &pblocks[0], bvc, nullptr /*checkpoint*/); // got block from handle_notify_new_block
2017-08-29 17:10:53 +02:00
if (!m_core.cleanup_handle_incoming_blocks(true))
{
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
m_core.resume_mine();
return 1;
}
2016-10-26 21:00:08 +02:00
m_core.resume_mine();
if( bvc.m_verifivation_failed )
{
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, true, false);
2016-10-26 21:00:08 +02:00
return 1;
}
if( bvc.m_added_to_main_chain )
{
//TODO: Add here announce protocol usage
2019-10-31 23:26:58 +01:00
NOTIFY_NEW_FLUFFY_BLOCK::request reg_arg{};
2016-10-26 21:00:08 +02:00
reg_arg.current_blockchain_height = arg.current_blockchain_height;
2017-03-12 15:14:51 +01:00
reg_arg.b = b;
2016-10-26 21:00:08 +02:00
relay_block(reg_arg, context);
}
else if( bvc.m_marked_as_orphaned )
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
context.m_needed_objects.clear();
2016-10-26 21:00:08 +02:00
context.m_state = cryptonote_connection_context::state_synchronizing;
2019-10-31 23:26:58 +01:00
NOTIFY_REQUEST_CHAIN::request r{};
2019-11-18 23:18:41 +01:00
m_core.get_blockchain_storage().get_short_chain_history(r.block_ids);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() );
2016-10-26 21:00:08 +02:00
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_PEER_STATE("requesting chain");
2016-10-26 21:00:08 +02:00
}
}
}
else
{
LOG_ERROR_CCONTEXT
(
2017-02-11 20:38:18 +01:00
"sent wrong block: failed to parse and validate block: "
2016-10-26 21:00:08 +02:00
<< epee::string_tools::buff_to_hex_nodelimer(arg.b.block)
2017-02-11 20:38:18 +01:00
<< ", dropping connection"
2016-10-26 21:00:08 +02:00
);
m_core.resume_mine();
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2016-10-26 21:00:08 +02:00
return 1;
}
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2018-07-12 03:58:17 +02:00
int t_cryptonote_protocol_handler<t_core>::handle_uptime_proof(int command, NOTIFY_UPTIME_PROOF::request& arg, cryptonote_connection_context& context)
{
MLOG_P2P_MESSAGE("Received NOTIFY_UPTIME_PROOF");
2019-09-18 07:22:27 +02:00
// NOTE: Don't relay your own uptime proof, otherwise we have the following situation
// Node1 sends uptime ->
// Node2 receives uptime and relays it back to Node1 for acknowledgement ->
// Node1 receives it, handle_uptime_proof returns true to acknowledge, Node1 tries to resend to the same peers again
// Instead, if we receive our own uptime proof, then acknowledge but don't
// send on. If the we are missing an uptime proof it will have been
// submitted automatically by the daemon itself instead of
// using my own proof relayed by other nodes.
(void)context;
bool my_uptime_proof_confirmation = false;
2019-09-18 07:36:00 +02:00
if (m_core.handle_uptime_proof(arg, my_uptime_proof_confirmation))
2019-09-18 07:22:27 +02:00
{
if (!my_uptime_proof_confirmation)
{
// NOTE: The default exclude context contains the peer who sent us this
// uptime proof, we want to ensure we relay it back so they know that the
// peer they relayed to received their uptime and confirm it, so send in an
// empty context so we don't omit the source peer from the relay back.
cryptonote_connection_context empty_context = {};
2019-09-18 07:36:00 +02:00
relay_uptime_proof(arg, empty_context);
2019-09-18 07:22:27 +02:00
}
}
2018-07-12 03:58:17 +02:00
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2019-05-31 03:06:42 +02:00
int t_cryptonote_protocol_handler<t_core>::handle_notify_new_service_node_vote(int command, NOTIFY_NEW_SERVICE_NODE_VOTE::request& arg, cryptonote_connection_context& context)
2019-05-01 08:01:17 +02:00
{
2019-05-31 03:06:42 +02:00
MLOG_P2P_MESSAGE("Received NOTIFY_NEW_SERVICE_NODE_VOTE (" << arg.votes.size() << " txes)");
2019-05-01 08:01:17 +02:00
if(context.m_state != cryptonote_connection_context::state_normal)
return 1;
if(!is_synchronized())
{
2019-05-31 03:06:42 +02:00
LOG_DEBUG_CC(context, "Received new service node vote while syncing, ignored");
2019-05-01 08:01:17 +02:00
return 1;
}
for(auto it = arg.votes.begin(); it != arg.votes.end();)
{
cryptonote::vote_verification_context vvc = {};
2019-05-31 03:06:42 +02:00
m_core.add_service_node_vote(*it, vvc);
2019-05-01 08:01:17 +02:00
if (vvc.m_verification_failed)
{
2019-09-17 00:54:44 +02:00
LOG_PRINT_CCONTEXT_L1("Vote type: " << it->type << ", verification failed, dropping connection");
2019-05-01 08:01:17 +02:00
drop_connection(context, false /*add_fail*/, false /*flush_all_spans i.e. delete cached block data from this peer*/);
return 1;
}
if (vvc.m_added_to_pool)
{
it++;
}
else
{
it = arg.votes.erase(it);
}
}
if (arg.votes.size())
2019-05-31 03:06:42 +02:00
relay_service_node_votes(arg, context);
2019-05-01 08:01:17 +02:00
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2016-10-26 21:00:08 +02:00
int t_cryptonote_protocol_handler<t_core>::handle_request_fluffy_missing_tx(int command, NOTIFY_REQUEST_FLUFFY_MISSING_TX::request& arg, cryptonote_connection_context& context)
{
2017-02-11 20:38:18 +01:00
MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_FLUFFY_MISSING_TX (" << arg.missing_tx_indices.size() << " txes), block hash " << arg.block_hash);
2017-01-15 17:05:55 +01:00
2018-04-16 01:16:02 +02:00
std::vector<std::pair<cryptonote::blobdata, block>> local_blocks;
std::vector<cryptonote::blobdata> local_txs;
2016-10-26 21:00:08 +02:00
2017-02-11 20:38:18 +01:00
block b;
if (!m_core.get_block_by_hash(arg.block_hash, b))
{
LOG_ERROR_CCONTEXT("failed to find block: " << arg.block_hash << ", dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2017-02-11 20:38:18 +01:00
return 1;
2016-10-26 21:00:08 +02:00
}
2017-02-11 20:38:18 +01:00
std::vector<crypto::hash> txids;
2016-10-26 21:00:08 +02:00
NOTIFY_NEW_FLUFFY_BLOCK::request fluffy_response;
2017-02-11 20:38:18 +01:00
fluffy_response.b.block = t_serializable_object_to_blob(b);
fluffy_response.current_blockchain_height = arg.current_blockchain_height;
2019-06-12 09:48:46 +02:00
// NOTE: Dupe index check
{
std::unordered_set<uint64_t> requested_index_set;
requested_index_set.reserve(16); // typical maximum number of txs per block
for (uint64_t requested_index : arg.missing_tx_indices)
{
if (!requested_index_set.insert(requested_index).second)
{
LOG_ERROR_CCONTEXT
(
"Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX"
<< ", request is asking for the same tx index more than once "
<< ", tx index = " << requested_index << ", block tx count " << b.tx_hashes.size()
<< ", block_height = " << arg.current_blockchain_height
<< ", dropping connection"
);
drop_connection(context, false, false);
return 1;
}
}
}
2017-01-22 21:38:10 +01:00
for(auto& tx_idx: arg.missing_tx_indices)
2016-10-26 21:00:08 +02:00
{
2017-02-11 20:38:18 +01:00
if(tx_idx < b.tx_hashes.size())
2016-10-26 21:00:08 +02:00
{
2017-06-01 20:42:33 +02:00
MDEBUG(" tx " << b.tx_hashes[tx_idx]);
2017-02-11 20:38:18 +01:00
txids.push_back(b.tx_hashes[tx_idx]);
2016-10-26 21:00:08 +02:00
}
else
{
LOG_ERROR_CCONTEXT
(
"Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX"
<< ", request is asking for a tx whose index is out of bounds "
2017-02-11 20:38:18 +01:00
<< ", tx index = " << tx_idx << ", block tx count " << b.tx_hashes.size()
<< ", block_height = " << arg.current_blockchain_height
2016-10-26 21:00:08 +02:00
<< ", dropping connection"
);
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2016-10-26 21:00:08 +02:00
return 1;
}
2019-06-26 05:04:37 +02:00
}
2017-02-11 20:38:18 +01:00
2018-04-16 01:16:02 +02:00
std::vector<cryptonote::transaction> txs;
std::vector<crypto::hash> missed;
2017-02-11 20:38:18 +01:00
if (!m_core.get_transactions(txids, txs, missed))
{
LOG_ERROR_CCONTEXT("Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX, "
<< "failed to get requested transactions");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2017-02-11 20:38:18 +01:00
return 1;
}
if (!missed.empty() || txs.size() != txids.size())
{
LOG_ERROR_CCONTEXT("Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX, "
<< missed.size() << " requested transactions not found" << ", dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2017-02-11 20:38:18 +01:00
return 1;
}
for(auto& tx: txs)
{
fluffy_response.b.txs.push_back(t_serializable_object_to_blob(tx));
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_P2P_MESSAGE
2016-10-26 21:00:08 +02:00
(
"-->>NOTIFY_RESPONSE_FLUFFY_MISSING_TX: "
<< ", txs.size()=" << fluffy_response.b.txs.size()
<< ", rsp.current_blockchain_height=" << fluffy_response.current_blockchain_height
);
post_notify<NOTIFY_NEW_FLUFFY_BLOCK>(fluffy_response, context);
return 1;
}
Service Node Deregister Part 5 (#89)
* Retrieve quorum list from height, reviewed
* Setup data structures for de/register TX
* Submit and validate partial/full deregisters
* Add P2P relaying of partial deregistration votes
* Code review adjustments for deregistration part 1
- Fix check_tx_semantic
- Remove signature_pod as votes are now stored as blobs. Serialization
overrides don't intefere with crypto::signature anymore.
* deregistration_vote_pool - changed sign/verify interface and removed repeated code
* Misc review, fix sign/verify api, vote threshold
* Deregister/tx edge case handling for combinatoric votes
* core, service_node_list: separated address from service node pubkey
* Retrieve quorum list from height, reviewed
* Setup data structures for de/register TX
* Submit and validate partial/full deregisters
* Add P2P relaying of partial deregistration votes
* Code review adjustments for deregistration part 1
- Fix check_tx_semantic
- Remove signature_pod as votes are now stored as blobs. Serialization
overrides don't intefere with crypto::signature anymore.
* deregistration_vote_pool - changed sign/verify interface and removed repeated code
* Misc review, fix sign/verify api, vote threshold
* Deregister/tx edge case handling for combinatoric votes
* Store service node lists for the duration of deregister lifetimes
* Quorum min/max bug, sort node list, fix node to test list
* Change quorum to store acc pub address, fix oob bug
* Code review for expiring votes, acc keys to pub_key, improve err msgs
* Add early out for is_deregistration_tx and protect against quorum changes
* Remove debug code, fix segfault
* Remove irrelevant check for tx v3 in blockchain, fix >= height for pruning quorum states
Incorrect assumption that a transaction can be kept in the chain if it could
eventually become invalid, because if it were the chain would be split and
eventually these transaction would be dropped. But also that we should not
override the pre-existing logic which handles this case anyway.
2018-07-18 04:42:47 +02:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2014-03-03 23:07:58 +01:00
int t_cryptonote_protocol_handler<t_core>::handle_notify_new_transactions(int command, NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& context)
{
2019-11-06 07:28:33 +01:00
MLOG_P2P_MESSAGE("Received NOTIFY_NEW_TRANSACTIONS (" << arg.txs.size() << " txes w/ " << arg.blinks.size() << " blinks)");
2019-03-27 21:38:42 +01:00
for (const auto &blob: arg.txs)
MLOGIF_P2P_MESSAGE(cryptonote::transaction tx; crypto::hash hash; bool ret = cryptonote::parse_and_validate_tx_from_blob(blob, tx, hash);, ret, "Including transaction " << hash);
2014-03-03 23:07:58 +01:00
if(context.m_state != cryptonote_connection_context::state_normal)
return 1;
2019-11-18 23:18:41 +01:00
// while syncing, core will lock for a long time, so we ignore those txes as they aren't really
// needed anyway, and avoid a long block before replying. (Not for .requested though: in that
// case we specifically asked for these txes).
if(!is_synchronized() && !arg.requested)
2017-05-14 15:06:55 +02:00
{
LOG_DEBUG_CC(context, "Received new tx while syncing, ignored");
return 1;
}
2019-11-25 05:57:15 +01:00
bool bad_blinks = false;
auto parsed_blinks = m_core.parse_incoming_blinks(arg.blinks);
auto &blinks = parsed_blinks.first;
std::unordered_set<crypto::hash> blink_approved;
for (auto &b : blinks)
if (b->approved())
blink_approved.insert(b->get_txhash());
else
bad_blinks = true;
2019-11-25 19:22:30 +01:00
bool all_okay;
2014-03-03 23:07:58 +01:00
{
2019-11-25 19:22:30 +01:00
auto lock = m_core.incoming_tx_lock();
const auto txpool_opts = tx_pool_options::from_peer();
auto parsed_txs = m_core.parse_incoming_txs(arg.txs, txpool_opts);
for (auto &txi : parsed_txs)
if (blink_approved.count(txi.tx_hash))
txi.approved_blink = true;
all_okay = m_core.handle_parsed_txs(parsed_txs, txpool_opts);
// Even if !all_okay (which means we want to drop the connection) we may still have added some
// incoming txs and so still need to finish handling/relaying them
std::vector<cryptonote::blobdata> newtxs;
newtxs.reserve(arg.txs.size());
auto &unknown_txs = parsed_blinks.second;
for (size_t i = 0; i < arg.txs.size(); ++i)
{
if (parsed_txs[i].tvc.m_should_be_relayed)
newtxs.push_back(std::move(arg.txs[i]));
2019-11-25 05:57:15 +01:00
2019-11-25 19:22:30 +01:00
if (parsed_txs[i].tvc.m_added_to_pool)
unknown_txs.erase(parsed_txs[i].tx_hash);
}
arg.txs = std::move(newtxs);
2014-03-03 23:07:58 +01:00
2019-11-25 19:22:30 +01:00
// Attempt to add any blinks signatures we received, but with unknown txs removed (where unknown
// means previously unknown and didn't just get added to the mempool). (Don't bother worrying
// about approved because add_blinks() already does that).
blinks.erase(std::remove_if(blinks.begin(), blinks.end(), [&](const auto &b) { return unknown_txs.count(b->get_txhash()) > 0; }), blinks.end());
m_core.add_blinks(blinks);
}
2019-11-06 07:28:33 +01:00
2019-11-18 23:18:41 +01:00
// If this is a response to a request for txes that we sent (.requested) then don't relay this
// on to our peers because they probably already have it: we just missed it somehow.
if(arg.txs.size() && !arg.requested)
2014-03-03 23:07:58 +01:00
{
//TODO: add announce usage here
relay_transactions(arg, context);
}
2019-11-25 05:57:15 +01:00
if (!all_okay || bad_blinks)
2019-11-06 07:28:33 +01:00
{
2019-11-25 05:57:15 +01:00
LOG_PRINT_CCONTEXT_L1((!all_okay && bad_blinks ? "Tx and Blink" : !all_okay ? "Tx" : "Blink") << " verification(s) failed, dropping connection");
2019-11-06 07:28:33 +01:00
drop_connection(context, false, false);
}
2018-04-28 04:07:51 +02:00
return 1;
2014-03-03 23:07:58 +01:00
}
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2019-11-18 23:18:41 +01:00
int t_cryptonote_protocol_handler<t_core>::handle_request_get_blocks(int command, NOTIFY_REQUEST_GET_BLOCKS::request& arg, cryptonote_connection_context& context)
2014-03-03 23:07:58 +01:00
{
2019-11-18 23:18:41 +01:00
MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_GET_BLOCKS (" << arg.blocks.size() << " blocks)");
2019-03-09 10:11:44 +01:00
2019-11-18 23:18:41 +01:00
if (arg.blocks.size() > CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT)
{
LOG_ERROR_CCONTEXT(
"Requested blocks count is too big ("
<< arg.blocks.size() << ") expected not more than "
<< CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT);
drop_connection(context, false, false);
return 1;
}
2019-03-09 10:11:44 +01:00
2019-11-18 23:18:41 +01:00
NOTIFY_RESPONSE_GET_BLOCKS::request rsp;
if(!m_core.get_blockchain_storage().handle_get_blocks(arg, rsp))
2014-03-03 23:07:58 +01:00
{
2019-11-18 23:18:41 +01:00
LOG_ERROR_CCONTEXT("failed to handle request NOTIFY_REQUEST_GET_BLOCKS, dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2017-07-02 23:41:15 +02:00
return 1;
2014-03-03 23:07:58 +01:00
}
2019-11-18 23:18:41 +01:00
MLOG_P2P_MESSAGE("-->>NOTIFY_RESPONSE_GET_BLOCKS: blocks.size()=" << rsp.blocks.size()
2019-06-26 05:09:15 +02:00
<< ", rsp.m_current_blockchain_height=" << rsp.current_blockchain_height << ", missed_ids.size()=" << rsp.missed_ids.size());
2019-11-18 23:18:41 +01:00
post_notify<NOTIFY_RESPONSE_GET_BLOCKS>(rsp, context);
2014-03-03 23:07:58 +01:00
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
2015-01-05 20:30:17 +01:00
2015-12-14 05:54:39 +01:00
2014-03-03 23:07:58 +01:00
template<class t_core>
2019-11-18 23:18:41 +01:00
int t_cryptonote_protocol_handler<t_core>::handle_response_get_blocks(int command, NOTIFY_RESPONSE_GET_BLOCKS::request& arg, cryptonote_connection_context& context)
2014-03-03 23:07:58 +01:00
{
2019-11-18 23:18:41 +01:00
MLOG_P2P_MESSAGE("Received NOTIFY_RESPONSE_GET_BLOCKS (" << arg.blocks.size() << " blocks)");
MLOG_PEER_STATE("received blocks");
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
boost::posix_time::ptime request_time = context.m_last_request_time;
context.m_last_request_time = boost::date_time::not_a_date_time;
2015-12-14 05:54:39 +01:00
2017-07-02 23:41:15 +02:00
// calculate size of request
2019-11-18 23:18:41 +01:00
size_t blocks_size = 0, others_size = 0;
2017-07-08 18:59:39 +02:00
for (const auto &element : arg.blocks) {
2017-07-02 23:41:15 +02:00
blocks_size += element.block.size();
for (const auto &tx : element.txs)
blocks_size += tx.size();
2019-11-18 23:18:41 +01:00
others_size += element.checkpoint.size();
for (const auto &blink : element.blinks)
others_size += sizeof(blink.tx_hash) + sizeof(blink.height) + blink.quorum.size() + blink.position.size() + blink.signature.size() * sizeof(crypto::signature);
2015-12-14 05:54:39 +01:00
}
2019-11-18 23:18:41 +01:00
size_t size = blocks_size + others_size;
2017-07-08 18:59:39 +02:00
for (const auto &element : arg.missed_ids)
2015-12-14 05:54:39 +01:00
size += sizeof(element.data);
size += sizeof(arg.current_blockchain_height);
{
CRITICAL_REGION_LOCAL(m_buffer_mutex);
m_avg_buffer.push_back(size);
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
++m_sync_spans_downloaded;
m_sync_download_objects_size += size;
2017-07-02 23:41:15 +02:00
MDEBUG(context << " downloaded " << size << " bytes worth of blocks");
2014-03-03 23:07:58 +01:00
if(context.m_last_response_height > arg.current_blockchain_height)
{
2019-11-18 23:18:41 +01:00
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_GET_BLOCKS: arg.m_current_blockchain_height=" << arg.current_blockchain_height
2014-03-03 23:07:58 +01:00
<< " < m_last_response_height=" << context.m_last_response_height << ", dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
++m_sync_bad_spans_downloaded;
2014-03-03 23:07:58 +01:00
return 1;
}
context.m_remote_blockchain_height = arg.current_blockchain_height;
2017-12-27 14:54:19 +01:00
if (context.m_remote_blockchain_height > m_core.get_target_blockchain_height())
m_core.set_target_blockchain_height(context.m_remote_blockchain_height);
2014-03-03 23:07:58 +01:00
2017-02-12 18:17:30 +01:00
std::vector<crypto::hash> block_hashes;
block_hashes.reserve(arg.blocks.size());
2017-07-02 23:41:15 +02:00
const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
uint64_t start_height = std::numeric_limits<uint64_t>::max();
cryptonote::block b;
2017-01-22 21:38:10 +01:00
for(const block_complete_entry& block_entry: arg.blocks)
2014-03-03 23:07:58 +01:00
{
2016-12-04 13:27:45 +01:00
if (m_stopping)
{
return 1;
}
2018-12-13 20:47:47 +01:00
crypto::hash block_hash;
if(!parse_and_validate_block_from_blob(block_entry.block, b, block_hash))
2014-03-03 23:07:58 +01:00
{
2017-02-11 20:38:18 +01:00
LOG_ERROR_CCONTEXT("sent wrong block: failed to parse and validate block: "
<< epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
++m_sync_bad_spans_downloaded;
2014-03-03 23:07:58 +01:00
return 1;
2015-12-14 05:54:39 +01:00
}
2017-07-02 23:41:15 +02:00
if (b.miner_tx.vin.size() != 1 || b.miner_tx.vin.front().type() != typeid(txin_gen))
2015-12-14 05:54:39 +01:00
{
2017-07-02 23:41:15 +02:00
LOG_ERROR_CCONTEXT("sent wrong block: block: miner tx does not have exactly one txin_gen input"
<< epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
++m_sync_bad_spans_downloaded;
2017-07-02 23:41:15 +02:00
return 1;
2014-03-03 23:07:58 +01:00
}
2017-07-02 23:41:15 +02:00
if (start_height == std::numeric_limits<uint64_t>::max())
start_height = boost::get<txin_gen>(b.miner_tx.vin[0]).height;
2015-12-14 05:54:39 +01:00
2017-02-12 18:17:30 +01:00
auto req_it = context.m_requested_objects.find(block_hash);
2014-03-03 23:07:58 +01:00
if(req_it == context.m_requested_objects.end())
{
2019-11-18 23:18:41 +01:00
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_BLOCKS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block))
2014-03-03 23:07:58 +01:00
<< " wasn't requested, dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
++m_sync_bad_spans_downloaded;
2014-03-03 23:07:58 +01:00
return 1;
}
2015-12-14 05:54:39 +01:00
if(b.tx_hashes.size() != block_entry.txs.size())
2014-03-03 23:07:58 +01:00
{
2019-11-18 23:18:41 +01:00
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_BLOCKS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block))
2014-03-03 23:07:58 +01:00
<< ", tx_hashes.size()=" << b.tx_hashes.size() << " mismatch with block_complete_entry.m_txs.size()=" << block_entry.txs.size() << ", dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
++m_sync_bad_spans_downloaded;
2014-03-03 23:07:58 +01:00
return 1;
}
context.m_requested_objects.erase(req_it);
2017-02-12 18:17:30 +01:00
block_hashes.push_back(block_hash);
2014-03-03 23:07:58 +01:00
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if(!context.m_requested_objects.empty())
2014-03-03 23:07:58 +01:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MERROR(context << "returned not all requested objects (context.m_requested_objects.size()="
Change logging to easylogging++
This replaces the epee and data_loggers logging systems with
a single one, and also adds filename:line and explicit severity
levels. Categories may be defined, and logging severity set
by category (or set of categories). epee style 0-4 log level
maps to a sensible severity configuration. Log files now also
rotate when reaching 100 MB.
To select which logs to output, use the MONERO_LOGS environment
variable, with a comma separated list of categories (globs are
supported), with their requested severity level after a colon.
If a log matches more than one such setting, the last one in
the configuration string applies. A few examples:
This one is (mostly) silent, only outputting fatal errors:
MONERO_LOGS=*:FATAL
This one is very verbose:
MONERO_LOGS=*:TRACE
This one is totally silent (logwise):
MONERO_LOGS=""
This one outputs all errors and warnings, except for the
"verify" category, which prints just fatal errors (the verify
category is used for logs about incoming transactions and
blocks, and it is expected that some/many will fail to verify,
hence we don't want the spam):
MONERO_LOGS=*:WARNING,verify:FATAL
Log levels are, in decreasing order of priority:
FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
Subcategories may be added using prefixes and globs. This
example will output net.p2p logs at the TRACE level, but all
other net* logs only at INFO:
MONERO_LOGS=*:ERROR,net*:INFO,net.p2p:TRACE
Logs which are intended for the user (which Monero was using
a lot through epee, but really isn't a nice way to go things)
should use the "global" category. There are a few helper macros
for using this category, eg: MGINFO("this shows up by default")
or MGINFO_RED("this is red"), to try to keep a similar look
and feel for now.
Existing epee log macros still exist, and map to the new log
levels, but since they're used as a "user facing" UI element
as much as a logging system, they often don't map well to log
severities (ie, a log level 0 log may be an error, or may be
something we want the user to see, such as an important info).
In those cases, I tried to use the new macros. In other cases,
I left the existing macros in. When modifying logs, it is
probably best to switch to the new macros with explicit levels.
The --log-level options and set_log commands now also accept
category settings, in addition to the epee style log levels.
2017-01-01 17:34:23 +01:00
<< context.m_requested_objects.size() << "), dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
++m_sync_bad_spans_downloaded;
2014-03-03 23:07:58 +01:00
return 1;
}
{
2017-08-12 11:59:27 +02:00
MLOG_YELLOW(el::Level::Debug, context << " Got NEW BLOCKS inside of " << __FUNCTION__ << ": size: " << arg.blocks.size()
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
<< ", blocks: " << start_height << " - " << (start_height + arg.blocks.size() - 1) <<
" (pruning seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) << ")");
2015-12-14 05:54:39 +01:00
2017-07-02 23:41:15 +02:00
// add that new span to the block queue
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
const boost::posix_time::time_duration dt = now - request_time;
2017-07-02 23:41:15 +02:00
const float rate = size * 1e6 / (dt.total_microseconds() + 1);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MDEBUG(context << " adding span: " << arg.blocks.size() << " at height " << start_height << ", " << dt.total_microseconds()/1e6 << " seconds, " << (rate/1024) << " kB/s, size now " << (m_block_queue.get_data_size() + blocks_size) / 1048576.f << " MB");
2017-07-02 23:41:15 +02:00
m_block_queue.add_blocks(start_height, arg.blocks, context.m_connection_id, rate, blocks_size);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
const crypto::hash last_block_hash = cryptonote::get_block_hash(b);
2017-09-17 15:13:59 +02:00
context.m_last_known_hash = last_block_hash;
2017-08-15 18:49:06 +02:00
2017-08-18 21:14:23 +02:00
if (!m_core.get_test_drop_download() || !m_core.get_test_drop_download_height()) { // DISCARD BLOCKS for testing
return 1;
}
}
2015-12-14 05:54:39 +01:00
2017-08-18 21:14:23 +02:00
try_add_next_blocks(context);
return 1;
}
2017-02-12 18:17:30 +01:00
2017-08-18 21:14:23 +02:00
template<class t_core>
int t_cryptonote_protocol_handler<t_core>::try_add_next_blocks(cryptonote_connection_context& context)
{
bool force_next_span = false;
{
// We try to lock the sync lock. If we can, it means no other thread is
// currently adding blocks, so we do that for as long as we can from the
// block queue. Then, we go back to download.
const boost::unique_lock<boost::mutex> sync{m_sync_lock, boost::try_to_lock};
if (!sync.owns_lock())
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MINFO(context << "Failed to lock m_sync_lock, going back to download");
2017-08-18 21:14:23 +02:00
goto skip;
}
MDEBUG(context << " lock m_sync_lock, adding blocks to chain...");
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_PEER_STATE("adding blocks");
2017-08-18 21:14:23 +02:00
{
2017-02-13 20:36:31 +01:00
m_core.pause_mine();
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
m_add_timer.resume();
bool starting = true;
2019-08-07 03:45:37 +02:00
LOKI_DEFER
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
m_add_timer.pause();
m_core.resume_mine();
2019-08-07 03:45:37 +02:00
if (!starting) m_last_add_end_time = tools::get_tick_count();
};
2017-02-13 20:36:31 +01:00
2017-07-02 23:41:15 +02:00
while (1)
{
const uint64_t previous_height = m_core.get_current_blockchain_height();
uint64_t start_height;
2018-04-16 01:16:02 +02:00
std::vector<cryptonote::block_complete_entry> blocks;
2017-07-02 23:41:15 +02:00
boost::uuids::uuid span_connection_id;
if (!m_block_queue.get_next_span(start_height, blocks, span_connection_id))
{
MDEBUG(context << " no next span found, going back to download");
break;
}
2017-02-12 18:17:30 +01:00
2017-12-11 23:36:58 +01:00
if (blocks.empty())
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MERROR(context << "Next span has no blocks");
2018-04-28 04:10:59 +02:00
m_block_queue.remove_spans(span_connection_id, start_height);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
continue;
2017-12-11 23:36:58 +01:00
}
2017-08-15 17:54:08 +02:00
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MDEBUG(context << " next span in the queue has blocks " << start_height << "-" << (start_height + blocks.size() - 1)
<< ", we need " << previous_height);
2017-08-15 17:54:08 +02:00
block new_block;
2018-12-13 20:47:47 +01:00
crypto::hash last_block_hash;
if (!parse_and_validate_block_from_blob(blocks.back().block, new_block, last_block_hash))
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
{
MERROR(context << "Failed to parse block, but it should already have been parsed");
m_block_queue.remove_spans(span_connection_id, start_height);
continue;
}
if (m_core.have_block(last_block_hash))
{
const uint64_t subchain_height = start_height + blocks.size();
LOG_DEBUG_CC(context, "These are old blocks, ignoring: blocks " << start_height << " - " << (subchain_height-1) << ", blockchain height " << m_core.get_current_blockchain_height());
m_block_queue.remove_spans(span_connection_id, start_height);
++m_sync_old_spans_downloaded;
continue;
}
2017-08-15 17:54:08 +02:00
if (!parse_and_validate_block_from_blob(blocks.front().block, new_block))
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MERROR(context << "Failed to parse block, but it should already have been parsed");
2018-04-28 04:10:59 +02:00
m_block_queue.remove_spans(span_connection_id, start_height);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
continue;
2017-08-15 17:54:08 +02:00
}
2019-08-07 03:45:37 +02:00
2017-08-15 17:54:08 +02:00
bool parent_known = m_core.have_block(new_block.prev_id);
if (!parent_known)
{
// it could be:
// - later in the current chain
// - later in an alt chain
// - orphan
// if it was requested, then it'll be resolved later, otherwise it's an orphan
2017-08-18 21:14:23 +02:00
bool parent_requested = m_block_queue.requested(new_block.prev_id);
2017-08-15 17:54:08 +02:00
if (!parent_requested)
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
// we might be able to ask for that block directly, as we now can request out of order,
// otherwise we continue out of order, unless this block is the one we need, in which
// case we request block hashes, though it might be safer to disconnect ?
if (start_height > previous_height)
{
if (should_drop_connection(context, get_next_needed_pruning_stripe().first))
{
MDEBUG(context << "Got block with unknown parent which was not requested, but peer does not have that block - dropping connection");
if (!context.m_is_income)
m_p2p->add_used_stripe_peer(context);
drop_connection(context, false, true);
return 1;
}
MDEBUG(context << "Got block with unknown parent which was not requested, but peer does not have that block - back to download");
goto skip;
}
2017-08-18 21:14:23 +02:00
// this can happen if a connection was sicced onto a late span, if it did not have those blocks,
// since we don't know that at the sic time
LOG_ERROR_CCONTEXT("Got block with unknown parent which was not requested - querying block hashes");
2018-04-28 04:10:59 +02:00
m_block_queue.remove_spans(span_connection_id, start_height);
2017-08-18 21:14:23 +02:00
context.m_needed_objects.clear();
context.m_last_response_height = 0;
goto skip;
2017-08-15 17:54:08 +02:00
}
// parent was requested, so we wait for it to be retrieved
MINFO(context << " parent was requested, we'll get back to it");
break;
}
2017-07-02 23:41:15 +02:00
const boost::posix_time::ptime start = boost::posix_time::microsec_clock::universal_time();
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (starting)
{
starting = false;
if (m_last_add_end_time)
{
const uint64_t tnow = tools::get_tick_count();
const uint64_t ns = tools::ticks_to_ns(tnow - m_last_add_end_time);
MINFO("Restarting adding block after idle for " << ns/1e9 << " seconds");
}
}
2017-02-13 20:36:31 +01:00
2018-11-23 12:15:04 +01:00
std::vector<block> pblocks;
2019-06-26 06:00:05 +02:00
if (!m_core.prepare_handle_incoming_blocks(blocks, pblocks))
2018-11-23 14:05:48 +01:00
{
LOG_ERROR_CCONTEXT("Failure in prepare_handle_incoming_blocks");
return 1;
}
2017-02-12 18:17:30 +01:00
2016-12-04 13:27:45 +01:00
{
2019-08-07 03:45:37 +02:00
bool remove_spans = false;
LOKI_DEFER
2017-07-02 23:41:15 +02:00
{
2019-08-07 03:45:37 +02:00
if (!m_core.cleanup_handle_incoming_blocks())
LOG_PRINT_CCONTEXT_L0("Failure in cleanup_handle_incoming_blocks");
// in case the peer had dropped beforehand, remove the span anyway so other threads can wake up and get it
if (remove_spans)
m_block_queue.remove_spans(span_connection_id, start_height);
};
2016-12-04 13:27:45 +01:00
2019-08-07 03:45:37 +02:00
if (!pblocks.empty() && pblocks.size() != blocks.size())
2017-12-24 14:04:40 +01:00
{
2019-08-07 03:45:37 +02:00
LOG_ERROR_CCONTEXT("Internal error: blocks.size() != block_entry.txs.size()");
2018-04-28 04:07:51 +02:00
return 1;
2017-12-24 14:04:40 +01:00
}
2019-08-07 03:45:37 +02:00
uint64_t block_process_time_full = 0, transactions_process_time_full = 0;
size_t num_txs = 0, blockidx = 0;
for(const block_complete_entry& block_entry: blocks)
2015-12-14 05:54:39 +01:00
{
2019-08-07 03:45:37 +02:00
if (m_stopping)
return 1;
// process transactions
TIME_MEASURE_START(transactions_process_time);
num_txs += block_entry.txs.size();
2019-11-25 19:22:30 +01:00
auto parsed_txs = m_core.handle_incoming_txs(block_entry.txs, tx_pool_options::from_block());
2017-07-02 23:41:15 +02:00
2019-11-25 05:57:15 +01:00
for (size_t i = 0; i < parsed_txs.size(); ++i)
2019-08-07 03:45:37 +02:00
{
2019-11-25 05:57:15 +01:00
if (parsed_txs[i].tvc.m_verifivation_failed)
2017-08-29 17:10:53 +02:00
{
2019-08-07 03:45:37 +02:00
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
cryptonote::transaction tx;
2019-11-25 05:57:15 +01:00
parse_and_validate_tx_from_blob(block_entry.txs[i], tx); // must succeed if we got here
2019-11-18 23:18:41 +01:00
LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_BLOCKS, tx_id = "
2019-08-07 03:45:37 +02:00
<< epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(tx)) << ", dropping connection");
drop_connection(context, false, true);
return 1;
}))
LOG_ERROR_CCONTEXT("span connection id not found");
remove_spans = true;
2017-08-29 17:10:53 +02:00
return 1;
}
2017-07-02 23:41:15 +02:00
}
2019-08-07 03:45:37 +02:00
TIME_MEASURE_FINISH(transactions_process_time);
transactions_process_time_full += transactions_process_time;
//
// NOTE: Checkpoint parsing
//
checkpoint_t checkpoint_allocated_on_stack_;
checkpoint_t *checkpoint = nullptr;
if (block_entry.checkpoint.size())
2019-06-26 06:00:05 +02:00
{
2019-08-07 03:45:37 +02:00
// TODO(doyle): It's wasteful to have to parse the checkpoint to
// figure out the height when at some point during the syncing
// step we know exactly what height the block entries are for
2019-06-26 06:00:05 +02:00
2019-08-07 03:45:37 +02:00
if (!t_serializable_object_from_blob(checkpoint_allocated_on_stack_, block_entry.checkpoint))
{
MERROR("Checkpoint blob available but failed to parse");
return false;
}
2019-06-26 06:00:05 +02:00
2019-08-28 07:54:02 +02:00
checkpoint = &checkpoint_allocated_on_stack_;
2019-08-07 03:45:37 +02:00
}
2017-07-02 23:41:15 +02:00
2019-08-07 03:45:37 +02:00
// process block
2017-07-02 23:41:15 +02:00
2019-08-07 03:45:37 +02:00
TIME_MEASURE_START(block_process_time);
2019-10-31 23:26:58 +01:00
block_verification_context bvc{};
2017-07-02 23:41:15 +02:00
2019-08-07 03:45:37 +02:00
m_core.handle_incoming_block(block_entry.block, pblocks.empty() ? NULL : &pblocks[blockidx], bvc, checkpoint, false); // <--- process block
2017-07-02 23:41:15 +02:00
2019-08-07 03:45:37 +02:00
if (bvc.m_verifivation_failed || bvc.m_marked_as_orphaned)
2017-08-29 17:10:53 +02:00
{
2019-08-07 03:45:37 +02:00
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
char const *ERR_MSG =
bvc.m_verifivation_failed
? "Block verification failed, dropping connection"
: "Block received at sync phase was marked as orphaned, dropping connection";
2017-08-29 17:10:53 +02:00
2019-08-07 03:45:37 +02:00
LOG_PRINT_CCONTEXT_L1(ERR_MSG);
drop_connection(context, true, true);
return 1;
}))
LOG_ERROR_CCONTEXT("span connection id not found");
2015-12-14 05:54:39 +01:00
2019-08-07 03:45:37 +02:00
remove_spans = true;
2017-08-29 17:10:53 +02:00
return 1;
}
2019-08-07 03:45:37 +02:00
TIME_MEASURE_FINISH(block_process_time);
block_process_time_full += block_process_time;
++blockidx;
2015-12-14 05:54:39 +01:00
2019-08-07 03:45:37 +02:00
} // each download block
2015-12-14 05:54:39 +01:00
2019-08-07 03:45:37 +02:00
remove_spans = true;
MDEBUG(context << "Block process time (" << blocks.size() << " blocks, " << num_txs << " txs): " << block_process_time_full + transactions_process_time_full << " (" << transactions_process_time_full << "/" << block_process_time_full << ") ms");
2017-08-29 17:10:53 +02:00
}
2015-12-14 05:54:39 +01:00
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
const uint64_t current_blockchain_height = m_core.get_current_blockchain_height();
if (current_blockchain_height > previous_height)
2017-07-02 23:41:15 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
const uint64_t target_blockchain_height = m_core.get_target_blockchain_height();
2017-07-02 23:41:15 +02:00
const boost::posix_time::time_duration dt = boost::posix_time::microsec_clock::universal_time() - start;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
std::string progress_message = "";
if (current_blockchain_height < target_blockchain_height)
{
uint64_t completion_percent = (current_blockchain_height * 100 / target_blockchain_height);
if (completion_percent == 100) // never show 100% if not actually up to date
completion_percent = 99;
progress_message = " (" + std::to_string(completion_percent) + "%, "
+ std::to_string(target_blockchain_height - current_blockchain_height) + " left)";
}
const uint32_t previous_stripe = tools::get_pruning_stripe(previous_height, target_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES);
const uint32_t current_stripe = tools::get_pruning_stripe(current_blockchain_height, target_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES);
2017-07-02 23:41:15 +02:00
std::string timing_message = "";
if (ELPP->vRegistry()->allowed(el::Level::Info, "sync-info"))
timing_message = std::string(" (") + std::to_string(dt.total_microseconds()/1e6) + " sec, "
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
+ std::to_string((current_blockchain_height - previous_height) * 1e6 / dt.total_microseconds())
+ " blocks/sec), " + std::to_string(m_block_queue.get_data_size() / 1048576.f) + " MB queued in "
+ std::to_string(m_block_queue.get_num_filled_spans()) + " spans, stripe "
+ std::to_string(previous_stripe) + " -> " + std::to_string(current_stripe);
2017-07-02 23:41:15 +02:00
if (ELPP->vRegistry()->allowed(el::Level::Debug, "sync-info"))
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
timing_message += std::string(": ") + m_block_queue.get_overview(current_blockchain_height);
MGINFO_YELLOW("Synced " << current_blockchain_height << "/" << target_blockchain_height
<< progress_message << timing_message);
if (previous_stripe != current_stripe)
notify_new_stripe(context, current_stripe);
2017-07-02 23:41:15 +02:00
}
2015-12-14 05:54:39 +01:00
}
2017-08-18 21:14:23 +02:00
}
2015-12-14 05:54:39 +01:00
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_PEER_STATE("stopping adding blocks");
if (should_download_next_span(context, false))
2017-07-02 23:41:15 +02:00
{
force_next_span = true;
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
else if (should_drop_connection(context, get_next_needed_pruning_stripe().first))
{
if (!context.m_is_income)
{
m_p2p->add_used_stripe_peer(context);
drop_connection(context, false, false);
}
return 1;
}
2014-03-03 23:07:58 +01:00
}
2017-07-02 23:41:15 +02:00
2017-02-13 20:36:31 +01:00
skip:
2017-07-02 23:41:15 +02:00
if (!request_missing_objects(context, true, force_next_span))
{
LOG_ERROR_CCONTEXT("Failed to request missing objects, dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2017-07-02 23:41:15 +02:00
return 1;
}
2014-03-03 23:07:58 +01:00
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
void t_cryptonote_protocol_handler<t_core>::notify_new_stripe(cryptonote_connection_context& cntxt, uint32_t stripe)
{
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool
{
if (cntxt.m_connection_id == context.m_connection_id)
return true;
if (context.m_state == cryptonote_connection_context::state_normal)
{
const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed);
if (stripe && peer_stripe && peer_stripe != stripe)
return true;
context.m_state = cryptonote_connection_context::state_synchronizing;
LOG_PRINT_CCONTEXT_L2("requesting callback");
++context.m_callback_request_count;
m_p2p->request_callback(context);
MLOG_PEER_STATE("requesting callback");
}
return true;
});
}
//------------------------------------------------------------------------------------------------------------------------
2019-11-18 23:18:41 +01:00
// Tells the other end to send us the given txes (typically with attached blink data) as if they
// are new transactions.
template<class t_core>
int t_cryptonote_protocol_handler<t_core>::handle_request_get_txs(int command, NOTIFY_REQUEST_GET_TXS::request& arg, cryptonote_connection_context& context)
{
MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_GET_TXS (" << arg.txs.size() << " txs)");
if (arg.txs.size() > CURRENCY_PROTOCOL_MAX_TXS_REQUEST_COUNT)
{
LOG_ERROR_CCONTEXT(
"Requested txs count is too big (" << arg.txs.size() << ") expected not more than " << CURRENCY_PROTOCOL_MAX_TXS_REQUEST_COUNT);
drop_connection(context, false, false);
return 1;
}
NOTIFY_NEW_TRANSACTIONS::request rsp;
rsp.requested = true;
if(!m_core.get_blockchain_storage().handle_get_txs(arg, rsp))
{
LOG_ERROR_CCONTEXT("failed to handle request NOTIFY_REQUEST_GET_TXS, dropping connection");
drop_connection(context, false, false);
return 1;
}
MLOG_P2P_MESSAGE("-->>NOTIFY_NEW_TRANSACTIONS: requested=true, txs[" << rsp.txs.size() << "], blinks[" << rsp.blinks.size() << "]");
post_notify<NOTIFY_NEW_TRANSACTIONS>(rsp, context);
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
template<class t_core>
2014-03-03 23:07:58 +01:00
bool t_cryptonote_protocol_handler<t_core>::on_idle()
{
2017-08-16 20:27:16 +02:00
m_idle_peer_kicker.do_call(boost::bind(&t_cryptonote_protocol_handler<t_core>::kick_idle_peers, this));
2018-12-07 13:32:50 +01:00
m_standby_checker.do_call(boost::bind(&t_cryptonote_protocol_handler<t_core>::check_standby_peers, this));
2019-02-26 13:40:40 +01:00
m_sync_search_checker.do_call(boost::bind(&t_cryptonote_protocol_handler<t_core>::update_sync_search, this));
2014-03-03 23:07:58 +01:00
return m_core.on_idle();
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2017-08-16 20:27:16 +02:00
bool t_cryptonote_protocol_handler<t_core>::kick_idle_peers()
{
MTRACE("Checking for idle peers...");
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (context.m_state == cryptonote_connection_context::state_synchronizing && context.m_last_request_time != boost::date_time::not_a_date_time)
2017-08-16 20:27:16 +02:00
{
const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
const boost::posix_time::time_duration dt = now - context.m_last_request_time;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (dt.total_microseconds() > IDLE_PEER_KICK_TIME)
2017-08-16 20:27:16 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MINFO(context << " kicking idle peer, last update " << (dt.total_microseconds() / 1.e6) << " seconds ago");
LOG_PRINT_CCONTEXT_L2("requesting callback");
context.m_last_request_time = boost::date_time::not_a_date_time;
context.m_state = cryptonote_connection_context::state_standby; // we'll go back to adding, then (if we can't), download
++context.m_callback_request_count;
m_p2p->request_callback(context);
2017-08-16 20:27:16 +02:00
}
}
return true;
});
return true;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2019-02-26 13:40:40 +01:00
bool t_cryptonote_protocol_handler<t_core>::update_sync_search()
{
const uint64_t target = m_core.get_target_blockchain_height();
const uint64_t height = m_core.get_current_blockchain_height();
if (target > height) // if we're not synced yet, don't do it
return true;
MTRACE("Checking for outgoing syncing peers...");
unsigned n_syncing = 0, n_synced = 0;
boost::uuids::uuid last_synced_peer_id(boost::uuids::nil_uuid());
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool
{
if (!peer_id || context.m_is_income) // only consider connected outgoing peers
return true;
if (context.m_state == cryptonote_connection_context::state_synchronizing)
++n_syncing;
if (context.m_state == cryptonote_connection_context::state_normal)
{
++n_synced;
if (!context.m_anchor)
last_synced_peer_id = context.m_connection_id;
}
return true;
});
MTRACE(n_syncing << " syncing, " << n_synced << " synced");
// if we're at max out peers, and not enough are syncing
if (n_synced + n_syncing >= m_max_out_peers && n_syncing < P2P_DEFAULT_SYNC_SEARCH_CONNECTIONS_COUNT && last_synced_peer_id != boost::uuids::nil_uuid())
{
if (!m_p2p->for_connection(last_synced_peer_id, [&](cryptonote_connection_context& ctx, nodetool::peerid_type peer_id, uint32_t f)->bool{
MINFO(ctx << "dropping synced peer, " << n_syncing << " syncing, " << n_synced << " synced");
drop_connection(ctx, false, false);
return true;
}))
MDEBUG("Failed to find peer we wanted to drop");
}
return true;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2018-12-07 13:32:50 +01:00
bool t_cryptonote_protocol_handler<t_core>::check_standby_peers()
{
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool
{
if (context.m_state == cryptonote_connection_context::state_standby)
{
LOG_PRINT_CCONTEXT_L2("requesting callback");
++context.m_callback_request_count;
m_p2p->request_callback(context);
}
return true;
});
return true;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2014-03-03 23:07:58 +01:00
int t_cryptonote_protocol_handler<t_core>::handle_request_chain(int command, NOTIFY_REQUEST_CHAIN::request& arg, cryptonote_connection_context& context)
{
2017-01-22 11:14:45 +01:00
MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_CHAIN (" << arg.block_ids.size() << " blocks");
2014-03-03 23:07:58 +01:00
NOTIFY_RESPONSE_CHAIN_ENTRY::request r;
if(!m_core.find_blockchain_supplement(arg.block_ids, r))
{
LOG_ERROR_CCONTEXT("Failed to handle NOTIFY_REQUEST_CHAIN.");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2014-03-03 23:07:58 +01:00
return 1;
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_P2P_MESSAGE("-->>NOTIFY_RESPONSE_CHAIN_ENTRY: m_start_height=" << r.start_height << ", m_total_height=" << r.total_height << ", m_block_ids.size()=" << r.m_block_ids.size());
2014-03-03 23:07:58 +01:00
post_notify<NOTIFY_RESPONSE_CHAIN_ENTRY>(r, context);
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
bool t_cryptonote_protocol_handler<t_core>::should_download_next_span(cryptonote_connection_context& context, bool standby)
2014-03-03 23:07:58 +01:00
{
2018-04-16 01:16:02 +02:00
std::vector<crypto::hash> hashes;
2017-07-02 23:41:15 +02:00
boost::uuids::uuid span_connection_id;
boost::posix_time::ptime request_time;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
boost::uuids::uuid connection_id;
2017-08-18 21:14:23 +02:00
std::pair<uint64_t, uint64_t> span;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
bool filled;
2017-08-18 21:14:23 +02:00
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
const uint64_t blockchain_height = m_core.get_current_blockchain_height();
if (context.m_remote_blockchain_height <= blockchain_height)
return false;
const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
const bool has_next_block = tools::has_unpruned_block(blockchain_height, context.m_remote_blockchain_height, context.m_pruning_seed);
if (has_next_block)
2017-07-02 23:41:15 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (!m_block_queue.has_next_span(blockchain_height, filled, request_time, connection_id))
2017-07-02 23:41:15 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MDEBUG(context << " we should download it as no peer reserved it");
2017-07-02 23:41:15 +02:00
return true;
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (!filled)
{
const long dt = (now - request_time).total_microseconds();
if (dt >= REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD)
{
MDEBUG(context << " we should download it as it's not been received yet after " << dt/1e6);
return true;
}
// in standby, be ready to double download early since we're idling anyway
// let the fastest peer trigger first
long threshold;
const double dl_speed = context.m_max_speed_down;
if (standby && dt >= REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY && dl_speed > 0)
{
bool download = false;
if (m_p2p->for_connection(connection_id, [&](cryptonote_connection_context& ctx, nodetool::peerid_type peer_id, uint32_t f)->bool{
const time_t nowt = time(NULL);
const time_t time_since_last_recv = nowt - ctx.m_last_recv;
const float last_activity = std::min((float)time_since_last_recv, dt/1e6f);
const bool stalled = last_activity > LAST_ACTIVITY_STALL_THRESHOLD;
if (stalled)
{
MDEBUG(context << " we should download it as the downloading peer is stalling for " << nowt - ctx.m_last_recv << " seconds");
download = true;
return true;
}
// estimate the standby peer can give us 80% of its max speed
// and let it download if that speed is > N times as fast as the current one
// N starts at 10 after REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY,
// decreases to 1.25 at REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD,
// so that at times goes without the download being done, a retry becomes easier
const float max_multiplier = 10.f;
const float min_multiplier = 1.25f;
float multiplier = max_multiplier;
if (dt/1e6 >= REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY)
{
multiplier = max_multiplier - (dt/1e6-REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY) * (max_multiplier - min_multiplier) / (REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD - REQUEST_NEXT_SCHEDULED_SPAN_THRESHOLD_STANDBY);
multiplier = std::min(max_multiplier, std::max(min_multiplier, multiplier));
}
if (dl_speed * .8f > ctx.m_current_speed_down * multiplier)
{
MDEBUG(context << " we should download it as we are substantially faster (" << dl_speed << " vs "
<< ctx.m_current_speed_down << ", multiplier " << multiplier << " after " << dt/1e6 << " seconds)");
download = true;
return true;
}
return true;
}))
{
if (download)
return true;
}
else
{
MWARNING(context << " we should download it as the downloading peer is unexpectedly not known to us");
return true;
}
}
}
}
return false;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
bool t_cryptonote_protocol_handler<t_core>::should_drop_connection(cryptonote_connection_context& context, uint32_t next_stripe)
{
if (context.m_anchor)
{
MDEBUG(context << "This is an anchor peer, not dropping");
2017-07-02 23:41:15 +02:00
return false;
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (context.m_pruning_seed == 0)
{
MDEBUG(context << "This peer is not striped, not dropping");
2017-07-02 23:41:15 +02:00
return false;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
}
2017-07-02 23:41:15 +02:00
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed);
if (next_stripe == peer_stripe)
2017-07-02 23:41:15 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MDEBUG(context << "This peer has needed stripe " << peer_stripe << ", not dropping");
return false;
2017-07-02 23:41:15 +02:00
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (!context.m_needed_objects.empty())
2017-07-02 23:41:15 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
const uint64_t next_available_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1;
if (tools::has_unpruned_block(next_available_block_height, context.m_remote_blockchain_height, context.m_pruning_seed))
{
MDEBUG(context << "This peer has unpruned next block at height " << next_available_block_height << ", not dropping");
return false;
}
2017-07-02 23:41:15 +02:00
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (next_stripe > 0)
2017-07-02 23:41:15 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
unsigned int n_out_peers = 0, n_peers_on_next_stripe = 0;
m_p2p->for_each_connection([&](cryptonote_connection_context& ctx, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{
if (!ctx.m_is_income)
++n_out_peers;
if (ctx.m_state >= cryptonote_connection_context::state_synchronizing && tools::get_pruning_stripe(ctx.m_pruning_seed) == next_stripe)
++n_peers_on_next_stripe;
return true;
});
const uint32_t distance = (peer_stripe + (1<<CRYPTONOTE_PRUNING_LOG_STRIPES) - next_stripe) % (1<<CRYPTONOTE_PRUNING_LOG_STRIPES);
if ((n_out_peers >= m_max_out_peers && n_peers_on_next_stripe == 0) || (distance > 1 && n_peers_on_next_stripe <= 2) || distance > 2)
{
MDEBUG(context << "we want seed " << next_stripe << ", and either " << n_out_peers << " is at max out peers ("
<< m_max_out_peers << ") or distance " << distance << " from " << next_stripe << " to " << peer_stripe <<
" is too large and we have only " << n_peers_on_next_stripe << " peers on next seed, dropping connection to make space");
return true;
}
2017-07-02 23:41:15 +02:00
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MDEBUG(context << "End of checks, not dropping");
2017-07-02 23:41:15 +02:00
return false;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
void t_cryptonote_protocol_handler<t_core>::skip_unneeded_hashes(cryptonote_connection_context& context, bool check_block_queue) const
{
// take out blocks we already have
size_t skip = 0;
while (skip < context.m_needed_objects.size() && (m_core.have_block(context.m_needed_objects[skip]) || (check_block_queue && m_block_queue.have(context.m_needed_objects[skip]))))
{
// if we're popping the last hash, record it so we can ask again from that hash,
// this prevents never being able to progress on peers we get old hash lists from
if (skip + 1 == context.m_needed_objects.size())
context.m_last_known_hash = context.m_needed_objects[skip];
++skip;
}
if (skip > 0)
{
MDEBUG(context << "skipping " << skip << "/" << context.m_needed_objects.size() << " blocks");
context.m_needed_objects = std::vector<crypto::hash>(context.m_needed_objects.begin() + skip, context.m_needed_objects.end());
}
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2017-07-02 23:41:15 +02:00
bool t_cryptonote_protocol_handler<t_core>::request_missing_objects(cryptonote_connection_context& context, bool check_having_blocks, bool force_next_span)
{
2017-07-11 22:48:54 +02:00
// flush stale spans
std::set<boost::uuids::uuid> live_connections;
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{
live_connections.insert(context.m_connection_id);
return true;
});
m_block_queue.flush_stale_spans(live_connections);
2017-07-02 23:41:15 +02:00
// if we don't need to get next span, and the block queue is full enough, wait a bit
bool start_from_current_chain = false;
if (!force_next_span)
{
2018-12-07 13:32:50 +01:00
do
2017-07-02 23:41:15 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
size_t nspans = m_block_queue.get_num_filled_spans();
2017-07-02 23:41:15 +02:00
size_t size = m_block_queue.get_data_size();
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
const uint64_t bc_height = m_core.get_current_blockchain_height();
const auto next_needed_pruning_stripe = get_next_needed_pruning_stripe();
const uint32_t add_stripe = tools::get_pruning_stripe(bc_height, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES);
const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed);
const size_t block_queue_size_threshold = m_block_download_max_size ? m_block_download_max_size : BLOCK_QUEUE_SIZE_THRESHOLD;
bool queue_proceed = nspans < BLOCK_QUEUE_NSPANS_THRESHOLD || size < block_queue_size_threshold;
// get rid of blocks we already requested, or already have
skip_unneeded_hashes(context, true);
uint64_t next_needed_height = m_block_queue.get_next_needed_height(bc_height);
uint64_t next_block_height;
if (context.m_needed_objects.empty())
next_block_height = next_needed_height;
else
next_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1;
bool stripe_proceed_main = (add_stripe == 0 || peer_stripe == 0 || add_stripe == peer_stripe) && (next_block_height < bc_height + BLOCK_QUEUE_FORCE_DOWNLOAD_NEAR_BLOCKS || next_needed_height < bc_height + BLOCK_QUEUE_FORCE_DOWNLOAD_NEAR_BLOCKS);
bool stripe_proceed_secondary = tools::has_unpruned_block(next_block_height, context.m_remote_blockchain_height, context.m_pruning_seed);
bool proceed = stripe_proceed_main || (queue_proceed && stripe_proceed_secondary);
if (!stripe_proceed_main && !stripe_proceed_secondary && should_drop_connection(context, tools::get_pruning_stripe(next_block_height, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES)))
{
if (!context.m_is_income)
m_p2p->add_used_stripe_peer(context);
return false; // drop outgoing connections
}
MDEBUG(context << "proceed " << proceed << " (queue " << queue_proceed << ", stripe " << stripe_proceed_main << "/" <<
stripe_proceed_secondary << "), " << next_needed_pruning_stripe.first << "-" << next_needed_pruning_stripe.second <<
" needed, bc add stripe " << add_stripe << ", we have " << peer_stripe << "), bc_height " << bc_height);
MDEBUG(context << " - next_block_height " << next_block_height << ", seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) <<
", next_needed_height "<< next_needed_height);
MDEBUG(context << " - last_response_height " << context.m_last_response_height << ", m_needed_objects size " << context.m_needed_objects.size());
// if we're waiting for next span, try to get it before unblocking threads below,
// or a runaway downloading of future spans might happen
if (stripe_proceed_main && should_download_next_span(context, true))
{
MDEBUG(context << " we should try for that next span too, we think we could get it faster, resuming");
force_next_span = true;
MLOG_PEER_STATE("resuming");
break;
}
if (proceed)
2017-07-02 23:41:15 +02:00
{
2018-12-07 13:32:50 +01:00
if (context.m_state != cryptonote_connection_context::state_standby)
2017-07-02 23:41:15 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
LOG_DEBUG_CC(context, "Block queue is " << nspans << " and " << size << ", resuming");
MLOG_PEER_STATE("resuming");
2017-07-02 23:41:15 +02:00
}
break;
}
2018-02-02 23:33:53 +01:00
// this one triggers if all threads are in standby, which should not happen,
// but happened at least once, so we unblock at least one thread if so
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
boost::unique_lock<boost::mutex> sync{m_sync_lock, boost::try_to_lock};
2018-02-02 23:33:53 +01:00
if (sync.owns_lock())
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
bool filled = false;
boost::posix_time::ptime time;
boost::uuids::uuid connection_id;
if (m_block_queue.has_next_span(m_core.get_current_blockchain_height(), filled, time, connection_id) && filled)
{
LOG_DEBUG_CC(context, "No other thread is adding blocks, and next span needed is ready, resuming");
MLOG_PEER_STATE("resuming");
context.m_state = cryptonote_connection_context::state_standby;
++context.m_callback_request_count;
m_p2p->request_callback(context);
return true;
}
else
{
sync.unlock();
2018-02-02 23:33:53 +01:00
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
// if this has gone on for too long, drop incoming connection to guard against some wedge state
if (!context.m_is_income)
{
const uint64_t now = tools::get_tick_count();
const uint64_t dt = now - m_last_add_end_time;
if (tools::ticks_to_ns(dt) >= DROP_ON_SYNC_WEDGE_THRESHOLD)
{
MDEBUG(context << "Block addition seems to have wedged, dropping connection");
return false;
}
}
}
2017-07-02 23:41:15 +02:00
}
2018-12-07 13:32:50 +01:00
if (context.m_state != cryptonote_connection_context::state_standby)
2017-07-02 23:41:15 +02:00
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (!queue_proceed)
LOG_DEBUG_CC(context, "Block queue is " << nspans << " and " << size << ", pausing");
else if (!stripe_proceed_main && !stripe_proceed_secondary)
LOG_DEBUG_CC(context, "We do not have the stripe required to download another block, pausing");
2017-08-16 20:27:16 +02:00
context.m_state = cryptonote_connection_context::state_standby;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_PEER_STATE("pausing");
2017-08-18 21:14:23 +02:00
}
2018-12-07 13:32:50 +01:00
return true;
} while(0);
2017-08-16 20:27:16 +02:00
context.m_state = cryptonote_connection_context::state_synchronizing;
2017-07-02 23:41:15 +02:00
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MDEBUG(context << " request_missing_objects: check " << check_having_blocks << ", force_next_span " << force_next_span
<< ", m_needed_objects " << context.m_needed_objects.size() << " lrh " << context.m_last_response_height << ", chain "
<< m_core.get_current_blockchain_height() << ", pruning seed " << epee::string_tools::to_string_hex(context.m_pruning_seed));
2017-07-02 23:41:15 +02:00
if(context.m_needed_objects.size() || force_next_span)
2014-03-03 23:07:58 +01:00
{
//we know objects that we need, request this objects
2019-11-18 23:18:41 +01:00
NOTIFY_REQUEST_GET_BLOCKS::request req;
2017-07-02 23:41:15 +02:00
bool is_next = false;
2014-03-03 23:07:58 +01:00
size_t count = 0;
2017-08-16 22:19:53 +02:00
const size_t count_limit = m_core.get_block_sync_size(m_core.get_current_blockchain_height());
2017-07-02 23:41:15 +02:00
std::pair<uint64_t, uint64_t> span = std::make_pair(0, 0);
2017-08-18 21:14:23 +02:00
if (force_next_span)
{
2017-07-02 23:41:15 +02:00
if (span.second == 0)
{
2018-04-16 01:16:02 +02:00
std::vector<crypto::hash> hashes;
2017-07-02 23:41:15 +02:00
boost::uuids::uuid span_connection_id;
boost::posix_time::ptime time;
span = m_block_queue.get_next_span_if_scheduled(hashes, span_connection_id, time);
if (span.second > 0)
{
is_next = true;
for (const auto &hash: hashes)
{
req.blocks.push_back(hash);
context.m_requested_objects.insert(hash);
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
m_block_queue.reset_next_span_time();
2017-07-02 23:41:15 +02:00
}
2014-03-03 23:07:58 +01:00
}
}
2017-07-02 23:41:15 +02:00
if (span.second == 0)
{
MDEBUG(context << " span size is 0");
if (context.m_last_response_height + 1 < context.m_needed_objects.size())
{
MERROR(context << " ERROR: inconsistent context: lrh " << context.m_last_response_height << ", nos " << context.m_needed_objects.size());
context.m_needed_objects.clear();
context.m_last_response_height = 0;
goto skip;
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
skip_unneeded_hashes(context, false);
2018-04-16 01:16:02 +02:00
2017-07-02 23:41:15 +02:00
const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1;
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, context.m_pruning_seed, context.m_remote_blockchain_height, context.m_needed_objects);
2017-07-02 23:41:15 +02:00
MDEBUG(context << " span from " << first_block_height << ": " << span.first << "/" << span.second);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (span.second > 0)
{
const uint32_t stripe = tools::get_pruning_stripe(span.first, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES);
if (context.m_pruning_seed && stripe != tools::get_pruning_stripe(context.m_pruning_seed))
{
MDEBUG(context << " starting early on next seed (" << span.first << " with stripe " << stripe <<
", context seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) << ")");
}
}
2017-07-02 23:41:15 +02:00
}
if (span.second == 0 && !force_next_span)
{
MDEBUG(context << " still no span reserved, we may be in the corner case of next span scheduled and everything else scheduled/filled");
2018-04-16 01:16:02 +02:00
std::vector<crypto::hash> hashes;
2017-07-02 23:41:15 +02:00
boost::uuids::uuid span_connection_id;
boost::posix_time::ptime time;
span = m_block_queue.get_next_span_if_scheduled(hashes, span_connection_id, time);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (span.second > 0 && !tools::has_unpruned_block(span.first, context.m_remote_blockchain_height, context.m_pruning_seed))
span = std::make_pair(0, 0);
2017-07-02 23:41:15 +02:00
if (span.second > 0)
{
is_next = true;
for (const auto &hash: hashes)
{
req.blocks.push_back(hash);
2017-08-18 21:14:23 +02:00
++count;
2017-07-02 23:41:15 +02:00
context.m_requested_objects.insert(hash);
2017-08-18 21:14:23 +02:00
// that's atrocious O(n) wise, but this is rare
auto i = std::find(context.m_needed_objects.begin(), context.m_needed_objects.end(), hash);
if (i != context.m_needed_objects.end())
context.m_needed_objects.erase(i);
2017-07-02 23:41:15 +02:00
}
}
}
MDEBUG(context << " span: " << span.first << "/" << span.second << " (" << span.first << " - " << (span.first + span.second - 1) << ")");
if (span.second > 0)
{
if (!is_next)
{
const uint64_t first_context_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1;
uint64_t skip = span.first - first_context_block_height;
if (skip > context.m_needed_objects.size())
{
MERROR("ERROR: skip " << skip << ", m_needed_objects " << context.m_needed_objects.size() << ", first_context_block_height" << first_context_block_height);
return false;
}
2018-04-16 01:16:02 +02:00
if (skip > 0)
context.m_needed_objects = std::vector<crypto::hash>(context.m_needed_objects.begin() + skip, context.m_needed_objects.end());
2017-07-02 23:41:15 +02:00
if (context.m_needed_objects.size() < span.second)
{
MERROR("ERROR: span " << span.first << "/" << span.second << ", m_needed_objects " << context.m_needed_objects.size());
return false;
}
for (size_t n = 0; n < span.second; ++n)
{
2018-04-16 01:16:02 +02:00
req.blocks.push_back(context.m_needed_objects[n]);
2017-07-02 23:41:15 +02:00
++count;
2018-04-16 01:16:02 +02:00
context.m_requested_objects.insert(context.m_needed_objects[n]);
2017-07-02 23:41:15 +02:00
}
2018-04-16 01:16:02 +02:00
context.m_needed_objects = std::vector<crypto::hash>(context.m_needed_objects.begin() + span.second, context.m_needed_objects.end());
2017-07-02 23:41:15 +02:00
}
context.m_last_request_time = boost::posix_time::microsec_clock::universal_time();
2019-11-18 23:18:41 +01:00
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_GET_BLOCKS: blocks.size()=" << req.blocks.size()
2019-06-26 05:09:15 +02:00
<< "requested blocks count=" << count << " / " << count_limit << " from " << span.first << ", first hash " << req.blocks.front());
2017-07-02 23:41:15 +02:00
2019-11-18 23:18:41 +01:00
post_notify<NOTIFY_REQUEST_GET_BLOCKS>(req, context);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_PEER_STATE("requesting objects");
return true;
}
// if we're still around, we might be at a point where the peer is pruned, so we could either
// drop it to make space for other peers, or ask for a span further down the line
const uint32_t next_stripe = get_next_needed_pruning_stripe().first;
const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed);
if (next_stripe && peer_stripe && next_stripe != peer_stripe)
{
// at this point, we have to either close the connection, or start getting blocks past the
// current point, or become dormant
MDEBUG(context << "this peer is pruned at seed " << epee::string_tools::to_string_hex(context.m_pruning_seed) <<
", next stripe needed is " << next_stripe);
if (!context.m_is_income)
{
if (should_drop_connection(context, next_stripe))
{
m_p2p->add_used_stripe_peer(context);
return false; // drop outgoing connections
}
}
// we'll get back stuck waiting for the go ahead
context.m_state = cryptonote_connection_context::state_normal;
MLOG_PEER_STATE("Nothing to do for now, switching to normal state");
2017-07-02 23:41:15 +02:00
return true;
}
}
2015-12-14 05:54:39 +01:00
2017-07-02 23:41:15 +02:00
skip:
context.m_needed_objects.clear();
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
// we might have been called from the "received chain entry" handler, and end up
// here because we can't use any of those blocks (maybe because all of them are
// actually already requested). In this case, if we can add blocks instead, do so
if (m_core.get_current_blockchain_height() < m_core.get_target_blockchain_height())
{
const boost::unique_lock<boost::mutex> sync{m_sync_lock, boost::try_to_lock};
if (sync.owns_lock())
{
uint64_t start_height;
std::vector<cryptonote::block_complete_entry> blocks;
boost::uuids::uuid span_connection_id;
bool filled = false;
if (m_block_queue.get_next_span(start_height, blocks, span_connection_id, filled) && filled)
{
LOG_DEBUG_CC(context, "No other thread is adding blocks, resuming");
MLOG_PEER_STATE("will try to add blocks next");
context.m_state = cryptonote_connection_context::state_standby;
++context.m_callback_request_count;
m_p2p->request_callback(context);
return true;
}
}
}
2017-07-02 23:41:15 +02:00
if(context.m_last_response_height < context.m_remote_blockchain_height-1)
2014-03-03 23:07:58 +01:00
{//we have to fetch more objects ids, request blockchain entry
2015-12-14 05:54:39 +01:00
2019-10-31 23:26:58 +01:00
NOTIFY_REQUEST_CHAIN::request r{};
2019-11-18 23:18:41 +01:00
m_core.get_blockchain_storage().get_short_chain_history(r.block_ids);
2017-12-11 23:36:58 +01:00
CHECK_AND_ASSERT_MES(!r.block_ids.empty(), false, "Short chain history is empty");
2017-07-02 23:41:15 +02:00
if (!start_from_current_chain)
{
2017-08-12 11:59:27 +02:00
// we'll want to start off from where we are on that peer, which may not be added yet
2017-09-10 18:35:59 +02:00
if (context.m_last_known_hash != crypto::null_hash && r.block_ids.front() != context.m_last_known_hash)
2017-08-12 11:59:27 +02:00
r.block_ids.push_front(context.m_last_known_hash);
2017-07-02 23:41:15 +02:00
}
2017-08-16 20:27:16 +02:00
context.m_last_request_time = boost::posix_time::microsec_clock::universal_time();
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << r.block_ids.size() << ", start_from_current_chain " << start_from_current_chain);
2014-03-03 23:07:58 +01:00
post_notify<NOTIFY_REQUEST_CHAIN>(r, context);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_PEER_STATE("requesting chain");
2014-03-03 23:07:58 +01:00
}else
2015-12-14 05:54:39 +01:00
{
CHECK_AND_ASSERT_MES(context.m_last_response_height == context.m_remote_blockchain_height-1
&& !context.m_needed_objects.size()
&& !context.m_requested_objects.size(), false, "request_missing_blocks final condition failed!"
2014-03-03 23:07:58 +01:00
<< "\r\nm_last_response_height=" << context.m_last_response_height
<< "\r\nm_remote_blockchain_height=" << context.m_remote_blockchain_height
<< "\r\nm_needed_objects.size()=" << context.m_needed_objects.size()
<< "\r\nm_requested_objects.size()=" << context.m_requested_objects.size()
2014-05-25 19:06:40 +02:00
<< "\r\non connection [" << epee::net_utils::print_connection_context_short(context)<< "]");
2015-12-14 05:54:39 +01:00
2014-03-03 23:07:58 +01:00
context.m_state = cryptonote_connection_context::state_normal;
2017-07-07 21:52:24 +02:00
if (context.m_remote_blockchain_height >= m_core.get_target_blockchain_height())
{
if (m_core.get_current_blockchain_height() >= m_core.get_target_blockchain_height())
{
MGINFO_GREEN("SYNCHRONIZED OK");
on_connection_synchronized();
}
}
else
{
MINFO(context << " we've reached this peer's blockchain height");
}
2014-03-03 23:07:58 +01:00
}
return true;
}
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2014-03-03 23:07:58 +01:00
bool t_cryptonote_protocol_handler<t_core>::on_connection_synchronized()
{
bool val_expected = false;
2014-03-20 12:46:11 +01:00
if(m_synchronized.compare_exchange_strong(val_expected, true))
2014-03-03 23:07:58 +01:00
{
2017-01-23 02:03:04 +01:00
MGINFO_YELLOW(ENDL << "**********************************************************************" << ENDL
2018-04-10 06:49:20 +02:00
<< "You are now synchronized with the network. You may now start loki-wallet-cli." << ENDL
2014-03-03 23:07:58 +01:00
<< ENDL
2017-01-23 02:03:04 +01:00
<< "Use the \"help\" command to see the list of available commands." << ENDL
2014-03-03 23:07:58 +01:00
<< "**********************************************************************");
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
m_sync_timer.pause();
if (ELPP->vRegistry()->allowed(el::Level::Info, "sync-info"))
{
const uint64_t sync_time = m_sync_timer.value();
const uint64_t add_time = m_add_timer.value();
if (sync_time && add_time)
{
MCLOG_YELLOW(el::Level::Info, "sync-info", "Sync time: " << sync_time/1e9/60 << " min, idle time " <<
(100.f * (1.0f - add_time / (float)sync_time)) << "%" << ", " <<
(10 * m_sync_download_objects_size / 1024 / 1024) / 10.f << " + " <<
(10 * m_sync_download_chain_size / 1024 / 1024) / 10.f << " MB downloaded, " <<
100.0f * m_sync_old_spans_downloaded / m_sync_spans_downloaded << "% old spans, " <<
100.0f * m_sync_bad_spans_downloaded / m_sync_spans_downloaded << "% bad spans");
}
}
2014-03-03 23:07:58 +01:00
m_core.on_synchronized();
}
2017-08-22 15:54:18 +02:00
m_core.safesyncmode(true);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
m_p2p->clear_used_stripe_peers();
2014-03-03 23:07:58 +01:00
return true;
}
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2014-03-03 23:07:58 +01:00
size_t t_cryptonote_protocol_handler<t_core>::get_synchronizing_connections_count()
{
size_t count = 0;
2017-11-29 23:53:58 +01:00
m_p2p->for_each_connection([&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{
2014-03-03 23:07:58 +01:00
if(context.m_state == cryptonote_connection_context::state_synchronizing)
++count;
return true;
});
return count;
}
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2014-03-03 23:07:58 +01:00
int t_cryptonote_protocol_handler<t_core>::handle_response_chain_entry(int command, NOTIFY_RESPONSE_CHAIN_ENTRY::request& arg, cryptonote_connection_context& context)
{
2017-01-22 11:14:45 +01:00
MLOG_P2P_MESSAGE("Received NOTIFY_RESPONSE_CHAIN_ENTRY: m_block_ids.size()=" << arg.m_block_ids.size()
2014-03-03 23:07:58 +01:00
<< ", m_start_height=" << arg.start_height << ", m_total_height=" << arg.total_height);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_PEER_STATE("received chain");
context.m_last_request_time = boost::date_time::not_a_date_time;
m_sync_download_chain_size += arg.m_block_ids.size() * sizeof(crypto::hash);
2015-12-14 05:54:39 +01:00
2014-03-03 23:07:58 +01:00
if(!arg.m_block_ids.size())
{
LOG_ERROR_CCONTEXT("sent empty m_block_ids, dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, true, false);
2014-03-03 23:07:58 +01:00
return 1;
}
2017-12-07 23:22:14 +01:00
if (arg.total_height < arg.m_block_ids.size() || arg.start_height > arg.total_height - arg.m_block_ids.size())
{
LOG_ERROR_CCONTEXT("sent invalid start/nblocks/height, dropping connection");
drop_connection(context, true, false);
return 1;
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MDEBUG(context << "first block hash " << arg.m_block_ids.front() << ", last " << arg.m_block_ids.back());
2015-12-14 05:54:39 +01:00
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
if (arg.total_height >= CRYPTONOTE_MAX_BLOCK_NUMBER || arg.m_block_ids.size() >= CRYPTONOTE_MAX_BLOCK_NUMBER)
{
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_CHAIN_ENTRY, with total_height=" << arg.total_height << " and block_ids=" << arg.m_block_ids.size());
drop_connection(context, false, false);
return 1;
}
2014-03-03 23:07:58 +01:00
context.m_remote_blockchain_height = arg.total_height;
context.m_last_response_height = arg.start_height + arg.m_block_ids.size()-1;
if(context.m_last_response_height > context.m_remote_blockchain_height)
{
2017-02-11 20:38:18 +01:00
LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_CHAIN_ENTRY, with m_total_height=" << arg.total_height
<< ", m_start_height=" << arg.start_height
<< ", m_block_ids.size()=" << arg.m_block_ids.size());
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2017-07-02 23:41:15 +02:00
return 1;
2014-03-03 23:07:58 +01:00
}
2017-09-13 22:03:04 +02:00
uint64_t n_use_blocks = m_core.prevalidate_block_hashes(arg.start_height, arg.m_block_ids);
2018-06-02 22:32:42 +02:00
if (n_use_blocks + HASH_OF_HASHES_STEP <= arg.m_block_ids.size())
2017-09-13 22:03:04 +02:00
{
2018-06-02 22:32:42 +02:00
LOG_ERROR_CCONTEXT("Most blocks are invalid, dropping connection");
drop_connection(context, true, false);
2017-09-13 22:03:04 +02:00
return 1;
}
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
context.m_needed_objects.clear();
2017-09-13 22:03:04 +02:00
uint64_t added = 0;
2017-01-22 21:38:10 +01:00
for(auto& bl_id: arg.m_block_ids)
2014-03-03 23:07:58 +01:00
{
2017-07-02 23:41:15 +02:00
context.m_needed_objects.push_back(bl_id);
2017-09-13 22:03:04 +02:00
if (++added == n_use_blocks)
break;
2014-03-03 23:07:58 +01:00
}
2017-09-13 22:03:04 +02:00
context.m_last_response_height -= arg.m_block_ids.size() - n_use_blocks;
2014-03-03 23:07:58 +01:00
2017-07-02 23:41:15 +02:00
if (!request_missing_objects(context, false))
{
LOG_ERROR_CCONTEXT("Failed to request missing objects, dropping connection");
2017-08-09 21:49:24 +02:00
drop_connection(context, false, false);
2017-07-02 23:41:15 +02:00
return 1;
}
2017-08-22 18:17:19 +02:00
if (arg.total_height > m_core.get_target_blockchain_height())
m_core.set_target_blockchain_height(arg.total_height);
2014-03-03 23:07:58 +01:00
return 1;
}
2019-11-18 23:18:41 +01:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
int t_cryptonote_protocol_handler<t_core>::handle_request_block_blinks(int command, NOTIFY_REQUEST_BLOCK_BLINKS::request& arg, cryptonote_connection_context& context)
{
MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_BLOCK_BLINKS: heights.size()=" << arg.heights.size());
NOTIFY_RESPONSE_BLOCK_BLINKS::request r;
r.txs = m_core.get_pool().get_mined_blinks({arg.heights.begin(), arg.heights.end()});
MLOG_P2P_MESSAGE("-->>NOTIFY_RESPONSE_BLOCK_BLINKS: txs.size()=" << r.txs.size());
post_notify<NOTIFY_RESPONSE_BLOCK_BLINKS>(r, context);
return 1;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
int t_cryptonote_protocol_handler<t_core>::handle_response_block_blinks(int command, NOTIFY_RESPONSE_BLOCK_BLINKS::request& arg, cryptonote_connection_context& context)
{
MLOG_P2P_MESSAGE("Received NOTIFY_RESPONSE_BLOCK_BLINKS: txs.size()=" << arg.txs.size());
2019-11-24 19:57:44 +01:00
m_core.get_pool().keep_missing_blinks(arg.txs);
2019-11-18 23:18:41 +01:00
if (arg.txs.empty())
{
2019-11-24 19:57:44 +01:00
MDEBUG("NOTIFY_RESPONSE_BLOCKS_BLINKS included only blink txes we already knew about");
2019-11-18 23:18:41 +01:00
return 1;
}
NOTIFY_REQUEST_GET_TXS::request req;
while (!arg.txs.empty())
{
if (arg.txs.size() <= CURRENCY_PROTOCOL_MAX_TXS_REQUEST_COUNT)
req.txs = std::move(arg.txs);
else
{
req.txs = {arg.txs.end() - CURRENCY_PROTOCOL_MAX_TXS_REQUEST_COUNT, arg.txs.end()};
arg.txs.resize(arg.txs.size() - CURRENCY_PROTOCOL_MAX_TXS_REQUEST_COUNT);
}
MLOG_P2P_MESSAGE("-->>NOTIFY_REQUEST_GET_TXS: requesting for tx & blink data, txs.size()=" << req.txs.size());
post_notify<NOTIFY_REQUEST_GET_TXS>(req, context);
}
MLOG_PEER_STATE("requesting missing blink txs");
return 1;
}
2014-03-03 23:07:58 +01:00
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2019-06-04 04:28:56 +02:00
bool t_cryptonote_protocol_handler<t_core>::relay_block(NOTIFY_NEW_FLUFFY_BLOCK::request& arg, cryptonote_connection_context& exclude_context)
2014-03-03 23:07:58 +01:00
{
2016-11-29 17:21:33 +01:00
// sort peers between fluffy ones and others
2019-06-04 04:28:56 +02:00
std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> fluffyConnections;
m_p2p->for_each_connection([this, &exclude_context, &fluffyConnections](connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)
2016-10-26 21:00:08 +02:00
{
2019-04-09 10:07:13 +02:00
if (peer_id && exclude_context.m_connection_id != context.m_connection_id && context.m_remote_address.get_zone() == epee::net_utils::zone::public_)
2016-10-26 21:00:08 +02:00
{
2019-06-04 04:28:56 +02:00
LOG_DEBUG_CC(context, "PEER FLUFFY BLOCKS - RELAYING THIN/COMPACT WHATEVER BLOCK");
fluffyConnections.push_back({context.m_remote_address.get_zone(), context.m_connection_id});
2016-10-26 21:00:08 +02:00
}
2016-11-29 17:21:33 +01:00
return true;
2016-10-26 21:00:08 +02:00
});
2016-11-29 17:21:33 +01:00
2019-06-04 04:28:56 +02:00
std::string fluffyBlob;
if (arg.b.txs.size())
2018-08-01 15:56:37 +02:00
{
2019-06-04 04:28:56 +02:00
epee::serialization::store_t_to_binary(arg, fluffyBlob);
2018-08-01 15:56:37 +02:00
}
2019-06-04 04:28:56 +02:00
else
2018-08-01 15:56:37 +02:00
{
2019-06-04 04:28:56 +02:00
// NOTE: We should never ideally hit this case. If we do, some developer
// at the calling site passed in the full block information
// relay_block is only meant to send the header, tx blobs should be
// requested subsequently in handle notify fluffy transactions
LOG_PRINT_L1("relay_block called with argument that contains TX blobs, this is the non-expected case");
NOTIFY_NEW_FLUFFY_BLOCK::request arg_without_tx_blobs = {};
arg_without_tx_blobs.current_blockchain_height = arg.current_blockchain_height;
arg_without_tx_blobs.b.block = arg.b.block;
epee::serialization::store_t_to_binary(arg_without_tx_blobs, fluffyBlob);
2018-08-01 15:56:37 +02:00
}
2016-11-29 17:21:33 +01:00
2019-06-04 04:28:56 +02:00
m_p2p->relay_notify_to_list(NOTIFY_NEW_FLUFFY_BLOCK::ID, epee::strspan<uint8_t>(fluffyBlob), std::move(fluffyConnections));
2018-04-28 04:07:51 +02:00
return true;
2014-03-03 23:07:58 +01:00
}
//------------------------------------------------------------------------------------------------------------------------
2015-12-14 05:54:39 +01:00
template<class t_core>
2019-09-18 07:36:00 +02:00
bool t_cryptonote_protocol_handler<t_core>::relay_uptime_proof(NOTIFY_UPTIME_PROOF::request& arg, cryptonote_connection_context& exclude_context)
2019-05-01 08:01:17 +02:00
{
2019-08-13 04:23:08 +02:00
bool result = relay_to_synchronized_peers<NOTIFY_UPTIME_PROOF>(arg, exclude_context);
2019-05-01 08:01:17 +02:00
return result;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2019-05-31 03:06:42 +02:00
bool t_cryptonote_protocol_handler<t_core>::relay_service_node_votes(NOTIFY_NEW_SERVICE_NODE_VOTE::request& arg, cryptonote_connection_context& exclude_context)
2019-05-01 08:01:17 +02:00
{
2019-08-13 04:23:08 +02:00
bool result = relay_to_synchronized_peers<NOTIFY_NEW_SERVICE_NODE_VOTE>(arg, exclude_context);
2019-05-01 08:01:17 +02:00
return result;
Service Node Deregister Part 5 (#89)
* Retrieve quorum list from height, reviewed
* Setup data structures for de/register TX
* Submit and validate partial/full deregisters
* Add P2P relaying of partial deregistration votes
* Code review adjustments for deregistration part 1
- Fix check_tx_semantic
- Remove signature_pod as votes are now stored as blobs. Serialization
overrides don't intefere with crypto::signature anymore.
* deregistration_vote_pool - changed sign/verify interface and removed repeated code
* Misc review, fix sign/verify api, vote threshold
* Deregister/tx edge case handling for combinatoric votes
* core, service_node_list: separated address from service node pubkey
* Retrieve quorum list from height, reviewed
* Setup data structures for de/register TX
* Submit and validate partial/full deregisters
* Add P2P relaying of partial deregistration votes
* Code review adjustments for deregistration part 1
- Fix check_tx_semantic
- Remove signature_pod as votes are now stored as blobs. Serialization
overrides don't intefere with crypto::signature anymore.
* deregistration_vote_pool - changed sign/verify interface and removed repeated code
* Misc review, fix sign/verify api, vote threshold
* Deregister/tx edge case handling for combinatoric votes
* Store service node lists for the duration of deregister lifetimes
* Quorum min/max bug, sort node list, fix node to test list
* Change quorum to store acc pub address, fix oob bug
* Code review for expiring votes, acc keys to pub_key, improve err msgs
* Add early out for is_deregistration_tx and protect against quorum changes
* Remove debug code, fix segfault
* Remove irrelevant check for tx v3 in blockchain, fix >= height for pruning quorum states
Incorrect assumption that a transaction can be kept in the chain if it could
eventually become invalid, because if it were the chain would be split and
eventually these transaction would be dropped. But also that we should not
override the pre-existing logic which handles this case anyway.
2018-07-18 04:42:47 +02:00
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2014-03-03 23:07:58 +01:00
bool t_cryptonote_protocol_handler<t_core>::relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, cryptonote_connection_context& exclude_context)
{
2019-04-09 10:07:13 +02:00
const bool hide_tx_broadcast =
1 < m_p2p->get_zone_count() && exclude_context.m_remote_address.get_zone() == epee::net_utils::zone::invalid;
if (hide_tx_broadcast)
MDEBUG("Attempting to conceal origin of tx via anonymity network connection(s)");
2019-01-31 00:17:45 +01:00
const bool pad_transactions = m_core.pad_transactions() || hide_tx_broadcast;
2019-11-06 07:28:33 +01:00
// no check for success, so tell core they're relayed unconditionally and snag a copy of the
// hash so that we can look up any associated blink data we should include.
std::vector<crypto::hash> relayed_txes;
relayed_txes.reserve(arg.txs.size());
for (auto &tx_blob : arg.txs)
relayed_txes.push_back(
m_core.on_transaction_relayed(tx_blob)
);
// Rebuild arg.blinks from blink data that we have because we don't necessarily have the same
// blink data that got sent to us (we may have additional blink info, or may have rejected some
// of the incoming blink data).
arg.blinks.clear();
2019-11-18 23:38:16 +01:00
if (m_core.get_blockchain_storage().get_current_hard_fork_version() >= HF_VERSION_BLINK)
2018-11-02 23:27:25 +01:00
{
2019-11-06 07:28:33 +01:00
auto &pool = m_core.get_pool();
auto lock = pool.blink_shared_lock();
for (auto &hash : relayed_txes)
{
if (auto blink = pool.get_blink(hash))
{
arg.blinks.emplace_back();
auto l = blink->shared_lock();
2019-11-18 23:18:41 +01:00
blink->fill_serialization_data(arg.blinks.back());
2019-11-06 07:28:33 +01:00
}
}
2018-11-02 23:27:25 +01:00
}
if (pad_transactions)
{
// stuff some dummy bytes in to stay safe from traffic volume analysis
2019-11-03 19:11:56 +01:00
arg._.clear();
arg._.resize(std::uniform_int_distribution<size_t>{0, 1024}(tools::rng), ' ');
2018-11-02 23:27:25 +01:00
}
2019-04-09 10:07:13 +02:00
std::vector<std::pair<epee::net_utils::zone, boost::uuids::uuid>> connections;
m_p2p->for_each_connection([hide_tx_broadcast, &exclude_context, &connections](connection_context& context, nodetool::peerid_type peer_id, uint32_t support_flags)
{
const epee::net_utils::zone current_zone = context.m_remote_address.get_zone();
const bool broadcast_to_peer =
peer_id &&
(hide_tx_broadcast != bool(current_zone == epee::net_utils::zone::public_)) &&
2019-11-06 07:28:33 +01:00
exclude_context.m_connection_id != context.m_connection_id;
2019-04-09 10:07:13 +02:00
if (broadcast_to_peer)
connections.push_back({current_zone, context.m_connection_id});
return true;
});
if (connections.empty())
MERROR("Transaction not relayed - no" << (hide_tx_broadcast ? " privacy": "") << " peers available");
else
{
std::string fullBlob;
epee::serialization::store_t_to_binary(arg, fullBlob);
m_p2p->relay_notify_to_list(NOTIFY_NEW_TRANSACTIONS::ID, epee::strspan<uint8_t>(fullBlob), std::move(connections));
}
return true;
2014-03-03 23:07:58 +01:00
}
2017-08-09 21:49:24 +02:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
std::string t_cryptonote_protocol_handler<t_core>::get_peers_overview() const
{
std::stringstream ss;
const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
m_p2p->for_each_connection([&](const connection_context &ctx, nodetool::peerid_type peer_id, uint32_t support_flags) {
const uint32_t stripe = tools::get_pruning_stripe(ctx.m_pruning_seed);
char state_char = cryptonote::get_protocol_state_char(ctx.m_state);
ss << stripe + state_char;
if (ctx.m_last_request_time != boost::date_time::not_a_date_time)
ss << (((now - ctx.m_last_request_time).total_microseconds() > IDLE_PEER_KICK_TIME) ? "!" : "?");
ss << + " ";
return true;
});
return ss.str();
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
std::pair<uint32_t, uint32_t> t_cryptonote_protocol_handler<t_core>::get_next_needed_pruning_stripe() const
{
const uint64_t want_height_from_blockchain = m_core.get_current_blockchain_height();
const uint64_t want_height_from_block_queue = m_block_queue.get_next_needed_height(want_height_from_blockchain);
const uint64_t want_height = std::max(want_height_from_blockchain, want_height_from_block_queue);
uint64_t blockchain_height = m_core.get_target_blockchain_height();
// if we don't know the remote chain size yet, assume infinitely large so we get the right stripe if we're not near the tip
if (blockchain_height == 0)
blockchain_height = CRYPTONOTE_MAX_BLOCK_NUMBER;
const uint32_t next_pruning_stripe = tools::get_pruning_stripe(want_height, blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES);
if (next_pruning_stripe == 0)
return std::make_pair(0, 0);
// if we already have a few peers on this stripe, but none on next one, try next one
unsigned int n_next = 0, n_subsequent = 0, n_others = 0;
const uint32_t subsequent_pruning_stripe = 1 + next_pruning_stripe % (1<<CRYPTONOTE_PRUNING_LOG_STRIPES);
m_p2p->for_each_connection([&](const connection_context &context, nodetool::peerid_type peer_id, uint32_t support_flags) {
if (context.m_state >= cryptonote_connection_context::state_synchronizing)
{
if (context.m_pruning_seed == 0 || tools::get_pruning_stripe(context.m_pruning_seed) == next_pruning_stripe)
++n_next;
else if (tools::get_pruning_stripe(context.m_pruning_seed) == subsequent_pruning_stripe)
++n_subsequent;
else
++n_others;
}
return true;
});
const bool use_next = (n_next > m_max_out_peers / 2 && n_subsequent <= 1) || (n_next > 2 && n_subsequent == 0);
const uint32_t ret_stripe = use_next ? subsequent_pruning_stripe: next_pruning_stripe;
MIDEBUG(const std::string po = get_peers_overview(), "get_next_needed_pruning_stripe: want height " << want_height << " (" <<
want_height_from_blockchain << " from blockchain, " << want_height_from_block_queue << " from block queue), stripe " <<
next_pruning_stripe << " (" << n_next << "/" << m_max_out_peers << " on it and " << n_subsequent << " on " <<
subsequent_pruning_stripe << ", " << n_others << " others) -> " << ret_stripe << " (+" <<
(ret_stripe - next_pruning_stripe + (1 << CRYPTONOTE_PRUNING_LOG_STRIPES)) % (1 << CRYPTONOTE_PRUNING_LOG_STRIPES) <<
"), current peers " << po);
return std::make_pair(next_pruning_stripe, ret_stripe);
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
bool t_cryptonote_protocol_handler<t_core>::needs_new_sync_connections() const
{
const uint64_t target = m_core.get_target_blockchain_height();
const uint64_t height = m_core.get_current_blockchain_height();
if (target && target <= height)
return false;
size_t n_out_peers = 0;
m_p2p->for_each_connection([&](cryptonote_connection_context& ctx, nodetool::peerid_type peer_id, uint32_t support_flags)->bool{
if (!ctx.m_is_income)
++n_out_peers;
return true;
});
if (n_out_peers >= m_max_out_peers)
return false;
return true;
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
2017-08-09 21:49:24 +02:00
void t_cryptonote_protocol_handler<t_core>::drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans)
{
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
LOG_DEBUG_CC(context, "dropping connection id " << context.m_connection_id << " (pruning seed " <<
epee::string_tools::to_string_hex(context.m_pruning_seed) <<
"), add_fail " << add_fail << ", flush_all_spans " << flush_all_spans);
2018-05-01 17:21:43 +02:00
2017-08-09 21:49:24 +02:00
if (add_fail)
m_p2p->add_host_fail(context.m_remote_address);
2017-08-18 21:14:23 +02:00
m_block_queue.flush_spans(context.m_connection_id, flush_all_spans);
2018-11-26 18:19:25 +01:00
m_p2p->drop_connection(context);
2017-08-18 21:14:23 +02:00
}
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
void t_cryptonote_protocol_handler<t_core>::on_connection_close(cryptonote_connection_context &context)
{
2017-08-09 21:49:24 +02:00
uint64_t target = 0;
m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id, uint32_t support_flags) {
if (cntxt.m_state >= cryptonote_connection_context::state_synchronizing && cntxt.m_connection_id != context.m_connection_id)
target = std::max(target, cntxt.m_remote_blockchain_height);
return true;
});
const uint64_t previous_target = m_core.get_target_blockchain_height();
if (target < previous_target)
{
MINFO("Target height decreasing from " << previous_target << " to " << target);
m_core.set_target_blockchain_height(target);
2019-04-14 11:03:33 +02:00
if (target == 0 && context.m_state > cryptonote_connection_context::state_before_handshake && !m_stopping)
2019-06-28 09:19:08 +02:00
MCWARNING("global", "lokid is now disconnected from the network");
2017-08-09 21:49:24 +02:00
}
2017-08-18 21:14:23 +02:00
m_block_queue.flush_spans(context.m_connection_id, false);
Pruning
The blockchain prunes seven eighths of prunable tx data.
This saves about two thirds of the blockchain size, while
keeping the node useful as a sync source for an eighth
of the blockchain.
No other data is currently pruned.
There are three ways to prune a blockchain:
- run monerod with --prune-blockchain
- run "prune_blockchain" in the monerod console
- run the monero-blockchain-prune utility
The first two will prune in place. Due to how LMDB works, this
will not reduce the blockchain size on disk. Instead, it will
mark parts of the file as free, so that future data will use
that free space, causing the file to not grow until free space
grows scarce.
The third way will create a second database, a pruned copy of
the original one. Since this is a new file, this one will be
smaller than the original one.
Once the database is pruned, it will stay pruned as it syncs.
That is, there is no need to use --prune-blockchain again, etc.
2018-04-30 00:30:51 +02:00
MLOG_PEER_STATE("closed");
2017-08-09 21:49:24 +02:00
}
2015-01-05 20:30:17 +01:00
2016-12-04 13:27:45 +01:00
//------------------------------------------------------------------------------------------------------------------------
template<class t_core>
void t_cryptonote_protocol_handler<t_core>::stop()
{
m_stopping = true;
m_core.stop();
}
2015-01-05 20:30:17 +01:00
} // namespace
2018-07-25 10:16:01 +02:00