Skip to content

Commit

Permalink
Add paging to api.GetAddress, fix incorrect computation of balance
Browse files Browse the repository at this point in the history
  • Loading branch information
martinboehm committed Jul 20, 2018
1 parent 880bac6 commit f2274ce
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 26 deletions.
47 changes: 40 additions & 7 deletions api/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/golang/glog"
)

const txsOnPage = 30

// Worker is handle to api worker
type Worker struct {
db *db.RocksDB
Expand Down Expand Up @@ -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
}
Expand All @@ -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 {
Expand All @@ -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
Expand Down
12 changes: 10 additions & 2 deletions server/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down
19 changes: 2 additions & 17 deletions server/socketio.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package server

import (
"blockbook/api"
"blockbook/bchain"
"blockbook/common"
"blockbook/db"
Expand Down Expand Up @@ -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"`
}
Expand All @@ -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
}

Expand Down

0 comments on commit f2274ce

Please sign in to comment.