Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
gruve-p committed Mar 10, 2024
2 parents e2b2af9 + ff50487 commit a3cf5ea
Show file tree
Hide file tree
Showing 21 changed files with 2,956 additions and 95 deletions.
2 changes: 1 addition & 1 deletion contrib/android/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ If you just follow the instructions above, you will build the apk
in debug mode. The most notable difference is that the apk will be
signed using a debug keystore. If you are planning to upload
what you build to e.g. the Play Store, you should create your own
keystore, back it up safely, and run `./contrib/make_apk.sh release`.
keystore, back it up safely, and run `./build.sh` in `release` mode.
See e.g. [kivy wiki](https://github.com/kivy/kivy/wiki/Creating-a-Release-APK)
and [android dev docs](https://developer.android.com/studio/build/building-cmdline#sign_cmdline).
Expand Down
13 changes: 5 additions & 8 deletions electrum_grs/gui/qml/components/CpfpBumpFeeDialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,15 @@ ElDialog {
columns: 2

Label {
Layout.columnSpan: 2
Layout.fillWidth: true
text: qsTr('A CPFP is a transaction that sends an unconfirmed output back to yourself, with a high fee. The goal is to have miners confirm the parent transaction in order to get the fee attached to the child transaction.')
text: qsTr('A CPFP is a transaction that sends an unconfirmed output back to yourself, with a high fee.')
wrapMode: Text.Wrap
}

Label {
Layout.columnSpan: 2
Layout.fillWidth: true
Layout.bottomMargin: constants.paddingLarge
text: qsTr('The proposed fee is computed using your fee/kB settings, applied to the total size of both child and parent transactions. After you broadcast a CPFP transaction, it is normal to see a new unconfirmed transaction in your history.')
wrapMode: Text.Wrap
HelpButton {
heading: qsTr('CPFP - Child Pays For Parent')
helptext: qsTr('A CPFP is a transaction that sends an unconfirmed output back to yourself, with a high fee. The goal is to have miners confirm the parent transaction in order to get the fee attached to the child transaction.')
+ '<br/><br/>' + qsTr('The proposed fee is computed using your fee/vkB settings, applied to the total size of both child and parent transactions. After you broadcast a CPFP transaction, it is normal to see a new unconfirmed transaction in your history.')
}

Label {
Expand Down
20 changes: 20 additions & 0 deletions electrum_grs/gui/qml/components/controls/HelpButton.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Material

ToolButton {
id: root
property string heading
property string helptext

icon.source: Qt.resolvedUrl('../../../icons/info.png')
icon.color: 'transparent'
onClicked: {
var dialog = app.helpDialog.createObject(app, {
heading: root.heading,
text: root.helptext
})
dialog.open()
}
}
60 changes: 60 additions & 0 deletions electrum_grs/gui/qml/components/controls/HelpDialog.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import QtQuick.Controls.Material

ElDialog {
id: dialog

header: Item { }

property string text
property string heading

z: 1 // raise z so it also covers dialogs using overlay as parent

anchors.centerIn: parent

padding: 0

width: rootPane.width

Overlay.modal: Rectangle {
color: "#55000000"
}

Pane {
id: rootPane
width: rootLayout.width + leftPadding + rightPadding
padding: constants.paddingLarge

ColumnLayout {
id: rootLayout
width: dialog.parent.width * 2/3

RowLayout {
Image {
source: Qt.resolvedUrl('../../../icons/info.png')
Layout.preferredWidth: constants.iconSizeSmall
Layout.preferredHeight: constants.iconSizeSmall
}
Label {
text: dialog.heading
font.underline: true
font.italic: true
}
}
TextArea {
id: message
Layout.fillWidth: true
readOnly: true
text: dialog.text
wrapMode: TextInput.WordWrap
textFormat: TextEdit.RichText
background: Rectangle {
color: 'transparent'
}
}
}
}
}
8 changes: 8 additions & 0 deletions electrum_grs/gui/qml/components/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,14 @@ ApplicationWindow
}
}

property alias helpDialog: _helpDialog
Component {
id: _helpDialog
HelpDialog {
onClosed: destroy()
}
}

property alias passwordDialog: _passwordDialog
Component {
id: _passwordDialog
Expand Down
5 changes: 4 additions & 1 deletion electrum_grs/gui/qt/transaction_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@

class TxSizeLabel(QLabel):
def setAmount(self, byte_size):
self.setText(('x %s bytes =' % byte_size) if byte_size else '')
text = ""
if byte_size:
text = f"x {byte_size} {UI_UNIT_NAME_TXSIZE_VBYTES} ="
self.setText(text)


class TxFiatLabel(QLabel):
Expand Down
6 changes: 3 additions & 3 deletions electrum_grs/gui/qt/update_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ def __init__(self, *, latest_version=None):
self.content.addWidget(self.pb)

versions = QHBoxLayout()
versions.addWidget(QLabel(_("Current version: {}".format(version.ELECTRUM_VERSION))))
self.latest_version_label = QLabel(_("Latest version: {}".format(" ")))
versions.addWidget(QLabel(_("Current version: {}").format(version.ELECTRUM_VERSION)))
self.latest_version_label = QLabel(_("Latest version: {}").format(" "))
versions.addWidget(self.latest_version_label)
self.content.addLayout(versions)

Expand Down Expand Up @@ -80,7 +80,7 @@ def is_newer(latest_version):
def update_view(self, latest_version=None):
if latest_version:
self.pb.hide()
self.latest_version_label.setText(_("Latest version: {}".format(latest_version)))
self.latest_version_label.setText(_("Latest version: {}").format(latest_version))
if self.is_newer(latest_version):
self.heading_label.setText('<h2>' + _("There is a new update available") + '</h2>')
url = "<a href='{u}'>{u}</a>".format(u=UpdateCheck.download_url)
Expand Down
2 changes: 1 addition & 1 deletion electrum_grs/gui/qt/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def __init__(self, text: str):

class InfoButton(HelpMixin, QPushButton):
def __init__(self, text: str):
QPushButton.__init__(self, 'Info')
QPushButton.__init__(self, _('Info'))
HelpMixin.__init__(self, text, help_title=_('Info'))
self.setFocusPolicy(Qt.NoFocus)
self.setFixedWidth(6 * char_width_in_lineedit())
Expand Down
1 change: 1 addition & 0 deletions electrum_grs/gui/qt/wizard/wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def strt(self):
self.load_next_component(viewstate.view, viewstate.wizard_data, viewstate.params)
# TODO: re-test if needed on macOS
self.refresh_gui() # Need for QT on MacOSX. Lame.
self.next_button.setFocus() # setDefault() is not enough

def refresh_gui(self):
# For some reason, to refresh the GUI this needs to be called twice
Expand Down
8 changes: 3 additions & 5 deletions electrum_grs/lnchannel.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,8 @@ def __init__(self, state: 'StoredDict', *, name=None, lnworker=None, initial_fee
self.onion_keys = state['onion_keys'] # type: Dict[int, bytes]
self.data_loss_protect_remote_pcp = state['data_loss_protect_remote_pcp']
self.hm = HTLCManager(log=state['log'], initial_feerate=initial_feerate)
self.unfulfilled_htlcs = state["unfulfilled_htlcs"]
self.unfulfilled_htlcs = state["unfulfilled_htlcs"] # type: Dict[int, Tuple[str, Optional[str]]]
# ^ htlc_id -> onion_packet_hex, forwarding_key
self._state = ChannelState[state['state']]
self.peer_state = PeerState.DISCONNECTED
self._sweep_info = {}
Expand Down Expand Up @@ -1058,11 +1059,8 @@ def receive_htlc(self, htlc: UpdateAddHtlc, onion_packet:bytes = None) -> Update
htlc = attr.evolve(htlc, htlc_id=self.hm.get_next_htlc_id(REMOTE))
with self.db_lock:
self.hm.recv_htlc(htlc)
local_ctn = self.get_latest_ctn(LOCAL)
remote_ctn = self.get_latest_ctn(REMOTE)
if onion_packet:
# TODO neither local_ctn nor remote_ctn are used anymore... no point storing them.
self.unfulfilled_htlcs[htlc.htlc_id] = local_ctn, remote_ctn, onion_packet.hex(), False
self.unfulfilled_htlcs[htlc.htlc_id] = onion_packet.hex(), None

self.logger.info("receive_htlc")
return htlc
Expand Down
Loading

0 comments on commit a3cf5ea

Please sign in to comment.