From 8771664af738173d7dd1dc9d0002cfde5cee3997 Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Mon, 28 Jul 2014 09:33:00 -0500 Subject: [PATCH] Send btcdconnected ntfns to connected clients. If a websocket client was already connected and the wallet and/or chain server is loaded into the rpc server (enabling the handlers specific to those components), the btcdconnected notifications were not being sent, and this could break clients that expected the notification. I'm not happy with this change, but since this is how notifications are currently done (unsolicited), and to not break compatibility yet, I'm adding these back in for now. Eventually, this notification will require explicit registration before it is received by a client. See issue #84. Closes #115. --- chain/chain.go | 10 +++++++--- chainntfns.go | 2 ++ rpcserver.go | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/chain/chain.go b/chain/chain.go index 68776c1..15181c4 100644 --- a/chain/chain.go +++ b/chain/chain.go @@ -54,9 +54,7 @@ func NewClient(net *btcnet.Params, connect, user, pass string, certs []byte) (*C } initializedClient := make(chan struct{}) ntfnCallbacks := btcrpcclient.NotificationHandlers{ - OnClientConnected: func() { - log.Info("Established connection to btcd") - }, + OnClientConnected: client.onClientConnect, OnBlockConnected: client.onBlockConnected, OnBlockDisconnected: client.onBlockDisconnected, OnRecvTx: client.onRecvTx, @@ -146,6 +144,7 @@ func (c *Client) BlockStamp() (*keystore.BlockStamp, error) { // btcrpcclient callbacks, which isn't very Go-like and doesn't allow // blocking client calls. type ( + ClientConnected struct{} BlockConnected keystore.BlockStamp BlockDisconnected keystore.BlockStamp RecvTx struct { @@ -187,6 +186,11 @@ func parseBlock(block *btcws.BlockDetails) (blk *txstore.Block, idx int, err err return blk, block.Index, nil } +func (c *Client) onClientConnect() { + log.Info("Established websocket RPC connection to btcd") + c.enqueueNotification <- ClientConnected{} +} + func (c *Client) onBlockConnected(hash *btcwire.ShaHash, height int32) { c.enqueueNotification <- BlockConnected{Hash: hash, Height: height} } diff --git a/chainntfns.go b/chainntfns.go index 07d706b..8b1e297 100644 --- a/chainntfns.go +++ b/chainntfns.go @@ -28,6 +28,8 @@ func (w *Wallet) handleChainNotifications() { for n := range w.chainSvr.Notifications() { var err error switch n := n.(type) { + case chain.ClientConnected: + w.notifyChainServerConnected(true) case chain.BlockConnected: w.connectBlock(keystore.BlockStamp(n)) case chain.BlockDisconnected: diff --git a/rpcserver.go b/rpcserver.go index 3765c1b..b424f29 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -514,6 +514,7 @@ func (s *rpcServer) SetWallet(wallet *Wallet) { s.wallet = wallet s.registerWalletNtfns <- struct{}{} + chainSvrConnected := false if s.chainSvr != nil { // If the chain server rpc client is also set, there's no reason // to keep the mutex around. Make the locker simply execute @@ -523,7 +524,15 @@ func (s *rpcServer) SetWallet(wallet *Wallet) { // With both the wallet and chain server set, all handlers are // ok to run. s.handlerLookup = lookupAnyHandler + + chainSvrConnected = !s.chainSvr.Disconnected() } + + // Make sure already connected websocket clients get a notification + // if the chain RPC client connection is set and connected. This is + // run as a goroutine since it must aquire the handlerLock, which is + // locked here. + go s.notifyChainServerConnected(chainSvrConnected) } // SetChainServer sets the chain server client component needed to run a fully @@ -546,6 +555,12 @@ func (s *rpcServer) SetChainServer(chainSvr *chain.Client) { // ok to run. s.handlerLookup = lookupAnyHandler } + + // Make sure already connected websocket clients get a notification + // if the chain RPC client connection is set and connected. This is + // run as a goroutine since it must aquire the handlerLock, which is + // locked here. + go s.notifyChainServerConnected(!chainSvr.Disconnected()) } // HandlerClosure creates a closure function for handling requests of the given