show unmatured coins in status bar. fixes #1163
This commit is contained in:
parent
4bce96526b
commit
687cc7783f
|
@ -410,9 +410,12 @@ def update_layout():
|
||||||
elif not wallet.up_to_date:
|
elif not wallet.up_to_date:
|
||||||
text = "Synchronizing..."
|
text = "Synchronizing..."
|
||||||
else:
|
else:
|
||||||
c, u = wallet.get_balance()
|
c, u, x = wallet.get_balance()
|
||||||
text = "Balance:"+format_satoshis(c)
|
text = "Balance:"+format_satoshis(c)
|
||||||
if u : text += ' [' + format_satoshis(u,True).strip() + ']'
|
if u:
|
||||||
|
text += ' [' + format_satoshis(u,True).strip() + ']'
|
||||||
|
if x:
|
||||||
|
text += ' [' + format_satoshis(x,True).strip() + ']'
|
||||||
|
|
||||||
|
|
||||||
# vibrate if status changed
|
# vibrate if status changed
|
||||||
|
|
13
gui/gtk.py
13
gui/gtk.py
|
@ -1122,9 +1122,12 @@ class ElectrumWindow:
|
||||||
text = "Synchronizing..."
|
text = "Synchronizing..."
|
||||||
else:
|
else:
|
||||||
self.status_image.set_from_stock(Gtk.STOCK_YES, Gtk.IconSize.MENU)
|
self.status_image.set_from_stock(Gtk.STOCK_YES, Gtk.IconSize.MENU)
|
||||||
c, u = self.wallet.get_balance()
|
c, u, x = self.wallet.get_balance()
|
||||||
text = "Balance: %s "%( format_satoshis(c,False,self.num_zeros) )
|
text = "Balance: %s "%(format_satoshis(c, False, self.num_zeros))
|
||||||
if u: text += "[%s unconfirmed]"%( format_satoshis(u,True,self.num_zeros).strip() )
|
if u:
|
||||||
|
text += "[%s unconfirmed]"%(format_satoshis(u, True, self.num_zeros).strip())
|
||||||
|
if x:
|
||||||
|
text += "[%s unmatured]"%(format_satoshis(x, True, self.num_zeros).strip())
|
||||||
else:
|
else:
|
||||||
self.status_image.set_from_stock(Gtk.STOCK_NO, Gtk.IconSize.MENU)
|
self.status_image.set_from_stock(Gtk.STOCK_NO, Gtk.IconSize.MENU)
|
||||||
self.network_button.set_tooltip_text("Not connected.")
|
self.network_button.set_tooltip_text("Not connected.")
|
||||||
|
@ -1148,13 +1151,13 @@ class ElectrumWindow:
|
||||||
if self.wallet.is_change(address): Type = "C"
|
if self.wallet.is_change(address): Type = "C"
|
||||||
if address in self.wallet.imported_keys.keys():
|
if address in self.wallet.imported_keys.keys():
|
||||||
Type = "I"
|
Type = "I"
|
||||||
c, u = self.wallet.get_addr_balance(address)
|
c, u, x = self.wallet.get_addr_balance(address)
|
||||||
if address in self.wallet.frozen_addresses: Type = Type + "F"
|
if address in self.wallet.frozen_addresses: Type = Type + "F"
|
||||||
label = self.wallet.labels.get(address)
|
label = self.wallet.labels.get(address)
|
||||||
h = self.wallet.history.get(address,[])
|
h = self.wallet.history.get(address,[])
|
||||||
n = len(h)
|
n = len(h)
|
||||||
tx = "0" if n==0 else "%d"%n
|
tx = "0" if n==0 else "%d"%n
|
||||||
self.recv_list.append((address, label, tx, format_satoshis(c,False,self.num_zeros), Type ))
|
self.recv_list.append((address, label, tx, format_satoshis(c+u+x, False, self.num_zeros), Type ))
|
||||||
|
|
||||||
def update_sending_tab(self):
|
def update_sending_tab(self):
|
||||||
self.addressbook_list.clear()
|
self.addressbook_list.clear()
|
||||||
|
|
|
@ -850,8 +850,8 @@ class MiniDriver(QObject):
|
||||||
self.window.activate()
|
self.window.activate()
|
||||||
|
|
||||||
def update_balance(self):
|
def update_balance(self):
|
||||||
conf_balance, unconf_balance = self.g.wallet.get_balance()
|
conf_balance, unconf_balance, x = self.g.wallet.get_balance()
|
||||||
balance = D(conf_balance + unconf_balance)
|
balance = D(conf_balance + unconf_balance + x)
|
||||||
self.window.set_balances(balance)
|
self.window.set_balances(balance)
|
||||||
|
|
||||||
def update_completions(self):
|
def update_completions(self):
|
||||||
|
|
|
@ -525,10 +525,12 @@ class ElectrumWindow(QMainWindow):
|
||||||
text = _("Server is lagging (%d blocks)"%server_lag)
|
text = _("Server is lagging (%d blocks)"%server_lag)
|
||||||
icon = QIcon(":icons/status_lagging.png")
|
icon = QIcon(":icons/status_lagging.png")
|
||||||
else:
|
else:
|
||||||
c, u = self.wallet.get_account_balance(self.current_account)
|
c, u, x = self.wallet.get_account_balance(self.current_account)
|
||||||
text = _( "Balance" ) + ": %s "%( self.format_amount(c) ) + self.base_unit()
|
text = _("Balance" ) + ": %s "%(self.format_amount(c)) + self.base_unit()
|
||||||
if u: text += " [%s unconfirmed]"%( self.format_amount(u,True).strip() )
|
if u:
|
||||||
|
text += " [%s unconfirmed]"%(self.format_amount(u, True).strip())
|
||||||
|
if x:
|
||||||
|
text += " [%s unmatured]"%(self.format_amount(x, True).strip())
|
||||||
# append fiat balance and price from exchange rate plugin
|
# append fiat balance and price from exchange rate plugin
|
||||||
r = {}
|
r = {}
|
||||||
run_hook('get_fiat_status_text', c+u, r)
|
run_hook('get_fiat_status_text', c+u, r)
|
||||||
|
@ -958,8 +960,9 @@ class ElectrumWindow(QMainWindow):
|
||||||
palette = QPalette()
|
palette = QPalette()
|
||||||
palette.setColor(self.amount_e.foregroundRole(), QColor('red'))
|
palette.setColor(self.amount_e.foregroundRole(), QColor('red'))
|
||||||
text = _( "Not enough funds" )
|
text = _( "Not enough funds" )
|
||||||
c, u = self.wallet.get_frozen_balance()
|
c, u, x = self.wallet.get_frozen_balance()
|
||||||
if c+u: text += ' (' + self.format_amount(c+u).strip() + ' ' + self.base_unit() + ' ' +_("are frozen") + ')'
|
if c+u+x:
|
||||||
|
text += ' (' + self.format_amount(c+u+x).strip() + ' ' + self.base_unit() + ' ' +_("are frozen") + ')'
|
||||||
self.statusBar().showMessage(text)
|
self.statusBar().showMessage(text)
|
||||||
self.amount_e.setPalette(palette)
|
self.amount_e.setPalette(palette)
|
||||||
self.fee_e.setPalette(palette)
|
self.fee_e.setPalette(palette)
|
||||||
|
@ -1030,7 +1033,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
menu.exec_(self.from_list.viewport().mapToGlobal(position))
|
menu.exec_(self.from_list.viewport().mapToGlobal(position))
|
||||||
|
|
||||||
def set_pay_from(self, domain = None):
|
def set_pay_from(self, domain = None):
|
||||||
self.pay_from = [] if domain == [] else self.wallet.get_unspent_coins(domain)
|
self.pay_from = [] if domain == [] else self.wallet.get_spendable_coins(domain)
|
||||||
self.redraw_from_list()
|
self.redraw_from_list()
|
||||||
|
|
||||||
def redraw_from_list(self):
|
def redraw_from_list(self):
|
||||||
|
@ -1438,7 +1441,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
domain = self.wallet.get_account_addresses(self.current_account)
|
domain = self.wallet.get_account_addresses(self.current_account)
|
||||||
for i in self.wallet.frozen_addresses:
|
for i in self.wallet.frozen_addresses:
|
||||||
if i in domain: domain.remove(i)
|
if i in domain: domain.remove(i)
|
||||||
return self.wallet.get_unspent_coins(domain)
|
return self.wallet.get_spendable_coins(domain)
|
||||||
|
|
||||||
|
|
||||||
def send_from_addresses(self, addrs):
|
def send_from_addresses(self, addrs):
|
||||||
|
@ -1554,8 +1557,8 @@ class ElectrumWindow(QMainWindow):
|
||||||
for k, account in account_items:
|
for k, account in account_items:
|
||||||
if len(accounts) > 1:
|
if len(accounts) > 1:
|
||||||
name = self.wallet.get_account_name(k)
|
name = self.wallet.get_account_name(k)
|
||||||
c, u = self.wallet.get_account_balance(k)
|
c, u, x = self.wallet.get_account_balance(k)
|
||||||
account_item = QTreeWidgetItem( [ name, '', self.format_amount(c+u), ''] )
|
account_item = QTreeWidgetItem([ name, '', self.format_amount(c + u + x), ''])
|
||||||
l.addTopLevelItem(account_item)
|
l.addTopLevelItem(account_item)
|
||||||
account_item.setExpanded(self.accounts_expanded.get(k, True))
|
account_item.setExpanded(self.accounts_expanded.get(k, True))
|
||||||
account_item.setData(0, Qt.UserRole, k)
|
account_item.setData(0, Qt.UserRole, k)
|
||||||
|
@ -1577,8 +1580,8 @@ class ElectrumWindow(QMainWindow):
|
||||||
for address in addr_list:
|
for address in addr_list:
|
||||||
num, is_used = self.wallet.is_used(address)
|
num, is_used = self.wallet.is_used(address)
|
||||||
label = self.wallet.labels.get(address,'')
|
label = self.wallet.labels.get(address,'')
|
||||||
c, u = self.wallet.get_addr_balance(address)
|
c, u, x = self.wallet.get_addr_balance(address)
|
||||||
balance = self.format_amount(c + u)
|
balance = self.format_amount(c + u + x)
|
||||||
item = QTreeWidgetItem( [ address, label, balance, "%d"%num] )
|
item = QTreeWidgetItem( [ address, label, balance, "%d"%num] )
|
||||||
item.setFont(0, QFont(MONOSPACE_FONT))
|
item.setFont(0, QFont(MONOSPACE_FONT))
|
||||||
item.setData(0, Qt.UserRole, address)
|
item.setData(0, Qt.UserRole, address)
|
||||||
|
|
|
@ -124,9 +124,12 @@ class ElectrumGui:
|
||||||
if not self.wallet.up_to_date:
|
if not self.wallet.up_to_date:
|
||||||
msg = _( "Synchronizing..." )
|
msg = _( "Synchronizing..." )
|
||||||
else:
|
else:
|
||||||
c, u = self.wallet.get_balance()
|
c, u, x = self.wallet.get_balance()
|
||||||
msg = _("Balance")+": %f "%(Decimal( c ) / 100000000)
|
msg = _("Balance")+": %f "%(Decimal(c) / 100000000)
|
||||||
if u: msg += " [%f unconfirmed]"%(Decimal( u ) / 100000000)
|
if u:
|
||||||
|
msg += " [%f unconfirmed]"%(Decimal(u) / 100000000)
|
||||||
|
if x:
|
||||||
|
msg += " [%f unmatured]"%(Decimal(x) / 100000000)
|
||||||
else:
|
else:
|
||||||
msg = _( "Not connected" )
|
msg = _( "Not connected" )
|
||||||
|
|
||||||
|
|
|
@ -132,9 +132,12 @@ class ElectrumGui:
|
||||||
if not self.wallet.up_to_date:
|
if not self.wallet.up_to_date:
|
||||||
msg = _("Synchronizing...")
|
msg = _("Synchronizing...")
|
||||||
else:
|
else:
|
||||||
c, u = self.wallet.get_balance()
|
c, u, x = self.wallet.get_balance()
|
||||||
msg = _("Balance")+": %f "%(Decimal( c ) / 100000000)
|
msg = _("Balance")+": %f "%(Decimal(c) / 100000000)
|
||||||
if u: msg += " [%f unconfirmed]"%(Decimal( u ) / 100000000)
|
if u:
|
||||||
|
msg += " [%f unconfirmed]"%(Decimal(u) / 100000000)
|
||||||
|
if x:
|
||||||
|
msg += " [%f unmatured]"%(Decimal(x) / 100000000)
|
||||||
else:
|
else:
|
||||||
msg = _("Not connected")
|
msg = _("Not connected")
|
||||||
|
|
||||||
|
|
|
@ -231,12 +231,14 @@ class Commands:
|
||||||
|
|
||||||
def getbalance(self, account= None):
|
def getbalance(self, account= None):
|
||||||
if account is None:
|
if account is None:
|
||||||
c, u = self.wallet.get_balance()
|
c, u, x = self.wallet.get_balance()
|
||||||
else:
|
else:
|
||||||
c, u = self.wallet.get_account_balance(account)
|
c, u, x = self.wallet.get_account_balance(account)
|
||||||
|
out = {"confirmed": str(Decimal(c)/100000000)}
|
||||||
out = { "confirmed": str(Decimal(c)/100000000) }
|
if u:
|
||||||
if u: out["unconfirmed"] = str(Decimal(u)/100000000)
|
out["unconfirmed"] = str(Decimal(u)/100000000)
|
||||||
|
if x:
|
||||||
|
out["unmatured"] = str(Decimal(x)/100000000)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def getaddressbalance(self, addr):
|
def getaddressbalance(self, addr):
|
||||||
|
|
|
@ -480,19 +480,21 @@ class Abstract_Wallet(object):
|
||||||
coins, spent = self.get_addr_io(address)
|
coins, spent = self.get_addr_io(address)
|
||||||
for txi in spent:
|
for txi in spent:
|
||||||
coins.pop(txi)
|
coins.pop(txi)
|
||||||
return coins.items()
|
return coins
|
||||||
|
|
||||||
# return the total amount ever received by an address
|
# return the total amount ever received by an address
|
||||||
def get_addr_received(self, address):
|
def get_addr_received(self, address):
|
||||||
received, sent = self.get_addr_io(address)
|
received, sent = self.get_addr_io(address)
|
||||||
return sum([v for height, v, is_cb in received.values()])
|
return sum([v for height, v, is_cb in received.values()])
|
||||||
|
|
||||||
# return the confirmed balance and pending (unconfirmed) balance change of a bitcoin address
|
# return the balance of a bitcoin address: confirmed and matured, unconfirmed, unmatured
|
||||||
def get_addr_balance(self, address):
|
def get_addr_balance(self, address):
|
||||||
received, sent = self.get_addr_io(address)
|
received, sent = self.get_addr_io(address)
|
||||||
c = u = 0
|
c = u = x = 0
|
||||||
for txo, (tx_height, v, is_cb) in received.items():
|
for txo, (tx_height, v, is_cb) in received.items():
|
||||||
if tx_height > 0:
|
if is_cb and tx_height + COINBASE_MATURITY > self.network.get_local_height():
|
||||||
|
x += v
|
||||||
|
elif tx_height > 0:
|
||||||
c += v
|
c += v
|
||||||
else:
|
else:
|
||||||
u += v
|
u += v
|
||||||
|
@ -501,17 +503,19 @@ class Abstract_Wallet(object):
|
||||||
c -= v
|
c -= v
|
||||||
else:
|
else:
|
||||||
u -= v
|
u -= v
|
||||||
return c, u
|
return c, u, x
|
||||||
|
|
||||||
|
|
||||||
def get_unspent_coins(self, domain=None):
|
def get_spendable_coins(self, domain=None):
|
||||||
coins = []
|
coins = []
|
||||||
if domain is None:
|
if domain is None:
|
||||||
domain = self.addresses(True)
|
domain = self.addresses(True)
|
||||||
for addr in domain:
|
for addr in domain:
|
||||||
c = self.get_addr_utxo(addr)
|
c = self.get_addr_utxo(addr)
|
||||||
for txo, v in c:
|
for txo, v in c.items():
|
||||||
tx_height, value, is_cb = v
|
tx_height, value, is_cb = v
|
||||||
|
if is_cb and tx_height + COINBASE_MATURITY > self.network.get_local_height():
|
||||||
|
continue
|
||||||
prevout_hash, prevout_n = txo.split(':')
|
prevout_hash, prevout_n = txo.split(':')
|
||||||
output = {
|
output = {
|
||||||
'address':addr,
|
'address':addr,
|
||||||
|
@ -564,13 +568,15 @@ class Abstract_Wallet(object):
|
||||||
return self.get_balance(self.frozen_addresses)
|
return self.get_balance(self.frozen_addresses)
|
||||||
|
|
||||||
def get_balance(self, domain=None):
|
def get_balance(self, domain=None):
|
||||||
if domain is None: domain = self.addresses(True)
|
if domain is None:
|
||||||
cc = uu = 0
|
domain = self.addresses(True)
|
||||||
|
cc = uu = xx = 0
|
||||||
for addr in domain:
|
for addr in domain:
|
||||||
c, u = self.get_addr_balance(addr)
|
c, u, x = self.get_addr_balance(addr)
|
||||||
cc += c
|
cc += c
|
||||||
uu += u
|
uu += u
|
||||||
return cc, uu
|
xx += x
|
||||||
|
return cc, uu, xx
|
||||||
|
|
||||||
def set_fee(self, fee):
|
def set_fee(self, fee):
|
||||||
if self.fee_per_kb != fee:
|
if self.fee_per_kb != fee:
|
||||||
|
@ -597,7 +603,7 @@ class Abstract_Wallet(object):
|
||||||
return addr
|
return addr
|
||||||
|
|
||||||
def add_transaction(self, tx_hash, tx, tx_height):
|
def add_transaction(self, tx_hash, tx, tx_height):
|
||||||
is_coinbase = tx.inputs[0].get('prevout_hash') == '0'*64
|
is_coinbase = tx.inputs[0].get('is_coinbase') == True
|
||||||
with self.transaction_lock:
|
with self.transaction_lock:
|
||||||
# add inputs
|
# add inputs
|
||||||
self.txi[tx_hash] = d = {}
|
self.txi[tx_hash] = d = {}
|
||||||
|
@ -734,8 +740,8 @@ class Abstract_Wallet(object):
|
||||||
history.reverse()
|
history.reverse()
|
||||||
|
|
||||||
# 3. add balance
|
# 3. add balance
|
||||||
c, u = self.get_balance(domain)
|
c, u, x = self.get_balance(domain)
|
||||||
balance = c + u
|
balance = c + u + x
|
||||||
h2 = []
|
h2 = []
|
||||||
for item in history:
|
for item in history:
|
||||||
tx_hash, conf, delta, timestamp = item
|
tx_hash, conf, delta, timestamp = item
|
||||||
|
@ -793,16 +799,15 @@ class Abstract_Wallet(object):
|
||||||
if domain is None:
|
if domain is None:
|
||||||
domain = self.addresses(True)
|
domain = self.addresses(True)
|
||||||
for i in self.frozen_addresses:
|
for i in self.frozen_addresses:
|
||||||
if i in domain: domain.remove(i)
|
if i in domain:
|
||||||
coins = self.get_unspent_coins(domain)
|
domain.remove(i)
|
||||||
|
coins = self.get_spendable_coins(domain)
|
||||||
|
|
||||||
amount = sum( map(lambda x:x[2], outputs) )
|
amount = sum(map(lambda x:x[2], outputs))
|
||||||
total = fee = 0
|
total = fee = 0
|
||||||
inputs = []
|
inputs = []
|
||||||
tx = Transaction.from_io(inputs, outputs)
|
tx = Transaction.from_io(inputs, outputs)
|
||||||
for item in coins:
|
for item in coins:
|
||||||
if item.get('coinbase') and item.get('height') + COINBASE_MATURITY > self.network.get_local_height():
|
|
||||||
continue
|
|
||||||
v = item.get('value')
|
v = item.get('value')
|
||||||
total += v
|
total += v
|
||||||
self.add_input_info(item)
|
self.add_input_info(item)
|
||||||
|
@ -1066,7 +1071,7 @@ class Abstract_Wallet(object):
|
||||||
|
|
||||||
def is_used(self, address):
|
def is_used(self, address):
|
||||||
h = self.history.get(address,[])
|
h = self.history.get(address,[])
|
||||||
c, u = self.get_addr_balance(address)
|
c, u, x = self.get_addr_balance(address)
|
||||||
return len(h), len(h) > 0 and c == -u
|
return len(h), len(h) > 0 and c == -u
|
||||||
|
|
||||||
def address_is_old(self, address, age_limit=2):
|
def address_is_old(self, address, age_limit=2):
|
||||||
|
|
Loading…
Reference in New Issue