commit b9a1e2f05c4871e9d7a3fa90e01a6548152bf65f
parent 7d3865cc4ee1682c4188707594389f92c3287838
Author: parazyd <parazyd@dyne.org>
Date: Thu, 15 Apr 2021 12:35:36 +0200
Fix logic bug in blockchain.block.headers and implement cp_height.
Diffstat:
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/obelisk/protocol.py b/obelisk/protocol.py
@@ -251,6 +251,7 @@ class ElectrumProtocol(asyncio.Protocol): # pylint: disable=R0904,R0902
cp_headers.append(data)
# TODO: Review
+ # TODO: Is index is 0 or last elem?
branch, root = merkle_branch_and_root(cp_headers, 0)
return {
"result": {
@@ -268,20 +269,22 @@ class ElectrumProtocol(asyncio.Protocol): # pylint: disable=R0904,R0902
return JsonRPCError.invalidparams()
# Electrum doesn't allow max_chunk_size to be less than 2016
# gopher://bitreich.org/9/memecache/convenience-store.mkv
- # TODO: cp_height
max_chunk_size = 2016
start_height = query["params"][0]
count = query["params"][1]
+ cp_height = query["params"][2] if len(query["params"]) == 3 else 0
if not is_non_negative_integer(start_height):
return JsonRPCError.invalidparams()
if not is_non_negative_integer(count):
return JsonRPCError.invalidparams()
+ if cp_height != 0 and not start_height + (count - 1) <= cp_height:
+ return JsonRPCError.invalidparams()
count = min(count, max_chunk_size)
headers = bytearray()
for i in range(count):
- _ec, data = await self.bx.fetch_block_header(i)
+ _ec, data = await self.bx.fetch_block_header(start_height + i)
if _ec and _ec != 0:
self.log.debug("Got error: %s", repr(_ec))
return JsonRPCError.internalerror()
@@ -292,6 +295,26 @@ class ElectrumProtocol(asyncio.Protocol): # pylint: disable=R0904,R0902
"count": len(headers) // 80,
"max": max_chunk_size,
}
+
+ # The assumption is to fetch more headers if necessary.
+ # TODO: Review
+ if cp_height > 0 and cp_height - start_height > count:
+ for i in range(cp_height - start_height):
+ _ec, data = await self.bx.fetch_block_header(start_height +
+ count + i)
+ if _ec and _ec != 0:
+ self.log.debug("Got error: %s", repr(_ec))
+ return JsonRPCError.internalerror()
+ headers.extend(data)
+
+ # TODO: Review
+ # TODO: Is index is 0 or last elem?
+ hdr_lst = [headers[i:i + 80] for i in range(0, len(headers), 80)]
+ print(hdr_lst)
+ branch, root = merkle_branch_and_root(hdr_lst, 0)
+ resp["branch"] = [safe_hexlify(i) for i in branch]
+ resp["root"] = safe_hexlify(root)
+
return {"result": resp}
async def blockchain_estimatefee(self, writer, query): # pylint: disable=W0613
diff --git a/tests/test_electrum_protocol.py b/tests/test_electrum_protocol.py
@@ -40,7 +40,7 @@ async def test_blockchain_block_header(protocol, writer):
async def test_blockchain_block_headers(protocol, writer):
- expect = "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b6720100000006128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000e241352e3bec0a95a6217e10c3abb54adfa05abb12c126695595580fb92e222032e7494dffff001d00d23534"
+ expect = "01000000c54675276e0401706aa93db6494dd7d1058b19424f23c8d7c01076da000000001c4375c8056b0ded0fa3d7fc1b5511eaf53216aed72ea95e1b5d19eccbe855f91a184a4dffff001d0336a22601000000bca72b7ccb44f1f0dd803f2c321143c9dda7f5a2a6ed87c76aac918a000000004266985f02f11bdffa559a233f5600c95c04bd70340e75673cadaf3ef6ac72b448194a4dffff001d035c84d801000000769d6d6e4672a620669baa56dd39d066523e461762ad3610fb2055b400000000c50652340352ad79b799b870e3fa2c80804d0fc54063b413e0e2d6dc66ca3f9a55194a4dffff001d022510a4"
query = {"params": [123, 3]}
data = await protocol.blockchain_block_headers(writer, query)
assert data["result"]["hex"] == expect