URI: 
       tdo not include fee in the transaction amount shown in history. adapt history to the case where it was recovered from a pruning server - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 650a9b6074d3248a9146548e59cb98a639311872
   DIR parent 8ec2b16e218c47d0932d80e3bf225207f9ffdc23
  HTML Author: thomasv <thomasv@gitorious>
       Date:   Fri, 16 Nov 2012 14:39:31 +0100
       
       do not include fee in the transaction amount shown in history. adapt history to the case where it was recovered from a pruning server
       
       Diffstat:
         M electrum                            |      23 ++++++++++-------------
         M lib/gui.py                          |      37 ++++++++++---------------------
         M lib/gui_lite.py                     |      11 ++++++-----
         M lib/gui_qt.py                       |      59 +++++++++++++------------------
         M lib/gui_text.py                     |      20 ++++++++++----------
         M lib/history_widget.py               |       6 +-----
         M lib/wallet.py                       |     116 +++++++++++++++++++++++++++----
       
       7 files changed, 164 insertions(+), 108 deletions(-)
       ---
   DIR diff --git a/electrum b/electrum
       t@@ -484,23 +484,20 @@ if __name__ == '__main__':
                        print flags, m_addr, b, label
        
            if cmd == 'history':
       -        lines = wallet.get_tx_history()
       -        b = 0 
       -        for line in lines:
       -            import datetime
       -            v = wallet.get_tx_value(line['tx_hash'])
       -            b += v
       +        import datetime
       +        for item in wallet.get_tx_history():
       +            tx_hash, conf, is_mine, value, fee, balance, timestamp = item
                    try:
       -                time_str = str( datetime.datetime.fromtimestamp( line['timestamp']))
       +                time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3]
                    except:
       -                print line['timestamp']
       -                time_str = 'pending'
       -            label = line.get('label')
       -            if not label: label = line['tx_hash']
       +                time_str = "----"
       +
       +            label, is_default_label = wallet.get_label(tx_hash)
       +            if not label: label = tx_hash
                    else: label = label + ' '*(64 - len(label) )
        
       -            print time_str , "  " + label + "  " + format_satoshis(v)+ "  "+ format_satoshis(b)
       -        print "# balance: ", format_satoshis(b)
       +            print "%17s"%time_str, "  " + label + "  " + format_satoshis(value)+ "  "+ format_satoshis(balance)
       +        print "# balance: ", format_satoshis(balance)
        
            elif cmd == 'label':
                try:
   DIR diff --git a/lib/gui.py b/lib/gui.py
       t@@ -1223,39 +1223,26 @@ class ElectrumWindow:
            def update_history_tab(self):
                cursor = self.history_treeview.get_cursor()[0]
                self.history_list.clear()
       -        balance = 0 
       -        for tx in self.wallet.get_tx_history():
       -            tx_hash = tx['tx_hash']
       -            conf = self.wallet.verifier.get_confirmations(tx_hash)
       +
       +        for item in self.wallet.get_tx_history():
       +            tx_hash, conf, is_mine, value, fee, balance, timestamp = item
                    if conf:
       -                time_str = datetime.datetime.fromtimestamp( tx['timestamp']).isoformat(' ')[:-3]
       +                try:
       +                    time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3]
       +                except:
       +                    time_str = "------"
                        conf_icon = gtk.STOCK_APPLY
                    else:
                        time_str = 'pending'
                        conf_icon = gtk.STOCK_EXECUTE
       -            v = self.wallet.get_tx_value(tx_hash)
       -            balance += v 
       +
                    label, is_default_label = self.wallet.get_label(tx_hash)
       -            tooltip = tx_hash + "\n%d confirmations"%conf 
       -
       -            inputs = map(lambda x: x.get('address'), tx['inputs'])
       -            outputs = map(lambda x: x.get('address'), tx['outputs'])
       -            details = "Transaction Details:\n\n" \
       -                      + "Transaction ID:\n" + tx_hash + "\n\n" \
       -                      + "Status: %d confirmations\n\n"%conf  \
       -                      + "Date: %s\n\n"%time_str \
       -                      + "Inputs:\n-"+ '\n-'.join(inputs) + "\n\n" \
       -                      + "Outputs:\n-"+ '\n-'.join(outputs)
       -            r = self.wallet.receipts.get(tx_hash)
       -            if r:
       -                details += "\n_______________________________________" \
       -                           + '\n\nSigned URI: ' + r[2] \
       -                           + "\n\nSigned by: " + r[0] \
       -                           + '\n\nSignature: ' + r[1]
       -                
       +            tooltip = tx_hash + "\n%d confirmations"%conf if tx_hash else ''
       +            details = self.wallet.get_tx_details(tx_hash)
        
                    self.history_list.prepend( [tx_hash, conf_icon, time_str, label, is_default_label,
       -                                        format_satoshis(v,True,self.wallet.num_zeros), format_satoshis(balance,False,self.wallet.num_zeros), tooltip, details] )
       +                                        format_satoshis(value,True,self.wallet.num_zeros),
       +                                        format_satoshis(balance,False,self.wallet.num_zeros), tooltip, details] )
                if cursor: self.history_treeview.set_cursor( cursor )
        
        
   DIR diff --git a/lib/gui_lite.py b/lib/gui_lite.py
       t@@ -438,12 +438,13 @@ class MiniWindow(QDialog):
                self.address_completions.setStringList(completions)
        
            def update_history(self, tx_history):
       -        for tx in tx_history[-10:]:
       -            tx_hash = tx['tx_hash']
       +        from util import format_satoshis
       +        for item in tx_history[-10:]:
       +            tx_hash, conf, is_mine, value, fee, balance, timestamp = item
                    label = self.actuator.wallet.get_label(tx_hash)[0]
       -            value = self.actuator.wallet.get_tx_value(tx_hash)
       -            amount = D(value) / 10**8
       -            self.history_list.append(label, amount)
       +            #amount = D(value) / 10**8
       +            v_str = format_satoshis(value, True)
       +            self.history_list.append(label, v_str)
        
            def acceptbit(self):
                self.actuator.acceptbit(self.quote_currencies[0])
   DIR diff --git a/lib/gui_qt.py b/lib/gui_qt.py
       t@@ -323,38 +323,16 @@ class ElectrumWindow(QMainWindow):
                item = self.history_list.currentItem()
                if not item: return
                tx_hash = str(item.toolTip(0))
       +        if not tx_hash: return
                menu = QMenu()
                menu.addAction(_("Copy ID to Clipboard"), lambda: self.app.clipboard().setText(tx_hash))
                menu.addAction(_("Details"), lambda: self.tx_details(tx_hash))
                menu.addAction(_("Edit description"), lambda: self.tx_label_clicked(item,2))
                menu.exec_(self.contacts_list.viewport().mapToGlobal(position))
        
       -    def tx_details(self, tx_hash):
       -        tx = self.wallet.transactions.get(tx_hash)
       -
       -        conf = self.wallet.verifier.get_confirmations(tx_hash)
       -        timestamp = tx.get('timestamp')
       -        if conf and timestamp:
       -            time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
       -        else:
       -            time_str = 'pending'
       -
       -        inputs = map(lambda x: x.get('address'), tx['inputs'])
       -        outputs = map(lambda x: x.get('address'), tx['outputs'])
       -        tx_details = _("Transaction Details") +"\n\n" \
       -            + "Transaction ID:\n" + tx_hash + "\n\n" \
       -            + "Status: %d confirmations\n\n"%conf  \
       -            + "Date: %s\n\n"%time_str \
       -            + "Inputs:\n-"+ '\n-'.join(inputs) + "\n\n" \
       -            + "Outputs:\n-"+ '\n-'.join(outputs)
       -
       -        r = self.wallet.receipts.get(tx_hash)
       -        if r:
       -            tx_details += "\n_______________________________________" \
       -                + '\n\nSigned URI: ' + r[2] \
       -                + "\n\nSigned by: " + r[0] \
       -                + '\n\nSignature: ' + r[1]
        
       +    def tx_details(self, tx_hash):
       +        tx_details = self.wallet.get_tx_details(tx_hash)
                QMessageBox.information(self, 'Details', tx_details, 'OK')
        
        
       t@@ -432,14 +410,13 @@ class ElectrumWindow(QMainWindow):
        
        
            def update_history_tab(self):
       +
                self.history_list.clear()
       -        balance = 0
       -        for tx in self.wallet.get_tx_history():
       -            tx_hash = tx['tx_hash']
       -            conf = self.wallet.verifier.get_confirmations(tx_hash)
       +        for item in self.wallet.get_tx_history():
       +            tx_hash, conf, is_mine, value, fee, balance, timestamp = item
                    if conf:
                        try:
       -                    time_str = datetime.datetime.fromtimestamp( tx['timestamp']).isoformat(' ')[:-3]
       +                    time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3]
                        except:
                            time_str = "unknown"
                        if conf == -1:
       t@@ -453,20 +430,32 @@ class ElectrumWindow(QMainWindow):
                    else:
                        time_str = 'pending'
                        icon = QIcon(":icons/unconfirmed.png")
       -            v = self.wallet.get_tx_value(tx_hash)
       -            balance += v 
       -            label, is_default_label = self.wallet.get_label(tx_hash)
        
       -            item = QTreeWidgetItem( [ '', time_str, label, format_satoshis(v,True,self.wallet.num_zeros), format_satoshis(balance,False,self.wallet.num_zeros)] )
       +            if value is not None:
       +                v_str = format_satoshis(value, True, self.wallet.num_zeros)
       +            else:
       +                v_str = '--'
       +
       +            balance_str = format_satoshis(balance, False, self.wallet.num_zeros)
       +            
       +            if tx_hash:
       +                label, is_default_label = self.wallet.get_label(tx_hash)
       +            else:
       +                label = _('Pruned transaction outputs')
       +                is_default_label = False
       +
       +            item = QTreeWidgetItem( [ '', time_str, label, v_str, balance_str] )
                    item.setFont(2, QFont(MONOSPACE_FONT))
                    item.setFont(3, QFont(MONOSPACE_FONT))
                    item.setFont(4, QFont(MONOSPACE_FONT))
       -            item.setToolTip(0, tx_hash)
       +            if tx_hash:
       +                item.setToolTip(0, tx_hash)
                    if is_default_label:
                        item.setForeground(2, QBrush(QColor('grey')))
        
                    item.setIcon(0, icon)
                    self.history_list.insertTopLevelItem(0,item)
       +            
        
                self.history_list.setCurrentItem(self.history_list.topLevelItem(0))
        
   DIR diff --git a/lib/gui_text.py b/lib/gui_text.py
       t@@ -66,19 +66,19 @@ class ElectrumGui:
        
                b = 0 
                messages = []
       -        for tx in self.wallet.get_tx_history():
       -            v = self.wallet.get_tx_value(tx['tx_hash'])
       -            b += v
       -            try:
       -                time_str = str( datetime.datetime.fromtimestamp( tx['timestamp']))
       -            except:
       -                print tx['timestamp']
       +
       +        for item in self.wallet.get_tx_history():
       +            tx_hash, conf, is_mine, value, fee, balance, timestamp = item
       +            if conf:
       +                try:
       +                    time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3]
       +                except:
       +                    time_str = "------"
       +            else:
                        time_str = 'pending'
       -            tx_hash = tx['tx_hash']
        
                    label, is_default_label = self.wallet.get_label(tx_hash)
       -            #label += ' '*(40 - len(label) )
       -            messages.append( format_str%( time_str, label, format_satoshis(v), format_satoshis(b) ) )
       +            messages.append( format_str%( time_str, label, format_satoshis(value), format_satoshis(balance) ) )
        
                self.print_list(messages[::-1], format_str%( _("Date"), _("Description"), _("Amount"), _("Balance")))
        
   DIR diff --git a/lib/history_widget.py b/lib/history_widget.py
       t@@ -10,10 +10,6 @@ class HistoryWidget(QTreeWidget):
                self.setIndentation(0)
        
            def append(self, address, amount):
       -        if amount >= 0:
       -            display_amount = "+%s" % amount
       -        else:
       -            display_amount = "-%s" % (-amount)
       -        item = QTreeWidgetItem([display_amount, address])
       +        item = QTreeWidgetItem([amount, address])
                self.insertTopLevelItem(0, item)
        
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -76,7 +76,7 @@ class Wallet:
                self.transactions          = config.get('transactions',{})        # txid -> deserialised
        
                # not saved
       -        self.prevout_values = {}
       +        self.prevout_values = {}     # my own transaction outputs
                self.spent_outputs = []
                self.receipt = None          # next receipt
                self.banner = ''
       t@@ -355,7 +355,8 @@ class Wallet:
        
            def fill_addressbook(self):
                for tx_hash, tx in self.transactions.items():
       -            if self.get_tx_value(tx_hash)<0:
       +            is_send, _, _ = self.get_tx_value(tx_hash)
       +            if is_send:
                        for o in tx['outputs']:
                            addr = o.get('address')
                            if not self.is_mine(addr) and addr not in self.addressbook:
       t@@ -374,24 +375,79 @@ class Wallet:
                # return the balance for that tx
                if addresses is None: addresses = self.all_addresses()
                with self.lock:
       -            v = 0
       +            is_send = False
       +            is_pruned = False
       +            v_in = v_out = v = 0
                    d = self.transactions.get(tx_hash)
                    if not d: return 0
                    for item in d.get('inputs'):
                        addr = item.get('address')
                        if addr in addresses:
       +                    is_send = True
                            key = item['prevout_hash']  + ':%d'%item['prevout_n']
                            value = self.prevout_values.get( key )
       -                    if value is None: continue
       +                    if value is None:
       +                        is_pruned = True
       +                        break
       +
                            v -= value
       +                    v_in += value
       +
       +            if is_pruned: v = 0
                    for item in d.get('outputs'):
                        addr = item.get('address')
       -                if addr in addresses: 
       -                    value = item.get('value')
       -                    v += value 
       -            return v
       +                value = item.get('value')
       +                v_out += value
       +                if not is_pruned:
       +                    if addr in addresses: v += value
       +                else:
       +                    if addr not in addresses: v -= value
       +
       +            # I can compute the fee only if I am the spender and inputs were not pruned
       +            fee = v_in - v_out if is_send and not is_pruned else None
       +            return is_send, v, fee
        
        
       +    def get_tx_details(self, tx_hash):
       +        import datetime
       +        if not tx_hash: return ''
       +        tx = self.transactions.get(tx_hash)
       +        is_mine, v, fee = self.get_tx_value(tx_hash)
       +        conf = self.verifier.get_confirmations(tx_hash)
       +        timestamp = tx.get('timestamp')
       +        if conf and timestamp:
       +            time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
       +        else:
       +            time_str = 'pending'
       +
       +        inputs = map(lambda x: x.get('address'), tx['inputs'])
       +        outputs = map(lambda x: x.get('address'), tx['outputs'])
       +        tx_details = "Transaction Details" +"\n\n" \
       +            + "Transaction ID:\n" + tx_hash + "\n\n" \
       +            + "Status: %d confirmations\n"%conf
       +        if is_mine:
       +            if fee: 
       +                tx_details += "Amount sent: %s\n"% format_satoshis(v+fee, False) \
       +                              + "Transaction fee: %s\n"% format_satoshis(fee, False)
       +            else:
       +                tx_details += "Amount sent: %s\n"% format_satoshis(v, False) \
       +                              + "Transaction fee: unknown\n"
       +        else:
       +            tx_details += "Amount received: %s\n"% format_satoshis(v, False) \
       +
       +        tx_details += "Date: %s\n\n"%time_str \
       +            + "Inputs:\n-"+ '\n-'.join(inputs) + "\n\n" \
       +            + "Outputs:\n-"+ '\n-'.join(outputs)
       +
       +        r = self.receipts.get(tx_hash)
       +        if r:
       +            tx_details += "\n_______________________________________" \
       +                + '\n\nSigned URI: ' + r[2] \
       +                + "\n\nSigned by: " + r[0] \
       +                + '\n\nSignature: ' + r[1]
       +
       +        return tx_details
       +
            
            def update_tx_outputs(self, tx_hash):
                tx = self.transactions.get(tx_hash)
       t@@ -412,8 +468,13 @@ class Wallet:
                h = self.history.get(addr,[])
                if h == ['*']: return 0,0
                c = u = 0
       +
                for tx_hash, tx_height in h:
       -            v = self.get_tx_value(tx_hash, [addr])
       +            # if the tx is mine, then I know its outputs and input values
       +            # if it is not mine, I only need its outputs
       +            is_mine, v, fee = self.get_tx_value(tx_hash, [addr])
       +            if v is None:raise
       +
                    if tx_height:
                        c += v
                    else:
       t@@ -455,7 +516,6 @@ class Wallet:
                            output['tx_hash'] = tx_hash
                            coins.append(output)
        
       -        #coins = sorted( coins, key = lambda x: x[1]['timestamp'] )
        
                for addr in self.prioritized_addresses:
                    h = self.history.get(addr, [])
       t@@ -468,7 +528,6 @@ class Wallet:
                            output['tx_hash'] = tx_hash
                            prioritized_coins.append(output)
        
       -        #prioritized_coins = sorted( prioritized_coins, key = lambda x: x[1]['timestamp'] )
        
                inputs = []
                coins = prioritized_coins + coins
       t@@ -584,9 +643,35 @@ class Wallet:
        
            def get_tx_history(self):
                with self.lock:
       -            lines = self.transactions.values()
       -        lines.sort(key = lambda x: x.get('timestamp') if x.get('timestamp') else 1e12)
       -        return lines
       +            history = self.transactions.values()
       +        history.sort(key = lambda x: x.get('timestamp') if x.get('timestamp') else 1e12)
       +        result = []
       +    
       +        balance = 0
       +        for tx in history:
       +            is_mine, v, fee = self.get_tx_value(tx['tx_hash'])
       +            if v is not None: balance += v
       +        c, u = self.get_balance()
       +
       +        if balance != c+u:
       +            v_str = format_satoshis( c+u - balance, True, self.num_zeros)
       +            result.append( ('', 1000, 0, c+u-balance, None, c+u-balance, None ) )
       +
       +        balance = c + u - balance
       +        for tx in history:
       +            tx_hash = tx['tx_hash']
       +            timestamp = tx.get('timestamp')
       +            conf = self.verifier.get_confirmations(tx_hash) if self.verifier else None
       +            is_mine, v, fee = self.get_tx_value(tx_hash)
       +            if v is not None:
       +                balance += v
       +                value = v + fee if fee is not None else v
       +            else:
       +                value = None
       +
       +            result.append( (tx_hash, conf, is_mine, value, fee, balance, timestamp) )
       +
       +        return result
        
            def get_transactions_at_height(self, height):
                with self.lock:
       t@@ -609,7 +694,8 @@ class Wallet:
                tx = self.transactions.get(tx_hash)
                if tx:
                    default_label = ''
       -            if self.get_tx_value(tx_hash)<0:
       +            is_mine, _, _ = self.get_tx_value(tx_hash)
       +            if is_mine:
                        for o in tx['outputs']:
                            o_addr = o.get('address')
                            if not self.is_mine(o_addr):