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())
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())
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)