Benefits of this rewrite include:
- support of disconnecting / reconnecting a device without having
to close the wallet, even in a different USB socket
- support of multiple keepkey / trezor devices, both during wallet
creation and general use
- wallet is watching-only dynamically according to whether the
associated device is currently plugged in or not
Break out the workflow logic of the install wizard
into a base class. This means reimplementing with
full support in a new GUI is now easy; you just provide
ways to request passwords, show messages etc. The API
is fully documented in the base class.
There are a couple of minor outstanding issues, including that
the old messages shown when recovering a wallet are missing.
I will come back to that. Ledger wallet might be broken.
Other improvements:
The install wizard code is now easy to follow and understand.
Hardware wallets can now be restored without any need for their
accompanying libraries.
Various bits of trustedcoin were broken and have been fixed.
Many plugin hooks can be removed. I have only started on this.
They have a different wallet type; they require no plugin nor
plugin libraries to use.
Remove pointless public key code that was implemented in the
base classes already.
Partial fix for #1592. Unfortunately the plugin and library
are still required to actually restore the wallet, but for
no reason that isn't fixable.
As per BIP44, 20 addresses are checked for transactions, not just the
first one.
Show the last account only if used or named.
If all accounts are used, prompt for password to create new one.
Fixes#1128
This should speed up synchronization / restoration of large wallets.
Wallets are written only when they switch to up_to_date state, or
when stop_threads() is called when closing the daemon, or when
a command line command finishes.
Bucketing is generalization of coin chooser logic that makes it easy
to implement other algorithms.
- Put core coin chooser functionality in base class.
- Specialize derived class to implement classic electrum algorithm of
oldest coins first. One bucket per output.
No intended change in behaviour.
Coin chooser now sorts the coins as it wants; remove redundant sorting
from get_spendable_coins().
This has several advantages. Fee calculation is now very fast,
as we don't need to keep reserializing the tx. Another is that
we can reason about the fees after adding a change output without
having to add it, recalculate the tx fee, and remove it again.
Proper fix for #1525.
Using python's GC module, I've verified that the daemon, when running,
now releases all verifiers, synchronizers and wallets - all the resources
we care about releasing.
The main problem is, I think, that the synchronizer and wallet
still exist in the daemon process, and updates to things like
TXI and TXO are made but never saved (as client exit is what
saves the wallet).
I suspect fixing the lingering objects is hard; this is a short
term fix to ensure that when internal wallet state is updated,
the wallet is written to disk, so later daemon clients pick up
the correct state.
Previously the verifier job would scan all transactions in
unverified_tx each time it ran.
Nothing was ever removed from this map; it would essentially
be the full set of transactions.
As the job runs about 10 times a second, for a wallet with 500 txs
this would be 5,000 useless loops a second.
This patch makes unverified_tx be simply the set of confirmed
transactions that haven't yet been verified. txs are added once
confirmed, and removed once verified. Hence it will almost always be
empty.
The synchronizer's work is done from the network proxy's main loop.
A minor problem with the old synchronizer was that it considered itself
out of date if the network was out of date. This was too generic: the
network can have pending requests unrelated to the synchronizer. This
resulted in the synchronizer often unnecessarily flipping the wallet
between up-to-date and not-up-to-date, and causing unnecessary calls
to wallet.save_transactions(). This was observable when opening the
network dialog box: frequently just opening it would cause a wallet
status change and transaction flush, simply because the network dialog
sends a get_parameters() request. This rework of the synchronizer does
not have that issue.
Two callers of get_spendable_coins were removing frozen addrs
before calling. Put that functionality in the function.
We shouldn't be able to send_from a frozen address. This was
possible in the current release because logic assumed a two-element
tuple was returned when it is now three-element. Fix that too.
Command line options listunspent and createrawtransaction currently
ignore frozen addresses. I'm not sure that's right but I've preserved
that behaviour.
With this patch only the wallet class refers to self.frozen_addresses;
other clients use is_frozen() now.
Speedup mainly from writing to storage only once.
Make frozen_addresses a set in memory, as sets give cleaner
code and are more efficient.
Minor change in behaviour: command line freezing used to return
False if the address isn't in the wallet OR the address was already
frozen. Now it returns more like a success code: it returns False
only if the address isn't in the wallet regardless of frozen state.
Similarly for unfreezing.
As discussed on #electrum yesterday.
Increase change gap limit to 6.
Choose the next unused change address, if any, otherwise pick
one at random from the gap limit.
Fees should be recalculated when send_from changes.
Fees should be recalculated when editing fee preference, but
only save to storage when leaving the fee per kb widget.
No need to emit a textEdited signal; the widget does that already
(with the effect that we used to call update_fee() twice).
Whilst it's not a good idea to have two electrum instances
open on the same wallet, we should avoid throwing an
exception. Also note how the old code's handling of the
exception (caused by both renaming the file almost at the
same time, rather than a non-POSIX system not supporting
the atomic rename) can lead to the wallet file being lost
enirely because os.remove(self.path) succeeds and the
rename of the temporary no-longer-existing file then fails.
A couple of changes
1) Old electrum wallets seemed to save labels in latin1, when you call json.dumps on line 83/84 it fails silently, which causes the label import to fail. Whenever electrum saves, it then overwrites your default wallet with no labels - essentially deleting all your labels. The solution to this is iterating over all the labels for old wallets decoding anything that fails to unicode() as latin1, and then unicoding it :)
2) Failing to import data and then deleting it is bad. So I'm raising an exception to avoid data being lost.
The verifier will retain responsibility for verification, but will no longer
hold the transaction sets itself.
Change requires_fee to take a wallet.
Add new function add_unverified_tx()
Move get_confirmations() to the wallet from the verifier.