diff --git a/src/net_processing.cpp b/src/net_processing.cpp
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -4523,8 +4523,26 @@
         if (state.GetResult() == avalanche::ProofRegistrationResult::INVALID) {
             WITH_LOCK(cs_rejectedProofs, rejectedProofs->insert(proofid));
             Misbehaving(nodeid, 100, state.GetRejectReason());
+            return;
+        }
+
+        if (!gArgs.GetBoolArg("-enableavalancheproofreplacement",
+                              AVALANCHE_DEFAULT_PROOF_REPLACEMENT_ENABLED)) {
+            // If proof replacement is not enabled there is no point dealing
+            // with proof polling, so we're done.
+            return;
+        }
+
+        if (state.IsValid() ||
+            state.GetResult() ==
+                avalanche::ProofRegistrationResult::CONFLICTING) {
+            g_avalanche->addProofToReconcile(proof);
+            return;
         }
 
+        LogPrint(BCLog::AVALANCHE,
+                 "Not polling the avalanche proof (%s): peer=%d, proofid %s\n",
+                 state.GetRejectReason(), nodeid, proofid.ToString());
         return;
     }
 
diff --git a/test/functional/abc_p2p_avalanche_proof_voting.py b/test/functional/abc_p2p_avalanche_proof_voting.py
new file mode 100755
--- /dev/null
+++ b/test/functional/abc_p2p_avalanche_proof_voting.py
@@ -0,0 +1,178 @@
+#!/usr/bin/env python3
+# Copyright (c) 2021 The Bitcoin developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test the resolution of conflicting proofs via avalanche."""
+import time
+
+from test_framework.avatools import (
+    create_coinbase_stakes,
+    get_ava_p2p_interface,
+)
+from test_framework.key import ECKey, ECPubKey
+from test_framework.messages import (
+    AvalancheVote,
+    AvalancheVoteError,
+    FromHex,
+    LegacyAvalancheProof,
+)
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.wallet_util import bytes_to_wif
+
+QUORUM_NODE_COUNT = 16
+
+
+class AvalancheProofVotingTest(BitcoinTestFramework):
+    def set_test_params(self):
+        self.setup_clean_chain = True
+        self.num_nodes = 1
+        self.conflicting_proof_cooldown = 100
+        self.extra_args = [
+            ['-enableavalanche=1', '-enableavalancheproofreplacement=1',
+                f'-avalancheconflictingproofcooldown={self.conflicting_proof_cooldown}', '-avacooldown=0'],
+        ]
+        self.supports_cli = False
+
+    def run_test(self):
+        node = self.nodes[0]
+
+        # Build a fake quorum of nodes.
+        def get_quorum():
+            return [get_ava_p2p_interface(node)
+                    for _ in range(0, QUORUM_NODE_COUNT)]
+
+        # Pick on node from the quorum for polling.
+        quorum = get_quorum()
+
+        privkey = ECKey()
+        privkey.set(bytes.fromhex(
+            "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"), True)
+        proof_master = privkey.get_pubkey().get_bytes().hex()
+
+        addrkey0 = node.get_deterministic_priv_key()
+        blockhash = node.generatetoaddress(10, addrkey0.address)
+        stakes = create_coinbase_stakes(node, blockhash[:5], addrkey0.key)
+
+        quorum_proof = node.buildavalancheproof(
+            42, 0, bytes_to_wif(privkey.get_bytes()), stakes)
+        for n in quorum:
+            success = node.addavalanchenode(
+                n.nodeid, proof_master, quorum_proof)
+            assert success is True
+
+        conflicting_stakes = create_coinbase_stakes(
+            node, blockhash[5:], addrkey0.key)
+
+        def build_conflicting_proof(sequence):
+            return node.buildavalancheproof(sequence, 0, bytes_to_wif(
+                privkey.get_bytes()), conflicting_stakes)
+
+        proof_seq10 = build_conflicting_proof(10)
+        proof_seq20 = build_conflicting_proof(20)
+        proof_seq30 = build_conflicting_proof(30)
+        proof_seq40 = build_conflicting_proof(40)
+
+        orphan = node.buildavalancheproof(
+            100, 2000000000, bytes_to_wif(privkey.get_bytes()), [{
+                'txid': '0' * 64,
+                'vout': 0,
+                'amount': 10e6,
+                'height': 42,
+                'iscoinbase': False,
+                'privatekey': bytes_to_wif(privkey.get_bytes()),
+            }]
+        )
+
+        no_stake = node.buildavalancheproof(
+            200, 2000000000, bytes_to_wif(privkey.get_bytes()), []
+        )
+
+        # Get the key so we can verify signatures.
+        avakey = ECPubKey()
+        avakey.set(bytes.fromhex(node.getavalanchekey()))
+
+        self.log.info("Trigger polling from the node...")
+
+        def can_find_proof_in_poll(hash, response):
+            found_hash = False
+            for n in quorum:
+                poll = n.get_avapoll_if_available()
+
+                # That node has not received a poll
+                if poll is None:
+                    continue
+
+                # We got a poll, check for the hash and repond
+                votes = []
+                for inv in poll.invs:
+                    # Vote yes to everything
+                    r = AvalancheVoteError.ACCEPTED
+
+                    # Look for what we expect
+                    if inv.hash == hash:
+                        r = response
+                        found_hash = True
+
+                    votes.append(AvalancheVote(r, inv.hash))
+
+                n.send_avaresponse(poll.round, votes, privkey)
+
+            return found_hash
+
+        peer = get_ava_p2p_interface(node)
+
+        mock_time = int(time.time())
+        node.setmocktime(mock_time)
+
+        def send_and_check_for_polling(
+                proof_hex, response=AvalancheVoteError.ACCEPTED):
+            proof = FromHex(LegacyAvalancheProof(), proof_hex)
+            peer.send_avaproof(proof)
+            self.wait_until(
+                lambda: can_find_proof_in_poll(
+                    proof.proofid, response))
+
+        self.log.info("Check we poll for valid proof")
+        send_and_check_for_polling(proof_seq30)
+
+        self.log.info(
+            "Check we don't poll for subsequent proofs if the cooldown is not elapsed, proof not the favorite")
+        with node.assert_debug_log(["Not polling the avalanche proof (cooldown-not-elapsed)"]):
+            peer.send_avaproof(FromHex(LegacyAvalancheProof(), proof_seq20))
+
+        self.log.info(
+            "Check we don't poll for subsequent proofs if the cooldown is not elapsed, proof is the favorite")
+        with node.assert_debug_log(["Not polling the avalanche proof (cooldown-not-elapsed)"]):
+            peer.send_avaproof(FromHex(LegacyAvalancheProof(), proof_seq40))
+
+        self.log.info(
+            "Check we poll for conflicting proof if the proof is not the favorite")
+        mock_time += self.conflicting_proof_cooldown
+        node.setmocktime(mock_time)
+        send_and_check_for_polling(proof_seq20)
+
+        self.log.info(
+            "Check we poll for conflicting proof if the proof is the favorite")
+        mock_time += self.conflicting_proof_cooldown
+        node.setmocktime(mock_time)
+        send_and_check_for_polling(proof_seq40)
+
+        mock_time += self.conflicting_proof_cooldown
+        node.setmocktime(mock_time)
+
+        self.log.info("Check we don't poll for orphans")
+        with node.assert_debug_log(["Not polling the avalanche proof (orphan-proof)"]):
+            peer.send_avaproof(FromHex(LegacyAvalancheProof(), orphan))
+
+        self.log.info("Check we don't poll for proofs that get evicted")
+        with node.assert_debug_log(["Not polling the avalanche proof (evicted-proof)"]):
+            peer.send_avaproof(FromHex(LegacyAvalancheProof(), proof_seq10))
+
+        self.log.info("Check we don't poll for invalid proofs and get banned")
+        with node.assert_debug_log(["Misbehaving", "invalid-proof"]):
+            peer.send_avaproof(FromHex(LegacyAvalancheProof(), no_stake))
+        peer.wait_for_disconnect()
+
+
+if __name__ == '__main__':
+    AvalancheProofVotingTest().main()
diff --git a/test/functional/test_framework/avatools.py b/test/functional/test_framework/avatools.py
--- a/test/functional/test_framework/avatools.py
+++ b/test/functional/test_framework/avatools.py
@@ -14,6 +14,7 @@
     NODE_AVALANCHE,
     NODE_NETWORK,
     AvalancheDelegation,
+    AvalancheProof,
     AvalancheResponse,
     CInv,
     CTransaction,
@@ -24,6 +25,7 @@
     hash256,
     msg_avahello,
     msg_avapoll,
+    msg_avaproof,
     msg_tcpavaresponse,
 )
 from .p2p import P2PInterface, p2p_lock
@@ -242,6 +244,11 @@
 
         return delegation.proofid
 
+    def send_avaproof(self, proof: AvalancheProof):
+        msg = msg_avaproof()
+        msg.proof = proof
+        self.send_message(msg)
+
 
 def get_ava_p2p_interface(
         node: TestNode,