This change removes the three separate mutexes which used to lock an
account's wallet, tx store, and utxo store. Accounts no longer
contain any locking mechanism and rely on go's other synchronization
constructs (goroutines and channels) for correct access.
All accounts are now managed as a collection through the new
AccountManager, rather than the old AccountStore. AccountManager runs
as its own goroutine to provide access to accounts.
RPC requests are now queued for handling, being denied if the queue
buffer is exhausted. Notifications are also queued (instead of being
sent from their own goroutine after being received, in which order is
undefined), however, notifications are never dropped and will
potentially grow a queue of infinite size if unhandled.
Fixes several hangs cased by incorrect locking, by removing the
locking. Instead, a single goroutine manages all file writes.
The old account 'dirty' boolean flags have been removed. Instead,
anytime an account structure is modified, the portion that was
modified (wallet, tx store, or utxo store) must be scheduled to be
written.
There were several places where various account files (wallet, tx, or
utxo stores) were being marked as dirty, and then not being either
immediately synced to disk or marked as a dirty account so they would
be scheduled to be synced to disk. This change adds Account functions
to mark as dirty and add the account to the map of scheduled accounts
so they won't be missed by the disk syncer goroutine.
Strings are immutable, so instead of copying as a new variable (like
how was needed when receiving byte slices), just pass the marshaled
JSON string to the notification processing code.
This change greatly cleans up the RPC connection between btcwallet and
btcd. Proper (JSON-RPC spec-following) notifications are now expected
rather than Responses with a non-empty IDs.
A new RPCConn interface type has also been introduced with a
BtcdRPCConn concrete type for btcd RPC connections. Non-btcd-specific
code handles the RPCConn, while the btcd details have been abstracted
away to a handful of functions. This will make it easier to write
tests by creating a new fake RPC connection with hardcoded expected
replies.