- implement it specifically for the "singlesig trezor" case
- aimed to be generic enough that support for more complex scripts
and other keystores could be added later
fixes https://github.com/spesmilo/electrum/issues/8813
regression from eef9680743
We started setting the witness field in above commit to be able to provide the witnesses for already pre-signed
external inputs to the device, e.g. for a coinjoin.
Trezor One fw has pretty strict limits on the witness field: max 109 bytes,
probably because that's a ~tight upper bound for a p2wpkh witness:
<num_witness_items> <len(sig)> <sig> <len(pubkey)> <pubkey>, it comes out to 3+73(high-S and high-R)+33.
ed1785a985/legacy/firmware/protob/messages-bitcoin.options (L35)
Trezor model T seems to have higher limits.
tx_inputs is called for the tx being signed (for_sig=True), and for its parents/prev_txes (for_sig=False).
The witness is only useful for the tx being signed, I think.
Users reported seeing a "DataError: bytes overflow" exception when using a Trezor One to sign 2of3 p2wsh multisig txs.
There were no external inputs involved so for the tx being signed all witnesses were None, however we were also
setting the witness for the inputs of prev_txes.
The witness for a 2of3 pw2sh multisig input is around ~253 bytes.
To sidestep the problem, we now only set the witness in the for_sig=True case.
Note that this means if someone tries to do a coinjoin with a Trezor One involving non-trivial external inputs,
they will run into the same limit and exception.
```
$ python3 -O
Python 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> assert (x := 2)
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
```
pity. it looked to be a neat and concise pattern.
Required a much higher mental load to parse the name "convert_bip32_path_to_list_of_uint32"
than to parse "convert_bip32_strpath_to_intpath".
And we already have the ~inverse: "convert_bip32_intpath_to_strpath".
This fixes a regression where the plugin was assuming ordering for
txin.pubkeys (which is now a set).
(previously txin.pubkeys was a list ordered according to the final
sort order of keys inside the bitcoin script)
This transport IIUC is only used for the trezor emulator.
The default timeout is 10 seconds. Every time we enumerate hw devices,
we also enumerate trezor devices, including scanning for the udp transport.
For some reason, recently on Windows, sporadically, this scan keeps
hitting the timeout for me. Quite annoying, as I might not even be testing
trezor (and I am certainly not testing using the trezor emulator on Windows...),
but scanning to test other plugins.
Probably overkill to have a 10 sec timeout for contacting localhost anyway.
Since Electrum is not using TxRequestSerializedType.serialized_tx
we might ask the device not to serialize transactions
by setting SignTx.serialize=False
This flag is only present in trezorlib 0.13.4, so only users on that
version will benefit from the speedup.
However, we decided to keep the minimum required version to 0.13.0,
since the newer version is not strictly required.
Sometimes we want its "remember path" behaviour but it does not make sense to
parent the dialog from main window. When so, caller code no longer needs to
get a reference to a main window.
Also rm last usages of get_parent_main_window().
If the Bridge is unavailable, on my machine it takes 2 seconds to timeout.
i.e. call_bridge("enumerate") and BridgeTransport.enumerate() both take 2 seconds each.
With this change, if the Bridge is unavailable, DeviceMgr.scan_devices() takes 4 seconds less.
In below log, with 6 different hw devices connected, scan time was originally ~7.5 seconds;
with this change it became ~3.5 seconds.
Now the time is dominated by WebUsbTransport.enumerate(), called by Trezor,
KeepKey, SafeT, ~1.1 seconds each.
-----
I | plugin.DeviceMgr | scan_devices() entered. 1598666278.6756
I | plugin.DeviceMgr | scan_devices(). _scan_devices_with_hid() DONE. 1598666278.7583
I | plugin.DeviceMgr | scan_devices(). starting custom enumeration loop. 1598666278.7593
I | plugin.DeviceMgr | scan_devices(). custom enumeration iter DONE, for <bound method SafeTPlugin.enumerate of <electrum.plugins.safe_t.qt.Plugin object at 0x000001F60060A730>>. 1598666279.9345
I | plugins.trezor.qt.Plugin | trezor custom enumeration entered. 1598666279.9345
I | plugins.trezor.qt.Plugin | trezor custom enumeration. call_bridge('enumerate') DONE. 1598666281.9385
>> trezorlib enumerating <class 'trezorlib.transport.bridge.BridgeTransport'> DONE at 1598666283.9500.
>> trezorlib enumerating <class 'trezorlib.transport.webusb.WebUsbTransport'> DONE at 1598666285.0427.
>> trezorlib enumerating <class 'trezorlib.transport.hid.HidTransport'> DONE at 1598666285.1198.
>> trezorlib enumerating <class 'trezorlib.transport.udp.UdpTransport'> DONE at 1598666285.1237.
I | plugins.trezor.qt.Plugin | trezor custom enumeration. trezorlib.transport.enumerate_devices() DONE. 1598666285.1257
I | plugin.DeviceMgr | scan_devices(). custom enumeration iter DONE, for <bound method TrezorPlugin.enumerate of <electrum.plugins.trezor.qt.Plugin object at 0x000001F60C16F4C0>>. 1598666285.1257
I | plugin.DeviceMgr | scan_devices(). custom enumeration iter DONE, for <bound method KeepKeyPlugin.enumerate of <electrum.plugins.keepkey.qt.Plugin object at 0x000001F60BADF130>>. 1598666286.2251
I | plugin.DeviceMgr | scan_devices(). custom enumeration iter DONE, for <bound method ColdcardPlugin.detect_simulator of <electrum.plugins.coldcard.qt.Plugin object at 0x000001F60BAA5AC0>>. 1598666286.2251
I | plugin.DeviceMgr | scan_devices(). custom enumeration loop DONE. 1598666286.2251
I | plugin.DeviceMgr | scan_devices(). find out what was disconnected DONE. 1598666286.2251
I | plugin.DeviceMgr | scan_devices(). Unpair disconnected devices DONE. 1598666286.2251