// handleChainNotifications is the major chain notification handler that // receives websocket notifications about the blockchain. func (w *Wallet) handleChainNotifications() { chainClient, err := w.requireChainClient() if err != nil { log.Errorf("handleChainNotifications called without RPC client") w.wg.Done() return } // At the moment there is no recourse if the rescan fails for // some reason, however, the wallet will not be marked synced // and many methods will error early since the wallet is known // to be out of date. err = w.syncWithChain() if err != nil && !w.ShuttingDown() { log.Warnf("Unable to synchronize wallet to chain: %v", err) } for n := range chainClient.Notifications() { var err error strErrType := "" switch n := n.(type) { case chain.ClientConnected: log.Infof("The client has successfully connected to dcrd and " + "is now handling websocket notifications") case chain.BlockConnected: err = walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error { return w.connectBlock(tx, wtxmgr.BlockMeta(n)) }) strErrType = "BlockConnected" case chain.BlockDisconnected: err = walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error { return w.disconnectBlock(tx, wtxmgr.BlockMeta(n)) }) strErrType = "BlockDisconnected" case chain.Reorganization: w.handleReorganizing(n.OldHash, n.OldHeight, n.NewHash, n.NewHeight) case chain.RelevantTx: err = walletdb.Update(w.db, func(tx walletdb.ReadWriteTx) error { return w.addRelevantTx(tx, n.TxRecord, n.Block) }) strErrType = "RelevantTx" // The following are handled by the wallet's rescan // goroutines, so just pass them there. case *chain.RescanProgress, *chain.RescanFinished: w.rescanNotifications <- n } if err != nil { log.Errorf("Cannot handle chain server "+ "notification %v: %v", strErrType, err) } } w.wg.Done() }
func (w *Wallet) handleChainNotifications() { sync := func(w *Wallet) { // At the moment there is no recourse if the rescan fails for // some reason, however, the wallet will not be marked synced // and many methods will error early since the wallet is known // to be out of date. err := w.syncWithChain() if err != nil && !w.ShuttingDown() { log.Warnf("Unable to synchronize wallet to chain: %v", err) } } for n := range w.chainSvr.Notifications() { var err error strErrType := "" switch n := n.(type) { case chain.ClientConnected: go sync(w) case chain.BlockConnected: w.connectBlock(wtxmgr.BlockMeta(n)) case chain.BlockDisconnected: err = w.disconnectBlock(wtxmgr.BlockMeta(n)) case chain.Reorganization: w.handleReorganizing(n.OldHash, n.OldHeight, n.NewHash, n.NewHeight) case chain.StakeDifficulty: err = w.handleStakeDifficulty(n.BlockHash, n.BlockHeight, n.StakeDiff) strErrType = "StakeDifficulty" case chain.RelevantTx: err = w.addRelevantTx(n.TxRecord, n.Block) // The following are handled by the wallet's rescan // goroutines, so just pass them there. case *chain.RescanProgress, *chain.RescanFinished: w.rescanNotifications <- n } if err != nil { log.Errorf("Cannot handle chain server "+ "notification %v: %v", strErrType, err) } } w.wg.Done() }