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 Aug 15, 2024
2 parents d299692 + bd84508 commit fae8ba2
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 22 deletions.
6 changes: 3 additions & 3 deletions contrib/deterministic-build/requirements-hw.txt
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,9 @@ setuptools==65.5.1 \
six==1.16.0 \
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
trezor==0.13.8 \
--hash=sha256:0bd22f761622199df99f8dada3327a94e68542d0b4b5ccfdfaca133308616c86 \
--hash=sha256:634d4eddf35603257c321618d8548c6a35b27384657b65e3b0bdbad635a57cff
trezor==0.13.9 \
--hash=sha256:30ffcbefb5f9300fe1ac34754a593ff10ae400bce22e2a062c45870ed4949fd5 \
--hash=sha256:9450bd7bb9d23e5e33a3c9e58e18f058b44c9d9c34ca664b4981a795aa9fb1ef
typing-extensions==4.9.0 \
--hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \
--hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd
Expand Down
4 changes: 2 additions & 2 deletions electrum_grs/gui/qt/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -2044,8 +2044,8 @@ def do_decrypt(self, message_e, pubkey_e, encrypted_e, password):
if self.wallet.is_watching_only():
self.show_message(_('This is a watching-only wallet.'))
return
cyphertext = encrypted_e.toPlainText()
task = partial(self.wallet.decrypt_message, pubkey_e.text(), cyphertext, password)
ciphertext = encrypted_e.toPlainText()
task = partial(self.wallet.decrypt_message, pubkey_e.text(), ciphertext, password)

def setText(text):
try:
Expand Down
2 changes: 1 addition & 1 deletion electrum_grs/gui/qt/wizard/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ def on_filename(filename):
pw_label.show()
self.pw_e.show()
if not self.name_e.hasFocus():
self.pw_e.setFocus(True)
self.pw_e.setFocus()
else:
pw_label.hide()
self.pw_e.hide()
Expand Down
4 changes: 3 additions & 1 deletion electrum_grs/gui/qt/wizard/wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,13 @@ def __init__(self, config: 'SimpleConfig', app: 'QElectrumApplication', *, start
self.back_button = QPushButton(_("Back"), self)
self.back_button.clicked.connect(self.on_back_button_clicked)
self.back_button.setEnabled(False)
self.back_button.setDefault(False)
self.back_button.setAutoDefault(False)
self.next_button = QPushButton(_("Next"), self)
self.next_button.clicked.connect(self.on_next_button_clicked)
self.next_button.setEnabled(False)
self.next_button.setDefault(True)
self.next_button.setAutoDefault(True)
self.requestPrev.connect(self.on_back_button_clicked)
self.requestNext.connect(self.on_next_button_clicked)
self.logo = QLabel()
Expand Down Expand Up @@ -126,7 +129,6 @@ 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
2 changes: 1 addition & 1 deletion electrum_grs/plugins/jade/jade.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def __init__(self, device: str, plugin: HW_PluginBase):
self.efusemac = verinfo['EFUSEMAC']
self.jade.disconnect()

# Reconnect with a the default timeout for all subsequent calls
# Reconnect with the default timeout for all subsequent calls
self.jade = JadeAPI.create_serial(device)
self.jade.connect()

Expand Down
12 changes: 10 additions & 2 deletions electrum_grs/plugins/trezor/clientbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@

from trezorlib.client import TrezorClient, PASSPHRASE_ON_DEVICE
from trezorlib.exceptions import TrezorFailure, Cancelled, OutdatedFirmwareError
from trezorlib.messages import WordRequestType, FailureType, RecoveryDeviceType, ButtonRequestType
from trezorlib.messages import WordRequestType, FailureType, ButtonRequestType
import trezorlib.btc
import trezorlib.device

try:
# trezor >= 0.13.9
from trezorlib.messages import RecoveryDeviceInputMethod
except ImportError:
# Backward compatibility for trezor < 0.13.9
from trezorlib.messages import RecoveryDeviceType as RecoveryDeviceInputMethod


MESSAGES = {
ButtonRequestType.ConfirmOutput:
_("Confirm the transaction output on your {} device"),
Expand Down Expand Up @@ -346,7 +354,7 @@ def mnemonic_callback(self, recovery_type):
if recovery_type is None:
return None

if recovery_type == RecoveryDeviceType.Matrix:
if recovery_type == RecoveryDeviceInputMethod.Matrix:
return self._matrix_char

step = 0
Expand Down
6 changes: 3 additions & 3 deletions electrum_grs/plugins/trezor/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from electrum_grs.gui.qt.wizard.wallet import WCScriptAndDerivation, WCHWUnlock, WCHWXPub, WalletWizardComponent

from .trezor import (TrezorPlugin, TIM_NEW, TIM_RECOVER, TrezorInitSettings,
PASSPHRASE_ON_DEVICE, Capability, BackupType, RecoveryDeviceType)
PASSPHRASE_ON_DEVICE, Capability, BackupType, RecoveryDeviceInputMethod)

if TYPE_CHECKING:
from electrum_grs.gui.qt.wizard.wallet import QENewWalletWizard
Expand Down Expand Up @@ -409,14 +409,14 @@ def show_expert_settings():
rb1 = QRadioButton(gb_rectype)
rb1.setText(_('Scrambled words'))
self.bg_rectype.addButton(rb1)
self.bg_rectype.setId(rb1, RecoveryDeviceType.ScrambledWords)
self.bg_rectype.setId(rb1, RecoveryDeviceInputMethod.ScrambledWords)
hbox_rectype.addWidget(rb1)
rb1.setChecked(True)

rb2 = QRadioButton(gb_rectype)
rb2.setText(_('Matrix'))
self.bg_rectype.addButton(rb2)
self.bg_rectype.setId(rb2, RecoveryDeviceType.Matrix)
self.bg_rectype.setId(rb2, RecoveryDeviceInputMethod.Matrix)
hbox_rectype.addWidget(rb2)

# no backup
Expand Down
10 changes: 5 additions & 5 deletions electrum_grs/plugins/trezor/trezor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
import trezorlib.transport
from trezorlib.transport.bridge import BridgeTransport, call_bridge

from .clientbase import TrezorClientBase
from .clientbase import TrezorClientBase, RecoveryDeviceInputMethod

from trezorlib.messages import (
Capability, BackupType, RecoveryDeviceType, HDNodeType, HDNodePathType,
Capability, BackupType, HDNodeType, HDNodePathType,
InputScriptType, OutputScriptType, MultisigRedeemScriptType,
TxInputType, TxOutputType, TxOutputBinType, TransactionType, AmountUnit)

Expand All @@ -56,7 +56,7 @@ def __getattr__(self, key):

Capability = _EnumMissing()
BackupType = _EnumMissing()
RecoveryDeviceType = _EnumMissing()
RecoveryDeviceInputMethod = _EnumMissing()
AmountUnit = _EnumMissing()

PASSPHRASE_ON_DEVICE = object()
Expand Down Expand Up @@ -251,7 +251,7 @@ def get_coin_name(self):

@runs_in_hwd_thread
def _initialize_device(self, settings: TrezorInitSettings, method, device_id, handler):
if method == TIM_RECOVER and settings.recovery_type == RecoveryDeviceType.ScrambledWords:
if method == TIM_RECOVER and settings.recovery_type == RecoveryDeviceInputMethod.ScrambledWords:
handler.show_error(_(
"You will be asked to enter 24 words regardless of your "
"seed's actual length. If you enter a word incorrectly or "
Expand Down Expand Up @@ -281,7 +281,7 @@ def _initialize_device(self, settings: TrezorInitSettings, method, device_id, ha
passphrase_protection=settings.passphrase_enabled,
pin_protection=settings.pin_enabled,
label=settings.label)
if settings.recovery_type == RecoveryDeviceType.Matrix:
if settings.recovery_type == RecoveryDeviceInputMethod.Matrix:
handler.close_matrix_dialog()
else:
raise RuntimeError("Unsupported recovery method")
Expand Down
4 changes: 3 additions & 1 deletion electrum_grs/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -1645,7 +1645,7 @@ def get_all_labels(self) -> Dict[str, str]:
with self.lock:
return copy.copy(self._labels)

def get_tx_status(self, tx_hash, tx_mined_info: TxMinedInfo):
def get_tx_status(self, tx_hash: str, tx_mined_info: TxMinedInfo):
extra = []
height = tx_mined_info.height
conf = tx_mined_info.conf
Expand All @@ -1658,6 +1658,8 @@ def get_tx_status(self, tx_hash, tx_mined_info: TxMinedInfo):
tx = self.db.get_transaction(tx_hash)
if not tx:
return 2, _("unknown")
if not tx.is_complete():
tx.add_info_from_wallet(self) # needed for estimated_size(), for txin size calc
fee = self.adb.get_tx_fee(tx_hash)
if fee is not None:
size = tx.estimated_size()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def test_parse_URI_lightning_consistency(self):
self.assertRaises(InvalidBitcoinURI, parse_bip21_URI, 'groestlcoin:tgrs1qvu0c9xme0ul3gzx4nzqdgxsu25acuk9wvsj2j2?amount=0.0007&message=test266&lightning=lntb700u1p3kqy26pp5l7rj7w0u5sdsj24umzdlhdhkk8a597sn865rhap4h4jenjefdk7ssp5d9zjr96ezp89gsyenfse5f4jn9ls29p0awvp0zxlt6tpzn2m3j5qdqvw3jhxapjxcmqcqzynxq8zals8sq9q7sqqqqqqqqqqqqqqqqqqqqqqqqq9qsqfppqu5ua3szskclyd48wlfdwfd32j65phxy9vu8dmmk3u20u0e0yqw484xzn4hc3cux6kk2wenhw7zy0mseu9ntpk9l4fws2d46svzszrc6mqy535740ks9j22w67fw0x4dt8w2hhzspcqakql')
# bip21 uri that includes "lightning" key. top-level amount mismatches LN amount
self.assertRaises(InvalidBitcoinURI, parse_bip21_URI, 'groestlcoin:tgrs1qu5ua3szskclyd48wlfdwfd32j65phxy9yf7ytl?amount=0.0008&message=test266&lightning=lntb700u1p3kqy26pp5l7rj7w0u5sdsj24umzdlhdhkk8a597sn865rhap4h4jenjefdk7ssp5d9zjr96ezp89gsyenfse5f4jn9ls29p0awvp0zxlt6tpzn2m3j5qdqvw3jhxapjxcmqcqzynxq8zals8sq9q7sqqqqqqqqqqqqqqqqqqqqqqqqq9qsqfppqu5ua3szskclyd48wlfdwfd32j65phxy9vu8dmmk3u20u0e0yqw484xzn4hc3cux6kk2wenhw7zy0mseu9ntpk9l4fws2d46svzszrc6mqy535740ks9j22w67fw0x4dt8w2hhzspcqakql')
# bip21 uri that includes "lightning" key with garbage unparseable value
# bip21 uri that includes "lightning" key with garbage unparsable value
self.assertRaises(InvalidBitcoinURI, parse_bip21_URI, 'groestlcoin:tgrs1qu5ua3szskclyd48wlfdwfd32j65phxy9yf7ytl?amount=0.0008&message=test266&lightning=lntb700u1p3kqy26pp5l7rj7w0u5sdsj24umzdlhdasdasdasdasd')

def test_is_hash256_str(self):
Expand Down
68 changes: 66 additions & 2 deletions tests/test_wallet_vertical.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
from electrum_grs import Transaction
from electrum_grs import SimpleConfig
from electrum_grs import util
from electrum_grs.address_synchronizer import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCONF_PARENT
from electrum_grs.address_synchronizer import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_LOCAL
from electrum_grs.wallet import (sweep, Multisig_Wallet, Standard_Wallet, Imported_Wallet,
restore_wallet_from_text, Abstract_Wallet, CannotBumpFee, BumpFeeStrategy,
TransactionPotentiallyDangerousException, TransactionDangerousException,
TxSighashRiskLevel)
from electrum_grs.util import bfh, NotEnoughFunds, UnrelatedTransactionException, UserFacingException
from electrum_grs.util import bfh, NotEnoughFunds, UnrelatedTransactionException, UserFacingException, TxMinedInfo
from electrum_grs.transaction import Transaction, PartialTxOutput, tx_from_any, Sighash
from electrum_grs.mnemonic import calc_seed_type
from electrum_grs.network import Network
Expand Down Expand Up @@ -4183,6 +4183,70 @@ async def test_restoring_wallet_with_manual_delete(self, mock_save_db):
self.assertEqual(999890, sum(w.get_balance()))


class TestWalletHistory_HelperFns(ElectrumTestCase):
TESTNET = True

def setUp(self):
super().setUp()
self.config = SimpleConfig({'electrum_path': self.electrum_path})

@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
async def test_get_tx_status_feerate_for_local_2of3_multisig_partial_tx(self, mock_save_db):
wallet1 = WalletIntegrityHelper.create_multisig_wallet(
[
keystore.from_seed('bitter grass shiver impose acquire brush forget axis eager alone wine silver', passphrase='', for_multisig=True),
keystore.from_xpub('Vpub5fcdcgEwTJmbmqAktuK8Kyq92fMf7sWkcP6oqAii2tG47dNbfkGEGUbfS9NuZaRywLkHE6EmUksrqo32ZL3ouLN1HTar6oRiHpDzKMAF1tf'),
keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra')
],
'2of3', gap_limit=2,
config=self.config,
)

# bootstrap wallet1
funding_tx = Transaction('01000000000101a41aae475d026c9255200082c7fad26dc47771275b0afba238dccda98a597bd20000000000fdffffff02400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c9dcd410000000000160014824626055515f3ed1d2cfc9152d2e70685c71e8f02483045022100b9f39fad57d07ce1e18251424034f21f10f20e59931041b5167ae343ce973cf602200fefb727fa0ffd25b353f1bcdae2395898fe407b692c62f5885afbf52fa06f5701210301a28f68511ace43114b674371257bb599fd2c686c4b19544870b1799c954b40e9c11300')
wallet1.adb.receive_tx_callback(funding_tx, TX_HEIGHT_UNCONFIRMED)

# wallet1 -> wallet2
outputs = [PartialTxOutput.from_address_and_value("2MuUcGmQ2mLN3vjTuqDSgZpk4LPKDsuPmhN", 165000)]
tx = wallet1.create_transaction(outputs=outputs, password=None, fee=5000, tx_version=1, rbf=False, sign=False)
self.assertEqual(
"wsh(sortedmulti(2,[b2e35a7d/1h]tpubD9aPYLPPYw8MxU3cD57LwpV5v7GomHxdv62MSbPcRkp47zwXx69ACUFsKrj8xzuzRrij9FWVhfvkvNqtqsr8ZtefkDsGZ9GLuHzoS6bXyk1/0/0,[53b77ddb/1h]tpubD8spLJysN7v7V1KHvkZ7AwjnXShKafopi7Vu3Ahs2S46FxBPTode8DgGxDo55k4pJvETGScZFwnM5f2Y31EUjteJdhxR73sjr9ieydgah2U/0/0,[43067d63/1h]tpubD8khd1g1tzFeKeaU59QV811hyvhwn9KDfy5sqFJ5m2wJLw6rUt4AZviqutRPXTUAK4SpU2we3y2WBP916Ma8Em4qFGcbYkFvXVfpGYV3oZR/0/0))",
tx.inputs()[0].script_descriptor.to_string_no_checksum())
partial_tx = tx.serialize_as_bytes().hex()
self.assertEqual("70736274ff01007e0100000001213e1012a461e056752fab5a6414a2fb63f950cd21a50ac5e2b82d339d6cbdd20000000000feffffff023075000000000000220020cc5e4cc05a76d0648cd0742768556317e9f8cc729aed077134287909035dba88888402000000000017a914187842cea9c15989a51ce7ca889a08b824bf874387000000000001012b400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c0100eb01000000000101a41aae475d026c9255200082c7fad26dc47771275b0afba238dccda98a597bd20000000000fdffffff02400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c9dcd410000000000160014824626055515f3ed1d2cfc9152d2e70685c71e8f02483045022100b9f39fad57d07ce1e18251424034f21f10f20e59931041b5167ae343ce973cf602200fefb727fa0ffd25b353f1bcdae2395898fe407b692c62f5885afbf52fa06f5701210301a28f68511ace43114b674371257bb599fd2c686c4b19544870b1799c954b40e9c1130001056952210223f815ab09f6bfc8519165c5232947ae89d9d43d678fb3486f3b28382a2371fa210273c529c2c9a99592f2066cebc2172a48991af2b471cb726b9df78c6497ce984e2102aa8fc578b445a1e4257be6b978fcece92980def98dce0e1eb89e7364635ae94153ae22060223f815ab09f6bfc8519165c5232947ae89d9d43d678fb3486f3b28382a2371fa10b2e35a7d01000080000000000000000022060273c529c2c9a99592f2066cebc2172a48991af2b471cb726b9df78c6497ce984e1053b77ddb010000800000000000000000220602aa8fc578b445a1e4257be6b978fcece92980def98dce0e1eb89e7364635ae9411043067d6301000080000000000000000000010169522102174696a58a8dcd6c6455bd25e0749e9a6fc7d84ee09e192ab37b0d0b18c2de1a2102c807a19ca6783261f8c198ffcc437622e7ecba8d6c5692f3a5e7f1e45af53fd52102eee40c7e24d89639182db32f5e9188613e4bc212da2ee9b4ccc85d9b82e1a98053ae220202174696a58a8dcd6c6455bd25e0749e9a6fc7d84ee09e192ab37b0d0b18c2de1a1053b77ddb010000800100000000000000220202c807a19ca6783261f8c198ffcc437622e7ecba8d6c5692f3a5e7f1e45af53fd51043067d63010000800100000000000000220202eee40c7e24d89639182db32f5e9188613e4bc212da2ee9b4ccc85d9b82e1a98010b2e35a7d0100008001000000000000000000",
partial_tx)
tx = tx_from_any(partial_tx) # simulates moving partial txn between cosigners
self.assertFalse(tx.is_complete())

wallet1.adb.add_transaction(tx)
# let's see if the calculated feerate correct:
self.assertEqual((3, 'Local [26.3 sat/vB]'),
wallet1.get_tx_status(tx.txid(), TxMinedInfo(height=TX_HEIGHT_LOCAL, conf=0)))

@mock.patch.object(wallet.Abstract_Wallet, 'save_db')
async def test_get_tx_status_feerate_for_local_2of3_multisig_signed_tx(self, mock_save_db):
wallet1 = WalletIntegrityHelper.create_multisig_wallet(
[
keystore.from_seed('bitter grass shiver impose acquire brush forget axis eager alone wine silver', passphrase='', for_multisig=True),
keystore.from_xpub('Vpub5fcdcgEwTJmbmqAktuK8Kyq92fMf7sWkcP6oqAii2tG47dNbfkGEGUbfS9NuZaRywLkHE6EmUksrqo32ZL3ouLN1HTar6oRiHpDzKMAF1tf'),
keystore.from_xpub('Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra')
],
'2of3', gap_limit=2,
config=self.config,
)

# bootstrap wallet1
funding_tx = Transaction('01000000000101a41aae475d026c9255200082c7fad26dc47771275b0afba238dccda98a597bd20000000000fdffffff02400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c9dcd410000000000160014824626055515f3ed1d2cfc9152d2e70685c71e8f02483045022100b9f39fad57d07ce1e18251424034f21f10f20e59931041b5167ae343ce973cf602200fefb727fa0ffd25b353f1bcdae2395898fe407b692c62f5885afbf52fa06f5701210301a28f68511ace43114b674371257bb599fd2c686c4b19544870b1799c954b40e9c11300')
wallet1.adb.receive_tx_callback(funding_tx, TX_HEIGHT_UNCONFIRMED)

# wallet1 -> wallet2
tx = tx_from_any("01000000000101213e1012a461e056752fab5a6414a2fb63f950cd21a50ac5e2b82d339d6cbdd20000000000feffffff023075000000000000220020cc5e4cc05a76d0648cd0742768556317e9f8cc729aed077134287909035dba88888402000000000017a914187842cea9c15989a51ce7ca889a08b824bf8743870400473044022055cb04fa71c4b5955724d7ac5da90436d75212e7847fc121cb588f54bcdffdc4022064eca1ad639b7c748101059dc69f2893abb3b396bcf9c13f670415076f93ddbf01473044022009230e456724f2a4c10d886c836eeec599b21db0bf078aa8fc8c95868b8920ec02200dfda835a66acb5af50f0d95fcc4b76c6e8f4789a7184c182275b087d1efe556016952210223f815ab09f6bfc8519165c5232947ae89d9d43d678fb3486f3b28382a2371fa210273c529c2c9a99592f2066cebc2172a48991af2b471cb726b9df78c6497ce984e2102aa8fc578b445a1e4257be6b978fcece92980def98dce0e1eb89e7364635ae94153ae00000000")
wallet1.adb.add_transaction(tx)
# let's see if the calculated feerate correct:
self.assertEqual((3, 'Local [26.3 sat/vB]'),
wallet1.get_tx_status(tx.txid(), TxMinedInfo(height=TX_HEIGHT_LOCAL, conf=0)))


class TestImportedWallet(ElectrumTestCase):
TESTNET = True
transactions = {
Expand Down

0 comments on commit fae8ba2

Please sign in to comment.