In this commit, we fix a bug introduced in an earlier commit. Before
this commit, we would *always* remove an unmined transaction if it
failed to be accepted by the network upon restart. Instead, we should
only remove transaction that are actually due to us trying to spend an
output that’s already spent, or an orphan transaction.
In this commit, we extend the PublishTransction method to be a more
general semi reliable transaction broadcast mechanism. We do this by
removing the special casing for neutrino. With this change, we’ll
_always_ write any transactions to be broadcast to disk. A side effect
of this, is that if the transaction doesn’t *directly* involve any
outputs we control, then it’ll linger around until a restart, when we
try to rebroadcast, and observe that it has bene rejected.
In this commit, we do away with the internal relayFee all together.
Instead, we’ll pass in the fee rate when we’re crafting any
transactions. This allows the caller to manually dictate their desired
fee rate.
During the time of initial block hash catch-up, it is possible to
request an address be generated. This commit updates the active
addresses by calling `w.activeData` after the catch-up is complete.
This changes the database access APIs and each of the "manager"
packages (waddrmgr/wstakemgr) so that transactions are opened (only)
by the wallet package and the namespace buckets that each manager
expects to operate on are passed in as parameters.
This helps improve the atomicity situation as it means that many
calls to these APIs can be grouped together into a single
database transaction.
This change does not attempt to completely fix the "half-processed"
block problem. Mined transactions are still added to the wallet
database under their own database transaction as this is how they are
notified by the consensus JSON-RPC server (as loose transactions,
without the rest of the block that contains them). It will make
updating to a fixed notification model significantly easier, as the
same "manager" APIs can still be used, but grouped into a single
atomic transaction.
Previously, this would not increment the spendable balance for matured
coinbase outputs and would only increment the immature balance if the
output was still immature.
This updates both btcsuite and external dependencies to their latest
versions. In particular, gRPC was updated to version 1.0.3 and bolt
to 1.3.0.
The walletrpc package needed to be regenerated for the gRPC update.
While here, update the Travis-CI script so this can be tested there.
Since the coinbase maturity is now allowed to be defined per chain and
the old blockchain.CoinbaseMaturity constant has been removed, this
updates the code accordingly.
Also, update glide.lock to use the required version of btcd.
This updates all code to make use of the new chainhash package since the
old wire.ShaHash type and related functions have been removed in favor
of the abstracted package.
Also, while here, rename all variables that included sha in their name
to include hash instead.
Finally, update glide.lock to use the required version of btcd, btcutil,
and btcrpcclient.
This changes the wallet.Open function signature to remove the database
namespace parameters. This is done so that the wallet package itself
is responsible for the location and opening of these namespaces from
the database, rather than requiring the caller to open these ahead of
time.
A new wallet.Create function has also been added. This function
initializes a new wallet in an empty database, using the same
namespaces as wallet.Open will eventually use. This relieves the
caller from needing to manage wallet database namespaces explicitly.
Fixes#397.
These notifications were added to support real time updates for
btcgui. As the btcgui project is no longer being developed, there are
no more consumers of this API, and it makes sense to remove them given
their various issues (the largest being that notifiations are sent
unsubscribed to clients that may never be interrested in them).
A new notification server has already been added to the wallet package
to handle notifications in a RPC-server agnostic way. This server is
the means by which the wallet notifies changes for gRPC clients. If
per-client registered notifications are to be re-added for the
JSON-RPC server, they should be integrated with the new notification
server rather than using this legacy code.
This began as a change to improve the fee calculation code and evolved
into a much larger refactor which improves the readability and
modularity of all of the transaction creation code.
Transaction fee calculations have been switched from full increments
of the relay fee to a proportion based on the transaction size. This
means that for a relay fee of 1e3 satoshis/kB, a 500 byte transaction
is only required to pay a 5e2 satoshi fee and a 1500 byte transaction
only need pay a 1.5e3 fee. The previous code would end up estimating
these fees to be 1e3 and 2e3 respectively.
Because the previous code would add more fee than needed in almost
every case, the transaction size estimations were optimistic
(best/smallest case) and signing was done in a loop where the fee was
incremented by the relay fee again each time the actual size of the
signed transaction rendered the fee too low. This has switched to
using worst case transaction size estimates rather than best case, and
signing is only performed once.
Transaction input signature creation has switched from using
txscript.SignatureScript to txscript.SignTxOutput. The new API is
able to redeem outputs other than just P2PKH, so the previous
restrictions about P2SH outputs being unspendable (except through the
signrawtransaction RPC) no longer hold.
Several new public packages have been added:
wallet/txauthor - transaction authoring and signing
wallet/txfees - fee estimations and change output inclusion
wallet/txrules - simple consensus and mempool policy rule checks
Along with some internal packages:
wallet/internal/txsizes - transaction size estimation
internal/helpers - context free convenience functions
The txsizes package is internal as the estimations it provides are
specific for the algorithms used by these new packages.
This is a rather monolithic commit that moves the old RPC server to
its own package (rpc/legacyrpc), introduces a new RPC server using
gRPC (rpc/rpcserver), and provides the ability to defer wallet loading
until request at a later time by an RPC (--noinitialload).
The legacy RPC server remains the default for now while the new gRPC
server is not enabled by default. Enabling the new server requires
setting a listen address (--experimenalrpclisten). This experimental
flag is used to effectively feature gate the server until it is ready
to use as a default. Both RPC servers can be run at the same time,
but require binding to different listen addresses.
In theory, with the legacy RPC server now living in its own package it
should become much easier to unit test the handlers. This will be
useful for any future changes to the package, as compatibility with
Core's wallet is still desired.
Type safety has also been improved in the legacy RPC server. Multiple
handler types are now used for methods that do and do not require the
RPC client as a dependency. This can statically help prevent nil
pointer dereferences, and was very useful for catching bugs during
refactoring.
To synchronize the wallet loading process between the main package
(the default) and through the gRPC WalletLoader service (with the
--noinitialload option), as well as increasing the loose coupling of
packages, a new wallet.Loader type has been added. All creating and
loading of existing wallets is done through a single Loader instance,
and callbacks can be attached to the instance to run after the wallet
has been opened. This is how the legacy RPC server is associated with
a loaded wallet, even after the wallet is loaded by a gRPC method in a
completely unrelated package.
Documentation for the new RPC server has been added to the
rpc/documentation directory. The documentation includes a
specification for the new RPC API, addresses how to make changes to
the server implementation, and provides short example clients in
several different languages.
Some of the new RPC methods are not implementated exactly as described
by the specification. These are considered bugs with the
implementation, not the spec. Known bugs are commented as such.
This change introduces additional network activity with the btcd
process to ensure that the network connection is not silently dropped.
Previously, if the connection was lost (e.g. wallet runs on a laptop
and connects to remote btcd, and the laptop is suspended/resumed) the
lost connection would not be detectable since all normal RPC activity
(excluding requests from btcwallet to btcd made by the user) is in the
direction of btcd to wallet in the form of websocket notifications.
sync.Locker cannot be safely used to switch a sync.Mutex to a noop
locker since other goroutines that attempt to lock the mutex will race
on the changing interface. Instead, just statically dispatch
sync.Mutex methods.