def run_test(self): n = self.nodes[0] n.generate(1) sync_electrum_height(n) cli = ElectrumConnection() self.test_subscribe_headers(n, cli) self.test_subscribe_scripthash(n, cli)
async def test_get_frist_use(self, n): cli = ElectrumConnection() await cli.connect() # New address that has never received coins. Should return an error. addr = n.getnewaddress() await assert_raises_async(ElectrumErrorResponse, cli.call, "blockchain.address.get_first_use", addr) await assert_raises_async(ElectrumErrorResponse, cli.call, "blockchain.scripthash.get_first_use", address_to_scripthash(addr)) # Send coin to the new address txid = await self.sendtoaddr(n, cli, addr, 1) # Wait for electrum server to see the utxo. async def wait_for_utxo(): utxo = await cli.call("blockchain.address.listunspent", addr) if len(utxo) == 1: return utxo return None utxo = await waitForAsync(10, wait_for_utxo) # Observe that get_first_use returns the tx when it's in the mempool res = await cli.call("blockchain.address.get_first_use", addr) res2 = await cli.call("blockchain.scripthash.get_first_use", address_to_scripthash(addr)) assert_equal(res, res2) assert_equal( "0000000000000000000000000000000000000000000000000000000000000000", res['block_hash']) assert_equal(0, res['height']) assert_equal(txid, res['tx_hash']) # Confirm tx, observe that block height and gets set. n.generate(1) sync_electrum_height(n) res = await cli.call("blockchain.address.get_first_use", addr) res2 = await cli.call("blockchain.scripthash.get_first_use", address_to_scripthash(addr)) assert_equal(res, res2) assert_equal(n.getbestblockhash(), res['block_hash']) assert_equal(n.getblockcount(), res['height']) assert_equal(txid, res['tx_hash']) # Send another tx, observe that the first one is till returned. txid2 = await self.sendtoaddr(n, cli, addr, 2) res = await cli.call("blockchain.address.get_first_use", addr) assert_equal(txid, res['tx_hash']) # Also when the second tx is confirmed, the first is returned. n.generate(1) sync_electrum_height(n) res = await cli.call("blockchain.address.get_first_use", addr) assert_equal(txid, res['tx_hash'])
def run_test(self): n = self.nodes[0] n.generate(200) sync_electrum_height(n) async def async_tests(): await self.test_subscribe_address(n) await self.test_subscribe_scripthash(n) await self.test_unsubscribe_address(n) await self.test_unsubscribe_scripthash(n) await self.test_subscribe_headers(n) await self.test_multiple_client_subs(n) loop = asyncio.get_event_loop() loop.run_until_complete(async_tests())
async def test_chain_to_from_one_scripthash(self, n, cli, unspent): """ Creates a tx chain where the same scripthash is both funder and spender """ scriptpubkey = CScript([OP_TRUE, OP_TRUE, OP_DROP, OP_DROP]) scripthash = script_to_scripthash(scriptpubkey) assert_equal(0, len(await cli.call(GET_HISTORY, scripthash))) assert_equal(0, len(await cli.call(GET_MEMPOOL, scripthash))) def has_tx(res, txhash): for tx in res: if tx['tx_hash'] == txhash: return True return False CHAIN_LENGTH = 25 NUM_OUTPUTS = 1 tx_chain = self._create_tx_chain(unspent, scriptpubkey, CHAIN_LENGTH, NUM_OUTPUTS) # Check mempool assert (len(n.getrawmempool()) == 0) self.p2p.send_txs_and_test(tx_chain, n) wait_for_electrum_mempool(n, count=len(tx_chain), timeout=20) res = await cli.call(GET_HISTORY, scripthash) assert_equal(len(tx_chain), len(res)) assert (all([has_tx(res, tx.hash) for tx in tx_chain])) res_mempool = await cli.call(GET_MEMPOOL, scripthash) assert_equal(res, res_mempool) # Check when confirmed in a block self.mine_blocks(n, 1, tx_chain) sync_electrum_height(n) res = await cli.call(GET_HISTORY, scripthash) assert_equal(len(tx_chain), len(res)) assert (all([has_tx(res, tx.hash) for tx in tx_chain])) assert_equal(0, len(await cli.call(GET_MEMPOOL, scripthash)))
async def test_blockheight_confirmed(self, n, cli, unspent): # Just a unique anyone-can-spend scriptpubkey scriptpubkey = CScript([OP_TRUE, OP_DROP, OP_NOP]) scripthash = script_to_scripthash(scriptpubkey) # There should exist any history for scripthash assert_equal(0, len(await cli.call(GET_HISTORY, scripthash))) # Send tx to scripthash and confirm it tx = create_transaction(unspent, n=0, value=unspent.vout[0].nValue, sig=CScript([OP_TRUE]), out=scriptpubkey) pad_tx(tx) self.mine_blocks(n, 1, txns=[tx]) sync_electrum_height(n) # History should now have 1 entry at current tip height res = await cli.call(GET_HISTORY, scripthash) assert_equal(1, len(res)) assert_equal(n.getblockcount(), res[0]['height']) assert_equal(tx.hash, res[0]['tx_hash'])
async def test_blockheight_unconfirmed(self, n, cli, unspent): """ Check that unconfirmed transactions are correctly provided. Note that height is different for unconfirmed with confirmed parents and unconfirmed with unconfirmed parents. """ # Another unique anyone-can-spend scriptpubkey scriptpubkey = CScript([OP_FALSE, OP_DROP, OP_NOP]) scripthash = script_to_scripthash(scriptpubkey) # There should exist any history for scripthash assert_equal(0, len(await cli.call(GET_HISTORY, scripthash))) assert_equal(0, len(await cli.call(GET_MEMPOOL, scripthash))) # Send a chain of three txs. We expect that: # tx1: height 0, signaling unconfirmed with confirmed parents # tx2: height -1, signaling unconfirmed with unconfirmed parents # tx3: height -1, signaling unconfirmed with unconfirmed parents tx1 = create_transaction(unspent, n=0, value=unspent.vout[0].nValue, sig=CScript([OP_TRUE]), out=scriptpubkey) pad_tx(tx1) big_fee = 1 tx2 = create_transaction(tx1, n=0, value=unspent.vout[0].nValue - big_fee, sig=CScript([OP_TRUE]), out=scriptpubkey) pad_tx(tx2) tx3 = create_transaction(tx2, n=0, value=unspent.vout[0].nValue - big_fee, sig=CScript([OP_TRUE]), out=scriptpubkey) pad_tx(tx3) self.p2p.send_txs_and_test([tx1, tx2, tx3], n) wait_for_electrum_mempool(n, count=3) res = await cli.call(GET_HISTORY, scripthash) assert_equal(3, len(res)) assert_equal(res, await cli.call(GET_MEMPOOL, scripthash)) def get_tx(txhash): for tx in res: if tx['tx_hash'] == txhash: return tx assert (not "tx not in result") assert_equal(0, get_tx(tx1.hash)['height']) assert_equal(-1, get_tx(tx2.hash)['height']) assert_equal(-1, get_tx(tx3.hash)['height']) # Confirm tx1, see that # tx1: gets tipheight # tx2: gets height 0, tx3 keeps height -1 self.mine_blocks(n, 1, [tx1]) sync_electrum_height(n) for call in [GET_HISTORY, GET_MEMPOOL]: res = await cli.call(call, scripthash) if call == GET_HISTORY: assert_equal(n.getblockcount(), get_tx(tx1.hash)['height']) else: assert (tx['tx_hash'] != tx1.hash for tx in res) assert_equal(0, get_tx(tx2.hash)['height']) assert_equal(-1, get_tx(tx3.hash)['height']) # cleanup mempool for next test self.mine_blocks(n, 1, [tx2, tx3]) sync_electrum_height(n) assert (len(n.getrawmempool()) == 0)