Browse Source

json_db: store Transaction objects in memory, not raw hex

to avoid deserializing the same tx multiple times
sqlite_db
SomberNight 6 years ago
parent
commit
121b8048b0
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 39
      electrum/json_db.py
  2. 2
      electrum/util.py

39
electrum/json_db.py

@ -43,6 +43,13 @@ FINAL_SEED_VERSION = 18 # electrum >= 2.7 will set this to prevent
# old versions from overwriting new format # old versions from overwriting new format
class JsonDBJsonEncoder(util.MyEncoder):
def default(self, obj):
if isinstance(obj, Transaction):
return str(obj)
return super().default(obj)
class JsonDB(PrintError): class JsonDB(PrintError):
def __init__(self, raw, *, manual_upgrades): def __init__(self, raw, *, manual_upgrades):
@ -88,8 +95,8 @@ class JsonDB(PrintError):
@modifier @modifier
def put(self, key, value): def put(self, key, value):
try: try:
json.dumps(key, cls=util.MyEncoder) json.dumps(key, cls=JsonDBJsonEncoder)
json.dumps(value, cls=util.MyEncoder) json.dumps(value, cls=JsonDBJsonEncoder)
except: except:
self.print_error(f"json error: cannot save {repr(key)} ({repr(value)})") self.print_error(f"json error: cannot save {repr(key)} ({repr(value)})")
return False return False
@ -107,7 +114,7 @@ class JsonDB(PrintError):
@locked @locked
def dump(self): def dump(self):
return json.dumps(self.data, indent=4, sort_keys=True, cls=util.MyEncoder) return json.dumps(self.data, indent=4, sort_keys=True, cls=JsonDBJsonEncoder)
def load_data(self, s): def load_data(self, s):
try: try:
@ -576,18 +583,17 @@ class JsonDB(PrintError):
self.spent_outpoints[prevout_hash][str(prevout_n)] = tx_hash self.spent_outpoints[prevout_hash][str(prevout_n)] = tx_hash
@modifier @modifier
def add_transaction(self, tx_hash, tx): def add_transaction(self, tx_hash: str, tx: Transaction) -> None:
self.transactions[tx_hash] = str(tx) assert isinstance(tx, Transaction)
self.transactions[tx_hash] = tx
@modifier @modifier
def remove_transaction(self, tx_hash): def remove_transaction(self, tx_hash) -> Optional[Transaction]:
tx = self.transactions.pop(tx_hash, None) return self.transactions.pop(tx_hash, None)
return Transaction(tx) if tx else None
@locked @locked
def get_transaction(self, tx_hash) -> Optional[Transaction]: def get_transaction(self, tx_hash: str) -> Optional[Transaction]:
tx = self.transactions.get(tx_hash) return self.transactions.get(tx_hash)
return Transaction(tx) if tx else None
@locked @locked
def list_transactions(self): def list_transactions(self):
@ -656,13 +662,16 @@ class JsonDB(PrintError):
@profiler @profiler
def load_transactions(self): def load_transactions(self):
# references in self.data # references in self.data
self.txi = self.get_data_ref('txi') # txid -> address -> (prev_outpoint, value) self.txi = self.get_data_ref('txi') # txid -> address -> list of (prev_outpoint, value)
self.txo = self.get_data_ref('txo') # txid -> address -> (output_index, value, is_coinbase) self.txo = self.get_data_ref('txo') # txid -> address -> list of (output_index, value, is_coinbase)
self.transactions = self.get_data_ref('transactions') # type: Dict[str, Transaction] self.transactions = self.get_data_ref('transactions') # type: Dict[str, Transaction]
self.spent_outpoints = self.get_data_ref('spent_outpoints') self.spent_outpoints = self.get_data_ref('spent_outpoints')
self.history = self.get_data_ref('addr_history') # address -> list(txid, height) self.history = self.get_data_ref('addr_history') # address -> list of (txid, height)
self.verified_tx = self.get_data_ref('verified_tx3') # txid -> TxMinedInfo. Access with self.lock. self.verified_tx = self.get_data_ref('verified_tx3') # txid -> (height, timestamp, txpos, header_hash)
self.tx_fees = self.get_data_ref('tx_fees') self.tx_fees = self.get_data_ref('tx_fees')
# convert raw hex transactions to Transaction objects
for tx_hash, raw_tx in self.transactions.items():
self.transactions[tx_hash] = Transaction(raw_tx)
# convert list to set # convert list to set
for t in self.txi, self.txo: for t in self.txi, self.txo:
for d in t.values(): for d in t.values():

2
electrum/util.py

@ -199,7 +199,7 @@ class MyEncoder(json.JSONEncoder):
return obj.isoformat(' ')[:-3] return obj.isoformat(' ')[:-3]
if isinstance(obj, set): if isinstance(obj, set):
return list(obj) return list(obj)
return super(MyEncoder, self).default(obj) return super().default(obj)
class PrintError(object): class PrintError(object):
'''A handy base class''' '''A handy base class'''

Loading…
Cancel
Save