diff --git a/src/llmq/net_quorum.cpp b/src/llmq/net_quorum.cpp index 97015bad6252..c5a1c3320886 100644 --- a/src/llmq/net_quorum.cpp +++ b/src/llmq/net_quorum.cpp @@ -108,9 +108,11 @@ void NetQuorum::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDataS const bool request_limit_exceeded = !m_qman.RegisterDataRequest(key, request, /*add_expiry_bias=*/false); if (!Params().GetLLMQ(request.GetLLMQType()).has_value()) { - if (sendQDATA(CQuorumDataRequest::Errors::QUORUM_TYPE_INVALID, request_limit_exceeded)) { - m_peer_manager->PeerMisbehaving(pfrom.GetId(), 25, "request limit exceeded"); - } + // Unlike the misses below, this one cannot be explained by the peer being ahead of + // us: no quorum of an unregistered type can exist on this chain, so there is + // nothing to ask about. Answer with the error anyway, then score in full. + sendQDATA(CQuorumDataRequest::Errors::QUORUM_TYPE_INVALID, request_limit_exceeded); + m_peer_manager->PeerMisbehaving(pfrom.GetId(), 100, "invalid llmqType in QGETDATA"); return; } diff --git a/test/functional/p2p_quorum_data.py b/test/functional/p2p_quorum_data.py index ec649154ac2a..baa65f98267a 100755 --- a/test/functional/p2p_quorum_data.py +++ b/test/functional/p2p_quorum_data.py @@ -326,10 +326,14 @@ def send_bad_qdata_expect_disconnect(bad_qdata): qgetdata_invalid_block = msg_qgetdata(protx_hash_int, 100, 0x01, protx_hash_int) qgetdata_invalid_quorum = msg_qgetdata(int(mn2.get_node(self).getblockhash(0), 16), 100, 0x01, protx_hash_int) qgetdata_invalid_no_member = msg_qgetdata(quorum_hash_int, 100, 0x02, quorum_hash_int) - p2p_mn2.test_qgetdata(qgetdata_invalid_type, QUORUM_TYPE_INVALID) p2p_mn2.test_qgetdata(qgetdata_invalid_block, QUORUM_BLOCK_NOT_FOUND) p2p_mn2.test_qgetdata(qgetdata_invalid_quorum, QUORUM_NOT_FOUND) p2p_mn2.test_qgetdata(qgetdata_invalid_no_member, MASTERNODE_IS_NO_MEMBER) + # An unregistered LLMQ type is answered like the misses above, but unlike them it + # cannot be explained by the peer being ahead of us, so it is scored in full too. + # Kept last: the peer is dropped once it is. + p2p_mn2.test_qgetdata(qgetdata_invalid_type, QUORUM_TYPE_INVALID) + self.wait_until(lambda: not p2p_mn2.is_connected, timeout=10) # The last two error case require the node to miss its DKG data so we just reindex the node. mn2.get_node(self).disconnect_p2ps() self.restart_mn(mn1, reindex=True)