From c6cba802cd597f76ddd914609f51fd72cbf3e31a Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Tue, 6 Feb 2018 23:50:53 +0100 Subject: [PATCH] Implement Bitcore socket.io method getAddressTxids --- server/socketio.go | 105 +++++++++++++++++++++++++++++++++++++--- server/static/test.html | 23 ++++++++- 2 files changed, 121 insertions(+), 7 deletions(-) diff --git a/server/socketio.go b/server/socketio.go index e8037c1d..7940991f 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -4,6 +4,8 @@ import ( "blockbook/bchain" "blockbook/db" "context" + "encoding/json" + "errors" "net/http" "strings" @@ -27,23 +29,21 @@ func NewSocketIoServer(binding string, db *db.RocksDB, mempool *bchain.Mempool) server.On(gosocketio.OnConnection, func(c *gosocketio.Channel) { glog.Info("Client connected ", c.Id()) - c.Join("chat") }) server.On(gosocketio.OnDisconnection, func(c *gosocketio.Channel) { glog.Info("Client disconnected ", c.Id()) }) + server.On(gosocketio.OnError, func(c *gosocketio.Channel) { + glog.Info("Client error ", c.Id()) + }) + type Message struct { Name string `json:"name"` Message string `json:"message"` } - server.On("send", func(c *gosocketio.Channel, msg Message) string { - c.BroadcastTo("chat", "message", msg) - return "OK" - }) - addr, path := splitBinding(binding) serveMux := http.NewServeMux() serveMux.Handle(path, server) @@ -59,6 +59,14 @@ func NewSocketIoServer(binding string, db *db.RocksDB, mempool *bchain.Mempool) db: db, mempool: mempool, } + + server.On("message", s.onMessage) + + server.On("send", func(c *gosocketio.Channel, msg Message) string { + glog.Info(c.Id(), "; ", msg) + return "OK" + }) + return s, nil } @@ -87,3 +95,88 @@ func (s *SocketIoServer) Shutdown(ctx context.Context) error { glog.Infof("socketio server shutdown") return s.https.Shutdown(ctx) } + +type reqRange struct { + Start int `json:"start"` + End int `json:"end"` + QueryMempol bool `json:"queryMempol"` + QueryMempoolOnly bool `json:"queryMempoolOnly"` + From int `json:"from"` + To int `json:"to"` +} + +func (s *SocketIoServer) onMessage(c *gosocketio.Channel, req map[string]json.RawMessage) string { + var err error + var rv []byte + var rvi interface{} + method := string(req["method"]) + params := req["params"] + if method == "\"getAddressTxids\"" { + addr, rr, err := unmarshalGetAddressTxids(params) + if err == nil { + rvi, err = s.getAddressTxids(addr, &rr) + } + } else { + err = errors.New("unknown method") + } + if err == nil { + rv, err = json.Marshal(rvi) + } + if err == nil { + glog.Info(c.Id(), " ", method, " success, returning ", len(rv), " bytes") + return string(rv) + } + glog.Error(c.Id(), " ", method, ": ", err) + return "" +} + +func unmarshalGetAddressTxids(params []byte) (addr []string, rr reqRange, err error) { + var p []json.RawMessage + err = json.Unmarshal(params, &p) + if err != nil { + return + } + err = json.Unmarshal(p[0], &addr) + if err != nil { + return + } + err = json.Unmarshal(p[1], &rr) + return +} + +func (s *SocketIoServer) getAddressTxids(addr []string, rr *reqRange) ([]string, error) { + var txids []string + lower, higher := uint32(rr.To), uint32(rr.Start) + for _, address := range addr { + script, err := bchain.AddressToOutputScript(address) + if err != nil { + return nil, err + } + if !rr.QueryMempoolOnly { + err = s.db.GetTransactions(script, lower, higher, func(txid string, vout uint32, isOutput bool) error { + txids = append(txids, txid) + if isOutput && rr.QueryMempol { + input := s.mempool.GetInput(txid, vout) + if input != "" { + txids = append(txids, txid) + } + } + return nil + }) + if err != nil { + return nil, err + } + } + if rr.QueryMempoolOnly || rr.QueryMempol { + mtxids, err := s.mempool.GetTransactions(script) + if err != nil { + return nil, err + } + txids = append(txids, mtxids...) + } + if err != nil { + return nil, err + } + } + return txids, nil +} diff --git a/server/static/test.html b/server/static/test.html index da2bb2eb..74a3c44c 100644 --- a/server/static/test.html +++ b/server/static/test.html @@ -25,10 +25,31 @@ }); socket.on('connect', function () { console.log('socket connected'); - socket.emit('send', { name: "my name", message: "hello" }, function (result) { + + lookupTransactionsIdsMempool(["2MxvKTW83yhVsGCr4BSRqmhca7r8TB2dgW8", "bc1qrsf2l34jvqnq0lduyz0j5pfu2nkd93nnq0qggn"], false, 2000000, 0, function (result) { console.log('sent successfully'); console.log(result); }); }); + + function lookupTransactionsIdsMempool(addresses, mempool, start, end, f) { + const method = 'getAddressTxids'; + const rangeParam = mempool ? { + start, + end, + queryMempoolOnly: true, + } : { + start, + end, + queryMempol: false, + }; + const params = [ + addresses, + rangeParam, + ]; + return socket.send({ method, params }, f); + } + + \ No newline at end of file