This change modifies the order in which transaction to watched
addresses are processed and when frontend notifications occur. Due to
btcd notifying all transactions before sending the blockconnected
notification, the UTXO and transaction stores can be modified without
sending any frontend notifications, and then a single frontend
notification is sent when the blockconnected notification arrives.
The order in which each file is synced to disk was also changed to
write out the UTXO and transaction stores before writing the wallet.
This is to prevent a race where wallet closes after writing the dirty
wallet, but before the dirty UTXO store is written. In this
situation, newly added UTXOs will be missed and not found again on the
next wallet open during the rescan. Writing the wallet (which holds
the synced-to-block information) last prevents this.
An issue where the unconfirmed change UTXO created from a new
transaction never being properly notified to frontends is fixed now as
well.
When a wallet is opened, a rescan request will be sent to btcd with
all active addresses from the wallet, to rescan from the last synced
block (now saved to the wallet file) and the current best block.
As multi-account support is further explored, rescan requests should
be batched together to send a single request for all addresses from
all wallets.
This change introduces several changes to the wallet, tx, and utxo
files. Wallet files are still compatible, however, a rescan will try
to start at the genesis block since no correct "last synced to" or
"created at block X" was saved. The tx and utxo files, however, are
not compatible and should be deleted (or an error will occur on read).
If any errors occur opening the utxo file, a rescan will start
beginning at the creation block saved in the wallet.
While fixing this code, the dirty flag was also cleared so that
unneeded syncs wouldn't be needed later. The dirty flag set and sync
was also added for the 'getnewaddress' handler, as it was previously
missing.
This runs a syncer once every minute to write any dirty wallet data
structures out to disk. As currently implemented, dirty wallets will
be lost if not written before btcwallet closes or crashes.
Deterministic wallet help migitate this issue (as private keys can be
created again as long as a previous wallet file was written) but this
can still be a nuisance as a longer rescan will be required to catch
up to chain.