Get address data for explorer using index v3 - WIP

indexv3
Martin Boehm 2018-08-21 10:11:27 +02:00
parent c67306ad09
commit bbc47db6dd
4 changed files with 90 additions and 9 deletions

View File

@ -61,4 +61,7 @@ type Address struct {
UnconfirmedTxApperances int `json:"unconfirmedTxApperances"`
TxApperances int `json:"txApperances"`
Transactions []*Tx `json:"transactions"`
Page int `json:"page"`
TotalPages int `json:"totalPages"`
TxsOnPage int `json:"txsOnPage"`
}

View File

@ -4,13 +4,12 @@ import (
"blockbook/bchain"
"blockbook/common"
"blockbook/db"
"errors"
"math/big"
"github.com/golang/glog"
)
const txsOnPage = 30
// Worker is handle to api worker
type Worker struct {
db *db.RocksDB
@ -172,7 +171,83 @@ func UniqueTxidsInReverse(txids []string) []string {
}
// GetAddress computes address value and gets transactions for given address
func (w *Worker) GetAddress(addrID string, page int) (*Address, error) {
func (w *Worker) GetAddressNew(address string, page int, txsOnPage int) (*Address, error) {
glog.Info(address, " start")
ba, err := w.db.GetAddressBalance(address)
if err != nil {
return nil, err
}
if ba == nil {
return nil, errors.New("Address not found")
}
txc, err := w.getAddressTxids(address, false)
txc = UniqueTxidsInReverse(txc)
if err != nil {
return nil, err
}
txm, err := w.getAddressTxids(address, true)
if err != nil {
return nil, err
}
txm = UniqueTxidsInReverse(txm)
bestheight, _, err := w.db.GetBestBlock()
if err != nil {
return nil, err
}
// paging
if page < 0 {
page = 0
}
from := page * txsOnPage
totalPages := len(txc) / txsOnPage
if from >= len(txc) {
page = totalPages - 1
if page < 0 {
page = 0
}
}
from = page * txsOnPage
to := (page + 1) * txsOnPage
if to > len(txc) {
to = len(txc)
}
txs := make([]*Tx, len(txm)+to-from)
txi := 0
// load mempool transactions
var uBalSat big.Int
for _, tx := range txm {
tx, err := w.GetTransaction(tx, bestheight, false)
// mempool transaction may fail
if err != nil {
glog.Error("GetTransaction ", tx, ": ", err)
} else {
uBalSat.Sub(tx.getAddrVoutValue(address), tx.getAddrVinValue(address))
txs[txi] = tx
txi++
}
}
if len(txc) != int(ba.Txs) {
glog.Warning("DB inconsistency in address ", address, ": number of txs from column addresses ", len(txc), ", from addressBalance ", ba.Txs)
}
r := &Address{
AddrStr: address,
Balance: w.chainParser.AmountToDecimalString(&ba.BalanceSat),
TotalReceived: w.chainParser.AmountToDecimalString(ba.ReceivedSat()),
TotalSent: w.chainParser.AmountToDecimalString(&ba.SentSat),
TxApperances: len(txc),
UnconfirmedBalance: w.chainParser.AmountToDecimalString(&uBalSat),
UnconfirmedTxApperances: len(txm),
Page: page,
TotalPages: totalPages,
TxsOnPage: txsOnPage,
}
glog.Info(address, " finished")
return r, nil
}
// GetAddress computes address value and gets transactions for given address
func (w *Worker) GetAddress(addrID string, page int, txsOnPage int) (*Address, error) {
glog.Info(addrID, " start")
txc, err := w.getAddressTxids(addrID, false)
txc = UniqueTxidsInReverse(txc)

View File

@ -545,10 +545,10 @@ type AddrBalance struct {
BalanceSat big.Int
}
func (ab *AddrBalance) ReceivedSat() big.Int {
func (ab *AddrBalance) ReceivedSat() *big.Int {
var r big.Int
r.Add(&ab.BalanceSat, &ab.SentSat)
return r
return &r
}
type blockTxs struct {

View File

@ -18,8 +18,10 @@ import (
)
const blockbookAbout = "Blockbook - blockchain indexer for TREZOR wallet https://trezor.io/. Do not use for any other purpose."
const txsOnPage = 30
const txsInAPI = 1000
// PublicServer is handle to public http server
// PublicServer is a handle to public http server
type PublicServer struct {
binding string
certFiles string
@ -37,7 +39,7 @@ type PublicServer struct {
addressTpl *template.Template
}
// NewPublicServerS creates new public server http interface to blockbook and returns its handle
// NewPublicServer creates new public server http interface to blockbook and returns its handle
func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache, explorerURL string, metrics *common.Metrics, is *common.InternalState) (*PublicServer, error) {
api, err := api.NewWorker(db, chain, txCache, is)
@ -233,9 +235,10 @@ func (s *PublicServer) explorerAddress(w http.ResponseWriter, r *http.Request) {
page = 0
}
addrID := r.URL.Path[i+1:]
address, err = s.api.GetAddress(addrID, page)
address, err = s.api.GetAddress(addrID, page, txsOnPage)
if err != nil {
glog.Error(err)
// TODO return error.html
}
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
@ -351,7 +354,7 @@ func (s *PublicServer) apiAddress(w http.ResponseWriter, r *http.Request) {
page = 0
}
addrID := r.URL.Path[i+1:]
address, err = s.api.GetAddress(addrID, page)
address, err = s.api.GetAddress(addrID, page, txsInAPI)
if err != nil {
glog.Error(err)
}