Use a single handler (per wallet) for all tx notifications.
This commit is contained in:
parent
897fa1448b
commit
019df772b1
2 changed files with 132 additions and 112 deletions
42
cmd.go
42
cmd.go
|
@ -81,6 +81,7 @@ type BtcWallet struct {
|
|||
*wallet.Wallet
|
||||
mtx sync.RWMutex
|
||||
dirty bool
|
||||
NewBlockTxSeqN uint64
|
||||
UtxoStore struct {
|
||||
sync.RWMutex
|
||||
dirty bool
|
||||
|
@ -183,13 +184,35 @@ func OpenWallet(cfg *config, account string) (*BtcWallet, error) {
|
|||
}
|
||||
|
||||
func (w *BtcWallet) Track() {
|
||||
seq.Lock()
|
||||
n := seq.n
|
||||
seq.n++
|
||||
seq.Unlock()
|
||||
|
||||
// Use goroutines and a WaitGroup to prevent unnecessary waiting for
|
||||
// released locks.
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
wallets.Lock()
|
||||
name := w.Name()
|
||||
if wallets.m[name] == nil {
|
||||
wallets.m[name] = w
|
||||
}
|
||||
wallets.Unlock()
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
w.mtx.Lock()
|
||||
w.NewBlockTxSeqN = n
|
||||
w.mtx.Unlock()
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
replyHandlers.Lock()
|
||||
replyHandlers.m[n] = w.NewBlockTxHandler
|
||||
replyHandlers.Unlock()
|
||||
for _, addr := range w.GetActiveAddresses() {
|
||||
go w.ReqNewTxsForAddress(addr)
|
||||
}
|
||||
|
@ -231,10 +254,9 @@ func (w *BtcWallet) RescanForAddress(addr string, blocks ...int) {
|
|||
}
|
||||
|
||||
func (w *BtcWallet) ReqNewTxsForAddress(addr string) {
|
||||
seq.Lock()
|
||||
n := seq.n
|
||||
seq.n++
|
||||
seq.Unlock()
|
||||
w.mtx.RLock()
|
||||
n := w.NewBlockTxSeqN
|
||||
w.mtx.RUnlock()
|
||||
|
||||
m := &btcjson.Message{
|
||||
Jsonrpc: "1.0",
|
||||
|
@ -244,8 +266,10 @@ func (w *BtcWallet) ReqNewTxsForAddress(addr string) {
|
|||
}
|
||||
msg, _ := json.Marshal(m)
|
||||
|
||||
replyHandlers.Lock()
|
||||
replyHandlers.m[n] = func(result interface{}) bool {
|
||||
btcdMsgs <- msg
|
||||
}
|
||||
|
||||
func (w *BtcWallet) NewBlockTxHandler(result interface{}) bool {
|
||||
// TODO(jrick): btcd also sends the block hash in the reply.
|
||||
// Do we want it saved as well?
|
||||
v, ok := result.(map[string]interface{})
|
||||
|
@ -289,7 +313,7 @@ func (w *BtcWallet) ReqNewTxsForAddress(addr string) {
|
|||
return false
|
||||
}
|
||||
|
||||
// btcd sends the tx hashe as a BE string. Convert to a
|
||||
// btcd sends the tx hash as a BE string. Convert to a
|
||||
// LE ShaHash.
|
||||
txhash, err := btcwire.NewShaHashFromStr(txhashBE)
|
||||
if err != nil {
|
||||
|
@ -340,7 +364,3 @@ func (w *BtcWallet) ReqNewTxsForAddress(addr string) {
|
|||
// Never remove this handler.
|
||||
return false
|
||||
}
|
||||
replyHandlers.Unlock()
|
||||
|
||||
btcdMsgs <- msg
|
||||
}
|
||||
|
|
|
@ -319,7 +319,7 @@ func ListenAndServe() error {
|
|||
// requests for each channel in the set.
|
||||
go frontendListenerDuplicator()
|
||||
|
||||
// XXX(jrick): We need some sort of authentication before websocket
|
||||
// TODO(jrick): We need some sort of authentication before websocket
|
||||
// connections are allowed, and perhaps TLS on the server as well.
|
||||
http.Handle("/frontend", websocket.Handler(frontendReqsNotifications))
|
||||
if err := http.ListenAndServe(fmt.Sprintf(":%d", cfg.SvrPort), nil); err != nil {
|
||||
|
|
Loading…
Reference in a new issue