ban peers sending bad pow outright
PoW is expensive to verify, so be strict
This commit is contained in:
parent
faf5805fc0
commit
3455efafa8
|
@ -58,5 +58,6 @@ namespace cryptonote
|
||||||
bool m_marked_as_orphaned;
|
bool m_marked_as_orphaned;
|
||||||
bool m_already_exists;
|
bool m_already_exists;
|
||||||
bool m_partial_block_reward;
|
bool m_partial_block_reward;
|
||||||
|
bool m_bad_pow; // if bad pow, bad peer outright for DoS protection
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1689,6 +1689,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
|
||||||
{
|
{
|
||||||
MERROR_VER("Block with id: " << id << std::endl << " for alternative chain, does not have enough proof of work: " << proof_of_work << std::endl << " expected difficulty: " << current_diff);
|
MERROR_VER("Block with id: " << id << std::endl << " for alternative chain, does not have enough proof of work: " << proof_of_work << std::endl << " expected difficulty: " << current_diff);
|
||||||
bvc.m_verifivation_failed = true;
|
bvc.m_verifivation_failed = true;
|
||||||
|
bvc.m_bad_pow = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3620,6 +3621,7 @@ leave:
|
||||||
{
|
{
|
||||||
MERROR_VER("Block with id: " << id << std::endl << "does not have enough proof of work: " << proof_of_work << " at height " << blockchain_height << ", unexpected difficulty: " << current_diffic);
|
MERROR_VER("Block with id: " << id << std::endl << "does not have enough proof of work: " << proof_of_work << " at height " << blockchain_height << ", unexpected difficulty: " << current_diffic);
|
||||||
bvc.m_verifivation_failed = true;
|
bvc.m_verifivation_failed = true;
|
||||||
|
bvc.m_bad_pow = true;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,7 @@ namespace cryptonote
|
||||||
bool on_connection_synchronized();
|
bool on_connection_synchronized();
|
||||||
bool should_download_next_span(cryptonote_connection_context& context, bool standby);
|
bool should_download_next_span(cryptonote_connection_context& context, bool standby);
|
||||||
void drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans);
|
void drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans);
|
||||||
|
void drop_connection_with_score(cryptonote_connection_context &context, unsigned int score, bool flush_all_spans);
|
||||||
bool kick_idle_peers();
|
bool kick_idle_peers();
|
||||||
bool check_standby_peers();
|
bool check_standby_peers();
|
||||||
bool update_sync_search();
|
bool update_sync_search();
|
||||||
|
|
|
@ -475,7 +475,7 @@ namespace cryptonote
|
||||||
if(bvc.m_verifivation_failed)
|
if(bvc.m_verifivation_failed)
|
||||||
{
|
{
|
||||||
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
|
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
|
||||||
drop_connection(context, true, false);
|
drop_connection_with_score(context, bvc.m_bad_pow ? P2P_IP_FAILS_BEFORE_BLOCK : 1, false);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(bvc.m_added_to_main_chain)
|
if(bvc.m_added_to_main_chain)
|
||||||
|
@ -748,7 +748,7 @@ namespace cryptonote
|
||||||
if( bvc.m_verifivation_failed )
|
if( bvc.m_verifivation_failed )
|
||||||
{
|
{
|
||||||
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
|
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
|
||||||
drop_connection(context, true, false);
|
drop_connection_with_score(context, bvc.m_bad_pow ? P2P_IP_FAILS_BEFORE_BLOCK : 1, false);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if( bvc.m_added_to_main_chain )
|
if( bvc.m_added_to_main_chain )
|
||||||
|
@ -1309,7 +1309,7 @@ namespace cryptonote
|
||||||
{
|
{
|
||||||
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
|
if (!m_p2p->for_connection(span_connection_id, [&](cryptonote_connection_context& context, nodetool::peerid_type peer_id, uint32_t f)->bool{
|
||||||
LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
|
LOG_PRINT_CCONTEXT_L1("Block verification failed, dropping connection");
|
||||||
drop_connection(context, true, true);
|
drop_connection_with_score(context, bvc.m_bad_pow ? P2P_IP_FAILS_BEFORE_BLOCK : 1, true);
|
||||||
return 1;
|
return 1;
|
||||||
}))
|
}))
|
||||||
LOG_ERROR_CCONTEXT("span connection id not found");
|
LOG_ERROR_CCONTEXT("span connection id not found");
|
||||||
|
@ -2305,14 +2305,14 @@ skip:
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------
|
||||||
template<class t_core>
|
template<class t_core>
|
||||||
void t_cryptonote_protocol_handler<t_core>::drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans)
|
void t_cryptonote_protocol_handler<t_core>::drop_connection_with_score(cryptonote_connection_context &context, unsigned score, bool flush_all_spans)
|
||||||
{
|
{
|
||||||
LOG_DEBUG_CC(context, "dropping connection id " << context.m_connection_id << " (pruning seed " <<
|
LOG_DEBUG_CC(context, "dropping connection id " << context.m_connection_id << " (pruning seed " <<
|
||||||
epee::string_tools::to_string_hex(context.m_pruning_seed) <<
|
epee::string_tools::to_string_hex(context.m_pruning_seed) <<
|
||||||
"), add_fail " << add_fail << ", flush_all_spans " << flush_all_spans);
|
"), score " << score << ", flush_all_spans " << flush_all_spans);
|
||||||
|
|
||||||
if (add_fail)
|
if (score > 0)
|
||||||
m_p2p->add_host_fail(context.m_remote_address);
|
m_p2p->add_host_fail(context.m_remote_address, score);
|
||||||
|
|
||||||
m_block_queue.flush_spans(context.m_connection_id, flush_all_spans);
|
m_block_queue.flush_spans(context.m_connection_id, flush_all_spans);
|
||||||
|
|
||||||
|
@ -2320,6 +2320,12 @@ skip:
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------
|
||||||
template<class t_core>
|
template<class t_core>
|
||||||
|
void t_cryptonote_protocol_handler<t_core>::drop_connection(cryptonote_connection_context &context, bool add_fail, bool flush_all_spans)
|
||||||
|
{
|
||||||
|
return drop_connection_with_score(context, add_fail ? 1 : 0, flush_all_spans);
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------------------------------------------------
|
||||||
|
template<class t_core>
|
||||||
void t_cryptonote_protocol_handler<t_core>::on_connection_close(cryptonote_connection_context &context)
|
void t_cryptonote_protocol_handler<t_core>::on_connection_close(cryptonote_connection_context &context)
|
||||||
{
|
{
|
||||||
uint64_t target = 0;
|
uint64_t target = 0;
|
||||||
|
|
|
@ -342,7 +342,7 @@ namespace nodetool
|
||||||
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, uint32_t)> f);
|
virtual void for_each_connection(std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f);
|
||||||
virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f);
|
virtual bool for_connection(const boost::uuids::uuid&, std::function<bool(typename t_payload_net_handler::connection_context&, peerid_type, uint32_t)> f);
|
||||||
virtual bool add_host_fail(const epee::net_utils::network_address &address);
|
virtual bool add_host_fail(const epee::net_utils::network_address &address, unsigned int score = 1);
|
||||||
//----------------- i_connection_filter --------------------------------------------------------
|
//----------------- i_connection_filter --------------------------------------------------------
|
||||||
virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address, time_t *t = NULL);
|
virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address, time_t *t = NULL);
|
||||||
//-----------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -315,13 +315,13 @@ namespace nodetool
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
template<class t_payload_net_handler>
|
template<class t_payload_net_handler>
|
||||||
bool node_server<t_payload_net_handler>::add_host_fail(const epee::net_utils::network_address &address)
|
bool node_server<t_payload_net_handler>::add_host_fail(const epee::net_utils::network_address &address, unsigned int score)
|
||||||
{
|
{
|
||||||
if(!address.is_blockable())
|
if(!address.is_blockable())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CRITICAL_REGION_LOCAL(m_host_fails_score_lock);
|
CRITICAL_REGION_LOCAL(m_host_fails_score_lock);
|
||||||
uint64_t fails = ++m_host_fails_score[address.host_str()];
|
uint64_t fails = m_host_fails_score[address.host_str()] += score;
|
||||||
MDEBUG("Host " << address.host_str() << " fail score=" << fails);
|
MDEBUG("Host " << address.host_str() << " fail score=" << fails);
|
||||||
if(fails > P2P_IP_FAILS_BEFORE_BLOCK)
|
if(fails > P2P_IP_FAILS_BEFORE_BLOCK)
|
||||||
{
|
{
|
||||||
|
|
|
@ -60,7 +60,7 @@ namespace nodetool
|
||||||
virtual bool unblock_host(const epee::net_utils::network_address &address)=0;
|
virtual bool unblock_host(const epee::net_utils::network_address &address)=0;
|
||||||
virtual std::map<std::string, time_t> get_blocked_hosts()=0;
|
virtual std::map<std::string, time_t> get_blocked_hosts()=0;
|
||||||
virtual std::map<epee::net_utils::ipv4_network_subnet, time_t> get_blocked_subnets()=0;
|
virtual std::map<epee::net_utils::ipv4_network_subnet, time_t> get_blocked_subnets()=0;
|
||||||
virtual bool add_host_fail(const epee::net_utils::network_address &address)=0;
|
virtual bool add_host_fail(const epee::net_utils::network_address &address, unsigned int score = 1)=0;
|
||||||
virtual void add_used_stripe_peer(const t_connection_context &context)=0;
|
virtual void add_used_stripe_peer(const t_connection_context &context)=0;
|
||||||
virtual void remove_used_stripe_peer(const t_connection_context &context)=0;
|
virtual void remove_used_stripe_peer(const t_connection_context &context)=0;
|
||||||
virtual void clear_used_stripe_peers()=0;
|
virtual void clear_used_stripe_peers()=0;
|
||||||
|
@ -122,7 +122,7 @@ namespace nodetool
|
||||||
{
|
{
|
||||||
return std::map<epee::net_utils::ipv4_network_subnet, time_t>();
|
return std::map<epee::net_utils::ipv4_network_subnet, time_t>();
|
||||||
}
|
}
|
||||||
virtual bool add_host_fail(const epee::net_utils::network_address &address)
|
virtual bool add_host_fail(const epee::net_utils::network_address &address, unsigned int score)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,13 +217,13 @@ namespace cryptonote
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------------------------
|
||||||
bool core_rpc_server::add_host_fail(const connection_context *ctx)
|
bool core_rpc_server::add_host_fail(const connection_context *ctx, unsigned int score)
|
||||||
{
|
{
|
||||||
if(!ctx || !ctx->m_remote_address.is_blockable())
|
if(!ctx || !ctx->m_remote_address.is_blockable())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CRITICAL_REGION_LOCAL(m_host_fails_score_lock);
|
CRITICAL_REGION_LOCAL(m_host_fails_score_lock);
|
||||||
uint64_t fails = ++m_host_fails_score[ctx->m_remote_address.host_str()];
|
uint64_t fails = m_host_fails_score[ctx->m_remote_address.host_str()] += score;
|
||||||
MDEBUG("Host " << ctx->m_remote_address.host_str() << " fail score=" << fails);
|
MDEBUG("Host " << ctx->m_remote_address.host_str() << " fail score=" << fails);
|
||||||
if(fails > RPC_IP_FAILS_BEFORE_BLOCK)
|
if(fails > RPC_IP_FAILS_BEFORE_BLOCK)
|
||||||
{
|
{
|
||||||
|
|
|
@ -241,7 +241,7 @@ namespace cryptonote
|
||||||
private:
|
private:
|
||||||
bool check_core_busy();
|
bool check_core_busy();
|
||||||
bool check_core_ready();
|
bool check_core_ready();
|
||||||
bool add_host_fail(const connection_context *ctx);
|
bool add_host_fail(const connection_context *ctx, unsigned int score = 1);
|
||||||
|
|
||||||
//utils
|
//utils
|
||||||
uint64_t get_block_reward(const block& blk);
|
uint64_t get_block_reward(const block& blk);
|
||||||
|
|
Loading…
Reference in New Issue