diff --git a/src/net_processing.h b/src/net_processing.h
--- a/src/net_processing.h
+++ b/src/net_processing.h
@@ -234,6 +234,7 @@
     //! Next time to check for stale tip
     int64_t m_stale_tip_check_time;
     uint32_t getAvalancheVoteForBlock(const BlockHash &hash);
+    uint32_t getAvalancheVoteForAvalancheProof(const avalanche::ProofId &id);
 };
 
 struct CNodeStateStats {
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -4354,6 +4354,10 @@
                 case MSG_BLOCK: {
                     vote = getAvalancheVoteForBlock(BlockHash(inv.hash));
                 } break;
+                case MSG_AVA_PROOF: {
+                    vote = getAvalancheVoteForAvalancheProof(
+                        avalanche::ProofId(inv.hash));
+                } break;
             }
 
             votes.emplace_back(vote, inv.hash);
@@ -5184,6 +5188,26 @@
     return -3;
 };
 
+uint32_t
+PeerManager::getAvalancheVoteForAvalancheProof(const avalanche::ProofId &id) {
+    assert(g_avalanche);
+
+    // Rejected proof
+    if (WITH_LOCK(cs_rejectedProofs, return rejectedProofs->contains(id))) {
+        return 1;
+    }
+
+    // Unknown proof
+    if (g_avalanche->withPeerManager(
+            [&id](avalanche::PeerManager &pm) { return !pm.exists(id); })) {
+        return -1;
+    }
+
+    // The proof is known, valid, not orphaned, and our currently active proof
+    // for the peer it belongs to
+    return 0;
+};
+
 namespace {
 class CompareInvMempoolOrder {
     CTxMemPool *mp;
diff --git a/test/functional/abc_p2p_avalanche_voting_proofs.py b/test/functional/abc_p2p_avalanche_voting_proofs.py
new file mode 100755
--- /dev/null
+++ b/test/functional/abc_p2p_avalanche_voting_proofs.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020-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 polling of Avalanche stake proofs."""
+
+from test_framework.avatools import (
+    create_coinbase_stakes,
+    get_ava_p2p_interface,
+)
+from test_framework.key import ECKey, ECPubKey
+from test_framework.messages import (
+    MSG_AVA_PROOF,
+    AvalancheVote,
+    AvalancheVoteError,
+    FromHex,
+    LegacyAvalancheProof,
+)
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_equal
+from test_framework.wallet_util import bytes_to_wif
+
+QUORUM_NODE_COUNT = 16
+
+PROOF_0 = {
+    "sequence": 11,
+    "expiration": 12,
+    "priv_key": "12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747",
+}
+
+
+class AvalancheTest(BitcoinTestFramework):
+    def set_test_params(self):
+        self.setup_clean_chain = True
+        self.num_nodes = 2
+        self.extra_args = [
+            ['-enableavalanche=1', '-avacooldown=0'],
+            ['-enableavalanche=1', '-avacooldown=0', '-noparkdeepreorg', '-maxreorgdepth=-1']]
+        self.supports_cli = False
+
+    def run_test(self):
+        node = self.nodes[0]
+        poll_node = get_ava_p2p_interface(node)
+
+        # Generate a coinbases to use for stakes
+        addrkey_0 = node.get_deterministic_priv_key()
+        blockhashes = node.generatetoaddress(1, addrkey_0.address)
+        stakes_0 = create_coinbase_stakes(
+            node, [blockhashes[0]], addrkey_0.key)
+
+        # Get the key so we can verify signatures.
+        avakey = ECPubKey()
+        avakey.set(bytes.fromhex(node.getavalanchekey()))
+
+        privkey = ECKey()
+        privkey.set(bytes.fromhex(PROOF_0["priv_key"]), True)
+        masterkey = bytes_to_wif(privkey.get_bytes())
+
+        # Build a proof
+        proof_0 = node.buildavalancheproof(
+            PROOF_0["sequence"],
+            PROOF_0["expiration"],
+            masterkey,
+            stakes_0)
+
+        proof_0_obj = FromHex(LegacyAvalancheProof(), proof_0)
+        proof_0_id = proof_0_obj.proofid
+        unknown_proof_id = 100
+
+        # Create a helper to issue a poll and validate the responses
+        def poll_assert_response(expected):
+            self.log.info("Trigger polling from the node...")
+            poll_node.send_poll([proof_0_id, unknown_proof_id], MSG_AVA_PROOF)
+            response = poll_node.wait_for_avaresponse()
+            r = response.response
+
+            # Verify signature.
+            assert avakey.verify_schnorr(response.sig, r.get_hash())
+
+            votes = r.votes
+            assert_equal(len(votes), len(expected))
+            for i in range(0, len(votes)):
+                assert_equal(repr(votes[i]), repr(expected[i]))
+
+        # Check that all proofs are still unknown
+        poll_assert_response([AvalancheVote(AvalancheVoteError.UNKNOWN, proof_0_id),
+                              AvalancheVote(AvalancheVoteError.UNKNOWN, unknown_proof_id)])
+
+        # Send the proof to the poll node
+        assert node.sendavalancheproof(proof_0)
+
+        # Nodes should now respond that the proof is accepted
+        poll_assert_response([AvalancheVote(AvalancheVoteError.ACCEPTED, proof_0_id),
+                              AvalancheVote(AvalancheVoteError.UNKNOWN, unknown_proof_id)])
+
+
+if __name__ == '__main__':
+    AvalancheTest().main()