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