def test_case(self, rpcsend=None, conn=None):
        # First create funding transaction that pays to output that does not require signatures.
        out_value = 10000
        ftx = CTransaction()
        ftx.vout.append(CTxOut(out_value, CScript([OP_TRUE])))
        ftxHex = self.nodes[0].fundrawtransaction(ToHex(ftx),{ 'changePosition' : len(ftx.vout)})['hex']
        ftxHex = self.nodes[0].signrawtransaction(ftxHex)['hex']
        ftx = FromHex(CTransaction(), ftxHex)
        ftx.rehash()

        # Allow coinbase to mature
        self.nodes[0].generate(101)

        # Feed in funding txn and wait for both nodes to see it
        self.send_txn(rpcsend, conn, ftx)

        wait_until(lambda: ftx.hash in self.nodes[0].getrawmempool(), timeout=5)
        wait_until(lambda: ftx.hash in self.nodes[1].getrawmempool(), timeout=5)

        # Create non-final txn.
        parent_txid = ftx.sha256
        send_value = out_value - 500;
        tx = CTransaction()
        tx.vin.append(CTxIn(COutPoint(parent_txid, 0), b'', 0x01))
        tx.vout.append(CTxOut(int(send_value), CScript([OP_TRUE])))
        tx.nLockTime = int(time.time()) + 300
        tx.rehash()

        # Send non-final txn to node0. It should be forwarded over P2P to node1.
        self.send_txn(rpcsend, conn, tx)

        wait_until(lambda: tx.hash in self.nodes[0].getrawnonfinalmempool(), timeout=5)
        wait_until(lambda: tx.hash in self.nodes[1].getrawnonfinalmempool(), timeout=5)
        assert(tx.hash not in self.nodes[0].getrawmempool())
        assert(tx.hash not in self.nodes[1].getrawmempool())

        # Create finalising txn.
        finaltx = copy.deepcopy(tx)
        finaltx.vin[0].nSequence = 0xFFFFFFFF;
        finaltx.rehash()

        # Send finalising txn to node0. It should be forwarded over P2P to node1.
        self.send_txn(rpcsend, conn, finaltx)

        wait_until(lambda: finaltx.hash in self.nodes[0].getrawmempool(), timeout=5)
        wait_until(lambda: finaltx.hash in self.nodes[1].getrawmempool(), timeout=5)
        assert(tx.hash not in self.nodes[0].getrawnonfinalmempool())
        assert(tx.hash not in self.nodes[1].getrawnonfinalmempool())
示例#2
0
    def run_test(self):
        # Create a P2P connection to the first node
        node0 = NodeConnCB()
        connections = []
        connections.append(
            NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], node0))
        node0.add_connection(connections[0])

        # Start up network handling in another thread. This needs to be called
        # after the P2P connections have been created.
        NetworkThread().start()
        # wait_for_verack ensures that the P2P connection is fully up.
        node0.wait_for_verack()

        # Out of IBD
        self.nodes[0].generate(1)

        # First create funding transaction that pays to output that does not require signatures.
        out_value = 10000
        ftx = CTransaction()
        ftx.vout.append(CTxOut(out_value, CScript([OP_TRUE])))
        ftxHex = self.nodes[0].fundrawtransaction(
            ToHex(ftx), {'changePosition': len(ftx.vout)})['hex']
        ftxHex = self.nodes[0].signrawtransaction(ftxHex)['hex']
        ftx = FromHex(CTransaction(), ftxHex)
        ftx.rehash()

        # Allow coinbase to mature
        self.nodes[0].generate(101)

        # Feed in funding txn and wait for both nodes to see it
        connections[0].send_message(msg_tx(ftx))
        wait_until(lambda: ftx.hash in self.nodes[0].getrawmempool(),
                   timeout=5)
        wait_until(lambda: ftx.hash in self.nodes[1].getrawmempool(),
                   timeout=5)

        # Create non-final txn.
        parent_txid = ftx.sha256
        send_value = out_value - 500
        tx = CTransaction()
        tx.vin.append(CTxIn(COutPoint(parent_txid, 0), b'', 0x01))
        tx.vout.append(CTxOut(int(send_value), CScript([OP_TRUE])))
        tx.nLockTime = int(time.time()) + 300
        tx.rehash()

        # Send non-final txn to node0. It should be forwarded over P2P to node1.
        connections[0].send_message(msg_tx(tx))
        wait_until(lambda: tx.hash in self.nodes[0].getrawnonfinalmempool(),
                   timeout=5)
        wait_until(lambda: tx.hash in self.nodes[1].getrawnonfinalmempool(),
                   timeout=5)
        assert (tx.hash not in self.nodes[0].getrawmempool())
        assert (tx.hash not in self.nodes[1].getrawmempool())

        # Create finalising txn.
        finaltx = copy.deepcopy(tx)
        finaltx.vin[0].nSequence = 0xFFFFFFFF
        finaltx.rehash()

        # Send finalising txn to node0. It should be forwarded over P2P to node1.
        connections[0].send_message(msg_tx(finaltx))
        wait_until(lambda: finaltx.hash in self.nodes[0].getrawmempool(),
                   timeout=5)
        wait_until(lambda: finaltx.hash in self.nodes[1].getrawmempool(),
                   timeout=5)
        assert (tx.hash not in self.nodes[0].getrawnonfinalmempool())
        assert (tx.hash not in self.nodes[1].getrawnonfinalmempool())
示例#3
0
    def run_test(self):
        chain_height = self.nodes[0].getblockcount()
        assert_equal(chain_height, 200)

        self.log.debug("Mine a single block to get out of IBD")
        self.nodes[0].generate(1)
        self.sync_all()

        # Create funding transaction that pays to outputs that don't require signatures.
        out_value = 10000
        ftx = CTransaction()
        ftx.vout.append(CTxOut(out_value, CScript([OP_TRUE])))
        ftx.vout.append(CTxOut(out_value, CScript([OP_TRUE])))
        ftxHex = self.nodes[2].fundrawtransaction(
            ToHex(ftx), {'changePosition': len(ftx.vout)})['hex']
        ftxHex = self.nodes[2].signrawtransaction(ftxHex)['hex']
        self.nodes[2].sendrawtransaction(ftxHex)
        ftx = FromHex(CTransaction(), ftxHex)
        ftx.rehash()

        # Create & send a couple of non-final txns.
        for i in range(2):
            parent_txid = ftx.sha256
            send_value = out_value - 500
            non_final_tx = CTransaction()
            non_final_tx.vin.append(CTxIn(COutPoint(parent_txid, i), b'',
                                          0x01))
            non_final_tx.vout.append(
                CTxOut(int(send_value), CScript([OP_TRUE])))
            non_final_tx.nLockTime = int(time.time()) + 300
            non_final_txHex = self.nodes[2].signrawtransaction(
                ToHex(non_final_tx))['hex']
            self.nodes[2].sendrawtransaction(non_final_txHex)
        self.sync_all()
        self.log.debug(
            "Verify that all nodes have 2 transactions in their non-final mempools"
        )
        assert_equal(len(self.nodes[0].getrawnonfinalmempool()), 2)
        assert_equal(len(self.nodes[1].getrawnonfinalmempool()), 2)
        assert_equal(len(self.nodes[2].getrawnonfinalmempool()), 2)

        self.log.debug(
            "Send another 4 transactions from node2 (to its own address)")
        for i in range(4):
            self.nodes[2].sendtoaddress(self.nodes[2].getnewaddress(),
                                        Decimal("10"))
        self.sync_all()

        self.log.debug(
            "Verify that all nodes have 5 transactions in their main mempools")
        assert_equal(len(self.nodes[0].getrawmempool()), 5)
        assert_equal(len(self.nodes[1].getrawmempool()), 5)
        assert_equal(len(self.nodes[2].getrawmempool()), 5)

        self.log.debug(
            "Stop-start node0 and node1. Verify that node0 has the transactions in its mempools and node1 does not."
        )
        self.stop_nodes()
        self.start_node(0)
        self.start_node(1)
        # Give bitcoind a second to reload the mempool
        time.sleep(1)
        wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5)
        wait_until(lambda: len(self.nodes[0].getrawnonfinalmempool()) == 2)
        assert_equal(len(self.nodes[1].getrawmempool()), 0)
        assert_equal(len(self.nodes[1].getrawnonfinalmempool()), 0)

        self.log.debug(
            "Stop-start node0 with -persistmempool=0. Verify that it doesn't load its mempool.dat file."
        )
        self.stop_nodes()
        self.start_node(0, extra_args=["-persistmempool=0"])
        # Give bitcoind a second to reload the mempool
        time.sleep(1)
        assert_equal(len(self.nodes[0].getrawmempool()), 0)
        assert_equal(len(self.nodes[0].getrawnonfinalmempool()), 0)

        self.log.debug(
            "Stop-start node0. Verify that it has the transactions in its mempool."
        )
        self.stop_nodes()
        self.start_node(0)
        wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5)
        wait_until(lambda: len(self.nodes[0].getrawnonfinalmempool()) == 2)