Add pagination (#6452)

* Add pagination types and helper func

* Update API

* Add pagination to queryBalance

* Add QueryBalance to use Paginate

* Update GetAllBalances usage

* Add tests for QueryAllBalances

* Fix bank get balance querier tests

* Add pagination test setup

* revert simapp changes

* Fix pagenation tests

* Add more tests for pagination

* Add offset nullable

* Add more tests

* Fix paginate for offset

* Add grpc queryconn for query

* Fix paginate

* Fix maxlimit

* Fix queryClient

* Fix pagination tests

* refacor

* Fix grpc tests

* Revert

* review changes

* Fix lint

* Update types/query/pagination.go

* Fix review suggestions

* Remove maxLimit and use defaultLimit

* change example paginate as a testable fun

* Fix review comments

* Merge master

* Add bank query.pb.go

* Add missing import

* Add pageReq to queryBalance

* Add example for pagenate

* Fix cli tests

* Remove example for pagination

* Update paginate example

Co-authored-by: Aaron Craelius <aaronc@users.noreply.github.com>
Co-authored-by: Aaron Craelius <aaron@regen.network>
Co-authored-by: anilCSE <anil@vitwit.com>
Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
SaReN
2020-06-20 23:44:04 +00:00
committed by GitHub
co-authored by Aaron Craelius Aaron Craelius anilCSE Federico Kunze
parent 231ae6eaff
commit 4b0c66982a
15 changed files with 1251 additions and 47 deletions
+6 -1
View File
@@ -1,6 +1,7 @@
syntax = "proto3";
package cosmos.bank;
import "cosmos/query/pagination.proto";
import "gogoproto/gogo.proto";
import "cosmos/cosmos.proto";
@@ -41,16 +42,20 @@ message QueryBalanceResponse {
message QueryAllBalancesRequest {
// address is the address to query balances for
bytes address = 1 [(gogoproto.casttype) = "github.com/cosmos/cosmos-sdk/types.AccAddress"];
cosmos.query.PageRequest req = 2;
}
// QueryAllBalancesResponse is the response type for the Query/AllBalances RPC method
message QueryAllBalancesResponse {
// balances is the balances of the coins
repeated cosmos.Coin balances = 1 [(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
cosmos.query.PageResponse res = 2;
}
// QueryTotalSupplyRequest is the request type for the Query/TotalSupply RPC method
message QueryTotalSupplyRequest { }
message QueryTotalSupplyRequest {}
// QueryTotalSupplyResponse is the response type for the Query/TotalSupply RPC method
message QueryTotalSupplyResponse {
+49
View File
@@ -0,0 +1,49 @@
syntax = "proto3";
package cosmos.query;
option go_package = "github.com/cosmos/cosmos-sdk/types/query";
// PageRequest is to be embedded in gRPC request messages for efficient
// pagination. Ex:
//
// message SomeRequest {
// Foo some_parameter = 1;
// PageRequest page = 2;
// }
message PageRequest {
// key is a value returned in PageResponse.next_key to begin
// querying the next page most efficiently. Only one of offset or key
// should be set.
bytes key = 1;
// offset is a numeric offset that can be used when key is unavailable.
// It is less efficient than using key. Only one of offset or key should
// be set.
uint64 offset = 2;
// limit is the total number of results to be returned in the result page.
// If left empty it will default to a value to be set by each app.
uint64 limit = 3;
// count_total is set to true to indicate that the result set should include
// a count of the total number of items available for pagination in UIs. count_total
// is only respected when offset is used. It is ignored when key is set.
bool count_total = 4;
}
// PageResponse is to be embedded in gRPC response messages where the corresponding
// request message has used PageRequest
//
// message SomeResponse {
// repeated Bar results = 1;
// PageResponse page = 2;
// }
message PageResponse {
// next_key is the key to be passed to PageRequest.key to
// query the next page most efficiently
bytes next_key = 1;
// total is total number of results available if PageRequest.count_total
// was set, its value is undefined otherwise
uint64 total = 2;
}
+93
View File
@@ -0,0 +1,93 @@
package query
import (
"fmt"
"github.com/cosmos/cosmos-sdk/store/types"
)
// defaultLimit is the default `limit` for queries
// if the `limit` is not supplied, paginate will use `defaultLimit`
const defaultLimit = 100
// Paginate does pagination of all the results in the PrefixStore based on the
// provided PageRequest. onResult should be used to do actual unmarshaling.
func Paginate(
prefixStore types.KVStore,
req *PageRequest,
onResult func(key []byte, value []byte) error,
) (*PageResponse, error) {
offset := req.Offset
key := req.Key
limit := req.Limit
countTotal := req.CountTotal
if offset > 0 && key != nil {
return nil, fmt.Errorf("invalid request, either offset or key is expected, got both")
}
if limit == 0 {
limit = defaultLimit
// count total results when the limit is zero/not supplied
countTotal = true
}
if len(key) != 0 {
iterator := prefixStore.Iterator(key, nil)
defer iterator.Close()
var count uint64
var nextKey []byte
for ; iterator.Valid(); iterator.Next() {
if count == limit {
nextKey = iterator.Key()
break
}
err := onResult(iterator.Key(), iterator.Value())
if err != nil {
return nil, err
}
count++
}
return &PageResponse{
NextKey: nextKey,
}, nil
}
iterator := prefixStore.Iterator(nil, nil)
defer iterator.Close()
end := offset + limit
var count uint64
var nextKey []byte
for ; iterator.Valid(); iterator.Next() {
count++
if count <= offset {
continue
}
if count <= end {
err := onResult(iterator.Key(), iterator.Value())
if err != nil {
return nil, err
}
} else if !countTotal {
nextKey = iterator.Key()
break
}
}
res := &PageResponse{NextKey: nextKey}
if countTotal {
res.Total = count
}
return res, nil
}
+675
View File
@@ -0,0 +1,675 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/query/pagination.proto
package query
import (
fmt "fmt"
proto "github.com/gogo/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
// PageRequest is to be embedded in gRPC request messages for efficient
// pagination. Ex:
//
// message SomeRequest {
// Foo some_parameter = 1;
// PageRequest page = 2;
// }
type PageRequest struct {
// key is a value returned in PageResponse.next_key to begin
// querying the next page most efficiently. Only one of offset or key
// should be set.
Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
// offset is a numeric offset that can be used when key is unavailable.
// It is less efficient than using key. Only one of offset or key should
// be set.
Offset uint64 `protobuf:"varint,2,opt,name=offset,proto3" json:"offset,omitempty"`
// limit is the total number of results to be returned in the result page.
// If left empty it will default to a value to be set by each app.
Limit uint64 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"`
// count_total is set to true to indicate that the result set should include
// a count of the total number of items available for pagination in UIs. count_total
// is only respected when offset is used. It is ignored when key is set.
CountTotal bool `protobuf:"varint,4,opt,name=count_total,json=countTotal,proto3" json:"count_total,omitempty"`
}
func (m *PageRequest) Reset() { *m = PageRequest{} }
func (m *PageRequest) String() string { return proto.CompactTextString(m) }
func (*PageRequest) ProtoMessage() {}
func (*PageRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_4353dcf7b0208338, []int{0}
}
func (m *PageRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PageRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PageRequest.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *PageRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_PageRequest.Merge(m, src)
}
func (m *PageRequest) XXX_Size() int {
return m.Size()
}
func (m *PageRequest) XXX_DiscardUnknown() {
xxx_messageInfo_PageRequest.DiscardUnknown(m)
}
var xxx_messageInfo_PageRequest proto.InternalMessageInfo
func (m *PageRequest) GetKey() []byte {
if m != nil {
return m.Key
}
return nil
}
func (m *PageRequest) GetOffset() uint64 {
if m != nil {
return m.Offset
}
return 0
}
func (m *PageRequest) GetLimit() uint64 {
if m != nil {
return m.Limit
}
return 0
}
func (m *PageRequest) GetCountTotal() bool {
if m != nil {
return m.CountTotal
}
return false
}
// PageResponse is to be embedded in gRPC response messages where the corresponding
// request message has used PageRequest
//
// message SomeResponse {
// repeated Bar results = 1;
// PageResponse page = 2;
// }
type PageResponse struct {
// next_key is the key to be passed to PageRequest.key to
// query the next page most efficiently
NextKey []byte `protobuf:"bytes,1,opt,name=next_key,json=nextKey,proto3" json:"next_key,omitempty"`
// total is total number of results available if PageRequest.count_total
// was set, its value is undefined otherwise
Total uint64 `protobuf:"varint,2,opt,name=total,proto3" json:"total,omitempty"`
}
func (m *PageResponse) Reset() { *m = PageResponse{} }
func (m *PageResponse) String() string { return proto.CompactTextString(m) }
func (*PageResponse) ProtoMessage() {}
func (*PageResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_4353dcf7b0208338, []int{1}
}
func (m *PageResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *PageResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_PageResponse.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *PageResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_PageResponse.Merge(m, src)
}
func (m *PageResponse) XXX_Size() int {
return m.Size()
}
func (m *PageResponse) XXX_DiscardUnknown() {
xxx_messageInfo_PageResponse.DiscardUnknown(m)
}
var xxx_messageInfo_PageResponse proto.InternalMessageInfo
func (m *PageResponse) GetNextKey() []byte {
if m != nil {
return m.NextKey
}
return nil
}
func (m *PageResponse) GetTotal() uint64 {
if m != nil {
return m.Total
}
return 0
}
func init() {
proto.RegisterType((*PageRequest)(nil), "cosmos.query.PageRequest")
proto.RegisterType((*PageResponse)(nil), "cosmos.query.PageResponse")
}
func init() { proto.RegisterFile("cosmos/query/pagination.proto", fileDescriptor_4353dcf7b0208338) }
var fileDescriptor_4353dcf7b0208338 = []byte{
// 251 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x44, 0x90, 0xc1, 0x4a, 0xc3, 0x40,
0x10, 0x86, 0xb3, 0xb6, 0xd6, 0x32, 0xcd, 0x41, 0x16, 0x91, 0x78, 0x70, 0x0d, 0x3d, 0xe5, 0x62,
0x72, 0xf0, 0x01, 0x84, 0x5e, 0xbd, 0x48, 0xf0, 0xe4, 0xa5, 0xa4, 0x71, 0x1a, 0x97, 0x36, 0x3b,
0x69, 0x77, 0x02, 0xe6, 0x2d, 0x7c, 0x2c, 0x8f, 0x3d, 0x7a, 0x94, 0xe4, 0x45, 0x24, 0xd9, 0x40,
0x4f, 0xbb, 0xdf, 0xff, 0xc3, 0x7c, 0xf0, 0xc3, 0x7d, 0x4e, 0xb6, 0x24, 0x9b, 0x1c, 0x6a, 0x3c,
0x36, 0x49, 0x95, 0x15, 0xda, 0x64, 0xac, 0xc9, 0xc4, 0xd5, 0x91, 0x98, 0xa4, 0xef, 0xea, 0x78,
0xa8, 0x97, 0x06, 0x16, 0xaf, 0x59, 0x81, 0x29, 0x1e, 0x6a, 0xb4, 0x2c, 0xaf, 0x61, 0xb2, 0xc3,
0x26, 0x10, 0xa1, 0x88, 0xfc, 0xb4, 0xff, 0xca, 0x5b, 0x98, 0xd1, 0x76, 0x6b, 0x91, 0x83, 0x8b,
0x50, 0x44, 0xd3, 0x74, 0x24, 0x79, 0x03, 0x97, 0x7b, 0x5d, 0x6a, 0x0e, 0x26, 0x43, 0xec, 0x40,
0x3e, 0xc0, 0x22, 0xa7, 0xda, 0xf0, 0x9a, 0x89, 0xb3, 0x7d, 0x30, 0x0d, 0x45, 0x34, 0x4f, 0x61,
0x88, 0xde, 0xfa, 0x64, 0xf9, 0x0c, 0xbe, 0xf3, 0xd9, 0x8a, 0x8c, 0x45, 0x79, 0x07, 0x73, 0x83,
0x5f, 0xbc, 0x3e, 0x5b, 0xaf, 0x7a, 0x7e, 0xc1, 0xa6, 0x37, 0xb8, 0x2b, 0x4e, 0xec, 0x60, 0xb5,
0xfa, 0x69, 0x95, 0x38, 0xb5, 0x4a, 0xfc, 0xb5, 0x4a, 0x7c, 0x77, 0xca, 0x3b, 0x75, 0xca, 0xfb,
0xed, 0x94, 0xf7, 0x1e, 0x15, 0x9a, 0x3f, 0xeb, 0x4d, 0x9c, 0x53, 0x99, 0x8c, 0x13, 0xb8, 0xe7,
0xd1, 0x7e, 0xec, 0x12, 0x6e, 0x2a, 0x1c, 0x37, 0xd9, 0xcc, 0x86, 0x25, 0x9e, 0xfe, 0x03, 0x00,
0x00, 0xff, 0xff, 0xe5, 0x66, 0x0a, 0x76, 0x2a, 0x01, 0x00, 0x00,
}
func (m *PageRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *PageRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PageRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.CountTotal {
i--
if m.CountTotal {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x20
}
if m.Limit != 0 {
i = encodeVarintPagination(dAtA, i, uint64(m.Limit))
i--
dAtA[i] = 0x18
}
if m.Offset != 0 {
i = encodeVarintPagination(dAtA, i, uint64(m.Offset))
i--
dAtA[i] = 0x10
}
if len(m.Key) > 0 {
i -= len(m.Key)
copy(dAtA[i:], m.Key)
i = encodeVarintPagination(dAtA, i, uint64(len(m.Key)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *PageResponse) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *PageResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *PageResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.Total != 0 {
i = encodeVarintPagination(dAtA, i, uint64(m.Total))
i--
dAtA[i] = 0x10
}
if len(m.NextKey) > 0 {
i -= len(m.NextKey)
copy(dAtA[i:], m.NextKey)
i = encodeVarintPagination(dAtA, i, uint64(len(m.NextKey)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func encodeVarintPagination(dAtA []byte, offset int, v uint64) int {
offset -= sovPagination(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *PageRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Key)
if l > 0 {
n += 1 + l + sovPagination(uint64(l))
}
if m.Offset != 0 {
n += 1 + sovPagination(uint64(m.Offset))
}
if m.Limit != 0 {
n += 1 + sovPagination(uint64(m.Limit))
}
if m.CountTotal {
n += 2
}
return n
}
func (m *PageResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.NextKey)
if l > 0 {
n += 1 + l + sovPagination(uint64(l))
}
if m.Total != 0 {
n += 1 + sovPagination(uint64(m.Total))
}
return n
}
func sovPagination(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozPagination(x uint64) (n int) {
return sovPagination(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *PageRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPagination
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: PageRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PageRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPagination
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthPagination
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthPagination
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...)
if m.Key == nil {
m.Key = []byte{}
}
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType)
}
m.Offset = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPagination
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Offset |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType)
}
m.Limit = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPagination
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Limit |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CountTotal", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPagination
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.CountTotal = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := skipPagination(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPagination
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthPagination
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *PageResponse) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPagination
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: PageResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: PageResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field NextKey", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPagination
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthPagination
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthPagination
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.NextKey = append(m.NextKey[:0], dAtA[iNdEx:postIndex]...)
if m.NextKey == nil {
m.NextKey = []byte{}
}
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Total", wireType)
}
m.Total = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowPagination
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Total |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipPagination(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthPagination
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthPagination
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipPagination(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPagination
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPagination
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowPagination
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthPagination
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupPagination
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthPagination
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthPagination = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowPagination = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupPagination = fmt.Errorf("proto: unexpected end of group")
)
+213
View File
@@ -0,0 +1,213 @@
package query_test
import (
gocontext "context"
"fmt"
"testing"
"github.com/cosmos/cosmos-sdk/store/prefix"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
)
const (
holder = "holder"
multiPerm = "multiple permissions account"
randomPerm = "random permission"
numBalances = 235
defaultLimit = 100
overLimit = 101
underLimit = 10
lastPageRecords = 35
)
func TestPagination(t *testing.T) {
app, ctx := setupTest()
queryHelper := baseapp.NewQueryServerTestHelper(ctx)
types.RegisterQueryServer(queryHelper, app.BankKeeper)
queryClient := types.NewQueryClient(queryHelper)
var balances sdk.Coins
for i := 0; i < numBalances; i++ {
denom := fmt.Sprintf("foo%ddenom", i)
balances = append(balances, sdk.NewInt64Coin(denom, 100))
}
addr1 := sdk.AccAddress([]byte("addr1"))
acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
app.AccountKeeper.SetAccount(ctx, acc1)
require.NoError(t, app.BankKeeper.SetBalances(ctx, addr1, balances))
t.Log("verify empty page request results a max of defaultLimit records and counts total records")
pageReq := &query.PageRequest{}
request := types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err := queryClient.AllBalances(gocontext.Background(), request)
require.NoError(t, err)
require.Equal(t, res.Res.Total, uint64(numBalances))
require.Nil(t, res.Res.NextKey)
require.LessOrEqual(t, res.Balances.Len(), defaultLimit)
t.Log("verify page request with limit > defaultLimit, returns less or equal to `limit` records")
pageReq = &query.PageRequest{Limit: overLimit}
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), request)
require.NoError(t, err)
require.Equal(t, res.Res.Total, uint64(0))
require.NotNil(t, res.Res.NextKey)
require.LessOrEqual(t, res.Balances.Len(), overLimit)
t.Log("verify paginate with custom limit and countTotal true")
pageReq = &query.PageRequest{Limit: underLimit, CountTotal: true}
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), request)
require.NoError(t, err)
require.Equal(t, res.Balances.Len(), underLimit)
require.Nil(t, res.Res.NextKey)
require.Equal(t, res.Res.Total, uint64(numBalances))
t.Log("verify paginate with custom limit and countTotal false")
pageReq = &query.PageRequest{Limit: defaultLimit, CountTotal: false}
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), request)
require.NoError(t, err)
require.Equal(t, res.Balances.Len(), defaultLimit)
require.NotNil(t, res.Res.NextKey)
require.Equal(t, res.Res.Total, uint64(0))
t.Log("verify paginate with custom limit, key and countTotal false")
pageReq = &query.PageRequest{Key: res.Res.NextKey, Limit: defaultLimit, CountTotal: false}
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), request)
require.NoError(t, err)
require.Equal(t, res.Balances.Len(), defaultLimit)
require.NotNil(t, res.Res.NextKey)
require.Equal(t, res.Res.Total, uint64(0))
t.Log("verify paginate for last page, results in records less than max limit")
pageReq = &query.PageRequest{Key: res.Res.NextKey, Limit: defaultLimit, CountTotal: false}
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), request)
require.NoError(t, err)
require.LessOrEqual(t, res.Balances.Len(), defaultLimit)
require.Equal(t, res.Balances.Len(), lastPageRecords)
require.Nil(t, res.Res.NextKey)
require.Equal(t, res.Res.Total, uint64(0))
t.Log("verify paginate with offset and limit")
pageReq = &query.PageRequest{Offset: 200, Limit: defaultLimit, CountTotal: false}
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), request)
require.NoError(t, err)
require.LessOrEqual(t, res.Balances.Len(), defaultLimit)
require.Equal(t, res.Balances.Len(), lastPageRecords)
require.Nil(t, res.Res.NextKey)
require.Equal(t, res.Res.Total, uint64(0))
t.Log("verify paginate with offset and limit")
pageReq = &query.PageRequest{Offset: 100, Limit: defaultLimit, CountTotal: false}
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), request)
require.NoError(t, err)
require.LessOrEqual(t, res.Balances.Len(), defaultLimit)
require.NotNil(t, res.Res.NextKey)
require.Equal(t, res.Res.Total, uint64(0))
t.Log("verify paginate with offset and key - error")
pageReq = &query.PageRequest{Key: res.Res.NextKey, Offset: 100, Limit: defaultLimit, CountTotal: false}
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), request)
require.Error(t, err)
require.Equal(t, err.Error(), "invalid request, either offset or key is expected, got both")
t.Log("verify paginate with offset greater than total results")
pageReq = &query.PageRequest{Offset: 300, Limit: defaultLimit, CountTotal: false}
request = types.NewQueryAllBalancesRequest(addr1, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), request)
require.NoError(t, err)
require.LessOrEqual(t, res.Balances.Len(), 0)
require.Nil(t, res.Res.NextKey)
}
func ExamplePaginate() {
app, ctx := setupTest()
var balances sdk.Coins
for i := 0; i < 2; i++ {
denom := fmt.Sprintf("foo%ddenom", i)
balances = append(balances, sdk.NewInt64Coin(denom, 100))
}
addr1 := sdk.AccAddress([]byte("addr1"))
acc1 := app.AccountKeeper.NewAccountWithAddress(ctx, addr1)
app.AccountKeeper.SetAccount(ctx, acc1)
err := app.BankKeeper.SetBalances(ctx, addr1, balances)
if err != nil {
fmt.Println(err)
}
// Paginate example
pageReq := &query.PageRequest{Key: nil, Limit: 1, CountTotal: true}
request := types.NewQueryAllBalancesRequest(addr1, pageReq)
balResult := sdk.NewCoins()
authStore := ctx.KVStore(app.GetKey(authtypes.StoreKey))
balancesStore := prefix.NewStore(authStore, types.BalancesPrefix)
accountStore := prefix.NewStore(balancesStore, addr1.Bytes())
res, err := query.Paginate(accountStore, request.Req, func(key []byte, value []byte) error {
var tempRes sdk.Coin
err := app.Codec().UnmarshalBinaryBare(value, &tempRes)
if err != nil {
return err
}
balResult = append(balResult, tempRes)
return nil
})
if err != nil { // should return no error
fmt.Println(err)
}
fmt.Println(&types.QueryAllBalancesResponse{Balances: balResult, Res: res})
// Output:
// balances:<denom:"foo0denom" amount:"100" > res:<total:2 >
}
func setupTest() (*simapp.SimApp, sdk.Context) {
app := simapp.Setup(false)
ctx := app.BaseApp.NewContext(false, abci.Header{Height: 1})
appCodec := app.AppCodec()
db := dbm.NewMemDB()
ms := store.NewCommitMultiStore(db)
ms.LoadLatestVersion()
maccPerms := simapp.GetMaccPerms()
maccPerms[holder] = nil
maccPerms[authtypes.Burner] = []string{authtypes.Burner}
maccPerms[authtypes.Minter] = []string{authtypes.Minter}
maccPerms[multiPerm] = []string{authtypes.Burner, authtypes.Minter, authtypes.Staking}
maccPerms[randomPerm] = []string{"random"}
app.AccountKeeper = authkeeper.NewAccountKeeper(
appCodec, app.GetKey(authtypes.StoreKey), app.GetSubspace(authtypes.ModuleName),
authtypes.ProtoBaseAccount, maccPerms,
)
app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec, app.GetKey(authtypes.StoreKey), app.AccountKeeper,
app.GetSubspace(types.ModuleName), make(map[string]bool),
)
return app, ctx
}
+3 -3
View File
@@ -11,6 +11,7 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/bank/types"
)
@@ -50,9 +51,9 @@ func GetBalancesCmd(clientCtx client.Context) *cobra.Command {
}
denom := viper.GetString(flagDenom)
pageReq := &query.PageRequest{}
if denom == "" {
params := types.NewQueryAllBalancesRequest(addr)
params := types.NewQueryAllBalancesRequest(addr, pageReq)
res, err := queryClient.AllBalances(context.Background(), params)
if err != nil {
return err
@@ -71,7 +72,6 @@ func GetBalancesCmd(clientCtx client.Context) *cobra.Command {
}
cmd.Flags().String(flagDenom, "", "The specific balance denomination to query for")
return flags.GetCommands(cmd)[0]
}
+1 -1
View File
@@ -49,7 +49,7 @@ func QueryBalancesRequestHandlerFn(clientCtx client.Context) http.HandlerFunc {
denom := r.FormValue("denom")
if denom == "" {
params = types.NewQueryAllBalancesRequest(addr)
params = types.NewQueryAllBalancesRequest(addr, nil)
route = fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAllBalances)
} else {
params = types.NewQueryBalanceRequest(addr, denom)
+24 -3
View File
@@ -3,6 +3,8 @@ package keeper
import (
"context"
"github.com/cosmos/cosmos-sdk/store/prefix"
"github.com/cosmos/cosmos-sdk/types/query"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -38,14 +40,33 @@ func (q BaseKeeper) AllBalances(c context.Context, req *types.QueryAllBalancesRe
return nil, status.Errorf(codes.InvalidArgument, "empty request")
}
if len(req.Address) == 0 {
addr := req.Address
if len(addr) == 0 {
return nil, status.Errorf(codes.InvalidArgument, "invalid address")
}
ctx := sdk.UnwrapSDKContext(c)
balances := q.GetAllBalances(ctx, req.Address)
return &types.QueryAllBalancesResponse{Balances: balances}, nil
balances := sdk.NewCoins()
store := ctx.KVStore(q.storeKey)
balancesStore := prefix.NewStore(store, types.BalancesPrefix)
accountStore := prefix.NewStore(balancesStore, addr.Bytes())
res, err := query.Paginate(accountStore, req.Req, func(key []byte, value []byte) error {
var result sdk.Coin
err := q.cdc.UnmarshalBinaryBare(value, &result)
if err != nil {
return err
}
balances = append(balances, result)
return nil
})
if err != nil {
return &types.QueryAllBalancesResponse{}, err
}
return &types.QueryAllBalancesResponse{Balances: balances, Res: res}, nil
}
// TotalSupply implements the Query/TotalSupply gRPC method
+25 -3
View File
@@ -3,6 +3,8 @@ package keeper_test
import (
gocontext "context"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/baseapp"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
@@ -52,13 +54,21 @@ func (suite *IntegrationTestSuite) TestQueryAllBalances() {
_, err := queryClient.AllBalances(gocontext.Background(), &types.QueryAllBalancesRequest{})
suite.Require().Error(err)
req := types.NewQueryAllBalancesRequest(addr)
pageReq := &query.PageRequest{
Key: nil,
Limit: 1,
CountTotal: false,
}
req := types.NewQueryAllBalancesRequest(addr, pageReq)
res, err := queryClient.AllBalances(gocontext.Background(), req)
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.True(res.Balances.IsZero())
origCoins := sdk.NewCoins(newFooCoin(50), newBarCoin(30))
fooCoins := newFooCoin(50)
barCoins := newBarCoin(30)
origCoins := sdk.NewCoins(fooCoins, barCoins)
acc := app.AccountKeeper.NewAccountWithAddress(ctx, addr)
app.AccountKeeper.SetAccount(ctx, acc)
@@ -67,7 +77,19 @@ func (suite *IntegrationTestSuite) TestQueryAllBalances() {
res, err = queryClient.AllBalances(gocontext.Background(), req)
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.True(res.Balances.IsEqual(origCoins))
suite.Equal(res.Balances.Len(), 1)
suite.NotNil(res.Res.NextKey)
suite.T().Log("query second page with nextkey")
pageReq = &query.PageRequest{
Key: res.Res.NextKey,
Limit: 1,
CountTotal: true,
}
req = types.NewQueryAllBalancesRequest(addr, pageReq)
res, err = queryClient.AllBalances(gocontext.Background(), req)
suite.Equal(res.Balances.Len(), 1)
suite.Nil(res.Res.NextKey)
}
func (suite *IntegrationTestSuite) TestQueryTotalSupply() {
+1
View File
@@ -275,6 +275,7 @@ func (suite *IntegrationTestSuite) TestSendCoinsNewAccount() {
addr2 := sdk.AccAddress([]byte("addr2"))
suite.Require().Nil(app.AccountKeeper.GetAccount(ctx, addr2))
app.BankKeeper.GetAllBalances(ctx, addr2)
suite.Require().Empty(app.BankKeeper.GetAllBalances(ctx, addr2))
sendAmt := sdk.NewCoins(newFooCoin(50), newBarCoin(25))
+1 -1
View File
@@ -61,7 +61,7 @@ func (suite *IntegrationTestSuite) TestQuerier_QueryAllBalances() {
suite.Require().NotNil(err)
suite.Require().Nil(res)
req.Data = app.Codec().MustMarshalJSON(types.NewQueryAllBalancesRequest(addr))
req.Data = app.Codec().MustMarshalJSON(types.NewQueryAllBalancesRequest(addr, nil))
res, err = querier(ctx, []string{types.QueryAllBalances}, req)
suite.Require().NoError(err)
suite.Require().NotNil(res)
-1
View File
@@ -23,7 +23,6 @@ type ViewKeeper interface {
GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
LockedCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
+3 -2
View File
@@ -2,6 +2,7 @@ package types
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
)
// Querier path constants
@@ -18,8 +19,8 @@ func NewQueryBalanceRequest(addr sdk.AccAddress, denom string) *QueryBalanceRequ
}
// NewQueryAllBalancesRequest creates a new instance of QueryAllBalancesRequest.
func NewQueryAllBalancesRequest(addr sdk.AccAddress) *QueryAllBalancesRequest {
return &QueryAllBalancesRequest{Address: addr}
func NewQueryAllBalancesRequest(addr sdk.AccAddress, req *query.PageRequest) *QueryAllBalancesRequest {
return &QueryAllBalancesRequest{Address: addr, Req: req}
}
// QueryTotalSupply defines the params for the following queries:
+155 -31
View File
@@ -8,6 +8,7 @@ import (
fmt "fmt"
github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types"
types "github.com/cosmos/cosmos-sdk/types"
query "github.com/cosmos/cosmos-sdk/types/query"
_ "github.com/gogo/protobuf/gogoproto"
grpc1 "github.com/gogo/protobuf/grpc"
proto "github.com/gogo/protobuf/proto"
@@ -135,6 +136,7 @@ func (m *QueryBalanceResponse) GetBalance() *types.Coin {
type QueryAllBalancesRequest struct {
// address is the address to query balances for
Address github_com_cosmos_cosmos_sdk_types.AccAddress `protobuf:"bytes,1,opt,name=address,proto3,casttype=github.com/cosmos/cosmos-sdk/types.AccAddress" json:"address,omitempty"`
Req *query.PageRequest `protobuf:"bytes,2,opt,name=req,proto3" json:"req,omitempty"`
}
func (m *QueryAllBalancesRequest) Reset() { *m = QueryAllBalancesRequest{} }
@@ -177,10 +179,18 @@ func (m *QueryAllBalancesRequest) GetAddress() github_com_cosmos_cosmos_sdk_type
return nil
}
func (m *QueryAllBalancesRequest) GetReq() *query.PageRequest {
if m != nil {
return m.Req
}
return nil
}
// QueryAllBalancesResponse is the response type for the Query/AllBalances RPC method
type QueryAllBalancesResponse struct {
// balances is the balances of the coins
Balances github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=balances,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"balances"`
Res *query.PageResponse `protobuf:"bytes,2,opt,name=res,proto3" json:"res,omitempty"`
}
func (m *QueryAllBalancesResponse) Reset() { *m = QueryAllBalancesResponse{} }
@@ -223,6 +233,13 @@ func (m *QueryAllBalancesResponse) GetBalances() github_com_cosmos_cosmos_sdk_ty
return nil
}
func (m *QueryAllBalancesResponse) GetRes() *query.PageResponse {
if m != nil {
return m.Res
}
return nil
}
// QueryTotalSupplyRequest is the request type for the Query/TotalSupply RPC method
type QueryTotalSupplyRequest struct {
}
@@ -404,37 +421,40 @@ func init() {
func init() { proto.RegisterFile("cosmos/bank/query.proto", fileDescriptor_1b02ea4db7d9aa9f) }
var fileDescriptor_1b02ea4db7d9aa9f = []byte{
// 473 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0x4d, 0x6f, 0xd3, 0x40,
0x10, 0xb5, 0x8b, 0x9a, 0x94, 0x49, 0x4f, 0xdb, 0xa0, 0x06, 0x1f, 0xec, 0xb0, 0x82, 0x2a, 0x48,
0x74, 0x0d, 0xe5, 0x8e, 0x14, 0x57, 0x42, 0x42, 0x1c, 0x00, 0x17, 0x71, 0xa8, 0x90, 0x90, 0x3f,
0xb6, 0xa1, 0xaa, 0xed, 0x75, 0xbd, 0x36, 0x6a, 0xfe, 0x05, 0xbf, 0x83, 0x5f, 0xd2, 0x63, 0x8f,
0x88, 0x43, 0x40, 0xc9, 0x8d, 0x9f, 0xc0, 0x09, 0x79, 0x77, 0x5d, 0x39, 0xb1, 0x15, 0x7a, 0xa0,
0xb7, 0x64, 0xe6, 0xcd, 0x7b, 0x6f, 0xf6, 0xad, 0x17, 0x76, 0x03, 0xc6, 0x63, 0xc6, 0x6d, 0xdf,
0x4b, 0xce, 0xec, 0xf3, 0x82, 0x66, 0x53, 0x92, 0x66, 0x2c, 0x67, 0xa8, 0x27, 0x1b, 0xa4, 0x6c,
0x18, 0xfd, 0x09, 0x9b, 0x30, 0x51, 0xb7, 0xcb, 0x5f, 0x12, 0x62, 0xec, 0xa8, 0x59, 0x85, 0x14,
0x45, 0x7c, 0x01, 0x3b, 0xef, 0x4a, 0x1a, 0xc7, 0x8b, 0xbc, 0x24, 0xa0, 0x2e, 0x3d, 0x2f, 0x28,
0xcf, 0xd1, 0x6b, 0xe8, 0x7a, 0x61, 0x98, 0x51, 0xce, 0x07, 0xfa, 0x50, 0x1f, 0x6d, 0x3b, 0xcf,
0xfe, 0xcc, 0xac, 0xfd, 0xc9, 0x69, 0xfe, 0xb9, 0xf0, 0x49, 0xc0, 0x62, 0x7b, 0x89, 0x6b, 0x9f,
0x87, 0x67, 0x76, 0x3e, 0x4d, 0x29, 0x27, 0xe3, 0x20, 0x18, 0xcb, 0x41, 0xb7, 0x62, 0x40, 0x7d,
0xd8, 0x0c, 0x69, 0xc2, 0xe2, 0xc1, 0xc6, 0x50, 0x1f, 0xdd, 0x75, 0xe5, 0x1f, 0xfc, 0x02, 0xfa,
0xcb, 0xca, 0x3c, 0x65, 0x09, 0xa7, 0x68, 0x0f, 0xba, 0xbe, 0x2c, 0x09, 0xe9, 0xde, 0xc1, 0x36,
0x51, 0x8e, 0x0f, 0xd9, 0x69, 0xe2, 0x56, 0x4d, 0x7c, 0x02, 0xbb, 0x62, 0x7e, 0x1c, 0x45, 0x8a,
0x82, 0xdf, 0x86, 0x7b, 0xfc, 0x05, 0x06, 0x4d, 0x1d, 0xe5, 0xf5, 0x18, 0xb6, 0x94, 0x9d, 0x52,
0xe9, 0xce, 0xaa, 0x59, 0xe7, 0xe9, 0xe5, 0xcc, 0xd2, 0xbe, 0xfd, 0xb4, 0x46, 0x37, 0xd0, 0x2e,
0x07, 0xb8, 0x7b, 0xcd, 0x87, 0xef, 0xab, 0xfd, 0xde, 0xb3, 0xdc, 0x8b, 0x8e, 0x8a, 0x34, 0x8d,
0xa6, 0x6a, 0x3f, 0x9c, 0x29, 0x4b, 0x4b, 0x2d, 0x65, 0xe9, 0x03, 0x74, 0xb8, 0xa8, 0xfc, 0x27,
0x43, 0x8a, 0x0d, 0x3f, 0x51, 0x71, 0x49, 0xb9, 0x37, 0x27, 0xd5, 0x59, 0x5f, 0x87, 0xab, 0xd7,
0xc3, 0xfd, 0x04, 0xf7, 0x56, 0xd0, 0xca, 0xde, 0x4b, 0xe8, 0x78, 0x31, 0x2b, 0x92, 0x5c, 0xe2,
0x1d, 0x52, 0x1a, 0xfa, 0x31, 0xb3, 0xf6, 0x6e, 0x60, 0xe8, 0x55, 0x92, 0xbb, 0x6a, 0xfa, 0xe0,
0xf7, 0x06, 0x6c, 0x0a, 0x05, 0xf4, 0x16, 0xba, 0x2a, 0x17, 0x34, 0x24, 0xb5, 0xaf, 0x80, 0xb4,
0xdc, 0x6b, 0xe3, 0xc1, 0x1a, 0x84, 0x74, 0x88, 0x35, 0xf4, 0x11, 0x7a, 0xb5, 0xb0, 0xd1, 0xc3,
0xe6, 0x4c, 0xf3, 0xce, 0x19, 0x8f, 0xfe, 0x81, 0xaa, 0xb3, 0xd7, 0x72, 0x6b, 0x63, 0x6f, 0x26,
0xde, 0xc6, 0xde, 0x12, 0x3e, 0xd6, 0xd0, 0x11, 0x6c, 0x55, 0x67, 0x8e, 0x5a, 0x96, 0x5d, 0x49,
0xcf, 0xc0, 0xeb, 0x20, 0x15, 0xa9, 0x73, 0x78, 0x39, 0x37, 0xf5, 0xab, 0xb9, 0xa9, 0xff, 0x9a,
0x9b, 0xfa, 0xd7, 0x85, 0xa9, 0x5d, 0x2d, 0x4c, 0xed, 0xfb, 0xc2, 0xd4, 0x8e, 0x1f, 0xaf, 0x8d,
0xed, 0x42, 0xbe, 0x53, 0x22, 0x3d, 0xbf, 0x23, 0x1e, 0x9c, 0xe7, 0x7f, 0x03, 0x00, 0x00, 0xff,
0xff, 0x27, 0x7c, 0xfe, 0x36, 0xc3, 0x04, 0x00, 0x00,
// 527 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0xc1, 0x6e, 0xd3, 0x30,
0x18, 0xc7, 0x93, 0x4d, 0x6b, 0x87, 0xbb, 0x93, 0x57, 0xb4, 0x2e, 0x12, 0x69, 0xb1, 0x60, 0x2a,
0x62, 0x4b, 0xa0, 0xdc, 0x91, 0xda, 0x49, 0x48, 0x88, 0x03, 0x23, 0x43, 0x1c, 0x26, 0x24, 0x94,
0xa6, 0x26, 0x54, 0x4b, 0xed, 0x34, 0x4e, 0xa4, 0xf5, 0x2d, 0x90, 0x78, 0x05, 0x4e, 0x3c, 0xc9,
0x8e, 0x3b, 0x22, 0x0e, 0x05, 0xb5, 0x37, 0x1e, 0x81, 0x13, 0xb2, 0xfd, 0x65, 0x4a, 0xdb, 0xa8,
0xec, 0xc0, 0x6e, 0x89, 0xfd, 0xff, 0xfe, 0xfe, 0x7d, 0xfe, 0x7f, 0x09, 0xda, 0x0b, 0xb8, 0x18,
0x71, 0xe1, 0xf6, 0x7d, 0x76, 0xee, 0x8e, 0x33, 0x9a, 0x4c, 0x9c, 0x38, 0xe1, 0x29, 0xc7, 0x35,
0xbd, 0xe1, 0xc8, 0x0d, 0xeb, 0x1e, 0xa8, 0x94, 0xc0, 0x8d, 0xfd, 0x70, 0xc8, 0xfc, 0x74, 0xc8,
0x99, 0xd6, 0x5a, 0xf5, 0x90, 0x87, 0x5c, 0x3d, 0xba, 0xf2, 0x09, 0x56, 0x77, 0xa1, 0x08, 0x8c,
0xd4, 0x22, 0xb9, 0x40, 0xbb, 0x6f, 0xa4, 0x49, 0xcf, 0x8f, 0x7c, 0x16, 0x50, 0x8f, 0x8e, 0x33,
0x2a, 0x52, 0xfc, 0x0a, 0x55, 0xfd, 0xc1, 0x20, 0xa1, 0x42, 0x34, 0xcc, 0x96, 0xd9, 0xde, 0xe9,
0x3d, 0xfd, 0x33, 0x6d, 0x1e, 0x85, 0xc3, 0xf4, 0x53, 0xd6, 0x77, 0x02, 0x3e, 0x72, 0x17, 0xbc,
0x8e, 0xc4, 0xe0, 0xdc, 0x4d, 0x27, 0x31, 0x15, 0x4e, 0x37, 0x08, 0xba, 0xba, 0xd0, 0xcb, 0x1d,
0x70, 0x1d, 0x6d, 0x0d, 0x28, 0xe3, 0xa3, 0xc6, 0x46, 0xcb, 0x6c, 0xdf, 0xf1, 0xf4, 0x0b, 0x79,
0x8e, 0xea, 0x8b, 0x27, 0x8b, 0x98, 0x33, 0x41, 0xf1, 0x01, 0xaa, 0xf6, 0xf5, 0x92, 0x3a, 0xba,
0xd6, 0xd9, 0x71, 0x80, 0xf8, 0x98, 0x0f, 0x99, 0x97, 0x6f, 0x92, 0x2f, 0x26, 0xda, 0x53, 0x06,
0xdd, 0x28, 0x02, 0x0f, 0x71, 0x2b, 0xf8, 0x8f, 0xd1, 0x66, 0x42, 0xc7, 0x0a, 0xbe, 0xd6, 0xd9,
0xcf, 0x61, 0x74, 0x36, 0x27, 0x7e, 0x98, 0xdf, 0x99, 0x27, 0x55, 0xe4, 0xab, 0x89, 0x1a, 0xab,
0x54, 0xd0, 0xda, 0x19, 0xda, 0x06, 0x7a, 0xc9, 0xb5, 0xb9, 0xdc, 0x5b, 0xef, 0xc9, 0xe5, 0xb4,
0x69, 0x7c, 0xfb, 0xd9, 0x6c, 0xdf, 0x80, 0x54, 0x16, 0x08, 0xef, 0xda, 0x0f, 0x1f, 0x4a, 0x4a,
0x01, 0x94, 0x56, 0x19, 0xa5, 0x86, 0x90, 0x98, 0x82, 0xec, 0xc3, 0xdd, 0xbd, 0xe5, 0xa9, 0x1f,
0x9d, 0x66, 0x71, 0x1c, 0x4d, 0xa0, 0x0d, 0x92, 0x40, 0x03, 0x0b, 0x5b, 0xd0, 0xc0, 0x3b, 0x54,
0x11, 0x6a, 0xe5, 0x3f, 0xe1, 0x83, 0x1b, 0x39, 0x84, 0x59, 0xd0, 0xc7, 0xbd, 0xfe, 0x98, 0xe7,
0x78, 0x3d, 0x39, 0x66, 0x71, 0x72, 0x3e, 0xa0, 0xbb, 0x4b, 0x6a, 0xc0, 0x7b, 0x81, 0x2a, 0xfe,
0x88, 0x67, 0x2c, 0xd5, 0xfa, 0x9e, 0x23, 0x81, 0x7e, 0x4c, 0x9b, 0x07, 0x37, 0x00, 0x7a, 0xc9,
0x52, 0x0f, 0xaa, 0x3b, 0xbf, 0x37, 0xd0, 0x96, 0x3a, 0x01, 0x9f, 0xa0, 0x2a, 0xa4, 0x88, 0x5b,
0x4e, 0xe1, 0x0b, 0x74, 0x4a, 0x3e, 0x1a, 0xeb, 0xfe, 0x1a, 0x85, 0x26, 0x24, 0x06, 0x7e, 0x8f,
0x6a, 0x85, 0xd1, 0xc0, 0x0f, 0x56, 0x6b, 0x56, 0xe7, 0xd9, 0x7a, 0xf8, 0x0f, 0x55, 0xd1, 0xbd,
0x90, 0x5b, 0x99, 0xfb, 0x6a, 0xe2, 0x65, 0xee, 0x25, 0xe1, 0x13, 0x03, 0x9f, 0xa2, 0xed, 0xfc,
0xce, 0x71, 0x49, 0xb3, 0x4b, 0xe9, 0x59, 0x64, 0x9d, 0x24, 0x37, 0xed, 0x1d, 0x5f, 0xce, 0x6c,
0xf3, 0x6a, 0x66, 0x9b, 0xbf, 0x66, 0xb6, 0xf9, 0x79, 0x6e, 0x1b, 0x57, 0x73, 0xdb, 0xf8, 0x3e,
0xb7, 0x8d, 0xb3, 0x47, 0x6b, 0x63, 0xbb, 0xd0, 0xff, 0x48, 0x95, 0x5e, 0xbf, 0xa2, 0xfe, 0x66,
0xcf, 0xfe, 0x06, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x62, 0xaf, 0x8a, 0x3f, 0x05, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -725,6 +745,18 @@ func (m *QueryAllBalancesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error)
_ = i
var l int
_ = l
if m.Req != nil {
{
size, err := m.Req.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
if len(m.Address) > 0 {
i -= len(m.Address)
copy(dAtA[i:], m.Address)
@@ -755,6 +787,18 @@ func (m *QueryAllBalancesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error
_ = i
var l int
_ = l
if m.Res != nil {
{
size, err := m.Res.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
if len(m.Balances) > 0 {
for iNdEx := len(m.Balances) - 1; iNdEx >= 0; iNdEx-- {
{
@@ -946,6 +990,10 @@ func (m *QueryAllBalancesRequest) Size() (n int) {
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
if m.Req != nil {
l = m.Req.Size()
n += 1 + l + sovQuery(uint64(l))
}
return n
}
@@ -961,6 +1009,10 @@ func (m *QueryAllBalancesResponse) Size() (n int) {
n += 1 + l + sovQuery(uint64(l))
}
}
if m.Res != nil {
l = m.Res.Size()
n += 1 + l + sovQuery(uint64(l))
}
return n
}
@@ -1289,6 +1341,42 @@ func (m *QueryAllBalancesRequest) Unmarshal(dAtA []byte) error {
m.Address = []byte{}
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Req", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Req == nil {
m.Req = &query.PageRequest{}
}
if err := m.Req.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
@@ -1376,6 +1464,42 @@ func (m *QueryAllBalancesResponse) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Res", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Res == nil {
m.Res = &query.PageResponse{}
}
if err := m.Res.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
+2 -1
View File
@@ -48,7 +48,8 @@ func InitGenesis(ctx sdk.Context, ak types.AccountKeeper, bk types.BankKeeper, k
panic(fmt.Sprintf("%s module account has not been set", types.ModuleName))
}
if bk.GetAllBalances(ctx, moduleAcc.GetAddress()).IsZero() {
balances := bk.GetAllBalances(ctx, moduleAcc.GetAddress())
if balances.IsZero() {
if err := bk.SetBalances(ctx, moduleAcc.GetAddress(), moduleHoldingsInt); err != nil {
panic(err)
}