URI: 
       taddress_synchronizer.get_history now returns HistoryItem(NamedTuple)s - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 241873f0a4bcf907f5a4ae3bba087355a5f14c34
   DIR parent 65b88dca8644b6a1be819029d81e3c8b83b11bc0
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Thu, 12 Sep 2019 04:05:57 +0200
       
       address_synchronizer.get_history now returns HistoryItem(NamedTuple)s
       
       Diffstat:
         M electrum/address_synchronizer.py    |      18 +++++++++++++++---
         M electrum/gui/stdio.py               |      11 ++++++-----
         M electrum/gui/text.py                |      11 ++++++-----
         M electrum/wallet.py                  |      46 +++++++++++++++++--------------
       
       4 files changed, 53 insertions(+), 33 deletions(-)
       ---
   DIR diff --git a/electrum/address_synchronizer.py b/electrum/address_synchronizer.py
       t@@ -26,7 +26,7 @@ import threading
        import asyncio
        import itertools
        from collections import defaultdict
       -from typing import TYPE_CHECKING, Dict, Optional, Set, Tuple
       +from typing import TYPE_CHECKING, Dict, Optional, Set, Tuple, NamedTuple, Sequence
        
        from . import bitcoin
        from .bitcoin import COINBASE_MATURITY, TYPE_ADDRESS, TYPE_PUBKEY
       t@@ -57,6 +57,14 @@ class UnrelatedTransactionException(AddTransactionException):
                return _("Transaction is unrelated to this wallet.")
        
        
       +class HistoryItem(NamedTuple):
       +    txid: str
       +    tx_mined_status: TxMinedInfo
       +    delta: Optional[int]
       +    fee: Optional[int]
       +    balance: Optional[int]
       +
       +
        class AddressSynchronizer(Logger):
            """
            inherited by wallet
       t@@ -418,7 +426,7 @@ class AddressSynchronizer(Logger):
                return f
        
            @with_local_height_cached
       -    def get_history(self, domain=None):
       +    def get_history(self, domain=None) -> Sequence[HistoryItem]:
                # get domain
                if domain is None:
                    domain = self.get_addresses()
       t@@ -448,7 +456,11 @@ class AddressSynchronizer(Logger):
                balance = c + u + x
                h2 = []
                for tx_hash, tx_mined_status, delta, fee in history:
       -            h2.append((tx_hash, tx_mined_status, delta, fee, balance))
       +            h2.append(HistoryItem(txid=tx_hash,
       +                                  tx_mined_status=tx_mined_status,
       +                                  delta=delta,
       +                                  fee=fee,
       +                                  balance=balance))
                    if balance is None or delta is None:
                        balance = None
                    else:
   DIR diff --git a/electrum/gui/stdio.py b/electrum/gui/stdio.py
       t@@ -94,9 +94,9 @@ class ElectrumGui:
                + "%d"%(width[2]+delta)+"s"+"%"+"%d"%(width[3]+delta)+"s"
                messages = []
        
       -        for tx_hash, tx_mined_status, delta, balance in reversed(self.wallet.get_history()):
       -            if tx_mined_status.conf:
       -                timestamp = tx_mined_status.timestamp
       +        for hist_item in reversed(self.wallet.get_history()):
       +            if hist_item.tx_mined_status.conf:
       +                timestamp = hist_item.tx_mined_status.timestamp
                        try:
                            time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
                        except Exception:
       t@@ -104,8 +104,9 @@ class ElectrumGui:
                    else:
                        time_str = 'unconfirmed'
        
       -            label = self.wallet.get_label(tx_hash)
       -            messages.append( format_str%( time_str, label, format_satoshis(delta, whitespaces=True), format_satoshis(balance, whitespaces=True) ) )
       +            label = self.wallet.get_label(hist_item.txid)
       +            messages.append(format_str % (time_str, label, format_satoshis(delta, whitespaces=True),
       +                                          format_satoshis(hist_item.balance, whitespaces=True)))
        
                self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance")))
        
   DIR diff --git a/electrum/gui/text.py b/electrum/gui/text.py
       t@@ -117,9 +117,9 @@ class ElectrumGui:
        
                b = 0
                self.history = []
       -        for tx_hash, tx_mined_status, value, balance in self.wallet.get_history():
       -            if tx_mined_status.conf:
       -                timestamp = tx_mined_status.timestamp
       +        for hist_item in self.wallet.get_history():
       +            if hist_item.tx_mined_status.conf:
       +                timestamp = hist_item.tx_mined_status.timestamp
                        try:
                            time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
                        except Exception:
       t@@ -127,10 +127,11 @@ class ElectrumGui:
                    else:
                        time_str = 'unconfirmed'
        
       -            label = self.wallet.get_label(tx_hash)
       +            label = self.wallet.get_label(hist_item.txid)
                    if len(label) > 40:
                        label = label[0:37] + '...'
       -            self.history.append( format_str%( time_str, label, format_satoshis(value, whitespaces=True), format_satoshis(balance, whitespaces=True) ) )
       +            self.history.append(format_str % (time_str, label, format_satoshis(hist_item.value, whitespaces=True),
       +                                              format_satoshis(hist_item.balance, whitespaces=True)))
        
        
            def print_balance(self):
   DIR diff --git a/electrum/wallet.py b/electrum/wallet.py
       t@@ -482,26 +482,27 @@ class Abstract_Wallet(AddressSynchronizer):
                # we also assume that block timestamps are monotonic (which is false...!)
                h = self.get_history(domain)
                balance = 0
       -        for tx_hash, tx_mined_status, value, fee, balance in h:
       -            if tx_mined_status.timestamp is None or tx_mined_status.timestamp > target_timestamp:
       -                return balance - value
       +        for hist_item in h:
       +            balance = hist_item.balance
       +            if hist_item.tx_mined_status.timestamp is None or hist_item.tx_mined_status.timestamp > target_timestamp:
       +                return balance - hist_item.delta
                # return last balance
                return balance
        
            def get_onchain_history(self):
       -        for tx_hash, tx_mined_status, value, fee, balance in self.get_history():
       +        for hist_item in self.get_history():
                    yield {
       -                'txid': tx_hash,
       -                'fee_sat': fee,
       -                'height': tx_mined_status.height,
       -                'confirmations': tx_mined_status.conf,
       -                'timestamp': tx_mined_status.timestamp,
       -                'incoming': True if value>0 else False,
       -                'bc_value': Satoshis(value),
       -                'bc_balance': Satoshis(balance),
       -                'date': timestamp_to_datetime(tx_mined_status.timestamp),
       -                'label': self.get_label(tx_hash),
       -                'txpos_in_block': tx_mined_status.txpos,
       +                'txid': hist_item.tx_mined_status,
       +                'fee_sat': hist_item.fee,
       +                'height': hist_item.tx_mined_status.height,
       +                'confirmations': hist_item.tx_mined_status.conf,
       +                'timestamp': hist_item.tx_mined_status.timestamp,
       +                'incoming': True if hist_item.delta>0 else False,
       +                'bc_value': Satoshis(hist_item.delta),
       +                'bc_balance': Satoshis(hist_item.balance),
       +                'date': timestamp_to_datetime(hist_item.tx_mined_status.timestamp),
       +                'label': self.get_label(hist_item.txid),
       +                'txpos_in_block': hist_item.tx_mined_status.txpos,
                    }
        
            def save_invoice(self, invoice):
       t@@ -757,13 +758,18 @@ class Abstract_Wallet(AddressSynchronizer):
        
            def get_unconfirmed_base_tx_for_batching(self) -> Optional[Transaction]:
                candidate = None
       -        for tx_hash, tx_mined_status, delta, fee, balance in self.get_history():
       +        for hist_item in self.get_history():
                    # tx should not be mined yet
       -            if tx_mined_status.conf > 0: continue
       +            if hist_item.tx_mined_status.conf > 0: continue
       +            # conservative future proofing of code: only allow known unconfirmed types
       +            if hist_item.tx_mined_status.height not in (TX_HEIGHT_UNCONFIRMED,
       +                                                        TX_HEIGHT_UNCONF_PARENT,
       +                                                        TX_HEIGHT_LOCAL):
       +                continue
                    # tx should be "outgoing" from wallet
       -            if delta >= 0:
       +            if hist_item.delta >= 0:
                        continue
       -            tx = self.db.get_transaction(tx_hash)
       +            tx = self.db.get_transaction(hist_item.txid)
                    if not tx:
                        continue
                    # is_mine outputs should not be spent yet
       t@@ -776,7 +782,7 @@ class Abstract_Wallet(AddressSynchronizer):
                    if not all([self.is_mine(self.get_txin_address(txin)) for txin in tx.inputs()]):
                        continue
                    # prefer txns already in mempool (vs local)
       -            if tx_mined_status.height == TX_HEIGHT_LOCAL:
       +            if hist_item.tx_mined_status.height == TX_HEIGHT_LOCAL:
                        candidate = tx
                        continue
                    # tx must have opted-in for RBF