diff --git a/electrumx/server/mempool.py b/electrumx/server/mempool.py index d71a943..67305a0 100644 --- a/electrumx/server/mempool.py +++ b/electrumx/server/mempool.py @@ -31,6 +31,13 @@ class MemPoolTx(object): size = attr.ib() +@attr.s(slots=True) +class MemPoolTxSummary(object): + hash = attr.ib() + fee = attr.ib() + has_unconfirmed_inputs = attr.ib() + + class MemPoolAPI(ABC): '''A concrete instance of this class is passed to the MemPool object and used by it to query DB and blockchain state.''' @@ -299,7 +306,6 @@ class MemPool(object): Can be positive or negative. ''' value = 0 - # hashXs is a defaultdict if hashX in self.hashXs: for hash in self.hashXs[hashX]: tx = self.txs[hash] @@ -325,18 +331,12 @@ class MemPool(object): return result async def transaction_summaries(self, hashX): - '''Return a list of (tx_hash, tx_fee, unconfirmed) tuples for - mempool entries for the hashX. - - unconfirmed is True if any txin is unconfirmed. - ''' - # hashXs is a defaultdict, so use get() to query + '''Return a list of MemPoolTxSummary objects for the hashX.''' result = [] for tx_hash in self.hashXs.get(hashX, ()): tx = self.txs[tx_hash] - unconfirmed = any(prev_hash in self.txs - for prev_hash, prev_idx in tx.prevouts) - result.append((tx_hash, tx.fee, unconfirmed)) + has_ui = any(hash in self.txs for hash, idx in tx.prevouts) + result.append(MemPoolTxSummary(tx_hash, tx.fee, has_ui)) return result async def unordered_UTXOs(self, hashX): @@ -347,7 +347,6 @@ class MemPool(object): the outputs. ''' utxos = [] - # hashXs is a defaultdict, so use get() to query for tx_hash in self.hashXs.get(hashX, ()): tx = self.txs.get(tx_hash) for pos, (hX, value) in enumerate(tx.out_pairs): diff --git a/electrumx/server/session.py b/electrumx/server/session.py index 3210741..5d6b9f3 100644 --- a/electrumx/server/session.py +++ b/electrumx/server/session.py @@ -779,15 +779,16 @@ class ElectrumX(SessionBase): Status is a hex string, but must be None if there is no history. ''' # Note history is ordered and mempool unordered in electrum-server - # For mempool, height is -1 if unconfirmed txins, otherwise 0 - history = await self.session_mgr.limited_history(hashX) + # For mempool, height is -1 if it has unconfirmed inputs, otherwise 0 + db_history = await self.session_mgr.limited_history(hashX) mempool = await self.mempool.transaction_summaries(hashX) - status = ''.join('{}:{:d}:'.format(hash_to_hex_str(tx_hash), height) - for tx_hash, height in history) - status += ''.join('{}:{:d}:'.format(hash_to_hex_str(hex_hash), - -unconfirmed) - for hex_hash, tx_fee, unconfirmed in mempool) + status = ''.join(f'{hash_to_hex_str(tx_hash)}:' + f'{height:d}:' + for tx_hash, height in db_history) + status += ''.join(f'{hash_to_hex_str(tx.hash)}:' + f'{-tx.has_unconfirmed_inputs:d}:' + for tx in mempool) if status: status = sha256(status.encode()).hex() else: @@ -872,11 +873,11 @@ class ElectrumX(SessionBase): async def unconfirmed_history(self, hashX): # Note unconfirmed history is unordered in electrum-server - # Height is -1 if unconfirmed txins, otherwise 0 - mempool = await self.mempool.transaction_summaries(hashX) - return [{'tx_hash': hash_to_hex_str(tx_hash), 'height': -unconfirmed, - 'fee': fee} - for tx_hash, fee, unconfirmed in mempool] + # height is -1 if it has unconfirmed inputs, otherwise 0 + return [{'tx_hash': hash_to_hex_str(tx.hash), + 'height': -tx.has_unconfirmed_inputs, + 'fee': tx.fee} + for tx in await self.mempool.transaction_summaries(hashX)] async def confirmed_and_unconfirmed_history(self, hashX): # Note history is ordered but unconfirmed is unordered in e-s