Get address data for explorer using index v3 - WIP
parent
c67306ad09
commit
bbc47db6dd
|
@ -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"`
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue