#!/usr/bin/env python3
# Copyright (c) 2019 The Bitcoin Unlimited developers
"""
Tests to check if basic electrum server integration works
"""
import random
from test_framework.util import waitFor, assert_equal
from test_framework.test_framework import BitcoinTestFramework
from test_framework.loginit import logging
from test_framework.electrumutil import compare, bitcoind_electrum_args, \
    create_electrum_connection, address_to_scripthash
from test_framework.nodemessages import COIN


class ElectrumBasicTests(BitcoinTestFramework):

    def __init__(self):
        super().__init__()
        self.setup_clean_chain = True
        self.num_nodes = 1
        self.extra_args = [bitcoind_electrum_args()]

    def run_test(self):
        n = self.nodes[0]

        logging.info("Checking that blocks are indexed")
        n.generate(200)

        self.test_mempoolsync(n)
        electrum_client = create_electrum_connection()
        self.test_address_balance(n, electrum_client)

    def test_mempoolsync(self, n):
        # waitFor throws on timeout, failing the test
        waitFor(10, lambda: compare(n, "index_height", n.getblockcount()))
        waitFor(10, lambda: compare(n, "index_txns", n.getblockcount() + 1, True)) # +1 is genesis tx
        waitFor(10, lambda: compare(n, "mempool_count", 0, True))

        logging.info("Check that mempool is communicated")
        n.sendtoaddress(n.getnewaddress(), 1)
        assert_equal(1, len(n.getrawmempool()))
        waitFor(10, lambda: compare(n, "mempool_count", 1, True))

        n.generate(1)
        assert_equal(0, len(n.getrawmempool()))
        waitFor(10, lambda: compare(n, "index_height", n.getblockcount()))
        waitFor(10, lambda: compare(n, "mempool_count", 0, True))
        waitFor(10, lambda: compare(n, "index_txns", n.getblockcount() + 2, True))

    def test_address_balance(self, n, electrum_client):
        addr = n.getnewaddress()
        txhash = n.sendtoaddress(addr, 1)

        scripthash = address_to_scripthash(addr)

        def check_address(address, unconfirmed = 0, confirmed = 0):
            res = electrum_client.call("blockchain.scripthash.get_balance",
                address_to_scripthash(addr))

            return res["unconfirmed"] == unconfirmed * COIN \
                and res["confirmed"] == confirmed * COIN

        waitFor(10, lambda: check_address(scripthash, unconfirmed = 1))
        n.generate(1)
        waitFor(10, lambda: check_address(scripthash, confirmed = 1))



    def setup_network(self, dummy = None):
        self.nodes = self.setup_nodes()

if __name__ == '__main__':
    ElectrumBasicTests().main()

@@ -203,17 +203,32 @@
 rt_equal
+, assert_raises
 %0A
-
 from tes
@@ -498,16 +498,55 @@
 ort COIN
+, CTransaction, ToHex, CTxIn, COutPoint
 %0A%0A%0Aclass
@@ -980,16 +980,114 @@
 ction()%0A
+        self.test_unknown_method(electrum_client)%0A        self.test_invalid_args(electrum_client)%0A
         
@@ -1897,16 +1897,16 @@
  True))%0A
-
         
@@ -1977,24 +1977,1523 @@
  2, True))%0A%0A
+    def test_unknown_method(self, electrum_client):%0A        from test_framework.connectrum.exc import ElectrumErrorResponse%0A        assert_raises(%0A            ElectrumErrorResponse,%0A            electrum_client.call,%0A            %22method.that.does.not.exist%22, 42)%0A        try:%0A            electrum_client.call(%22method.that.does.not.exist%22)%0A        except Exception as e:%0A            error_code = %22-32601%22%0A            assert error_code in str(e)%0A%0A    def test_invalid_args(self, electrum_client):%0A        from test_framework.connectrum.exc import ElectrumErrorResponse%0A        error_code = %22-32602%22%0A%0A        hash_param_methods = (%0A            %22blockchain.scripthash.get_balance%22,%0A            %22blockchain.scripthash.get_history%22,%0A            %22blockchain.scripthash.listunspent%22)%0A%0A        for method in hash_param_methods:%0A            assert_raises(%0A                ElectrumErrorResponse,%0A                electrum_client.call,%0A                method, %22invalidhash%22)%0A%0A            try:%0A                electrum_client.call(method, %22invalidhash%22)%0A            except Exception as e:%0A                print(%22ERROR:%22 + str(e))%0A                assert error_code in str(e)%0A%0A        # invalid tx%0A        try:%0A            tx = CTransaction()%0A            tx.calc_sha256()%0A            tx.vin = %5BCTxIn(COutPoint(0xbeef, 1))%5D%0A            electrum_client.call(%22blockchain.transaction.broadcast%22, ToHex(tx))%0A        except Exception as e:%0A            print(%22ERROR: %22 + str(e))%0A            assert error_code in str(e)%0A%0A%0A%0A%0A
     def test

Add test for unknown method (#2071)