Several of the bitcoin data structures contain variable length entries,
many of which have well-defined maximum limits. However, there are still
a few cases, such as variable length strings and number of transactions
which don't have clearly defined maximum limits. Instead they are only
limited by the maximum size of a message.
In order to efficiently decode messages, space is pre-allocated for the
slices which hold these variable length pieces as to avoid needing to
dynamically grow the backing arrays. Due to this however, it was
previously possible to claim extremely high slice lengths which exceed
available memory (or maximum allowed slice lengths).
This commit imposes limits to all of these cases based on calculating
the maximum possible number of elements that could fit into a message
and using those as sane upper limits.
The variable length string case was found (and tests added to hit it) by
drahn@ which prompted an audit to find all cases.
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.
Define errors (previously done in btcwallet and btcd's rpcserver) in
one place so they can just be called by name rather than generated in
code using btcjson.
Closes#5
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.