URI: 
       tjson_db: store Transaction objects in memory, not raw hex - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 121b8048b056e797a8a46899e137c277082a66aa
   DIR parent 2ad73050b383adca1dba50afe7cbdb8377a6cbd3
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Fri,  1 Mar 2019 17:55:28 +0100
       
       json_db: store Transaction objects in memory, not raw hex
       
       tto avoid deserializing the same tx multiple times
       
       Diffstat:
         M electrum/json_db.py                 |      39 +++++++++++++++++++------------
         M electrum/util.py                    |       2 +-
       
       2 files changed, 25 insertions(+), 16 deletions(-)
       ---
   DIR diff --git a/electrum/json_db.py b/electrum/json_db.py
       t@@ -43,6 +43,13 @@ FINAL_SEED_VERSION = 18     # electrum >= 2.7 will set this to prevent
                                    # 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):
        
            def __init__(self, raw, *, manual_upgrades):
       t@@ -88,8 +95,8 @@ class JsonDB(PrintError):
            @modifier
            def put(self, key, value):
                try:
       -            json.dumps(key, cls=util.MyEncoder)
       -            json.dumps(value, cls=util.MyEncoder)
       +            json.dumps(key, cls=JsonDBJsonEncoder)
       +            json.dumps(value, cls=JsonDBJsonEncoder)
                except:
                    self.print_error(f"json error: cannot save {repr(key)} ({repr(value)})")
                    return False
       t@@ -107,7 +114,7 @@ class JsonDB(PrintError):
        
            @locked
            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):
                try:
       t@@ -576,18 +583,17 @@ class JsonDB(PrintError):
                self.spent_outpoints[prevout_hash][str(prevout_n)] = tx_hash
        
            @modifier
       -    def add_transaction(self, tx_hash, tx):
       -        self.transactions[tx_hash] = str(tx)
       +    def add_transaction(self, tx_hash: str, tx: Transaction) -> None:
       +        assert isinstance(tx, Transaction)
       +        self.transactions[tx_hash] = tx
        
            @modifier
       -    def remove_transaction(self, tx_hash):
       -        tx = self.transactions.pop(tx_hash, None)
       -        return Transaction(tx) if tx else None
       +    def remove_transaction(self, tx_hash) -> Optional[Transaction]:
       +        return self.transactions.pop(tx_hash, None)
        
            @locked
       -    def get_transaction(self, tx_hash) -> Optional[Transaction]:
       -        tx = self.transactions.get(tx_hash)
       -        return Transaction(tx) if tx else None
       +    def get_transaction(self, tx_hash: str) -> Optional[Transaction]:
       +        return self.transactions.get(tx_hash)
        
            @locked
            def list_transactions(self):
       t@@ -656,13 +662,16 @@ class JsonDB(PrintError):
            @profiler
            def load_transactions(self):
                # references in self.data
       -        self.txi = self.get_data_ref('txi')  # txid -> address -> (prev_outpoint, value)
       -        self.txo = self.get_data_ref('txo')  # txid -> address -> (output_index, value, is_coinbase)
       +        self.txi = self.get_data_ref('txi')  # txid -> address -> list of (prev_outpoint, value)
       +        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.spent_outpoints = self.get_data_ref('spent_outpoints')
       -        self.history = self.get_data_ref('addr_history')  # address -> list(txid, height)
       -        self.verified_tx = self.get_data_ref('verified_tx3') # txid -> TxMinedInfo.  Access with self.lock.
       +        self.history = self.get_data_ref('addr_history')  # address -> list of (txid, height)
       +        self.verified_tx = self.get_data_ref('verified_tx3')  # txid -> (height, timestamp, txpos, header_hash)
                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
                for t in self.txi, self.txo:
                    for d in t.values():
   DIR diff --git a/electrum/util.py b/electrum/util.py
       t@@ -199,7 +199,7 @@ class MyEncoder(json.JSONEncoder):
                    return obj.isoformat(' ')[:-3]
                if isinstance(obj, set):
                    return list(obj)
       -        return super(MyEncoder, self).default(obj)
       +        return super().default(obj)
        
        class PrintError(object):
            '''A handy base class'''