diff --git a/electrumx/server/controller.py b/electrumx/server/controller.py index 0686eed..10bf9eb 100644 --- a/electrumx/server/controller.py +++ b/electrumx/server/controller.py @@ -22,7 +22,6 @@ import pylru from aiorpcx import RPCError, TaskSet, _version as aiorpcx_version import electrumx from electrumx.lib.hash import hash_to_hex_str, hex_str_to_hash -from electrumx.lib.hash import HASHX_LEN from electrumx.lib.peer import Peer from electrumx.lib.server_base import ServerBase import electrumx.lib.util as util @@ -32,9 +31,6 @@ from electrumx.server.peers import PeerManager from electrumx.server.session import LocalRPC, BAD_REQUEST, DAEMON_ERROR -version_string = util.version_string - - class SessionGroup(object): def __init__(self, gid): @@ -57,6 +53,7 @@ class Controller(ServerBase): '''Initialize everything that doesn't require the event loop.''' super().__init__(env) + version_string = util.version_string if aiorpcx_version < self.AIORPCX_MIN: raise RuntimeError('ElectrumX requires aiorpcX >= ' f'{version_string(self.AIORPCX_MIN)}') @@ -611,15 +608,6 @@ class Controller(ServerBase): pass raise RPCError(BAD_REQUEST, f'{address} is not a valid address') - def scripthash_to_hashX(self, scripthash): - try: - bin_hash = hex_str_to_hash(scripthash) - if len(bin_hash) == 32: - return bin_hash[:HASHX_LEN] - except Exception: - pass - raise RPCError(BAD_REQUEST, f'{scripthash} is not a valid script hash') - def assert_tx_hash(self, value): '''Raise an RPCError if the value is not a valid transaction hash.''' @@ -719,31 +707,16 @@ class Controller(ServerBase): hashX = self.address_to_hashX(address) return await self.get_balance(hashX) - async def scripthash_get_balance(self, scripthash): - '''Return the confirmed and unconfirmed balance of a scripthash.''' - hashX = self.scripthash_to_hashX(scripthash) - return await self.get_balance(hashX) - async def address_get_history(self, address): '''Return the confirmed and unconfirmed history of an address.''' hashX = self.address_to_hashX(address) return await self.confirmed_and_unconfirmed_history(hashX) - async def scripthash_get_history(self, scripthash): - '''Return the confirmed and unconfirmed history of a scripthash.''' - hashX = self.scripthash_to_hashX(scripthash) - return await self.confirmed_and_unconfirmed_history(hashX) - async def address_get_mempool(self, address): '''Return the mempool transactions touching an address.''' hashX = self.address_to_hashX(address) return await self.unconfirmed_history(hashX) - async def scripthash_get_mempool(self, scripthash): - '''Return the mempool transactions touching a scripthash.''' - hashX = self.scripthash_to_hashX(scripthash) - return await self.unconfirmed_history(hashX) - async def hashX_listunspent(self, hashX): '''Return the list of UTXOs of a script hash, including mempool effects.''' @@ -763,11 +736,6 @@ class Controller(ServerBase): hashX = self.address_to_hashX(address) return await self.hashX_listunspent(hashX) - async def scripthash_listunspent(self, scripthash): - '''Return the list of UTXOs of a scripthash.''' - hashX = self.scripthash_to_hashX(scripthash) - return await self.hashX_listunspent(hashX) - def block_get_header(self, height): '''The deserialized header at a given height. diff --git a/electrumx/server/session.py b/electrumx/server/session.py index b706c49..6a6cfa0 100644 --- a/electrumx/server/session.py +++ b/electrumx/server/session.py @@ -16,14 +16,26 @@ from functools import partial from aiorpcx import ServerSession, JSONRPCAutoDetect, RPCError import electrumx -from electrumx.lib.hash import sha256, hash_to_hex_str +from electrumx.lib.hash import (sha256, hash_to_hex_str, hex_str_to_hash, + HASHX_LEN) import electrumx.lib.util as util from electrumx.server.daemon import DaemonError + BAD_REQUEST = 1 DAEMON_ERROR = 2 +def scripthash_to_hashX(scripthash): + try: + bin_hash = hex_str_to_hash(scripthash) + if len(bin_hash) == 32: + return bin_hash[:HASHX_LEN] + except Exception: + pass + raise RPCError(BAD_REQUEST, f'{scripthash} is not a valid script hash') + + class Semaphores(object): def __init__(self, semaphores): @@ -320,11 +332,31 @@ class ElectrumX(SessionBase): hashX = self.controller.address_to_hashX(address) return await self.hashX_subscribe(hashX, address) + async def scripthash_get_balance(self, scripthash): + '''Return the confirmed and unconfirmed balance of a scripthash.''' + hashX = scripthash_to_hashX(scripthash) + return await self.controller.get_balance(hashX) + + async def scripthash_get_history(self, scripthash): + '''Return the confirmed and unconfirmed history of a scripthash.''' + hashX = scripthash_to_hashX(scripthash) + return await self.controller.confirmed_and_unconfirmed_history(hashX) + + async def scripthash_get_mempool(self, scripthash): + '''Return the mempool transactions touching a scripthash.''' + hashX = scripthash_to_hashX(scripthash) + return await self.controller.unconfirmed_history(hashX) + + async def scripthash_listunspent(self, scripthash): + '''Return the list of UTXOs of a scripthash.''' + hashX = scripthash_to_hashX(scripthash) + return await self.controller.hashX_listunspent(hashX) + async def scripthash_subscribe(self, scripthash): '''Subscribe to a script hash. scripthash: the SHA256 hash of the script to subscribe to''' - hashX = self.controller.scripthash_to_hashX(scripthash) + hashX = scripthash_to_hashX(scripthash) return await self.hashX_subscribe(hashX, scripthash) def _merkle_proof(self, cp_height, height): @@ -507,14 +539,10 @@ class ElectrumX(SessionBase): 'blockchain.block.get_header': controller.block_get_header, 'blockchain.estimatefee': controller.estimatefee, 'blockchain.relayfee': controller.relayfee, - 'blockchain.scripthash.get_balance': - controller.scripthash_get_balance, - 'blockchain.scripthash.get_history': - controller.scripthash_get_history, - 'blockchain.scripthash.get_mempool': - controller.scripthash_get_mempool, - 'blockchain.scripthash.listunspent': - controller.scripthash_listunspent, + 'blockchain.scripthash.get_balance': self.scripthash_get_balance, + 'blockchain.scripthash.get_history': self.scripthash_get_history, + 'blockchain.scripthash.get_mempool': self.scripthash_get_mempool, + 'blockchain.scripthash.listunspent': self.scripthash_listunspent, 'blockchain.scripthash.subscribe': self.scripthash_subscribe, 'blockchain.transaction.broadcast': self.transaction_broadcast, 'blockchain.transaction.get': controller.transaction_get,