Add paging to api.GetAddress, fix incorrect computation of balance
parent
880bac6d79
commit
f2274ce43c
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue