6a08c7de07
This change removes the three separate mutexes which used to lock an account's wallet, tx store, and utxo store. Accounts no longer contain any locking mechanism and rely on go's other synchronization constructs (goroutines and channels) for correct access. All accounts are now managed as a collection through the new AccountManager, rather than the old AccountStore. AccountManager runs as its own goroutine to provide access to accounts. RPC requests are now queued for handling, being denied if the queue buffer is exhausted. Notifications are also queued (instead of being sent from their own goroutine after being received, in which order is undefined), however, notifications are never dropped and will potentially grow a queue of infinite size if unhandled.
117 lines
3.8 KiB
Go
117 lines
3.8 KiB
Go
/*
|
|
* Copyright (c) 2013, 2014 Conformal Systems LLC <info@conformal.com>
|
|
*
|
|
* 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 (
|
|
"github.com/conformal/btcjson"
|
|
)
|
|
|
|
// RPCResponse is an interface type covering both server
|
|
// (frontend <-> btcwallet) and client (btcwallet <-> btcd) responses.
|
|
type RPCResponse interface {
|
|
Result() interface{}
|
|
Error() *btcjson.Error
|
|
}
|
|
|
|
// ClientRequest is a type holding a bitcoin client's request and
|
|
// a channel to send the response.
|
|
type ClientRequest struct {
|
|
ws bool
|
|
request btcjson.Cmd
|
|
response chan RPCResponse
|
|
}
|
|
|
|
// NewClientRequest creates a new ClientRequest from a btcjson.Cmd.
|
|
func NewClientRequest(request btcjson.Cmd, ws bool) *ClientRequest {
|
|
return &ClientRequest{
|
|
ws: ws,
|
|
request: request,
|
|
response: make(chan RPCResponse),
|
|
}
|
|
}
|
|
|
|
// Handle sends a client request to the RPC gateway for processing,
|
|
// and returns the result when handling is finished.
|
|
func (r *ClientRequest) Handle() (interface{}, *btcjson.Error) {
|
|
clientRequests <- r
|
|
resp := <-r.response
|
|
return resp.Result(), resp.Error()
|
|
}
|
|
|
|
// ClientResponse holds a result and error returned from handling a
|
|
// client's request.
|
|
type ClientResponse struct {
|
|
result interface{}
|
|
err *btcjson.Error
|
|
}
|
|
|
|
// Result returns the result of a response to a client.
|
|
func (r *ClientResponse) Result() interface{} {
|
|
return r.result
|
|
}
|
|
|
|
// Error returns the error of a response to a client, or nil if
|
|
// there is no error.
|
|
func (r *ClientResponse) Error() *btcjson.Error {
|
|
return r.err
|
|
}
|
|
|
|
// ServerRequest is a type responsible for handling requests to a bitcoin
|
|
// server and providing a method to access the response.
|
|
type ServerRequest struct {
|
|
request btcjson.Cmd
|
|
result interface{}
|
|
response chan RPCResponse
|
|
}
|
|
|
|
// NewServerRequest creates a new ServerRequest from a btcjson.Cmd. request
|
|
// may be nil to create a new var for the result (with types determined by
|
|
// the unmarshaling rules described in the json package), or set to a var
|
|
// with an expected type (i.e. *btcjson.BlockResult) to directly unmarshal
|
|
// the response's result into a convenient type.
|
|
func NewServerRequest(request btcjson.Cmd, result interface{}) *ServerRequest {
|
|
return &ServerRequest{
|
|
request: request,
|
|
result: result,
|
|
response: make(chan RPCResponse, 1),
|
|
}
|
|
}
|
|
|
|
// ServerResponse holds a response's result and error returned from sending a
|
|
// ServerRequest.
|
|
type ServerResponse struct {
|
|
// Result will be set to a concrete type (i.e. *btcjson.BlockResult)
|
|
// and may be type asserted to that type if a non-nil result was used
|
|
// to create the originating ServerRequest. Otherwise, Result will be
|
|
// set to new memory allocated by json.Unmarshal, and the type rules
|
|
// for unmarshaling described in the json package should be followed
|
|
// when type asserting Result.
|
|
result interface{}
|
|
|
|
// Err points to an unmarshaled error, or nil if result is valid.
|
|
err *btcjson.Error
|
|
}
|
|
|
|
// Result returns the result of a server's RPC response.
|
|
func (r *ServerResponse) Result() interface{} {
|
|
return r.result
|
|
}
|
|
|
|
// Result returns the error of a server's RPC response.
|
|
func (r *ServerResponse) Error() *btcjson.Error {
|
|
return r.err
|
|
}
|