예제 #1
0
    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)
예제 #2
0
    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())
예제 #4
0
    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'])
예제 #6
0
    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)