This commit reorders the RPC server code to more closely match the
ordering used by the rest of the code base such that functions are
typically defined before they are used and near their call site.
This changes the behavior of the rescan RPC to automatically set the
client up for transaction notifications for transactions paying to any
rescanned address and spending outputs in the final rescan UTXO set
after a rescanned is performed through the best block in the chain.
The notification queue used for websocket client notifications had a
bug which caused the next queued item in some situations to not be
sent, but instead send a previously sent item. This change fixes this
by setting the 'next' variable to the next item which must be
dequeued, if the queue length is non-zero.
This bug did not always manifest itself as if the receiving goroutine
was ready, a queued item could be sent directly to it rather than
waiting in the queue to be sent at a later time.
This commit modifies the RPC server such that all handlers now receive a
channel which will be notified when a client disconnects. This
notification can then be used to stop long-running operations early when a
client disconnects.
This capability was already present for websocket clients, but this commit
exposes it to standard HTTP clients as well.
Also, since the new websoscket package allows the message type to be set
independently from the type of the variable, remove the casts between
strings and []byte in the websocket read/write paths. This avoids extra
copies thereby reducing the garbage generated.
Closes#134.
This change modifies the params struct to embed a *btcnet.Params,
removing the old parameter fields that are handled by the btcnet
package.
Hardcoded network checks have also been removed in favor of modifying
behavior based on the current active net's parameters.
Not all library packages, notable btcutil and btcchain, have been
updated to use btcnet yet, but with this change, each package can be
updated one at a time since the active net's btcnet.Params are
available at each callsite.
ok @davecgh
This change fixes rescan to include transactions that pay to the
pubkey for a rescanned pubkey hash address. This behavior was lost
when the rescan was optimized for specific types of the
btcutil.Address interface.
ok @davecgh
This commit correctly sets the error in the marhsalled reply if it is
already a *btcjson.Error. Previously it would only set the error if it
was not of that type which led to some RPC results showing no error when
they actually had one.
Copying the RIPEMD160 after SHA256 hash result into a new stack array
to be used as a map lookup key can be quite expensive, and this should
be avoided if possible on intensive tasks such as rescans. This
change takes advantage of the new Hash160 methods of the
AddressPubKeyHash and AddressScriptHash types to use the address's
underlying hash array directly, rather than creating a copy from the
ScriptAddress result.
Unfortunately, for AddressPubKey, ScriptAddress may return either a
byte slice of len 33 or 65 depending on whether the pubkey is
compressed or not, so no such straightforward optimization is
possible.
As a result of this change, I have seen rescans perform roughly 3.5x
faster than before.
The websocket extension command to register for notifications when a new
transaction has been accepted to the memory pool and the resulting
notifications have been renamed. This commit catches up to the change.
This change periodically (about every 10 seconds) notifies the
connected websocket client of the height of the last processed block
as part of the rescan. This enables clients to listen for the
notification and keep track of how much progress a rescan has made
even without any results being found. If the websocket connection is
lost during the rescan, on reconnect, clients may safely start over at
the last notified height.
This change adds select statements to each channel write that may
occur from a non-RPCS goroutine to unblock once the server has begun
shutting down. This prevents issues in clean shutdown where non-RPCS
goroutines may block indefinitely on message sends to the RPC server.
This change adds rescan fast paths for all current implementations of
the btcutil.Address interface. Rather than encoding a payment address
string from a txout script, the minimum number of bytes (which depends
on the address type) are copied into a stack array and used as a
lookup key to a map exclusive for that address type. This performs
better than the previous implementation due to avoiding the base58
encoding and generating less garbage (so each GC cycle completes
faster).
If the address type switch falls into the default (unhandled) case,
the encoded payment address is used as a fallback. This keeps the
intended rescan behavior even when new implementations of
btcutil.Address are added without a rescan fast path.
Benchmarks indicate that when a fast path is followed, for 20 byte
RIPEMD-160 hashes (such as P2PKH and P2SH), skipping the payment
address encoding (and thus bypassing the base58 encoding code) can
result in map lookups up to 60x faster.