diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 805ab4d30..8ad40aef2 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -534,7 +534,13 @@ public: return false; } else - m_config.m_pcommands_handler->notify(m_current_head.m_command, buff_to_invoke, m_connection_context); + { + const int notify_result = m_config.m_pcommands_handler->notify( + m_current_head.m_command, buff_to_invoke, m_connection_context + ); + if(notify_result < 0) + return false; + } } // reuse small buffer if (!temp.empty() && temp.capacity() <= 64 * 1024) diff --git a/contrib/epee/include/storages/levin_abstract_invoke2.h b/contrib/epee/include/storages/levin_abstract_invoke2.h index 8dfc169c1..7fd52ea1b 100644 --- a/contrib/epee/include/storages/levin_abstract_invoke2.h +++ b/contrib/epee/include/storages/levin_abstract_invoke2.h @@ -212,7 +212,7 @@ namespace epee #define END_INVOKE_MAP2() \ LOG_ERROR("Unknown command:" << command); \ on_levin_traffic(context, false, false, true, in_buff.size(), "invalid-command"); \ - return LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED; \ + return is_notify ? LEVIN_OK : LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED; \ } \ catch (const std::exception &e) { \ MERROR("Error in handle_invoke_map: " << e.what()); \ diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 7e0fe0b8a..fbdb2cc44 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -617,7 +617,7 @@ namespace cryptonote if (!m_core.check_incoming_block_size(arg.b.block)) { drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } // Parse and quick hash incoming block, dropping the connection on failure @@ -633,7 +633,7 @@ namespace cryptonote ); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } // Log block info @@ -661,7 +661,7 @@ namespace cryptonote MERROR("sent bad block entry: there are duplicate tx hashes in parsed block: " << epee::string_tools::buff_to_hex_nodelimer(arg.b.block)); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } // Keeping a map of the full transactions provided in this payload allows us to pass them @@ -678,7 +678,7 @@ namespace cryptonote ); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } // try adding block to the blockchain @@ -739,7 +739,7 @@ namespace cryptonote // drop connection and punish peer LOG_PRINT_CCONTEXT_L0("Block verification failed, dropping connection"); drop_connection_with_score(context, bvc.m_bad_pow ? P2P_IP_FAILS_BEFORE_BLOCK : 1, false); - return 1; + return LEVIN_ERROR_CONNECTION; } } else if( bvc.m_added_to_main_chain ) @@ -778,7 +778,7 @@ namespace cryptonote { LOG_ERROR_CCONTEXT("Requested fluffy tx before handshake, dropping connection"); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } std::vector> local_blocks; @@ -789,7 +789,7 @@ namespace cryptonote { LOG_ERROR_CCONTEXT("failed to find block: " << arg.block_hash << ", dropping connection"); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } std::vector txids; @@ -814,7 +814,7 @@ namespace cryptonote << ", dropping connection" ); drop_connection(context, true, false); - return 1; + return LEVIN_ERROR_CONNECTION; } txids.push_back(b.tx_hashes[tx_idx]); seen[tx_idx] = true; @@ -831,7 +831,7 @@ namespace cryptonote ); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } } @@ -842,14 +842,14 @@ namespace cryptonote LOG_ERROR_CCONTEXT("Failed to handle request NOTIFY_REQUEST_FLUFFY_MISSING_TX, " << "failed to get requested transactions"); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } 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"); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } for(auto& tx: txs) @@ -930,7 +930,7 @@ namespace cryptonote { LOG_PRINT_CCONTEXT_L1("Duplicate transaction in notification, dropping connection"); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } } @@ -964,7 +964,7 @@ namespace cryptonote { LOG_PRINT_CCONTEXT_L1("Tx verification failed, dropping connection"); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } switch (tvc.m_relay) @@ -1008,7 +1008,7 @@ namespace cryptonote { LOG_ERROR_CCONTEXT("Requested objects before handshake, dropping connection"); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } MLOG_P2P_MESSAGE("Received NOTIFY_REQUEST_GET_OBJECTS (" << arg.blocks.size() << " blocks)"); if (arg.blocks.size() > CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT) @@ -1018,7 +1018,7 @@ namespace cryptonote << arg.blocks.size() << ") expected not more then " << CURRENCY_PROTOCOL_MAX_OBJECT_REQUEST_COUNT); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } NOTIFY_RESPONSE_GET_OBJECTS::request rsp; @@ -1026,7 +1026,7 @@ namespace cryptonote { LOG_ERROR_CCONTEXT("failed to handle request NOTIFY_REQUEST_GET_OBJECTS, dropping connection"); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } context.m_last_request_time = boost::posix_time::microsec_clock::universal_time(); MLOG_P2P_MESSAGE("-->>NOTIFY_RESPONSE_GET_OBJECTS: blocks.size()=" @@ -1066,7 +1066,7 @@ namespace cryptonote { LOG_ERROR_CCONTEXT("Got NOTIFY_RESPONSE_GET_OBJECTS out of the blue, dropping connection"); drop_connection(context, true, false); - return 1; + return LEVIN_ERROR_CONNECTION; } context.m_expect_response = 0; @@ -1097,7 +1097,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("sent wrong NOTIFY_HAVE_OBJECTS: no blocks"); drop_connection(context, true, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } if(context.m_last_response_height > arg.current_blockchain_height) { @@ -1105,13 +1105,15 @@ namespace cryptonote << " < m_last_response_height=" << context.m_last_response_height << ", dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } if (arg.current_blockchain_height < context.m_remote_blockchain_height) { MINFO(context << "Claims " << arg.current_blockchain_height << ", claimed " << context.m_remote_blockchain_height << " before"); hit_score(context, 1); + if (context.m_score <= DROP_PEERS_ON_SCORE) + return LEVIN_ERROR_CONNECTION; } context.m_remote_blockchain_height = arg.current_blockchain_height; if (context.m_remote_blockchain_height > m_core.get_target_blockchain_height()) @@ -1137,7 +1139,7 @@ namespace cryptonote << epee::string_tools::buff_to_hex_nodelimer(arg.blocks[i].block) << ", dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } if (b.miner_tx.vin.size() != 1 || b.miner_tx.vin.front().type() != typeid(txin_gen)) { @@ -1145,7 +1147,7 @@ namespace cryptonote << epee::string_tools::buff_to_hex_nodelimer(arg.blocks[i].block) << ", dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } const auto this_height = boost::get(b.miner_tx.vin[0]).height; @@ -1154,7 +1156,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("Sent invalid chain"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } // if first block @@ -1166,7 +1168,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("sent block ahead of expected height, dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } if (this_height == 0 || context.get_expected_hash(this_height - 1) != b.prev_id) @@ -1174,7 +1176,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("Sent invalid chain"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } } else if (b.prev_id != previous) @@ -1182,7 +1184,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("Sent invalid chain"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } previous = block_hash; @@ -1191,7 +1193,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT("Sent invalid chain"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } auto req_it = context.m_requested_objects.find(block_hash); @@ -1201,7 +1203,7 @@ namespace cryptonote << " wasn't requested, dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } if(b.tx_hashes.size() != arg.blocks[i].txs.size()) { @@ -1209,7 +1211,7 @@ namespace cryptonote << ", tx_hashes.size()=" << b.tx_hashes.size() << " mismatch with block_complete_entry.m_txs.size()=" << arg.blocks[i].txs.size() << ", dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } context.m_requested_objects.erase(req_it); @@ -1222,7 +1224,7 @@ namespace cryptonote << context.m_requested_objects.size() << "), dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } const bool pruned_ok = should_ask_for_pruned_data(context, start_height, arg.blocks.size(), true); @@ -1236,14 +1238,14 @@ namespace cryptonote MERROR(context << "returned a pruned block, dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } if (block_entry.block_weight) { MERROR(context << "returned a block weight for a non pruned block, dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } for (const tx_blob_entry &tx_entry: block_entry.txs) { @@ -1252,7 +1254,7 @@ namespace cryptonote MERROR(context << "returned at least one pruned object which we did not expect, dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } } } @@ -1267,7 +1269,7 @@ namespace cryptonote MERROR(context << "returned at least one pruned block with 0 weight, dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; - return 1; + return LEVIN_ERROR_CONNECTION; } } } @@ -1795,7 +1797,7 @@ skip: { LOG_ERROR_CCONTEXT("Requested chain before handshake, dropping connection"); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } NOTIFY_RESPONSE_CHAIN_ENTRY::request r; if(!m_core.find_blockchain_supplement(arg.block_ids, !arg.prune, r)) @@ -2498,14 +2500,14 @@ skip: { LOG_ERROR_CCONTEXT("Got NOTIFY_RESPONSE_CHAIN_ENTRY out of the blue, dropping connection"); drop_connection(context, true, false); - return 1; + return LEVIN_ERROR_CONNECTION; } context.m_expect_response = 0; if (arg.start_height + 1 > context.m_expect_height) // we expect an overlapping block { LOG_ERROR_CCONTEXT("Got NOTIFY_RESPONSE_CHAIN_ENTRY past expected height, dropping connection"); drop_connection(context, true, false); - return 1; + return LEVIN_ERROR_CONNECTION; } context.m_last_request_time = boost::date_time::not_a_date_time; @@ -2516,19 +2518,19 @@ skip: { LOG_ERROR_CCONTEXT("sent empty m_block_ids, dropping connection"); drop_connection(context, true, false); - return 1; + return LEVIN_ERROR_CONNECTION; } 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; + return LEVIN_ERROR_CONNECTION; } if (!arg.m_block_weights.empty() && arg.m_block_weights.size() != arg.m_block_ids.size()) { LOG_ERROR_CCONTEXT("sent invalid block weight array, dropping connection"); drop_connection(context, true, false); - return 1; + return LEVIN_ERROR_CONNECTION; } MDEBUG(context << "first block hash " << arg.m_block_ids.front() << ", last " << arg.m_block_ids.back()); @@ -2536,12 +2538,14 @@ skip: { 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; + return LEVIN_ERROR_CONNECTION; } if (arg.total_height < context.m_remote_blockchain_height) { MINFO(context << "Claims " << arg.total_height << ", claimed " << context.m_remote_blockchain_height << " before"); hit_score(context, 1); + if (context.m_score <= DROP_PEERS_ON_SCORE) + return LEVIN_ERROR_CONNECTION; } context.m_remote_blockchain_height = arg.total_height; context.m_last_response_height = arg.start_height + arg.m_block_ids.size()-1; @@ -2551,7 +2555,7 @@ skip: << ", m_start_height=" << arg.start_height << ", m_block_ids.size()=" << arg.m_block_ids.size()); drop_connection(context, false, false); - return 1; + return LEVIN_ERROR_CONNECTION; } uint64_t n_use_blocks = m_core.prevalidate_block_hashes(arg.start_height, arg.m_block_ids, arg.m_block_weights); @@ -2559,7 +2563,7 @@ skip: { LOG_ERROR_CCONTEXT("Most blocks are invalid, dropping connection"); drop_connection(context, true, false); - return 1; + return LEVIN_ERROR_CONNECTION; } context.m_expected_heights_start = arg.start_height; @@ -2577,7 +2581,7 @@ skip: { LOG_ERROR_CCONTEXT("Duplicate blocks in chain entry response, dropping connection"); drop_connection_with_score(context, 5, false); - return 1; + return LEVIN_ERROR_CONNECTION; } int where; const bool have_block = m_core.have_block_unlocked(arg.m_block_ids[i], &where); @@ -2588,7 +2592,7 @@ skip: { LOG_ERROR_CCONTEXT("First block hash is unknown, dropping connection"); drop_connection_with_score(context, 5, false); - return 1; + return LEVIN_ERROR_CONNECTION; } if (!have_block) expect_unknown = true; @@ -2605,19 +2609,19 @@ skip: case HAVE_BLOCK_INVALID: LOG_ERROR_CCONTEXT("Block is invalid or known without known type, dropping connection"); drop_connection(context, true, false); - return 1; + return LEVIN_ERROR_CONNECTION; case HAVE_BLOCK_MAIN_CHAIN: if (expect_unknown) { LOG_ERROR_CCONTEXT("Block is on the main chain, but we did not expect a known block, dropping connection"); drop_connection_with_score(context, 5, false); - return 1; + return LEVIN_ERROR_CONNECTION; } if (m_core.get_block_id_by_height(arg.start_height + i) != arg.m_block_ids[i]) { LOG_ERROR_CCONTEXT("Block is on the main chain, but not at the expected height, dropping connection"); drop_connection_with_score(context, 5, false); - return 1; + return LEVIN_ERROR_CONNECTION; } break; case HAVE_BLOCK_ALT_CHAIN: @@ -2625,7 +2629,7 @@ skip: { LOG_ERROR_CCONTEXT("Block is on the main chain, but we did not expect a known block, dropping connection"); drop_connection_with_score(context, 5, false); - return 1; + return LEVIN_ERROR_CONNECTION; } break; } diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index b32f79bef..36759c32a 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -308,7 +308,7 @@ namespace nodetool BEGIN_INVOKE_MAP2(node_server) if (is_filtered_command(context.m_remote_address, command)) - return LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED; + return is_notify ? LEVIN_OK : LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED; HANDLE_INVOKE_T2(COMMAND_HANDSHAKE, &node_server::handle_handshake) HANDLE_INVOKE_T2(COMMAND_TIMED_SYNC, &node_server::handle_timed_sync)