// marshalAndSend marshals the passed command to JSON-RPC and sends it to the // server. It returns a response channel on which the reply will be delivered. func (c *Client) marshalAndSend(cmd btcjson.Cmd, responseChan chan *response) { marshalledJSON, err := cmd.MarshalJSON() if err != nil { responseChan <- &response{result: nil, err: err} return } log.Tracef("Sending command [%s] with id %d", cmd.Method(), cmd.Id()) c.sendMessage(marshalledJSON) }
// NtfnBlockDisconnected handles btcd notifications resulting from // blocks disconnected from the main chain in the event of a chain // switch and notifies frontends of the new blockchain height. func NtfnBlockDisconnected(n btcjson.Cmd) error { bdn, ok := n.(*btcws.BlockDisconnectedNtfn) if !ok { return fmt.Errorf("%v handler: unexpected type", n.Method()) } hash, err := btcwire.NewShaHashFromStr(bdn.Hash) if err != nil { return fmt.Errorf("%v handler: invalid hash string", n.Method()) } // Rollback Utxo and Tx data stores. AcctMgr.Rollback(bdn.Height, hash) // Pass notification to frontends too. marshaled, _ := n.MarshalJSON() allClients <- marshaled return nil }
// NtfnBlockConnected handles btcd notifications resulting from newly // connected blocks to the main blockchain. // // TODO(jrick): Send block time with notification. This will be used // to mark wallet files with a possibly-better earliest block height, // and will greatly reduce rescan times for wallets created with an // out of sync btcd. func NtfnBlockConnected(n btcjson.Cmd) error { bcn, ok := n.(*btcws.BlockConnectedNtfn) if !ok { return fmt.Errorf("%v handler: unexpected type", n.Method()) } hash, err := btcwire.NewShaHashFromStr(bcn.Hash) if err != nil { return fmt.Errorf("%v handler: invalid hash string", n.Method()) } // Update the blockstamp for the newly-connected block. bs := &wallet.BlockStamp{ Height: bcn.Height, Hash: *hash, } curBlock.Lock() curBlock.BlockStamp = *bs curBlock.Unlock() // btcd notifies btcwallet about transactions first, and then sends // the new block notification. New balance notifications for txs // in blocks are therefore sent here after all tx notifications // have arrived and finished being processed by the handlers. workers := NotifyBalanceRequest{ block: *hash, wg: make(chan *sync.WaitGroup), } NotifyBalanceSyncerChans.access <- workers if wg := <-workers.wg; wg != nil { wg.Wait() NotifyBalanceSyncerChans.remove <- *hash } AcctMgr.BlockNotify(bs) // Pass notification to frontends too. marshaled, _ := n.MarshalJSON() allClients <- marshaled return nil }