diff --git a/bchain/coins/btc/bitcoinparser.go b/bchain/coins/btc/bitcoinparser.go index 537e78d4..e148440a 100644 --- a/bchain/coins/btc/bitcoinparser.go +++ b/bchain/coins/btc/bitcoinparser.go @@ -126,7 +126,7 @@ func TryParseOPReturn(script []byte) string { return "" } -// outputScriptToAddresses converts ScriptPubKey to bitcoin addresses +// outputScriptToAddresses converts ScriptPubKey to addresses with a flag that the addresses are searchable func (p *BitcoinParser) outputScriptToAddresses(script []byte) ([]string, bool, error) { sc, addresses, _, err := txscript.ExtractPkScriptAddrs(script, p.Params) if err != nil { diff --git a/bchain/mempool_nonutxo.go b/bchain/mempool_nonutxo.go index 28485dab..c0151c50 100644 --- a/bchain/mempool_nonutxo.go +++ b/bchain/mempool_nonutxo.go @@ -83,8 +83,8 @@ func (m *NonUTXOMempool) Resync(onNewTxAddr OnNewTxAddrFunc) (int, error) { if len(addrDesc) > 0 { io = append(io, addrIndex{string(addrDesc), int32(output.N)}) } - if onNewTxAddr != nil && len(output.ScriptPubKey.Addresses) == 1 { - onNewTxAddr(tx.Txid, output.ScriptPubKey.Addresses[0], true) + if onNewTxAddr != nil { + onNewTxAddr(tx.Txid, addrDesc, true) } } for _, input := range tx.Vin { @@ -97,7 +97,7 @@ func (m *NonUTXOMempool) Resync(onNewTxAddr OnNewTxAddrFunc) (int, error) { } io = append(io, addrIndex{string(addrDesc), int32(^i)}) if onNewTxAddr != nil { - onNewTxAddr(tx.Txid, a, false) + onNewTxAddr(tx.Txid, addrDesc, false) } } } diff --git a/bchain/mempool_utxo.go b/bchain/mempool_utxo.go index 54017e00..86fe6a5e 100644 --- a/bchain/mempool_utxo.go +++ b/bchain/mempool_utxo.go @@ -132,8 +132,8 @@ func (m *UTXOMempool) getTxAddrs(txid string, chanInput chan outpoint, chanResul if len(addrDesc) > 0 { io = append(io, addrIndex{string(addrDesc), int32(output.N)}) } - if m.onNewTxAddr != nil && len(output.ScriptPubKey.Addresses) == 1 { - m.onNewTxAddr(tx.Txid, output.ScriptPubKey.Addresses[0], true) + if m.onNewTxAddr != nil { + m.onNewTxAddr(tx.Txid, addrDesc, true) } } dispatched := 0 diff --git a/bchain/types.go b/bchain/types.go index 4728a4bf..d7177a6f 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -144,7 +144,7 @@ func (ad AddressDescriptor) String() string { type OnNewBlockFunc func(hash string, height uint32) // OnNewTxAddrFunc is used to send notification about a new transaction/address -type OnNewTxAddrFunc func(txid string, addr string, isOutput bool) +type OnNewTxAddrFunc func(txid string, desc AddressDescriptor, isOutput bool) // BlockChain defines common interface to block chain daemon type BlockChain interface { diff --git a/blockbook.go b/blockbook.go index 8bd998d9..1c4df0b1 100644 --- a/blockbook.go +++ b/blockbook.go @@ -495,9 +495,9 @@ func storeInternalStateLoop() { glog.Info("storeInternalStateLoop stopped") } -func onNewTxAddr(txid string, addr string, isOutput bool) { +func onNewTxAddr(txid string, desc bchain.AddressDescriptor, isOutput bool) { for _, c := range callbacksOnNewTxAddr { - c(txid, addr, isOutput) + c(txid, desc, isOutput) } } diff --git a/server/public.go b/server/public.go index b39aa796..4a7cb432 100644 --- a/server/public.go +++ b/server/public.go @@ -148,8 +148,8 @@ func (s *PublicServer) OnNewBlock(hash string, height uint32) { } // OnNewTxAddr notifies users subscribed to bitcoind/addresstxid about new block -func (s *PublicServer) OnNewTxAddr(txid string, addr string, isOutput bool) { - s.socketio.OnNewTxAddr(txid, addr, isOutput) +func (s *PublicServer) OnNewTxAddr(txid string, desc bchain.AddressDescriptor, isOutput bool) { + s.socketio.OnNewTxAddr(txid, desc, isOutput) } func (s *PublicServer) txRedirect(w http.ResponseWriter, r *http.Request) { diff --git a/server/socketio.go b/server/socketio.go index 2e931d1f..c4242e9b 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -726,8 +726,18 @@ func (s *SocketIoServer) onSubscribe(c *gosocketio.Channel, req []byte) interfac onError(c.Id(), sc, "invalid data", err.Error()+", req: "+r) return nil } - for _, a := range addrs { - c.Join("bitcoind/addresstxid-" + a) + // normalize the addresses to AddressDescriptor + descs := make([]bchain.AddressDescriptor, len(addrs)) + for i, a := range addrs { + d, err := s.chainParser.GetAddrDescFromAddress(a) + if err != nil { + onError(c.Id(), sc, "invalid address "+a, err.Error()+", req: "+r) + return nil + } + descs[i] = d + } + for _, d := range descs { + c.Join("bitcoind/addresstxid-" + string(d)) } } else { sc = r[1 : len(r)-1] @@ -748,13 +758,18 @@ func (s *SocketIoServer) OnNewBlockHash(hash string) { } // OnNewTxAddr notifies users subscribed to bitcoind/addresstxid about new block -func (s *SocketIoServer) OnNewTxAddr(txid string, addr string, isOutput bool) { - data := map[string]interface{}{"address": addr, "txid": txid} - if !isOutput { - data["input"] = true - } - c := s.server.BroadcastTo("bitcoind/addresstxid-"+addr, "bitcoind/addresstxid", data) - if c > 0 { - glog.Info("broadcasting new txid ", txid, " for addr ", addr, " to ", c, " channels") +func (s *SocketIoServer) OnNewTxAddr(txid string, desc bchain.AddressDescriptor, isOutput bool) { + addr, searchable, err := s.chainParser.GetAddressesFromAddrDesc(desc) + if err != nil { + glog.Error("GetAddressesFromAddrDesc error ", err, " for descriptor ", desc) + } else if searchable && len(addr) == 1 { + data := map[string]interface{}{"address": addr[0], "txid": txid} + if !isOutput { + data["input"] = true + } + c := s.server.BroadcastTo("bitcoind/addresstxid-"+string(desc), "bitcoind/addresstxid", data) + if c > 0 { + glog.Info("broadcasting new txid ", txid, " for addr ", addr[0], " to ", c, " channels") + } } }