Browse Source

wallet_db: WalletDB.get_txo_addr now returns dict instead of list

master
SomberNight 5 years ago
parent
commit
da6080421e
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 42
      electrum/address_synchronizer.py
  2. 6
      electrum/wallet_db.py

42
electrum/address_synchronizer.py

@ -135,10 +135,9 @@ class AddressSynchronizer(Logger):
prevout_hash = txin.prevout.txid.hex() prevout_hash = txin.prevout.txid.hex()
prevout_n = txin.prevout.out_idx prevout_n = txin.prevout.out_idx
for addr in self.db.get_txo_addresses(prevout_hash): for addr in self.db.get_txo_addresses(prevout_hash):
l = self.db.get_txo_addr(prevout_hash, addr) d = self.db.get_txo_addr(prevout_hash, addr)
for n, v, is_cb in l: if prevout_n in d:
if n == prevout_n: return addr
return addr
tx = self.db.get_transaction(prevout_hash) tx = self.db.get_transaction(prevout_hash)
if tx: if tx:
return tx.outputs()[prevout_n].address return tx.outputs()[prevout_n].address
@ -153,9 +152,11 @@ class AddressSynchronizer(Logger):
address = self.get_txin_address(txin) address = self.get_txin_address(txin)
if address: if address:
d = self.db.get_txo_addr(prevout_hash, address) d = self.db.get_txo_addr(prevout_hash, address)
for n, v, cb in d: try:
if n == txin.prevout.out_idx: v, cb = d[prevout_n]
return v return v
except KeyError:
pass
tx = self.db.get_transaction(prevout_hash) tx = self.db.get_transaction(prevout_hash)
if tx: if tx:
return tx.outputs()[prevout_n].value return tx.outputs()[prevout_n].value
@ -285,16 +286,17 @@ class AddressSynchronizer(Logger):
self.remove_transaction(tx_hash2) self.remove_transaction(tx_hash2)
# add inputs # add inputs
def add_value_from_prev_output(): def add_value_from_prev_output():
# note: this nested loop takes linear time in num is_mine outputs of prev_tx # note: this takes linear time in num is_mine outputs of prev_tx
for addr in self.db.get_txo_addresses(prevout_hash): addr = self.get_txin_address(txi)
if addr and self.is_mine(addr):
outputs = self.db.get_txo_addr(prevout_hash, addr) outputs = self.db.get_txo_addr(prevout_hash, addr)
# note: instead of [(n, v, is_cb), ...]; we could store: {n -> (v, is_cb)} try:
for n, v, is_cb in outputs: v, is_cb = outputs[prevout_n]
if n == prevout_n: except KeyError:
if addr and self.is_mine(addr): pass
self.db.add_txi_addr(tx_hash, addr, ser, v) else:
self._get_addr_balance_cache.pop(addr, None) # invalidate cache self.db.add_txi_addr(tx_hash, addr, ser, v)
return self._get_addr_balance_cache.pop(addr, None) # invalidate cache
for txi in tx.inputs(): for txi in tx.inputs():
if txi.is_coinbase_input(): if txi.is_coinbase_input():
continue continue
@ -656,7 +658,7 @@ class AddressSynchronizer(Logger):
delta -= v delta -= v
# add the value of the coins received at address # add the value of the coins received at address
d = self.db.get_txo_addr(tx_hash, address) d = self.db.get_txo_addr(tx_hash, address)
for n, v, cb in d: for n, (v, cb) in d.items():
delta += v delta += v
return delta return delta
@ -670,7 +672,7 @@ class AddressSynchronizer(Logger):
delta -= v delta -= v
for addr in self.db.get_txo_addresses(txid): for addr in self.db.get_txo_addresses(txid):
d = self.db.get_txo_addr(txid, addr) d = self.db.get_txo_addr(txid, addr)
for n, v, cb in d: for n, (v, cb) in d.items():
delta += v delta += v
return delta return delta
@ -758,8 +760,8 @@ class AddressSynchronizer(Logger):
received = {} received = {}
sent = {} sent = {}
for tx_hash, height in h: for tx_hash, height in h:
l = self.db.get_txo_addr(tx_hash, address) d = self.db.get_txo_addr(tx_hash, address)
for n, v, is_cb in l: for n, (v, is_cb) in d.items():
received[tx_hash + ':%d'%n] = (height, v, is_cb) received[tx_hash + ':%d'%n] = (height, v, is_cb)
for tx_hash, height in h: for tx_hash, height in h:
l = self.db.get_txi_addr(tx_hash, address) l = self.db.get_txi_addr(tx_hash, address)

6
electrum/wallet_db.py

@ -794,12 +794,12 @@ class WalletDB(JsonDB):
return list(d.items()) return list(d.items())
@locked @locked
def get_txo_addr(self, tx_hash: str, address: str) -> Iterable[Tuple[int, int, bool]]: def get_txo_addr(self, tx_hash: str, address: str) -> Dict[int, Tuple[int, bool]]:
"""Returns an iterable of (output_index, value, is_coinbase).""" """Returns a dict: output_index -> (value, is_coinbase)."""
assert isinstance(tx_hash, str) assert isinstance(tx_hash, str)
assert isinstance(address, str) assert isinstance(address, str)
d = self.txo.get(tx_hash, {}).get(address, {}) d = self.txo.get(tx_hash, {}).get(address, {})
return [(int(n), v, cb) for (n, (v, cb)) in d.items()] return {int(n): (v, cb) for (n, (v, cb)) in d.items()}
@modifier @modifier
def add_txi_addr(self, tx_hash: str, addr: str, ser: str, v: int) -> None: def add_txi_addr(self, tx_hash: str, addr: str, ser: str, v: int) -> None:

Loading…
Cancel
Save