From f94e6ac527549525681ee3c45615c74fe0bf04aa Mon Sep 17 00:00:00 2001 From: Jack Robison <jackrobison@lbry.io> Date: Wed, 14 Jul 2021 13:04:40 -0400 Subject: [PATCH] update lookup_utxos --- lbry/wallet/server/leveldb.py | 72 ++++++++--------------------------- 1 file changed, 16 insertions(+), 56 deletions(-) diff --git a/lbry/wallet/server/leveldb.py b/lbry/wallet/server/leveldb.py index ed9d3fd48..ac0fc8fc5 100644 --- a/lbry/wallet/server/leveldb.py +++ b/lbry/wallet/server/leveldb.py @@ -1333,16 +1333,12 @@ class LevelDB: def read_utxos(): utxos = [] utxos_append = utxos.append - s_unpack = unpack fs_tx_hash = self.fs_tx_hash - # Key: b'u' + address_hashX + tx_idx + tx_num - # Value: the UTXO value as a 64-bit unsigned integer - prefix = DB_PREFIXES.UTXO_PREFIX.value + hashX - for db_key, db_value in self.db.iterator(prefix=prefix): - tx_pos, tx_num = s_unpack('<HI', db_key[-6:]) - value, = unpack('<Q', db_value) - tx_hash, height = fs_tx_hash(tx_num) - utxos_append(UTXO(tx_num, tx_pos, tx_hash, height, value)) + for db_key, db_value in self.db.iterator(prefix=Prefixes.utxo.pack_partial_key(hashX)): + k = Prefixes.utxo.unpack_key(db_key) + v = Prefixes.utxo.unpack_value(db_value) + tx_hash, height = fs_tx_hash(k.tx_num) + utxos_append(UTXO(k.tx_num, k.nout, tx_hash, height, v.amount)) return utxos while True: @@ -1354,50 +1350,14 @@ class LevelDB: await sleep(0.25) async def lookup_utxos(self, prevouts): - """For each prevout, lookup it up in the DB and return a (hashX, - value) pair or None if not found. - - Used by the mempool code. - """ - def lookup_hashXs(): - """Return (hashX, suffix) pairs, or None if not found, - for each prevout. - """ - def lookup_hashX(tx_hash, tx_idx): - idx_packed = pack('<H', tx_idx) - - # Key: b'h' + compressed_tx_hash + tx_idx + tx_num - # Value: hashX - prefix = DB_PREFIXES.HASHX_UTXO_PREFIX.value + tx_hash[:4] + idx_packed - - # Find which entry, if any, the TX_HASH matches. - for db_key, hashX in self.db.iterator(prefix=prefix): - tx_num_packed = db_key[-4:] - tx_num, = unpack('<I', tx_num_packed) - hash, height = self.fs_tx_hash(tx_num) - if hash == tx_hash: - return hashX, idx_packed + tx_num_packed - return None, None - return [lookup_hashX(*prevout) for prevout in prevouts] - - def lookup_utxos(hashX_pairs): - def lookup_utxo(hashX, suffix): - if not hashX: - # This can happen when the daemon is a block ahead - # of us and has mempool txs spending outputs from - # that new block - return None - # Key: b'u' + address_hashX + tx_idx + tx_num - # Value: the UTXO value as a 64-bit unsigned integer - key = DB_PREFIXES.UTXO_PREFIX.value + hashX + suffix - db_value = self.db.get(key) - if not db_value: - # This can happen if the DB was updated between - # getting the hashXs and getting the UTXOs - return None - value, = unpack('<Q', db_value) - return hashX, value - return [lookup_utxo(*hashX_pair) for hashX_pair in hashX_pairs] - - hashX_pairs = await asyncio.get_event_loop().run_in_executor(self.executor, lookup_hashXs) - return await asyncio.get_event_loop().run_in_executor(self.executor, lookup_utxos, hashX_pairs) + def lookup_utxos(): + utxos = [] + utxo_append = utxos.append + for (tx_hash, nout) in prevouts: + tx_num = self.transaction_num_mapping[tx_hash] + hashX = self.db.get(Prefixes.hashX_utxo.pack_key(tx_hash[:4], tx_num, nout)) + utxo_value = self.db.get(Prefixes.utxo.pack_key(hashX, tx_num, nout)) + if utxo_value: + utxo_append((hashX, Prefixes.utxo.unpack_value(utxo_value).amount)) + return utxos + return await asyncio.get_event_loop().run_in_executor(self.executor, lookup_utxos)