This commit provides a new --cpuprofile flag that can be used to specify a
file path to write CPU profile data into. The resulting profile can then be
consumed by the 'go tool pprof' command.
Since the main SIGINT handler is running as a goroutine, the main
goroutine must be kept active long enough for it to finish or it will be
nuked when the main goroutine exits. This commit makes that happen by
slightly modifying how it waits for shutdown.
Rather than having the main goroutine only wait for the server to
shutdown, there is now a shutdown channel that is used to signal the main
goroutine to shutdown for all cases such as a graceful shutdown, a
scheduled shutdown, an RPC stop, or a SIGINT.
While here, also add a few prints to indicate a SIGINT was received and
the shutdown progress.
Profiling showed the MRU inventory handling was taking 5% of the total
block handling time. Upon inspection this is because the original
implementation was extremely inefficient using iteration to find the
oldest node for eviction.
This commit reworks it to use a map and list in order to achieve close to
O(1) performance for lookups, insertion, and eviction.
The following benchmark results show the difference:
Before: BenchmarkMruInventoryList 100 1069168 ns/op
After: BenchmarkMruInventoryList 10000000 152 ns/op
Closes#21
The ValidateTransactionScripts was recently changed to accept script flags
which pass through to the script engine in order to control its validation
behavior. This commit modifies the transaction memory pool script
validation code for this change and additionally adds the new flag to
perform canonical signtaure checking.
This change allows btcwallet to keep a pool of transactions that have
not yet been mined into a block, notifying wallet when transactions
are mined, as well as introducing a new way to send the
btcd:blockconnected notification with wallet-specific information as
part of the same notification. When a transaction is sent using the
RPC call 'sendrawtransaction', a notification request will be
automatically registered with the connected wallet (if using
websockets) to notify the wallet when the transaction first appears in
a block.
To perform this notification, and to avoid requiring wallets from
waiting for seperate mined tx notifications (and resend after a
timeout) or from sending an additional tx mined request for every tx
in the pool after each new block, the blockconnected notification is
now created seperately for each wallet. If the notified wallet has
sent a transaction, an additional JSON field "minedtxs" will include
an array of transaction IDs that the wallet has created and which are
included in the new block.
This new unique blockconnected notification can also be used for
additional notifications that may happen each new block in the future,
and to cut down on existing notification handlers in btcwallet, such
as for transactions to a watched address.
Rather than relying on the http package's DefaultServeMux for the RPC
server, create a unique mux specifically for the RPC server. This ensures
things, such as the http profiling handlers, do not commingle.
Rather than having to keep the usage in sync with the supported commands,
simply include the usage as a field in the command handlers map and
dynamically generate the usage from there.
This commit modifies the command handler in btcctl to check the existence
of a display handler before issues an RPC command. This prevents a round
trip to the server if there is no display handler.
Also, fix a couple of comments while here.
This commit significantly reworks btcctl to use a map based approach to
command handling. This reduces the number of lines of code needed,
simplifies adding new commands, improves the error handling, and removes
several cases where unexpected data was not handled properly (it could
panic).
This commit also adds the ability to specify the optional parameter on
getrawtransaction.
Discussed with dhill@.
It was previously possible for the unprotected iteration of the mempool
orphans to lead to undefined results. This commit remedies that by
reworking the locking code a bit. It also embeds the mutex directly into
the mempool struct rather than having a separate field for it so the
syntax is a slightly cleaner.
Results from FetchTxByShaList must each be checked for a nil Err and a
non-nil Tx. Fix this issue in two places where these conditions were
not being checked.
The latest websockets code added a quit channel to the RPC server, but did
not initialize it. This commit corrects that so shutdown works properly
again.
If we don't hear from a peer for 5 minutes, we disconnect them. To keep
traffic flowing we send a ping every 2 minutes if we have not send any
other message that should get a reply.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
This change paves the way for running btcwallet on the same system without
having to change any settings. The well-known ports used by the
reference implementation (8332 mainnet, 18332 testnet) will be exposed by
the separate wallet process, which will in turn forward unknown requests
to btcd via websockets (on 8334/18334). This allows the wallet process to
ultimately provide a unified interface that exposes the same RPC-JSON API
as the reference implementation will maintaining wallet and chain
separation.