Remove wallet notifications chan from std commands.
This commit cleans up the standard RPC command hanlding a bit by removing the websocket specific notification channel from the handlers. This was previously required because the sendrawtransaction, when called from a websocket enabled connection, needs to add a notification for when the transaction is mined. This commit modifies that to instead implement a websocket extended version of sendrawtransaction which invokes the standard handler and adds the notification. In addition, the main send was modified to first look if the command has a websocket specific handler first, and then falls back to standard commands, rather than the previous approach of first checking for a standard command and falling through to websocket commands. This essentially allows websockets connections to extend commands with the same name with additional functionality such as what was done in this commit.
This commit is contained in:
parent
5ad6d543d6
commit
9b166b3876
2 changed files with 96 additions and 100 deletions
72
rpcserver.go
72
rpcserver.go
|
@ -328,7 +328,7 @@ func jsonRPCRead(w http.ResponseWriter, r *http.Request, s *rpcServer) {
|
||||||
if jsonErr != nil {
|
if jsonErr != nil {
|
||||||
reply.Error = jsonErr
|
reply.Error = jsonErr
|
||||||
} else {
|
} else {
|
||||||
reply = standardCmdReply(cmd, s, nil)
|
reply = standardCmdReply(cmd, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcsLog.Tracef("reply: %v", reply)
|
rpcsLog.Tracef("reply: %v", reply)
|
||||||
|
@ -341,9 +341,9 @@ func jsonRPCRead(w http.ResponseWriter, r *http.Request, s *rpcServer) {
|
||||||
rpcsLog.Debugf(msg)
|
rpcsLog.Debugf(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jrick): Remove the wallet notification chan.
|
type commandHandler func(*rpcServer, btcjson.Cmd) (interface{}, error)
|
||||||
type commandHandler func(*rpcServer, btcjson.Cmd, chan []byte) (interface{}, error)
|
|
||||||
|
|
||||||
|
// handlers maps RPC command strings to appropriate handler functions.
|
||||||
var handlers = map[string]commandHandler{
|
var handlers = map[string]commandHandler{
|
||||||
"addmultisigaddress": handleAskWallet,
|
"addmultisigaddress": handleAskWallet,
|
||||||
"addnode": handleAddNode,
|
"addnode": handleAddNode,
|
||||||
|
@ -421,22 +421,19 @@ var handlers = map[string]commandHandler{
|
||||||
|
|
||||||
// handleUnimplemented is a temporary handler for commands that we should
|
// handleUnimplemented is a temporary handler for commands that we should
|
||||||
// support but do not.
|
// support but do not.
|
||||||
func handleUnimplemented(s *rpcServer, cmd btcjson.Cmd,
|
func handleUnimplemented(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
return nil, btcjson.ErrUnimplemented
|
return nil, btcjson.ErrUnimplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleAskWallet is the handler for commands that we do recognise as valid
|
// handleAskWallet is the handler for commands that we do recognise as valid
|
||||||
// but that we can not answer correctly since it involves wallet state.
|
// but that we can not answer correctly since it involves wallet state.
|
||||||
// These commands will be implemented in btcwallet.
|
// These commands will be implemented in btcwallet.
|
||||||
func handleAskWallet(s *rpcServer, cmd btcjson.Cmd,
|
func handleAskWallet(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
return nil, btcjson.ErrNoWallet
|
return nil, btcjson.ErrNoWallet
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleAddNode handles addnode commands.
|
// handleAddNode handles addnode commands.
|
||||||
func handleAddNode(s *rpcServer, cmd btcjson.Cmd,
|
func handleAddNode(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
c := cmd.(*btcjson.AddNodeCmd)
|
c := cmd.(*btcjson.AddNodeCmd)
|
||||||
|
|
||||||
addr := normalizeAddress(c.Addr, activeNetParams.peerPort)
|
addr := normalizeAddress(c.Addr, activeNetParams.peerPort)
|
||||||
|
@ -464,8 +461,7 @@ func handleAddNode(s *rpcServer, cmd btcjson.Cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleDebugLevel handles debuglevel commands.
|
// handleDebugLevel handles debuglevel commands.
|
||||||
func handleDebugLevel(s *rpcServer, cmd btcjson.Cmd,
|
func handleDebugLevel(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
c := cmd.(*btcjson.DebugLevelCmd)
|
c := cmd.(*btcjson.DebugLevelCmd)
|
||||||
|
|
||||||
// Special show command to list supported subsystems.
|
// Special show command to list supported subsystems.
|
||||||
|
@ -559,8 +555,7 @@ func createVoutList(mtx *btcwire.MsgTx, net btcwire.BitcoinNet) ([]btcjson.Vout,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleDecodeRawTransaction handles decoderawtransaction commands.
|
// handleDecodeRawTransaction handles decoderawtransaction commands.
|
||||||
func handleDecodeRawTransaction(s *rpcServer, cmd btcjson.Cmd,
|
func handleDecodeRawTransaction(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
c := cmd.(*btcjson.DecodeRawTransactionCmd)
|
c := cmd.(*btcjson.DecodeRawTransactionCmd)
|
||||||
|
|
||||||
// Deserialize the transaction.
|
// Deserialize the transaction.
|
||||||
|
@ -607,9 +602,7 @@ func handleDecodeRawTransaction(s *rpcServer, cmd btcjson.Cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetBestBlockHash implements the getbestblockhash command.
|
// handleGetBestBlockHash implements the getbestblockhash command.
|
||||||
func handleGetBestBlockHash(s *rpcServer, cmd btcjson.Cmd,
|
func handleGetBestBlockHash(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
var sha *btcwire.ShaHash
|
|
||||||
sha, _, err := s.server.db.NewestSha()
|
sha, _, err := s.server.db.NewestSha()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpcsLog.Errorf("Error getting newest sha: %v", err)
|
rpcsLog.Errorf("Error getting newest sha: %v", err)
|
||||||
|
@ -634,8 +627,7 @@ func messageToHex(msg btcwire.Message) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetBlock implements the getblock command.
|
// handleGetBlock implements the getblock command.
|
||||||
func handleGetBlock(s *rpcServer, cmd btcjson.Cmd,
|
func handleGetBlock(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
c := cmd.(*btcjson.GetBlockCmd)
|
c := cmd.(*btcjson.GetBlockCmd)
|
||||||
sha, err := btcwire.NewShaHashFromStr(c.Hash)
|
sha, err := btcwire.NewShaHashFromStr(c.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -732,8 +724,7 @@ func handleGetBlock(s *rpcServer, cmd btcjson.Cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetBlockCount implements the getblockcount command.
|
// handleGetBlockCount implements the getblockcount command.
|
||||||
func handleGetBlockCount(s *rpcServer, cmd btcjson.Cmd,
|
func handleGetBlockCount(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
_, maxidx, err := s.server.db.NewestSha()
|
_, maxidx, err := s.server.db.NewestSha()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpcsLog.Errorf("Error getting newest sha: %v", err)
|
rpcsLog.Errorf("Error getting newest sha: %v", err)
|
||||||
|
@ -744,8 +735,7 @@ func handleGetBlockCount(s *rpcServer, cmd btcjson.Cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetBlockHash implements the getblockhash command.
|
// handleGetBlockHash implements the getblockhash command.
|
||||||
func handleGetBlockHash(s *rpcServer, cmd btcjson.Cmd,
|
func handleGetBlockHash(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
c := cmd.(*btcjson.GetBlockHashCmd)
|
c := cmd.(*btcjson.GetBlockHashCmd)
|
||||||
sha, err := s.server.db.FetchBlockShaByHeight(c.Index)
|
sha, err := s.server.db.FetchBlockShaByHeight(c.Index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -757,14 +747,12 @@ func handleGetBlockHash(s *rpcServer, cmd btcjson.Cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetConnectionCount implements the getconnectioncount command.
|
// handleGetConnectionCount implements the getconnectioncount command.
|
||||||
func handleGetConnectionCount(s *rpcServer, cmd btcjson.Cmd,
|
func handleGetConnectionCount(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
return s.server.ConnectedCount(), nil
|
return s.server.ConnectedCount(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetDifficulty implements the getdifficulty command.
|
// handleGetDifficulty implements the getdifficulty command.
|
||||||
func handleGetDifficulty(s *rpcServer, cmd btcjson.Cmd,
|
func handleGetDifficulty(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
sha, _, err := s.server.db.NewestSha()
|
sha, _, err := s.server.db.NewestSha()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rpcsLog.Errorf("Error getting sha: %v", err)
|
rpcsLog.Errorf("Error getting sha: %v", err)
|
||||||
|
@ -781,21 +769,19 @@ func handleGetDifficulty(s *rpcServer, cmd btcjson.Cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetGenerate implements the getgenerate command.
|
// handleGetGenerate implements the getgenerate command.
|
||||||
func handleGetGenerate(s *rpcServer, cmd btcjson.Cmd,
|
func handleGetGenerate(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
// btcd does not do mining so we can hardcode replies here.
|
// btcd does not do mining so we can hardcode replies here.
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetHashesPerSec implements the gethashespersec command.
|
// handleGetHashesPerSec implements the gethashespersec command.
|
||||||
func handleGetHashesPerSec(s *rpcServer, cmd btcjson.Cmd,
|
func handleGetHashesPerSec(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
walletNotification chan []byte) (interface{}, error) {
|
|
||||||
// btcd does not do mining so we can hardcode replies here.
|
// btcd does not do mining so we can hardcode replies here.
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetPeerInfo implements the getpeerinfo command.
|
// handleGetPeerInfo implements the getpeerinfo command.
|
||||||
func handleGetPeerInfo(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
func handleGetPeerInfo(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
return s.server.PeerInfo(), nil
|
return s.server.PeerInfo(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,7 +799,7 @@ type mempoolDescriptor struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetRawMempool implements the getrawmempool command.
|
// handleGetRawMempool implements the getrawmempool command.
|
||||||
func handleGetRawMempool(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
func handleGetRawMempool(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.GetRawMempoolCmd)
|
c := cmd.(*btcjson.GetRawMempoolCmd)
|
||||||
descs := s.server.txMemPool.TxDescs()
|
descs := s.server.txMemPool.TxDescs()
|
||||||
|
|
||||||
|
@ -854,7 +840,7 @@ func handleGetRawMempool(s *rpcServer, cmd btcjson.Cmd, walletNotification chan
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleGetRawTransaction implements the getrawtransaction command.
|
// handleGetRawTransaction implements the getrawtransaction command.
|
||||||
func handleGetRawTransaction(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
func handleGetRawTransaction(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.GetRawTransactionCmd)
|
c := cmd.(*btcjson.GetRawTransactionCmd)
|
||||||
|
|
||||||
// Convert the provided transaction hash hex to a ShaHash.
|
// Convert the provided transaction hash hex to a ShaHash.
|
||||||
|
@ -962,7 +948,7 @@ func createTxRawResult(net btcwire.BitcoinNet, txSha string, mtx *btcwire.MsgTx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleSendRawTransaction implements the sendrawtransaction command.
|
// handleSendRawTransaction implements the sendrawtransaction command.
|
||||||
func handleSendRawTransaction(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
func handleSendRawTransaction(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.SendRawTransactionCmd)
|
c := cmd.(*btcjson.SendRawTransactionCmd)
|
||||||
// Deserialize and send off to tx relay
|
// Deserialize and send off to tx relay
|
||||||
serializedTx, err := hex.DecodeString(c.HexTx)
|
serializedTx, err := hex.DecodeString(c.HexTx)
|
||||||
|
@ -1000,23 +986,17 @@ func handleSendRawTransaction(s *rpcServer, cmd btcjson.Cmd, walletNotification
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If called from websocket code, add a mined tx hashes
|
|
||||||
// request.
|
|
||||||
if walletNotification != nil {
|
|
||||||
s.ws.AddMinedTxRequest(walletNotification, tx.Sha())
|
|
||||||
}
|
|
||||||
|
|
||||||
return tx.Sha().String(), nil
|
return tx.Sha().String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleSetGenerate implements the setgenerate command.
|
// handleSetGenerate implements the setgenerate command.
|
||||||
func handleSetGenerate(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
func handleSetGenerate(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
// btcd does not do mining so we can hardcode replies here.
|
// btcd does not do mining so we can hardcode replies here.
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleStop implements the stop command.
|
// handleStop implements the stop command.
|
||||||
func handleStop(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
func handleStop(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
s.server.Stop()
|
s.server.Stop()
|
||||||
return "btcd stopping.", nil
|
return "btcd stopping.", nil
|
||||||
}
|
}
|
||||||
|
@ -1067,7 +1047,7 @@ func verifyChain(db btcdb.Db, level, depth int32) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleVerifyChain(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
func handleVerifyChain(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.VerifyChainCmd)
|
c := cmd.(*btcjson.VerifyChainCmd)
|
||||||
|
|
||||||
err := verifyChain(s.server.db, c.CheckLevel, c.CheckDepth)
|
err := verifyChain(s.server.db, c.CheckLevel, c.CheckDepth)
|
||||||
|
@ -1095,9 +1075,7 @@ func parseCmd(b []byte) (btcjson.Cmd, *btcjson.Error) {
|
||||||
// standardCmdReply checks that a parsed command is a standard
|
// standardCmdReply checks that a parsed command is a standard
|
||||||
// Bitcoin JSON-RPC command and runs the proper handler to reply to the
|
// Bitcoin JSON-RPC command and runs the proper handler to reply to the
|
||||||
// command.
|
// command.
|
||||||
func standardCmdReply(cmd btcjson.Cmd, s *rpcServer,
|
func standardCmdReply(cmd btcjson.Cmd, s *rpcServer) (reply btcjson.Reply) {
|
||||||
walletNotification chan []byte) (reply btcjson.Reply) {
|
|
||||||
|
|
||||||
id := cmd.Id()
|
id := cmd.Id()
|
||||||
reply.Id = &id
|
reply.Id = &id
|
||||||
|
|
||||||
|
@ -1107,7 +1085,7 @@ func standardCmdReply(cmd btcjson.Cmd, s *rpcServer,
|
||||||
return reply
|
return reply
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := handler(s, cmd, walletNotification)
|
result, err := handler(s, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
jsonErr, ok := err.(btcjson.Error)
|
jsonErr, ok := err.(btcjson.Error)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
114
rpcwebsocket.go
114
rpcwebsocket.go
|
@ -230,9 +230,10 @@ type wsCommandHandler func(*rpcServer, btcjson.Cmd, chan []byte, *requestContext
|
||||||
var wsHandlers = map[string]wsCommandHandler{
|
var wsHandlers = map[string]wsCommandHandler{
|
||||||
"getcurrentnet": handleGetCurrentNet,
|
"getcurrentnet": handleGetCurrentNet,
|
||||||
"getbestblock": handleGetBestBlock,
|
"getbestblock": handleGetBestBlock,
|
||||||
"rescan": handleRescan,
|
|
||||||
"notifynewtxs": handleNotifyNewTXs,
|
"notifynewtxs": handleNotifyNewTXs,
|
||||||
"notifyspent": handleNotifySpent,
|
"notifyspent": handleNotifySpent,
|
||||||
|
"rescan": handleRescan,
|
||||||
|
"sendrawtransaction:": handleWalletSendRawTransaction,
|
||||||
}
|
}
|
||||||
|
|
||||||
// respondToAnyCmd checks that a parsed command is a standard or
|
// respondToAnyCmd checks that a parsed command is a standard or
|
||||||
|
@ -242,22 +243,20 @@ var wsHandlers = map[string]wsCommandHandler{
|
||||||
func respondToAnyCmd(cmd btcjson.Cmd, s *rpcServer,
|
func respondToAnyCmd(cmd btcjson.Cmd, s *rpcServer,
|
||||||
walletNotification chan []byte, rc *requestContexts) {
|
walletNotification chan []byte, rc *requestContexts) {
|
||||||
|
|
||||||
reply := standardCmdReply(cmd, s, walletNotification)
|
// Lookup the websocket extension for the command and if it doesn't
|
||||||
if reply.Error != &btcjson.ErrMethodNotFound {
|
// exist fallback to handling the command as a standard command.
|
||||||
mreply, _ := json.Marshal(reply)
|
|
||||||
walletNotification <- mreply
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
wsHandler, ok := wsHandlers[cmd.Method()]
|
wsHandler, ok := wsHandlers[cmd.Method()]
|
||||||
if !ok {
|
if !ok {
|
||||||
reply.Error = &btcjson.ErrMethodNotFound
|
reply := standardCmdReply(cmd, s)
|
||||||
mreply, _ := json.Marshal(reply)
|
mreply, _ := json.Marshal(reply)
|
||||||
walletNotification <- mreply
|
walletNotification <- mreply
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call the appropriate handler which responds unless there was an
|
||||||
|
// error in which case the error is marshalled and sent here.
|
||||||
if err := wsHandler(s, cmd, walletNotification, rc); err != nil {
|
if err := wsHandler(s, cmd, walletNotification, rc); err != nil {
|
||||||
|
var reply btcjson.Reply
|
||||||
jsonErr, ok := err.(btcjson.Error)
|
jsonErr, ok := err.(btcjson.Error)
|
||||||
if ok {
|
if ok {
|
||||||
reply.Error = &jsonErr
|
reply.Error = &jsonErr
|
||||||
|
@ -325,6 +324,54 @@ func handleGetBestBlock(s *rpcServer, cmd btcjson.Cmd,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleNotifyNewTXs implements the notifynewtxs command extension for
|
||||||
|
// websocket connections.
|
||||||
|
func handleNotifyNewTXs(s *rpcServer, cmd btcjson.Cmd,
|
||||||
|
walletNotification chan []byte, rc *requestContexts) error {
|
||||||
|
|
||||||
|
id := cmd.Id()
|
||||||
|
reply := &btcjson.Reply{Id: &id}
|
||||||
|
|
||||||
|
notifyCmd, ok := cmd.(*btcws.NotifyNewTXsCmd)
|
||||||
|
if !ok {
|
||||||
|
return btcjson.ErrInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, addr := range notifyCmd.Addresses {
|
||||||
|
hash, _, err := btcutil.DecodeAddress(addr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot decode address: %v", err)
|
||||||
|
}
|
||||||
|
s.ws.AddTxRequest(walletNotification, rc, string(hash),
|
||||||
|
cmd.Id())
|
||||||
|
}
|
||||||
|
|
||||||
|
mreply, _ := json.Marshal(reply)
|
||||||
|
walletNotification <- mreply
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleNotifySpent implements the notifyspent command extension for
|
||||||
|
// websocket connections.
|
||||||
|
func handleNotifySpent(s *rpcServer, cmd btcjson.Cmd,
|
||||||
|
walletNotification chan []byte, rc *requestContexts) error {
|
||||||
|
|
||||||
|
id := cmd.Id()
|
||||||
|
reply := &btcjson.Reply{Id: &id}
|
||||||
|
|
||||||
|
notifyCmd, ok := cmd.(*btcws.NotifySpentCmd)
|
||||||
|
if !ok {
|
||||||
|
return btcjson.ErrInternal
|
||||||
|
}
|
||||||
|
|
||||||
|
s.ws.AddSpentRequest(walletNotification, rc, notifyCmd.OutPoint,
|
||||||
|
cmd.Id())
|
||||||
|
|
||||||
|
mreply, _ := json.Marshal(reply)
|
||||||
|
walletNotification <- mreply
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleRescan implements the rescan command extension for websocket
|
// handleRescan implements the rescan command extension for websocket
|
||||||
// connections.
|
// connections.
|
||||||
func handleRescan(s *rpcServer, cmd btcjson.Cmd,
|
func handleRescan(s *rpcServer, cmd btcjson.Cmd,
|
||||||
|
@ -444,51 +491,22 @@ func handleRescan(s *rpcServer, cmd btcjson.Cmd,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleNotifyNewTXs implements the notifynewtxs command extension for
|
// handleWalletSendRawTransaction implements the websocket extended version of
|
||||||
// websocket connections.
|
// the sendrawtransaction command.
|
||||||
func handleNotifyNewTXs(s *rpcServer, cmd btcjson.Cmd,
|
func handleWalletSendRawTransaction(s *rpcServer, cmd btcjson.Cmd,
|
||||||
walletNotification chan []byte, rc *requestContexts) error {
|
walletNotification chan []byte, rc *requestContexts) error {
|
||||||
|
|
||||||
id := cmd.Id()
|
result, err := handleSendRawTransaction(s, cmd)
|
||||||
reply := &btcjson.Reply{Id: &id}
|
|
||||||
|
|
||||||
notifyCmd, ok := cmd.(*btcws.NotifyNewTXsCmd)
|
|
||||||
if !ok {
|
|
||||||
return btcjson.ErrInternal
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, addr := range notifyCmd.Addresses {
|
|
||||||
hash, _, err := btcutil.DecodeAddress(addr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot decode address: %v", err)
|
return err
|
||||||
}
|
|
||||||
s.ws.AddTxRequest(walletNotification, rc, string(hash),
|
|
||||||
cmd.Id())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mreply, _ := json.Marshal(reply)
|
// The result is already guaranteed to be a valid hash string if no
|
||||||
walletNotification <- mreply
|
// error was returned above, so it's safe to ignore the error here.
|
||||||
return nil
|
txSha, _ := btcwire.NewShaHashFromStr(result.(string))
|
||||||
}
|
|
||||||
|
|
||||||
// handleNotifySpent implements the notifyspent command extension for
|
// Request to be notified when the transaction is mined.
|
||||||
// websocket connections.
|
s.ws.AddMinedTxRequest(walletNotification, txSha)
|
||||||
func handleNotifySpent(s *rpcServer, cmd btcjson.Cmd,
|
|
||||||
walletNotification chan []byte, rc *requestContexts) error {
|
|
||||||
|
|
||||||
id := cmd.Id()
|
|
||||||
reply := &btcjson.Reply{Id: &id}
|
|
||||||
|
|
||||||
notifyCmd, ok := cmd.(*btcws.NotifySpentCmd)
|
|
||||||
if !ok {
|
|
||||||
return btcjson.ErrInternal
|
|
||||||
}
|
|
||||||
|
|
||||||
s.ws.AddSpentRequest(walletNotification, rc, notifyCmd.OutPoint,
|
|
||||||
cmd.Id())
|
|
||||||
|
|
||||||
mreply, _ := json.Marshal(reply)
|
|
||||||
walletNotification <- mreply
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue