obelisk

Electrum server using libbitcoin as its backend
git clone https://git.parazyd.org/obelisk
Log | Files | Refs | README | LICENSE

commit ca12144acb227a3d27bdf8d54d3c49aac64df114
parent 41f60ddbf3c1206d910918959361957948d2bcc3
Author: parazyd <parazyd@dyne.org>
Date:   Wed,  7 Apr 2021 19:57:17 +0200

Implement blockchain.transaction.get

There is support for including/excluding mempool transactions.
We default to inclusive.

Diffstat:
Melectrumobelisk/protocol.py | 19++++++++++++++++++-
Melectrumobelisk/util.py | 13++++++++++++-
Melectrumobelisk/zeromq.py | 21+++++++++++++++++++++
3 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/electrumobelisk/protocol.py b/electrumobelisk/protocol.py @@ -237,7 +237,24 @@ class ElectrumProtocol(asyncio.Protocol): # pylint: disable=R0904,R0902 return async def blockchain_transaction_get(self, query): - return + if "params" not in query or len(query["params"]) < 1: + return {"error": "malformed request"} + tx_hash = query["params"][0] + verbose = query["params"][1] if len(query["params"]) > 1 else False + + # _ec, rawtx = await self.bx.fetch_blockchain_transaction(tx_hash) + _ec, rawtx = await self.bx.fetch_mempool_transaction(tx_hash) + if _ec and _ec != 0: + self.log.debug("Got error: %s", repr(_ec)) + return {"error": "request corrupted"} + if not rawtx: + return {"error": f"txid {tx_hash} not found"} + + if verbose: + # TODO: Help needed + return {"error": "not implemented with verbose=true"} + + return {"result", safe_hexlify(rawtx)} async def blockchain_transaction_get_merkle(self, query): if "params" not in query or len(query["params"]) != 2: diff --git a/electrumobelisk/util.py b/electrumobelisk/util.py @@ -41,7 +41,7 @@ def is_hex_str(text): return False try: b = bytes.fromhex(text) - except: + except: # pylint: disable=W0702 return False # Forbid whitespaces in text: if len(text) != 2 * len(b): @@ -61,3 +61,14 @@ def is_hash256_str(text): def safe_hexlify(val): """hexlify and return a string""" return str(hexlify(val), "utf-8") + + +def bh2u(val): + """ + str with hex representation of a bytes-like object + + >>> x = bytes((1, 2, 10)) + >>> bh2u(x) + '01020A' + """ + return val.hex() diff --git a/electrumobelisk/zeromq.py b/electrumobelisk/zeromq.py @@ -24,6 +24,7 @@ import zmq import zmq.asyncio from electrumobelisk.libbitcoin_errors import make_error_code, ErrorCode +from electrumobelisk.util import bh2u def create_random_id(): @@ -276,3 +277,23 @@ class Client: if error_code: return error_code, None return error_code, unpack_table("32s", data) + + async def fetch_blockchain_transaction(self, txid): + """Fetch transaction by txid (not including mempool)""" + command = b"blockchain.fetch_transaction2" + error_code, data = await self._simple_request( + command, + bytes.fromhex(txid)[::-1]) + if error_code: + return error_code, None + return error_code, bh2u(data) + + async def fetch_mempool_transaction(self, txid): + """Fetch transaction by txid (including mempool)""" + command = b"transaction_pool.fetch_transaction2" + error_code, data = await self._simple_request( + command, + bytes.fromhex(txid)[::-1]) + if error_code: + return error_code, None + return error_code, bh2u(data)