diff --git a/api/worker.go b/api/worker.go index 9d74b9bb..4ad421d3 100644 --- a/api/worker.go +++ b/api/worker.go @@ -8,6 +8,8 @@ import ( "github.com/golang/glog" ) +const txsOnPage = 30 + // Worker is handle to api worker type Worker struct { db *db.RocksDB @@ -151,10 +153,27 @@ func (t *Tx) getAddrVinValue(addrID string) float64 { return val } +// UniqueTxidsInReverse reverts the order of transactions (so that newest are first) and removes duplicate transactions +func UniqueTxidsInReverse(txids []string) []string { + i := len(txids) + ut := make([]string, i) + txidsMap := make(map[string]struct{}) + for _, txid := range txids { + _, e := txidsMap[txid] + if !e { + i-- + ut[i] = txid + txidsMap[txid] = struct{}{} + } + } + return ut[i:] +} + // GetAddress computes address value and gets transactions for given address -func (w *Worker) GetAddress(addrID string) (*Address, error) { +func (w *Worker) GetAddress(addrID string, page int) (*Address, error) { glog.Info(addrID, " start") txc, err := w.getAddressTxids(addrID, false) + txc = UniqueTxidsInReverse(txc) if err != nil { return nil, err } @@ -166,7 +185,11 @@ func (w *Worker) GetAddress(addrID string) (*Address, error) { if err != nil { return nil, err } - txs := make([]*Tx, len(txc)+len(txm)) + lc := len(txc) + if lc > txsOnPage { + lc = txsOnPage + } + txs := make([]*Tx, len(txm)+lc) txi := 0 var uBal, bal, totRecv, totSent float64 for _, tx := range txm { @@ -175,20 +198,30 @@ func (w *Worker) GetAddress(addrID string) (*Address, error) { if err != nil { glog.Error("GetTransaction ", tx, ": ", err) } else { - txs[txi] = tx uBal = tx.getAddrVoutValue(addrID) - tx.getAddrVinValue(addrID) + txs[txi] = tx txi++ } } - for i := len(txc) - 1; i >= 0; i-- { - tx, err := w.GetTransaction(txc[i], bestheight, false) + if page < 0 { + page = 0 + } + from := page * txsOnPage + if from > len(txc) { + from = 0 + } + to := from + txsOnPage + for i, tx := range txc { + tx, err := w.GetTransaction(tx, bestheight, false) if err != nil { return nil, err } else { - txs[txi] = tx totRecv += tx.getAddrVoutValue(addrID) totSent += tx.getAddrVinValue(addrID) - txi++ + if i >= from && i < to { + txs[txi] = tx + txi++ + } } } bal = totRecv - totSent diff --git a/server/public.go b/server/public.go index a78b66c8..54555325 100644 --- a/server/public.go +++ b/server/public.go @@ -226,8 +226,12 @@ func (s *PublicServer) explorerAddress(w http.ResponseWriter, r *http.Request) { var address *api.Address var err error if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 { + page, ec := strconv.Atoi(r.URL.Query().Get("page")) + if ec != nil { + page = 0 + } addrID := r.URL.Path[i+1:] - address, err = s.api.GetAddress(addrID) + address, err = s.api.GetAddress(addrID, page) if err != nil { glog.Error(err) } @@ -340,8 +344,12 @@ func (s *PublicServer) apiAddress(w http.ResponseWriter, r *http.Request) { var address *api.Address var err error if i := strings.LastIndexByte(r.URL.Path, '/'); i > 0 { + page, ec := strconv.Atoi(r.URL.Query().Get("page")) + if ec != nil { + page = 0 + } addrID := r.URL.Path[i+1:] - address, err = s.api.GetAddress(addrID) + address, err = s.api.GetAddress(addrID, page) if err != nil { glog.Error(err) } diff --git a/server/socketio.go b/server/socketio.go index e996d513..46c0a563 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -1,6 +1,7 @@ package server import ( + "blockbook/api" "blockbook/bchain" "blockbook/common" "blockbook/db" @@ -196,22 +197,6 @@ func unmarshalGetAddressRequest(params []byte) (addr []string, opts addrOpts, er return } -// bitcore returns txids from the newest to the oldest, we have to revert the order -func uniqueTxidsInReverse(txids []string) []string { - i := len(txids) - ut := make([]string, i) - txidsMap := make(map[string]struct{}) - for _, txid := range txids { - _, e := txidsMap[txid] - if !e { - i-- - ut[i] = txid - txidsMap[txid] = struct{}{} - } - } - return ut[i:] -} - type resultAddressTxids struct { Result []string `json:"result"` } @@ -236,7 +221,7 @@ func (s *SocketIoServer) getAddressTxids(addr []string, opts *addrOpts) (res res txids = append(txids, m...) } } - res.Result = uniqueTxidsInReverse(txids) + res.Result = api.UniqueTxidsInReverse(txids) return res, nil }