mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-12-23 07:08:55 +00:00
Merge pull request #501
d887c18
hardfork: fix more major/minor issues (moneromooo-monero)3b47ca2
hardfork: fix rescan on load (moneromooo-monero)4cea2b1
Add IP blocking for misbehaving nodes (adapted from Boolberry) (Javier Smooth)9c64b12
quiet down p2p logging a bit (Javier Smooth)53c75ab
blockchain: log versions as numbers, not characters (moneromooo-monero)edade8d
hardfork: fix actual/voting confusion (moneromooo-monero)
This commit is contained in:
commit
4061a32082
@ -899,9 +899,7 @@ POP_WARNINGS
|
|||||||
boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this,
|
boost::bind(&boosted_tcp_server<t_protocol_handler>::handle_accept, this,
|
||||||
boost::asio::placeholders::error));
|
boost::asio::placeholders::error));
|
||||||
|
|
||||||
bool r = conn->start(true, 1 < m_threads_count);
|
conn->start(true, 1 < m_threads_count);
|
||||||
if (!r)
|
|
||||||
_erro("[sock " << conn->socket().native_handle() << "] Failed to start connection, connections_count = " << m_sock_count);
|
|
||||||
conn->save_dbg_log();
|
conn->save_dbg_log();
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
|
@ -105,6 +105,11 @@
|
|||||||
#define P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT 5000 //5 seconds
|
#define P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT 5000 //5 seconds
|
||||||
#define P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT 70
|
#define P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT 70
|
||||||
|
|
||||||
|
#define P2P_FAILED_ADDR_FORGET_SECONDS (60*60) //1 hour
|
||||||
|
#define P2P_IP_BLOCKTIME (60*60*24) //24 hour
|
||||||
|
#define P2P_IP_FAILS_BEFORE_BLOCK 10
|
||||||
|
#define P2P_IDLE_CONNECTION_KILL_INTERVAL (5*60) //5 minutes
|
||||||
|
|
||||||
#define ALLOW_DEBUG_COMMANDS
|
#define ALLOW_DEBUG_COMMANDS
|
||||||
|
|
||||||
#define CRYPTONOTE_NAME "bitmonero"
|
#define CRYPTONOTE_NAME "bitmonero"
|
||||||
|
@ -257,13 +257,13 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet)
|
|||||||
if (testnet) {
|
if (testnet) {
|
||||||
m_hardfork = new HardFork(*db, 1, testnet_hard_fork_version_1_till);
|
m_hardfork = new HardFork(*db, 1, testnet_hard_fork_version_1_till);
|
||||||
for (size_t n = 0; n < sizeof(testnet_hard_forks) / sizeof(testnet_hard_forks[0]); ++n)
|
for (size_t n = 0; n < sizeof(testnet_hard_forks) / sizeof(testnet_hard_forks[0]); ++n)
|
||||||
m_hardfork->add(testnet_hard_forks[n].version, testnet_hard_forks[n].height, testnet_hard_forks[n].threshold, testnet_hard_forks[n].time);
|
m_hardfork->add_fork(testnet_hard_forks[n].version, testnet_hard_forks[n].height, testnet_hard_forks[n].threshold, testnet_hard_forks[n].time);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_hardfork = new HardFork(*db, 1, mainnet_hard_fork_version_1_till);
|
m_hardfork = new HardFork(*db, 1, mainnet_hard_fork_version_1_till);
|
||||||
for (size_t n = 0; n < sizeof(mainnet_hard_forks) / sizeof(mainnet_hard_forks[0]); ++n)
|
for (size_t n = 0; n < sizeof(mainnet_hard_forks) / sizeof(mainnet_hard_forks[0]); ++n)
|
||||||
m_hardfork->add(mainnet_hard_forks[n].version, mainnet_hard_forks[n].height, mainnet_hard_forks[n].threshold, mainnet_hard_forks[n].time);
|
m_hardfork->add_fork(mainnet_hard_forks[n].version, mainnet_hard_forks[n].height, mainnet_hard_forks[n].threshold, mainnet_hard_forks[n].time);
|
||||||
}
|
}
|
||||||
m_hardfork->init();
|
m_hardfork->init();
|
||||||
|
|
||||||
@ -2338,7 +2338,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||||||
// this is a cheap test
|
// this is a cheap test
|
||||||
if (!m_hardfork->check(bl))
|
if (!m_hardfork->check(bl))
|
||||||
{
|
{
|
||||||
LOG_PRINT_L1("Block with id: " << id << std::endl << "has old version: " << bl.major_version << std::endl << "current: " << m_hardfork->get_current_version());
|
LOG_PRINT_L1("Block with id: " << id << std::endl << "has old version: " << (unsigned)bl.major_version << std::endl << "current: " << (unsigned)m_hardfork->get_current_version());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,11 @@ static uint8_t get_block_vote(const cryptonote::block &b)
|
|||||||
return b.minor_version;
|
return b.minor_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t get_block_version(const cryptonote::block &b)
|
||||||
|
{
|
||||||
|
return b.major_version;
|
||||||
|
}
|
||||||
|
|
||||||
HardFork::HardFork(cryptonote::BlockchainDB &db, uint8_t original_version, uint64_t original_version_till_height, time_t forked_time, time_t update_time, uint64_t window_size, uint8_t default_threshold_percent):
|
HardFork::HardFork(cryptonote::BlockchainDB &db, uint8_t original_version, uint64_t original_version_till_height, time_t forked_time, time_t update_time, uint64_t window_size, uint8_t default_threshold_percent):
|
||||||
db(db),
|
db(db),
|
||||||
original_version(original_version),
|
original_version(original_version),
|
||||||
@ -61,7 +66,7 @@ HardFork::HardFork(cryptonote::BlockchainDB &db, uint8_t original_version, uint6
|
|||||||
throw "default_threshold_percent needs to be between 0 and 100";
|
throw "default_threshold_percent needs to be between 0 and 100";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HardFork::add(uint8_t version, uint64_t height, uint8_t threshold, time_t time)
|
bool HardFork::add_fork(uint8_t version, uint64_t height, uint8_t threshold, time_t time)
|
||||||
{
|
{
|
||||||
CRITICAL_REGION_LOCAL(lock);
|
CRITICAL_REGION_LOCAL(lock);
|
||||||
|
|
||||||
@ -82,42 +87,43 @@ bool HardFork::add(uint8_t version, uint64_t height, uint8_t threshold, time_t t
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HardFork::add(uint8_t version, uint64_t height, time_t time)
|
bool HardFork::add_fork(uint8_t version, uint64_t height, time_t time)
|
||||||
{
|
{
|
||||||
return add(version, height, default_threshold_percent, time);
|
return add_fork(version, height, default_threshold_percent, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t HardFork::get_effective_version(uint8_t version) const
|
uint8_t HardFork::get_effective_version(uint8_t voting_version) const
|
||||||
{
|
{
|
||||||
if (!heights.empty()) {
|
if (!heights.empty()) {
|
||||||
uint8_t max_version = heights.back().version;
|
uint8_t max_version = heights.back().version;
|
||||||
if (version > max_version)
|
if (voting_version > max_version)
|
||||||
version = max_version;
|
voting_version = max_version;
|
||||||
}
|
}
|
||||||
return version;
|
return voting_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HardFork::do_check(uint8_t version) const
|
bool HardFork::do_check(uint8_t block_version, uint8_t voting_version) const
|
||||||
{
|
{
|
||||||
return version >= heights[current_fork_index].version;
|
return block_version >= heights[current_fork_index].version
|
||||||
|
&& voting_version >= heights[current_fork_index].version;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HardFork::check(const cryptonote::block &block) const
|
bool HardFork::check(const cryptonote::block &block) const
|
||||||
{
|
{
|
||||||
CRITICAL_REGION_LOCAL(lock);
|
CRITICAL_REGION_LOCAL(lock);
|
||||||
return do_check(get_block_vote(block));
|
return do_check(::get_block_version(block), ::get_block_vote(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HardFork::add(uint8_t block_version, uint64_t height)
|
bool HardFork::add(uint8_t block_version, uint8_t voting_version, uint64_t height)
|
||||||
{
|
{
|
||||||
CRITICAL_REGION_LOCAL(lock);
|
CRITICAL_REGION_LOCAL(lock);
|
||||||
|
|
||||||
if (!do_check(block_version))
|
if (!do_check(block_version, voting_version))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
db.set_hard_fork_version(height, heights[current_fork_index].version);
|
db.set_hard_fork_version(height, heights[current_fork_index].version);
|
||||||
|
|
||||||
const uint8_t version = get_effective_version(block_version);
|
voting_version = get_effective_version(voting_version);
|
||||||
|
|
||||||
while (versions.size() >= window_size) {
|
while (versions.size() >= window_size) {
|
||||||
const uint8_t old_version = versions.front();
|
const uint8_t old_version = versions.front();
|
||||||
@ -126,8 +132,8 @@ bool HardFork::add(uint8_t block_version, uint64_t height)
|
|||||||
versions.pop_front();
|
versions.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
last_versions[version]++;
|
last_versions[voting_version]++;
|
||||||
versions.push_back(version);
|
versions.push_back(voting_version);
|
||||||
|
|
||||||
uint8_t voted = get_voted_fork_index(height + 1);
|
uint8_t voted = get_voted_fork_index(height + 1);
|
||||||
if (voted > current_fork_index) {
|
if (voted > current_fork_index) {
|
||||||
@ -143,7 +149,7 @@ bool HardFork::add(uint8_t block_version, uint64_t height)
|
|||||||
|
|
||||||
bool HardFork::add(const cryptonote::block &block, uint64_t height)
|
bool HardFork::add(const cryptonote::block &block, uint64_t height)
|
||||||
{
|
{
|
||||||
return add(get_block_vote(block), height);
|
return add(::get_block_version(block), ::get_block_vote(block), height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HardFork::init()
|
void HardFork::init()
|
||||||
@ -185,7 +191,7 @@ uint8_t HardFork::get_block_version(uint64_t height) const
|
|||||||
return original_version;
|
return original_version;
|
||||||
|
|
||||||
const cryptonote::block &block = db.get_block_from_height(height);
|
const cryptonote::block &block = db.get_block_from_height(height);
|
||||||
return get_block_vote(block);
|
return ::get_block_version(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HardFork::reorganize_from_block_height(uint64_t height)
|
bool HardFork::reorganize_from_block_height(uint64_t height)
|
||||||
@ -225,7 +231,7 @@ bool HardFork::reorganize_from_block_height(uint64_t height)
|
|||||||
|
|
||||||
const uint64_t bc_height = db.height();
|
const uint64_t bc_height = db.height();
|
||||||
for (uint64_t h = height + 1; h < bc_height; ++h) {
|
for (uint64_t h = height + 1; h < bc_height; ++h) {
|
||||||
add(get_block_version(h), h);
|
add(db.get_block_from_height(h), h);
|
||||||
}
|
}
|
||||||
|
|
||||||
db.batch_stop();
|
db.batch_stop();
|
||||||
@ -258,7 +264,7 @@ bool HardFork::rescan_from_block_height(uint64_t height)
|
|||||||
versions.push_back(v);
|
versions.push_back(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t lastv = db.get_hard_fork_version(height);
|
uint8_t lastv = db.get_hard_fork_version(db.height() - 1);
|
||||||
current_fork_index = 0;
|
current_fork_index = 0;
|
||||||
while (current_fork_index + 1 < heights.size() && heights[current_fork_index].version != lastv)
|
while (current_fork_index + 1 < heights.size() && heights[current_fork_index].version != lastv)
|
||||||
++current_fork_index;
|
++current_fork_index;
|
||||||
|
@ -71,7 +71,7 @@ namespace cryptonote
|
|||||||
* @param threshold The threshold of votes needed for this fork (0-100)
|
* @param threshold The threshold of votes needed for this fork (0-100)
|
||||||
* @param time Approximate time of the hardfork (seconds since epoch)
|
* @param time Approximate time of the hardfork (seconds since epoch)
|
||||||
*/
|
*/
|
||||||
bool add(uint8_t version, uint64_t height, uint8_t threshold, time_t time);
|
bool add_fork(uint8_t version, uint64_t height, uint8_t threshold, time_t time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief add a new hardfork height
|
* @brief add a new hardfork height
|
||||||
@ -79,10 +79,11 @@ namespace cryptonote
|
|||||||
* returns true if no error, false otherwise
|
* returns true if no error, false otherwise
|
||||||
*
|
*
|
||||||
* @param version the major block version for the fork
|
* @param version the major block version for the fork
|
||||||
|
* @param voting_version the minor block version for the fork, used for voting
|
||||||
* @param height The height the hardfork takes effect
|
* @param height The height the hardfork takes effect
|
||||||
* @param time Approximate time of the hardfork (seconds since epoch)
|
* @param time Approximate time of the hardfork (seconds since epoch)
|
||||||
*/
|
*/
|
||||||
bool add(uint8_t version, uint64_t height, time_t time);
|
bool add_fork(uint8_t version, uint64_t height, time_t time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief initialize the object
|
* @brief initialize the object
|
||||||
@ -203,10 +204,10 @@ namespace cryptonote
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
uint8_t get_block_version(uint64_t height) const;
|
uint8_t get_block_version(uint64_t height) const;
|
||||||
bool do_check(uint8_t version) const;
|
bool do_check(uint8_t block_version, uint8_t voting_version) const;
|
||||||
int get_voted_fork_index(uint64_t height) const;
|
int get_voted_fork_index(uint64_t height) const;
|
||||||
uint8_t get_effective_version(uint8_t version) const;
|
uint8_t get_effective_version(uint8_t voting_version) const;
|
||||||
bool add(uint8_t block_version, uint64_t height);
|
bool add(uint8_t block_version, uint8_t voting_version, uint64_t height);
|
||||||
|
|
||||||
bool rescan_from_block_height(uint64_t height);
|
bool rescan_from_block_height(uint64_t height);
|
||||||
bool rescan_from_chain_height(uint64_t height);
|
bool rescan_from_chain_height(uint64_t height);
|
||||||
|
@ -571,6 +571,7 @@ namespace cryptonote
|
|||||||
{
|
{
|
||||||
LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
|
LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
|
||||||
m_p2p->drop_connection(context);
|
m_p2p->drop_connection(context);
|
||||||
|
m_p2p->add_ip_fail(context.m_remote_ip);
|
||||||
m_core.cleanup_handle_incoming_blocks();
|
m_core.cleanup_handle_incoming_blocks();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -578,6 +579,7 @@ namespace cryptonote
|
|||||||
{
|
{
|
||||||
LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection");
|
LOG_PRINT_CCONTEXT_L1("Block received at sync phase was marked as orphaned, dropping connection");
|
||||||
m_p2p->drop_connection(context);
|
m_p2p->drop_connection(context);
|
||||||
|
m_p2p->add_ip_fail(context.m_remote_ip);
|
||||||
m_core.cleanup_handle_incoming_blocks();
|
m_core.cleanup_handle_incoming_blocks();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -728,6 +730,7 @@ namespace cryptonote
|
|||||||
{
|
{
|
||||||
LOG_ERROR_CCONTEXT("sent empty m_block_ids, dropping connection");
|
LOG_ERROR_CCONTEXT("sent empty m_block_ids, dropping connection");
|
||||||
m_p2p->drop_connection(context);
|
m_p2p->drop_connection(context);
|
||||||
|
m_p2p->add_ip_fail(context.m_remote_ip);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -736,6 +739,7 @@ namespace cryptonote
|
|||||||
LOG_ERROR_CCONTEXT("sent m_block_ids starting from unknown id: "
|
LOG_ERROR_CCONTEXT("sent m_block_ids starting from unknown id: "
|
||||||
<< epee::string_tools::pod_to_hex(arg.m_block_ids.front()) << " , dropping connection");
|
<< epee::string_tools::pod_to_hex(arg.m_block_ids.front()) << " , dropping connection");
|
||||||
m_p2p->drop_connection(context);
|
m_p2p->drop_connection(context);
|
||||||
|
m_p2p->add_ip_fail(context.m_remote_ip);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include <boost/program_options/variables_map.hpp>
|
#include <boost/program_options/variables_map.hpp>
|
||||||
#include <boost/serialization/version.hpp>
|
#include <boost/serialization/version.hpp>
|
||||||
#include <boost/uuid/uuid.hpp>
|
#include <boost/uuid/uuid.hpp>
|
||||||
|
#include <boost/serialization/map.hpp>
|
||||||
|
|
||||||
#include "cryptonote_config.h"
|
#include "cryptonote_config.h"
|
||||||
#include "warnings.h"
|
#include "warnings.h"
|
||||||
@ -66,7 +67,8 @@ namespace nodetool
|
|||||||
|
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
class node_server: public epee::levin::levin_commands_handler<p2p_connection_context_t<typename t_payload_net_handler::connection_context> >,
|
class node_server: public epee::levin::levin_commands_handler<p2p_connection_context_t<typename t_payload_net_handler::connection_context> >,
|
||||||
public i_p2p_endpoint<typename t_payload_net_handler::connection_context>
|
public i_p2p_endpoint<typename t_payload_net_handler::connection_context>,
|
||||||
|
public epee::net_utils::i_connection_filter
|
||||||
{
|
{
|
||||||
struct by_conn_id{};
|
struct by_conn_id{};
|
||||||
struct by_peer_id{};
|
struct by_peer_id{};
|
||||||
@ -169,6 +171,10 @@ namespace nodetool
|
|||||||
virtual bool drop_connection(const epee::net_utils::connection_context_base& context);
|
virtual bool drop_connection(const epee::net_utils::connection_context_base& context);
|
||||||
virtual void request_callback(const epee::net_utils::connection_context_base& context);
|
virtual void request_callback(const epee::net_utils::connection_context_base& context);
|
||||||
virtual void for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type)> f);
|
virtual void for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type)> f);
|
||||||
|
virtual bool block_ip(uint32_t adress);
|
||||||
|
virtual bool add_ip_fail(uint32_t address);
|
||||||
|
//----------------- i_connection_filter --------------------------------------------------------
|
||||||
|
virtual bool is_remote_ip_allowed(uint32_t adress);
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr);
|
bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr);
|
||||||
bool handle_command_line(
|
bool handle_command_line(
|
||||||
@ -196,6 +202,8 @@ namespace nodetool
|
|||||||
template<class t_callback>
|
template<class t_callback>
|
||||||
bool try_ping(basic_node_data& node_data, p2p_connection_context& context, t_callback cb);
|
bool try_ping(basic_node_data& node_data, p2p_connection_context& context, t_callback cb);
|
||||||
bool make_expected_connections_count(bool white_list, size_t expected_connections);
|
bool make_expected_connections_count(bool white_list, size_t expected_connections);
|
||||||
|
void cache_connect_fail_info(const net_address& addr);
|
||||||
|
bool is_addr_recently_failed(const net_address& addr);
|
||||||
bool is_priority_node(const net_address& na);
|
bool is_priority_node(const net_address& na);
|
||||||
|
|
||||||
template <class Container>
|
template <class Container>
|
||||||
@ -282,6 +290,15 @@ namespace nodetool
|
|||||||
//keep connections to initiate some interactions
|
//keep connections to initiate some interactions
|
||||||
net_server m_net_server;
|
net_server m_net_server;
|
||||||
boost::uuids::uuid m_network_id;
|
boost::uuids::uuid m_network_id;
|
||||||
|
|
||||||
|
std::map<net_address, time_t> m_conn_fails_cache;
|
||||||
|
epee::critical_section m_conn_fails_cache_lock;
|
||||||
|
|
||||||
|
epee::critical_section m_blocked_ips_lock;
|
||||||
|
std::map<uint32_t, time_t> m_blocked_ips;
|
||||||
|
|
||||||
|
epee::critical_section m_ip_fails_score_lock;
|
||||||
|
std::map<uint32_t, uint64_t> m_ip_fails_score;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
//
|
//
|
||||||
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
|
||||||
|
|
||||||
|
// IP blocking adapted from Boolberry
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -161,6 +163,22 @@ namespace nodetool
|
|||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
|
bool node_server<t_payload_net_handler>::is_remote_ip_allowed(uint32_t addr)
|
||||||
|
{
|
||||||
|
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
|
||||||
|
auto it = m_blocked_ips.find(addr);
|
||||||
|
if(it == m_blocked_ips.end())
|
||||||
|
return true;
|
||||||
|
if(time(nullptr) - it->second > P2P_IP_BLOCKTIME )
|
||||||
|
{
|
||||||
|
m_blocked_ips.erase(it);
|
||||||
|
LOG_PRINT_CYAN("IP " << epee::string_tools::get_ip_string_from_int32(addr) << "is unblocked.", LOG_LEVEL_0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::make_default_config()
|
bool node_server<t_payload_net_handler>::make_default_config()
|
||||||
{
|
{
|
||||||
m_config.m_peer_id = crypto::rand<uint64_t>();
|
m_config.m_peer_id = crypto::rand<uint64_t>();
|
||||||
@ -168,6 +186,31 @@ namespace nodetool
|
|||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
|
bool node_server<t_payload_net_handler>::block_ip(uint32_t addr)
|
||||||
|
{
|
||||||
|
CRITICAL_REGION_LOCAL(m_blocked_ips_lock);
|
||||||
|
m_blocked_ips[addr] = time(nullptr);
|
||||||
|
LOG_PRINT_CYAN("IP " << epee::string_tools::get_ip_string_from_int32(addr) << " blocked.", LOG_LEVEL_0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
template<class t_payload_net_handler>
|
||||||
|
bool node_server<t_payload_net_handler>::add_ip_fail(uint32_t address)
|
||||||
|
{
|
||||||
|
CRITICAL_REGION_LOCAL(m_ip_fails_score_lock);
|
||||||
|
uint64_t fails = ++m_ip_fails_score[address];
|
||||||
|
LOG_PRINT_CYAN("IP " << epee::string_tools::get_ip_string_from_int32(address) << " fail score=" << fails, LOG_LEVEL_1);
|
||||||
|
if(fails > P2P_IP_FAILS_BEFORE_BLOCK)
|
||||||
|
{
|
||||||
|
auto it = m_ip_fails_score.find(address);
|
||||||
|
CHECK_AND_ASSERT_MES(it != m_ip_fails_score.end(), false, "internal error");
|
||||||
|
it->second = P2P_IP_FAILS_BEFORE_BLOCK/2;
|
||||||
|
block_ip(address);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr)
|
bool node_server<t_payload_net_handler>::parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr)
|
||||||
{
|
{
|
||||||
return epee::string_tools::parse_peer_from_string(pe.ip, pe.port, node_addr);
|
return epee::string_tools::parse_peer_from_string(pe.ip, pe.port, node_addr);
|
||||||
@ -428,6 +471,7 @@ namespace nodetool
|
|||||||
m_net_server.set_threads_prefix("P2P");
|
m_net_server.set_threads_prefix("P2P");
|
||||||
m_net_server.get_config_object().m_pcommands_handler = this;
|
m_net_server.get_config_object().m_pcommands_handler = this;
|
||||||
m_net_server.get_config_object().m_invoke_timeout = P2P_DEFAULT_INVOKE_TIMEOUT;
|
m_net_server.get_config_object().m_invoke_timeout = P2P_DEFAULT_INVOKE_TIMEOUT;
|
||||||
|
m_net_server.set_connection_filter(this);
|
||||||
|
|
||||||
//try to bind
|
//try to bind
|
||||||
LOG_PRINT_L0("Binding on " << m_bind_ip << ":" << m_port);
|
LOG_PRINT_L0("Binding on " << m_bind_ip << ":" << m_port);
|
||||||
@ -624,6 +668,7 @@ namespace nodetool
|
|||||||
if(!handle_remote_peerlist(rsp.local_peerlist, rsp.node_data.local_time, context))
|
if(!handle_remote_peerlist(rsp.local_peerlist, rsp.node_data.local_time, context))
|
||||||
{
|
{
|
||||||
LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE: failed to handle_remote_peerlist(...), closing connection.");
|
LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE: failed to handle_remote_peerlist(...), closing connection.");
|
||||||
|
add_ip_fail(context.m_remote_ip);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hsh_result = true;
|
hsh_result = true;
|
||||||
@ -685,6 +730,7 @@ namespace nodetool
|
|||||||
{
|
{
|
||||||
LOG_ERROR_CCONTEXT("COMMAND_TIMED_SYNC: failed to handle_remote_peerlist(...), closing connection.");
|
LOG_ERROR_CCONTEXT("COMMAND_TIMED_SYNC: failed to handle_remote_peerlist(...), closing connection.");
|
||||||
m_net_server.get_config_object().close(context.m_connection_id );
|
m_net_server.get_config_object().close(context.m_connection_id );
|
||||||
|
add_ip_fail(context.m_remote_ip);
|
||||||
}
|
}
|
||||||
if(!context.m_is_income)
|
if(!context.m_is_income)
|
||||||
m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_ip, context.m_remote_port);
|
m_peerlist.set_peer_just_seen(context.peer_id, context.m_remote_ip, context.m_remote_port);
|
||||||
@ -829,6 +875,20 @@ namespace nodetool
|
|||||||
|
|
||||||
#undef LOG_PRINT_CC_PRIORITY_NODE
|
#undef LOG_PRINT_CC_PRIORITY_NODE
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
template<class t_payload_net_handler>
|
||||||
|
bool node_server<t_payload_net_handler>::is_addr_recently_failed(const net_address& addr)
|
||||||
|
{
|
||||||
|
CRITICAL_REGION_LOCAL(m_conn_fails_cache_lock);
|
||||||
|
auto it = m_conn_fails_cache.find(addr);
|
||||||
|
if(it == m_conn_fails_cache.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(time(NULL) - it->second > P2P_FAILED_ADDR_FORGET_SECONDS)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(bool use_white_list)
|
bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(bool use_white_list)
|
||||||
@ -866,7 +926,13 @@ namespace nodetool
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_PRINT_L1("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip)
|
if(!is_remote_ip_allowed(pe.adr.ip))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(is_addr_recently_failed(pe.adr))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LOG_PRINT_L2("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip)
|
||||||
<< ":" << boost::lexical_cast<std::string>(pe.adr.port)
|
<< ":" << boost::lexical_cast<std::string>(pe.adr.port)
|
||||||
<< "[white=" << use_white_list
|
<< "[white=" << use_white_list
|
||||||
<< "] last_seen: " << (pe.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never"));
|
<< "] last_seen: " << (pe.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never"));
|
||||||
@ -1270,6 +1336,7 @@ namespace nodetool
|
|||||||
|
|
||||||
LOG_PRINT_CCONTEXT_L1("WRONG NETWORK AGENT CONNECTED! id=" << epee::string_tools::get_str_from_guid_a(arg.node_data.network_id));
|
LOG_PRINT_CCONTEXT_L1("WRONG NETWORK AGENT CONNECTED! id=" << epee::string_tools::get_str_from_guid_a(arg.node_data.network_id));
|
||||||
drop_connection(context);
|
drop_connection(context);
|
||||||
|
add_ip_fail(context.m_remote_ip);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1277,6 +1344,7 @@ namespace nodetool
|
|||||||
{
|
{
|
||||||
LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE came not from incoming connection");
|
LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE came not from incoming connection");
|
||||||
drop_connection(context);
|
drop_connection(context);
|
||||||
|
add_ip_fail(context.m_remote_ip);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,8 @@ namespace nodetool
|
|||||||
virtual void request_callback(const epee::net_utils::connection_context_base& context)=0;
|
virtual void request_callback(const epee::net_utils::connection_context_base& context)=0;
|
||||||
virtual uint64_t get_connections_count()=0;
|
virtual uint64_t get_connections_count()=0;
|
||||||
virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type)> f)=0;
|
virtual void for_each_connection(std::function<bool(t_connection_context&, peerid_type)> f)=0;
|
||||||
|
virtual bool block_ip(uint32_t adress)=0;
|
||||||
|
virtual bool add_ip_fail(uint32_t adress)=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class t_connection_context>
|
template<class t_connection_context>
|
||||||
@ -84,5 +86,13 @@ namespace nodetool
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
virtual bool block_ip(uint32_t adress)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual bool add_ip_fail(uint32_t adress)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include "net_peerlist_boost_serialization.h"
|
#include "net_peerlist_boost_serialization.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define CURRENT_PEERLIST_STORAGE_ARCHIVE_VER 4
|
||||||
|
|
||||||
namespace nodetool
|
namespace nodetool
|
||||||
{
|
{
|
||||||
@ -394,4 +395,4 @@ namespace nodetool
|
|||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_CLASS_VERSION(nodetool::peerlist_manager, 4)
|
BOOST_CLASS_VERSION(nodetool::peerlist_manager, CURRENT_PEERLIST_STORAGE_ARCHIVE_VER)
|
||||||
|
@ -135,6 +135,7 @@ private:
|
|||||||
static cryptonote::block mkblock(uint8_t version)
|
static cryptonote::block mkblock(uint8_t version)
|
||||||
{
|
{
|
||||||
cryptonote::block b;
|
cryptonote::block b;
|
||||||
|
b.major_version = version;
|
||||||
b.minor_version = version;
|
b.minor_version = version;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@ -144,7 +145,7 @@ TEST(empty_hardforks, Success)
|
|||||||
TestDB db;
|
TestDB db;
|
||||||
HardFork hf(db);
|
HardFork hf(db);
|
||||||
|
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
hf.init();
|
hf.init();
|
||||||
ASSERT_TRUE(hf.get_state(time(NULL)) == HardFork::Ready);
|
ASSERT_TRUE(hf.get_state(time(NULL)) == HardFork::Ready);
|
||||||
ASSERT_TRUE(hf.get_state(time(NULL) + 3600*24*400) == HardFork::Ready);
|
ASSERT_TRUE(hf.get_state(time(NULL) + 3600*24*400) == HardFork::Ready);
|
||||||
@ -163,13 +164,13 @@ TEST(ordering, Success)
|
|||||||
TestDB db;
|
TestDB db;
|
||||||
HardFork hf(db);
|
HardFork hf(db);
|
||||||
|
|
||||||
ASSERT_TRUE(hf.add(2, 2, 1));
|
ASSERT_TRUE(hf.add_fork(2, 2, 1));
|
||||||
ASSERT_FALSE(hf.add(3, 3, 1));
|
ASSERT_FALSE(hf.add_fork(3, 3, 1));
|
||||||
ASSERT_FALSE(hf.add(3, 2, 2));
|
ASSERT_FALSE(hf.add_fork(3, 2, 2));
|
||||||
ASSERT_FALSE(hf.add(2, 3, 2));
|
ASSERT_FALSE(hf.add_fork(2, 3, 2));
|
||||||
ASSERT_TRUE(hf.add(3, 10, 2));
|
ASSERT_TRUE(hf.add_fork(3, 10, 2));
|
||||||
ASSERT_TRUE(hf.add(4, 20, 3));
|
ASSERT_TRUE(hf.add_fork(4, 20, 3));
|
||||||
ASSERT_FALSE(hf.add(5, 5, 4));
|
ASSERT_FALSE(hf.add_fork(5, 5, 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(states, Success)
|
TEST(states, Success)
|
||||||
@ -177,8 +178,8 @@ TEST(states, Success)
|
|||||||
TestDB db;
|
TestDB db;
|
||||||
HardFork hf(db);
|
HardFork hf(db);
|
||||||
|
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(2, BLOCKS_PER_YEAR, SECONDS_PER_YEAR));
|
ASSERT_TRUE(hf.add_fork(2, BLOCKS_PER_YEAR, SECONDS_PER_YEAR));
|
||||||
|
|
||||||
ASSERT_TRUE(hf.get_state(0) == HardFork::Ready);
|
ASSERT_TRUE(hf.get_state(0) == HardFork::Ready);
|
||||||
ASSERT_TRUE(hf.get_state(SECONDS_PER_YEAR / 2) == HardFork::Ready);
|
ASSERT_TRUE(hf.get_state(SECONDS_PER_YEAR / 2) == HardFork::Ready);
|
||||||
@ -186,7 +187,7 @@ TEST(states, Success)
|
|||||||
ASSERT_TRUE(hf.get_state(SECONDS_PER_YEAR + (HardFork::DEFAULT_UPDATE_TIME + HardFork::DEFAULT_FORKED_TIME) / 2) == HardFork::UpdateNeeded);
|
ASSERT_TRUE(hf.get_state(SECONDS_PER_YEAR + (HardFork::DEFAULT_UPDATE_TIME + HardFork::DEFAULT_FORKED_TIME) / 2) == HardFork::UpdateNeeded);
|
||||||
ASSERT_TRUE(hf.get_state(SECONDS_PER_YEAR + HardFork::DEFAULT_FORKED_TIME * 2) == HardFork::LikelyForked);
|
ASSERT_TRUE(hf.get_state(SECONDS_PER_YEAR + HardFork::DEFAULT_FORKED_TIME * 2) == HardFork::LikelyForked);
|
||||||
|
|
||||||
ASSERT_TRUE(hf.add(3, BLOCKS_PER_YEAR * 5, SECONDS_PER_YEAR * 5));
|
ASSERT_TRUE(hf.add_fork(3, BLOCKS_PER_YEAR * 5, SECONDS_PER_YEAR * 5));
|
||||||
|
|
||||||
ASSERT_TRUE(hf.get_state(0) == HardFork::Ready);
|
ASSERT_TRUE(hf.get_state(0) == HardFork::Ready);
|
||||||
ASSERT_TRUE(hf.get_state(SECONDS_PER_YEAR / 2) == HardFork::Ready);
|
ASSERT_TRUE(hf.get_state(SECONDS_PER_YEAR / 2) == HardFork::Ready);
|
||||||
@ -201,10 +202,10 @@ TEST(steps_asap, Success)
|
|||||||
HardFork hf(db, 1,0,1,1,1);
|
HardFork hf(db, 1,0,1,1,1);
|
||||||
|
|
||||||
// v h t
|
// v h t
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(4, 2, 1));
|
ASSERT_TRUE(hf.add_fork(4, 2, 1));
|
||||||
ASSERT_TRUE(hf.add(7, 4, 2));
|
ASSERT_TRUE(hf.add_fork(7, 4, 2));
|
||||||
ASSERT_TRUE(hf.add(9, 6, 3));
|
ASSERT_TRUE(hf.add_fork(9, 6, 3));
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
for (uint64_t h = 0; h < 10; ++h) {
|
for (uint64_t h = 0; h < 10; ++h) {
|
||||||
@ -229,9 +230,9 @@ TEST(steps_1, Success)
|
|||||||
TestDB db;
|
TestDB db;
|
||||||
HardFork hf(db, 1,0,1,1,1);
|
HardFork hf(db, 1,0,1,1,1);
|
||||||
|
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
for (int n = 1 ; n < 10; ++n)
|
for (int n = 1 ; n < 10; ++n)
|
||||||
ASSERT_TRUE(hf.add(n+1, n, n));
|
ASSERT_TRUE(hf.add_fork(n+1, n, n));
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
for (uint64_t h = 0 ; h < 10; ++h) {
|
for (uint64_t h = 0 ; h < 10; ++h) {
|
||||||
@ -251,10 +252,10 @@ TEST(reorganize, Same)
|
|||||||
HardFork hf(db, 1, 0, 1, 1, history, 100);
|
HardFork hf(db, 1, 0, 1, 1, history, 100);
|
||||||
|
|
||||||
// v h t
|
// v h t
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(4, 2, 1));
|
ASSERT_TRUE(hf.add_fork(4, 2, 1));
|
||||||
ASSERT_TRUE(hf.add(7, 4, 2));
|
ASSERT_TRUE(hf.add_fork(7, 4, 2));
|
||||||
ASSERT_TRUE(hf.add(9, 6, 3));
|
ASSERT_TRUE(hf.add_fork(9, 6, 3));
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
// index 0 1 2 3 4 5 6 7 8 9
|
// index 0 1 2 3 4 5 6 7 8 9
|
||||||
@ -270,6 +271,10 @@ TEST(reorganize, Same)
|
|||||||
uint8_t version = hh >= history ? block_versions[hh - history] : 1;
|
uint8_t version = hh >= history ? block_versions[hh - history] : 1;
|
||||||
ASSERT_EQ(hf.get(hh), version);
|
ASSERT_EQ(hf.get(hh), version);
|
||||||
}
|
}
|
||||||
|
ASSERT_EQ(hf.get_start_height(1), 0);
|
||||||
|
ASSERT_EQ(hf.get_start_height(4), 2 + history);
|
||||||
|
ASSERT_EQ(hf.get_start_height(7), 4 + history);
|
||||||
|
ASSERT_EQ(hf.get_start_height(9), 6 + history);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,10 +286,10 @@ TEST(reorganize, Changed)
|
|||||||
HardFork hf(db, 1, 0, 1, 1, 4, 100);
|
HardFork hf(db, 1, 0, 1, 1, 4, 100);
|
||||||
|
|
||||||
// v h t
|
// v h t
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(4, 2, 1));
|
ASSERT_TRUE(hf.add_fork(4, 2, 1));
|
||||||
ASSERT_TRUE(hf.add(7, 4, 2));
|
ASSERT_TRUE(hf.add_fork(7, 4, 2));
|
||||||
ASSERT_TRUE(hf.add(9, 6, 3));
|
ASSERT_TRUE(hf.add_fork(9, 6, 3));
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
// fork 4 7 9
|
// fork 4 7 9
|
||||||
@ -301,6 +306,10 @@ TEST(reorganize, Changed)
|
|||||||
for (int hh = 0; hh < 16; ++hh) {
|
for (int hh = 0; hh < 16; ++hh) {
|
||||||
ASSERT_EQ(hf.get(hh), expected_versions[hh]);
|
ASSERT_EQ(hf.get(hh), expected_versions[hh]);
|
||||||
}
|
}
|
||||||
|
ASSERT_EQ(hf.get_start_height(1), 0);
|
||||||
|
ASSERT_EQ(hf.get_start_height(4), 6);
|
||||||
|
ASSERT_EQ(hf.get_start_height(7), 8);
|
||||||
|
ASSERT_EQ(hf.get_start_height(9), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delay a bit for 9, and go back to 1 to check it stays at 9
|
// delay a bit for 9, and go back to 1 to check it stays at 9
|
||||||
@ -321,6 +330,10 @@ TEST(reorganize, Changed)
|
|||||||
for (int hh = 0; hh < 15; ++hh) {
|
for (int hh = 0; hh < 15; ++hh) {
|
||||||
ASSERT_EQ(hf.get(hh), expected_versions_new[hh]);
|
ASSERT_EQ(hf.get(hh), expected_versions_new[hh]);
|
||||||
}
|
}
|
||||||
|
ASSERT_EQ(hf.get_start_height(1), 0);
|
||||||
|
ASSERT_EQ(hf.get_start_height(4), 6);
|
||||||
|
ASSERT_EQ(hf.get_start_height(7), 11);
|
||||||
|
ASSERT_EQ(hf.get_start_height(9), 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(voting, threshold)
|
TEST(voting, threshold)
|
||||||
@ -330,8 +343,8 @@ TEST(voting, threshold)
|
|||||||
HardFork hf(db, 1, 0, 1, 1, 8, threshold);
|
HardFork hf(db, 1, 0, 1, 1, 8, threshold);
|
||||||
|
|
||||||
// v h t
|
// v h t
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(2, 2, 1));
|
ASSERT_TRUE(hf.add_fork(2, 2, 1));
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
for (uint64_t h = 0; h <= 8; ++h) {
|
for (uint64_t h = 0; h <= 8; ++h) {
|
||||||
@ -359,10 +372,10 @@ TEST(voting, different_thresholds)
|
|||||||
HardFork hf(db, 1, 0, 1, 1, 4, 50); // window size 4
|
HardFork hf(db, 1, 0, 1, 1, 4, 50); // window size 4
|
||||||
|
|
||||||
// v h t
|
// v h t
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(2, 5, 0, 1)); // asap
|
ASSERT_TRUE(hf.add_fork(2, 5, 0, 1)); // asap
|
||||||
ASSERT_TRUE(hf.add(3, 10, 100, 2)); // all votes
|
ASSERT_TRUE(hf.add_fork(3, 10, 100, 2)); // all votes
|
||||||
ASSERT_TRUE(hf.add(4, 15, 3)); // default 50% votes
|
ASSERT_TRUE(hf.add_fork(4, 15, 3)); // default 50% votes
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
|
||||||
@ -386,8 +399,8 @@ TEST(new_blocks, denied)
|
|||||||
HardFork hf(db, 1, 0, 1, 1, 4, 50);
|
HardFork hf(db, 1, 0, 1, 1, 4, 50);
|
||||||
|
|
||||||
// v h t
|
// v h t
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(2, 2, 1));
|
ASSERT_TRUE(hf.add_fork(2, 2, 1));
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
ASSERT_TRUE(hf.add(mkblock(1), 0));
|
ASSERT_TRUE(hf.add(mkblock(1), 0));
|
||||||
@ -411,8 +424,8 @@ TEST(new_version, early)
|
|||||||
HardFork hf(db, 1, 0, 1, 1, 4, 50);
|
HardFork hf(db, 1, 0, 1, 1, 4, 50);
|
||||||
|
|
||||||
// v h t
|
// v h t
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(2, 4, 1));
|
ASSERT_TRUE(hf.add_fork(2, 4, 1));
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
ASSERT_TRUE(hf.add(mkblock(2), 0));
|
ASSERT_TRUE(hf.add(mkblock(2), 0));
|
||||||
@ -433,9 +446,9 @@ TEST(reorganize, changed)
|
|||||||
HardFork hf(db, 1, 0, 1, 1, 4, 50);
|
HardFork hf(db, 1, 0, 1, 1, 4, 50);
|
||||||
|
|
||||||
// v h t
|
// v h t
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(2, 2, 1));
|
ASSERT_TRUE(hf.add_fork(2, 2, 1));
|
||||||
ASSERT_TRUE(hf.add(3, 5, 2));
|
ASSERT_TRUE(hf.add_fork(3, 5, 2));
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
#define ADD(v, h, a) \
|
#define ADD(v, h, a) \
|
||||||
@ -487,9 +500,9 @@ TEST(get, higher)
|
|||||||
HardFork hf(db, 1, 0, 1, 1, 4, 50);
|
HardFork hf(db, 1, 0, 1, 1, 4, 50);
|
||||||
|
|
||||||
// v h t
|
// v h t
|
||||||
ASSERT_TRUE(hf.add(1, 0, 0));
|
ASSERT_TRUE(hf.add_fork(1, 0, 0));
|
||||||
ASSERT_TRUE(hf.add(2, 2, 1));
|
ASSERT_TRUE(hf.add_fork(2, 2, 1));
|
||||||
ASSERT_TRUE(hf.add(3, 5, 2));
|
ASSERT_TRUE(hf.add_fork(3, 5, 2));
|
||||||
hf.init();
|
hf.init();
|
||||||
|
|
||||||
ASSERT_EQ(hf.get_ideal_version(0), 1);
|
ASSERT_EQ(hf.get_ideal_version(0), 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user