tImplement blockchain.scripthash.get_history - obelisk - Electrum server using libbitcoin as its backend
 (HTM) git clone https://git.parazyd.org/obelisk
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit b65268c196825ce7bb62ec0e163e5eeca88e3612
 (DIR) parent f3a8be0295a0d054356b41f3a39abdc8bd89cb0c
 (HTM) Author: parazyd <parazyd@dyne.org>
       Date:   Fri,  9 Apr 2021 09:17:40 +0200
       
       Implement blockchain.scripthash.get_history
       
       Still missing mempool stuff.
       
       Diffstat:
         M electrumobelisk/protocol.py         |      23 ++++++++++++++++++++++-
         M electrumobelisk/zeromq.py           |       5 ++++-
         M test.py                             |      36 ++++++++++++++++++++++++++++++-
       
       3 files changed, 61 insertions(+), 3 deletions(-)
       ---
 (DIR) diff --git a/electrumobelisk/protocol.py b/electrumobelisk/protocol.py
       t@@ -328,7 +328,28 @@ class ElectrumProtocol(asyncio.Protocol):  # pylint: disable=R0904,R0902
                """Method: blockchain.scripthash.get_history
                Return the confirmed and unconfirmed history of a script hash.
                """
       -        return
       +        if "params" not in query or len(query["params"]) != 1:
       +            return {"error": "malformed query"}
       +
       +        if not is_hash256_str(query["params"][0]):
       +            return {"error": "invalid scripthash"}
       +
       +        _ec, data = await self.bx.fetch_history4(query["params"][0])
       +        if _ec and _ec != 0:
       +            self.log.debug("Got error: %s", repr(_ec))
       +            return {"error": "request corrupted"}
       +
       +        self.log.debug("hist: %s", data)
       +        ret = []
       +        # TODO: mempool
       +        for i in data:
       +            kind = "received" if "received" in i else "spent"
       +            ret.append({
       +                "height": i[kind]["height"],
       +                "tx_hash": safe_hexlify(i[kind]["hash"][::-1]),
       +            })
       +
       +        return {"result": ret}
        
            async def blockchain_scripthash_get_mempool(self, writer, query):  # pylint: disable=W0613
                """Method: blockchain.scripthash.get_mempool
 (DIR) diff --git a/electrumobelisk/zeromq.py b/electrumobelisk/zeromq.py
       t@@ -370,7 +370,10 @@ class Client:
                    kind, height, tx_hash, index, value = row
                    return (
                        kind,
       -                {"hash": tx_hash, "index": index},
       +                {
       +                    "hash": tx_hash,
       +                    "index": index
       +                },
                        height,
                        value,
                        checksum(tx_hash[::-1].hex(), index),
 (DIR) diff --git a/test.py b/test.py
       t@@ -109,6 +109,40 @@ async def test_blockchain_scripthash_get_balance(protocol, writer):
            return "blockchain_scripthash_get_balance", True
        
        
       +async def test_blockchain_scripthash_get_history(protocol, writer):
       +    shs = [
       +        "c036b0ff3ad79662cd517cd5fe1fa0af07377b9262d16f276f11ced69aaa6921",
       +        "92dd1eb7c042956d3dd9185a58a2578f61fee91347196604540838ccd0f8c08c",
       +    ]
       +    expect = [
       +        (
       +            1936167,
       +            "084eba0e08c78b63e07535b74a5a849994d49afade95d0d205e4963e3f568600",
       +        ),
       +        (
       +            1970700,
       +            "a9c3c22cc2589284288b28e802ea81723d649210d59dfa7e03af00475f4cec20",
       +        ),
       +        (
       +            1936171,
       +            "705c4f265df23726c09c5acb80f9e8a85845c17d68974d89814383855c8545a2",
       +        ),
       +    ]
       +
       +    res = []
       +    for i in shs:
       +        params = {"params": [i]}
       +        data = await protocol.blockchain_scripthash_get_history(writer, params)
       +        if "result" in data:
       +            for i in data["result"]:
       +                res.append((i["height"], i["tx_hash"]))
       +
       +    if expect != res:
       +        return "blockchain_scripthash_get_history", False
       +
       +    return "blockchain_scripthash_get_history", True
       +
       +
        class MockWriter(asyncio.StreamWriter):
            def __init__(self):
                self.mock = None
       t@@ -134,7 +168,7 @@ async def main():
                # test_blockchain_headers_subscribe,
                test_blockchain_relayfee,
                test_blockchain_scripthash_get_balance,
       -        # test_blockchain_scripthash_get_history,
       +        test_blockchain_scripthash_get_history,
                # test_blockchain_scripthash_get_mempool,
                # test_blockchain_scripthash_listunspent,
                # test_blockchain_scripthash_subscribe,