Example #1
0
def test_correct_ping(tmp_path):
    node1 = Node(config=Config(
        chain="regtest",
        data_dir=tmp_path / "node1",
        p2p_port=get_random_port(),
        allow_rpc=False,
    ))
    node2 = Node(config=Config(
        chain="regtest",
        data_dir=tmp_path / "node2",
        p2p_port=get_random_port(),
        allow_rpc=False,
    ))
    node1.start()
    node2.start()

    wait_until(lambda: node1.p2p_manager.is_alive())
    wait_until(lambda: node2.p2p_manager.is_alive())

    node2.p2p_manager.connect(("0.0.0.0", node1.p2p_port))
    wait_until(lambda: len(node1.p2p_manager.connections))
    connection = node1.p2p_manager.connections[0]
    wait_until(lambda: connection.status == P2pConnStatus.Connected)
    connection = node2.p2p_manager.connections[0]
    wait_until(lambda: connection.status == P2pConnStatus.Connected)

    node1.p2p_manager.connections[0].ping_sent = time.time()
    node1.p2p_manager.connections[0].ping_nonce = 1
    node1.p2p_manager.send(Ping(1), 0)

    wait_until(lambda: node1.p2p_manager.connections[0].latency)

    node1.stop()
    node2.stop()
Example #2
0
def test_chain_selection():
    assert Config(chain="mainnet") == Config(chain=Main())
    assert Config(chain="testnet") == Config(chain=TestNet())
    assert Config(chain="signet") == Config(chain=SigNet())
    assert Config(chain="regtest") == Config(chain=RegTest())
    with pytest.raises(ValueError):
        Config(chain=None)
    with pytest.raises(ValueError):
        Config(chain="wrongchain")
Example #3
0
def test_init(tmp_path):
    node = Node(
        config=Config(
            chain="regtest", data_dir=tmp_path, allow_p2p=False, allow_rpc=True
        )
    )
    node.start()

    wait_until(lambda: node.rpc_manager.is_alive())

    response = json.loads(
        requests.post(
            url=f"http://127.0.0.1:{node.rpc_port}",
            data=json.dumps(
                {
                    "jsonrpc": "1.0",
                    "id": "pytest",
                    "method": "stop",
                }
            ).encode(),
            headers={"Content-Type": "text/plain"},
        ).text
    )

    assert response["result"] == "Btclib node stopping"

    node.stop()
Example #4
0
def test_no_method(tmp_path):
    node = Node(config=Config(
        chain="regtest",
        data_dir=tmp_path,
        allow_p2p=False,
        rpc_port=get_random_port(),
    ))
    node.start()

    wait_until(lambda: node.rpc_manager.is_alive())

    response = json.loads(
        requests.post(
            url=f"http://127.0.0.1:{node.rpc_port}",
            data=json.dumps({
                "jsonrpc": "1.0",
                "id": "pytest",
            }).encode(),
            headers={
                "Content-Type": "text/plain"
            },
        ).text)

    assert response["error"]["message"] == "Invalid request"

    node.stop()
Example #5
0
def test_block_header_last(tmp_path):
    node = Node(config=Config(
        chain="regtest",
        data_dir=tmp_path,
        allow_p2p=False,
        rpc_port=get_random_port(),
    ))
    node.start()

    wait_until(lambda: node.rpc_manager.is_alive())

    chain = generate_random_header_chain(2000, RegTest().genesis.hash)
    node.index.add_headers(chain)

    response = json.loads(
        requests.post(
            url=f"http://127.0.0.1:{node.rpc_port}",
            data=json.dumps({
                "jsonrpc": "1.0",
                "id": "pytest",
                "method": "getblockheader",
                "params": [chain[-1].hash],
            }).encode(),
            headers={
                "Content-Type": "text/plain"
            },
        ).text)

    assert response["result"]["hash"] == chain[-1].hash
    assert response["result"]["height"] == 2000
    assert response["result"]["previousblockhash"] == chain[-2].hash
    assert "nextblockhash" not in response["result"]

    node.stop()
Example #6
0
    def __init__(self, config=Config()):
        super().__init__()

        self.chain = config.chain
        self.data_dir = config.data_dir
        self.data_dir.mkdir(exist_ok=True, parents=True)

        self.terminate_flag = threading.Event()
        self.logger = Logger(self.data_dir / "history.log", config.debug)

        self.index = BlockIndex(self.data_dir, self.chain, self.logger)
        self.chainstate = Chainstate(self.data_dir, self.logger)
        self.block_db = BlockDB(self.data_dir, self.logger)
        self.mempool = Mempool()

        self.status = NodeStatus.Starting

        self.download_window = []

        if config.p2p_port:
            self.p2p_port = config.p2p_port
        else:
            self.p2p_port = None
        peer_db = PeerDB(self.chain, self.data_dir)
        self.p2p_manager = P2pManager(self, self.p2p_port, peer_db)

        if config.rpc_port:
            self.rpc_port = config.rpc_port
        else:
            self.rpc_port = None
        self.rpc_manager = RpcManager(self, self.rpc_port)
Example #7
0
def test_init(tmp_path):
    node = Node(config=Config(
        chain="regtest", data_dir=tmp_path, allow_p2p=True, allow_rpc=False))
    node.start()

    wait_until(lambda: node.p2p_manager.is_alive())

    node.stop()
Example #8
0
def test_get_connection_count(tmp_path):
    node1 = Node(config=Config(
        chain="regtest",
        data_dir=tmp_path / "node1",
        p2p_port=get_random_port(),
        rpc_port=get_random_port(),
    ))
    node2 = Node(config=Config(
        chain="regtest",
        data_dir=tmp_path / "node2",
        p2p_port=get_random_port(),
        rpc_port=get_random_port(),
    ))
    node1.start()
    node2.start()

    wait_until(lambda: node1.rpc_manager.is_alive())
    wait_until(lambda: node2.rpc_manager.is_alive())

    node2.p2p_manager.connect(("0.0.0.0", node1.p2p_port))
    wait_until(lambda: len(node1.p2p_manager.connections))
    connection = node1.p2p_manager.connections[0]
    wait_until(lambda: connection.status == P2pConnStatus.Connected)
    connection = node2.p2p_manager.connections[0]
    wait_until(lambda: connection.status == P2pConnStatus.Connected)

    response = json.loads(
        requests.post(
            url=f"http://127.0.0.1:{node1.rpc_port}",
            data=json.dumps({
                "jsonrpc": "1.0",
                "id": "pytest",
                "method": "getconnectioncount",
            }).encode(),
            headers={
                "Content-Type": "text/plain"
            },
        ).text)

    assert response["result"] == 1

    node1.stop()
    node2.stop()
Example #9
0
def test(tmp_path):
    node = Node(
        config=Config(
            chain="regtest", data_dir=tmp_path, allow_p2p=False, allow_rpc=False
        )
    )
    node.status = NodeStatus.HeaderSynced
    length = 2000 * 1  # 2000
    chain = generate_random_chain(length, RegTest().genesis.hash)
    headers = [block.header for block in chain]
    for x in range(0, length, 2000):
        node.index.add_headers(headers[x : x + 2000])
    for x in node.index.header_dict:
        block_info = node.index.get_block_info(x)
        block_info.downloaded = True
        node.index.insert_block_info(block_info)
    for block in chain:
        node.block_db.add_block(block)
    for x in range(len(chain)):
        update_chain(node)
    assert len(node.index.active_chain) == length + 1
Example #10
0
def test_port():
    assert Config(chain="regtest", p2p_port=1).p2p_port == 1
    assert Config(chain="regtest", p2p_port=1, allow_p2p=False).p2p_port != 1
    assert Config(chain="regtest", rpc_port=1).rpc_port == 1
    assert Config(chain="regtest", rpc_port=1, allow_rpc=False).rpc_port != 1
Example #11
0
def test_data_dir():
    config = Config(chain="regtest", data_dir="dir")
    assert config.data_dir != "dir"
Example #12
0
def test_download(tmp_path):

    length = 3000
    chain = generate_random_chain(length, RegTest().genesis.hash)
    headers = [block.header for block in chain]

    bootstrap_node = Node(config=Config(
        chain="regtest",
        data_dir=tmp_path / "node0",
        p2p_port=get_random_port(),
        allow_rpc=False,
    ))
    bootstrap_node.status = NodeStatus.HeaderSynced
    for x in range(0, length, 2000):
        bootstrap_node.index.add_headers(headers[x:x + 2000])
    for x in bootstrap_node.index.header_dict:
        block_info = bootstrap_node.index.get_block_info(x)
        block_info.downloaded = True
        bootstrap_node.index.insert_block_info(block_info)
    for block in chain:
        bootstrap_node.block_db.add_block(block)
    for x in range(len(chain)):
        update_chain(bootstrap_node)
    assert bootstrap_node.status == NodeStatus.BlockSynced
    bootstrap_node.start()

    download_nodes = [bootstrap_node]
    for x in range(1, 10):
        shutil.copytree(tmp_path / "node0", tmp_path / f"node{x}")
        node = Node(config=Config(
            chain="regtest",
            data_dir=tmp_path / f"node{x}",
            p2p_port=get_random_port(),
            allow_rpc=False,
        ))
        node.start()
        wait_until(lambda: node.p2p_manager.is_alive())
        download_nodes.append(node)

    main_node = Node(config=Config(
        chain="regtest",
        data_dir=tmp_path / "main",
        p2p_port=get_random_port(),
        allow_rpc=False,
    ))
    main_node.start()
    wait_until(lambda: main_node.p2p_manager.is_alive())

    for node in download_nodes:
        main_node.p2p_manager.connect(("0.0.0.0", node.p2p_port))
        time.sleep(0.25)

    wait_until(lambda: len(main_node.index.active_chain) == length + 1,
               timeout=20)
    wait_until(lambda: main_node.status == NodeStatus.BlockSynced, timeout=0.5)

    main_node.stop()
    main_node.join()
    for node in download_nodes:
        node.stop()
        node.join()
Example #13
0
from btclib_node import Node
from btclib_node.config import Config

node = Node(
    config=Config(
        chain="testnet", data_dir=".btclib", p2p_port=30000, rpc_port=30001, debug=True
    )
)
node.start()
Example #14
0
from btclib_node import Node
from btclib_node.config import Config

node = Node(config=Config(chain="mainnet",
                          data_dir=".btclib",
                          p2p_port=30000,
                          rpc_port=30001,
                          debug=True))
node.start()
Example #15
0
def test_init(tmp_path):
    node = Node(config=Config(
        chain="regtest", data_dir=tmp_path, allow_p2p=False, allow_rpc=False))
    node.start()
    node.stop()