2013-08-21 16:37:30 +02:00
|
|
|
/*
|
2015-05-01 19:10:23 +02:00
|
|
|
* Copyright (c) 2013-2015 The btcsuite developers
|
2013-08-21 16:37:30 +02:00
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2014-02-24 20:35:30 +01:00
|
|
|
"bytes"
|
2014-06-12 18:39:26 +02:00
|
|
|
"crypto/sha256"
|
|
|
|
"crypto/subtle"
|
|
|
|
"crypto/tls"
|
2014-02-12 03:14:07 +01:00
|
|
|
"encoding/base64"
|
2013-10-04 21:02:17 +02:00
|
|
|
"encoding/hex"
|
2014-04-09 18:07:09 +02:00
|
|
|
"encoding/json"
|
2014-04-18 00:13:53 +02:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
2014-06-12 18:39:26 +02:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
|
|
|
"sync"
|
2014-07-03 03:36:38 +02:00
|
|
|
"sync/atomic"
|
2014-06-12 18:39:26 +02:00
|
|
|
"time"
|
|
|
|
|
2015-02-06 17:43:23 +01:00
|
|
|
"github.com/btcsuite/btcd/btcec"
|
2015-05-01 07:55:49 +02:00
|
|
|
"github.com/btcsuite/btcd/btcjson"
|
2015-04-17 22:05:38 +02:00
|
|
|
"github.com/btcsuite/btcd/chaincfg"
|
2015-01-30 19:31:29 +01:00
|
|
|
"github.com/btcsuite/btcd/txscript"
|
2015-02-05 22:41:38 +01:00
|
|
|
"github.com/btcsuite/btcd/wire"
|
2015-01-16 04:28:09 +01:00
|
|
|
"github.com/btcsuite/btcrpcclient"
|
2015-01-15 17:48:58 +01:00
|
|
|
"github.com/btcsuite/btcutil"
|
2015-01-17 07:25:53 +01:00
|
|
|
"github.com/btcsuite/btcwallet/chain"
|
2014-10-29 07:43:29 +01:00
|
|
|
"github.com/btcsuite/btcwallet/waddrmgr"
|
2015-04-02 20:13:38 +02:00
|
|
|
"github.com/btcsuite/btcwallet/wallet"
|
2015-04-06 21:03:24 +02:00
|
|
|
"github.com/btcsuite/btcwallet/wtxmgr"
|
2015-01-16 00:24:53 +01:00
|
|
|
"github.com/btcsuite/websocket"
|
2013-08-21 16:37:30 +02:00
|
|
|
)
|
|
|
|
|
2014-06-04 02:52:04 +02:00
|
|
|
// Error types to simplify the reporting of specific categories of
|
2015-04-17 22:05:38 +02:00
|
|
|
// errors, and their *btcjson.RPCError creation.
|
2014-06-04 02:52:04 +02:00
|
|
|
type (
|
|
|
|
// DeserializationError describes a failed deserializaion due to bad
|
2015-04-17 22:05:38 +02:00
|
|
|
// user input. It cooresponds to btcjson.ErrRPCDeserialization.
|
2014-06-04 02:52:04 +02:00
|
|
|
DeserializationError struct {
|
|
|
|
error
|
|
|
|
}
|
|
|
|
|
|
|
|
// InvalidParameterError describes an invalid parameter passed by
|
2015-04-17 22:05:38 +02:00
|
|
|
// the user. It cooresponds to btcjson.ErrRPCInvalidParameter.
|
2014-06-04 02:52:04 +02:00
|
|
|
InvalidParameterError struct {
|
|
|
|
error
|
|
|
|
}
|
|
|
|
|
|
|
|
// ParseError describes a failed parse due to bad user input. It
|
2015-04-17 22:05:38 +02:00
|
|
|
// cooresponds to btcjson.ErrRPCParse.
|
2014-06-04 02:52:04 +02:00
|
|
|
ParseError struct {
|
|
|
|
error
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
// Errors variables that are defined once here to avoid duplication below.
|
|
|
|
var (
|
|
|
|
ErrNeedPositiveAmount = InvalidParameterError{
|
|
|
|
errors.New("amount must be positive"),
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrNeedPositiveMinconf = InvalidParameterError{
|
|
|
|
errors.New("minconf must be positive"),
|
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
ErrAddressNotInWallet = btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWallet,
|
2014-12-12 09:54:26 +01:00
|
|
|
Message: "address not found in wallet",
|
2014-06-04 02:52:04 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
ErrAccountNameNotFound = btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWalletInvalidAccountName,
|
2014-12-12 09:54:26 +01:00
|
|
|
Message: "account name not found",
|
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
ErrUnloadedWallet = btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWallet,
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
Message: "Request requires a wallet but wallet has not loaded yet",
|
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
ErrWalletUnlockNeeded = btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWalletUnlockNeeded,
|
|
|
|
Message: "Enter the wallet passphrase with walletpassphrase first",
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrNotImportedAccount = btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWallet,
|
|
|
|
Message: "imported addresses must belong to the imported account",
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrNoTransactionInfo = btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCNoTxInfo,
|
|
|
|
Message: "No information for transaction",
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2015-04-16 18:54:56 +02:00
|
|
|
|
|
|
|
ErrReservedAccountName = btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInvalidParameter,
|
|
|
|
Message: "Account name is reserved by RPC server",
|
|
|
|
}
|
2014-06-04 02:52:04 +02:00
|
|
|
)
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// TODO(jrick): There are several error paths which 'replace' various errors
|
|
|
|
// with a more appropiate error from the btcjson package. Create a map of
|
|
|
|
// these replacements so they can be handled once after an RPC handler has
|
|
|
|
// returned and before the error is marshaled.
|
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
// confirmed checks whether a transaction at height txHeight has met minconf
|
|
|
|
// confirmations for a blockchain at height curHeight.
|
|
|
|
func confirmed(minconf, txHeight, curHeight int32) bool {
|
|
|
|
return confirms(txHeight, curHeight) >= minconf
|
|
|
|
}
|
|
|
|
|
|
|
|
// confirms returns the number of confirmations for a transaction in a block at
|
|
|
|
// height txHeight (or -1 for an unconfirmed tx) given the chain height
|
|
|
|
// curHeight.
|
|
|
|
func confirms(txHeight, curHeight int32) int32 {
|
|
|
|
switch {
|
|
|
|
case txHeight == -1, txHeight > curHeight:
|
|
|
|
return 0
|
|
|
|
default:
|
|
|
|
return curHeight - txHeight + 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-12 18:39:26 +02:00
|
|
|
type websocketClient struct {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
conn *websocket.Conn
|
|
|
|
authenticated bool
|
|
|
|
remoteAddr string
|
|
|
|
allRequests chan []byte
|
|
|
|
responses chan []byte
|
|
|
|
quit chan struct{} // closed on disconnect
|
2014-08-01 10:52:35 +02:00
|
|
|
wg sync.WaitGroup
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func newWebsocketClient(c *websocket.Conn, authenticated bool, remoteAddr string) *websocketClient {
|
|
|
|
return &websocketClient{
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
conn: c,
|
|
|
|
authenticated: authenticated,
|
|
|
|
remoteAddr: remoteAddr,
|
|
|
|
allRequests: make(chan []byte),
|
|
|
|
responses: make(chan []byte),
|
|
|
|
quit: make(chan struct{}),
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *websocketClient) send(b []byte) error {
|
|
|
|
select {
|
|
|
|
case c.responses <- b:
|
|
|
|
return nil
|
|
|
|
case <-c.quit:
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return errors.New("websocket client disconnected")
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
// isManagerLockedError returns whether or not the passed error is due to the
|
|
|
|
// address manager being locked.
|
|
|
|
func isManagerLockedError(err error) bool {
|
|
|
|
merr, ok := err.(waddrmgr.ManagerError)
|
|
|
|
return ok && merr.ErrorCode == waddrmgr.ErrLocked
|
|
|
|
}
|
|
|
|
|
|
|
|
// isManagerWrongPassphraseError returns whether or not the passed error is due
|
|
|
|
// to the address manager being provided with an invalid passprhase.
|
|
|
|
func isManagerWrongPassphraseError(err error) bool {
|
|
|
|
merr, ok := err.(waddrmgr.ManagerError)
|
|
|
|
return ok && merr.ErrorCode == waddrmgr.ErrWrongPassphrase
|
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
// isManagerDuplicateAddressError returns whether or not the passed error is due to a
|
2014-10-29 07:43:29 +01:00
|
|
|
// duplicate item being provided to the address manager.
|
2014-12-12 09:54:26 +01:00
|
|
|
func isManagerDuplicateAddressError(err error) bool {
|
2014-10-29 07:43:29 +01:00
|
|
|
merr, ok := err.(waddrmgr.ManagerError)
|
2014-12-12 09:54:26 +01:00
|
|
|
return ok && merr.ErrorCode == waddrmgr.ErrDuplicateAddress
|
|
|
|
}
|
2014-10-29 07:43:29 +01:00
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
// isManagerAddressNotFoundError returns whether or not the passed error is due to a
|
|
|
|
// the address not being found.
|
|
|
|
func isManagerAddressNotFoundError(err error) bool {
|
|
|
|
merr, ok := err.(waddrmgr.ManagerError)
|
|
|
|
return ok && merr.ErrorCode == waddrmgr.ErrAddressNotFound
|
|
|
|
}
|
|
|
|
|
|
|
|
// isManagerAccountNotFoundError returns whether or not the passed error is due
|
|
|
|
// to the account not being found.
|
|
|
|
func isManagerAccountNotFoundError(err error) bool {
|
|
|
|
merr, ok := err.(waddrmgr.ManagerError)
|
|
|
|
return ok && merr.ErrorCode == waddrmgr.ErrAccountNotFound
|
2014-10-29 07:43:29 +01:00
|
|
|
}
|
|
|
|
|
2014-06-12 18:39:26 +02:00
|
|
|
// parseListeners splits the list of listen addresses passed in addrs into
|
|
|
|
// IPv4 and IPv6 slices and returns them. This allows easy creation of the
|
|
|
|
// listeners on the correct interface "tcp4" and "tcp6". It also properly
|
|
|
|
// detects addresses which apply to "all interfaces" and adds the address to
|
|
|
|
// both slices.
|
|
|
|
func parseListeners(addrs []string) ([]string, []string, error) {
|
|
|
|
ipv4ListenAddrs := make([]string, 0, len(addrs)*2)
|
|
|
|
ipv6ListenAddrs := make([]string, 0, len(addrs)*2)
|
|
|
|
for _, addr := range addrs {
|
|
|
|
host, _, err := net.SplitHostPort(addr)
|
|
|
|
if err != nil {
|
|
|
|
// Shouldn't happen due to already being normalized.
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Empty host or host of * on plan9 is both IPv4 and IPv6.
|
|
|
|
if host == "" || (host == "*" && runtime.GOOS == "plan9") {
|
|
|
|
ipv4ListenAddrs = append(ipv4ListenAddrs, addr)
|
|
|
|
ipv6ListenAddrs = append(ipv6ListenAddrs, addr)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the IP.
|
|
|
|
ip := net.ParseIP(host)
|
|
|
|
if ip == nil {
|
|
|
|
return nil, nil, fmt.Errorf("'%s' is not a valid IP "+
|
|
|
|
"address", host)
|
|
|
|
}
|
|
|
|
|
|
|
|
// To4 returns nil when the IP is not an IPv4 address, so use
|
|
|
|
// this determine the address type.
|
|
|
|
if ip.To4() == nil {
|
|
|
|
ipv6ListenAddrs = append(ipv6ListenAddrs, addr)
|
|
|
|
} else {
|
|
|
|
ipv4ListenAddrs = append(ipv4ListenAddrs, addr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ipv4ListenAddrs, ipv6ListenAddrs, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// genCertPair generates a key/cert pair to the paths provided.
|
|
|
|
func genCertPair(certFile, keyFile string) error {
|
|
|
|
log.Infof("Generating TLS certificates...")
|
|
|
|
|
|
|
|
// Create directories for cert and key files if they do not yet exist.
|
|
|
|
certDir, _ := filepath.Split(certFile)
|
|
|
|
keyDir, _ := filepath.Split(keyFile)
|
|
|
|
if err := os.MkdirAll(certDir, 0700); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := os.MkdirAll(keyDir, 0700); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate cert pair.
|
|
|
|
org := "btcwallet autogenerated cert"
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
validUntil := time.Now().Add(time.Hour * 24 * 365 * 10)
|
2014-06-12 18:39:26 +02:00
|
|
|
cert, key, err := btcutil.NewTLSCertPair(org, validUntil, nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write cert and key files.
|
|
|
|
if err = ioutil.WriteFile(certFile, cert, 0666); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err = ioutil.WriteFile(keyFile, key, 0600); err != nil {
|
|
|
|
if rmErr := os.Remove(certFile); rmErr != nil {
|
|
|
|
log.Warnf("Cannot remove written certificates: %v", rmErr)
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Info("Done generating TLS certificates")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// rpcServer holds the items the RPC server may need to access (auth,
|
|
|
|
// config, shutdown, etc.)
|
|
|
|
type rpcServer struct {
|
2015-04-02 20:13:38 +02:00
|
|
|
wallet *wallet.Wallet
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
chainSvr *chain.Client
|
|
|
|
createOK bool
|
|
|
|
handlerLookup func(string) (requestHandler, bool)
|
|
|
|
handlerLock sync.Locker
|
|
|
|
|
|
|
|
listeners []net.Listener
|
|
|
|
authsha [sha256.Size]byte
|
|
|
|
upgrader websocket.Upgrader
|
|
|
|
|
|
|
|
maxPostClients int64 // Max concurrent HTTP POST clients.
|
|
|
|
maxWebsocketClients int64 // Max concurrent websocket clients.
|
|
|
|
|
|
|
|
// Channels to register or unregister a websocket client for
|
|
|
|
// websocket notifications.
|
|
|
|
registerWSC chan *websocketClient
|
|
|
|
unregisterWSC chan *websocketClient
|
|
|
|
|
|
|
|
// Channels read from other components from which notifications are
|
|
|
|
// created.
|
2015-02-19 21:01:22 +01:00
|
|
|
connectedBlocks <-chan waddrmgr.BlockStamp
|
|
|
|
disconnectedBlocks <-chan waddrmgr.BlockStamp
|
2015-04-06 21:03:24 +02:00
|
|
|
relevantTxs <-chan chain.RelevantTx
|
2015-02-19 21:01:22 +01:00
|
|
|
managerLocked <-chan bool
|
|
|
|
confirmedBalance <-chan btcutil.Amount
|
|
|
|
unconfirmedBalance <-chan btcutil.Amount
|
|
|
|
//chainServerConnected <-chan bool
|
|
|
|
registerWalletNtfns chan struct{}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
|
|
|
// enqueueNotification and dequeueNotification handle both sides of an
|
|
|
|
// infinitly growing queue for websocket client notifications.
|
|
|
|
enqueueNotification chan wsClientNotification
|
|
|
|
dequeueNotification chan wsClientNotification
|
|
|
|
|
|
|
|
// notificationHandlerQuit is closed when the notification handler
|
|
|
|
// goroutine shuts down. After this is closed, no more notifications
|
|
|
|
// will be sent to any websocket client response channel.
|
2014-07-14 16:24:41 +02:00
|
|
|
notificationHandlerQuit chan struct{}
|
2014-06-24 23:00:27 +02:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
wg sync.WaitGroup
|
|
|
|
quit chan struct{}
|
|
|
|
quitMtx sync.Mutex
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// newRPCServer creates a new server for serving RPC client connections, both
|
|
|
|
// HTTP POST and websocket.
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
func newRPCServer(listenAddrs []string, maxPost, maxWebsockets int64) (*rpcServer, error) {
|
2014-06-12 18:39:26 +02:00
|
|
|
login := cfg.Username + ":" + cfg.Password
|
|
|
|
auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login))
|
|
|
|
s := rpcServer{
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
handlerLookup: unloadedWalletHandlerFunc,
|
|
|
|
handlerLock: new(sync.Mutex),
|
|
|
|
authsha: sha256.Sum256([]byte(auth)),
|
|
|
|
maxPostClients: maxPost,
|
|
|
|
maxWebsocketClients: maxWebsockets,
|
2014-06-12 18:39:26 +02:00
|
|
|
upgrader: websocket.Upgrader{
|
|
|
|
// Allow all origins.
|
|
|
|
CheckOrigin: func(r *http.Request) bool { return true },
|
|
|
|
},
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
registerWSC: make(chan *websocketClient),
|
|
|
|
unregisterWSC: make(chan *websocketClient),
|
|
|
|
registerWalletNtfns: make(chan struct{}),
|
|
|
|
enqueueNotification: make(chan wsClientNotification),
|
|
|
|
dequeueNotification: make(chan wsClientNotification),
|
2014-07-14 16:24:41 +02:00
|
|
|
notificationHandlerQuit: make(chan struct{}),
|
|
|
|
quit: make(chan struct{}),
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
2015-01-09 08:41:42 +01:00
|
|
|
// Setup TLS if not disabled.
|
|
|
|
listenFunc := net.Listen
|
|
|
|
if !cfg.DisableServerTLS {
|
|
|
|
// Check for existence of cert file and key file
|
|
|
|
if !fileExists(cfg.RPCKey) && !fileExists(cfg.RPCCert) {
|
|
|
|
// if both files do not exist, we generate them.
|
|
|
|
err := genCertPair(cfg.RPCCert, cfg.RPCKey)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
keypair, err := tls.LoadX509KeyPair(cfg.RPCCert, cfg.RPCKey)
|
2014-06-12 18:39:26 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2015-01-09 08:41:42 +01:00
|
|
|
tlsConfig := tls.Config{
|
|
|
|
Certificates: []tls.Certificate{keypair},
|
|
|
|
MinVersion: tls.VersionTLS12,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change the standard net.Listen function to the tls one.
|
|
|
|
listenFunc = func(net string, laddr string) (net.Listener, error) {
|
|
|
|
return tls.Listen(net, laddr, &tlsConfig)
|
|
|
|
}
|
2015-01-23 23:08:34 +01:00
|
|
|
} else {
|
|
|
|
log.Info("Server TLS is disabled")
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ipv4ListenAddrs, ipv6ListenAddrs, err := parseListeners(listenAddrs)
|
2015-01-09 08:41:42 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2014-06-12 18:39:26 +02:00
|
|
|
listeners := make([]net.Listener, 0,
|
|
|
|
len(ipv6ListenAddrs)+len(ipv4ListenAddrs))
|
|
|
|
for _, addr := range ipv4ListenAddrs {
|
2015-01-09 08:41:42 +01:00
|
|
|
listener, err := listenFunc("tcp4", addr)
|
2014-06-12 18:39:26 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Warnf("RPCS: Can't listen on %s: %v", addr,
|
|
|
|
err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
listeners = append(listeners, listener)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, addr := range ipv6ListenAddrs {
|
2015-01-09 08:41:42 +01:00
|
|
|
listener, err := listenFunc("tcp6", addr)
|
2014-06-12 18:39:26 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Warnf("RPCS: Can't listen on %s: %v", addr,
|
|
|
|
err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
listeners = append(listeners, listener)
|
|
|
|
}
|
|
|
|
if len(listeners) == 0 {
|
|
|
|
return nil, errors.New("no valid listen address")
|
|
|
|
}
|
|
|
|
|
|
|
|
s.listeners = listeners
|
|
|
|
|
|
|
|
return &s, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start starts a HTTP server to provide standard RPC and extension
|
|
|
|
// websocket connections for any number of btcwallet clients.
|
|
|
|
func (s *rpcServer) Start() {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
s.wg.Add(3)
|
|
|
|
go s.notificationListener()
|
|
|
|
go s.notificationQueue()
|
|
|
|
go s.notificationHandler()
|
2014-06-12 18:39:26 +02:00
|
|
|
|
|
|
|
log.Trace("Starting RPC server")
|
|
|
|
|
|
|
|
serveMux := http.NewServeMux()
|
|
|
|
const rpcAuthTimeoutSeconds = 10
|
2014-07-03 03:36:38 +02:00
|
|
|
|
2014-06-12 18:39:26 +02:00
|
|
|
httpServer := &http.Server{
|
|
|
|
Handler: serveMux,
|
|
|
|
|
|
|
|
// Timeout connections which don't complete the initial
|
|
|
|
// handshake within the allowed timeframe.
|
|
|
|
ReadTimeout: time.Second * rpcAuthTimeoutSeconds,
|
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
serveMux.Handle("/", throttledFn(s.maxPostClients,
|
|
|
|
func(w http.ResponseWriter, r *http.Request) {
|
2014-07-03 03:36:38 +02:00
|
|
|
w.Header().Set("Connection", "close")
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
|
|
r.Close = true
|
2014-06-12 18:39:26 +02:00
|
|
|
|
2014-07-03 03:36:38 +02:00
|
|
|
if err := s.checkAuthHeader(r); err != nil {
|
|
|
|
log.Warnf("Unauthorized client connection attempt")
|
|
|
|
http.Error(w, "401 Unauthorized.", http.StatusUnauthorized)
|
|
|
|
return
|
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
s.wg.Add(1)
|
2014-07-03 03:36:38 +02:00
|
|
|
s.PostClientRPC(w, r)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
s.wg.Done()
|
|
|
|
}))
|
2014-07-03 03:36:38 +02:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
serveMux.Handle("/ws", throttledFn(s.maxWebsocketClients,
|
|
|
|
func(w http.ResponseWriter, r *http.Request) {
|
2014-07-03 03:36:38 +02:00
|
|
|
authenticated := false
|
|
|
|
switch s.checkAuthHeader(r) {
|
|
|
|
case nil:
|
|
|
|
authenticated = true
|
|
|
|
case ErrNoAuth:
|
|
|
|
// nothing
|
|
|
|
default:
|
|
|
|
// If auth was supplied but incorrect, rather than simply
|
|
|
|
// being missing, immediately terminate the connection.
|
|
|
|
log.Warnf("Disconnecting improperly authorized " +
|
|
|
|
"websocket client")
|
|
|
|
http.Error(w, "401 Unauthorized.", http.StatusUnauthorized)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
conn, err := s.upgrader.Upgrade(w, r, nil)
|
|
|
|
if err != nil {
|
|
|
|
log.Warnf("Cannot websocket upgrade client %s: %v",
|
|
|
|
r.RemoteAddr, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
wsc := newWebsocketClient(conn, authenticated, r.RemoteAddr)
|
|
|
|
s.WebsocketClientRPC(wsc)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}))
|
2014-06-12 18:39:26 +02:00
|
|
|
|
|
|
|
for _, listener := range s.listeners {
|
|
|
|
s.wg.Add(1)
|
|
|
|
go func(listener net.Listener) {
|
|
|
|
log.Infof("RPCS: RPC server listening on %s", listener.Addr())
|
2014-06-24 23:00:27 +02:00
|
|
|
_ = httpServer.Serve(listener)
|
2014-06-12 18:39:26 +02:00
|
|
|
log.Tracef("RPCS: RPC listener done for %s", listener.Addr())
|
|
|
|
s.wg.Done()
|
|
|
|
}(listener)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-24 23:00:27 +02:00
|
|
|
// Stop gracefully shuts down the rpc server by stopping and disconnecting all
|
|
|
|
// clients, disconnecting the chain server connection, and closing the wallet's
|
|
|
|
// account files.
|
|
|
|
func (s *rpcServer) Stop() {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
s.quitMtx.Lock()
|
|
|
|
defer s.quitMtx.Unlock()
|
|
|
|
|
2014-06-24 23:00:27 +02:00
|
|
|
select {
|
|
|
|
case <-s.quit:
|
|
|
|
return
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Warn("Server shutting down")
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Stop the connected wallet and chain server, if any.
|
|
|
|
s.handlerLock.Lock()
|
|
|
|
if s.wallet != nil {
|
|
|
|
s.wallet.Stop()
|
|
|
|
}
|
|
|
|
if s.chainSvr != nil {
|
|
|
|
s.chainSvr.Stop()
|
|
|
|
}
|
|
|
|
s.handlerLock.Unlock()
|
|
|
|
|
|
|
|
// Stop all the listeners.
|
2014-06-24 23:00:27 +02:00
|
|
|
for _, listener := range s.listeners {
|
|
|
|
err := listener.Close()
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Cannot close listener %s: %v",
|
|
|
|
listener.Addr(), err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Signal the remaining goroutines to stop.
|
|
|
|
close(s.quit)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *rpcServer) WaitForShutdown() {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// First wait for the wallet and chain server to stop, if they
|
|
|
|
// were ever set.
|
|
|
|
s.handlerLock.Lock()
|
|
|
|
if s.wallet != nil {
|
|
|
|
s.wallet.WaitForShutdown()
|
|
|
|
}
|
|
|
|
if s.chainSvr != nil {
|
|
|
|
s.chainSvr.WaitForShutdown()
|
|
|
|
}
|
|
|
|
s.handlerLock.Unlock()
|
|
|
|
|
2014-06-24 23:00:27 +02:00
|
|
|
s.wg.Wait()
|
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
type noopLocker struct{}
|
|
|
|
|
|
|
|
func (noopLocker) Lock() {}
|
|
|
|
func (noopLocker) Unlock() {}
|
|
|
|
|
|
|
|
// SetWallet sets the wallet dependency component needed to run a fully
|
|
|
|
// functional bitcoin wallet RPC server. If wallet is nil, this informs the
|
|
|
|
// server that the createencryptedwallet RPC method is valid and must be called
|
|
|
|
// by a client before any other wallet methods are allowed.
|
2015-04-02 20:13:38 +02:00
|
|
|
func (s *rpcServer) SetWallet(wallet *wallet.Wallet) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
s.handlerLock.Lock()
|
|
|
|
defer s.handlerLock.Unlock()
|
|
|
|
|
|
|
|
if wallet == nil {
|
|
|
|
s.handlerLookup = missingWalletHandlerFunc
|
|
|
|
s.createOK = true
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
s.wallet = wallet
|
|
|
|
s.registerWalletNtfns <- struct{}{}
|
|
|
|
|
|
|
|
if s.chainSvr != nil {
|
|
|
|
// If the chain server rpc client is also set, there's no reason
|
|
|
|
// to keep the mutex around. Make the locker simply execute
|
|
|
|
// noops instead.
|
|
|
|
s.handlerLock = noopLocker{}
|
|
|
|
|
|
|
|
// With both the wallet and chain server set, all handlers are
|
|
|
|
// ok to run.
|
|
|
|
s.handlerLookup = lookupAnyHandler
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetChainServer sets the chain server client component needed to run a fully
|
|
|
|
// functional bitcoin wallet RPC server. This should be set even before the
|
|
|
|
// client is connected, as any request handlers should return the error for
|
|
|
|
// a never connected client, rather than panicking (or never being looked up)
|
|
|
|
// if the client was never conneceted and added.
|
|
|
|
func (s *rpcServer) SetChainServer(chainSvr *chain.Client) {
|
|
|
|
s.handlerLock.Lock()
|
|
|
|
defer s.handlerLock.Unlock()
|
|
|
|
|
|
|
|
s.chainSvr = chainSvr
|
2014-07-30 16:47:50 +02:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if s.wallet != nil {
|
|
|
|
// If the wallet had already been set, there's no reason to keep
|
|
|
|
// the mutex around. Make the locker simply execute noops
|
|
|
|
// instead.
|
|
|
|
s.handlerLock = noopLocker{}
|
|
|
|
|
|
|
|
// With both the chain server and wallet set, all handlers are
|
|
|
|
// ok to run.
|
|
|
|
s.handlerLookup = lookupAnyHandler
|
2014-07-28 16:51:49 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// HandlerClosure creates a closure function for handling requests of the given
|
|
|
|
// method. This may be a request that is handled directly by btcwallet, or
|
|
|
|
// a chain server request that is handled by passing the request down to btcd.
|
|
|
|
//
|
|
|
|
// NOTE: These handlers do not handle special cases, such as the authenticate
|
2014-10-29 07:43:29 +01:00
|
|
|
// method. Each of these must be checked beforehand (the method is already
|
|
|
|
// known) and handled accordingly.
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
func (s *rpcServer) HandlerClosure(method string) requestHandlerClosure {
|
|
|
|
s.handlerLock.Lock()
|
|
|
|
defer s.handlerLock.Unlock()
|
|
|
|
|
|
|
|
// With the lock held, make copies of these pointers for the closure.
|
|
|
|
wallet := s.wallet
|
|
|
|
chainSvr := s.chainSvr
|
|
|
|
|
|
|
|
if handler, ok := s.handlerLookup(method); ok {
|
2015-04-17 22:05:38 +02:00
|
|
|
return func(req *btcjson.Request) (interface{}, *btcjson.RPCError) {
|
|
|
|
cmd, err := btcjson.UnmarshalCmd(req)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, btcjson.ErrRPCInvalidRequest
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
res, err := handler(wallet, chainSvr, cmd)
|
|
|
|
if err != nil {
|
|
|
|
return nil, jsonError(err)
|
|
|
|
}
|
|
|
|
return res, nil
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
return func(req *btcjson.Request) (interface{}, *btcjson.RPCError) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if chainSvr == nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &btcjson.RPCError{
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
Code: -1,
|
|
|
|
Message: "Chain server is disconnected",
|
|
|
|
}
|
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
res, err := chainSvr.RawRequest(req.Method, req.Params)
|
|
|
|
if err != nil {
|
|
|
|
return nil, jsonError(err)
|
|
|
|
}
|
|
|
|
return &res, nil
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-12 18:39:26 +02:00
|
|
|
// ErrNoAuth represents an error where authentication could not succeed
|
|
|
|
// due to a missing Authorization HTTP header.
|
|
|
|
var ErrNoAuth = errors.New("no auth")
|
|
|
|
|
|
|
|
// checkAuthHeader checks the HTTP Basic authentication supplied by a client
|
|
|
|
// in the HTTP request r. It errors with ErrNoAuth if the request does not
|
|
|
|
// contain the Authorization header, or another non-nil error if the
|
|
|
|
// authentication was provided but incorrect.
|
|
|
|
//
|
|
|
|
// This check is time-constant.
|
|
|
|
func (s *rpcServer) checkAuthHeader(r *http.Request) error {
|
|
|
|
authhdr := r.Header["Authorization"]
|
|
|
|
if len(authhdr) == 0 {
|
|
|
|
return ErrNoAuth
|
|
|
|
}
|
|
|
|
|
|
|
|
authsha := sha256.Sum256([]byte(authhdr[0]))
|
|
|
|
cmp := subtle.ConstantTimeCompare(authsha[:], s.authsha[:])
|
|
|
|
if cmp != 1 {
|
|
|
|
return errors.New("bad auth")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2014-07-03 03:36:38 +02:00
|
|
|
// throttledFn wraps an http.HandlerFunc with throttling of concurrent active
|
|
|
|
// clients by responding with an HTTP 429 when the threshold is crossed.
|
|
|
|
func throttledFn(threshold int64, f http.HandlerFunc) http.Handler {
|
|
|
|
return throttled(threshold, f)
|
|
|
|
}
|
|
|
|
|
|
|
|
// throttled wraps an http.Handler with throttling of concurrent active
|
|
|
|
// clients by responding with an HTTP 429 when the threshold is crossed.
|
|
|
|
func throttled(threshold int64, h http.Handler) http.Handler {
|
|
|
|
var active int64
|
|
|
|
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
current := atomic.AddInt64(&active, 1)
|
|
|
|
defer atomic.AddInt64(&active, -1)
|
|
|
|
|
|
|
|
if current-1 >= threshold {
|
|
|
|
log.Warnf("Reached threshold of %d concurrent active clients", threshold)
|
|
|
|
http.Error(w, "429 Too Many Requests", 429)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
h.ServeHTTP(w, r)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
// sanitizeRequest returns a sanitized string for the request which may be
|
|
|
|
// safely logged. It is intended to strip private keys, passphrases, and any
|
|
|
|
// other secrets from request parameters before they may be saved to a log file.
|
|
|
|
func sanitizeRequest(r *btcjson.Request) string {
|
2014-08-14 21:23:47 +02:00
|
|
|
// These are considered unsafe to log, so sanitize parameters.
|
|
|
|
switch r.Method {
|
|
|
|
case "encryptwallet", "importprivkey", "importwallet",
|
|
|
|
"signrawtransaction", "walletpassphrase",
|
|
|
|
"walletpassphrasechange":
|
|
|
|
|
|
|
|
return fmt.Sprintf(`{"id":%v,"method":"%s","params":SANITIZED %d parameters}`,
|
|
|
|
r.ID, r.Method, len(r.Params))
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf(`{"id":%v,"method":"%s","params":%v}`, r.ID,
|
|
|
|
r.Method, r.Params)
|
|
|
|
}
|
|
|
|
|
2014-06-12 18:39:26 +02:00
|
|
|
// idPointer returns a pointer to the passed ID, or nil if the interface is nil.
|
|
|
|
// Interface pointers are usually a red flag of doing something incorrectly,
|
|
|
|
// but this is only implemented here to work around an oddity with btcjson,
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// which uses empty interface pointers for response IDs.
|
2014-06-12 18:39:26 +02:00
|
|
|
func idPointer(id interface{}) (p *interface{}) {
|
|
|
|
if id != nil {
|
|
|
|
p = &id
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// invalidAuth checks whether a websocket request is a valid (parsable)
|
|
|
|
// authenticate request and checks the supplied username and passphrase
|
|
|
|
// against the server auth.
|
2015-04-17 22:05:38 +02:00
|
|
|
func (s *rpcServer) invalidAuth(req *btcjson.Request) bool {
|
|
|
|
cmd, err := btcjson.UnmarshalCmd(req)
|
2014-06-12 18:39:26 +02:00
|
|
|
if err != nil {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return false
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
authCmd, ok := cmd.(*btcjson.AuthenticateCmd)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if !ok {
|
|
|
|
return false
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Check credentials.
|
|
|
|
login := authCmd.Username + ":" + authCmd.Passphrase
|
|
|
|
auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login))
|
|
|
|
authSha := sha256.Sum256([]byte(auth))
|
|
|
|
return subtle.ConstantTimeCompare(authSha[:], s.authsha[:]) != 1
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
func (s *rpcServer) WebsocketClientRead(wsc *websocketClient) {
|
|
|
|
for {
|
|
|
|
_, request, err := wsc.conn.ReadMessage()
|
|
|
|
if err != nil {
|
|
|
|
if err != io.EOF && err != io.ErrUnexpectedEOF {
|
|
|
|
log.Warnf("Websocket receive failed from client %s: %v",
|
|
|
|
wsc.remoteAddr, err)
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
close(wsc.allRequests)
|
|
|
|
break
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
wsc.allRequests <- request
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
func (s *rpcServer) WebsocketClientRespond(wsc *websocketClient) {
|
2014-07-04 07:54:45 +02:00
|
|
|
// A for-select with a read of the quit channel is used instead of a
|
|
|
|
// for-range to provide clean shutdown. This is necessary due to
|
|
|
|
// WebsocketClientRead (which sends to the allRequests chan) not closing
|
|
|
|
// allRequests during shutdown if the remote websocket client is still
|
|
|
|
// connected.
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
out:
|
2014-07-04 07:54:45 +02:00
|
|
|
for {
|
|
|
|
select {
|
2015-04-17 22:05:38 +02:00
|
|
|
case reqBytes, ok := <-wsc.allRequests:
|
2014-07-04 07:54:45 +02:00
|
|
|
if !ok {
|
|
|
|
// client disconnected
|
2014-06-12 18:39:26 +02:00
|
|
|
break out
|
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
var req btcjson.Request
|
|
|
|
err := json.Unmarshal(reqBytes, &req)
|
|
|
|
if err != nil {
|
2014-07-04 07:54:45 +02:00
|
|
|
if !wsc.authenticated {
|
|
|
|
// Disconnect immediately.
|
|
|
|
break out
|
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
resp := makeResponse(req.ID, nil,
|
|
|
|
btcjson.ErrRPCInvalidRequest)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
mresp, err := json.Marshal(resp)
|
|
|
|
// We expect the marshal to succeed. If it
|
|
|
|
// doesn't, it indicates some non-marshalable
|
|
|
|
// type in the response.
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
err = wsc.send(mresp)
|
2014-07-04 07:54:45 +02:00
|
|
|
if err != nil {
|
|
|
|
break out
|
|
|
|
}
|
|
|
|
continue
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
if req.Method == "authenticate" {
|
|
|
|
if wsc.authenticated || s.invalidAuth(&req) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Disconnect immediately.
|
|
|
|
break out
|
|
|
|
}
|
|
|
|
wsc.authenticated = true
|
2015-04-17 22:05:38 +02:00
|
|
|
resp := makeResponse(req.ID, nil, nil)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Expected to never fail.
|
|
|
|
mresp, err := json.Marshal(resp)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
err = wsc.send(mresp)
|
|
|
|
if err != nil {
|
|
|
|
break out
|
|
|
|
}
|
2014-08-19 15:03:06 +02:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if !wsc.authenticated {
|
|
|
|
// Disconnect immediately.
|
|
|
|
break out
|
|
|
|
}
|
2014-06-12 18:39:26 +02:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
switch req.Method {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case "stop":
|
|
|
|
s.Stop()
|
2015-04-17 22:05:38 +02:00
|
|
|
resp := makeResponse(req.ID,
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
"btcwallet stopping.", nil)
|
|
|
|
mresp, err := json.Marshal(resp)
|
|
|
|
// Expected to never fail.
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
err = wsc.send(mresp)
|
|
|
|
if err != nil {
|
|
|
|
break out
|
|
|
|
}
|
2014-06-12 18:39:26 +02:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
default:
|
2015-04-17 22:05:38 +02:00
|
|
|
req := req // Copy for the closure
|
|
|
|
f := s.HandlerClosure(req.Method)
|
2014-08-01 10:52:35 +02:00
|
|
|
wsc.wg.Add(1)
|
2015-04-17 22:05:38 +02:00
|
|
|
go func() {
|
|
|
|
resp, jsonErr := f(&req)
|
|
|
|
mresp, err := btcjson.MarshalResponse(req.ID, resp, jsonErr)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
log.Errorf("Unable to marshal response: %v", err)
|
|
|
|
} else {
|
|
|
|
_ = wsc.send(mresp)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2014-08-01 10:52:35 +02:00
|
|
|
wsc.wg.Done()
|
2015-04-17 22:05:38 +02:00
|
|
|
}()
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
2014-06-25 18:40:31 +02:00
|
|
|
case <-s.quit:
|
|
|
|
break out
|
|
|
|
}
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
2014-07-14 16:24:41 +02:00
|
|
|
|
|
|
|
// Remove websocket client from notification group, or if the server is
|
|
|
|
// shutting down, wait until the notification handler has finished
|
|
|
|
// running. This is needed to ensure that no more notifications will be
|
|
|
|
// sent to the client's responses chan before it's closed below.
|
|
|
|
select {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case s.unregisterWSC <- wsc:
|
2014-07-14 16:24:41 +02:00
|
|
|
case <-s.quit:
|
|
|
|
<-s.notificationHandlerQuit
|
|
|
|
}
|
|
|
|
|
2014-08-01 10:52:35 +02:00
|
|
|
// allow client to disconnect after all handler goroutines are done
|
|
|
|
wsc.wg.Wait()
|
|
|
|
close(wsc.responses)
|
2014-06-12 18:39:26 +02:00
|
|
|
s.wg.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *rpcServer) WebsocketClientSend(wsc *websocketClient) {
|
|
|
|
const deadline time.Duration = 2 * time.Second
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
out:
|
|
|
|
for {
|
|
|
|
select {
|
2014-08-01 10:52:35 +02:00
|
|
|
case response, ok := <-wsc.responses:
|
|
|
|
if !ok {
|
|
|
|
// client disconnected
|
|
|
|
break out
|
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
err := wsc.conn.SetWriteDeadline(time.Now().Add(deadline))
|
|
|
|
if err != nil {
|
|
|
|
log.Warnf("Cannot set write deadline on "+
|
|
|
|
"client %s: %v", wsc.remoteAddr, err)
|
|
|
|
}
|
|
|
|
err = wsc.conn.WriteMessage(websocket.TextMessage,
|
|
|
|
response)
|
|
|
|
if err != nil {
|
|
|
|
log.Warnf("Failed websocket send to client "+
|
|
|
|
"%s: %v", wsc.remoteAddr, err)
|
|
|
|
break out
|
|
|
|
}
|
|
|
|
|
|
|
|
case <-s.quit:
|
|
|
|
break out
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
close(wsc.quit)
|
|
|
|
log.Infof("Disconnected websocket client %s", wsc.remoteAddr)
|
|
|
|
s.wg.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
// WebsocketClientRPC starts the goroutines to serve JSON-RPC requests and
|
|
|
|
// notifications over a websocket connection for a single client.
|
|
|
|
func (s *rpcServer) WebsocketClientRPC(wsc *websocketClient) {
|
|
|
|
log.Infof("New websocket client %s", wsc.remoteAddr)
|
|
|
|
|
|
|
|
// Clear the read deadline set before the websocket hijacked
|
|
|
|
// the connection.
|
|
|
|
if err := wsc.conn.SetReadDeadline(time.Time{}); err != nil {
|
|
|
|
log.Warnf("Cannot remove read deadline: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add client context so notifications duplicated to each
|
|
|
|
// client are received by this client.
|
2014-06-25 18:40:31 +02:00
|
|
|
select {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case s.registerWSC <- wsc:
|
2014-06-25 18:40:31 +02:00
|
|
|
case <-s.quit:
|
|
|
|
return
|
|
|
|
}
|
2014-06-12 18:39:26 +02:00
|
|
|
|
2014-07-04 07:54:45 +02:00
|
|
|
// WebsocketClientRead is intentionally not run with the waitgroup
|
|
|
|
// so it is ignored during shutdown. This is to prevent a hang during
|
|
|
|
// shutdown where the goroutine is blocked on a read of the
|
|
|
|
// websocket connection if the client is still connected.
|
2014-06-12 18:39:26 +02:00
|
|
|
go s.WebsocketClientRead(wsc)
|
2014-07-04 07:54:45 +02:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
s.wg.Add(2)
|
2014-06-12 18:39:26 +02:00
|
|
|
go s.WebsocketClientRespond(wsc)
|
|
|
|
go s.WebsocketClientSend(wsc)
|
|
|
|
|
2014-07-03 03:36:38 +02:00
|
|
|
<-wsc.quit
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// maxRequestSize specifies the maximum number of bytes in the request body
|
|
|
|
// that may be read from a client. This is currently limited to 4MB.
|
|
|
|
const maxRequestSize = 1024 * 1024 * 4
|
|
|
|
|
|
|
|
// PostClientRPC processes and replies to a JSON-RPC client request.
|
|
|
|
func (s *rpcServer) PostClientRPC(w http.ResponseWriter, r *http.Request) {
|
|
|
|
body := http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
rpcRequest, err := ioutil.ReadAll(body)
|
|
|
|
if err != nil {
|
|
|
|
// TODO: what if the underlying reader errored?
|
|
|
|
http.Error(w, "413 Request Too Large.",
|
|
|
|
http.StatusRequestEntityTooLarge)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// First check whether wallet has a handler for this request's method.
|
|
|
|
// If unfound, the request is sent to the chain server for further
|
|
|
|
// processing. While checking the methods, disallow authenticate
|
|
|
|
// requests, as they are invalid for HTTP POST clients.
|
2015-04-17 22:05:38 +02:00
|
|
|
var req btcjson.Request
|
|
|
|
err = json.Unmarshal(rpcRequest, &req)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
resp, err := btcjson.MarshalResponse(req.ID, nil, btcjson.ErrRPCInvalidRequest)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
log.Errorf("Unable to marshal response: %v", err)
|
|
|
|
http.Error(w, "500 Internal Server Error",
|
|
|
|
http.StatusInternalServerError)
|
|
|
|
return
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
_, err = w.Write(resp)
|
2014-06-12 18:39:26 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Warnf("Cannot write invalid request request to "+
|
|
|
|
"client: %v", err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
// Create the response and error from the request. Two special cases
|
2014-10-29 07:43:29 +01:00
|
|
|
// are handled for the authenticate and stop request methods.
|
2015-04-17 22:05:38 +02:00
|
|
|
var res interface{}
|
|
|
|
var jsonErr *btcjson.RPCError
|
|
|
|
switch req.Method {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case "authenticate":
|
|
|
|
// Drop it.
|
2014-06-12 18:39:26 +02:00
|
|
|
return
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case "stop":
|
|
|
|
s.Stop()
|
2015-04-17 22:05:38 +02:00
|
|
|
res = "btcwallet stopping"
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
default:
|
2015-04-17 22:05:38 +02:00
|
|
|
res, jsonErr = s.HandlerClosure(req.Method)(&req)
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Marshal and send.
|
2015-04-17 22:05:38 +02:00
|
|
|
mresp, err := btcjson.MarshalResponse(req.ID, res, jsonErr)
|
2014-06-12 18:39:26 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
log.Errorf("Unable to marshal response: %v", err)
|
|
|
|
http.Error(w, "500 Internal Server Error", http.StatusInternalServerError)
|
|
|
|
return
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
_, err = w.Write(mresp)
|
|
|
|
if err != nil {
|
2014-06-12 18:39:26 +02:00
|
|
|
log.Warnf("Unable to respond to client: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Notification messages for websocket clients.
|
|
|
|
type (
|
|
|
|
wsClientNotification interface {
|
|
|
|
// This returns a slice only because some of these types result
|
|
|
|
// in multpile client notifications.
|
2015-04-17 22:05:38 +02:00
|
|
|
notificationCmds(w *wallet.Wallet) []interface{}
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
blockConnected waddrmgr.BlockStamp
|
|
|
|
blockDisconnected waddrmgr.BlockStamp
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
relevantTx chain.RelevantTx
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
managerLocked bool
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
|
|
|
confirmedBalance btcutil.Amount
|
|
|
|
unconfirmedBalance btcutil.Amount
|
|
|
|
|
|
|
|
btcdConnected bool
|
|
|
|
)
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
func (b blockConnected) notificationCmds(w *wallet.Wallet) []interface{} {
|
|
|
|
n := btcjson.NewBlockConnectedNtfn(b.Hash.String(), b.Height)
|
|
|
|
return []interface{}{n}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
func (b blockDisconnected) notificationCmds(w *wallet.Wallet) []interface{} {
|
|
|
|
n := btcjson.NewBlockDisconnectedNtfn(b.Hash.String(), b.Height)
|
|
|
|
return []interface{}{n}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
func (t relevantTx) notificationCmds(w *wallet.Wallet) []interface{} {
|
2015-04-06 21:03:24 +02:00
|
|
|
syncBlock := w.Manager.SyncedTo()
|
|
|
|
|
|
|
|
var block *wtxmgr.Block
|
|
|
|
if t.Block != nil {
|
|
|
|
block = &t.Block.Block
|
2014-12-12 09:54:26 +01:00
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
details, err := w.TxStore.UniqueTxDetails(&t.TxRecord.Hash, block)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
2015-04-06 21:03:24 +02:00
|
|
|
log.Errorf("Cannot fetch transaction details for "+
|
|
|
|
"client notification: %v", err)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return nil
|
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
if details == nil {
|
|
|
|
log.Errorf("No details found for client transaction notification")
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return nil
|
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
|
|
|
|
ltr := wallet.ListTransactions(details, syncBlock.Height, activeNet.Params)
|
2015-04-17 22:05:38 +02:00
|
|
|
ntfns := make([]interface{}, len(ltr))
|
2015-04-06 21:03:24 +02:00
|
|
|
for i := range ntfns {
|
2015-04-17 22:05:38 +02:00
|
|
|
ntfns[i] = btcjson.NewNewTxNtfn(ltr[i].Account, ltr[i])
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
return ntfns
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
func (l managerLocked) notificationCmds(w *wallet.Wallet) []interface{} {
|
|
|
|
n := btcjson.NewWalletLockStateNtfn(bool(l))
|
|
|
|
return []interface{}{n}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
func (b confirmedBalance) notificationCmds(w *wallet.Wallet) []interface{} {
|
|
|
|
n := btcjson.NewAccountBalanceNtfn("",
|
2014-12-12 09:54:26 +01:00
|
|
|
btcutil.Amount(b).ToBTC(), true)
|
2015-04-17 22:05:38 +02:00
|
|
|
return []interface{}{n}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
func (b unconfirmedBalance) notificationCmds(w *wallet.Wallet) []interface{} {
|
|
|
|
n := btcjson.NewAccountBalanceNtfn("",
|
2014-12-12 09:54:26 +01:00
|
|
|
btcutil.Amount(b).ToBTC(), false)
|
2015-04-17 22:05:38 +02:00
|
|
|
return []interface{}{n}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
func (b btcdConnected) notificationCmds(w *wallet.Wallet) []interface{} {
|
|
|
|
n := btcjson.NewBtcdConnectedNtfn(bool(b))
|
|
|
|
return []interface{}{n}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *rpcServer) notificationListener() {
|
|
|
|
out:
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case n := <-s.connectedBlocks:
|
|
|
|
s.enqueueNotification <- blockConnected(n)
|
|
|
|
case n := <-s.disconnectedBlocks:
|
|
|
|
s.enqueueNotification <- blockDisconnected(n)
|
2015-04-06 21:03:24 +02:00
|
|
|
case n := <-s.relevantTxs:
|
|
|
|
s.enqueueNotification <- relevantTx(n)
|
2014-10-29 07:43:29 +01:00
|
|
|
case n := <-s.managerLocked:
|
|
|
|
s.enqueueNotification <- managerLocked(n)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case n := <-s.confirmedBalance:
|
|
|
|
s.enqueueNotification <- confirmedBalance(n)
|
|
|
|
case n := <-s.unconfirmedBalance:
|
|
|
|
s.enqueueNotification <- unconfirmedBalance(n)
|
|
|
|
|
|
|
|
// Registration of all notifications is done by the handler so
|
|
|
|
// it doesn't require another rpcServer mutex.
|
|
|
|
case <-s.registerWalletNtfns:
|
|
|
|
connectedBlocks, err := s.wallet.ListenConnectedBlocks()
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Could not register for new "+
|
|
|
|
"connected block notifications: %v",
|
|
|
|
err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
disconnectedBlocks, err := s.wallet.ListenDisconnectedBlocks()
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Could not register for new "+
|
|
|
|
"disconnected block notifications: %v",
|
|
|
|
err)
|
|
|
|
continue
|
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
relevantTxs, err := s.wallet.ListenRelevantTxs()
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
2015-04-06 21:03:24 +02:00
|
|
|
log.Errorf("Could not register for new relevant "+
|
|
|
|
"transaction notifications: %v", err)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
continue
|
|
|
|
}
|
2014-10-29 07:43:29 +01:00
|
|
|
managerLocked, err := s.wallet.ListenLockStatus()
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
2014-10-29 07:43:29 +01:00
|
|
|
log.Errorf("Could not register for manager "+
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
"lock state changes: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
confirmedBalance, err := s.wallet.ListenConfirmedBalance()
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Could not register for confirmed "+
|
|
|
|
"balance changes: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
unconfirmedBalance, err := s.wallet.ListenUnconfirmedBalance()
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("Could not register for unconfirmed "+
|
|
|
|
"balance changes: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
s.connectedBlocks = connectedBlocks
|
|
|
|
s.disconnectedBlocks = disconnectedBlocks
|
2015-04-06 21:03:24 +02:00
|
|
|
s.relevantTxs = relevantTxs
|
2014-10-29 07:43:29 +01:00
|
|
|
s.managerLocked = managerLocked
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
s.confirmedBalance = confirmedBalance
|
|
|
|
s.unconfirmedBalance = unconfirmedBalance
|
2014-07-30 16:47:50 +02:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case <-s.quit:
|
|
|
|
break out
|
|
|
|
}
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
close(s.enqueueNotification)
|
|
|
|
go s.drainNotifications()
|
|
|
|
s.wg.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *rpcServer) drainNotifications() {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-s.connectedBlocks:
|
|
|
|
case <-s.disconnectedBlocks:
|
2015-04-06 21:03:24 +02:00
|
|
|
case <-s.relevantTxs:
|
|
|
|
case <-s.managerLocked:
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case <-s.confirmedBalance:
|
|
|
|
case <-s.unconfirmedBalance:
|
2014-07-29 15:36:28 +02:00
|
|
|
case <-s.registerWalletNtfns:
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-13 16:03:36 +02:00
|
|
|
// notificationQueue manages an infinitly-growing queue of notifications that
|
|
|
|
// wallet websocket clients may be interested in. It quits when the
|
2014-10-29 07:43:29 +01:00
|
|
|
// enqueueNotification channel is closed, dropping any still pending
|
2014-08-13 16:03:36 +02:00
|
|
|
// notifications.
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
func (s *rpcServer) notificationQueue() {
|
|
|
|
var q []wsClientNotification
|
|
|
|
var dequeue chan<- wsClientNotification
|
|
|
|
skipQueue := s.dequeueNotification
|
|
|
|
var next wsClientNotification
|
|
|
|
out:
|
|
|
|
for {
|
2014-06-25 18:40:31 +02:00
|
|
|
select {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case n, ok := <-s.enqueueNotification:
|
|
|
|
if !ok {
|
|
|
|
// Sender closed input channel.
|
|
|
|
break out
|
|
|
|
}
|
|
|
|
|
|
|
|
// Either send to out immediately if skipQueue is
|
|
|
|
// non-nil (queue is empty) and reader is ready,
|
|
|
|
// or append to the queue and send later.
|
|
|
|
select {
|
|
|
|
case skipQueue <- n:
|
|
|
|
default:
|
|
|
|
q = append(q, n)
|
|
|
|
dequeue = s.dequeueNotification
|
|
|
|
skipQueue = nil
|
|
|
|
next = q[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
case dequeue <- next:
|
|
|
|
q[0] = nil // avoid leak
|
|
|
|
q = q[1:]
|
|
|
|
if len(q) == 0 {
|
|
|
|
dequeue = nil
|
|
|
|
skipQueue = s.dequeueNotification
|
2014-07-26 17:15:34 +02:00
|
|
|
} else {
|
|
|
|
next = q[0]
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2014-06-25 18:40:31 +02:00
|
|
|
}
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
close(s.dequeueNotification)
|
|
|
|
s.wg.Done()
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
func (s *rpcServer) notificationHandler() {
|
|
|
|
clients := make(map[chan struct{}]*websocketClient)
|
2014-06-24 23:00:27 +02:00
|
|
|
out:
|
2014-06-12 18:39:26 +02:00
|
|
|
for {
|
|
|
|
select {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case c := <-s.registerWSC:
|
|
|
|
clients[c.quit] = c
|
|
|
|
|
|
|
|
case c := <-s.unregisterWSC:
|
|
|
|
delete(clients, c.quit)
|
|
|
|
|
|
|
|
case nmsg, ok := <-s.dequeueNotification:
|
|
|
|
// No more notifications.
|
|
|
|
if !ok {
|
|
|
|
break out
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ignore if there are no clients to receive the
|
|
|
|
// notification.
|
|
|
|
if len(clients) == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
ns := nmsg.notificationCmds(s.wallet)
|
|
|
|
for _, n := range ns {
|
2015-04-17 22:05:38 +02:00
|
|
|
mn, err := btcjson.MarshalCmd(nil, n)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// All notifications are expected to be
|
|
|
|
// marshalable.
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
for _, c := range clients {
|
|
|
|
if err := c.send(mn); err != nil {
|
|
|
|
delete(clients, c.quit)
|
|
|
|
}
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2014-06-24 23:00:27 +02:00
|
|
|
case <-s.quit:
|
|
|
|
break out
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
}
|
2014-07-14 16:24:41 +02:00
|
|
|
close(s.notificationHandlerQuit)
|
2014-06-24 23:00:27 +02:00
|
|
|
s.wg.Done()
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// requestHandler is a handler function to handle an unmarshaled and parsed
|
2015-04-17 22:05:38 +02:00
|
|
|
// request into a marshalable response. If the error is a *btcjson.RPCError
|
2014-06-04 02:52:04 +02:00
|
|
|
// or any of the above special error classes, the server will respond with
|
|
|
|
// the JSON-RPC appropiate error code. All other errors use the wallet
|
2015-04-17 22:05:38 +02:00
|
|
|
// catch-all error code, btcjson.ErrRPCWallet.
|
|
|
|
type requestHandler func(*wallet.Wallet, *chain.Client, interface{}) (interface{}, error)
|
|
|
|
|
|
|
|
var rpcHandlers = map[string]struct {
|
|
|
|
handler requestHandler
|
|
|
|
|
|
|
|
// Function variables cannot be compared against anything but nil, so
|
|
|
|
// use a boolean to record whether help generation is necessary. This
|
|
|
|
// is used by the tests to ensure that help can be generated for every
|
|
|
|
// implemented method.
|
|
|
|
//
|
|
|
|
// A single map and this bool is here is used rather than several maps
|
|
|
|
// for the unimplemented handlers so every method has exactly one
|
|
|
|
// handler function.
|
|
|
|
noHelp bool
|
|
|
|
}{
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Reference implementation wallet methods (implemented)
|
2015-04-17 22:05:38 +02:00
|
|
|
"addmultisigaddress": {handler: AddMultiSigAddress},
|
|
|
|
"createmultisig": {handler: CreateMultiSig},
|
|
|
|
"dumpprivkey": {handler: DumpPrivKey},
|
|
|
|
"getaccount": {handler: GetAccount},
|
|
|
|
"getaccountaddress": {handler: GetAccountAddress},
|
|
|
|
"getaddressesbyaccount": {handler: GetAddressesByAccount},
|
|
|
|
"getbalance": {handler: GetBalance},
|
|
|
|
"getbestblockhash": {handler: GetBestBlockHash},
|
|
|
|
"getblockcount": {handler: GetBlockCount},
|
|
|
|
"getinfo": {handler: GetInfo},
|
|
|
|
"getnewaddress": {handler: GetNewAddress},
|
|
|
|
"getrawchangeaddress": {handler: GetRawChangeAddress},
|
|
|
|
"getreceivedbyaccount": {handler: GetReceivedByAccount},
|
|
|
|
"getreceivedbyaddress": {handler: GetReceivedByAddress},
|
|
|
|
"gettransaction": {handler: GetTransaction},
|
|
|
|
"help": {handler: Help},
|
|
|
|
"importprivkey": {handler: ImportPrivKey},
|
|
|
|
"keypoolrefill": {handler: KeypoolRefill},
|
|
|
|
"listaccounts": {handler: ListAccounts},
|
|
|
|
"listlockunspent": {handler: ListLockUnspent},
|
|
|
|
"listreceivedbyaccount": {handler: ListReceivedByAccount},
|
|
|
|
"listreceivedbyaddress": {handler: ListReceivedByAddress},
|
|
|
|
"listsinceblock": {handler: ListSinceBlock},
|
|
|
|
"listtransactions": {handler: ListTransactions},
|
|
|
|
"listunspent": {handler: ListUnspent},
|
|
|
|
"lockunspent": {handler: LockUnspent},
|
|
|
|
"sendfrom": {handler: SendFrom},
|
|
|
|
"sendmany": {handler: SendMany},
|
|
|
|
"sendtoaddress": {handler: SendToAddress},
|
|
|
|
"settxfee": {handler: SetTxFee},
|
|
|
|
"signmessage": {handler: SignMessage},
|
|
|
|
"signrawtransaction": {handler: SignRawTransaction},
|
|
|
|
"validateaddress": {handler: ValidateAddress},
|
|
|
|
"verifymessage": {handler: VerifyMessage},
|
|
|
|
"walletlock": {handler: WalletLock},
|
|
|
|
"walletpassphrase": {handler: WalletPassphrase},
|
|
|
|
"walletpassphrasechange": {handler: WalletPassphraseChange},
|
2013-11-12 18:01:32 +01:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Reference implementation methods (still unimplemented)
|
2015-04-17 22:05:38 +02:00
|
|
|
"backupwallet": {handler: Unimplemented, noHelp: true},
|
|
|
|
"dumpwallet": {handler: Unimplemented, noHelp: true},
|
|
|
|
"getwalletinfo": {handler: Unimplemented, noHelp: true},
|
|
|
|
"importwallet": {handler: Unimplemented, noHelp: true},
|
|
|
|
"listaddressgroupings": {handler: Unimplemented, noHelp: true},
|
2013-12-30 18:44:51 +01:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Reference methods which can't be implemented by btcwallet due to
|
|
|
|
// design decision differences
|
2015-04-17 22:05:38 +02:00
|
|
|
"encryptwallet": {handler: Unsupported, noHelp: true},
|
|
|
|
"move": {handler: Unsupported, noHelp: true},
|
|
|
|
"setaccount": {handler: Unsupported, noHelp: true},
|
2013-12-30 18:44:51 +01:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Extensions to the reference client JSON-RPC API
|
2015-04-17 22:05:38 +02:00
|
|
|
"createnewaccount": {handler: CreateNewAccount},
|
|
|
|
"exportwatchingwallet": {handler: ExportWatchingWallet},
|
|
|
|
"getbestblock": {handler: GetBestBlock},
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// This was an extension but the reference implementation added it as
|
|
|
|
// well, but with a different API (no account parameter). It's listed
|
|
|
|
// here because it hasn't been update to use the reference
|
|
|
|
// implemenation's API.
|
2015-04-17 22:05:38 +02:00
|
|
|
"getunconfirmedbalance": {handler: GetUnconfirmedBalance},
|
|
|
|
"listaddresstransactions": {handler: ListAddressTransactions},
|
|
|
|
"listalltransactions": {handler: ListAllTransactions},
|
|
|
|
"renameaccount": {handler: RenameAccount},
|
|
|
|
"walletislocked": {handler: WalletIsLocked},
|
2013-11-12 18:01:32 +01:00
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Unimplemented handles an unimplemented RPC request with the
|
|
|
|
// appropiate error.
|
2015-04-17 22:05:38 +02:00
|
|
|
func Unimplemented(*wallet.Wallet, *chain.Client, interface{}) (interface{}, error) {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCUnimplemented,
|
|
|
|
Message: "Method unimplemented",
|
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Unsupported handles a standard bitcoind RPC request which is
|
|
|
|
// unsupported by btcwallet due to design differences.
|
2015-04-17 22:05:38 +02:00
|
|
|
func Unsupported(*wallet.Wallet, *chain.Client, interface{}) (interface{}, error) {
|
|
|
|
return nil, &btcjson.RPCError{
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
Code: -1,
|
|
|
|
Message: "Request unsupported by btcwallet",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnloadedWallet is the handler func that is run when a wallet has not been
|
|
|
|
// loaded yet when trying to execute a wallet RPC.
|
2015-04-17 22:05:38 +02:00
|
|
|
func UnloadedWallet(*wallet.Wallet, *chain.Client, interface{}) (interface{}, error) {
|
|
|
|
return nil, &ErrUnloadedWallet
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// NoEncryptedWallet is the handler func that is run when no wallet has been
|
|
|
|
// created by the user yet.
|
|
|
|
// loaded yet when trying to execute a wallet RPC.
|
2015-04-17 22:05:38 +02:00
|
|
|
func NoEncryptedWallet(*wallet.Wallet, *chain.Client, interface{}) (interface{}, error) {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWallet,
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
Message: "Request requires a wallet but no wallet has been " +
|
|
|
|
"created -- use createencryptedwallet to recover",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(jrick): may be a good idea to add handlers for passthrough to the chain
|
|
|
|
// server. If a handler can not be looked up in one of the above maps, use this
|
|
|
|
// passthrough handler instead. This isn't done at the moment since all
|
|
|
|
// requests are executed serialized, and blocking all requests, and even just
|
|
|
|
// requests from the same client, on the result of a btcd RPC can result is too
|
|
|
|
// much waiting for the round trip.
|
|
|
|
|
|
|
|
// lookupAnyHandler looks up a request handler func for the passed method from
|
2014-06-12 18:39:26 +02:00
|
|
|
// the http post and (if the request is from a websocket connection) websocket
|
|
|
|
// handler maps. If a suitable handler could not be found, ok is false.
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
func lookupAnyHandler(method string) (f requestHandler, ok bool) {
|
2015-04-17 22:05:38 +02:00
|
|
|
handlerData, ok := rpcHandlers[method]
|
|
|
|
f = handlerData.handler
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return
|
2014-01-03 19:34:37 +01:00
|
|
|
}
|
2013-11-12 18:01:32 +01:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// unloadedWalletHandlerFunc looks up whether a request requires a wallet, and
|
|
|
|
// if so, returns a specialized handler func to return errors for an unloaded
|
|
|
|
// wallet component necessary to complete the request. If ok is false, the
|
|
|
|
// function is invalid and should be passed through instead.
|
|
|
|
func unloadedWalletHandlerFunc(method string) (f requestHandler, ok bool) {
|
|
|
|
_, ok = rpcHandlers[method]
|
|
|
|
if ok {
|
|
|
|
f = UnloadedWallet
|
|
|
|
}
|
|
|
|
return
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
2014-06-04 02:52:04 +02:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// missingWalletHandlerFunc looks up whether a request requires a wallet, and
|
|
|
|
// if so, returns a specialized handler func to return errors for no wallets
|
|
|
|
// being created yet with the createencryptedwallet RPC. If ok is false, the
|
|
|
|
// function is invalid and should be passed through instead.
|
|
|
|
func missingWalletHandlerFunc(method string) (f requestHandler, ok bool) {
|
|
|
|
_, ok = rpcHandlers[method]
|
|
|
|
if ok {
|
|
|
|
f = NoEncryptedWallet
|
|
|
|
}
|
|
|
|
return
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
2014-01-30 16:14:02 +01:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// requestHandlerClosure is a closure over a requestHandler or passthrough
|
|
|
|
// request with the RPC server's wallet and chain server variables as part
|
|
|
|
// of the closure context.
|
2015-04-17 22:05:38 +02:00
|
|
|
type requestHandlerClosure func(*btcjson.Request) (interface{}, *btcjson.RPCError)
|
2014-03-28 04:18:23 +01:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// makeResponse makes the JSON-RPC response struct for the result and error
|
|
|
|
// returned by a requestHandler. The returned response is not ready for
|
|
|
|
// marshaling and sending off to a client, but must be
|
2015-04-17 22:05:38 +02:00
|
|
|
func makeResponse(id, result interface{}, err error) btcjson.Response {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
idPtr := idPointer(id)
|
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return btcjson.Response{
|
|
|
|
ID: idPtr,
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
Error: jsonError(err),
|
2014-01-30 16:14:02 +01:00
|
|
|
}
|
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
resultBytes, err := json.Marshal(result)
|
|
|
|
if err != nil {
|
|
|
|
return btcjson.Response{
|
|
|
|
ID: idPtr,
|
|
|
|
Error: &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInternal.Code,
|
|
|
|
Message: "Unexpected error marshalling result",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return btcjson.Response{
|
|
|
|
ID: idPtr,
|
|
|
|
Result: json.RawMessage(resultBytes),
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2013-08-21 17:14:21 +02:00
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// jsonError creates a JSON-RPC error from the Go error.
|
2015-04-17 22:05:38 +02:00
|
|
|
func jsonError(err error) *btcjson.RPCError {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err == nil {
|
|
|
|
return nil
|
|
|
|
}
|
2013-12-30 18:44:51 +01:00
|
|
|
|
2015-05-26 17:39:22 +02:00
|
|
|
code := btcjson.ErrRPCWallet
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
switch e := err.(type) {
|
2015-04-17 22:05:38 +02:00
|
|
|
case btcjson.RPCError:
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return &e
|
2015-04-17 22:05:38 +02:00
|
|
|
case *btcjson.RPCError:
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return e
|
|
|
|
case DeserializationError:
|
2015-04-17 22:05:38 +02:00
|
|
|
code = btcjson.ErrRPCDeserialization
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case InvalidParameterError:
|
2015-04-17 22:05:38 +02:00
|
|
|
code = btcjson.ErrRPCInvalidParameter
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
case ParseError:
|
2015-04-17 22:05:38 +02:00
|
|
|
code = btcjson.ErrRPCParse.Code
|
2015-05-26 17:39:22 +02:00
|
|
|
case waddrmgr.ManagerError:
|
|
|
|
switch e.ErrorCode {
|
|
|
|
case waddrmgr.ErrWrongPassphrase:
|
|
|
|
code = btcjson.ErrRPCWalletPassphraseIncorrect
|
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
}
|
|
|
|
return &btcjson.RPCError{
|
|
|
|
Code: code,
|
|
|
|
Message: err.Error(),
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2013-12-30 18:44:51 +01:00
|
|
|
}
|
|
|
|
|
2014-06-12 18:39:26 +02:00
|
|
|
// makeMultiSigScript is a helper function to combine common logic for
|
2014-03-20 12:12:13 +01:00
|
|
|
// AddMultiSig and CreateMultiSig.
|
|
|
|
// all error codes are rpc parse error here to match bitcoind which just throws
|
|
|
|
// a runtime exception. *sigh*.
|
2015-04-02 20:13:38 +02:00
|
|
|
func makeMultiSigScript(w *wallet.Wallet, keys []string, nRequired int) ([]byte, error) {
|
2014-03-20 12:12:13 +01:00
|
|
|
keysesPrecious := make([]*btcutil.AddressPubKey, len(keys))
|
|
|
|
|
|
|
|
// The address list will made up either of addreseses (pubkey hash), for
|
|
|
|
// which we need to look up the keys in wallet, straight pubkeys, or a
|
|
|
|
// mixture of the two.
|
|
|
|
for i, a := range keys {
|
|
|
|
// try to parse as pubkey address
|
2015-04-17 22:05:38 +02:00
|
|
|
a, err := decodeAddress(a, activeNet.Params)
|
2014-03-20 12:12:13 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
switch addr := a.(type) {
|
|
|
|
case *btcutil.AddressPubKey:
|
|
|
|
keysesPrecious[i] = addr
|
|
|
|
case *btcutil.AddressPubKeyHash:
|
2014-10-29 07:43:29 +01:00
|
|
|
ainfo, err := w.Manager.Address(addr)
|
2014-03-20 12:12:13 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
apkinfo := ainfo.(waddrmgr.ManagedPubKeyAddress)
|
2014-03-20 12:12:13 +01:00
|
|
|
|
|
|
|
// This will be an addresspubkey
|
2015-04-17 22:05:38 +02:00
|
|
|
a, err := decodeAddress(apkinfo.ExportPubKey(),
|
2014-05-27 19:50:51 +02:00
|
|
|
activeNet.Params)
|
2014-03-20 12:12:13 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
apk := a.(*btcutil.AddressPubKey)
|
|
|
|
keysesPrecious[i] = apk
|
|
|
|
default:
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-30 19:31:29 +01:00
|
|
|
return txscript.MultiSigScript(keysesPrecious, nRequired)
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// AddMultiSigAddress handles an addmultisigaddress request by adding a
|
|
|
|
// multisig address to the given wallet.
|
2015-04-17 22:05:38 +02:00
|
|
|
func AddMultiSigAddress(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.AddMultisigAddressCmd)
|
2014-03-20 12:12:13 +01:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
// If an account is specified, ensure that is the imported account.
|
|
|
|
if cmd.Account != nil && *cmd.Account != waddrmgr.ImportedAddrAccountName {
|
|
|
|
return nil, &ErrNotImportedAccount
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
script, err := makeMultiSigScript(w, cmd.Keys, cmd.NRequired)
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, ParseError{err}
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(oga) blockstamp current block?
|
2014-10-29 07:43:29 +01:00
|
|
|
bs := &waddrmgr.BlockStamp{
|
|
|
|
Hash: *activeNet.Params.GenesisHash,
|
|
|
|
Height: 0,
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
2014-03-20 12:12:13 +01:00
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
addr, err := w.Manager.ImportScript(script, bs)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
2014-10-29 07:43:29 +01:00
|
|
|
return nil, err
|
2014-07-07 18:23:53 +02:00
|
|
|
}
|
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
return addr.Address().EncodeAddress(), nil
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// CreateMultiSig handles an createmultisig request by returning a
|
|
|
|
// multisig address for the given inputs.
|
2015-04-17 22:05:38 +02:00
|
|
|
func CreateMultiSig(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.CreateMultisigCmd)
|
2014-03-20 12:12:13 +01:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
script, err := makeMultiSigScript(w, cmd.Keys, cmd.NRequired)
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, ParseError{err}
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
|
2014-05-27 19:50:51 +02:00
|
|
|
address, err := btcutil.NewAddressScriptHash(script, activeNet.Params)
|
2014-03-20 12:12:13 +01:00
|
|
|
if err != nil {
|
|
|
|
// above is a valid script, shouldn't happen.
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-03-20 12:12:13 +01:00
|
|
|
}
|
|
|
|
|
2014-04-09 19:57:28 +02:00
|
|
|
return btcjson.CreateMultiSigResult{
|
|
|
|
Address: address.EncodeAddress(),
|
|
|
|
RedeemScript: hex.EncodeToString(script),
|
2014-03-20 12:12:13 +01:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// DumpPrivKey handles a dumpprivkey request with the private key
|
|
|
|
// for a single address, or an appropiate error if the wallet
|
2013-11-20 02:18:11 +01:00
|
|
|
// is locked.
|
2015-04-17 22:05:38 +02:00
|
|
|
func DumpPrivKey(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.DumpPrivKeyCmd)
|
2013-11-20 02:18:11 +01:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
addr, err := decodeAddress(cmd.Address, activeNet.Params)
|
2014-01-06 18:24:29 +01:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
2014-01-06 18:24:29 +01:00
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
key, err := w.DumpWIFPrivateKey(addr)
|
2014-10-29 07:43:29 +01:00
|
|
|
if isManagerLockedError(err) {
|
2013-12-02 20:56:06 +01:00
|
|
|
// Address was found, but the private key isn't
|
|
|
|
// accessible.
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrWalletUnlockNeeded
|
2013-11-20 02:18:11 +01:00
|
|
|
}
|
2014-06-04 02:52:04 +02:00
|
|
|
return key, err
|
2013-11-20 02:18:11 +01:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// DumpWallet handles a dumpwallet request by returning all private
|
|
|
|
// keys in a wallet, or an appropiate error if the wallet is locked.
|
2013-11-20 02:44:37 +01:00
|
|
|
// TODO: finish this to match bitcoind by writing the dump to a file.
|
2015-04-17 22:05:38 +02:00
|
|
|
func DumpWallet(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
keys, err := w.DumpPrivKeys()
|
2014-10-29 07:43:29 +01:00
|
|
|
if isManagerLockedError(err) {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrWalletUnlockNeeded
|
2013-11-20 02:18:11 +01:00
|
|
|
}
|
2014-10-29 07:43:29 +01:00
|
|
|
|
2014-06-04 02:52:04 +02:00
|
|
|
return keys, err
|
2013-11-20 02:18:11 +01:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
// ExportWatchingWallet handles an exportwatchingwallet request by exporting the
|
|
|
|
// current wallet as a watching wallet (with no private keys), and returning
|
|
|
|
// base64-encoding of serialized account files.
|
|
|
|
func ExportWatchingWallet(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2015-04-16 18:54:56 +02:00
|
|
|
cmd := icmd.(*btcjson.ExportWatchingWalletCmd)
|
|
|
|
|
|
|
|
if cmd.Account != nil && *cmd.Account != "*" {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWallet,
|
|
|
|
Message: "Individual accounts can not be exported as watching-only",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-02 20:13:38 +02:00
|
|
|
return w.ExportWatchingWallet(cfg.WalletPass)
|
Implement exporting a watching-only wallet.
This change allows for the use of watching-only wallets. Unlike
normal, "hot" wallets, watching-only wallets do not contain any
private keys, and can be used in situations where you want to keep one
wallet online to create new receiving addresses and watch for received
transactions, while keeping the hot wallet offline (possibly on an
air-gapped computer).
Two (websocket) extension RPC calls have been added:
First, exportwatchingwallet, which will export the current hot wallet
to a watching-only wallet, saving either to disk or returning the
base64-encoded wallet files to the caller.
Second, recoveraddresses, which is used to recover the next n
addresses from the address chain. This is used to "sync" a watching
wallet with the hot wallet, or vice versa.
2014-01-21 20:45:28 +01:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// GetAddressesByAccount handles a getaddressesbyaccount request by returning
|
2013-11-12 18:01:32 +01:00
|
|
|
// all addresses for an account, or an error if the requested account does
|
|
|
|
// not exist.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetAddressesByAccount(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.GetAddressesByAccountCmd)
|
2013-10-08 04:17:27 +02:00
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
account, err := w.Manager.LookupAccount(cmd.Account)
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-12-02 20:56:06 +01:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2015-03-26 19:22:59 +01:00
|
|
|
var addrStrs []string
|
|
|
|
err = w.Manager.ForEachAccountAddress(account,
|
|
|
|
func(maddr waddrmgr.ManagedAddress) error {
|
|
|
|
addrStrs = append(addrStrs, maddr.Address().EncodeAddress())
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
return addrStrs, err
|
2013-08-21 16:37:30 +02:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// GetBalance handles a getbalance request by returning the balance for an
|
2013-11-12 18:01:32 +01:00
|
|
|
// account (wallet), or an error if the requested account does not
|
|
|
|
// exist.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetBalance(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.GetBalanceCmd)
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
var balance btcutil.Amount
|
|
|
|
var err error
|
2015-04-16 18:54:56 +02:00
|
|
|
accountName := "*"
|
|
|
|
if cmd.Account != nil {
|
|
|
|
accountName = *cmd.Account
|
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
if accountName == "*" {
|
|
|
|
balance, err = w.CalculateBalance(int32(*cmd.MinConf))
|
2014-12-12 09:54:26 +01:00
|
|
|
} else {
|
2015-04-17 22:05:38 +02:00
|
|
|
var account uint32
|
|
|
|
account, err = w.Manager.LookupAccount(accountName)
|
2014-12-12 09:54:26 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
balance, err = w.CalculateAccountBalance(account, int32(*cmd.MinConf))
|
2013-09-09 20:14:57 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-09-03 17:00:01 +02:00
|
|
|
}
|
2014-12-12 09:54:26 +01:00
|
|
|
return balance.ToBTC(), nil
|
2013-09-03 17:00:01 +02:00
|
|
|
}
|
|
|
|
|
2014-12-31 15:15:25 +01:00
|
|
|
// GetBestBlock handles a getbestblock request by returning a JSON object
|
|
|
|
// with the height and hash of the most recently processed block.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetBestBlock(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2014-12-31 15:15:25 +01:00
|
|
|
blk := w.Manager.SyncedTo()
|
2015-04-17 22:05:38 +02:00
|
|
|
result := &btcjson.GetBestBlockResult{
|
2014-12-31 15:15:25 +01:00
|
|
|
Hash: blk.Hash.String(),
|
|
|
|
Height: blk.Height,
|
|
|
|
}
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetBestBlockHash handles a getbestblockhash request by returning the hash
|
|
|
|
// of the most recently processed block.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetBestBlockHash(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2014-12-31 15:15:25 +01:00
|
|
|
blk := w.Manager.SyncedTo()
|
|
|
|
return blk.Hash.String(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetBlockCount handles a getblockcount request by returning the chain height
|
|
|
|
// of the most recently processed block.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetBlockCount(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2014-12-31 15:15:25 +01:00
|
|
|
blk := w.Manager.SyncedTo()
|
|
|
|
return blk.Height, nil
|
|
|
|
}
|
|
|
|
|
2014-01-29 18:14:24 +01:00
|
|
|
// GetInfo handles a getinfo request by returning the a structure containing
|
|
|
|
// information about the current state of btcwallet.
|
|
|
|
// exist.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetInfo(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2014-01-29 18:14:24 +01:00
|
|
|
// Call down to btcd for all of the information in this command known
|
2014-06-12 18:39:26 +02:00
|
|
|
// by them.
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
info, err := chainSvr.GetInfo()
|
2014-05-28 06:54:50 +02:00
|
|
|
if err != nil {
|
2014-06-12 18:39:26 +02:00
|
|
|
return nil, err
|
2014-05-28 06:54:50 +02:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
|
|
|
bal, err := w.CalculateBalance(1)
|
2014-06-12 18:39:26 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2014-01-29 18:14:24 +01:00
|
|
|
}
|
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
// TODO(davec): This should probably have a database version as opposed
|
|
|
|
// to using the manager version.
|
|
|
|
info.WalletVersion = int32(waddrmgr.LatestMgrVersion)
|
2014-12-12 09:54:26 +01:00
|
|
|
info.Balance = bal.ToBTC()
|
|
|
|
info.PaytxFee = w.FeeIncrement.ToBTC()
|
2014-06-12 18:39:26 +02:00
|
|
|
// We don't set the following since they don't make much sense in the
|
|
|
|
// wallet architecture:
|
|
|
|
// - unlocked_until
|
|
|
|
// - errors
|
2014-01-29 18:14:24 +01:00
|
|
|
|
2014-04-09 18:07:09 +02:00
|
|
|
return info, nil
|
2014-01-29 18:14:24 +01:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
func decodeAddress(s string, params *chaincfg.Params) (btcutil.Address, error) {
|
|
|
|
addr, err := btcutil.DecodeAddress(s, params)
|
|
|
|
if err != nil {
|
|
|
|
msg := fmt.Sprintf("Invalid address %q: decode failed with %#q", s, err)
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInvalidAddressOrKey,
|
|
|
|
Message: msg,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !addr.IsForNet(activeNet.Params) {
|
|
|
|
msg := fmt.Sprintf("Invalid address %q: not intended for use on %s",
|
|
|
|
addr, params.Name)
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInvalidAddressOrKey,
|
|
|
|
Message: msg,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return addr, nil
|
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// GetAccount handles a getaccount request by returning the account name
|
|
|
|
// associated with a single address.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetAccount(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.GetAccountCmd)
|
2013-12-30 22:31:33 +01:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
addr, err := decodeAddress(cmd.Address, activeNet.Params)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-12-30 22:31:33 +01:00
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
// Fetch the associated account
|
|
|
|
account, err := w.Manager.AddrAccount(addr)
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrAddressNotInWallet
|
2013-12-30 22:31:33 +01:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
acctName, err := w.Manager.AccountName(account)
|
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrAccountNameNotFound
|
2014-12-12 09:54:26 +01:00
|
|
|
}
|
|
|
|
return acctName, nil
|
2013-12-30 22:31:33 +01:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// GetAccountAddress handles a getaccountaddress by returning the most
|
2013-12-31 19:11:47 +01:00
|
|
|
// recently-created chained address that has not yet been used (does not yet
|
|
|
|
// appear in the blockchain, or any tx that has arrived in the btcd mempool).
|
|
|
|
// If the most recently-requested address has been used, a new address (the
|
|
|
|
// next chained address in the keypool) is used. This can fail if the keypool
|
2015-04-17 22:05:38 +02:00
|
|
|
// runs out (and will return btcjson.ErrRPCWalletKeypoolRanOut if that happens).
|
|
|
|
func GetAccountAddress(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.GetAccountAddressCmd)
|
2013-12-31 19:11:47 +01:00
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
account, err := w.Manager.LookupAccount(cmd.Account)
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-12-31 19:11:47 +01:00
|
|
|
}
|
2014-12-12 09:54:26 +01:00
|
|
|
addr, err := w.CurrentAddress(account)
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-12-31 19:11:47 +01:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2014-06-04 02:52:04 +02:00
|
|
|
return addr.EncodeAddress(), err
|
2013-12-31 19:11:47 +01:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// GetUnconfirmedBalance handles a getunconfirmedbalance extension request
|
|
|
|
// by returning the current unconfirmed balance of an account.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetUnconfirmedBalance(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
|
|
|
cmd := icmd.(*btcjson.GetUnconfirmedBalanceCmd)
|
2013-12-30 21:11:41 +01:00
|
|
|
|
2015-04-16 18:54:56 +02:00
|
|
|
acctName := "default"
|
|
|
|
if cmd.Account != nil {
|
|
|
|
acctName = *cmd.Account
|
|
|
|
}
|
|
|
|
account, err := w.Manager.LookupAccount(acctName)
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-12-30 21:11:41 +01:00
|
|
|
}
|
2014-12-12 09:54:26 +01:00
|
|
|
unconfirmed, err := w.CalculateAccountBalance(account, 0)
|
2014-07-07 23:57:00 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2014-12-12 09:54:26 +01:00
|
|
|
confirmed, err := w.CalculateAccountBalance(account, 1)
|
2014-07-07 23:57:00 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
return (unconfirmed - confirmed).ToBTC(), nil
|
2013-12-30 21:11:41 +01:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// ImportPrivKey handles an importprivkey request by parsing
|
2013-11-20 02:18:11 +01:00
|
|
|
// a WIF-encoded private key and adding it to an account.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ImportPrivKey(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.ImportPrivKeyCmd)
|
2013-11-20 02:18:11 +01:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
// Ensure that private keys are only imported to the correct account.
|
|
|
|
//
|
|
|
|
// Yes, Label is the account name.
|
2015-04-16 18:54:56 +02:00
|
|
|
if cmd.Label != nil && *cmd.Label != waddrmgr.ImportedAddrAccountName {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrNotImportedAccount
|
2013-11-20 02:18:11 +01:00
|
|
|
}
|
|
|
|
|
2014-05-22 00:50:47 +02:00
|
|
|
wif, err := btcutil.DecodeWIF(cmd.PrivKey)
|
2015-04-17 22:05:38 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInvalidAddressOrKey,
|
|
|
|
Message: "WIF decode failed: " + err.Error(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !wif.IsForNet(activeNet.Params) {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInvalidAddressOrKey,
|
|
|
|
Message: "Key is not intended for " + activeNet.Params.Name,
|
|
|
|
}
|
2014-01-30 16:14:02 +01:00
|
|
|
}
|
|
|
|
|
2013-12-02 20:56:06 +01:00
|
|
|
// Import the private key, handling any errors.
|
2015-04-17 22:05:38 +02:00
|
|
|
_, err = w.ImportPrivateKey(wif, nil, *cmd.Rescan)
|
2014-10-29 07:43:29 +01:00
|
|
|
switch {
|
2014-12-12 09:54:26 +01:00
|
|
|
case isManagerDuplicateAddressError(err):
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Do not return duplicate key errors to the client.
|
|
|
|
return nil, nil
|
2014-10-29 07:43:29 +01:00
|
|
|
case isManagerLockedError(err):
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrWalletUnlockNeeded
|
2013-11-20 02:18:11 +01:00
|
|
|
}
|
2014-10-29 07:43:29 +01:00
|
|
|
|
|
|
|
return nil, err
|
2013-11-20 02:18:11 +01:00
|
|
|
}
|
|
|
|
|
2014-01-22 18:28:09 +01:00
|
|
|
// KeypoolRefill handles the keypoolrefill command. Since we handle the keypool
|
|
|
|
// automatically this does nothing since refilling is never manually required.
|
2015-04-17 22:05:38 +02:00
|
|
|
func KeypoolRefill(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2014-01-22 18:28:09 +01:00
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
// CreateNewAccount handles a createnewaccount request by creating and
|
|
|
|
// returning a new account. If the last account has no transaction history
|
|
|
|
// as per BIP 0044 a new account cannot be created so an error will be returned.
|
2015-04-17 22:05:38 +02:00
|
|
|
func CreateNewAccount(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
|
|
|
cmd := icmd.(*btcjson.CreateNewAccountCmd)
|
2014-12-12 09:54:26 +01:00
|
|
|
|
2015-04-16 18:54:56 +02:00
|
|
|
// The wildcard * is reserved by the rpc server with the special meaning
|
|
|
|
// of "all accounts", so disallow naming accounts to this string.
|
|
|
|
if cmd.Account == "*" {
|
|
|
|
return nil, &ErrReservedAccountName
|
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
// Check that we are within the maximum allowed non-empty accounts limit.
|
|
|
|
account, err := w.Manager.LastAccount()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if account > maxEmptyAccounts {
|
|
|
|
used, err := w.AccountUsed(account)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if !used {
|
|
|
|
return nil, errors.New("cannot create account: " +
|
|
|
|
"previous account has no transaction history")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = w.Manager.NewAccount(cmd.Account)
|
|
|
|
if isManagerLockedError(err) {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWalletUnlockNeeded,
|
2015-04-13 17:39:15 +02:00
|
|
|
Message: "Creating an account requires the wallet to be unlocked. " +
|
|
|
|
"Enter the wallet passphrase with walletpassphrase to unlock",
|
|
|
|
}
|
2014-12-12 09:54:26 +01:00
|
|
|
}
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// RenameAccount handles a renameaccount request by renaming an account.
|
|
|
|
// If the account does not exist an appropiate error will be returned.
|
2015-04-17 22:05:38 +02:00
|
|
|
func RenameAccount(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
|
|
|
cmd := icmd.(*btcjson.RenameAccountCmd)
|
2015-04-16 18:54:56 +02:00
|
|
|
|
|
|
|
// The wildcard * is reserved by the rpc server with the special meaning
|
|
|
|
// of "all accounts", so disallow naming accounts to this string.
|
|
|
|
if cmd.NewAccount == "*" {
|
|
|
|
return nil, &ErrReservedAccountName
|
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
// Check that given account exists
|
|
|
|
account, err := w.Manager.LookupAccount(cmd.OldAccount)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return nil, w.Manager.RenameAccount(account, cmd.NewAccount)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNewAddress handles a getnewaddress request by returning a new
|
|
|
|
// address for an account. If the account does not exist an appropiate
|
|
|
|
// error is returned.
|
|
|
|
// TODO: Follow BIP 0044 and warn if number of unused addresses exceeds
|
|
|
|
// the gap limit.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetNewAddress(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.GetNewAddressCmd)
|
2013-11-12 18:01:32 +01:00
|
|
|
|
2015-04-16 18:54:56 +02:00
|
|
|
acctName := "default"
|
|
|
|
if cmd.Account != nil {
|
|
|
|
acctName = *cmd.Account
|
|
|
|
}
|
|
|
|
account, err := w.Manager.LookupAccount(acctName)
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-11-21 17:57:28 +01:00
|
|
|
}
|
2014-12-12 09:54:26 +01:00
|
|
|
addr, err := w.NewAddress(account)
|
2014-02-03 16:52:02 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-02-03 16:52:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return the new payment address string.
|
|
|
|
return addr.EncodeAddress(), nil
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2014-02-03 16:52:02 +01:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// GetRawChangeAddress handles a getrawchangeaddress request by creating
|
|
|
|
// and returning a new change address for an account.
|
|
|
|
//
|
|
|
|
// Note: bitcoind allows specifying the account as an optional parameter,
|
|
|
|
// but ignores the parameter.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetRawChangeAddress(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2014-12-12 09:54:26 +01:00
|
|
|
cmd := icmd.(*btcjson.GetRawChangeAddressCmd)
|
2015-04-16 18:54:56 +02:00
|
|
|
|
|
|
|
acctName := "default"
|
|
|
|
if cmd.Account != nil {
|
|
|
|
acctName = *cmd.Account
|
|
|
|
}
|
|
|
|
account, err := w.Manager.LookupAccount(acctName)
|
2014-12-12 09:54:26 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
addr, err := w.NewChangeAddress(account)
|
2014-02-03 16:52:02 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-02-03 16:52:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Return the new payment address string.
|
|
|
|
return addr.EncodeAddress(), nil
|
2013-09-09 20:14:57 +02:00
|
|
|
}
|
|
|
|
|
2014-02-03 19:00:28 +01:00
|
|
|
// GetReceivedByAccount handles a getreceivedbyaccount request by returning
|
|
|
|
// the total amount received by addresses of an account.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetReceivedByAccount(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.GetReceivedByAccountCmd)
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
account, err := w.Manager.LookupAccount(cmd.Account)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2014-02-03 19:00:28 +01:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
bal, _, err := w.TotalReceivedForAccount(account, int32(*cmd.MinConf))
|
2014-02-03 19:00:28 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-02-03 19:00:28 +01:00
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
return bal.ToBTC(), nil
|
2014-02-03 19:00:28 +01:00
|
|
|
}
|
|
|
|
|
2014-09-02 20:54:56 +02:00
|
|
|
// GetReceivedByAddress handles a getreceivedbyaddress request by returning
|
|
|
|
// the total amount received by a single address.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetReceivedByAddress(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2014-09-02 20:54:56 +02:00
|
|
|
cmd := icmd.(*btcjson.GetReceivedByAddressCmd)
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
addr, err := decodeAddress(cmd.Address, activeNet.Params)
|
2014-09-02 20:54:56 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
2014-09-02 20:54:56 +02:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
total, err := w.TotalReceivedForAddr(addr, int32(*cmd.MinConf))
|
2014-09-02 20:54:56 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
return total.ToBTC(), nil
|
2014-09-02 20:54:56 +02:00
|
|
|
}
|
|
|
|
|
2014-06-02 18:49:59 +02:00
|
|
|
// GetTransaction handles a gettransaction request by returning details about
|
|
|
|
// a single transaction saved by wallet.
|
2015-04-17 22:05:38 +02:00
|
|
|
func GetTransaction(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.GetTransactionCmd)
|
2014-02-03 19:29:25 +01:00
|
|
|
|
2015-02-05 22:41:38 +01:00
|
|
|
txSha, err := wire.NewShaHashFromStr(cmd.Txid)
|
2014-02-24 20:35:30 +01:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCDecodeHexString,
|
|
|
|
Message: "Transaction hash string decode failed: " + err.Error(),
|
|
|
|
}
|
2014-02-24 20:35:30 +01:00
|
|
|
}
|
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
details, err := w.TxStore.TxDetails(txSha)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if details == nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrNoTransactionInfo
|
2014-02-03 19:29:25 +01:00
|
|
|
}
|
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
syncBlock := w.Manager.SyncedTo()
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
// TODO: The serialized transaction is already in the DB, so
|
|
|
|
// reserializing can be avoided here.
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
var txBuf bytes.Buffer
|
2015-04-06 21:03:24 +02:00
|
|
|
txBuf.Grow(details.MsgTx.SerializeSize())
|
|
|
|
err = details.MsgTx.Serialize(&txBuf)
|
2014-06-02 18:49:59 +02:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-06-02 18:49:59 +02:00
|
|
|
}
|
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
// TODO: Add a "generated" field to this result type. "generated":true
|
|
|
|
// is only added if the transaction is a coinbase.
|
2014-04-11 20:10:27 +02:00
|
|
|
ret := btcjson.GetTransactionResult{
|
2015-04-06 21:03:24 +02:00
|
|
|
TxID: cmd.Txid,
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
Hex: hex.EncodeToString(txBuf.Bytes()),
|
2015-04-06 21:03:24 +02:00
|
|
|
Time: details.Received.Unix(),
|
|
|
|
TimeReceived: details.Received.Unix(),
|
|
|
|
WalletConflicts: []string{}, // Not saved
|
|
|
|
//Generated: blockchain.IsCoinBaseTx(&details.MsgTx),
|
|
|
|
}
|
|
|
|
|
|
|
|
if details.Block.Height != -1 {
|
|
|
|
ret.BlockHash = details.Block.Hash.String()
|
|
|
|
ret.BlockTime = details.Block.Time.Unix()
|
|
|
|
ret.Confirmations = int64(confirms(details.Block.Height, syncBlock.Height))
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
debitTotal btcutil.Amount
|
|
|
|
creditTotal btcutil.Amount // Excludes change
|
|
|
|
outputTotal btcutil.Amount
|
|
|
|
fee btcutil.Amount
|
|
|
|
feeF64 float64
|
|
|
|
)
|
|
|
|
for _, deb := range details.Debits {
|
|
|
|
debitTotal += deb.Amount
|
|
|
|
}
|
|
|
|
for _, cred := range details.Credits {
|
|
|
|
if !cred.Change {
|
|
|
|
creditTotal += cred.Amount
|
2014-02-03 19:29:25 +01:00
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
}
|
|
|
|
for _, output := range details.MsgTx.TxOut {
|
|
|
|
outputTotal -= btcutil.Amount(output.Value)
|
|
|
|
}
|
|
|
|
// Fee can only be determined if every input is a debit.
|
|
|
|
if len(details.Debits) == len(details.MsgTx.TxIn) {
|
|
|
|
fee = debitTotal - outputTotal
|
|
|
|
feeF64 = fee.ToBTC()
|
2014-02-03 19:29:25 +01:00
|
|
|
}
|
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
if len(details.Debits) == 0 {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Credits must be set later, but since we know the full length
|
|
|
|
// of the details slice, allocate it with the correct cap.
|
2015-04-06 21:03:24 +02:00
|
|
|
ret.Details = make([]btcjson.GetTransactionDetailsResult, 0, len(details.Credits))
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
} else {
|
2015-04-06 21:03:24 +02:00
|
|
|
ret.Details = make([]btcjson.GetTransactionDetailsResult, 1, len(details.Credits)+1)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
ret.Details[0] = btcjson.GetTransactionDetailsResult{
|
2015-05-06 17:48:05 +02:00
|
|
|
// Fields left zeroed:
|
|
|
|
// InvolvesWatchOnly
|
|
|
|
// Account
|
|
|
|
// Address
|
|
|
|
// Vout
|
|
|
|
//
|
|
|
|
// TODO(jrick): Address and Vout should always be set,
|
|
|
|
// but we're doing the wrong thing here by not matching
|
|
|
|
// core. Instead, gettransaction should only be adding
|
|
|
|
// details for transaction outputs, just like
|
|
|
|
// listtransactions (but using the short result format).
|
2014-04-11 20:10:27 +02:00
|
|
|
Category: "send",
|
2015-04-06 21:03:24 +02:00
|
|
|
Amount: (-debitTotal).ToBTC(), // negative since it is a send
|
2015-05-06 17:48:05 +02:00
|
|
|
Fee: &feeF64,
|
2014-04-11 20:10:27 +02:00
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
ret.Fee = feeF64
|
2014-02-24 20:35:30 +01:00
|
|
|
}
|
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
credCat := wallet.RecvCategory(details, syncBlock.Height).String()
|
|
|
|
for _, cred := range details.Credits {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Change is ignored.
|
2015-04-06 21:03:24 +02:00
|
|
|
if cred.Change {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
continue
|
|
|
|
}
|
2014-04-11 20:10:27 +02:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
var addr string
|
2015-04-06 21:03:24 +02:00
|
|
|
_, addrs, _, err := txscript.ExtractPkScriptAddrs(
|
|
|
|
details.MsgTx.TxOut[cred.Index].PkScript, activeNet.Params)
|
|
|
|
if err == nil && len(addrs) == 1 {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
addr = addrs[0].EncodeAddress()
|
Another day, another tx store implementation.
The last transaction store was a great example of how not to write
scalable software. For a variety of reasons, it was very slow at
processing transaction inserts. Among them:
1) Every single transaction record being saved in a linked list
(container/list), and inserting into this list would be an O(n)
operation so that records could be ordered by receive date.
2) Every single transaction in the above mentioned list was iterated
over in order to find double spends which must be removed. It is
silly to do this check for mined transactions, which already have
been checked for this by btcd. Worse yet, if double spends were
found, the list would be iterated a second (or third, or fourth)
time for each removed transaction.
3) All spend tracking for signed-by-wallet transactions was found on
each transaction insert, even if the now spent previous transaction
outputs were known by the caller.
This list could keep going on, but you get the idea. It was bad.
To resolve these issues a new transaction store had to be implemented.
The new implementation:
1) Tracks mined and unmined transactions in different data structures.
Mined transactions are cheap to track because the required double
spend checks have already been performed by the chain server, and
double spend checks are only required to be performed on
newly-inserted mined transactions which may conflict with previous
unmined transactions.
2) Saves mined transactions grouped by block first, and then by their
transaction index. Lookup keys for mined transactions are simply
the block height (in the best chain, that's all we save) and index
of the transaction in the block. This makes looking up any
arbitrary transaction almost an O(1) operation (almost, because
block height and block indexes are mapped to their slice indexes
with a Go map).
3) Saves records in each transaction for whether the outputs are
wallet credits (spendable by wallet) and for whether inputs debit
from previous credits. Both structures point back to the source
or spender (credits point to the transaction that spends them, or
nil for unspent credits, and debits include keys to lookup the
transaction credits they spent. While complicated to keep track
of, this greatly simplifies the spent tracking for transactions
across rollbacks and transaction removals.
4) Implements double spend checking as an almost O(1) operation. A
Go map is used to map each previous outpoint for all unconfirmed
transactions to the unconfirmed tx record itself. Checking for
double spends on confirmed transaction inserts only involves
looking up each previous outpoint of the inserted tx in this map.
If a double spend is found, removal is simplified by only
removing the transaction and its spend chain from store maps,
rather than iterating a linked list several times over to remove
each dead transaction in the spend chain.
5) Allows the caller to specify the previous credits which are spent
by a debiting transaction. When a transaction is created by
wallet, the previous outputs are already known, and by passing
their record types to the AddDebits method, lookups for each
previously unspent credit are omitted.
6) Bookkeeps all blocks with transactions with unspent credits, and
bookkeeps the transaction indexes of all transactions with unspent
outputs for a single block. For the case where the caller adding a
debit record does not know what credits a transaction debits from,
these bookkeeping structures allow the store to only consider known
unspent transactions, rather than searching through both spent and
unspents.
7) Saves amount deltas for the entire balance as a result of each
block, due to transactions within that block. This improves the
performance of calculating the full balance by not needing to
iterate over every transaction, and then every credit, to determine
if a credit is spent or unspent. When transactions are moved from
unconfirmed to a block structure, the amount deltas are incremented
by the amount of all transaction credits (both spent and unspent)
and debited by the total amount the transaction spends from
previous wallet credits. For the common case of calculating a
balance with just one confirmation, the only involves iterating
over each block structure and adding the (possibly negative)
amount delta. Coinbase rewards are saved similarly, but with a
different amount variable so they can be seperatly included or
excluded.
Due to all of the changes in how the store internally works, the
serialization format has changed. To simplify the serialization
logic, support for reading the last store file version has been
removed. Past this change, a rescan (run automatically) will be
required to rebuild the transaction history.
2014-05-05 23:12:05 +02:00
|
|
|
}
|
2014-06-02 18:49:59 +02:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
ret.Details = append(ret.Details, btcjson.GetTransactionDetailsResult{
|
2015-05-06 17:48:05 +02:00
|
|
|
// Fields left zeroed:
|
|
|
|
// InvolvesWatchOnly
|
|
|
|
// Account
|
|
|
|
// Fee
|
|
|
|
Address: addr,
|
2015-04-06 21:03:24 +02:00
|
|
|
Category: credCat,
|
|
|
|
Amount: cred.Amount.ToBTC(),
|
2015-05-06 17:48:05 +02:00
|
|
|
Vout: cred.Index,
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
})
|
2014-02-03 19:29:25 +01:00
|
|
|
}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
ret.Amount = creditTotal.ToBTC()
|
2014-02-03 19:29:25 +01:00
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
// These generators create the following global variables in this package:
|
|
|
|
//
|
|
|
|
// var localeHelpDescs map[string]func() map[string]string
|
|
|
|
// var requestUsages string
|
|
|
|
//
|
|
|
|
// localeHelpDescs maps from locale strings (e.g. "en_US") to a function that
|
|
|
|
// builds a map of help texts for each RPC server method. This prevents help
|
|
|
|
// text maps for every locale map from being rooted and created during init.
|
|
|
|
// Instead, the appropiate function is looked up when help text is first needed
|
|
|
|
// using the current locale and saved to the global below for futher reuse.
|
|
|
|
//
|
|
|
|
// requestUsages contains single line usages for every supported request,
|
|
|
|
// separated by newlines. It is set during init. These usages are used for all
|
|
|
|
// locales.
|
|
|
|
//
|
|
|
|
//go:generate go run internal/rpchelp/genrpcserverhelp.go -tags generate
|
|
|
|
//go:generate gofmt -w rpcserverhelp.go
|
|
|
|
|
|
|
|
var helpDescs map[string]string
|
|
|
|
var helpDescsMu sync.Mutex // Help may execute concurrently, so synchronize access.
|
|
|
|
|
|
|
|
// Help handles the help request by returning one line usage of all available
|
|
|
|
// methods, or full help for a specific method.
|
|
|
|
func Help(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
|
|
|
cmd := icmd.(*btcjson.HelpCmd)
|
|
|
|
|
|
|
|
// btcd returns different help messages depending on the kind of
|
|
|
|
// connection the client is using. Only methods availble to HTTP POST
|
|
|
|
// clients are available to be used by wallet clients, even though
|
|
|
|
// wallet itself is a websocket client to btcd. Therefore, create a
|
|
|
|
// POST client as needed.
|
|
|
|
//
|
|
|
|
// Returns nil if chainSvr is currently nil or there is an error
|
|
|
|
// creating the client.
|
|
|
|
//
|
|
|
|
// This is hacky and is probably better handled by exposing help usage
|
|
|
|
// texts in a non-internal btcd package.
|
|
|
|
postClient := func() *btcrpcclient.Client {
|
|
|
|
if chainSvr == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
var certs []byte
|
|
|
|
if !cfg.DisableClientTLS {
|
|
|
|
var err error
|
|
|
|
certs, err = ioutil.ReadFile(cfg.CAFile)
|
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
conf := btcrpcclient.ConnConfig{
|
|
|
|
Host: cfg.RPCConnect,
|
|
|
|
User: cfg.BtcdUsername,
|
|
|
|
Pass: cfg.BtcdPassword,
|
|
|
|
DisableTLS: cfg.DisableClientTLS,
|
|
|
|
Certificates: certs,
|
|
|
|
HTTPPostMode: true,
|
|
|
|
}
|
|
|
|
client, err := btcrpcclient.New(&conf, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return client
|
|
|
|
}
|
|
|
|
|
|
|
|
if cmd.Command == nil || *cmd.Command == "" {
|
|
|
|
// Prepend chain server usage if it is available.
|
|
|
|
usages := requestUsages
|
|
|
|
client := postClient()
|
|
|
|
if client != nil {
|
|
|
|
rawChainUsage, err := client.RawRequest("help", nil)
|
|
|
|
var chainUsage string
|
|
|
|
if err == nil {
|
|
|
|
_ = json.Unmarshal([]byte(rawChainUsage), &chainUsage)
|
|
|
|
}
|
|
|
|
if chainUsage != "" {
|
|
|
|
usages = "Chain server usage:\n\n" + chainUsage + "\n\n" +
|
|
|
|
"Wallet server usage (overrides chain requests):\n\n" +
|
|
|
|
requestUsages
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return usages, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
defer helpDescsMu.Unlock()
|
|
|
|
helpDescsMu.Lock()
|
|
|
|
|
|
|
|
if helpDescs == nil {
|
|
|
|
// TODO: Allow other locales to be set via config or detemine
|
|
|
|
// this from environment variables. For now, hardcode US
|
|
|
|
// English.
|
|
|
|
helpDescs = localeHelpDescs["en_US"]()
|
|
|
|
}
|
|
|
|
|
|
|
|
helpText, ok := helpDescs[*cmd.Command]
|
|
|
|
if ok {
|
|
|
|
return helpText, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the chain server's detailed help if possible.
|
|
|
|
var chainHelp string
|
|
|
|
client := postClient()
|
|
|
|
if client != nil {
|
|
|
|
param := make([]byte, len(*cmd.Command)+2)
|
|
|
|
param[0] = '"'
|
|
|
|
copy(param[1:], *cmd.Command)
|
|
|
|
param[len(param)-1] = '"'
|
|
|
|
rawChainHelp, err := client.RawRequest("help", []json.RawMessage{param})
|
|
|
|
if err == nil {
|
|
|
|
_ = json.Unmarshal([]byte(rawChainHelp), &chainHelp)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if chainHelp != "" {
|
|
|
|
return chainHelp, nil
|
|
|
|
}
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInvalidParameter,
|
|
|
|
Message: fmt.Sprintf("No help for method '%s'", *cmd.Command),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// ListAccounts handles a listaccounts request by returning a map of account
|
|
|
|
// names to their balances.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ListAccounts(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.ListAccountsCmd)
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
accountBalances := map[string]float64{}
|
2015-03-26 19:22:59 +01:00
|
|
|
var accounts []uint32
|
|
|
|
err := w.Manager.ForEachAccount(func(account uint32) error {
|
|
|
|
accounts = append(accounts, account)
|
|
|
|
return nil
|
|
|
|
})
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-10-09 17:23:54 +02:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
minConf := int32(*cmd.MinConf)
|
2014-12-12 09:54:26 +01:00
|
|
|
for _, account := range accounts {
|
|
|
|
acctName, err := w.Manager.AccountName(account)
|
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrAccountNameNotFound
|
2014-12-12 09:54:26 +01:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
bal, err := w.CalculateAccountBalance(account, minConf)
|
2014-12-12 09:54:26 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
accountBalances[acctName] = bal.ToBTC()
|
|
|
|
}
|
2014-01-03 19:34:37 +01:00
|
|
|
// Return the map. This will be marshaled into a JSON object.
|
2014-12-12 09:54:26 +01:00
|
|
|
return accountBalances, nil
|
2013-10-09 17:23:54 +02:00
|
|
|
}
|
|
|
|
|
2014-07-01 17:02:13 +02:00
|
|
|
// ListLockUnspent handles a listlockunspent request by returning an slice of
|
2014-06-23 23:59:57 +02:00
|
|
|
// all locked outpoints.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ListLockUnspent(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return w.LockedOutpoints(), nil
|
2014-06-23 23:59:57 +02:00
|
|
|
}
|
|
|
|
|
2014-10-13 15:29:47 +02:00
|
|
|
// ListReceivedByAccount handles a listreceivedbyaccount request by returning
|
|
|
|
// a slice of objects, each one containing:
|
|
|
|
// "account": the receiving account;
|
|
|
|
// "amount": total amount received by the account;
|
|
|
|
// "confirmations": number of confirmations of the most recent transaction.
|
|
|
|
// It takes two parameters:
|
|
|
|
// "minconf": minimum number of confirmations to consider a transaction -
|
|
|
|
// default: one;
|
|
|
|
// "includeempty": whether or not to include addresses that have no transactions -
|
|
|
|
// default: false.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ListReceivedByAccount(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2014-10-13 15:29:47 +02:00
|
|
|
cmd := icmd.(*btcjson.ListReceivedByAccountCmd)
|
|
|
|
|
2015-03-26 19:22:59 +01:00
|
|
|
var accounts []uint32
|
|
|
|
err := w.Manager.ForEachAccount(func(account uint32) error {
|
|
|
|
accounts = append(accounts, account)
|
|
|
|
return nil
|
|
|
|
})
|
2014-12-12 09:54:26 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2014-10-13 15:29:47 +02:00
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
ret := make([]btcjson.ListReceivedByAccountResult, 0, len(accounts))
|
2015-04-17 22:05:38 +02:00
|
|
|
minConf := int32(*cmd.MinConf)
|
2014-12-12 09:54:26 +01:00
|
|
|
for _, account := range accounts {
|
|
|
|
acctName, err := w.Manager.AccountName(account)
|
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrAccountNameNotFound
|
2014-12-12 09:54:26 +01:00
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
bal, confirmations, err := w.TotalReceivedForAccount(account,
|
2015-04-17 22:05:38 +02:00
|
|
|
minConf)
|
2014-12-12 09:54:26 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
ret = append(ret, btcjson.ListReceivedByAccountResult{
|
|
|
|
Account: acctName,
|
|
|
|
Amount: bal.ToBTC(),
|
2014-10-13 15:29:47 +02:00
|
|
|
Confirmations: uint64(confirmations),
|
2014-12-12 09:54:26 +01:00
|
|
|
})
|
2014-10-13 15:29:47 +02:00
|
|
|
}
|
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
|
2014-06-06 18:10:29 +02:00
|
|
|
// ListReceivedByAddress handles a listreceivedbyaddress request by returning
|
|
|
|
// a slice of objects, each one containing:
|
|
|
|
// "account": the account of the receiving address;
|
|
|
|
// "address": the receiving address;
|
|
|
|
// "amount": total amount received by the address;
|
|
|
|
// "confirmations": number of confirmations of the most recent transaction.
|
|
|
|
// It takes two parameters:
|
|
|
|
// "minconf": minimum number of confirmations to consider a transaction -
|
|
|
|
// default: one;
|
|
|
|
// "includeempty": whether or not to include addresses that have no transactions -
|
|
|
|
// default: false.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ListReceivedByAddress(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.ListReceivedByAddressCmd)
|
2014-06-06 18:10:29 +02:00
|
|
|
|
|
|
|
// Intermediate data for each address.
|
|
|
|
type AddrData struct {
|
|
|
|
// Total amount received.
|
|
|
|
amount btcutil.Amount
|
|
|
|
// Number of confirmations of the last transaction.
|
|
|
|
confirmations int32
|
2014-09-04 17:24:07 +02:00
|
|
|
// Hashes of transactions which include an output paying to the address
|
|
|
|
tx []string
|
2014-12-12 09:54:26 +01:00
|
|
|
// Account which the address belongs to
|
|
|
|
account string
|
2014-06-06 18:10:29 +02:00
|
|
|
}
|
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
syncBlock := w.Manager.SyncedTo()
|
2014-06-06 18:10:29 +02:00
|
|
|
|
2014-07-07 23:57:00 +02:00
|
|
|
// Intermediate data for all addresses.
|
|
|
|
allAddrData := make(map[string]AddrData)
|
2015-04-17 22:05:38 +02:00
|
|
|
// Create an AddrData entry for each active address in the account.
|
|
|
|
// Otherwise we'll just get addresses from transactions later.
|
|
|
|
sortedAddrs, err := w.SortedActivePaymentAddresses()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for _, address := range sortedAddrs {
|
|
|
|
// There might be duplicates, just overwrite them.
|
|
|
|
allAddrData[address] = AddrData{}
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
minConf := *cmd.MinConf
|
2015-04-06 21:03:24 +02:00
|
|
|
var endHeight int32
|
2015-04-17 22:05:38 +02:00
|
|
|
if minConf == 0 {
|
2015-04-06 21:03:24 +02:00
|
|
|
endHeight = -1
|
|
|
|
} else {
|
2015-04-17 22:05:38 +02:00
|
|
|
endHeight = syncBlock.Height - int32(minConf) + 1
|
2015-04-06 21:03:24 +02:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
err = w.TxStore.RangeTransactions(0, endHeight, func(details []wtxmgr.TxDetails) (bool, error) {
|
2015-04-06 21:03:24 +02:00
|
|
|
confirmations := confirms(details[0].Block.Height, syncBlock.Height)
|
|
|
|
for _, tx := range details {
|
|
|
|
for _, cred := range tx.Credits {
|
|
|
|
pkScript := tx.MsgTx.TxOut[cred.Index].PkScript
|
|
|
|
_, addrs, _, err := txscript.ExtractPkScriptAddrs(
|
|
|
|
pkScript, activeNet.Params)
|
|
|
|
if err != nil {
|
|
|
|
// Non standard script, skip.
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for _, addr := range addrs {
|
|
|
|
addrStr := addr.EncodeAddress()
|
|
|
|
addrData, ok := allAddrData[addrStr]
|
|
|
|
if ok {
|
|
|
|
addrData.amount += cred.Amount
|
|
|
|
// Always overwrite confirmations with newer ones.
|
|
|
|
addrData.confirmations = confirmations
|
|
|
|
} else {
|
|
|
|
addrData = AddrData{
|
|
|
|
amount: cred.Amount,
|
|
|
|
confirmations: confirmations,
|
|
|
|
}
|
2014-06-06 18:10:29 +02:00
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
addrData.tx = append(addrData.tx, tx.Hash.String())
|
|
|
|
allAddrData[addrStr] = addrData
|
2014-06-06 18:10:29 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-04-06 21:03:24 +02:00
|
|
|
return false, nil
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2014-06-06 18:10:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Massage address data into output format.
|
|
|
|
numAddresses := len(allAddrData)
|
|
|
|
ret := make([]btcjson.ListReceivedByAddressResult, numAddresses, numAddresses)
|
|
|
|
idx := 0
|
|
|
|
for address, addrData := range allAddrData {
|
|
|
|
ret[idx] = btcjson.ListReceivedByAddressResult{
|
|
|
|
Address: address,
|
2014-12-12 09:54:26 +01:00
|
|
|
Amount: addrData.amount.ToBTC(),
|
2014-06-06 18:10:29 +02:00
|
|
|
Confirmations: uint64(addrData.confirmations),
|
2014-10-26 19:27:39 +01:00
|
|
|
TxIDs: addrData.tx,
|
2014-06-06 18:10:29 +02:00
|
|
|
}
|
|
|
|
idx++
|
|
|
|
}
|
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
|
2014-01-27 18:53:32 +01:00
|
|
|
// ListSinceBlock handles a listsinceblock request by returning an array of maps
|
|
|
|
// with details of sent and received wallet transactions since the given block.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ListSinceBlock(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.ListSinceBlockCmd)
|
2014-06-12 18:39:26 +02:00
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
syncBlock := w.Manager.SyncedTo()
|
2015-04-17 22:05:38 +02:00
|
|
|
targetConf := int64(*cmd.TargetConfirmations)
|
2015-04-06 21:03:24 +02:00
|
|
|
|
|
|
|
// For the result we need the block hash for the last block counted
|
|
|
|
// in the blockchain due to confirmations. We send this off now so that
|
|
|
|
// it can arrive asynchronously while we figure out the rest.
|
2015-04-17 22:05:38 +02:00
|
|
|
gbh := chainSvr.GetBlockHashAsync(int64(syncBlock.Height) + 1 - targetConf)
|
2015-04-06 21:03:24 +02:00
|
|
|
|
|
|
|
var start int32
|
2015-04-17 22:05:38 +02:00
|
|
|
if cmd.BlockHash != nil {
|
|
|
|
hash, err := wire.NewShaHashFromStr(*cmd.BlockHash)
|
2014-06-12 18:39:26 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, DeserializationError{err}
|
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
block, err := chainSvr.GetBlockVerbose(hash, false)
|
2014-01-27 18:53:32 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
start = int32(block.Height) + 1
|
2014-01-27 18:53:32 +01:00
|
|
|
}
|
|
|
|
|
2015-05-06 22:32:39 +02:00
|
|
|
txInfoList, err := w.ListSinceBlock(start, -1, syncBlock.Height)
|
2014-01-27 18:53:32 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-01-27 18:53:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Done with work, get the response.
|
2014-06-12 18:39:26 +02:00
|
|
|
blockHash, err := gbh.Receive()
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2014-01-27 18:53:32 +01:00
|
|
|
}
|
|
|
|
|
2014-04-12 02:33:15 +02:00
|
|
|
res := btcjson.ListSinceBlockResult{
|
|
|
|
Transactions: txInfoList,
|
2014-06-12 18:39:26 +02:00
|
|
|
LastBlock: blockHash.String(),
|
2014-04-12 02:33:15 +02:00
|
|
|
}
|
2014-01-27 18:53:32 +01:00
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// ListTransactions handles a listtransactions request by returning an
|
|
|
|
// array of maps with details of sent and recevied wallet transactions.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ListTransactions(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.ListTransactionsCmd)
|
2013-11-22 19:42:25 +01:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
// TODO: ListTransactions does not currently understand the difference
|
|
|
|
// between transactions pertaining to one account from another. This
|
|
|
|
// will be resolved when wtxmgr is combined with the waddrmgr namespace.
|
|
|
|
|
2015-04-16 18:54:56 +02:00
|
|
|
if cmd.Account != nil && *cmd.Account != "*" {
|
2015-04-17 22:05:38 +02:00
|
|
|
// For now, don't bother trying to continue if the user
|
|
|
|
// specified an account, since this can't be (easily or
|
|
|
|
// efficiently) calculated.
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWallet,
|
|
|
|
Message: "Transactions are not yet grouped by account",
|
2014-12-12 09:54:26 +01:00
|
|
|
}
|
2013-11-22 19:42:25 +01:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
return w.ListTransactions(*cmd.From, *cmd.Count)
|
2013-11-22 19:42:25 +01:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// ListAddressTransactions handles a listaddresstransactions request by
|
|
|
|
// returning an array of maps with details of spent and received wallet
|
|
|
|
// transactions. The form of the reply is identical to listtransactions,
|
|
|
|
// but the array elements are limited to transaction details which are
|
|
|
|
// about the addresess included in the request.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ListAddressTransactions(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
|
|
|
cmd := icmd.(*btcjson.ListAddressTransactionsCmd)
|
2013-12-30 17:10:06 +01:00
|
|
|
|
2015-04-16 18:54:56 +02:00
|
|
|
if cmd.Account != nil && *cmd.Account != "*" {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInvalidParameter,
|
|
|
|
Message: "Listing transactions for addresses may only be done for all accounts",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-06 18:24:29 +01:00
|
|
|
// Decode addresses.
|
2015-04-17 22:05:38 +02:00
|
|
|
hash160Map := make(map[string]struct{})
|
2014-01-06 18:24:29 +01:00
|
|
|
for _, addrStr := range cmd.Addresses {
|
2015-04-17 22:05:38 +02:00
|
|
|
addr, err := decodeAddress(addrStr, activeNet.Params)
|
2014-01-06 18:24:29 +01:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
2013-12-30 17:10:06 +01:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
hash160Map[string(addr.ScriptAddress())] = struct{}{}
|
2013-12-30 17:10:06 +01:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
return w.ListAddressTransactions(hash160Map)
|
2013-12-30 17:10:06 +01:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// ListAllTransactions handles a listalltransactions request by returning
|
|
|
|
// a map with details of sent and recevied wallet transactions. This is
|
|
|
|
// similar to ListTransactions, except it takes only a single optional
|
|
|
|
// argument for the account name and replies with all transactions.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ListAllTransactions(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
2015-04-16 18:54:56 +02:00
|
|
|
cmd := icmd.(*btcjson.ListAllTransactionsCmd)
|
|
|
|
|
|
|
|
if cmd.Account != nil && *cmd.Account != "*" {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInvalidParameter,
|
|
|
|
Message: "Listing all transactions may only be done for all accounts",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return w.ListAllTransactions()
|
2013-12-02 23:34:36 +01:00
|
|
|
}
|
|
|
|
|
2014-02-13 19:43:52 +01:00
|
|
|
// ListUnspent handles the listunspent command.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ListUnspent(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.ListUnspentCmd)
|
2014-06-04 02:52:04 +02:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
var addresses map[string]struct{}
|
|
|
|
if cmd.Addresses != nil {
|
|
|
|
addresses = make(map[string]struct{})
|
2014-02-13 19:43:52 +01:00
|
|
|
// confirm that all of them are good:
|
2015-04-17 22:05:38 +02:00
|
|
|
for _, as := range *cmd.Addresses {
|
|
|
|
a, err := decodeAddress(as, activeNet.Params)
|
2014-02-13 19:43:52 +01:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
2014-02-13 19:43:52 +01:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
addresses[a.EncodeAddress()] = struct{}{}
|
2014-02-13 19:43:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
return w.ListUnspent(int32(*cmd.MinConf), int32(*cmd.MaxConf), addresses)
|
2014-02-13 19:43:52 +01:00
|
|
|
}
|
|
|
|
|
2014-06-23 23:59:57 +02:00
|
|
|
// LockUnspent handles the lockunspent command.
|
2015-04-17 22:05:38 +02:00
|
|
|
func LockUnspent(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.LockUnspentCmd)
|
2014-06-23 23:59:57 +02:00
|
|
|
|
|
|
|
switch {
|
|
|
|
case cmd.Unlock && len(cmd.Transactions) == 0:
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
w.ResetLockedOutpoints()
|
2014-06-23 23:59:57 +02:00
|
|
|
default:
|
|
|
|
for _, input := range cmd.Transactions {
|
2015-02-05 22:41:38 +01:00
|
|
|
txSha, err := wire.NewShaHashFromStr(input.Txid)
|
2014-06-23 23:59:57 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, ParseError{err}
|
|
|
|
}
|
2015-02-05 22:41:38 +01:00
|
|
|
op := wire.OutPoint{Hash: *txSha, Index: input.Vout}
|
2014-06-23 23:59:57 +02:00
|
|
|
if cmd.Unlock {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
w.UnlockOutpoint(op)
|
2014-06-23 23:59:57 +02:00
|
|
|
} else {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
w.LockOutpoint(op)
|
2014-06-23 23:59:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
2015-04-29 02:12:53 +02:00
|
|
|
// sendPairs creates and sends payment transactions.
|
|
|
|
// It returns the transaction hash in string format upon success
|
|
|
|
// All errors are returned in btcjson.RPCError format
|
|
|
|
func sendPairs(w *wallet.Wallet, amounts map[string]btcutil.Amount,
|
|
|
|
account uint32, minconf int32) (string, error) {
|
|
|
|
txSha, err := w.SendPairs(amounts, account, minconf)
|
2014-06-04 02:52:04 +02:00
|
|
|
if err != nil {
|
2015-04-29 02:12:53 +02:00
|
|
|
if err == wallet.ErrNonPositiveAmount {
|
2015-04-06 21:03:24 +02:00
|
|
|
return "", ErrNeedPositiveAmount
|
2015-04-29 02:12:53 +02:00
|
|
|
}
|
|
|
|
if isManagerLockedError(err) {
|
2015-04-17 22:05:38 +02:00
|
|
|
return "", &ErrWalletUnlockNeeded
|
2013-11-12 18:01:32 +01:00
|
|
|
}
|
2015-04-29 02:12:53 +02:00
|
|
|
switch err.(type) {
|
|
|
|
case btcjson.RPCError:
|
|
|
|
return "", err
|
|
|
|
}
|
2014-10-29 07:43:29 +01:00
|
|
|
|
2015-04-29 02:12:53 +02:00
|
|
|
return "", &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInternal.Code,
|
|
|
|
Message: err.Error(),
|
2014-06-12 18:39:26 +02:00
|
|
|
}
|
2013-11-06 18:37:46 +01:00
|
|
|
}
|
2013-10-28 19:13:20 +01:00
|
|
|
|
2015-04-06 21:03:24 +02:00
|
|
|
txShaStr := txSha.String()
|
|
|
|
log.Infof("Successfully sent transaction %v", txShaStr)
|
|
|
|
return txShaStr, nil
|
2014-02-04 17:33:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// SendFrom handles a sendfrom RPC request by creating a new transaction
|
|
|
|
// spending unspent transaction outputs for a wallet to another payment
|
|
|
|
// address. Leftover inputs not sent to the payment address or a fee for
|
|
|
|
// the miner are sent back to a new address in the wallet. Upon success,
|
|
|
|
// the TxID for the created transaction is returned.
|
2015-04-17 22:05:38 +02:00
|
|
|
func SendFrom(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.SendFromCmd)
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
// Transaction comments are not yet supported. Error instead of
|
|
|
|
// pretending to save them.
|
|
|
|
if cmd.Comment != nil || cmd.CommentTo != nil {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCUnimplemented,
|
|
|
|
Message: "Transaction comments are not yet supported",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
account, err := w.Manager.LookupAccount(cmd.FromAccount)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2014-02-04 17:33:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check that signed integer parameters are positive.
|
|
|
|
if cmd.Amount < 0 {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, ErrNeedPositiveAmount
|
2014-02-04 17:33:29 +01:00
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
minConf := int32(*cmd.MinConf)
|
|
|
|
if minConf < 0 {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, ErrNeedPositiveMinconf
|
2014-02-04 17:33:29 +01:00
|
|
|
}
|
|
|
|
// Create map of address and amount pairs.
|
2015-04-17 22:05:38 +02:00
|
|
|
amt, err := btcutil.NewAmount(cmd.Amount)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
Another day, another tx store implementation.
The last transaction store was a great example of how not to write
scalable software. For a variety of reasons, it was very slow at
processing transaction inserts. Among them:
1) Every single transaction record being saved in a linked list
(container/list), and inserting into this list would be an O(n)
operation so that records could be ordered by receive date.
2) Every single transaction in the above mentioned list was iterated
over in order to find double spends which must be removed. It is
silly to do this check for mined transactions, which already have
been checked for this by btcd. Worse yet, if double spends were
found, the list would be iterated a second (or third, or fourth)
time for each removed transaction.
3) All spend tracking for signed-by-wallet transactions was found on
each transaction insert, even if the now spent previous transaction
outputs were known by the caller.
This list could keep going on, but you get the idea. It was bad.
To resolve these issues a new transaction store had to be implemented.
The new implementation:
1) Tracks mined and unmined transactions in different data structures.
Mined transactions are cheap to track because the required double
spend checks have already been performed by the chain server, and
double spend checks are only required to be performed on
newly-inserted mined transactions which may conflict with previous
unmined transactions.
2) Saves mined transactions grouped by block first, and then by their
transaction index. Lookup keys for mined transactions are simply
the block height (in the best chain, that's all we save) and index
of the transaction in the block. This makes looking up any
arbitrary transaction almost an O(1) operation (almost, because
block height and block indexes are mapped to their slice indexes
with a Go map).
3) Saves records in each transaction for whether the outputs are
wallet credits (spendable by wallet) and for whether inputs debit
from previous credits. Both structures point back to the source
or spender (credits point to the transaction that spends them, or
nil for unspent credits, and debits include keys to lookup the
transaction credits they spent. While complicated to keep track
of, this greatly simplifies the spent tracking for transactions
across rollbacks and transaction removals.
4) Implements double spend checking as an almost O(1) operation. A
Go map is used to map each previous outpoint for all unconfirmed
transactions to the unconfirmed tx record itself. Checking for
double spends on confirmed transaction inserts only involves
looking up each previous outpoint of the inserted tx in this map.
If a double spend is found, removal is simplified by only
removing the transaction and its spend chain from store maps,
rather than iterating a linked list several times over to remove
each dead transaction in the spend chain.
5) Allows the caller to specify the previous credits which are spent
by a debiting transaction. When a transaction is created by
wallet, the previous outputs are already known, and by passing
their record types to the AddDebits method, lookups for each
previously unspent credit are omitted.
6) Bookkeeps all blocks with transactions with unspent credits, and
bookkeeps the transaction indexes of all transactions with unspent
outputs for a single block. For the case where the caller adding a
debit record does not know what credits a transaction debits from,
these bookkeeping structures allow the store to only consider known
unspent transactions, rather than searching through both spent and
unspents.
7) Saves amount deltas for the entire balance as a result of each
block, due to transactions within that block. This improves the
performance of calculating the full balance by not needing to
iterate over every transaction, and then every credit, to determine
if a credit is spent or unspent. When transactions are moved from
unconfirmed to a block structure, the amount deltas are incremented
by the amount of all transaction credits (both spent and unspent)
and debited by the total amount the transaction spends from
previous wallet credits. For the common case of calculating a
balance with just one confirmation, the only involves iterating
over each block structure and adding the (possibly negative)
amount delta. Coinbase rewards are saved similarly, but with a
different amount variable so they can be seperatly included or
excluded.
Due to all of the changes in how the store internally works, the
serialization format has changed. To simplify the serialization
logic, support for reading the last store file version has been
removed. Past this change, a rescan (run automatically) will be
required to rebuild the transaction history.
2014-05-05 23:12:05 +02:00
|
|
|
pairs := map[string]btcutil.Amount{
|
2015-04-17 22:05:38 +02:00
|
|
|
cmd.ToAddress: amt,
|
2014-02-04 17:33:29 +01:00
|
|
|
}
|
|
|
|
|
2015-04-29 02:12:53 +02:00
|
|
|
return sendPairs(w, pairs, account, minConf)
|
2013-09-09 20:14:57 +02:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// SendMany handles a sendmany RPC request by creating a new transaction
|
|
|
|
// spending unspent transaction outputs for a wallet to any number of
|
|
|
|
// payment addresses. Leftover inputs not sent to the payment address
|
|
|
|
// or a fee for the miner are sent back to a new address in the wallet.
|
|
|
|
// Upon success, the TxID for the created transaction is returned.
|
2015-04-17 22:05:38 +02:00
|
|
|
func SendMany(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.SendManyCmd)
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
// Transaction comments are not yet supported. Error instead of
|
|
|
|
// pretending to save them.
|
|
|
|
if cmd.Comment != nil {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCUnimplemented,
|
|
|
|
Message: "Transaction comments are not yet supported",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
account, err := w.Manager.LookupAccount(cmd.FromAccount)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2013-09-09 20:14:57 +02:00
|
|
|
}
|
|
|
|
|
2013-11-12 18:01:32 +01:00
|
|
|
// Check that minconf is positive.
|
2015-04-17 22:05:38 +02:00
|
|
|
minConf := int32(*cmd.MinConf)
|
|
|
|
if minConf < 0 {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, ErrNeedPositiveMinconf
|
2013-09-09 20:14:57 +02:00
|
|
|
}
|
|
|
|
|
Another day, another tx store implementation.
The last transaction store was a great example of how not to write
scalable software. For a variety of reasons, it was very slow at
processing transaction inserts. Among them:
1) Every single transaction record being saved in a linked list
(container/list), and inserting into this list would be an O(n)
operation so that records could be ordered by receive date.
2) Every single transaction in the above mentioned list was iterated
over in order to find double spends which must be removed. It is
silly to do this check for mined transactions, which already have
been checked for this by btcd. Worse yet, if double spends were
found, the list would be iterated a second (or third, or fourth)
time for each removed transaction.
3) All spend tracking for signed-by-wallet transactions was found on
each transaction insert, even if the now spent previous transaction
outputs were known by the caller.
This list could keep going on, but you get the idea. It was bad.
To resolve these issues a new transaction store had to be implemented.
The new implementation:
1) Tracks mined and unmined transactions in different data structures.
Mined transactions are cheap to track because the required double
spend checks have already been performed by the chain server, and
double spend checks are only required to be performed on
newly-inserted mined transactions which may conflict with previous
unmined transactions.
2) Saves mined transactions grouped by block first, and then by their
transaction index. Lookup keys for mined transactions are simply
the block height (in the best chain, that's all we save) and index
of the transaction in the block. This makes looking up any
arbitrary transaction almost an O(1) operation (almost, because
block height and block indexes are mapped to their slice indexes
with a Go map).
3) Saves records in each transaction for whether the outputs are
wallet credits (spendable by wallet) and for whether inputs debit
from previous credits. Both structures point back to the source
or spender (credits point to the transaction that spends them, or
nil for unspent credits, and debits include keys to lookup the
transaction credits they spent. While complicated to keep track
of, this greatly simplifies the spent tracking for transactions
across rollbacks and transaction removals.
4) Implements double spend checking as an almost O(1) operation. A
Go map is used to map each previous outpoint for all unconfirmed
transactions to the unconfirmed tx record itself. Checking for
double spends on confirmed transaction inserts only involves
looking up each previous outpoint of the inserted tx in this map.
If a double spend is found, removal is simplified by only
removing the transaction and its spend chain from store maps,
rather than iterating a linked list several times over to remove
each dead transaction in the spend chain.
5) Allows the caller to specify the previous credits which are spent
by a debiting transaction. When a transaction is created by
wallet, the previous outputs are already known, and by passing
their record types to the AddDebits method, lookups for each
previously unspent credit are omitted.
6) Bookkeeps all blocks with transactions with unspent credits, and
bookkeeps the transaction indexes of all transactions with unspent
outputs for a single block. For the case where the caller adding a
debit record does not know what credits a transaction debits from,
these bookkeeping structures allow the store to only consider known
unspent transactions, rather than searching through both spent and
unspents.
7) Saves amount deltas for the entire balance as a result of each
block, due to transactions within that block. This improves the
performance of calculating the full balance by not needing to
iterate over every transaction, and then every credit, to determine
if a credit is spent or unspent. When transactions are moved from
unconfirmed to a block structure, the amount deltas are incremented
by the amount of all transaction credits (both spent and unspent)
and debited by the total amount the transaction spends from
previous wallet credits. For the common case of calculating a
balance with just one confirmation, the only involves iterating
over each block structure and adding the (possibly negative)
amount delta. Coinbase rewards are saved similarly, but with a
different amount variable so they can be seperatly included or
excluded.
Due to all of the changes in how the store internally works, the
serialization format has changed. To simplify the serialization
logic, support for reading the last store file version has been
removed. Past this change, a rescan (run automatically) will be
required to rebuild the transaction history.
2014-05-05 23:12:05 +02:00
|
|
|
// Recreate address/amount pairs, using btcutil.Amount.
|
|
|
|
pairs := make(map[string]btcutil.Amount, len(cmd.Amounts))
|
|
|
|
for k, v := range cmd.Amounts {
|
2015-04-17 22:05:38 +02:00
|
|
|
amt, err := btcutil.NewAmount(v)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
pairs[k] = amt
|
Another day, another tx store implementation.
The last transaction store was a great example of how not to write
scalable software. For a variety of reasons, it was very slow at
processing transaction inserts. Among them:
1) Every single transaction record being saved in a linked list
(container/list), and inserting into this list would be an O(n)
operation so that records could be ordered by receive date.
2) Every single transaction in the above mentioned list was iterated
over in order to find double spends which must be removed. It is
silly to do this check for mined transactions, which already have
been checked for this by btcd. Worse yet, if double spends were
found, the list would be iterated a second (or third, or fourth)
time for each removed transaction.
3) All spend tracking for signed-by-wallet transactions was found on
each transaction insert, even if the now spent previous transaction
outputs were known by the caller.
This list could keep going on, but you get the idea. It was bad.
To resolve these issues a new transaction store had to be implemented.
The new implementation:
1) Tracks mined and unmined transactions in different data structures.
Mined transactions are cheap to track because the required double
spend checks have already been performed by the chain server, and
double spend checks are only required to be performed on
newly-inserted mined transactions which may conflict with previous
unmined transactions.
2) Saves mined transactions grouped by block first, and then by their
transaction index. Lookup keys for mined transactions are simply
the block height (in the best chain, that's all we save) and index
of the transaction in the block. This makes looking up any
arbitrary transaction almost an O(1) operation (almost, because
block height and block indexes are mapped to their slice indexes
with a Go map).
3) Saves records in each transaction for whether the outputs are
wallet credits (spendable by wallet) and for whether inputs debit
from previous credits. Both structures point back to the source
or spender (credits point to the transaction that spends them, or
nil for unspent credits, and debits include keys to lookup the
transaction credits they spent. While complicated to keep track
of, this greatly simplifies the spent tracking for transactions
across rollbacks and transaction removals.
4) Implements double spend checking as an almost O(1) operation. A
Go map is used to map each previous outpoint for all unconfirmed
transactions to the unconfirmed tx record itself. Checking for
double spends on confirmed transaction inserts only involves
looking up each previous outpoint of the inserted tx in this map.
If a double spend is found, removal is simplified by only
removing the transaction and its spend chain from store maps,
rather than iterating a linked list several times over to remove
each dead transaction in the spend chain.
5) Allows the caller to specify the previous credits which are spent
by a debiting transaction. When a transaction is created by
wallet, the previous outputs are already known, and by passing
their record types to the AddDebits method, lookups for each
previously unspent credit are omitted.
6) Bookkeeps all blocks with transactions with unspent credits, and
bookkeeps the transaction indexes of all transactions with unspent
outputs for a single block. For the case where the caller adding a
debit record does not know what credits a transaction debits from,
these bookkeeping structures allow the store to only consider known
unspent transactions, rather than searching through both spent and
unspents.
7) Saves amount deltas for the entire balance as a result of each
block, due to transactions within that block. This improves the
performance of calculating the full balance by not needing to
iterate over every transaction, and then every credit, to determine
if a credit is spent or unspent. When transactions are moved from
unconfirmed to a block structure, the amount deltas are incremented
by the amount of all transaction credits (both spent and unspent)
and debited by the total amount the transaction spends from
previous wallet credits. For the common case of calculating a
balance with just one confirmation, the only involves iterating
over each block structure and adding the (possibly negative)
amount delta. Coinbase rewards are saved similarly, but with a
different amount variable so they can be seperatly included or
excluded.
Due to all of the changes in how the store internally works, the
serialization format has changed. To simplify the serialization
logic, support for reading the last store file version has been
removed. Past this change, a rescan (run automatically) will be
required to rebuild the transaction history.
2014-05-05 23:12:05 +02:00
|
|
|
}
|
|
|
|
|
2015-04-29 02:12:53 +02:00
|
|
|
return sendPairs(w, pairs, account, minConf)
|
2014-02-04 17:33:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// SendToAddress handles a sendtoaddress RPC request by creating a new
|
|
|
|
// transaction spending unspent transaction outputs for a wallet to another
|
|
|
|
// payment address. Leftover inputs not sent to the payment address or a fee
|
|
|
|
// for the miner are sent back to a new address in the wallet. Upon success,
|
|
|
|
// the TxID for the created transaction is returned.
|
2015-04-17 22:05:38 +02:00
|
|
|
func SendToAddress(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.SendToAddressCmd)
|
2013-09-09 20:14:57 +02:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
// Transaction comments are not yet supported. Error instead of
|
|
|
|
// pretending to save them.
|
|
|
|
if cmd.Comment != nil || cmd.CommentTo != nil {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCUnimplemented,
|
|
|
|
Message: "Transaction comments are not yet supported",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
amt, err := btcutil.NewAmount(cmd.Amount)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2014-02-04 17:33:29 +01:00
|
|
|
// Check that signed integer parameters are positive.
|
2015-04-17 22:05:38 +02:00
|
|
|
if amt < 0 {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, ErrNeedPositiveAmount
|
2013-09-09 20:14:57 +02:00
|
|
|
}
|
|
|
|
|
2014-02-04 17:33:29 +01:00
|
|
|
// Mock up map of address and amount pairs.
|
Another day, another tx store implementation.
The last transaction store was a great example of how not to write
scalable software. For a variety of reasons, it was very slow at
processing transaction inserts. Among them:
1) Every single transaction record being saved in a linked list
(container/list), and inserting into this list would be an O(n)
operation so that records could be ordered by receive date.
2) Every single transaction in the above mentioned list was iterated
over in order to find double spends which must be removed. It is
silly to do this check for mined transactions, which already have
been checked for this by btcd. Worse yet, if double spends were
found, the list would be iterated a second (or third, or fourth)
time for each removed transaction.
3) All spend tracking for signed-by-wallet transactions was found on
each transaction insert, even if the now spent previous transaction
outputs were known by the caller.
This list could keep going on, but you get the idea. It was bad.
To resolve these issues a new transaction store had to be implemented.
The new implementation:
1) Tracks mined and unmined transactions in different data structures.
Mined transactions are cheap to track because the required double
spend checks have already been performed by the chain server, and
double spend checks are only required to be performed on
newly-inserted mined transactions which may conflict with previous
unmined transactions.
2) Saves mined transactions grouped by block first, and then by their
transaction index. Lookup keys for mined transactions are simply
the block height (in the best chain, that's all we save) and index
of the transaction in the block. This makes looking up any
arbitrary transaction almost an O(1) operation (almost, because
block height and block indexes are mapped to their slice indexes
with a Go map).
3) Saves records in each transaction for whether the outputs are
wallet credits (spendable by wallet) and for whether inputs debit
from previous credits. Both structures point back to the source
or spender (credits point to the transaction that spends them, or
nil for unspent credits, and debits include keys to lookup the
transaction credits they spent. While complicated to keep track
of, this greatly simplifies the spent tracking for transactions
across rollbacks and transaction removals.
4) Implements double spend checking as an almost O(1) operation. A
Go map is used to map each previous outpoint for all unconfirmed
transactions to the unconfirmed tx record itself. Checking for
double spends on confirmed transaction inserts only involves
looking up each previous outpoint of the inserted tx in this map.
If a double spend is found, removal is simplified by only
removing the transaction and its spend chain from store maps,
rather than iterating a linked list several times over to remove
each dead transaction in the spend chain.
5) Allows the caller to specify the previous credits which are spent
by a debiting transaction. When a transaction is created by
wallet, the previous outputs are already known, and by passing
their record types to the AddDebits method, lookups for each
previously unspent credit are omitted.
6) Bookkeeps all blocks with transactions with unspent credits, and
bookkeeps the transaction indexes of all transactions with unspent
outputs for a single block. For the case where the caller adding a
debit record does not know what credits a transaction debits from,
these bookkeeping structures allow the store to only consider known
unspent transactions, rather than searching through both spent and
unspents.
7) Saves amount deltas for the entire balance as a result of each
block, due to transactions within that block. This improves the
performance of calculating the full balance by not needing to
iterate over every transaction, and then every credit, to determine
if a credit is spent or unspent. When transactions are moved from
unconfirmed to a block structure, the amount deltas are incremented
by the amount of all transaction credits (both spent and unspent)
and debited by the total amount the transaction spends from
previous wallet credits. For the common case of calculating a
balance with just one confirmation, the only involves iterating
over each block structure and adding the (possibly negative)
amount delta. Coinbase rewards are saved similarly, but with a
different amount variable so they can be seperatly included or
excluded.
Due to all of the changes in how the store internally works, the
serialization format has changed. To simplify the serialization
logic, support for reading the last store file version has been
removed. Past this change, a rescan (run automatically) will be
required to rebuild the transaction history.
2014-05-05 23:12:05 +02:00
|
|
|
pairs := map[string]btcutil.Amount{
|
2015-04-17 22:05:38 +02:00
|
|
|
cmd.Address: amt,
|
2013-11-12 18:01:32 +01:00
|
|
|
}
|
Perform smarter UTXO tracking.
This change fixes many issues with the tracking of unspent transaction
outputs. First, notifications for when UTXOs arse spent are now
requested from btcd, and when spent, will be removed from the
UtxoStore.
Second, when transactions are created, the unconfirmed (not yet in a
block) Utxo (with block height -1 and zeroed block hash) is added to
the wallet's UtxoStore. Notifications for when this UTXO is spent are
also requested from btcd. After the tx appears in a block, because
the UTXO has a pkScript to be spent by another owned wallet address, a
notification with the UTXO will be sent to btcwallet. We already
store the unconfirmed UTXO, so at this point the actual block height
and hash are filled in.
Finally, when calculating the balance, if confirmations is zero,
unconfirmed UTXOs (block height -1) will be included in the balance.
Otherwise, they are ignored.
2013-10-22 15:55:53 +02:00
|
|
|
|
2014-12-12 09:54:26 +01:00
|
|
|
// sendtoaddress always spends from the default account, this matches bitcoind
|
2015-04-29 02:12:53 +02:00
|
|
|
return sendPairs(w, pairs, waddrmgr.DefaultAccountNum, 1)
|
2013-09-03 15:49:16 +02:00
|
|
|
}
|
|
|
|
|
2013-12-04 01:22:47 +01:00
|
|
|
// SetTxFee sets the transaction fee per kilobyte added to transactions.
|
2015-04-17 22:05:38 +02:00
|
|
|
func SetTxFee(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.SetTxFeeCmd)
|
2013-11-12 18:01:32 +01:00
|
|
|
|
|
|
|
// Check that amount is not negative.
|
|
|
|
if cmd.Amount < 0 {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, ErrNeedPositiveAmount
|
2013-10-07 21:14:39 +02:00
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
incr, err := btcutil.NewAmount(cmd.Amount)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
w.FeeIncrement = incr
|
2013-10-07 21:14:39 +02:00
|
|
|
|
2013-11-12 18:01:32 +01:00
|
|
|
// A boolean true result is returned upon success.
|
2014-01-03 19:34:37 +01:00
|
|
|
return true, nil
|
2013-10-07 21:14:39 +02:00
|
|
|
}
|
|
|
|
|
2014-02-12 03:14:07 +01:00
|
|
|
// SignMessage signs the given message with the private key for the given
|
|
|
|
// address
|
2015-04-17 22:05:38 +02:00
|
|
|
func SignMessage(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.SignMessageCmd)
|
2014-02-12 03:14:07 +01:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
addr, err := decodeAddress(cmd.Address, activeNet.Params)
|
2014-02-12 03:14:07 +01:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
2014-02-12 03:14:07 +01:00
|
|
|
}
|
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
ainfo, err := w.Manager.Address(addr)
|
2014-04-03 17:00:46 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
pka, ok := ainfo.(waddrmgr.ManagedPubKeyAddress)
|
|
|
|
if !ok {
|
|
|
|
msg := fmt.Sprintf("Address '%s' does not have an associated private key", addr)
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCInvalidAddressOrKey,
|
|
|
|
Message: msg,
|
|
|
|
}
|
2014-04-03 17:00:46 +02:00
|
|
|
}
|
2014-10-29 07:43:29 +01:00
|
|
|
privKey, err := pka.PrivKey()
|
2014-02-12 03:14:07 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-02-12 03:14:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fullmsg := "Bitcoin Signed Message:\n" + cmd.Message
|
2014-09-27 20:59:18 +02:00
|
|
|
sigbytes, err := btcec.SignCompact(btcec.S256(), privKey,
|
2015-02-05 22:41:38 +01:00
|
|
|
wire.DoubleSha256([]byte(fullmsg)), ainfo.Compressed())
|
2014-02-12 03:14:07 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-02-12 03:14:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return base64.StdEncoding.EncodeToString(sigbytes), nil
|
|
|
|
}
|
|
|
|
|
2014-04-18 00:13:53 +02:00
|
|
|
// pendingTx is used for async fetching of transaction dependancies in
|
|
|
|
// SignRawTransaction.
|
|
|
|
type pendingTx struct {
|
2014-06-12 18:39:26 +02:00
|
|
|
resp btcrpcclient.FutureGetRawTransactionResult
|
2014-04-18 00:13:53 +02:00
|
|
|
inputs []uint32 // list of inputs that care about this tx.
|
|
|
|
}
|
|
|
|
|
|
|
|
// SignRawTransaction handles the signrawtransaction command.
|
2015-04-17 22:05:38 +02:00
|
|
|
func SignRawTransaction(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.SignRawTransactionCmd)
|
2014-04-18 00:13:53 +02:00
|
|
|
|
2014-07-02 03:50:23 +02:00
|
|
|
serializedTx, err := decodeHexStr(cmd.RawTx)
|
2014-04-18 00:13:53 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
2015-02-05 22:41:38 +01:00
|
|
|
msgTx := wire.NewMsgTx()
|
2014-04-18 00:13:53 +02:00
|
|
|
err = msgTx.Deserialize(bytes.NewBuffer(serializedTx))
|
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
e := errors.New("TX decode failed")
|
|
|
|
return nil, DeserializationError{e}
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// First we add the stuff we have been given.
|
|
|
|
// TODO(oga) really we probably should look these up with btcd anyway
|
|
|
|
// to make sure that they match the blockchain if present.
|
2015-02-05 22:41:38 +01:00
|
|
|
inputs := make(map[wire.OutPoint][]byte)
|
2014-04-18 00:13:53 +02:00
|
|
|
scripts := make(map[string][]byte)
|
2015-04-17 22:05:38 +02:00
|
|
|
var cmdInputs []btcjson.RawTxInput
|
|
|
|
if cmd.Inputs != nil {
|
|
|
|
cmdInputs = *cmd.Inputs
|
|
|
|
}
|
|
|
|
for _, rti := range cmdInputs {
|
2015-02-05 22:41:38 +01:00
|
|
|
inputSha, err := wire.NewShaHashFromStr(rti.Txid)
|
2014-04-18 00:13:53 +02:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, DeserializationError{err}
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
|
2014-07-02 03:50:23 +02:00
|
|
|
script, err := decodeHexStr(rti.ScriptPubKey)
|
2014-04-18 00:13:53 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// redeemScript is only actually used iff the user provided
|
|
|
|
// private keys. In which case, it is used to get the scripts
|
|
|
|
// for signing. If the user did not provide keys then we always
|
|
|
|
// get scripts from the wallet.
|
|
|
|
// Empty strings are ok for this one and hex.DecodeString will
|
|
|
|
// DTRT.
|
2015-04-17 22:05:38 +02:00
|
|
|
if cmd.PrivKeys != nil && len(*cmd.PrivKeys) != 0 {
|
2014-07-02 03:50:23 +02:00
|
|
|
redeemScript, err := decodeHexStr(rti.RedeemScript)
|
2014-04-18 00:13:53 +02:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
addr, err := btcutil.NewAddressScriptHash(redeemScript,
|
2014-05-27 19:50:51 +02:00
|
|
|
activeNet.Params)
|
2014-04-18 00:13:53 +02:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, DeserializationError{err}
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
scripts[addr.String()] = redeemScript
|
|
|
|
}
|
2015-02-05 22:41:38 +01:00
|
|
|
inputs[wire.OutPoint{
|
2014-04-18 00:13:53 +02:00
|
|
|
Hash: *inputSha,
|
2014-06-16 23:25:04 +02:00
|
|
|
Index: rti.Vout,
|
2014-04-18 00:13:53 +02:00
|
|
|
}] = script
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now we go and look for any inputs that we were not provided by
|
|
|
|
// querying btcd with getrawtransaction. We queue up a bunch of async
|
|
|
|
// requests and will wait for replies after we have checked the rest of
|
|
|
|
// the arguments.
|
2015-02-05 22:41:38 +01:00
|
|
|
requested := make(map[wire.ShaHash]*pendingTx)
|
2014-04-18 00:13:53 +02:00
|
|
|
for _, txIn := range msgTx.TxIn {
|
|
|
|
// Did we get this txin from the arguments?
|
2014-10-01 18:27:55 +02:00
|
|
|
if _, ok := inputs[txIn.PreviousOutPoint]; ok {
|
2014-04-18 00:13:53 +02:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Are we already fetching this tx? If so mark us as interested
|
|
|
|
// in this outpoint. (N.B. that any *sane* tx will only
|
|
|
|
// reference each outpoint once, since anything else is a double
|
|
|
|
// spend. We don't check this ourselves to save having to scan
|
|
|
|
// the array, it will fail later if so).
|
2014-10-01 18:27:55 +02:00
|
|
|
if ptx, ok := requested[txIn.PreviousOutPoint.Hash]; ok {
|
2014-04-18 00:13:53 +02:00
|
|
|
ptx.inputs = append(ptx.inputs,
|
2014-10-01 18:27:55 +02:00
|
|
|
txIn.PreviousOutPoint.Index)
|
2014-04-18 00:13:53 +02:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Never heard of this one before, request it.
|
2014-10-01 18:27:55 +02:00
|
|
|
prevHash := &txIn.PreviousOutPoint.Hash
|
|
|
|
requested[txIn.PreviousOutPoint.Hash] = &pendingTx{
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
resp: chainSvr.GetRawTransactionAsync(prevHash),
|
2014-10-01 18:27:55 +02:00
|
|
|
inputs: []uint32{txIn.PreviousOutPoint.Index},
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse list of private keys, if present. If there are any keys here
|
|
|
|
// they are the keys that we may use for signing. If empty we will
|
|
|
|
// use any keys known to us already.
|
2014-05-22 00:50:47 +02:00
|
|
|
var keys map[string]*btcutil.WIF
|
2015-04-17 22:05:38 +02:00
|
|
|
if cmd.PrivKeys != nil {
|
2014-05-22 00:50:47 +02:00
|
|
|
keys = make(map[string]*btcutil.WIF)
|
2014-04-18 00:13:53 +02:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
for _, key := range *cmd.PrivKeys {
|
2014-05-22 00:50:47 +02:00
|
|
|
wif, err := btcutil.DecodeWIF(key)
|
2014-04-18 00:13:53 +02:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, DeserializationError{err}
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
|
2014-05-27 19:50:51 +02:00
|
|
|
if !wif.IsForNet(activeNet.Params) {
|
2014-06-04 02:52:04 +02:00
|
|
|
s := "key network doesn't match wallet's"
|
|
|
|
return nil, DeserializationError{errors.New(s)}
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
|
2014-05-22 00:50:47 +02:00
|
|
|
addr, err := btcutil.NewAddressPubKey(wif.SerializePubKey(),
|
2014-05-27 19:50:51 +02:00
|
|
|
activeNet.Params)
|
2014-05-22 00:50:47 +02:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, DeserializationError{err}
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
2014-05-22 00:50:47 +02:00
|
|
|
keys[addr.EncodeAddress()] = wif
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
var hashType txscript.SigHashType
|
|
|
|
switch *cmd.Flags {
|
|
|
|
case "ALL":
|
|
|
|
hashType = txscript.SigHashAll
|
|
|
|
case "NONE":
|
|
|
|
hashType = txscript.SigHashNone
|
|
|
|
case "SINGLE":
|
|
|
|
hashType = txscript.SigHashSingle
|
|
|
|
case "ALL|ANYONECANPAY":
|
|
|
|
hashType = txscript.SigHashAll | txscript.SigHashAnyOneCanPay
|
|
|
|
case "NONE|ANYONECANPAY":
|
|
|
|
hashType = txscript.SigHashNone | txscript.SigHashAnyOneCanPay
|
|
|
|
case "SINGLE|ANYONECANPAY":
|
|
|
|
hashType = txscript.SigHashSingle | txscript.SigHashAnyOneCanPay
|
|
|
|
default:
|
|
|
|
e := errors.New("Invalid sighash parameter")
|
|
|
|
return nil, InvalidParameterError{e}
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// We have checked the rest of the args. now we can collect the async
|
|
|
|
// txs. TODO(oga) If we don't mind the possibility of wasting work we
|
|
|
|
// could move waiting to the following loop and be slightly more
|
|
|
|
// asynchronous.
|
|
|
|
for txid, ptx := range requested {
|
2014-06-12 18:39:26 +02:00
|
|
|
tx, err := ptx.resp.Receive()
|
2014-04-18 00:13:53 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, input := range ptx.inputs {
|
|
|
|
if input >= uint32(len(tx.MsgTx().TxOut)) {
|
2014-06-04 02:52:04 +02:00
|
|
|
e := fmt.Errorf("input %s:%d is not in tx",
|
|
|
|
txid.String(), input)
|
|
|
|
return nil, InvalidParameterError{e}
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
|
2015-02-05 22:41:38 +01:00
|
|
|
inputs[wire.OutPoint{
|
2014-04-18 00:13:53 +02:00
|
|
|
Hash: txid,
|
|
|
|
Index: input,
|
|
|
|
}] = tx.MsgTx().TxOut[input].PkScript
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// All args collected. Now we can sign all the inputs that we can.
|
|
|
|
// `complete' denotes that we successfully signed all outputs and that
|
|
|
|
// all scripts will run to completion. This is returned as part of the
|
|
|
|
// reply.
|
2015-05-07 18:28:25 +02:00
|
|
|
var signErrors []btcjson.SignRawTransactionError
|
2014-04-18 00:13:53 +02:00
|
|
|
for i, txIn := range msgTx.TxIn {
|
2014-10-01 18:27:55 +02:00
|
|
|
input, ok := inputs[txIn.PreviousOutPoint]
|
2014-04-18 00:13:53 +02:00
|
|
|
if !ok {
|
|
|
|
// failure to find previous is actually an error since
|
|
|
|
// we failed above if we don't have all the inputs.
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, fmt.Errorf("%s:%d not found",
|
2014-10-01 18:27:55 +02:00
|
|
|
txIn.PreviousOutPoint.Hash,
|
|
|
|
txIn.PreviousOutPoint.Index)
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
|
2015-01-30 19:31:29 +01:00
|
|
|
// Set up our callbacks that we pass to txscript so it can
|
2014-04-18 00:13:53 +02:00
|
|
|
// look up the appropriate keys and scripts by address.
|
2015-01-30 19:31:29 +01:00
|
|
|
getKey := txscript.KeyClosure(func(addr btcutil.Address) (
|
2014-09-27 20:59:18 +02:00
|
|
|
*btcec.PrivateKey, bool, error) {
|
2014-04-18 00:13:53 +02:00
|
|
|
if len(keys) != 0 {
|
2014-05-22 00:50:47 +02:00
|
|
|
wif, ok := keys[addr.EncodeAddress()]
|
2014-04-18 00:13:53 +02:00
|
|
|
if !ok {
|
|
|
|
return nil, false,
|
|
|
|
errors.New("no key for address")
|
|
|
|
}
|
2014-09-27 20:59:18 +02:00
|
|
|
return wif.PrivKey, wif.CompressPubKey, nil
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
2014-10-29 07:43:29 +01:00
|
|
|
address, err := w.Manager.Address(addr)
|
2014-04-18 00:13:53 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, false, err
|
|
|
|
}
|
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
pka, ok := address.(waddrmgr.ManagedPubKeyAddress)
|
2014-04-18 00:13:53 +02:00
|
|
|
if !ok {
|
|
|
|
return nil, false, errors.New("address is not " +
|
|
|
|
"a pubkey address")
|
|
|
|
}
|
|
|
|
|
|
|
|
key, err := pka.PrivKey()
|
|
|
|
if err != nil {
|
|
|
|
return nil, false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return key, pka.Compressed(), nil
|
|
|
|
})
|
|
|
|
|
2015-01-30 19:31:29 +01:00
|
|
|
getScript := txscript.ScriptClosure(func(
|
2014-04-18 00:13:53 +02:00
|
|
|
addr btcutil.Address) ([]byte, error) {
|
|
|
|
// If keys were provided then we can only use the
|
|
|
|
// scripts provided with our inputs, too.
|
|
|
|
if len(keys) != 0 {
|
|
|
|
script, ok := scripts[addr.EncodeAddress()]
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.New("no script for " +
|
|
|
|
"address")
|
|
|
|
}
|
|
|
|
return script, nil
|
|
|
|
}
|
2014-10-29 07:43:29 +01:00
|
|
|
address, err := w.Manager.Address(addr)
|
2014-04-18 00:13:53 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2014-10-29 07:43:29 +01:00
|
|
|
sa, ok := address.(waddrmgr.ManagedScriptAddress)
|
2014-04-18 00:13:53 +02:00
|
|
|
if !ok {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, errors.New("address is not a script" +
|
2014-04-18 00:13:53 +02:00
|
|
|
" address")
|
|
|
|
}
|
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
return sa.Script()
|
2014-04-18 00:13:53 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
// SigHashSingle inputs can only be signed if there's a
|
|
|
|
// corresponding output. However this could be already signed,
|
|
|
|
// so we always verify the output.
|
2015-01-30 19:31:29 +01:00
|
|
|
if (hashType&txscript.SigHashSingle) !=
|
|
|
|
txscript.SigHashSingle || i < len(msgTx.TxOut) {
|
2014-04-18 00:13:53 +02:00
|
|
|
|
2015-01-30 19:31:29 +01:00
|
|
|
script, err := txscript.SignTxOutput(activeNet.Params,
|
2014-10-11 22:00:27 +02:00
|
|
|
msgTx, i, input, hashType, getKey,
|
2014-04-18 00:13:53 +02:00
|
|
|
getScript, txIn.SignatureScript)
|
|
|
|
// Failure to sign isn't an error, it just means that
|
|
|
|
// the tx isn't complete.
|
|
|
|
if err != nil {
|
2015-05-07 18:28:25 +02:00
|
|
|
signErrors = append(signErrors,
|
|
|
|
btcjson.SignRawTransactionError{
|
|
|
|
TxID: txIn.PreviousOutPoint.Hash.String(),
|
|
|
|
Vout: txIn.PreviousOutPoint.Index,
|
|
|
|
ScriptSig: hex.EncodeToString(txIn.SignatureScript),
|
|
|
|
Sequence: txIn.Sequence,
|
|
|
|
Error: err.Error(),
|
|
|
|
})
|
2014-04-18 00:13:53 +02:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
txIn.SignatureScript = script
|
|
|
|
}
|
|
|
|
|
|
|
|
// Either it was already signed or we just signed it.
|
|
|
|
// Find out if it is completely satisfied or still needs more.
|
2015-04-20 23:21:19 +02:00
|
|
|
vm, err := txscript.NewEngine(input, msgTx, i,
|
2015-04-20 22:52:26 +02:00
|
|
|
txscript.StandardVerifyFlags)
|
2015-05-07 18:28:25 +02:00
|
|
|
if err == nil {
|
|
|
|
err = vm.Execute()
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
signErrors = append(signErrors,
|
|
|
|
btcjson.SignRawTransactionError{
|
|
|
|
TxID: txIn.PreviousOutPoint.Hash.String(),
|
|
|
|
Vout: txIn.PreviousOutPoint.Index,
|
|
|
|
ScriptSig: hex.EncodeToString(txIn.SignatureScript),
|
|
|
|
Sequence: txIn.Sequence,
|
|
|
|
Error: err.Error(),
|
|
|
|
})
|
2014-04-18 00:13:53 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
var buf bytes.Buffer
|
2014-04-18 00:13:53 +02:00
|
|
|
buf.Grow(msgTx.SerializeSize())
|
|
|
|
|
2014-05-28 06:54:50 +02:00
|
|
|
// All returned errors (not OOM, which panics) encounted during
|
|
|
|
// bytes.Buffer writes are unexpected.
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
if err = msgTx.Serialize(&buf); err != nil {
|
2014-05-28 06:54:50 +02:00
|
|
|
panic(err)
|
|
|
|
}
|
2014-04-18 00:13:53 +02:00
|
|
|
|
|
|
|
return btcjson.SignRawTransactionResult{
|
|
|
|
Hex: hex.EncodeToString(buf.Bytes()),
|
2015-05-07 18:28:25 +02:00
|
|
|
Complete: len(signErrors) == 0,
|
|
|
|
Errors: signErrors,
|
2014-04-18 00:13:53 +02:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2014-02-14 00:16:21 +01:00
|
|
|
// ValidateAddress handles the validateaddress command.
|
2015-04-17 22:05:38 +02:00
|
|
|
func ValidateAddress(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.ValidateAddressCmd)
|
2014-02-14 00:16:21 +01:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
result := btcjson.ValidateAddressWalletResult{}
|
|
|
|
addr, err := decodeAddress(cmd.Address, activeNet.Params)
|
2014-02-14 00:16:21 +01:00
|
|
|
if err != nil {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
// Use result zero value (IsValid=false).
|
2014-04-07 20:21:20 +02:00
|
|
|
return result, nil
|
2014-02-14 00:16:21 +01:00
|
|
|
}
|
|
|
|
|
2014-04-07 20:21:20 +02:00
|
|
|
// We could put whether or not the address is a script here,
|
|
|
|
// by checking the type of "addr", however, the reference
|
|
|
|
// implementation only puts that information if the script is
|
|
|
|
// "ismine", and we follow that behaviour.
|
|
|
|
result.Address = addr.EncodeAddress()
|
|
|
|
result.IsValid = true
|
|
|
|
|
2014-10-29 07:43:29 +01:00
|
|
|
ainfo, err := w.Manager.Address(addr)
|
2014-12-12 09:54:26 +01:00
|
|
|
if err != nil {
|
|
|
|
if isManagerAddressNotFoundError(err) {
|
2014-10-29 07:43:29 +01:00
|
|
|
// No additional information available about the address.
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// The address lookup was successful which means there is further
|
|
|
|
// information about it available and it is "mine".
|
|
|
|
result.IsMine = true
|
2014-12-12 09:54:26 +01:00
|
|
|
acctName, err := w.Manager.AccountName(ainfo.Account())
|
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &ErrAccountNameNotFound
|
2014-12-12 09:54:26 +01:00
|
|
|
}
|
|
|
|
result.Account = acctName
|
2014-10-29 07:43:29 +01:00
|
|
|
|
|
|
|
switch ma := ainfo.(type) {
|
|
|
|
case waddrmgr.ManagedPubKeyAddress:
|
|
|
|
result.IsCompressed = ma.Compressed()
|
|
|
|
result.PubKey = ma.ExportPubKey()
|
|
|
|
|
|
|
|
case waddrmgr.ManagedScriptAddress:
|
|
|
|
result.IsScript = true
|
|
|
|
|
|
|
|
// The script is only available if the manager is unlocked, so
|
|
|
|
// just break out now if there is an error.
|
|
|
|
script, err := ma.Script()
|
|
|
|
if err != nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
result.Hex = hex.EncodeToString(script)
|
|
|
|
|
|
|
|
// This typically shouldn't fail unless an invalid script was
|
|
|
|
// imported. However, if it fails for any reason, there is no
|
|
|
|
// further information available, so just set the script type
|
|
|
|
// a non-standard and break out now.
|
|
|
|
class, addrs, reqSigs, err := txscript.ExtractPkScriptAddrs(
|
|
|
|
script, activeNet.Params)
|
|
|
|
if err != nil {
|
|
|
|
result.Script = txscript.NonStandardTy.String()
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
addrStrings := make([]string, len(addrs))
|
|
|
|
for i, a := range addrs {
|
|
|
|
addrStrings[i] = a.EncodeAddress()
|
|
|
|
}
|
|
|
|
result.Addresses = addrStrings
|
|
|
|
|
|
|
|
// Multi-signature scripts also provide the number of required
|
|
|
|
// signatures.
|
|
|
|
result.Script = class.String()
|
|
|
|
if class == txscript.MultiSigTy {
|
|
|
|
result.SigsRequired = int32(reqSigs)
|
2014-03-06 01:34:44 +01:00
|
|
|
}
|
2014-02-14 00:16:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
2014-02-12 03:14:07 +01:00
|
|
|
// VerifyMessage handles the verifymessage command by verifying the provided
|
|
|
|
// compact signature for the given address and message.
|
2015-04-17 22:05:38 +02:00
|
|
|
func VerifyMessage(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.VerifyMessageCmd)
|
2014-02-12 03:14:07 +01:00
|
|
|
|
2015-04-17 22:05:38 +02:00
|
|
|
addr, err := decodeAddress(cmd.Address, activeNet.Params)
|
2014-02-12 03:14:07 +01:00
|
|
|
if err != nil {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, err
|
2014-02-12 03:14:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// decode base64 signature
|
2014-02-13 19:42:22 +01:00
|
|
|
sig, err := base64.StdEncoding.DecodeString(cmd.Signature)
|
2014-02-12 03:14:07 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-02-12 03:14:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Validate the signature - this just shows that it was valid at all.
|
|
|
|
// we will compare it with the key next.
|
|
|
|
pk, wasCompressed, err := btcec.RecoverCompact(btcec.S256(), sig,
|
2015-02-05 22:41:38 +01:00
|
|
|
wire.DoubleSha256([]byte("Bitcoin Signed Message:\n"+
|
2014-02-13 19:42:22 +01:00
|
|
|
cmd.Message)))
|
2014-02-12 03:14:07 +01:00
|
|
|
if err != nil {
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-02-12 03:14:07 +01:00
|
|
|
}
|
|
|
|
|
2014-11-06 14:36:48 +01:00
|
|
|
var serializedPubKey []byte
|
|
|
|
if wasCompressed {
|
|
|
|
serializedPubKey = pk.SerializeCompressed()
|
|
|
|
} else {
|
|
|
|
serializedPubKey = pk.SerializeUncompressed()
|
|
|
|
}
|
|
|
|
// Verify that the signed-by address matches the given address
|
|
|
|
switch checkAddr := addr.(type) {
|
|
|
|
case *btcutil.AddressPubKeyHash: // ok
|
|
|
|
return bytes.Equal(btcutil.Hash160(serializedPubKey), checkAddr.Hash160()[:]), nil
|
|
|
|
case *btcutil.AddressPubKey: // ok
|
|
|
|
return string(serializedPubKey) == checkAddr.String(), nil
|
|
|
|
default:
|
|
|
|
return nil, errors.New("address type not supported")
|
|
|
|
}
|
2014-02-12 03:14:07 +01:00
|
|
|
}
|
|
|
|
|
2014-01-03 19:34:37 +01:00
|
|
|
// WalletIsLocked handles the walletislocked extension request by
|
|
|
|
// returning the current lock state (false for unlocked, true for locked)
|
2014-07-01 17:02:13 +02:00
|
|
|
// of an account.
|
2015-04-17 22:05:38 +02:00
|
|
|
func WalletIsLocked(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
return w.Locked(), nil
|
2013-08-21 20:46:20 +02:00
|
|
|
}
|
|
|
|
|
2014-01-27 21:48:12 +01:00
|
|
|
// WalletLock handles a walletlock request by locking the all account
|
|
|
|
// wallets, returning an error if any wallet is not encrypted (for example,
|
|
|
|
// a watching-only wallet).
|
2015-04-17 22:05:38 +02:00
|
|
|
func WalletLock(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
w.Lock()
|
2014-07-01 17:02:13 +02:00
|
|
|
return nil, nil
|
2013-08-21 16:37:30 +02:00
|
|
|
}
|
|
|
|
|
2013-11-12 18:01:32 +01:00
|
|
|
// WalletPassphrase responds to the walletpassphrase request by unlocking
|
|
|
|
// the wallet. The decryption key is saved in the wallet until timeout
|
|
|
|
// seconds expires, after which the wallet is locked.
|
2015-04-17 22:05:38 +02:00
|
|
|
func WalletPassphrase(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.WalletPassphraseCmd)
|
2013-08-21 16:37:30 +02:00
|
|
|
|
2014-07-01 17:02:13 +02:00
|
|
|
timeout := time.Second * time.Duration(cmd.Timeout)
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
err := w.Unlock([]byte(cmd.Passphrase), timeout)
|
2014-07-01 17:02:13 +02:00
|
|
|
return nil, err
|
2013-08-21 16:37:30 +02:00
|
|
|
}
|
2013-08-22 18:00:37 +02:00
|
|
|
|
2014-01-27 15:30:42 +01:00
|
|
|
// WalletPassphraseChange responds to the walletpassphrasechange request
|
|
|
|
// by unlocking all accounts with the provided old passphrase, and
|
|
|
|
// re-encrypting each private key with an AES key derived from the new
|
|
|
|
// passphrase.
|
|
|
|
//
|
|
|
|
// If the old passphrase is correct and the passphrase is changed, all
|
|
|
|
// wallets will be immediately locked.
|
2015-04-17 22:05:38 +02:00
|
|
|
func WalletPassphraseChange(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (interface{}, error) {
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
cmd := icmd.(*btcjson.WalletPassphraseChangeCmd)
|
2014-01-27 15:30:42 +01:00
|
|
|
|
Remove account support, fix races on btcd connect.
This commit is the result of several big changes being made to the
wallet. In particular, the "handshake" (initial sync to the chain
server) was quite racy and required proper synchronization. To make
fixing this race easier, several other changes were made to the
internal wallet data structures and much of the RPC server ended up
being rewritten.
First, all account support has been removed. The previous Account
struct has been replaced with a Wallet structure, which includes a
keystore for saving keys, and a txstore for storing relevant
transactions. This decision has been made since it is the opinion of
myself and other developers that bitcoind accounts are fundamentally
broken (as accounts implemented by bitcoind support both arbitrary
address groupings as well as moving balances between accounts -- these
are fundamentally incompatible features), and since a BIP0032 keystore
is soon planned to be implemented (at which point, "accounts" can
return as HD extended keys). With the keystore handling the grouping
of related keys, there is no reason have many different Account
structs, and the AccountManager has been removed as well. All RPC
handlers that take an account option will only work with "" (the
default account) or "*" if the RPC allows specifying all accounts.
Second, much of the RPC server has been cleaned up. The global
variables for the RPC server and chain server client have been moved
to part of the rpcServer struct, and the handlers for each RPC method
that are looked up change depending on which components have been set.
Passthrough requests are also no longer handled specially, but when
the chain server is set, a handler to perform the passthrough will be
returned if the method is not otherwise a wallet RPC. The
notification system for websocket clients has also been rewritten so
wallet components can send notifications through channels, rather than
requiring direct access to the RPC server itself, or worse still,
sending directly to a websocket client's send channel. In the future,
this will enable proper registration of notifications, rather than
unsolicited broadcasts to every connected websocket client (see
issue #84).
Finally, and the main reason why much of this cleanup was necessary,
the races during intial sync with the chain server have been fixed.
Previously, when the 'Handshake' was run, a rescan would occur which
would perform modifications to Account data structures as
notifications were received. Synchronization was provided with a
single binary semaphore which serialized all access to wallet and
account data. However, the Handshake itself was not able to run with
this lock (or else notifications would block), and many data races
would occur as both notifications were being handled. If GOMAXPROCS
was ever increased beyond 1, btcwallet would always immediately crash
due to invalid addresses caused by the data races on startup. To fix
this, the single lock for all wallet access has been replaced with
mutexes for both the keystore and txstore. Handling of btcd
notifications and client requests may now occur simultaneously.
GOMAXPROCS has also been set to the number of logical CPUs at the
beginning of main, since with the data races fixed, there's no reason
to prevent the extra parallelism gained by increasing it.
Closes #78.
Closes #101.
Closes #110.
2014-07-09 05:17:38 +02:00
|
|
|
err := w.ChangePassphrase([]byte(cmd.OldPassphrase),
|
2014-01-27 15:30:42 +01:00
|
|
|
[]byte(cmd.NewPassphrase))
|
2014-10-29 07:43:29 +01:00
|
|
|
if isManagerWrongPassphraseError(err) {
|
2015-04-17 22:05:38 +02:00
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCWalletPassphraseIncorrect,
|
|
|
|
Message: "Incorrect passphrase",
|
|
|
|
}
|
2014-01-27 15:30:42 +01:00
|
|
|
}
|
2014-06-04 02:52:04 +02:00
|
|
|
return nil, err
|
2014-01-27 15:30:42 +01:00
|
|
|
}
|
|
|
|
|
2014-07-02 03:50:23 +02:00
|
|
|
// decodeHexStr decodes the hex encoding of a string, possibly prepending a
|
|
|
|
// leading '0' character if there is an odd number of bytes in the hex string.
|
|
|
|
// This is to prevent an error for an invalid hex string when using an odd
|
|
|
|
// number of bytes when calling hex.Decode.
|
|
|
|
func decodeHexStr(hexStr string) ([]byte, error) {
|
|
|
|
if len(hexStr)%2 != 0 {
|
|
|
|
hexStr = "0" + hexStr
|
|
|
|
}
|
2015-04-17 22:05:38 +02:00
|
|
|
decoded, err := hex.DecodeString(hexStr)
|
|
|
|
if err != nil {
|
|
|
|
return nil, &btcjson.RPCError{
|
|
|
|
Code: btcjson.ErrRPCDecodeHexString,
|
|
|
|
Message: "Hex string decode failed: " + err.Error(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return decoded, nil
|
2014-07-02 03:50:23 +02:00
|
|
|
}
|