commit 614407fd1362c82a2af813a48ebbdecd4670838e
parent 901c92c3a40271b74cf91c45cbb5eb9aaee1dd49
Author: parazyd <parazyd@dyne.org>
Date: Fri, 9 Apr 2021 00:09:35 +0200
Implement blockchain.scripthash.subscribe
What's left to do for it is the tx subscription and sending status
notifications.
Diffstat:
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/electrumobelisk/protocol.py b/electrumobelisk/protocol.py
@@ -21,7 +21,7 @@ import asyncio
import json
from binascii import unhexlify
-from electrumobelisk.hashes import double_sha256, hash_to_hex_str
+from electrumobelisk.hashes import sha256, double_sha256, hash_to_hex_str
from electrumobelisk.merkle import merkle_branch
from electrumobelisk.util import (
block_to_header,
@@ -62,6 +62,7 @@ class ElectrumProtocol(asyncio.Protocol): # pylint: disable=R0904,R0902
# Consider renaming bx to something else
self.bx = Client(log, endpoints, self.loop)
self.block_queue = None
+ self.tx_queue = None
# TODO: Clean up on client disconnect
self.tasks = []
self.sh_subscriptions = {}
@@ -331,7 +332,34 @@ class ElectrumProtocol(asyncio.Protocol): # pylint: disable=R0904,R0902
"""Method: blockchain.scripthash.subscribe
Subscribe to a script hash.
"""
- return
+ if "params" not in query or len(query["params"]) != 1:
+ return {"error": "malformed request"}
+
+ scripthash = query["params"][0]
+ if not is_hash256_str(scripthash):
+ return {"error": "invalid scripthash"}
+
+ _ec, history = await self.bx.fetch_history4(scripthash)
+ if _ec and _ec != 0:
+ return {"error": "request corrupted"}
+
+ # TODO: task for tx subscription
+ self.sh_subscriptions[scripthash] = "foo"
+
+ if len(history) < 1:
+ return {"result": None}
+
+ # TODO: Check how history4 acts for mempool/unconfirmed
+ status = []
+ for i in history:
+ kind = "received" if "received" in i else "spent"
+ status.append(safe_hexlify(i[kind]["hash"][::-1]))
+ status.append(str(i[kind]["height"])) # str because of join
+
+ # TODO: Check if trailing colon is necessary
+ concat = ":".join(status) + ":"
+ res = hash_to_hex_str(sha256(concat.encode()))
+ return {"result": res}
async def blockchain_scripthash_unsubscribe(self, writer, query): # pylint: disable=W0613
"""Method: blockchain.scripthash.unsubscribe
diff --git a/electrumobelisk/zeromq.py b/electrumobelisk/zeromq.py
@@ -364,6 +364,8 @@ class Client:
rows = unpack_table("<BI32sIQ", raw_points)
points = [make_tuple(row) for row in rows]
correlated_points = Client.__correlate(points)
+ # self.log.debug("history points: %s", points)
+ # self.log.debug("history correlated: %s", correlated_points)
return error_code, correlated_points
async def broadcast_transaction(self, rawtx):