protocol: add checks for top block hard fork version

We won't even talk to a peer which claims a wrong version
for its top block. This will avoid syncing to known bad
peers in the first place.
Also add IP fails when failing to verify a block.
This commit is contained in:
moneromooo-monero 2017-08-09 09:31:00 +01:00
parent 7482253a6d
commit 635929eaca
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3
3 changed files with 22 additions and 0 deletions

View File

@ -745,6 +745,15 @@ namespace cryptonote
*/ */
uint8_t get_ideal_hard_fork_version(uint64_t height) const { return m_hardfork->get_ideal_version(height); } uint8_t get_ideal_hard_fork_version(uint64_t height) const { return m_hardfork->get_ideal_version(height); }
/**
* @brief returns the actual hardfork version for a given block height
*
* @param height the height for which to check version info
*
* @return the version
*/
uint8_t get_hard_fork_version(uint64_t height) const { return m_hardfork->get(height); }
/** /**
* @brief get information about hardfork voting for a version * @brief get information about hardfork voting for a version
* *

View File

@ -195,10 +195,12 @@ namespace cryptonote
{ {
uint64_t current_height; uint64_t current_height;
crypto::hash top_id; crypto::hash top_id;
uint8_t top_version;
BEGIN_KV_SERIALIZE_MAP() BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(current_height) KV_SERIALIZE(current_height)
KV_SERIALIZE_VAL_POD_AS_BLOB(top_id) KV_SERIALIZE_VAL_POD_AS_BLOB(top_id)
KV_SERIALIZE_OPT(top_version, (uint8_t)0)
END_KV_SERIALIZE_MAP() END_KV_SERIALIZE_MAP()
}; };

View File

@ -256,6 +256,14 @@ namespace cryptonote
if(context.m_state == cryptonote_connection_context::state_synchronizing) if(context.m_state == cryptonote_connection_context::state_synchronizing)
return true; return true;
// 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)
const uint8_t version = m_core.get_blockchain_storage().get_ideal_hard_fork_version(hshd.current_height - 1);
if (version >= 6 && version != hshd.top_version)
{
LOG_DEBUG_CC(context, "Ignoring due to wrong top version (" << hshd.top_version << ", expected " << version);
return false;
}
uint64_t target = m_core.get_target_blockchain_height(); uint64_t target = m_core.get_target_blockchain_height();
if (target == 0) if (target == 0)
target = m_core.get_current_blockchain_height(); target = m_core.get_current_blockchain_height();
@ -297,6 +305,7 @@ namespace cryptonote
bool t_cryptonote_protocol_handler<t_core>::get_payload_sync_data(CORE_SYNC_DATA& hshd) 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); m_core.get_blockchain_top(hshd.current_height, hshd.top_id);
hshd.top_version = m_core.get_blockchain_storage().get_hard_fork_version(hshd.current_height);
hshd.current_height +=1; hshd.current_height +=1;
return true; return true;
} }
@ -348,6 +357,7 @@ namespace cryptonote
{ {
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection"); LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
m_p2p->drop_connection(context); m_p2p->drop_connection(context);
m_p2p->add_host_fail(context.m_remote_address);
m_block_queue.flush_spans(context.m_connection_id); m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }
@ -616,6 +626,7 @@ namespace cryptonote
{ {
LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection"); LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection");
m_p2p->drop_connection(context); m_p2p->drop_connection(context);
m_p2p->add_host_fail(context.m_remote_address);
m_block_queue.flush_spans(context.m_connection_id); m_block_queue.flush_spans(context.m_connection_id);
return 1; return 1;
} }