rpc: add paging to getnep5transfers call

And add some tests.
This commit is contained in:
Roman Khimov 2020-09-13 00:12:45 +03:00
parent c50ff7f20e
commit 970de84130
2 changed files with 225 additions and 81 deletions

View file

@ -545,24 +545,34 @@ func (s *Server) getNEP5Balances(ps request.Params) (interface{}, *response.Erro
return bs, nil
}
func getTimestampsAndLimit(ps request.Params, index int) (uint64, uint64, int, error) {
func getTimestampsAndLimit(ps request.Params, index int) (uint64, uint64, int, int, error) {
var start, end uint64
var limit int
pStart, pEnd, pLimit := ps.Value(index), ps.Value(index+1), ps.Value(index+2)
var limit, page int
pStart, pEnd, pLimit, pPage := ps.Value(index), ps.Value(index+1), ps.Value(index+2), ps.Value(index+3)
if pPage != nil {
p, err := pPage.GetInt()
if err != nil {
return 0, 0, 0, 0, err
}
if p < 0 {
return 0, 0, 0, 0, errors.New("can't use negative page")
}
page = p
}
if pLimit != nil {
l, err := pLimit.GetInt()
if err != nil {
return 0, 0, 0, err
return 0, 0, 0, 0, err
}
if l <= 0 {
return 0, 0, 0, errors.New("can't use negative or zero limit")
return 0, 0, 0, 0, errors.New("can't use negative or zero limit")
}
limit = l
}
if pEnd != nil {
val, err := pEnd.GetInt()
if err != nil {
return 0, 0, 0, err
return 0, 0, 0, 0, err
}
end = uint64(val)
} else {
@ -571,13 +581,13 @@ func getTimestampsAndLimit(ps request.Params, index int) (uint64, uint64, int, e
if pStart != nil {
val, err := pStart.GetInt()
if err != nil {
return 0, 0, 0, err
return 0, 0, 0, 0, err
}
start = uint64(val)
} else {
start = uint64(time.Now().Add(-time.Hour*24*7).Unix() * 1000)
}
return start, end, limit, nil
return start, end, limit, page, nil
}
func (s *Server) getNEP5Transfers(ps request.Params) (interface{}, *response.Error) {
@ -586,7 +596,7 @@ func (s *Server) getNEP5Transfers(ps request.Params) (interface{}, *response.Err
return nil, response.ErrInvalidParams
}
start, end, limit, err := getTimestampsAndLimit(ps, 1)
start, end, limit, page, err := getTimestampsAndLimit(ps, 1)
if err != nil {
return nil, response.NewInvalidParamsError(err.Error(), err)
}
@ -597,18 +607,29 @@ func (s *Server) getNEP5Transfers(ps request.Params) (interface{}, *response.Err
Sent: []result.NEP5Transfer{},
}
cache := make(map[int32]decimals)
var resCount, frameCount int
err = s.chain.ForEachNEP5Transfer(u, func(tr *state.NEP5Transfer) (bool, error) {
// Iterating from newest to oldest, not yet reached required
// time frame, continue looping.
if tr.Timestamp > end {
return true, nil
}
if tr.Timestamp < start ||
(limit != 0 && (len(bs.Received)+len(bs.Sent) >= limit)) {
// Iterating from newest to oldest, moved past required
// time frame, stop looping.
if tr.Timestamp < start {
return false, nil
}
frameCount++
// Using limits, not yet reached required page.
if limit != 0 && page*limit >= frameCount {
return true, nil
}
d, err := s.getDecimals(tr.Asset, cache)
if err != nil {
return false, err
}
transfer := result.NEP5Transfer{
Timestamp: tr.Timestamp,
Asset: d.Hash,
@ -621,14 +642,19 @@ func (s *Server) getNEP5Transfers(ps request.Params) (interface{}, *response.Err
transfer.Address = address.Uint160ToString(tr.From)
}
bs.Received = append(bs.Received, transfer)
return true, nil
} else {
transfer.Amount = amountToString(new(big.Int).Neg(&tr.Amount), d.Value)
if !tr.To.Equals(util.Uint160{}) {
transfer.Address = address.Uint160ToString(tr.To)
}
bs.Sent = append(bs.Sent, transfer)
}
transfer.Amount = amountToString(new(big.Int).Neg(&tr.Amount), d.Value)
if !tr.To.Equals(util.Uint160{}) {
transfer.Address = address.Uint160ToString(tr.To)
resCount++
// Using limits, reached limit.
if limit != 0 && resCount >= limit {
return false, nil
}
bs.Sent = append(bs.Sent, transfer)
return true, nil
})
if err != nil {