Rename get_utxos to all_utxos.
- no longer takes a limit - runs in a thread to avoid blocking
This commit is contained in:
parent
0c8d5ddf63
commit
a036a2eb3f
@ -80,13 +80,16 @@ async def query(args):
|
||||
if n is None:
|
||||
print('No history found')
|
||||
n = None
|
||||
for n, utxo in enumerate(db.get_utxos(hashX, limit), start=1):
|
||||
utxos = await db.all_utxos(hashX)
|
||||
for n, utxo in enumerate(utxos, start=1):
|
||||
print(f'UTXO #{n:,d}: tx_hash {hash_to_hex_str(utxo.tx_hash)} '
|
||||
f'tx_pos {utxo.tx_pos:,d} height {utxo.height:,d} '
|
||||
f'value {utxo.value:,d}')
|
||||
if n == limit:
|
||||
break
|
||||
if n is None:
|
||||
print('No UTXOs found')
|
||||
balance = db.get_balance(hashX)
|
||||
balance = sum(utxo.value for utxo in utxos)
|
||||
print(f'Balance: {coin.decimal_value(balance):,f} {coin.SHORTNAME}')
|
||||
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ class ChainState(object):
|
||||
self.force_chain_reorg = self._bp.force_chain_reorg
|
||||
self.tx_branch_and_root = self._bp.merkle.branch_and_root
|
||||
self.read_headers = self._bp.read_headers
|
||||
self.all_utxos = self._bp.all_utxos
|
||||
|
||||
async def broadcast_transaction(self, raw_tx):
|
||||
return await self._daemon.sendrawtransaction([raw_tx])
|
||||
@ -57,13 +58,6 @@ class ChainState(object):
|
||||
|
||||
return await run_in_thread(job)
|
||||
|
||||
async def get_utxos(self, hashX):
|
||||
'''Get UTXOs asynchronously to reduce latency.'''
|
||||
def job():
|
||||
return list(self._bp.get_utxos(hashX, limit=None))
|
||||
|
||||
return await run_in_thread(job)
|
||||
|
||||
def header_branch_and_root(self, length, height):
|
||||
return self._bp.header_mc.branch_and_root(length, height)
|
||||
|
||||
@ -115,15 +109,18 @@ class ChainState(object):
|
||||
if n is None:
|
||||
lines.append('No history found')
|
||||
n = None
|
||||
for n, utxo in enumerate(db.get_utxos(hashX, limit), start=1):
|
||||
utxos = await db.all_utxos(hashX)
|
||||
for n, utxo in enumerate(utxos, start=1):
|
||||
lines.append(f'UTXO #{n:,d}: tx_hash '
|
||||
f'{hash_to_hex_str(utxo.tx_hash)} '
|
||||
f'tx_pos {utxo.tx_pos:,d} height '
|
||||
f'{utxo.height:,d} value {utxo.value:,d}')
|
||||
if n == limit:
|
||||
break
|
||||
if n is None:
|
||||
lines.append('No UTXOs found')
|
||||
|
||||
balance = db.get_balance(hashX)
|
||||
balance = sum(utxo.value for utxo in utxos)
|
||||
lines.append(f'Balance: {coin.decimal_value(balance):,f} '
|
||||
f'{coin.SHORTNAME}')
|
||||
|
||||
|
||||
@ -375,28 +375,25 @@ class DB(object):
|
||||
with self.utxo_db.write_batch() as batch:
|
||||
self.write_utxo_state(batch)
|
||||
|
||||
def get_balance(self, hashX):
|
||||
'''Returns the confirmed balance of an address.'''
|
||||
return sum(utxo.value for utxo in self.get_utxos(hashX, limit=None))
|
||||
|
||||
def get_utxos(self, hashX, limit=1000):
|
||||
'''Generator that yields all UTXOs for an address sorted in no
|
||||
particular order. By default yields at most 1000 entries.
|
||||
Set limit to None to get them all.
|
||||
async def all_utxos(self, hashX):
|
||||
'''Return all UTXOs for an address sorted in no particular order. By
|
||||
default yields at most 1000 entries.
|
||||
'''
|
||||
limit = util.resolve_limit(limit)
|
||||
s_unpack = unpack
|
||||
# Key: b'u' + address_hashX + tx_idx + tx_num
|
||||
# Value: the UTXO value as a 64-bit unsigned integer
|
||||
prefix = b'u' + hashX
|
||||
for db_key, db_value in self.utxo_db.iterator(prefix=prefix):
|
||||
if limit == 0:
|
||||
return
|
||||
limit -= 1
|
||||
tx_pos, tx_num = s_unpack('<HI', db_key[-6:])
|
||||
value, = unpack('<Q', db_value)
|
||||
tx_hash, height = self.fs_tx_hash(tx_num)
|
||||
yield UTXO(tx_num, tx_pos, tx_hash, height, value)
|
||||
def read_utxos():
|
||||
utxos = []
|
||||
utxos_append = utxos.append
|
||||
s_unpack = unpack
|
||||
# Key: b'u' + address_hashX + tx_idx + tx_num
|
||||
# Value: the UTXO value as a 64-bit unsigned integer
|
||||
prefix = b'u' + hashX
|
||||
for db_key, db_value in self.utxo_db.iterator(prefix=prefix):
|
||||
tx_pos, tx_num = s_unpack('<HI', db_key[-6:])
|
||||
value, = unpack('<Q', db_value)
|
||||
tx_hash, height = self.fs_tx_hash(tx_num)
|
||||
utxos_append(UTXO(tx_num, tx_pos, tx_hash, height, value))
|
||||
return utxos
|
||||
|
||||
return await run_in_thread(read_utxos)
|
||||
|
||||
async def lookup_utxos(self, prevouts):
|
||||
'''For each prevout, lookup it up in the DB and return a (hashX,
|
||||
|
||||
@ -17,7 +17,7 @@ from collections import defaultdict, Counter
|
||||
from aiorpcx import (ClientSession, SOCKSProxy,
|
||||
Notification, handler_invocation,
|
||||
SOCKSError, RPCError, TaskTimeout,
|
||||
TaskGroup, run_in_thread, ignore_after, timeout_after)
|
||||
TaskGroup, ignore_after, timeout_after)
|
||||
|
||||
from electrumx.lib.peer import Peer
|
||||
from electrumx.lib.util import class_logger, protocol_tuple
|
||||
|
||||
@ -796,7 +796,7 @@ class ElectrumX(SessionBase):
|
||||
async def hashX_listunspent(self, hashX):
|
||||
'''Return the list of UTXOs of a script hash, including mempool
|
||||
effects.'''
|
||||
utxos = await self.chain_state.get_utxos(hashX)
|
||||
utxos = await self.chain_state.all_utxos(hashX)
|
||||
utxos = sorted(utxos)
|
||||
utxos.extend(await self.mempool.unordered_UTXOs(hashX))
|
||||
spends = await self.mempool.potential_spends(hashX)
|
||||
@ -853,7 +853,7 @@ class ElectrumX(SessionBase):
|
||||
return await self.hashX_subscribe(hashX, address)
|
||||
|
||||
async def get_balance(self, hashX):
|
||||
utxos = await self.chain_state.get_utxos(hashX)
|
||||
utxos = await self.chain_state.all_utxos(hashX)
|
||||
confirmed = sum(utxo.value for utxo in utxos)
|
||||
unconfirmed = await self.mempool.balance_delta(hashX)
|
||||
return {'confirmed': confirmed, 'unconfirmed': unconfirmed}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user