Changeset View
Changeset View
Standalone View
Standalone View
test/functional/test_framework/mininode.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2010 ArtForz -- public domain half-a-node | # Copyright (c) 2010 ArtForz -- public domain half-a-node | ||||
# Copyright (c) 2012 Jeff Garzik | # Copyright (c) 2012 Jeff Garzik | ||||
# Copyright (c) 2010-2019 The Bitcoin Core developers | # Copyright (c) 2010-2019 The Bitcoin Core developers | ||||
# Distributed under the MIT software license, see the accompanying | # Distributed under the MIT software license, see the accompanying | ||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
"""Bitcoin P2P network half-a-node. | """Bitcoin P2P network half-a-node. | ||||
This python code was modified from ArtForz' public domain half-a-node, as | This python code was modified from ArtForz' public domain half-a-node, as | ||||
found in the mini-node branch of http://github.com/jgarzik/pynode. | found in the mini-node branch of http://github.com/jgarzik/pynode. | ||||
P2PConnection: A low-level connection object to a node's P2P interface | P2PConnection: A low-level connection object to a node's P2P interface | ||||
P2PInterface: A high-level interface object for communicating to a node over P2P | P2PInterface: A high-level interface object for communicating to a node over P2P | ||||
P2PDataStore: A p2p interface class that keeps a store of transactions and blocks | P2PDataStore: A p2p interface class that keeps a store of transactions and blocks | ||||
and can respond correctly to getdata and getheaders messages""" | and can respond correctly to getdata and getheaders messages | ||||
P2PTxInvStore: A p2p interface class that inherits from P2PDataStore, and keeps | |||||
a count of how many times each txid has been announced.""" | |||||
import asyncio | import asyncio | ||||
from collections import defaultdict | from collections import defaultdict | ||||
from io import BytesIO | from io import BytesIO | ||||
import logging | import logging | ||||
import struct | import struct | ||||
import sys | import sys | ||||
import threading | import threading | ||||
▲ Show 20 Lines • Show All 707 Lines • ▼ Show 20 Lines | def send_txs_and_test(self, txs, node, *, success=True, | ||||
assert tx.hash not in raw_mempool, "{} tx found in mempool".format( | assert tx.hash not in raw_mempool, "{} tx found in mempool".format( | ||||
tx.hash) | tx.hash) | ||||
if reject_reason: | if reject_reason: | ||||
with node.assert_debug_log(expected_msgs=[reject_reason]): | with node.assert_debug_log(expected_msgs=[reject_reason]): | ||||
test() | test() | ||||
else: | else: | ||||
test() | test() | ||||
class P2PTxInvStore(P2PInterface): | |||||
"""A P2PInterface which stores a count of how many times each txid has been announced.""" | |||||
def __init__(self): | |||||
super().__init__() | |||||
self.tx_invs_received = defaultdict(int) | |||||
def on_inv(self, message): | |||||
# Store how many times invs have been received for each tx. | |||||
for i in message.inv: | |||||
if i.type == MSG_TX: | |||||
# save txid | |||||
self.tx_invs_received[i.hash] += 1 | |||||
def get_invs(self): | |||||
with mininode_lock: | |||||
return list(self.tx_invs_received.keys()) |