add checkpoint dialog to the kivy gui
This commit is contained in:
parent
e6560b8d7f
commit
2fcdd458b3
|
@ -0,0 +1,86 @@
|
|||
from kivy.app import App
|
||||
from kivy.factory import Factory
|
||||
from kivy.properties import ObjectProperty
|
||||
from kivy.lang import Builder
|
||||
|
||||
|
||||
|
||||
Builder.load_string('''
|
||||
#:import _ electrum_gui.kivy.i18n._
|
||||
|
||||
<CheckpointDialog@Popup>
|
||||
id: popup
|
||||
cp_height: 0
|
||||
cp_value: ''
|
||||
title: _('Checkpoint')
|
||||
size_hint: 0.8, 0.8
|
||||
pos_hint: {'top':0.9}
|
||||
BoxLayout:
|
||||
orientation: 'vertical'
|
||||
Label:
|
||||
id: description
|
||||
text: 'In the event of a blockchain fork, a checkpoint can be used to ensure that you are on the correct blockchain.'
|
||||
halign: 'left'
|
||||
text_size: self.width, None
|
||||
size: self.texture_size
|
||||
BoxLayout:
|
||||
orientation: 'horizontal'
|
||||
size_hint: 1, 0.2
|
||||
Label:
|
||||
text: _('Height')
|
||||
height: '48dp'
|
||||
TextInput:
|
||||
id: height_input
|
||||
text: '%d'%root.cp_height
|
||||
on_focus: root.on_height_str()
|
||||
TopLabel:
|
||||
text: _('Block hash') + ':'
|
||||
TxHashLabel:
|
||||
data: root.cp_value
|
||||
Label:
|
||||
text: 'Edit the height to fetch a checkpoint from your main server, and check its value from independent sources.'
|
||||
halign: 'left'
|
||||
text_size: self.width, None
|
||||
size: self.texture_size
|
||||
Widget:
|
||||
size_hint: 1, 0.3
|
||||
BoxLayout:
|
||||
orientation: 'horizontal'
|
||||
size_hint: 1, 0.2
|
||||
Button:
|
||||
text: _('Cancel')
|
||||
size_hint: 0.5, None
|
||||
height: '48dp'
|
||||
on_release: popup.dismiss()
|
||||
Button:
|
||||
text: _('OK')
|
||||
size_hint: 0.5, None
|
||||
height: '48dp'
|
||||
on_release:
|
||||
root.callback(root.cp_height, root.cp_value)
|
||||
popup.dismiss()
|
||||
''')
|
||||
|
||||
class CheckpointDialog(Factory.Popup):
|
||||
def __init__(self, network, callback):
|
||||
Factory.Popup.__init__(self)
|
||||
self.network = network
|
||||
self.cp_height, self.cp_value = self.network.blockchain.get_checkpoint()
|
||||
self.callback = callback
|
||||
|
||||
def on_height_str(self):
|
||||
try:
|
||||
new_height = int(self.ids.height_input.text)
|
||||
except:
|
||||
new_height = 0
|
||||
if new_height == self.cp_height:
|
||||
return
|
||||
try:
|
||||
header = self.network.synchronous_get(('blockchain.block.get_header', [new_height]), 5)
|
||||
new_value = self.network.blockchain.hash_header(header)
|
||||
except BaseException as e:
|
||||
self.network.print_error(str(e))
|
||||
new_value = ''
|
||||
if new_value:
|
||||
self.cp_height = new_height
|
||||
self.cp_value = new_value
|
|
@ -113,6 +113,12 @@ Builder.load_string('''
|
|||
title: _('Coin selection') + ': ' + self.status
|
||||
description: "Coin selection method"
|
||||
action: partial(root.coinselect_dialog, self)
|
||||
CardSeparator
|
||||
SettingsItem:
|
||||
status: root.checkpoint_status()
|
||||
title: _('Checkpoint') + ': ' + self.status
|
||||
description: _("Configure blockchain checkpoint")
|
||||
action: partial(root.checkpoint_dialog, self)
|
||||
''')
|
||||
|
||||
|
||||
|
@ -134,6 +140,7 @@ class SettingsDialog(Factory.Popup):
|
|||
self._language_dialog = None
|
||||
self._unit_dialog = None
|
||||
self._coinselect_dialog = None
|
||||
self._checkpoint_dialog = None
|
||||
|
||||
def update(self):
|
||||
self.wallet = self.app.wallet
|
||||
|
@ -177,6 +184,21 @@ class SettingsDialog(Factory.Popup):
|
|||
self._coinselect_dialog = ChoiceDialog(_('Coin selection'), choosers, chooser_name, cb)
|
||||
self._coinselect_dialog.open()
|
||||
|
||||
def checkpoint_status(self):
|
||||
height, value = self.app.network.blockchain.get_checkpoint()
|
||||
return "Block %d"% height if height else _("Genesis block")
|
||||
|
||||
def checkpoint_dialog(self, item, dt):
|
||||
from checkpoint_dialog import CheckpointDialog
|
||||
if self._checkpoint_dialog is None:
|
||||
def callback(height, value):
|
||||
if value:
|
||||
self.app.network.blockchain.set_checkpoint(height, value)
|
||||
item.status = self.checkpoint_status()
|
||||
|
||||
self._checkpoint_dialog = CheckpointDialog(self.app.network, callback)
|
||||
self._checkpoint_dialog.open()
|
||||
|
||||
def network_dialog(self, item, dt):
|
||||
if self._network_dialog is None:
|
||||
server, port, protocol, proxy, auto_connect = self.app.network.get_parameters()
|
||||
|
|
|
@ -192,8 +192,7 @@ class NetworkChoiceLayout(object):
|
|||
n = len(network.get_interfaces())
|
||||
status = _("Connected to %d nodes.")%n if n else _("Not connected")
|
||||
height_str = "%d "%(network.get_local_height()) + _("blocks")
|
||||
self.checkpoint_height = self.config.get('checkpoint_height', 0)
|
||||
self.checkpoint_value = self.config.get('checkpoint_value', bitcoin.GENESIS)
|
||||
self.checkpoint_height, self.checkpoint_value = network.blockchain.get_checkpoint()
|
||||
self.cph_label = QLabel(_('Height'))
|
||||
self.cph = QLineEdit("%d"%self.checkpoint_height)
|
||||
self.cph.setFixedWidth(80)
|
||||
|
@ -337,8 +336,7 @@ class NetworkChoiceLayout(object):
|
|||
auto_connect = self.autoconnect_cb.isChecked()
|
||||
|
||||
self.network.set_parameters(host, port, protocol, proxy, auto_connect)
|
||||
self.config.set_key('checkpoint_height', self.checkpoint_height)
|
||||
self.config.set_key('checkpoint_value', self.checkpoint_value)
|
||||
self.network.blockchain.set_checkpoint(self.checkpoint_height, self.checkpoint_value)
|
||||
|
||||
def suggest_proxy(self, found_proxy):
|
||||
self.tor_proxy = found_proxy
|
||||
|
|
|
@ -37,8 +37,7 @@ class Blockchain(util.PrintError):
|
|||
def __init__(self, config, network):
|
||||
self.config = config
|
||||
self.network = network
|
||||
self.checkpoint_height = self.config.get('checkpoint_height', 0)
|
||||
self.checkpoint_hash = self.config.get('checkpoint_value', bitcoin.GENESIS)
|
||||
self.checkpoint_height, self.checkpoint_hash = self.get_checkpoint()
|
||||
self.check_truncate_headers()
|
||||
self.set_local_height()
|
||||
|
||||
|
@ -189,6 +188,7 @@ class Blockchain(util.PrintError):
|
|||
return
|
||||
if self.hash_header(checkpoint) == self.checkpoint_hash:
|
||||
return
|
||||
self.print_error('checkpoint mismatch:', self.hash_header(checkpoint), self.checkpoint_hash)
|
||||
self.print_error('Truncating headers file at height %d'%self.checkpoint_height)
|
||||
name = self.path()
|
||||
f = open(name, 'rb+')
|
||||
|
@ -274,3 +274,15 @@ class Blockchain(util.PrintError):
|
|||
except BaseException as e:
|
||||
self.print_error('verify_chunk failed', str(e))
|
||||
return idx - 1
|
||||
|
||||
def get_checkpoint(self):
|
||||
height = self.config.get('checkpoint_height', 0)
|
||||
value = self.config.get('checkpoint_value', bitcoin.GENESIS)
|
||||
return (height, value)
|
||||
|
||||
def set_checkpoint(self, height, value):
|
||||
self.checkpoint_height = height
|
||||
self.checkpoint_hash = value
|
||||
self.config.set_key('checkpoint_height', height)
|
||||
self.config.set_key('checkpoint_value', value)
|
||||
self.check_truncate_headers()
|
||||
|
|
Loading…
Reference in New Issue