mirror of
https://github.com/dashpay/dash.git
synced 2024-12-27 04:52:59 +01:00
e42412924f
5b57dc5458800e56b4dddfeb32a1813804a62b0f RPC: getpeerinfo: Wrap long help line for bytesrecv_per_msg (Luke Dashjr) d681a28219d3876a2b6e3cd2fb0d92963674903e RPC: getpeerinfo: Deprecate "whitelisted" field (replaced by "permissions") (Luke Dashjr) Pull request description: If we were going to continue support for "whitelisted", we should have probably made it true if any permission flag was set, rather than only if "default permissions" were used. This corrects the description, and deprecates it. ACKs for top commit: laanwj: ACK 5b57dc5458800e56b4dddfeb32a1813804a62b0f Tree-SHA512: a2e2137f8be8110357c1b2fef2c923fa8c7c4a49b0b2b3a2d78aedf12f8ed5cc7e140018a21b37e6ec7770ed4007542aeef7ad4558973901b107e8e0f81d6003
116 lines
5.6 KiB
Python
Executable File
116 lines
5.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright (c) 2019-2020 The Bitcoin Core developers
|
|
# Distributed under the MIT software license, see the accompanying
|
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
"""Test p2p blocksonly mode & block-relay-only connections."""
|
|
|
|
import time
|
|
|
|
from test_framework.blocktools import create_transaction
|
|
from test_framework.messages import msg_tx
|
|
from test_framework.p2p import P2PInterface, P2PTxInvStore
|
|
from test_framework.test_framework import BitcoinTestFramework
|
|
from test_framework.util import assert_equal
|
|
|
|
|
|
class P2PBlocksOnly(BitcoinTestFramework):
|
|
def set_test_params(self):
|
|
self.num_nodes = 1
|
|
self.extra_args = [["-blocksonly"]]
|
|
|
|
def skip_test_if_missing_module(self):
|
|
self.skip_if_no_wallet()
|
|
|
|
def run_test(self):
|
|
self.blocksonly_mode_tests()
|
|
self.blocks_relay_conn_tests()
|
|
|
|
def blocksonly_mode_tests(self):
|
|
self.log.info("Tests with node running in -blocksonly mode")
|
|
assert_equal(self.nodes[0].getnetworkinfo()['localrelay'], False)
|
|
|
|
self.nodes[0].add_p2p_connection(P2PInterface())
|
|
tx, txid, tx_hex = self.check_p2p_tx_violation()
|
|
|
|
self.log.info('Check that txs from rpc are not rejected and relayed to other peers')
|
|
tx_relay_peer = self.nodes[0].add_p2p_connection(P2PInterface())
|
|
assert_equal(self.nodes[0].getpeerinfo()[0]['relaytxes'], True)
|
|
assert_equal(self.nodes[0].testmempoolaccept([tx_hex])[0]['allowed'], True)
|
|
with self.nodes[0].assert_debug_log(['received getdata for: tx {} peer=1'.format(txid)]):
|
|
self.nodes[0].sendrawtransaction(tx_hex)
|
|
self.bump_mocktime(60)
|
|
tx_relay_peer.wait_for_tx(txid)
|
|
assert_equal(self.nodes[0].getmempoolinfo()['size'], 1)
|
|
|
|
self.log.info("Restarting node 0 with relay permission and blocksonly")
|
|
self.restart_node(0, ["-persistmempool=0", "-whitelist=relay@127.0.0.1", "-blocksonly", '-deprecatedrpc=whitelisted'])
|
|
assert_equal(self.nodes[0].getrawmempool(), [])
|
|
first_peer = self.nodes[0].add_p2p_connection(P2PInterface())
|
|
second_peer = self.nodes[0].add_p2p_connection(P2PInterface())
|
|
peer_1_info = self.nodes[0].getpeerinfo()[0]
|
|
assert_equal(peer_1_info['permissions'], ['relay'])
|
|
peer_2_info = self.nodes[0].getpeerinfo()[1]
|
|
assert_equal(peer_2_info['permissions'], ['relay'])
|
|
assert_equal(self.nodes[0].testmempoolaccept([tx_hex])[0]['allowed'], True)
|
|
|
|
self.log.info('Check that the tx from first_peer with relay-permission is relayed to others (ie.second_peer)')
|
|
with self.nodes[0].assert_debug_log(["received getdata"]):
|
|
# Note that normally, first_peer would never send us transactions since we're a blocksonly node.
|
|
# By activating blocksonly, we explicitly tell our peers that they should not send us transactions,
|
|
# and Bitcoin Core respects that choice and will not send transactions.
|
|
# But if, for some reason, first_peer decides to relay transactions to us anyway, we should relay them to
|
|
# second_peer since we gave relay permission to first_peer.
|
|
# See https://github.com/bitcoin/bitcoin/issues/19943 for details.
|
|
first_peer.send_message(msg_tx(tx))
|
|
self.log.info('Check that the peer with relay-permission is still connected after sending the transaction')
|
|
assert_equal(first_peer.is_connected, True)
|
|
self.bump_mocktime(60)
|
|
second_peer.wait_for_tx(txid)
|
|
assert_equal(self.nodes[0].getmempoolinfo()['size'], 1)
|
|
self.log.info("Relay-permission peer's transaction is accepted and relayed")
|
|
|
|
self.nodes[0].disconnect_p2ps()
|
|
self.nodes[0].generate(1)
|
|
|
|
def blocks_relay_conn_tests(self):
|
|
self.log.info('Tests with node in normal mode with block-relay-only connections')
|
|
self.restart_node(0, ["-noblocksonly"]) # disables blocks only mode
|
|
assert_equal(self.nodes[0].getnetworkinfo()['localrelay'], True)
|
|
|
|
# Ensure we disconnect if a block-relay-only connection sends us a transaction
|
|
self.nodes[0].add_outbound_p2p_connection(P2PInterface(), p2p_idx=0, connection_type="block-relay-only")
|
|
assert_equal(self.nodes[0].getpeerinfo()[0]['relaytxes'], False)
|
|
_, txid, tx_hex = self.check_p2p_tx_violation(index=2)
|
|
|
|
self.log.info("Check that txs from RPC are not sent to blockrelay connection")
|
|
conn = self.nodes[0].add_outbound_p2p_connection(P2PTxInvStore(), p2p_idx=1, connection_type="block-relay-only")
|
|
|
|
self.nodes[0].sendrawtransaction(tx_hex)
|
|
|
|
# Bump time forward to ensure m_next_inv_send_time timer pops
|
|
self.nodes[0].setmocktime(int(time.time()) + 60)
|
|
|
|
conn.sync_send_with_ping()
|
|
assert(int(txid, 16) not in conn.get_invs())
|
|
|
|
def check_p2p_tx_violation(self, index=1):
|
|
self.log.info('Check that txs from P2P are rejected and result in disconnect')
|
|
input_txid = self.nodes[0].getblock(self.nodes[0].getblockhash(index), 2)['tx'][0]['txid']
|
|
tx = create_transaction(self.nodes[0], input_txid, self.nodes[0].getnewaddress(), amount=(500 - 0.001))
|
|
txid = tx.rehash()
|
|
tx_hex = tx.serialize().hex()
|
|
|
|
with self.nodes[0].assert_debug_log(['tx sent in violation of protocol peer=0']):
|
|
self.nodes[0].p2ps[0].send_message(msg_tx(tx))
|
|
self.nodes[0].p2ps[0].wait_for_disconnect()
|
|
assert_equal(self.nodes[0].getmempoolinfo()['size'], 0)
|
|
|
|
# Remove the disconnected peer
|
|
del self.nodes[0].p2ps[0]
|
|
|
|
return tx, txid, tx_hex
|
|
|
|
|
|
if __name__ == '__main__':
|
|
P2PBlocksOnly().main()
|