Exemplo n.º 1
0
    def run_test(self):

        self.stop_node(0)

        with self.run_node_with_connections(
                "logging difference between block created timestamp and header received timestamp",
                0, [], 2) as p2p_connections:

            # initialize
            self.nodes[0].generate(1)

            connection1 = p2p_connections[0]
            connection2 = p2p_connections[1]

            # 1. create first block (creation time is set)
            block = self.prepareBlock(2)

            # 2. sleep five seconds
            time.sleep(5)

            # 3. connection1 sends HEADERS msg to bitcoind and waits for GETDATA (received time is set)
            headers_message = msg_headers()
            headers_message.headers = [CBlockHeader(block)]
            connection1.cb.send_message(headers_message)
            connection1.cb.wait_for_getdata(block.sha256)

            # 4. connection1 sends BLOCK
            connection1.cb.send_message(msg_block(block))

            # 5. create second block
            block = self.prepareBlock(2)

            # 6. connection2 sends HEADERS msg to bitcoind
            headers_message = msg_headers()
            headers_message.headers = [CBlockHeader(block)]
            connection2.cb.send_message(headers_message)

            # 7. connection2 waits for GETDATA and sends BLOCK
            connection2.cb.wait_for_getdata(block.sha256)
            connection2.cb.send_message(msg_block(block))

            # syncing
            connection1.cb.sync_with_ping()
            connection2.cb.sync_with_ping()

            # check log file for logging about block timestamp and received headers timestamp difference
            time_difference_log_found = False
            for line in open(
                    glob.glob(self.options.tmpdir + "/node0" +
                              "/regtest/bitcoind.log")[0]):
                if "Chain tip timestamp-to-received-time difference" in line:
                    time_difference_log_found = True
                    logger.info("Found line: %s", line)
                    break

            assert_equal(time_difference_log_found, True)
Exemplo n.º 2
0
    def get_tests(self):
        # shorthand for functions
        block = self.chain.next_block

        node = self.nodes[0]
        self.chain.set_genesis_hash(int(node.getbestblockhash(), 16))

        # Now we need that block to mature so we can spend the coinbase.
        test = TestInstance(sync_every_block=False)
        for i in range(105):
            block(5000 + i)
            test.blocks_and_transactions.append([self.chain.tip, True])
            self.chain.save_spendable_output()
        yield test

        # collect spendable outputs now to avoid cluttering the code later on
        out = []
        for i in range(105):
            out.append(self.chain.get_spendable_output())

        assert_equal(node.getblock(node.getbestblockhash())['height'], 105)

        block(1)

        redeem_script = CScript([OP_TRUE, OP_RETURN, b"a" * 5000])

        spend_tx1 = CTransaction()
        spend_tx1.vin.append(
            CTxIn(COutPoint(out[2].tx.sha256, out[2].n), CScript(),
                  0xffffffff))
        spend_tx1.vout.append(CTxOut(500, redeem_script))
        spend_tx1.vout.append(CTxOut(500, redeem_script))
        spend_tx1.calc_sha256()
        self.log.info(spend_tx1.hash)

        self.chain.update_block(1, [spend_tx1])
        yield self.accepted()

        tx1 = CTransaction()
        tx1.vout = [CTxOut(499, CScript([OP_TRUE]))]
        tx1.vin.append(
            CTxIn(COutPoint(spend_tx1.sha256, 0), CScript(), 0xfffffff))
        tx1.vin.append(
            CTxIn(COutPoint(spend_tx1.sha256, 1), CScript(), 0xfffffff))
        tx1.calc_sha256()
        self.log.info(tx1.hash)
        yield TestInstance(
            [[tx1, RejectResult(16, b'bad-txns-inputs-too-large')]])
    def run_test(self):
        self.stop_node(0)

        askedFor = {}
        rejectSent = False
        def on_getdata(conn, message):
            if (conn in askedFor):
                askedFor[conn] += 1
            else:
                askedFor[conn] = 1
            nonlocal rejectSent
            # First node that receives GetData should send reject.
            if not rejectSent:
                rejectSent = True
                conn.send_message(msg_reject(message=b"getdata", code=self.REJECT_TOOBUSY, reason=b"node too busy"))


        with self.run_node_with_connections("Scenario 1: sending TOOBUSY reject message with 2 nodes", 0, [], self.num_peers) as connections:
            block = self.prepareBlock()

            for connection in connections:
                connection.cb.on_getdata = on_getdata
                headers_message = msg_headers()
                headers_message.headers = [CBlockHeader(block)]
                connection.cb.send_message(headers_message)
                connection.cb.wait_for_getdata(block.sha256)
                connection.cb.sync_with_ping()

            for key, value in askedFor.items():
                assert_equal(value, 1)
            assert_equal(len(askedFor), 2)

        self.num_peers = 1
        askedFor = {}
        rejectSent = False

        with self.run_node_with_connections("Scenario 2: sending TOOBUSY reject message with 1 node", 0, [], self.num_peers) as connections:
            block = self.prepareBlock()

            connection = connections[0]
            connection.cb.on_getdata = on_getdata

            headers_message = msg_headers()
            headers_message.headers = [CBlockHeader(block)]

            begin_test = datetime.datetime.now()
            connection.cb.send_message(headers_message)

            connection.cb.wait_for_getdata(block.sha256)
            connection.cb.last_message["getdata"] = []

            connection.cb.wait_for_getdata(block.sha256)
            end_test = datetime.datetime.now()
            assert(end_test - begin_test > datetime.timedelta(seconds = 5))

            assert_equal(next(iter(askedFor.values())), 2)
            assert_equal(len(askedFor), 1)
    def get_tests(self):
        # shorthand for functions
        block = self.chain.next_block

        node = self.nodes[0]
        self.chain.set_genesis_hash(int(node.getbestblockhash(), 16))

        test, out, _ = prepare_init_chain(self.chain, 105, 105, block_0=False)

        yield test

        assert_equal(node.getblock(node.getbestblockhash())['height'], 105)

        block(1)

        redeem_script = CScript([OP_TRUE, OP_RETURN, b"a" * 5000])

        spend_tx1 = CTransaction()
        spend_tx1.vin.append(
            CTxIn(COutPoint(out[2].tx.sha256, out[2].n), CScript(),
                  0xffffffff))
        spend_tx1.vout.append(CTxOut(500, redeem_script))
        spend_tx1.vout.append(CTxOut(500, redeem_script))
        spend_tx1.calc_sha256()
        self.log.info(spend_tx1.hash)

        self.chain.update_block(1, [spend_tx1])
        yield self.accepted()

        tx1 = CTransaction()
        tx1.vout = [CTxOut(499, CScript([OP_TRUE]))]
        tx1.vin.append(
            CTxIn(COutPoint(spend_tx1.sha256, 0), CScript(), 0xfffffff))
        tx1.vin.append(
            CTxIn(COutPoint(spend_tx1.sha256, 1), CScript(), 0xfffffff))
        tx1.calc_sha256()
        self.log.info(tx1.hash)
        yield TestInstance(
            [[tx1, RejectResult(16, b'bad-txns-inputs-too-large')]])
Exemplo n.º 5
0
    def run_test(self):

        self.stop_node(0)

        with self.run_node_with_connections("send GETDATA messages and check responses", 0, [], 1) as p2p_connections:

            receivedBlocks = set()
            def on_block(conn, message):
                nonlocal receivedBlocks
                receivedBlocks.add(message.block.hash)

            receivedTxs = set()
            def on_tx(conn, message):
                nonlocal receivedTxs
                receivedTxs.add(message.tx.hash)

            receivedTxsNotFound = set()
            def on_notfound(conn, message):
                nonlocal receivedTxsNotFound
                for inv in message.inv:
                    receivedTxsNotFound.add(inv.hash)

            self.nodes[0].generate(5)

            connection = p2p_connections[0]
            connection.cb.on_block = on_block
            connection.cb.on_tx = on_tx
            connection.cb.on_notfound = on_notfound

            # 1. Check that sending GETDATA of unknown block does no action.
            unknown_hash = 0xdecaf
            connection.cb.send_message(msg_getdata([CInv(CInv.BLOCK, unknown_hash)]))

            # 2. Check that sending GETDATA of known block returns BLOCK message.
            known_hash = self.nodes[0].getbestblockhash()
            connection.cb.send_message(msg_getdata([CInv(CInv.BLOCK, int(known_hash, 16))]))
            wait_until(lambda: known_hash in receivedBlocks)
            # previously requested unknown block is not in the received list
            assert_equal(unknown_hash not in receivedBlocks, True)
            assert_equal(len(receivedBlocks), 1)

            # 3. Check that sending GETDATA of unknown transaction returns NOTFOUND message.
            connection.cb.send_message(msg_getdata([CInv(CInv.TX, unknown_hash)]))
            wait_until(lambda: unknown_hash in receivedTxsNotFound)

            # 4. Check that sending GETDATA of known transaction returns TX message.
            known_hash = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1.0)
            connection.cb.send_message(msg_getdata([CInv(CInv.TX, int(known_hash, 16))]))
            wait_until(lambda: known_hash in receivedTxs)
            assert_equal(len(receivedTxs), 1)
Exemplo n.º 6
0
    def run_test(self):
        @contextlib.contextmanager
        def run_connection(title):
            logger.debug("setup %s", title)

            self.start_node(0)

            test_nodes = []
            for i in range(self.num_peers):
                test_nodes.append(NodeConnCB())

            connections = []
            for test_node in test_nodes:
                connection = NodeConn('127.0.0.1', p2p_port(0), self.nodes[0],
                                      test_node)
                connections.append(connection)
                test_node.add_connection(connection)

            thr = NetworkThread()
            thr.start()
            for test_node in test_nodes:
                test_node.wait_for_verack()

            logger.debug("before %s", title)
            yield test_nodes
            logger.debug("after %s", title)

            for connection in connections:
                connection.close()
            del connections

            # once all connection.close() are complete, NetworkThread run loop completes and thr.join() returns success
            thr.join()
            disconnect_nodes(self.nodes[0], 1)
            self.stop_node(0)
            logger.debug("finished %s", title)

        self.stop_node(0)

        askedFor = {}
        rejectSent = False

        def on_getdata(conn, message):
            if (conn in askedFor):
                askedFor[conn] += 1
            else:
                askedFor[conn] = 1
            nonlocal rejectSent
            # First node that receives GetData should send reject.
            if not rejectSent:
                rejectSent = True
                test_node.send_message(
                    msg_reject(message=b"getdata",
                               code=self.REJECT_TOOBUSY,
                               reason=b"node too busy"))

        with run_connection(
                "Scenario 1: sending TOOBUSY reject message with 2 nodes"
        ) as test_nodes:
            block = self.prepareBlock()

            for test_node in test_nodes:
                test_node.on_getdata = on_getdata
                headers_message = msg_headers()
                headers_message.headers = [CBlockHeader(block)]
                test_node.send_message(headers_message)
                test_node.wait_for_getdata(block.sha256)
                test_node.sync_with_ping()

            for key, value in askedFor.items():
                assert_equal(value, 1)
            assert_equal(len(askedFor), 2)

        self.num_peers = 1
        askedFor = {}
        rejectSent = False

        with run_connection(
                "Scenario 2: sending TOOBUSY reject message with 1 node"
        ) as test_nodes:
            block = self.prepareBlock()

            test_node = test_nodes[0]
            test_node.on_getdata = on_getdata

            headers_message = msg_headers()
            headers_message.headers = [CBlockHeader(block)]

            begin_test = datetime.datetime.now()
            test_node.send_message(headers_message)

            test_node.wait_for_getdata(block.sha256)
            test_node.last_message["getdata"] = []

            test_node.wait_for_getdata(block.sha256)
            end_test = datetime.datetime.now()
            assert (end_test - begin_test > datetime.timedelta(seconds=5))

            assert_equal(next(iter(askedFor.values())), 2)
            assert_equal(len(askedFor), 1)