detect non-final transactions, and transactions with unconfirmed inputs
This commit is contained in:
@@ -109,10 +109,12 @@ class TxDialog(Factory.Popup):
|
||||
self.tx_hash = self.tx.hash()
|
||||
self.description = self.wallet.get_label(self.tx_hash)
|
||||
if self.tx_hash in self.wallet.transactions.keys():
|
||||
conf, timestamp = self.wallet.get_confirmations(self.tx_hash)
|
||||
self.status_str = _("%d confirmations")%conf if conf else _('Pending')
|
||||
if timestamp:
|
||||
height, conf, timestamp = self.wallet.get_tx_height(self.tx_hash)
|
||||
if conf:
|
||||
self.status_str = _("%d confirmations")%conf
|
||||
self.date_str = datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
||||
else:
|
||||
self.status_str = _('Unconfirmed')
|
||||
else:
|
||||
self.can_broadcast = self.app.network is not None
|
||||
self.status_str = _('Signed')
|
||||
|
||||
@@ -118,19 +118,25 @@ class HistoryScreen(CScreen):
|
||||
|
||||
def parse_history(self, items):
|
||||
for item in items:
|
||||
tx_hash, conf, value, timestamp, balance = item
|
||||
time_str = _("unknown")
|
||||
if conf > 0:
|
||||
try:
|
||||
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
||||
except Exception:
|
||||
time_str = _("error")
|
||||
if conf == -1:
|
||||
time_str = _('Not Verified')
|
||||
tx_hash, height, conf, timestamp, value, balance = item
|
||||
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] if timestamp else _("unknown")
|
||||
if conf == 0:
|
||||
tx = self.app.wallet.transactions.get(tx_hash)
|
||||
is_final = tx.is_final()
|
||||
else:
|
||||
is_final = True
|
||||
if not is_final:
|
||||
time_str = _('Replaceable')
|
||||
icon = "atlas://gui/kivy/theming/light/close"
|
||||
elif conf == 0:
|
||||
elif height < 0:
|
||||
time_str = _('Unconfirmed inputs')
|
||||
icon = "atlas://gui/kivy/theming/light/close"
|
||||
elif height == 0:
|
||||
time_str = _('Unconfirmed')
|
||||
icon = "atlas://gui/kivy/theming/light/unconfirmed"
|
||||
elif conf == 0:
|
||||
time_str = _('Not Verified')
|
||||
icon = "atlas://gui/kivy/theming/light/close"
|
||||
elif conf < 6:
|
||||
conf = max(1, conf)
|
||||
icon = "atlas://gui/kivy/theming/light/clock{}".format(conf)
|
||||
|
||||
@@ -45,15 +45,19 @@ class HistoryList(MyTreeWidget):
|
||||
run_hook('history_tab_headers', headers)
|
||||
self.update_headers(headers)
|
||||
|
||||
def get_icon(self, conf, timestamp):
|
||||
time_str = _("unknown")
|
||||
if conf > 0:
|
||||
time_str = format_time(timestamp)
|
||||
if conf == -1:
|
||||
time_str = _('Not Verified')
|
||||
def get_icon(self, height, conf, timestamp, is_final):
|
||||
time_str = format_time(timestamp) if timestamp else _("unknown")
|
||||
if not is_final:
|
||||
time_str = _('Replaceable')
|
||||
icon = QIcon(":icons/warning.png")
|
||||
elif height < 0:
|
||||
time_str = _('Unconfirmed inputs')
|
||||
icon = QIcon(":icons/warning.png")
|
||||
elif height == 0:
|
||||
time_str = _('Unconfirmed')
|
||||
icon = QIcon(":icons/unconfirmed.png")
|
||||
elif conf == 0:
|
||||
time_str = _('Unconfirmed')
|
||||
time_str = _('Not Verified')
|
||||
icon = QIcon(":icons/unconfirmed.png")
|
||||
elif conf < 6:
|
||||
icon = QIcon(":icons/clock%d.png"%conf)
|
||||
@@ -68,17 +72,18 @@ class HistoryList(MyTreeWidget):
|
||||
def on_update(self):
|
||||
self.wallet = self.parent.wallet
|
||||
h = self.wallet.get_history(self.get_domain())
|
||||
|
||||
item = self.currentItem()
|
||||
current_tx = item.data(0, Qt.UserRole).toString() if item else None
|
||||
self.clear()
|
||||
run_hook('history_tab_update_begin')
|
||||
for h_item in h:
|
||||
tx_hash, conf, value, timestamp, balance = h_item
|
||||
if conf is None and timestamp is None:
|
||||
continue # skip history in offline mode
|
||||
|
||||
icon, time_str = self.get_icon(conf, timestamp)
|
||||
tx_hash, height, conf, timestamp, value, balance = h_item
|
||||
if conf == 0:
|
||||
tx = self.wallet.transactions.get(tx_hash)
|
||||
is_final = tx.is_final()
|
||||
else:
|
||||
is_final = True
|
||||
icon, time_str = self.get_icon(height, conf, timestamp, is_final)
|
||||
v_str = self.parent.format_amount(value, True, whitespaces=True)
|
||||
balance_str = self.parent.format_amount(balance, whitespaces=True)
|
||||
label = self.wallet.get_label(tx_hash)
|
||||
@@ -100,8 +105,8 @@ class HistoryList(MyTreeWidget):
|
||||
if current_tx == tx_hash:
|
||||
self.setCurrentItem(item)
|
||||
|
||||
def update_item(self, tx_hash, conf, timestamp):
|
||||
icon, time_str = self.get_icon(conf, timestamp)
|
||||
def update_item(self, tx_hash, height, conf, timestamp):
|
||||
icon, time_str = self.get_icon(height, conf, timestamp, True)
|
||||
items = self.findItems(tx_hash, Qt.UserRole|Qt.MatchContains|Qt.MatchRecursive, column=1)
|
||||
if items:
|
||||
item = items[0]
|
||||
@@ -125,10 +130,10 @@ class HistoryList(MyTreeWidget):
|
||||
column_data = item.text(column)
|
||||
|
||||
tx_URL = block_explorer_URL(self.config, 'tx', tx_hash)
|
||||
conf, timestamp = self.wallet.get_confirmations(tx_hash)
|
||||
height, conf, timestamp = self.wallet.get_tx_height(tx_hash)
|
||||
tx = self.wallet.transactions.get(tx_hash)
|
||||
is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
|
||||
rbf = is_mine and (conf == 0) and tx and not tx.is_final()
|
||||
rbf = is_mine and height <=0 and tx and not tx.is_final()
|
||||
menu = QMenu()
|
||||
|
||||
menu.addAction(_("Copy %s")%column_title, lambda: self.parent.app.clipboard().setText(column_data))
|
||||
|
||||
@@ -2196,14 +2196,14 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
|
||||
history = wallet.get_history()
|
||||
lines = []
|
||||
for item in history:
|
||||
tx_hash, confirmations, value, timestamp, balance = item
|
||||
if confirmations:
|
||||
tx_hash, height, conf, timestamp, value, balance = item
|
||||
if height>0:
|
||||
if timestamp is not None:
|
||||
time_string = format_time(timestamp)
|
||||
else:
|
||||
time_string = "unknown"
|
||||
time_string = _("unverified")
|
||||
else:
|
||||
time_string = "unconfirmed"
|
||||
time_string = _("unconfirmed")
|
||||
|
||||
if value is not None:
|
||||
value_string = format_satoshis(value, True)
|
||||
|
||||
@@ -183,17 +183,19 @@ class TxDialog(QDialog, MessageBoxMixin):
|
||||
self.broadcast_button.hide()
|
||||
|
||||
if self.tx.is_complete():
|
||||
status = _("Signed")
|
||||
|
||||
if tx_hash in self.wallet.transactions.keys():
|
||||
desc = self.wallet.get_label(tx_hash)
|
||||
conf, timestamp = self.wallet.get_confirmations(tx_hash)
|
||||
if timestamp:
|
||||
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
||||
height, conf, timestamp = self.wallet.get_tx_height(tx_hash)
|
||||
if height > 0:
|
||||
if conf:
|
||||
status = _("%d confirmations") % height
|
||||
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
||||
else:
|
||||
status = _('Not verified')
|
||||
else:
|
||||
time_str = _('Pending')
|
||||
status = _("%d confirmations")%conf
|
||||
status = _('Unconfirmed')
|
||||
else:
|
||||
status = _("Signed")
|
||||
self.broadcast_button.show()
|
||||
# cannot broadcast when offline
|
||||
if self.main_window.network is None:
|
||||
|
||||
@@ -106,9 +106,8 @@ class ElectrumGui:
|
||||
|
||||
b = 0
|
||||
self.history = []
|
||||
|
||||
for item in self.wallet.get_history():
|
||||
tx_hash, conf, value, timestamp, balance = item
|
||||
tx_hash, height, conf, timestamp, value, balance = item
|
||||
if conf:
|
||||
try:
|
||||
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
||||
|
||||
Reference in New Issue
Block a user