2013-08-06 23:55:22 +02:00
|
|
|
// Copyright (c) 2013 Conformal Systems LLC.
|
|
|
|
// Use of this source code is governed by an ISC
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2013-08-14 22:55:31 +02:00
|
|
|
"bytes"
|
|
|
|
"code.google.com/p/go.crypto/ripemd160"
|
|
|
|
"code.google.com/p/go.net/websocket"
|
2013-10-01 22:43:45 +02:00
|
|
|
"encoding/base64"
|
2013-08-14 22:55:31 +02:00
|
|
|
"encoding/hex"
|
2013-08-06 23:55:22 +02:00
|
|
|
"encoding/json"
|
2013-08-14 22:55:31 +02:00
|
|
|
"errors"
|
2013-10-01 22:43:45 +02:00
|
|
|
"fmt"
|
2013-08-06 23:55:22 +02:00
|
|
|
"github.com/conformal/btcchain"
|
2013-08-14 22:55:31 +02:00
|
|
|
"github.com/conformal/btcdb"
|
2013-08-06 23:55:22 +02:00
|
|
|
"github.com/conformal/btcjson"
|
|
|
|
"github.com/conformal/btcscript"
|
2013-10-08 18:37:06 +02:00
|
|
|
"github.com/conformal/btcutil"
|
2013-08-06 23:55:22 +02:00
|
|
|
"github.com/conformal/btcwire"
|
|
|
|
"math/big"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
"sync"
|
2013-10-03 01:33:42 +02:00
|
|
|
"sync/atomic"
|
2013-08-06 23:55:22 +02:00
|
|
|
)
|
|
|
|
|
2013-08-14 22:55:31 +02:00
|
|
|
// Errors
|
|
|
|
var (
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// ErrBadParamsField describes an error where the parameters JSON
|
|
|
|
// field cannot be properly parsed.
|
2013-08-14 22:55:31 +02:00
|
|
|
ErrBadParamsField = errors.New("bad params field")
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
|
|
|
// ErrMethodNotImplemented describes an error where the RPC or
|
|
|
|
// websocket JSON method is not implemented.
|
|
|
|
ErrMethodNotImplemented = errors.New("method not implemented")
|
2013-08-14 22:55:31 +02:00
|
|
|
)
|
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
// rpcServer holds the items the rpc server may need to access (config,
|
|
|
|
// shutdown, main server, etc.)
|
|
|
|
type rpcServer struct {
|
2013-10-03 01:33:42 +02:00
|
|
|
started int32
|
|
|
|
shutdown int32
|
2013-08-07 17:38:39 +02:00
|
|
|
server *server
|
2013-08-14 22:55:31 +02:00
|
|
|
ws wsContext
|
2013-08-07 17:38:39 +02:00
|
|
|
wg sync.WaitGroup
|
|
|
|
rpcport string
|
|
|
|
username string
|
|
|
|
password string
|
|
|
|
listeners []net.Listener
|
2013-08-14 22:55:31 +02:00
|
|
|
quit chan int
|
|
|
|
}
|
|
|
|
|
|
|
|
// wsContext holds the items the RPC server needs to handle websocket
|
|
|
|
// connections for wallets.
|
|
|
|
type wsContext struct {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// requests holds all wallet notification requests.
|
|
|
|
requests wsRequests
|
2013-08-14 22:55:31 +02:00
|
|
|
|
|
|
|
// Channel to add a wallet listener.
|
|
|
|
addWalletListener chan (chan []byte)
|
|
|
|
|
|
|
|
// Channel to removes a wallet listener.
|
|
|
|
removeWalletListener chan (chan []byte)
|
|
|
|
|
|
|
|
// Any chain notifications meant to be received by every connected
|
|
|
|
// wallet are sent across this channel.
|
|
|
|
walletNotificationMaster chan []byte
|
|
|
|
}
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// wsRequests maps request contexts for wallet notifications to a
|
|
|
|
// wallet notification channel. A Mutex is used to protect incorrect
|
|
|
|
// concurrent access to the map.
|
|
|
|
type wsRequests struct {
|
|
|
|
sync.Mutex
|
|
|
|
m map[chan []byte]*requestContexts
|
|
|
|
}
|
|
|
|
|
|
|
|
// getOrCreateContexts gets the request contexts, or creates and adds a
|
|
|
|
// new context if one for this wallet is not already present.
|
|
|
|
func (r *wsRequests) getOrCreateContexts(walletNotification chan []byte) *requestContexts {
|
|
|
|
rc, ok := r.m[walletNotification]
|
|
|
|
if !ok {
|
|
|
|
rc = &requestContexts{
|
|
|
|
txRequests: make(map[addressHash]interface{}),
|
|
|
|
spentRequests: make(map[btcwire.OutPoint]interface{}),
|
|
|
|
}
|
|
|
|
r.m[walletNotification] = rc
|
|
|
|
}
|
|
|
|
return rc
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddTxRequest adds the request context for new transaction notifications.
|
|
|
|
func (r *wsRequests) AddTxRequest(walletNotification chan []byte, addr addressHash, id interface{}) {
|
|
|
|
r.Lock()
|
|
|
|
defer r.Unlock()
|
|
|
|
|
|
|
|
rc := r.getOrCreateContexts(walletNotification)
|
|
|
|
rc.txRequests[addr] = id
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddSpentRequest adds a request context for notifications of a spent
|
|
|
|
// Outpoint.
|
|
|
|
func (r *wsRequests) AddSpentRequest(walletNotification chan []byte, op *btcwire.OutPoint, id interface{}) {
|
|
|
|
r.Lock()
|
|
|
|
defer r.Unlock()
|
|
|
|
|
|
|
|
rc := r.getOrCreateContexts(walletNotification)
|
|
|
|
rc.spentRequests[*op] = id
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveSpentRequest removes a request context for notifications of a
|
|
|
|
// spent Outpoint.
|
|
|
|
func (r *wsRequests) RemoveSpentRequest(walletNotification chan []byte, op *btcwire.OutPoint) {
|
|
|
|
r.Lock()
|
|
|
|
defer r.Unlock()
|
|
|
|
|
|
|
|
rc := r.getOrCreateContexts(walletNotification)
|
|
|
|
delete(rc.spentRequests, *op)
|
|
|
|
}
|
|
|
|
|
|
|
|
// CloseListeners removes all request contexts for notifications sent
|
|
|
|
// to a wallet notification channel and closes the channel to stop all
|
|
|
|
// goroutines currently serving that wallet.
|
|
|
|
func (r *wsRequests) CloseListeners(walletNotification chan []byte) {
|
|
|
|
r.Lock()
|
|
|
|
defer r.Unlock()
|
|
|
|
|
|
|
|
delete(r.m, walletNotification)
|
|
|
|
close(walletNotification)
|
|
|
|
}
|
|
|
|
|
2013-08-14 22:55:31 +02:00
|
|
|
type addressHash [ripemd160.Size]byte
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// requestContexts holds all requests for a single wallet connection.
|
|
|
|
type requestContexts struct {
|
|
|
|
// txRequests maps between a 160-byte pubkey hash and the JSON
|
|
|
|
// id of the requester so replies can be correctly routed back
|
|
|
|
// to the correct btcwallet callback.
|
|
|
|
txRequests map[addressHash]interface{}
|
|
|
|
|
|
|
|
// spentRequests maps between an Outpoint of an unspent
|
|
|
|
// transaction output and the JSON id of the requester so
|
|
|
|
// replies can be correctly routed back to the correct
|
|
|
|
// btcwallet callback.
|
|
|
|
spentRequests map[btcwire.OutPoint]interface{}
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Start is used by server.go to start the rpc listener.
|
|
|
|
func (s *rpcServer) Start() {
|
2013-10-03 01:33:42 +02:00
|
|
|
if atomic.AddInt32(&s.started, 1) != 1 {
|
2013-08-06 23:55:22 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Trace("RPCS: Starting RPC server")
|
2013-08-06 23:55:22 +02:00
|
|
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
2013-10-01 22:43:45 +02:00
|
|
|
login := s.username + ":" + s.password
|
|
|
|
auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login))
|
2013-10-03 14:12:18 +02:00
|
|
|
authhdr := r.Header["Authorization"]
|
|
|
|
if len(authhdr) > 0 && authhdr[0] == auth {
|
2013-10-01 22:43:45 +02:00
|
|
|
jsonRPCRead(w, r, s)
|
|
|
|
} else {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Warnf("RPCS: Auth failure.")
|
2013-10-01 22:43:45 +02:00
|
|
|
jsonAuthFail(w, r, s)
|
|
|
|
}
|
2013-08-06 23:55:22 +02:00
|
|
|
})
|
2013-08-14 22:55:31 +02:00
|
|
|
go s.walletListenerDuplicator()
|
|
|
|
http.Handle("/wallet", websocket.Handler(func(ws *websocket.Conn) {
|
|
|
|
s.walletReqsNotifications(ws)
|
|
|
|
}))
|
2013-08-07 17:38:39 +02:00
|
|
|
httpServer := &http.Server{}
|
|
|
|
for _, listener := range s.listeners {
|
2013-09-13 00:24:37 +02:00
|
|
|
s.wg.Add(1)
|
2013-08-07 17:38:39 +02:00
|
|
|
go func(listener net.Listener) {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Infof("RPCS: RPC server listening on %s", listener.Addr())
|
2013-08-07 17:38:39 +02:00
|
|
|
httpServer.Serve(listener)
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Tracef("RPCS: RPC listener done for %s", listener.Addr())
|
2013-08-07 17:38:39 +02:00
|
|
|
s.wg.Done()
|
|
|
|
}(listener)
|
|
|
|
}
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Stop is used by server.go to stop the rpc listener.
|
|
|
|
func (s *rpcServer) Stop() error {
|
2013-10-03 01:33:42 +02:00
|
|
|
if atomic.AddInt32(&s.shutdown, 1) != 1 {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Infof("RPCS: RPC server is already in the process of shutting down")
|
2013-08-06 23:55:22 +02:00
|
|
|
return nil
|
|
|
|
}
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Warnf("RPCS: RPC server shutting down")
|
2013-08-07 17:38:39 +02:00
|
|
|
for _, listener := range s.listeners {
|
|
|
|
err := listener.Close()
|
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Problem shutting down rpc: %v", err)
|
2013-08-07 17:38:39 +02:00
|
|
|
return err
|
|
|
|
}
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Infof("RPCS: RPC server shutdown complete")
|
2013-08-06 23:55:22 +02:00
|
|
|
s.wg.Wait()
|
2013-08-14 22:55:31 +02:00
|
|
|
close(s.quit)
|
2013-08-06 23:55:22 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2013-09-18 07:36:40 +02:00
|
|
|
// newRPCServer returns a new instance of the rpcServer struct.
|
|
|
|
func newRPCServer(s *server) (*rpcServer, error) {
|
2013-08-06 23:55:22 +02:00
|
|
|
rpc := rpcServer{
|
|
|
|
server: s,
|
2013-10-20 18:05:35 +02:00
|
|
|
quit: make(chan int),
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
// Get values from config
|
2013-09-18 07:36:40 +02:00
|
|
|
rpc.rpcport = cfg.RPCPort
|
|
|
|
rpc.username = cfg.RPCUser
|
|
|
|
rpc.password = cfg.RPCPass
|
2013-08-06 23:55:22 +02:00
|
|
|
|
2013-08-14 22:55:31 +02:00
|
|
|
// initialize memory for websocket connections
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
rpc.ws.requests.m = make(map[chan []byte]*requestContexts)
|
2013-08-14 22:55:31 +02:00
|
|
|
rpc.ws.addWalletListener = make(chan (chan []byte))
|
|
|
|
rpc.ws.removeWalletListener = make(chan (chan []byte))
|
|
|
|
rpc.ws.walletNotificationMaster = make(chan []byte)
|
|
|
|
|
2013-08-07 17:38:39 +02:00
|
|
|
// IPv4 listener.
|
|
|
|
var listeners []net.Listener
|
|
|
|
listenAddr4 := net.JoinHostPort("127.0.0.1", rpc.rpcport)
|
|
|
|
listener4, err := net.Listen("tcp4", listenAddr4)
|
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Couldn't create listener: %v", err)
|
2013-08-07 17:38:39 +02:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
listeners = append(listeners, listener4)
|
|
|
|
|
|
|
|
// IPv6 listener.
|
|
|
|
listenAddr6 := net.JoinHostPort("::1", rpc.rpcport)
|
|
|
|
listener6, err := net.Listen("tcp6", listenAddr6)
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Couldn't create listener: %v", err)
|
2013-08-06 23:55:22 +02:00
|
|
|
return nil, err
|
|
|
|
}
|
2013-08-07 17:38:39 +02:00
|
|
|
listeners = append(listeners, listener6)
|
|
|
|
|
|
|
|
rpc.listeners = listeners
|
2013-08-14 22:55:31 +02:00
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
return &rpc, err
|
|
|
|
}
|
|
|
|
|
2013-10-01 22:43:45 +02:00
|
|
|
// jsonAuthFail sends a message back to the client if the http auth is rejected.
|
|
|
|
func jsonAuthFail(w http.ResponseWriter, r *http.Request, s *rpcServer) {
|
|
|
|
fmt.Fprint(w, "401 Unauthorized.\n")
|
|
|
|
}
|
|
|
|
|
2013-08-14 22:55:31 +02:00
|
|
|
// jsonRPCRead is the RPC wrapper around the jsonRead function to handles
|
|
|
|
// reading and responding to RPC messages.
|
2013-09-18 07:36:40 +02:00
|
|
|
func jsonRPCRead(w http.ResponseWriter, r *http.Request, s *rpcServer) {
|
2013-08-06 23:55:22 +02:00
|
|
|
r.Close = true
|
2013-10-03 01:33:42 +02:00
|
|
|
if atomic.LoadInt32(&s.shutdown) != 0 {
|
2013-08-06 23:55:22 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
body, err := btcjson.GetRaw(r.Body)
|
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Error getting json message: %v", err)
|
2013-08-06 23:55:22 +02:00
|
|
|
return
|
|
|
|
}
|
2013-08-14 22:55:31 +02:00
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// Error is intentionally ignored here. It's used in in the
|
|
|
|
// websocket handler to tell when a method is not supported by
|
|
|
|
// the standard RPC API, and is not needed here. Error logging
|
|
|
|
// is done inside jsonRead, so no need to log the error here.
|
|
|
|
reply, _ := jsonRead(body, s)
|
|
|
|
log.Tracef("[RPCS] reply: %v", reply)
|
2013-08-14 22:55:31 +02:00
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
msg, err := btcjson.MarshallAndSend(reply, w)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf(msg)
|
|
|
|
return
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
log.Debugf(msg)
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// jsonRead abstracts the JSON unmarshalling and reply handling used
|
|
|
|
// by both RPC and websockets.
|
|
|
|
func jsonRead(body []byte, s *rpcServer) (reply btcjson.Reply, err error) {
|
2013-08-06 23:55:22 +02:00
|
|
|
var message btcjson.Message
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
if err := json.Unmarshal(body, &message); err != nil {
|
2013-08-06 23:55:22 +02:00
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32700,
|
|
|
|
Message: "Parse error",
|
|
|
|
}
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-06 23:55:22 +02:00
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: nil,
|
|
|
|
}
|
|
|
|
|
2013-08-14 22:55:31 +02:00
|
|
|
log.Tracef("RPCS: reply: %v", reply)
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return reply, jsonError
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Tracef("RPCS: received: %v", message)
|
2013-08-06 23:55:22 +02:00
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// Set final reply based on error if non-nil.
|
2013-08-14 22:55:31 +02:00
|
|
|
defer func() {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
if err != nil {
|
|
|
|
if jsonErr, ok := err.(btcjson.Error); ok {
|
|
|
|
reply = btcjson.Reply{
|
|
|
|
Error: &jsonErr,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
err = errors.New(jsonErr.Message)
|
|
|
|
} else {
|
|
|
|
rawJSONError := btcjson.Error{
|
|
|
|
Code: -32603,
|
|
|
|
Message: err.Error(),
|
|
|
|
}
|
|
|
|
reply = btcjson.Reply{
|
|
|
|
Error: &rawJSONError,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
}
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
// Deal with commands
|
|
|
|
switch message.Method {
|
2013-08-09 22:20:06 +02:00
|
|
|
case "stop":
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-09 22:20:06 +02:00
|
|
|
Result: "btcd stopping.",
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
s.server.Stop()
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
case "getblockcount":
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var maxidx int64
|
|
|
|
_, maxidx, err = s.server.db.NewestSha()
|
2013-10-11 22:31:19 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("RPCS: Error getting newest sha: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-10-11 22:31:19 +02:00
|
|
|
Code: -5,
|
|
|
|
Message: "Error getting block count",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-10-11 22:31:19 +02:00
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-06 23:55:22 +02:00
|
|
|
Result: maxidx,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-10-11 22:31:19 +02:00
|
|
|
case "getbestblockhash":
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var sha *btcwire.ShaHash
|
|
|
|
sha, _, err = s.server.db.NewestSha()
|
2013-10-11 22:31:19 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("RPCS: Error getting newest sha: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-10-11 22:31:19 +02:00
|
|
|
Code: -5,
|
|
|
|
Message: "Error getting best block hash",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-10-11 22:31:19 +02:00
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-10-17 18:33:46 +02:00
|
|
|
Result: sha.String(),
|
2013-10-11 22:31:19 +02:00
|
|
|
Id: &message.Id,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-10-21 19:00:13 +02:00
|
|
|
case "getconnectioncount":
|
|
|
|
var count int
|
|
|
|
|
|
|
|
reply = btcjson.Reply{
|
|
|
|
Result: count,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
|
2013-10-11 22:31:19 +02:00
|
|
|
case "getdifficulty":
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var sha *btcwire.ShaHash
|
|
|
|
sha, _, err = s.server.db.NewestSha()
|
2013-10-11 22:31:19 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("RPCS: Error getting sha: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-10-11 22:31:19 +02:00
|
|
|
Code: -5,
|
|
|
|
Message: "Error Getting difficulty",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-10-11 22:31:19 +02:00
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var blk *btcutil.Block
|
|
|
|
blk, err = s.server.db.FetchBlockBySha(sha)
|
2013-10-11 22:31:19 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("RPCS: Error getting block: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-10-11 22:31:19 +02:00
|
|
|
Code: -5,
|
|
|
|
Message: "Error Getting difficulty",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-10-11 22:31:19 +02:00
|
|
|
}
|
|
|
|
blockHeader := &blk.MsgBlock().Header
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-10-11 22:31:19 +02:00
|
|
|
Result: getDifficultyRatio(blockHeader.Bits),
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
// btcd does not do mining so we can hardcode replies here.
|
|
|
|
case "getgenerate":
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-06 23:55:22 +02:00
|
|
|
Result: false,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
case "setgenerate":
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-06 23:55:22 +02:00
|
|
|
Result: nil,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
case "gethashespersec":
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-06 23:55:22 +02:00
|
|
|
Result: 0,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
case "getblockhash":
|
|
|
|
var f interface{}
|
|
|
|
err = json.Unmarshal(body, &f)
|
|
|
|
m := f.(map[string]interface{})
|
|
|
|
var idx float64
|
|
|
|
for _, v := range m {
|
|
|
|
switch vv := v.(type) {
|
|
|
|
case []interface{}:
|
|
|
|
for _, u := range vv {
|
|
|
|
idx, _ = u.(float64)
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var sha *btcwire.ShaHash
|
|
|
|
sha, err = s.server.db.FetchBlockShaByHeight(int64(idx))
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("[RCPS] Error getting block: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-06 23:55:22 +02:00
|
|
|
Code: -1,
|
|
|
|
Message: "Block number out of range.",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-06 23:55:22 +02:00
|
|
|
Result: sha.String(),
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
case "getblock":
|
|
|
|
var f interface{}
|
|
|
|
err = json.Unmarshal(body, &f)
|
|
|
|
m := f.(map[string]interface{})
|
|
|
|
var hash string
|
|
|
|
for _, v := range m {
|
|
|
|
switch vv := v.(type) {
|
|
|
|
case []interface{}:
|
|
|
|
for _, u := range vv {
|
|
|
|
hash, _ = u.(string)
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var sha *btcwire.ShaHash
|
|
|
|
sha, err = btcwire.NewShaHashFromStr(hash)
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Error generating sha: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-06 23:55:22 +02:00
|
|
|
Code: -5,
|
|
|
|
Message: "Block not found",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var blk *btcutil.Block
|
|
|
|
blk, err = s.server.db.FetchBlockBySha(sha)
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Error fetching sha: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-06 23:55:22 +02:00
|
|
|
Code: -5,
|
|
|
|
Message: "Block not found",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
idx := blk.Height()
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var buf []byte
|
|
|
|
buf, err = blk.Bytes()
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Error fetching block: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-06 23:55:22 +02:00
|
|
|
Code: -5,
|
|
|
|
Message: "Block not found",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
txList, _ := blk.TxShas()
|
|
|
|
|
|
|
|
txNames := make([]string, len(txList))
|
|
|
|
for i, v := range txList {
|
|
|
|
txNames[i] = v.String()
|
|
|
|
}
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var maxidx int64
|
|
|
|
_, maxidx, err = s.server.db.NewestSha()
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
log.Errorf("RPCS: Cannot get newest sha: %v", err)
|
|
|
|
err = btcjson.Error{
|
|
|
|
Code: -5,
|
|
|
|
Message: "Block not found",
|
|
|
|
}
|
|
|
|
return
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
blockHeader := &blk.MsgBlock().Header
|
|
|
|
blockReply := btcjson.BlockResult{
|
|
|
|
Hash: hash,
|
|
|
|
Version: blockHeader.Version,
|
|
|
|
MerkleRoot: blockHeader.MerkleRoot.String(),
|
|
|
|
PreviousHash: blockHeader.PrevBlock.String(),
|
|
|
|
Nonce: blockHeader.Nonce,
|
|
|
|
Time: blockHeader.Timestamp.Unix(),
|
|
|
|
Confirmations: uint64(1 + maxidx - idx),
|
|
|
|
Height: idx,
|
|
|
|
Tx: txNames,
|
|
|
|
Size: len(buf),
|
|
|
|
Bits: strconv.FormatInt(int64(blockHeader.Bits), 16),
|
|
|
|
Difficulty: getDifficultyRatio(blockHeader.Bits),
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get next block unless we are already at the top.
|
|
|
|
if idx < maxidx {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var shaNext *btcwire.ShaHash
|
|
|
|
shaNext, err = s.server.db.FetchBlockShaByHeight(int64(idx + 1))
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: No next block: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
|
|
|
Code: -5,
|
|
|
|
Message: "Block not found",
|
|
|
|
}
|
|
|
|
return
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
blockReply.NextHash = shaNext.String()
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-06 23:55:22 +02:00
|
|
|
Result: blockReply,
|
|
|
|
Error: nil,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-10-17 18:23:53 +02:00
|
|
|
case "getrawmempool":
|
|
|
|
hashes := s.server.txMemPool.TxShas()
|
2013-10-17 19:11:04 +02:00
|
|
|
hashStrings := make([]string, len(hashes))
|
|
|
|
for i := 0; i < len(hashes); i++ {
|
|
|
|
hashStrings[i] = hashes[i].String()
|
|
|
|
}
|
2013-10-17 18:23:53 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-10-17 19:11:04 +02:00
|
|
|
Result: hashStrings,
|
2013-10-17 18:23:53 +02:00
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
case "getrawtransaction":
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// TODO: Perform smarter paramter parsing.
|
2013-08-06 23:55:22 +02:00
|
|
|
var f interface{}
|
|
|
|
err = json.Unmarshal(body, &f)
|
|
|
|
m := f.(map[string]interface{})
|
|
|
|
var tx string
|
|
|
|
var verbose float64
|
|
|
|
for _, v := range m {
|
|
|
|
switch vv := v.(type) {
|
|
|
|
case []interface{}:
|
|
|
|
for _, u := range vv {
|
|
|
|
switch uu := u.(type) {
|
|
|
|
case string:
|
|
|
|
tx = uu
|
|
|
|
case float64:
|
|
|
|
verbose = uu
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-14 22:55:31 +02:00
|
|
|
if int(verbose) != 0 {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// TODO: check error code. tx is not checked before
|
|
|
|
// this point.
|
2013-08-06 23:55:22 +02:00
|
|
|
txSha, _ := btcwire.NewShaHashFromStr(tx)
|
|
|
|
var txS *btcwire.MsgTx
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var txList []*btcdb.TxListReply
|
|
|
|
txList, err = s.server.db.FetchTxBySha(txSha)
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Error fetching tx: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-06 23:55:22 +02:00
|
|
|
Code: -5,
|
|
|
|
Message: "No information available about transaction",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
2013-10-03 22:42:38 +02:00
|
|
|
|
|
|
|
lastTx := len(txList) - 1
|
|
|
|
txS = txList[lastTx].Tx
|
|
|
|
blksha := txList[lastTx].BlkSha
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var blk *btcutil.Block
|
|
|
|
blk, err = s.server.db.FetchBlockBySha(blksha)
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Error fetching sha: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-06 23:55:22 +02:00
|
|
|
Code: -5,
|
|
|
|
Message: "Block not found",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
idx := blk.Height()
|
|
|
|
|
|
|
|
txOutList := txS.TxOut
|
|
|
|
voutList := make([]btcjson.Vout, len(txOutList))
|
|
|
|
|
|
|
|
txInList := txS.TxIn
|
|
|
|
vinList := make([]btcjson.Vin, len(txInList))
|
|
|
|
|
|
|
|
for i, v := range txInList {
|
|
|
|
vinList[i].Sequence = float64(v.Sequence)
|
|
|
|
disbuf, _ := btcscript.DisasmString(v.SignatureScript)
|
|
|
|
vinList[i].ScriptSig.Asm = strings.Replace(disbuf, " ", "", -1)
|
|
|
|
vinList[i].Vout = i + 1
|
|
|
|
log.Debugf(disbuf)
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, v := range txOutList {
|
|
|
|
voutList[i].N = i
|
|
|
|
voutList[i].Value = float64(v.Value) / 100000000
|
|
|
|
isbuf, _ := btcscript.DisasmString(v.PkScript)
|
|
|
|
voutList[i].ScriptPubKey.Asm = isbuf
|
|
|
|
voutList[i].ScriptPubKey.ReqSig = strings.Count(isbuf, "OP_CHECKSIG")
|
2013-10-08 18:37:06 +02:00
|
|
|
_, addrhash, err := btcscript.ScriptToAddrHash(v.PkScript)
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// TODO: set and return error?
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Error getting address hash for %v: %v", txSha, err)
|
2013-10-08 18:37:06 +02:00
|
|
|
}
|
|
|
|
if addr, err := btcutil.EncodeAddress(addrhash, s.server.btcnet); err != nil {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// TODO: set and return error?
|
2013-08-06 23:55:22 +02:00
|
|
|
addrList := make([]string, 1)
|
|
|
|
addrList[0] = addr
|
|
|
|
voutList[i].ScriptPubKey.Addresses = addrList
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var maxidx int64
|
|
|
|
_, maxidx, err = s.server.db.NewestSha()
|
2013-08-06 23:55:22 +02:00
|
|
|
if err != nil {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
log.Errorf("RPCS: Cannot get newest sha: %v", err)
|
|
|
|
err = btcjson.Error{
|
|
|
|
Code: -5,
|
|
|
|
Message: "No information about newest block",
|
|
|
|
}
|
|
|
|
return
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
confirmations := uint64(1 + maxidx - idx)
|
|
|
|
|
|
|
|
blockHeader := &blk.MsgBlock().Header
|
|
|
|
txReply := btcjson.TxRawResult{
|
|
|
|
Txid: tx,
|
|
|
|
Vout: voutList,
|
|
|
|
Vin: vinList,
|
|
|
|
Version: txS.Version,
|
|
|
|
LockTime: txS.LockTime,
|
|
|
|
// This is not a typo, they are identical in
|
|
|
|
// bitcoind as well.
|
|
|
|
Time: blockHeader.Timestamp.Unix(),
|
|
|
|
Blocktime: blockHeader.Timestamp.Unix(),
|
|
|
|
BlockHash: blksha.String(),
|
|
|
|
Confirmations: confirmations,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-06 23:55:22 +02:00
|
|
|
Result: txReply,
|
|
|
|
Error: nil,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
2013-08-14 22:55:31 +02:00
|
|
|
} else {
|
|
|
|
// Don't return details
|
|
|
|
// not used yet
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
case "decoderawtransaction":
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// TODO: Perform smarter paramter parsing.
|
2013-08-06 23:55:22 +02:00
|
|
|
var f interface{}
|
|
|
|
err = json.Unmarshal(body, &f)
|
|
|
|
m := f.(map[string]interface{})
|
|
|
|
var hash string
|
|
|
|
for _, v := range m {
|
|
|
|
switch vv := v.(type) {
|
|
|
|
case []interface{}:
|
|
|
|
for _, u := range vv {
|
|
|
|
hash, _ = u.(string)
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// TODO: use hash and fill result with info.
|
|
|
|
_ = hash
|
2013-08-06 23:55:22 +02:00
|
|
|
txReply := btcjson.TxRawDecodeResult{}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-06 23:55:22 +02:00
|
|
|
Result: txReply,
|
|
|
|
Error: nil,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
|
2013-08-14 22:55:31 +02:00
|
|
|
case "sendrawtransaction":
|
|
|
|
params, ok := message.Params.([]interface{})
|
|
|
|
if !ok || len(params) != 1 {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-14 22:55:31 +02:00
|
|
|
Code: -32602,
|
|
|
|
Message: "Invalid parameters",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
serializedtxhex, ok := params[0].(string)
|
|
|
|
if !ok {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-14 22:55:31 +02:00
|
|
|
Code: -32602,
|
|
|
|
Message: "Raw tx is not a string",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Deserialize and send off to tx relay
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
var serializedTx []byte
|
|
|
|
serializedTx, err = hex.DecodeString(serializedtxhex)
|
2013-08-14 22:55:31 +02:00
|
|
|
if err != nil {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-14 22:55:31 +02:00
|
|
|
Code: -22,
|
|
|
|
Message: "Unable to decode hex string",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
msgtx := btcwire.NewMsgTx()
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = msgtx.Deserialize(bytes.NewBuffer(serializedTx))
|
2013-08-14 22:55:31 +02:00
|
|
|
if err != nil {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-14 22:55:31 +02:00
|
|
|
Code: -22,
|
|
|
|
Message: "Unable to deserialize raw tx",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
err = s.server.txMemPool.ProcessTransaction(msgtx)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("RPCS: Failed to process transaction: %v", err)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
err = btcjson.Error{
|
2013-08-14 22:55:31 +02:00
|
|
|
Code: -22,
|
|
|
|
Message: "Failed to process transaction",
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
var result interface{}
|
|
|
|
txsha, err := msgtx.TxSha()
|
|
|
|
if err == nil {
|
|
|
|
result = txsha.String()
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply = btcjson.Reply{
|
2013-08-14 22:55:31 +02:00
|
|
|
Result: result,
|
|
|
|
Error: nil,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
default:
|
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32601,
|
|
|
|
Message: "Method not found",
|
|
|
|
}
|
|
|
|
reply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
err = ErrMethodNotImplemented
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func jsonWSRead(walletNotification chan []byte, replychan chan *btcjson.Reply, body []byte, s *rpcServer) error {
|
|
|
|
var message btcjson.Message
|
|
|
|
err := json.Unmarshal(body, &message)
|
|
|
|
if err != nil {
|
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32700,
|
|
|
|
Message: "Parse error",
|
|
|
|
}
|
|
|
|
|
|
|
|
reply := btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: nil,
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Tracef("RPCS: reply: %v", reply)
|
|
|
|
|
|
|
|
replychan <- &reply
|
|
|
|
return fmt.Errorf("RPCS: Error unmarshalling json message: %v", err)
|
|
|
|
}
|
|
|
|
log.Tracef("RPCS: received: %v", message)
|
|
|
|
|
|
|
|
var rawReply btcjson.Reply
|
|
|
|
defer func() {
|
|
|
|
replychan <- &rawReply
|
|
|
|
close(replychan)
|
|
|
|
}()
|
|
|
|
|
|
|
|
// Deal with commands
|
|
|
|
switch message.Method {
|
2013-08-14 22:55:31 +02:00
|
|
|
case "getcurrentnet":
|
|
|
|
var net btcwire.BitcoinNet
|
|
|
|
if cfg.TestNet3 {
|
|
|
|
net = btcwire.TestNet3
|
|
|
|
} else {
|
|
|
|
net = btcwire.MainNet
|
|
|
|
}
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: float64(net),
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
|
|
|
|
case "rescan":
|
|
|
|
var addr string
|
|
|
|
minblock, maxblock := int64(0), btcdb.AllShas
|
|
|
|
params, ok := message.Params.([]interface{})
|
|
|
|
if !ok {
|
|
|
|
return ErrBadParamsField
|
|
|
|
}
|
|
|
|
for i, v := range params {
|
|
|
|
switch v.(type) {
|
|
|
|
case string:
|
|
|
|
if i == 0 {
|
|
|
|
addr = v.(string)
|
|
|
|
}
|
|
|
|
case float64:
|
|
|
|
if i == 1 {
|
|
|
|
minblock = int64(v.(float64))
|
|
|
|
} else if i == 2 {
|
|
|
|
maxblock = int64(v.(float64))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
addrhash, _, err := btcutil.DecodeAddress(addr)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// FetchHeightRange may not return a complete list of block shas for
|
|
|
|
// the given range, so fetch range as many times as necessary.
|
|
|
|
for {
|
|
|
|
blkshalist, err := s.server.db.FetchHeightRange(minblock, maxblock)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if len(blkshalist) == 0 {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range blkshalist {
|
|
|
|
blk, err := s.server.db.FetchBlockBySha(&blkshalist[i])
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
txShaList, err := blk.TxShas()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
txList := s.server.db.FetchTxByShaList(txShaList)
|
2013-10-20 18:50:31 +02:00
|
|
|
for _, txReply := range txList {
|
|
|
|
if txReply.Err != nil || txReply.Tx == nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
for _, txout := range txReply.Tx.TxOut {
|
2013-08-14 22:55:31 +02:00
|
|
|
_, txaddrhash, err := btcscript.ScriptToAddrHash(txout.PkScript)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !bytes.Equal(addrhash, txaddrhash) {
|
|
|
|
reply := btcjson.Reply{
|
2013-10-20 18:50:31 +02:00
|
|
|
Result: txReply.Sha,
|
2013-08-14 22:55:31 +02:00
|
|
|
Error: nil,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
replychan <- &reply
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if maxblock-minblock > int64(len(blkshalist)) {
|
|
|
|
minblock += int64(len(blkshalist))
|
|
|
|
} else {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: nil,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
|
|
|
|
case "notifynewtxs":
|
|
|
|
params, ok := message.Params.([]interface{})
|
|
|
|
if !ok || len(params) != 1 {
|
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32602,
|
|
|
|
Message: "Invalid parameters",
|
|
|
|
}
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
return ErrBadParamsField
|
|
|
|
}
|
|
|
|
addr, ok := params[0].(string)
|
|
|
|
if !ok {
|
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32602,
|
|
|
|
Message: "Invalid parameters",
|
|
|
|
}
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
return ErrBadParamsField
|
|
|
|
}
|
|
|
|
addrhash, _, err := btcutil.DecodeAddress(addr)
|
|
|
|
if err != nil {
|
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32602,
|
|
|
|
Message: "Cannot decode address",
|
|
|
|
}
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
return ErrBadParamsField
|
|
|
|
}
|
|
|
|
var hash addressHash
|
|
|
|
copy(hash[:], addrhash)
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
s.ws.requests.AddTxRequest(walletNotification, hash, message.Id)
|
2013-08-14 22:55:31 +02:00
|
|
|
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: nil,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
|
|
|
|
case "notifyspent":
|
|
|
|
params, ok := message.Params.([]interface{})
|
|
|
|
if !ok || len(params) != 2 {
|
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32602,
|
|
|
|
Message: "Invalid parameters",
|
|
|
|
}
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
return ErrBadParamsField
|
|
|
|
}
|
|
|
|
hashBE, ok1 := params[0].(string)
|
|
|
|
index, ok2 := params[1].(float64)
|
|
|
|
if !ok1 || !ok2 {
|
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32602,
|
|
|
|
Message: "Invalid parameters",
|
|
|
|
}
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
return ErrBadParamsField
|
|
|
|
}
|
|
|
|
hash, err := btcwire.NewShaHashFromStr(hashBE)
|
|
|
|
if err != nil {
|
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32602,
|
|
|
|
Message: "Hash string cannot be parsed.",
|
|
|
|
}
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
return ErrBadParamsField
|
|
|
|
}
|
|
|
|
op := btcwire.NewOutPoint(hash, uint32(index))
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
s.ws.requests.AddSpentRequest(walletNotification, op, message.Id)
|
2013-08-14 22:55:31 +02:00
|
|
|
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: nil,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
|
2013-08-06 23:55:22 +02:00
|
|
|
default:
|
|
|
|
jsonError := btcjson.Error{
|
|
|
|
Code: -32601,
|
|
|
|
Message: "Method not found",
|
|
|
|
}
|
|
|
|
rawReply = btcjson.Reply{
|
|
|
|
Result: nil,
|
|
|
|
Error: &jsonError,
|
|
|
|
Id: &message.Id,
|
|
|
|
}
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
return ErrMethodNotImplemented
|
2013-08-06 23:55:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// getDifficultyRatio returns the proof-of-work difficulty as a multiple of the
|
|
|
|
// minimum difficulty using the passed bits field from the header of a block.
|
|
|
|
func getDifficultyRatio(bits uint32) float64 {
|
|
|
|
// The minimum difficulty is the max possible proof-of-work limit bits
|
|
|
|
// converted back to a number. Note this is not the same as the the
|
|
|
|
// proof of work limit directly because the block difficulty is encoded
|
|
|
|
// in a block with the compact form which loses precision.
|
|
|
|
max := btcchain.CompactToBig(activeNetParams.powLimitBits)
|
|
|
|
target := btcchain.CompactToBig(bits)
|
|
|
|
|
|
|
|
difficulty := new(big.Rat).SetFrac(max, target)
|
|
|
|
outString := difficulty.FloatString(2)
|
|
|
|
diff, err := strconv.ParseFloat(outString, 64)
|
|
|
|
if err != nil {
|
2013-10-10 21:13:54 +02:00
|
|
|
log.Errorf("RPCS: Cannot get difficulty: %v", err)
|
2013-08-06 23:55:22 +02:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
return diff
|
|
|
|
}
|
2013-08-14 22:55:31 +02:00
|
|
|
|
|
|
|
// AddWalletListener adds a channel to listen for new messages from a
|
|
|
|
// wallet.
|
|
|
|
func (s *rpcServer) AddWalletListener(c chan []byte) {
|
|
|
|
s.ws.addWalletListener <- c
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoveWalletListener removes a wallet listener channel.
|
|
|
|
func (s *rpcServer) RemoveWalletListener(c chan []byte) {
|
|
|
|
s.ws.removeWalletListener <- c
|
|
|
|
}
|
|
|
|
|
|
|
|
// walletListenerDuplicator listens for new wallet listener channels
|
|
|
|
// and duplicates messages sent to walletNotificationMaster to all
|
|
|
|
// connected listeners.
|
|
|
|
func (s *rpcServer) walletListenerDuplicator() {
|
|
|
|
// walletListeners is a map holding each currently connected wallet
|
|
|
|
// listener as the key. The value is ignored, as this is only used as
|
|
|
|
// a set.
|
|
|
|
walletListeners := make(map[chan []byte]bool)
|
|
|
|
|
|
|
|
// Don't want to add or delete a wallet listener while iterating
|
|
|
|
// through each to propigate to every attached wallet. Use a mutex to
|
|
|
|
// prevent this.
|
|
|
|
var mtx sync.Mutex
|
|
|
|
|
|
|
|
// Check for listener channels to add or remove from set.
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case c := <-s.ws.addWalletListener:
|
|
|
|
mtx.Lock()
|
|
|
|
walletListeners[c] = true
|
|
|
|
mtx.Unlock()
|
|
|
|
|
|
|
|
case c := <-s.ws.removeWalletListener:
|
|
|
|
mtx.Lock()
|
|
|
|
delete(walletListeners, c)
|
|
|
|
mtx.Unlock()
|
|
|
|
|
|
|
|
case <-s.quit:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
// Duplicate all messages sent across walletNotificationMaster to each
|
|
|
|
// listening wallet.
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case ntfn := <-s.ws.walletNotificationMaster:
|
|
|
|
mtx.Lock()
|
|
|
|
for c := range walletListeners {
|
|
|
|
c <- ntfn
|
|
|
|
}
|
|
|
|
mtx.Unlock()
|
|
|
|
|
|
|
|
case <-s.quit:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// walletReqsNotifications is the handler function for websocket
|
|
|
|
// connections from a btcwallet instance. It reads messages from wallet and
|
|
|
|
// sends back replies, as well as notififying wallets of chain updates.
|
|
|
|
func (s *rpcServer) walletReqsNotifications(ws *websocket.Conn) {
|
|
|
|
// Add wallet notification channel so this handler receives btcd chain
|
|
|
|
// notifications.
|
|
|
|
c := make(chan []byte)
|
|
|
|
s.AddWalletListener(c)
|
|
|
|
defer s.RemoveWalletListener(c)
|
|
|
|
|
|
|
|
// msgs is a channel for all messages received over the websocket.
|
|
|
|
msgs := make(chan []byte)
|
|
|
|
|
|
|
|
// Receive messages from websocket and send across reqs until the
|
|
|
|
// connection is lost.
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-s.quit:
|
|
|
|
close(msgs)
|
|
|
|
return
|
|
|
|
default:
|
|
|
|
var m []byte
|
|
|
|
if err := websocket.Message.Receive(ws, &m); err != nil {
|
|
|
|
close(msgs)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
msgs <- m
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case m, ok := <-msgs:
|
|
|
|
if !ok {
|
|
|
|
// Wallet disconnected.
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Handle request here.
|
|
|
|
go s.websocketJSONHandler(c, m)
|
|
|
|
case ntfn, _ := <-c:
|
|
|
|
// Send btcd notification to btcwallet instance over
|
|
|
|
// websocket.
|
|
|
|
if err := websocket.Message.Send(ws, ntfn); err != nil {
|
|
|
|
// Wallet disconnected.
|
|
|
|
return
|
|
|
|
}
|
|
|
|
case <-s.quit:
|
|
|
|
// Server closed.
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// websocketJSONHandler parses and handles a marshalled json message,
|
|
|
|
// sending the marshalled reply to a wallet notification channel.
|
|
|
|
func (s *rpcServer) websocketJSONHandler(walletNotification chan []byte, msg []byte) {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
s.wg.Add(1)
|
|
|
|
reply, err := jsonRead(msg, s)
|
|
|
|
s.wg.Done()
|
2013-08-14 22:55:31 +02:00
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
if err != ErrMethodNotImplemented {
|
|
|
|
replyBytes, err := json.Marshal(reply)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("RPCS: Error marshalling reply: %v", err)
|
|
|
|
}
|
|
|
|
walletNotification <- replyBytes
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try websocket extensions
|
|
|
|
replychan := make(chan *btcjson.Reply)
|
2013-08-14 22:55:31 +02:00
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case reply, ok := <-replychan:
|
|
|
|
if !ok {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
// no more replies expected.
|
2013-08-14 22:55:31 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if reply == nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
log.Tracef("[RPCS] reply: %v", *reply)
|
|
|
|
replyBytes, err := json.Marshal(reply)
|
|
|
|
if err != nil {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
log.Errorf("RPCS: Error Marshalling reply: %v", err)
|
2013-08-14 22:55:31 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
walletNotification <- replyBytes
|
|
|
|
|
|
|
|
case <-s.quit:
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
if err == ErrMethodNotImplemented {
|
|
|
|
// Try websocket extensions
|
|
|
|
s.wg.Add(1)
|
|
|
|
err = jsonWSRead(walletNotification, replychan, msg, s)
|
|
|
|
s.wg.Done()
|
|
|
|
}
|
|
|
|
if err != nil && err != ErrMethodNotImplemented {
|
2013-08-14 22:55:31 +02:00
|
|
|
log.Error(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NotifyBlockConnected creates and marshalls a JSON message to notify
|
|
|
|
// of a new block connected to the main chain. The notification is sent
|
|
|
|
// to each connected wallet.
|
|
|
|
func (s *rpcServer) NotifyBlockConnected(block *btcutil.Block) {
|
|
|
|
var id interface{} = "btcd:blockconnected"
|
|
|
|
hash, err := block.Sha()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Bad block; connected block notification dropped.")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
ntfn := btcjson.Reply{
|
|
|
|
Result: struct {
|
|
|
|
Hash string `json:"hash"`
|
|
|
|
Height int64 `json:"height"`
|
|
|
|
}{
|
|
|
|
Hash: hash.String(),
|
|
|
|
Height: block.Height(),
|
|
|
|
},
|
|
|
|
Id: &id,
|
|
|
|
}
|
|
|
|
m, _ := json.Marshal(ntfn)
|
|
|
|
s.ws.walletNotificationMaster <- m
|
|
|
|
}
|
|
|
|
|
|
|
|
// NotifyBlockDisconnected creates and marshalls a JSON message to notify
|
|
|
|
// of a new block disconnected from the main chain. The notification is sent
|
|
|
|
// to each connected wallet.
|
|
|
|
func (s *rpcServer) NotifyBlockDisconnected(block *btcutil.Block) {
|
|
|
|
var id interface{} = "btcd:blockdisconnected"
|
|
|
|
hash, err := block.Sha()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Bad block; connected block notification dropped.")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
ntfn := btcjson.Reply{
|
|
|
|
Result: struct {
|
|
|
|
Hash string `json:"hash"`
|
|
|
|
Height int64 `json:"height"`
|
|
|
|
}{
|
|
|
|
Hash: hash.String(),
|
|
|
|
Height: block.Height(),
|
|
|
|
},
|
|
|
|
Id: &id,
|
|
|
|
}
|
|
|
|
m, _ := json.Marshal(ntfn)
|
|
|
|
s.ws.walletNotificationMaster <- m
|
|
|
|
}
|
|
|
|
|
|
|
|
// NotifyNewTxListeners creates and marshals a JSON message to notify wallets
|
|
|
|
// of new transactions (with both spent and unspent outputs) for a watched
|
|
|
|
// address.
|
|
|
|
func (s *rpcServer) NotifyNewTxListeners(db btcdb.Db, block *btcutil.Block) {
|
|
|
|
txShaList, err := block.TxShas()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Bad block; All notifications for block dropped.")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
txList := db.FetchTxByShaList(txShaList)
|
2013-10-20 18:50:31 +02:00
|
|
|
for _, txReply := range txList {
|
|
|
|
if txReply.Err == nil && txReply.Tx != nil {
|
|
|
|
go s.newBlockNotifyCheckTxIn(txReply.Tx.TxIn)
|
|
|
|
go s.newBlockNotifyCheckTxOut(db, block, txReply)
|
|
|
|
}
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// newBlockNotifyCheckTxIn is a helper function to iterate through
|
|
|
|
// each transaction input of a new block and perform any checks and
|
|
|
|
// notify listening frontends when necessary.
|
|
|
|
func (s *rpcServer) newBlockNotifyCheckTxIn(txins []*btcwire.TxIn) {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
for wltNtfn, cxt := range s.ws.requests.m {
|
|
|
|
for _, txin := range txins {
|
|
|
|
for op, id := range cxt.spentRequests {
|
|
|
|
if txin.PreviousOutpoint != op {
|
|
|
|
continue
|
|
|
|
}
|
2013-08-14 22:55:31 +02:00
|
|
|
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
reply := &btcjson.Reply{
|
|
|
|
Result: struct {
|
|
|
|
TxHash string `json:"txhash"`
|
|
|
|
Index uint32 `json:"index"`
|
|
|
|
}{
|
|
|
|
TxHash: op.Hash.String(),
|
|
|
|
Index: uint32(op.Index),
|
|
|
|
},
|
|
|
|
Error: nil,
|
|
|
|
Id: &id,
|
|
|
|
}
|
|
|
|
replyBytes, err := json.Marshal(reply)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("RPCS: Unable to marshal spent notification: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
wltNtfn <- replyBytes
|
|
|
|
s.ws.requests.RemoveSpentRequest(wltNtfn, &op)
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// newBlockNotifyCheckTxOut is a helper function to iterate through
|
|
|
|
// each transaction output of a new block and perform any checks and
|
|
|
|
// notify listening frontends when necessary.
|
|
|
|
func (s *rpcServer) newBlockNotifyCheckTxOut(db btcdb.Db, block *btcutil.Block, tx *btcdb.TxListReply) {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
for wltNtfn, cxt := range s.ws.requests.m {
|
|
|
|
for i, txout := range tx.Tx.TxOut {
|
|
|
|
_, txaddrhash, err := btcscript.ScriptToAddrHash(txout.PkScript)
|
2013-08-14 22:55:31 +02:00
|
|
|
if err != nil {
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
log.Debug("Error getting payment address from tx; dropping any Tx notifications.")
|
2013-08-14 22:55:31 +02:00
|
|
|
break
|
|
|
|
}
|
Clean up notification contexts and goroutines after ws disconnect.
This refactors the wallet notification code to reverse the order of
how notification contexts are stored. Before, watched addresses and
outpoints were used as keys, with a special reply channel as the
value. This channel was read from and replies were marshalled and
sent to the main wallet notification chan, but the goroutine handling
this marshalling never exited because the reply channel was never
closed (and couldn't have been, because there was no way to tell it
was handling notifications for any particular wallet).
Notification contexts are now primarily mapped by wallet notification
channels, and code to send the notifications send directly to the
wallet channel, with the previous goroutine reading the reply chan
properly closing.
The RPC code is also refactored with this change as well, to separate
it more from websocket code. Websocket JSON extensions are no longer
available to RPC clients.
While here, unbreak RPC. Previously, replies were never sent back.
This broke when I merged in my websocket code, as sends for the reply
channel in jsonRead blocked before a reader for the channel was
opened. A 3 liner could have fixed this, but doing a proper fix
(changing jsonRead so it did not use the reply channel as it is
unneeded for the standard RPC API) is preferred.
2013-10-16 20:12:00 +02:00
|
|
|
for addr, id := range cxt.txRequests {
|
|
|
|
if !bytes.Equal(addr[:], txaddrhash) {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
blkhash, err := block.Sha()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Error getting block sha; dropping Tx notification.")
|
|
|
|
break
|
|
|
|
}
|
|
|
|
txaddr, err := btcutil.EncodeAddress(txaddrhash, s.server.btcnet)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Error encoding address; dropping Tx notification.")
|
|
|
|
break
|
|
|
|
}
|
|
|
|
reply := &btcjson.Reply{
|
|
|
|
Result: struct {
|
|
|
|
Sender string `json:"sender"`
|
|
|
|
Receiver string `json:"receiver"`
|
|
|
|
BlockHash string `json:"blockhash"`
|
|
|
|
Height int64 `json:"height"`
|
|
|
|
TxHash string `json:"txhash"`
|
|
|
|
Index uint32 `json:"index"`
|
|
|
|
Amount int64 `json:"amount"`
|
|
|
|
PkScript string `json:"pkscript"`
|
|
|
|
Spent bool `json:"spent"`
|
|
|
|
}{
|
|
|
|
Sender: "Unknown", // TODO(jrick)
|
|
|
|
Receiver: txaddr,
|
|
|
|
BlockHash: blkhash.String(),
|
|
|
|
Height: block.Height(),
|
|
|
|
TxHash: tx.Sha.String(),
|
|
|
|
Index: uint32(i),
|
|
|
|
Amount: txout.Value,
|
|
|
|
PkScript: btcutil.Base58Encode(txout.PkScript),
|
|
|
|
Spent: tx.TxSpent[i],
|
|
|
|
},
|
|
|
|
Error: nil,
|
|
|
|
Id: &id,
|
|
|
|
}
|
|
|
|
replyBytes, err := json.Marshal(reply)
|
|
|
|
if err != nil {
|
|
|
|
log.Errorf("RPCS: Unable to marshal tx notification: %v", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
wltNtfn <- replyBytes
|
2013-08-14 22:55:31 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|