From 063f1b2eff3da33e23e3bc8aa00a0d1cef5aab11 Mon Sep 17 00:00:00 2001 From: Neil Booth Date: Tue, 17 Jul 2018 14:45:55 +0800 Subject: [PATCH] Move block_get_header and estimate_fee to session --- electrumx/server/controller.py | 35 +++----------------------- electrumx/server/session.py | 45 ++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/electrumx/server/controller.py b/electrumx/server/controller.py index e4cd216..3178048 100644 --- a/electrumx/server/controller.py +++ b/electrumx/server/controller.py @@ -28,7 +28,8 @@ import electrumx.lib.util as util from electrumx.server.daemon import DaemonError from electrumx.server.mempool import MemPool from electrumx.server.peers import PeerManager -from electrumx.server.session import LocalRPC, BAD_REQUEST, DAEMON_ERROR +from electrumx.server.session import (LocalRPC, BAD_REQUEST, DAEMON_ERROR, + non_negative_integer) class SessionGroup(object): @@ -594,7 +595,7 @@ class Controller(ServerBase): count: number of blocks to reorg (default 3) ''' - count = self.non_negative_integer(count) + count = non_negative_integer(count) if not self.bp.force_chain_reorg(count): raise RPCError(BAD_REQUEST, 'still catching up with daemon') return 'scheduled a reorg of {:,d} blocks'.format(count) @@ -611,18 +612,6 @@ class Controller(ServerBase): pass raise RPCError(BAD_REQUEST, f'{value} should be a transaction hash') - def non_negative_integer(self, value): - '''Return param value it is or can be converted to a non-negative - integer, otherwise raise an RPCError.''' - try: - value = int(value) - if value >= 0: - return value - except ValueError: - pass - raise RPCError(BAD_REQUEST, - f'{value} should be a non-negative integer') - async def daemon_request(self, method, *args): '''Catch a DaemonError and convert it to an RPCError.''' try: @@ -689,22 +678,6 @@ class Controller(ServerBase): for utxo in utxos if (utxo.tx_hash, utxo.tx_pos) not in spends] - def block_get_header(self, height): - '''The deserialized header at a given height. - - height: the header's height''' - height = self.non_negative_integer(height) - return self.electrum_header(height) - - async def estimatefee(self, number): - '''The estimated transaction fee per kilobyte to be paid for a - transaction to be included within a certain number of blocks. - - number: the number of blocks - ''' - number = self.non_negative_integer(number) - return await self.daemon_request('estimatefee', [number]) - def mempool_get_fee_histogram(self): '''Memory pool fee histogram. @@ -738,7 +711,7 @@ class Controller(ServerBase): height: the height of the block it is in ''' self.assert_tx_hash(tx_hash) - height = self.non_negative_integer(height) + height = non_negative_integer(height) hex_hashes = await self.daemon_request('block_hex_hashes', height, 1) block_hash = hex_hashes[0] diff --git a/electrumx/server/session.py b/electrumx/server/session.py index da9a41c..67f9558 100644 --- a/electrumx/server/session.py +++ b/electrumx/server/session.py @@ -36,6 +36,19 @@ def scripthash_to_hashX(scripthash): raise RPCError(BAD_REQUEST, f'{scripthash} is not a valid script hash') +def non_negative_integer(value): + '''Return param value it is or can be converted to a non-negative + integer, otherwise raise an RPCError.''' + try: + value = int(value) + if value >= 0: + return value + except ValueError: + pass + raise RPCError(BAD_REQUEST, + f'{value} should be a non-negative integer') + + class Semaphores(object): def __init__(self, semaphores): @@ -423,8 +436,8 @@ class ElectrumX(SessionBase): def block_header(self, height, cp_height=0): '''Return a raw block header as a hexadecimal string, or as a dictionary with a merkle proof.''' - height = self.controller.non_negative_integer(height) - cp_height = self.controller.non_negative_integer(cp_height) + height = non_negative_integer(height) + cp_height = non_negative_integer(cp_height) raw_header_hex = self.controller.raw_header(height).hex() if cp_height == 0: return raw_header_hex @@ -445,9 +458,9 @@ class ElectrumX(SessionBase): start_height and count must be non-negative integers. At most MAX_CHUNK_SIZE headers will be returned. ''' - start_height = self.controller.non_negative_integer(start_height) - count = self.controller.non_negative_integer(count) - cp_height = self.controller.non_negative_integer(cp_height) + start_height = non_negative_integer(start_height) + count = non_negative_integer(count) + cp_height = non_negative_integer(cp_height) count = min(count, self.MAX_CHUNK_SIZE) hex_str, count = self.controller.block_headers(start_height, count) @@ -464,12 +477,19 @@ class ElectrumX(SessionBase): '''Return a chunk of block headers as a hexadecimal string. index: the chunk index''' - index = self.controller.non_negative_integer(index) + index = non_negative_integer(index) chunk_size = self.coin.CHUNK_SIZE start_height = index * chunk_size hex_str, n = self.controller.block_headers(start_height, chunk_size) return hex_str + def block_get_header(self, height): + '''The deserialized header at a given height. + + height: the header's height''' + height = non_negative_integer(height) + return self.controller.electrum_header(height) + def is_tor(self): '''Try to detect if the connection is to a tor hidden service we are running.''' @@ -519,6 +539,15 @@ class ElectrumX(SessionBase): return banner + async def estimatefee(self, number): + '''The estimated transaction fee per kilobyte to be paid for a + transaction to be included within a certain number of blocks. + + number: the number of blocks + ''' + number = non_negative_integer(number) + return await self.controller.daemon_request('estimatefee', [number]) + def ping(self): '''Serves as a connection keep-alive mechanism and for the client to confirm the server is still responding. @@ -584,8 +613,8 @@ class ElectrumX(SessionBase): controller = self.controller handlers = { 'blockchain.block.get_chunk': self.block_get_chunk, - 'blockchain.block.get_header': controller.block_get_header, - 'blockchain.estimatefee': controller.estimatefee, + 'blockchain.block.get_header': self.block_get_header, + 'blockchain.estimatefee': self.estimatefee, 'blockchain.relayfee': controller.relayfee, 'blockchain.scripthash.get_balance': self.scripthash_get_balance, 'blockchain.scripthash.get_history': self.scripthash_get_history,