feat(epochs): backport (#23815)

Co-authored-by: Tyler <48813565+technicallyty@users.noreply.github.com>
This commit is contained in:
Alex | Interchain Labs 2025-02-26 16:10:00 -05:00 committed by GitHub
parent 4ed61468a2
commit ff779eca8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 10362 additions and 796 deletions

View File

@ -38,8 +38,9 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [Unreleased]
### Features
### Features
* (x/epochs) [#23815](https://github.com/cosmos/cosmos-sdk/pull/23815) Upstream `x/epochs` from Osmosis
* (client) [#21074](https://github.com/cosmos/cosmos-sdk/pull/21074) Add auto cli for node service
### Bug Fixes

View File

@ -0,0 +1,505 @@
// Code generated by protoc-gen-go-pulsar. DO NOT EDIT.
package modulev1
import (
_ "cosmossdk.io/api/cosmos/app/v1alpha1"
fmt "fmt"
runtime "github.com/cosmos/cosmos-proto/runtime"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoiface "google.golang.org/protobuf/runtime/protoiface"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
io "io"
reflect "reflect"
sync "sync"
)
var (
md_Module protoreflect.MessageDescriptor
)
func init() {
file_cosmos_epochs_module_v1_module_proto_init()
md_Module = File_cosmos_epochs_module_v1_module_proto.Messages().ByName("Module")
}
var _ protoreflect.Message = (*fastReflection_Module)(nil)
type fastReflection_Module Module
func (x *Module) ProtoReflect() protoreflect.Message {
return (*fastReflection_Module)(x)
}
func (x *Module) slowProtoReflect() protoreflect.Message {
mi := &file_cosmos_epochs_module_v1_module_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
var _fastReflection_Module_messageType fastReflection_Module_messageType
var _ protoreflect.MessageType = fastReflection_Module_messageType{}
type fastReflection_Module_messageType struct{}
func (x fastReflection_Module_messageType) Zero() protoreflect.Message {
return (*fastReflection_Module)(nil)
}
func (x fastReflection_Module_messageType) New() protoreflect.Message {
return new(fastReflection_Module)
}
func (x fastReflection_Module_messageType) Descriptor() protoreflect.MessageDescriptor {
return md_Module
}
// Descriptor returns message descriptor, which contains only the protobuf
// type information for the message.
func (x *fastReflection_Module) Descriptor() protoreflect.MessageDescriptor {
return md_Module
}
// Type returns the message type, which encapsulates both Go and protobuf
// type information. If the Go type information is not needed,
// it is recommended that the message descriptor be used instead.
func (x *fastReflection_Module) Type() protoreflect.MessageType {
return _fastReflection_Module_messageType
}
// New returns a newly allocated and mutable empty message.
func (x *fastReflection_Module) New() protoreflect.Message {
return new(fastReflection_Module)
}
// Interface unwraps the message reflection interface and
// returns the underlying ProtoMessage interface.
func (x *fastReflection_Module) Interface() protoreflect.ProtoMessage {
return (*Module)(x)
}
// Range iterates over every populated field in an undefined order,
// calling f for each field descriptor and value encountered.
// Range returns immediately if f returns false.
// While iterating, mutating operations may only be performed
// on the current field descriptor.
func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
}
// Has reports whether a field is populated.
//
// Some fields have the property of nullability where it is possible to
// distinguish between the default value of a field and whether the field
// was explicitly populated with the default value. Singular message fields,
// member fields of a oneof, and proto2 scalar fields are nullable. Such
// fields are populated only if explicitly set.
//
// In other cases (aside from the nullable cases above),
// a proto3 scalar field is populated if it contains a non-zero value, and
// a repeated field is populated if it is non-empty.
func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module does not contain field %s", fd.FullName()))
}
}
// Clear clears the field such that a subsequent Has call reports false.
//
// Clearing an extension field clears both the extension type and value
// associated with the given field number.
//
// Clear is a mutating operation and unsafe for concurrent use.
func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module does not contain field %s", fd.FullName()))
}
}
// Get retrieves the value for a field.
//
// For unpopulated scalars, it returns the default value, where
// the default value of a bytes scalar is guaranteed to be a copy.
// For unpopulated composite types, it returns an empty, read-only view
// of the value; to obtain a mutable reference, use Mutable.
func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value {
switch descriptor.FullName() {
default:
if descriptor.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module does not contain field %s", descriptor.FullName()))
}
}
// Set stores the value for a field.
//
// For a field belonging to a oneof, it implicitly clears any other field
// that may be currently set within the same oneof.
// For extension fields, it implicitly stores the provided ExtensionType.
// When setting a composite type, it is unspecified whether the stored value
// aliases the source's memory in any way. If the composite value is an
// empty, read-only value, then it panics.
//
// Set is a mutating operation and unsafe for concurrent use.
func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module does not contain field %s", fd.FullName()))
}
}
// Mutable returns a mutable reference to a composite type.
//
// If the field is unpopulated, it may allocate a composite value.
// For a field belonging to a oneof, it implicitly clears any other field
// that may be currently set within the same oneof.
// For extension fields, it implicitly stores the provided ExtensionType
// if not already stored.
// It panics if the field does not contain a composite type.
//
// Mutable is a mutating operation and unsafe for concurrent use.
func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module does not contain field %s", fd.FullName()))
}
}
// NewField returns a new value that is assignable to the field
// for the given descriptor. For scalars, this returns the default value.
// For lists, maps, and messages, this returns a new, empty, mutable value.
func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value {
switch fd.FullName() {
default:
if fd.IsExtension() {
panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.epochs.module.v1.Module"))
}
panic(fmt.Errorf("message cosmos.epochs.module.v1.Module does not contain field %s", fd.FullName()))
}
}
// WhichOneof reports which field within the oneof is populated,
// returning nil if none are populated.
// It panics if the oneof descriptor does not belong to this message.
func (x *fastReflection_Module) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor {
switch d.FullName() {
default:
panic(fmt.Errorf("%s is not a oneof field in cosmos.epochs.module.v1.Module", d.FullName()))
}
panic("unreachable")
}
// GetUnknown retrieves the entire list of unknown fields.
// The caller may only mutate the contents of the RawFields
// if the mutated bytes are stored back into the message with SetUnknown.
func (x *fastReflection_Module) GetUnknown() protoreflect.RawFields {
return x.unknownFields
}
// SetUnknown stores an entire list of unknown fields.
// The raw fields must be syntactically valid according to the wire format.
// An implementation may panic if this is not the case.
// Once stored, the caller must not mutate the content of the RawFields.
// An empty RawFields may be passed to clear the fields.
//
// SetUnknown is a mutating operation and unsafe for concurrent use.
func (x *fastReflection_Module) SetUnknown(fields protoreflect.RawFields) {
x.unknownFields = fields
}
// IsValid reports whether the message is valid.
//
// An invalid message is an empty, read-only value.
//
// An invalid message often corresponds to a nil pointer of the concrete
// message type, but the details are implementation dependent.
// Validity is not part of the protobuf data model, and may not
// be preserved in marshaling or other operations.
func (x *fastReflection_Module) IsValid() bool {
return x != nil
}
// ProtoMethods returns optional fastReflectionFeature-path implementations of various operations.
// This method may return nil.
//
// The returned methods type is identical to
// "google.golang.org/protobuf/runtime/protoiface".Methods.
// Consult the protoiface package documentation for details.
func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods {
size := func(input protoiface.SizeInput) protoiface.SizeOutput {
x := input.Message.Interface().(*Module)
if x == nil {
return protoiface.SizeOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Size: 0,
}
}
options := runtime.SizeInputToOptions(input)
_ = options
var n int
var l int
_ = l
if x.unknownFields != nil {
n += len(x.unknownFields)
}
return protoiface.SizeOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Size: n,
}
}
marshal := func(input protoiface.MarshalInput) (protoiface.MarshalOutput, error) {
x := input.Message.Interface().(*Module)
if x == nil {
return protoiface.MarshalOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Buf: input.Buf,
}, nil
}
options := runtime.MarshalInputToOptions(input)
_ = options
size := options.Size(x)
dAtA := make([]byte, size)
i := len(dAtA)
_ = i
var l int
_ = l
if x.unknownFields != nil {
i -= len(x.unknownFields)
copy(dAtA[i:], x.unknownFields)
}
if input.Buf != nil {
input.Buf = append(input.Buf, dAtA...)
} else {
input.Buf = dAtA
}
return protoiface.MarshalOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Buf: input.Buf,
}, nil
}
unmarshal := func(input protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) {
x := input.Message.Interface().(*Module)
if x == nil {
return protoiface.UnmarshalOutput{
NoUnkeyedLiterals: input.NoUnkeyedLiterals,
Flags: input.Flags,
}, nil
}
options := runtime.UnmarshalInputToOptions(input)
_ = options
dAtA := input.Buf
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow
}
if iNdEx >= l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, 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 protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: wiretype end group for non-group")
}
if fieldNum <= 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := runtime.Skip(dAtA[iNdEx:])
if err != nil {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength
}
if (iNdEx + skippy) > l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
if !options.DiscardUnknown {
x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
}
iNdEx += skippy
}
}
if iNdEx > l {
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF
}
return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil
}
return &protoiface.Methods{
NoUnkeyedLiterals: struct{}{},
Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown,
Size: size,
Marshal: marshal,
Unmarshal: unmarshal,
Merge: nil,
CheckInitialized: nil,
}
}
// Since: cosmos-sdk 0.53
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.0
// protoc (unknown)
// source: cosmos/epochs/module/v1/module.proto
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// Module is the config object of the epochs module.
type Module struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *Module) Reset() {
*x = Module{}
if protoimpl.UnsafeEnabled {
mi := &file_cosmos_epochs_module_v1_module_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Module) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Module) ProtoMessage() {}
// Deprecated: Use Module.ProtoReflect.Descriptor instead.
func (*Module) Descriptor() ([]byte, []int) {
return file_cosmos_epochs_module_v1_module_proto_rawDescGZIP(), []int{0}
}
var File_cosmos_epochs_module_v1_module_proto protoreflect.FileDescriptor
var file_cosmos_epochs_module_v1_module_proto_rawDesc = []byte{
0x0a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x2f,
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65,
0x70, 0x6f, 0x63, 0x68, 0x73, 0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a,
0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x22, 0x37, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x2d, 0xba, 0xc0, 0x96,
0xda, 0x01, 0x27, 0x0a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64,
0x6b, 0x2f, 0x78, 0x2f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x42, 0xdc, 0x01, 0x0a, 0x1b, 0x63,
0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x73,
0x2e, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75,
0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f,
0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d,
0x6f, 0x73, 0x2f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x2f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
0x2f, 0x76, 0x31, 0x3b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43,
0x45, 0x4d, 0xaa, 0x02, 0x17, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x70, 0x6f, 0x63,
0x68, 0x73, 0x2e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x17, 0x43,
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x5c, 0x4d, 0x6f, 0x64,
0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x23, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c,
0x45, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x5c, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5c, 0x56, 0x31,
0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x43,
0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x73, 0x3a, 0x3a, 0x4d,
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (
file_cosmos_epochs_module_v1_module_proto_rawDescOnce sync.Once
file_cosmos_epochs_module_v1_module_proto_rawDescData = file_cosmos_epochs_module_v1_module_proto_rawDesc
)
func file_cosmos_epochs_module_v1_module_proto_rawDescGZIP() []byte {
file_cosmos_epochs_module_v1_module_proto_rawDescOnce.Do(func() {
file_cosmos_epochs_module_v1_module_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_epochs_module_v1_module_proto_rawDescData)
})
return file_cosmos_epochs_module_v1_module_proto_rawDescData
}
var file_cosmos_epochs_module_v1_module_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_cosmos_epochs_module_v1_module_proto_goTypes = []interface{}{
(*Module)(nil), // 0: cosmos.epochs.module.v1.Module
}
var file_cosmos_epochs_module_v1_module_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_cosmos_epochs_module_v1_module_proto_init() }
func file_cosmos_epochs_module_v1_module_proto_init() {
if File_cosmos_epochs_module_v1_module_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_cosmos_epochs_module_v1_module_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Module); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_cosmos_epochs_module_v1_module_proto_rawDesc,
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_cosmos_epochs_module_v1_module_proto_goTypes,
DependencyIndexes: file_cosmos_epochs_module_v1_module_proto_depIdxs,
MessageInfos: file_cosmos_epochs_module_v1_module_proto_msgTypes,
}.Build()
File_cosmos_epochs_module_v1_module_proto = out.File
file_cosmos_epochs_module_v1_module_proto_rawDesc = nil
file_cosmos_epochs_module_v1_module_proto_goTypes = nil
file_cosmos_epochs_module_v1_module_proto_depIdxs = nil
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,169 @@
// Since: cosmos-sdk 0.53
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.5.1
// - protoc (unknown)
// source: cosmos/epochs/v1beta1/query.proto
package epochsv1beta1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.64.0 or later.
const _ = grpc.SupportPackageIsVersion9
const (
Query_EpochInfos_FullMethodName = "/cosmos.epochs.v1beta1.Query/EpochInfos"
Query_CurrentEpoch_FullMethodName = "/cosmos.epochs.v1beta1.Query/CurrentEpoch"
)
// QueryClient is the client API for Query service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
//
// Query defines the gRPC querier service.
type QueryClient interface {
// EpochInfos provide running epochInfos
EpochInfos(ctx context.Context, in *QueryEpochInfosRequest, opts ...grpc.CallOption) (*QueryEpochInfosResponse, error)
// CurrentEpoch provide current epoch of specified identifier
CurrentEpoch(ctx context.Context, in *QueryCurrentEpochRequest, opts ...grpc.CallOption) (*QueryCurrentEpochResponse, error)
}
type queryClient struct {
cc grpc.ClientConnInterface
}
func NewQueryClient(cc grpc.ClientConnInterface) QueryClient {
return &queryClient{cc}
}
func (c *queryClient) EpochInfos(ctx context.Context, in *QueryEpochInfosRequest, opts ...grpc.CallOption) (*QueryEpochInfosResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(QueryEpochInfosResponse)
err := c.cc.Invoke(ctx, Query_EpochInfos_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *queryClient) CurrentEpoch(ctx context.Context, in *QueryCurrentEpochRequest, opts ...grpc.CallOption) (*QueryCurrentEpochResponse, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(QueryCurrentEpochResponse)
err := c.cc.Invoke(ctx, Query_CurrentEpoch_FullMethodName, in, out, cOpts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
// All implementations must embed UnimplementedQueryServer
// for forward compatibility.
//
// Query defines the gRPC querier service.
type QueryServer interface {
// EpochInfos provide running epochInfos
EpochInfos(context.Context, *QueryEpochInfosRequest) (*QueryEpochInfosResponse, error)
// CurrentEpoch provide current epoch of specified identifier
CurrentEpoch(context.Context, *QueryCurrentEpochRequest) (*QueryCurrentEpochResponse, error)
mustEmbedUnimplementedQueryServer()
}
// UnimplementedQueryServer must be embedded to have
// forward compatible implementations.
//
// NOTE: this should be embedded by value instead of pointer to avoid a nil
// pointer dereference when methods are called.
type UnimplementedQueryServer struct{}
func (UnimplementedQueryServer) EpochInfos(context.Context, *QueryEpochInfosRequest) (*QueryEpochInfosResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method EpochInfos not implemented")
}
func (UnimplementedQueryServer) CurrentEpoch(context.Context, *QueryCurrentEpochRequest) (*QueryCurrentEpochResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CurrentEpoch not implemented")
}
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
func (UnimplementedQueryServer) testEmbeddedByValue() {}
// UnsafeQueryServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to QueryServer will
// result in compilation errors.
type UnsafeQueryServer interface {
mustEmbedUnimplementedQueryServer()
}
func RegisterQueryServer(s grpc.ServiceRegistrar, srv QueryServer) {
// If the following call pancis, it indicates UnimplementedQueryServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
t.testEmbeddedByValue()
}
s.RegisterService(&Query_ServiceDesc, srv)
}
func _Query_EpochInfos_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryEpochInfosRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).EpochInfos(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_EpochInfos_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).EpochInfos(ctx, req.(*QueryEpochInfosRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Query_CurrentEpoch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryCurrentEpochRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).CurrentEpoch(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: Query_CurrentEpoch_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).CurrentEpoch(ctx, req.(*QueryCurrentEpochRequest))
}
return interceptor(ctx, in, info, handler)
}
// Query_ServiceDesc is the grpc.ServiceDesc for Query service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Query_ServiceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.epochs.v1beta1.Query",
HandlerType: (*QueryServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "EpochInfos",
Handler: _Query_EpochInfos_Handler,
},
{
MethodName: "CurrentEpoch",
Handler: _Query_CurrentEpoch_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/epochs/v1beta1/query.proto",
}

View File

@ -0,0 +1,13 @@
// Since: cosmos-sdk 0.53
syntax = "proto3";
package cosmos.epochs.module.v1;
import "cosmos/app/v1alpha1/module.proto";
// Module is the config object of the epochs module.
message Module {
option (cosmos.app.v1alpha1.module) = {
go_import: "github.com/cosmos/cosmos-sdk/x/epochs"
};
}

View File

@ -0,0 +1,17 @@
// Since: cosmos-sdk 0.53
syntax = "proto3";
package cosmos.epochs.v1beta1;
option go_package = "github.com/cosmos/cosmos-sdk/x/epochs/types";
// EventEpochEnd is an event emitted when an epoch end.
message EventEpochEnd {
int64 epoch_number = 1;
}
// EventEpochStart is an event emitted when an epoch start.
message EventEpochStart {
int64 epoch_number = 1;
int64 epoch_start_time = 2;
}

View File

@ -0,0 +1,61 @@
// Since: cosmos-sdk 0.53
syntax = "proto3";
package cosmos.epochs.v1beta1;
import "gogoproto/gogo.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/epochs/types";
// EpochInfo is a struct that describes the data going into
// a timer defined by the x/epochs module.
message EpochInfo {
// identifier is a unique reference to this particular timer.
string identifier = 1;
// start_time is the time at which the timer first ever ticks.
// If start_time is in the future, the epoch will not begin until the start
// time.
google.protobuf.Timestamp start_time = 2 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// duration is the time in between epoch ticks.
// In order for intended behavior to be met, duration should
// be greater than the chains expected block time.
// Duration must be non-zero.
google.protobuf.Duration duration = 3
[(gogoproto.nullable) = false, (gogoproto.stdduration) = true, (gogoproto.jsontag) = "duration,omitempty"];
// current_epoch is the current epoch number, or in other words,
// how many times has the timer 'ticked'.
// The first tick (current_epoch=1) is defined as
// the first block whose blocktime is greater than the EpochInfo start_time.
int64 current_epoch = 4;
// current_epoch_start_time describes the start time of the current timer
// interval. The interval is (current_epoch_start_time,
// current_epoch_start_time + duration] When the timer ticks, this is set to
// current_epoch_start_time = last_epoch_start_time + duration only one timer
// tick for a given identifier can occur per block.
//
// NOTE! The current_epoch_start_time may diverge significantly from the
// wall-clock time the epoch began at. Wall-clock time of epoch start may be
// >> current_epoch_start_time. Suppose current_epoch_start_time = 10,
// duration = 5. Suppose the chain goes offline at t=14, and comes back online
// at t=30, and produces blocks at every successive time. (t=31, 32, etc.)
// * The t=30 block will start the epoch for (10, 15]
// * The t=31 block will start the epoch for (15, 20]
// * The t=32 block will start the epoch for (20, 25]
// * The t=33 block will start the epoch for (25, 30]
// * The t=34 block will start the epoch for (30, 35]
// * The **t=36** block will start the epoch for (35, 40]
google.protobuf.Timestamp current_epoch_start_time = 5 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// epoch_counting_started is a boolean, that indicates whether this
// epoch timer has began yet.
bool epoch_counting_started = 6;
reserved 7;
// current_epoch_start_height is the block height at which the current epoch
// started. (The block height at which the timer last ticked)
int64 current_epoch_start_height = 8;
}
// GenesisState defines the epochs module's genesis state.
message GenesisState {
repeated EpochInfo epochs = 1 [(gogoproto.nullable) = false];
}

View File

@ -0,0 +1,43 @@
// Since: cosmos-sdk 0.53
syntax = "proto3";
package cosmos.epochs.v1beta1;
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "cosmos/epochs/v1beta1/genesis.proto";
option go_package = "github.com/cosmos/cosmos-sdk/x/epochs/types";
// Query defines the gRPC querier service.
service Query {
// EpochInfos provide running epochInfos
rpc EpochInfos(QueryEpochInfosRequest) returns (QueryEpochInfosResponse) {
option (google.api.http).get = "/cosmos/epochs/v1beta1/epochs";
}
// CurrentEpoch provide current epoch of specified identifier
rpc CurrentEpoch(QueryCurrentEpochRequest) returns (QueryCurrentEpochResponse) {
option (google.api.http).get = "/cosmos/epochs/v1beta1/current_epoch";
}
}
// QueryEpochInfosRequest defines the gRPC request structure for
// querying all epoch info.
message QueryEpochInfosRequest {}
// QueryEpochInfosRequest defines the gRPC response structure for
// querying all epoch info.
message QueryEpochInfosResponse {
repeated EpochInfo epochs = 1 [(gogoproto.nullable) = false];
}
// QueryCurrentEpochRequest defines the gRPC request structure for
// querying an epoch by its identifier.
message QueryCurrentEpochRequest {
string identifier = 1;
}
// QueryCurrentEpochResponse defines the gRPC response structure for
// querying an epoch by its identifier.
message QueryCurrentEpochResponse {
int64 current_epoch = 1;
}

View File

@ -81,6 +81,9 @@ import (
distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/epochs"
epochskeeper "github.com/cosmos/cosmos-sdk/x/epochs/keeper"
epochstypes "github.com/cosmos/cosmos-sdk/x/epochs/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/gov"
@ -154,6 +157,7 @@ type SimApp struct {
NFTKeeper nftkeeper.Keeper
ConsensusParamsKeeper consensusparamkeeper.Keeper
CircuitKeeper circuitkeeper.Keeper
EpochsKeeper epochskeeper.Keeper
// the module manager
ModuleManager *module.Manager
@ -260,6 +264,7 @@ func NewSimApp(
authzkeeper.StoreKey,
nftkeeper.StoreKey,
group.StoreKey,
epochstypes.StoreKey,
)
// register streaming services
@ -381,6 +386,17 @@ func NewSimApp(
// If evidence needs to be handled for the app, set routes in router here and seal
app.EvidenceKeeper = *evidenceKeeper
app.EpochsKeeper = epochskeeper.NewKeeper(
runtime.NewKVStoreService(keys[epochstypes.StoreKey]),
appCodec,
)
app.EpochsKeeper.SetHooks(
epochstypes.NewMultiEpochHooks(
// insert epoch hooks receivers here
),
)
/**** Module Options ****/
// NOTE: Any module instantiated in the module manager that is later modified
@ -406,6 +422,7 @@ func NewSimApp(
nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper),
circuit.NewAppModule(appCodec, app.CircuitKeeper),
epochs.NewAppModule(appCodec, app.EpochsKeeper),
)
// BasicModuleManager defines the module BasicManager is in charge of setting up basic,
@ -439,6 +456,7 @@ func NewSimApp(
stakingtypes.ModuleName,
genutiltypes.ModuleName,
authz.ModuleName,
epochstypes.ModuleName,
)
app.ModuleManager.SetOrderEndBlockers(
govtypes.ModuleName,
@ -469,6 +487,7 @@ func NewSimApp(
vestingtypes.ModuleName,
consensusparamtypes.ModuleName,
circuittypes.ModuleName,
epochstypes.ModuleName,
}
app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...)
app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...)

View File

@ -13,6 +13,7 @@ import (
circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
epochsmodulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
@ -52,6 +53,8 @@ import (
consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
_ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
_ "github.com/cosmos/cosmos-sdk/x/epochs" // import for side-effects
epochstypes "github.com/cosmos/cosmos-sdk/x/epochs/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/gov"
@ -113,6 +116,7 @@ var (
evidencetypes.ModuleName,
stakingtypes.ModuleName,
authz.ModuleName,
epochstypes.ModuleName,
},
EndBlockers: []string{
govtypes.ModuleName,
@ -146,6 +150,7 @@ var (
upgradetypes.ModuleName,
vestingtypes.ModuleName,
circuittypes.ModuleName,
epochstypes.ModuleName,
},
// When ExportGenesis is not specified, the export genesis module order
// is equal to the init genesis order
@ -244,6 +249,10 @@ var (
Name: circuittypes.ModuleName,
Config: appconfig.WrapAny(&circuitmodulev1.Module{}),
},
{
Name: epochstypes.ModuleName,
Config: appconfig.WrapAny(&epochsmodulev1.Module{}),
},
},
}),
depinject.Supply(

View File

@ -37,6 +37,7 @@ import (
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
epochskeeper "github.com/cosmos/cosmos-sdk/x/epochs/keeper"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
@ -78,6 +79,7 @@ type SimApp struct {
NFTKeeper nftkeeper.Keeper
ConsensusParamsKeeper consensuskeeper.Keeper
CircuitKeeper circuitkeeper.Keeper
EpochsKeeper epochskeeper.Keeper
// simulation manager
sm *module.SimulationManager
@ -177,6 +179,7 @@ func NewSimApp(
&app.NFTKeeper,
&app.ConsensusParamsKeeper,
&app.CircuitKeeper,
&app.EpochsKeeper,
); err != nil {
panic(err)
}

View File

@ -17,8 +17,11 @@ import (
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/x/evidence"
evidencetypes "cosmossdk.io/x/evidence/types"
"cosmossdk.io/x/feegrant"
feegrantmodule "cosmossdk.io/x/feegrant/module"
"cosmossdk.io/x/upgrade"
upgradetypes "cosmossdk.io/x/upgrade/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/runtime"
@ -29,17 +32,29 @@ import (
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/types/msgservice"
"github.com/cosmos/cosmos-sdk/x/auth"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
"github.com/cosmos/cosmos-sdk/x/authz"
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
"github.com/cosmos/cosmos-sdk/x/bank"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/distribution"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/epochs"
epochstypes "github.com/cosmos/cosmos-sdk/x/epochs/types"
"github.com/cosmos/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/gov"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
grouptypes "github.com/cosmos/cosmos-sdk/x/group"
group "github.com/cosmos/cosmos-sdk/x/group/module"
"github.com/cosmos/cosmos-sdk/x/mint"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
func TestSimAppExportAndBlockedAddrs(t *testing.T) {
@ -193,20 +208,21 @@ func TestRunMigrations(t *testing.T) {
_, err = app.ModuleManager.RunMigrations(
app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()}), configurator,
module.VersionMap{
"bank": 1,
"auth": auth.AppModule{}.ConsensusVersion(),
"authz": authzmodule.AppModule{}.ConsensusVersion(),
"staking": staking.AppModule{}.ConsensusVersion(),
"mint": mint.AppModule{}.ConsensusVersion(),
"distribution": distribution.AppModule{}.ConsensusVersion(),
"slashing": slashing.AppModule{}.ConsensusVersion(),
"gov": gov.AppModule{}.ConsensusVersion(),
"group": group.AppModule{}.ConsensusVersion(),
"upgrade": upgrade.AppModule{}.ConsensusVersion(),
"vesting": vesting.AppModule{}.ConsensusVersion(),
"feegrant": feegrantmodule.AppModule{}.ConsensusVersion(),
"evidence": evidence.AppModule{}.ConsensusVersion(),
"genutil": genutil.AppModule{}.ConsensusVersion(),
banktypes.ModuleName: 1,
authtypes.ModuleName: auth.AppModule{}.ConsensusVersion(),
authz.ModuleName: authzmodule.AppModule{}.ConsensusVersion(),
stakingtypes.ModuleName: staking.AppModule{}.ConsensusVersion(),
minttypes.ModuleName: mint.AppModule{}.ConsensusVersion(),
distrtypes.ModuleName: distribution.AppModule{}.ConsensusVersion(),
slashingtypes.ModuleName: slashing.AppModule{}.ConsensusVersion(),
govtypes.ModuleName: gov.AppModule{}.ConsensusVersion(),
grouptypes.ModuleName: group.AppModule{}.ConsensusVersion(),
upgradetypes.ModuleName: upgrade.AppModule{}.ConsensusVersion(),
vestingtypes.ModuleName: vesting.AppModule{}.ConsensusVersion(),
feegrant.ModuleName: feegrantmodule.AppModule{}.ConsensusVersion(),
evidencetypes.ModuleName: evidence.AppModule{}.ConsensusVersion(),
genutiltypes.ModuleName: genutil.AppModule{}.ConsensusVersion(),
epochstypes.ModuleName: epochs.AppModule{}.ConsensusVersion(),
},
)
if tc.expRunErr {

View File

@ -214,6 +214,7 @@ require (
// Below are the long-lived replace of the SimApp
replace (
cosmossdk.io/api => ../api
// use cosmos fork of keyring
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
// Simapp always use the latest version of the cosmos-sdk

View File

@ -182,8 +182,6 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX
cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cosmossdk.io/api v0.7.6 h1:PC20PcXy1xYKH2KU4RMurVoFjjKkCgYRbVAD4PdqUuY=
cosmossdk.io/api v0.7.6/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38=
cosmossdk.io/client/v2 v2.0.0-beta.5.0.20241121152743-3dad36d9a29e h1:NqQEVIjRqSdsAfTI9uDRZ1oU/cQuCoAbUuIkndQM+Bo=
cosmossdk.io/client/v2 v2.0.0-beta.5.0.20241121152743-3dad36d9a29e/go.mod h1:4p0P6o0ro+FizakJUYS9SeM94RNbv0thLmkHRw5o5as=
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=

View File

@ -212,6 +212,7 @@ require (
// Below are the long-lived replace for tests.
replace (
cosmossdk.io/api => ../api
// We always want to test against the latest version of the simapp.
cosmossdk.io/simapp => ../simapp
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0

View File

@ -182,8 +182,6 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX
cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cosmossdk.io/api v0.7.6 h1:PC20PcXy1xYKH2KU4RMurVoFjjKkCgYRbVAD4PdqUuY=
cosmossdk.io/api v0.7.6/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38=
cosmossdk.io/client/v2 v2.0.0-beta.5.0.20241121152743-3dad36d9a29e h1:NqQEVIjRqSdsAfTI9uDRZ1oU/cQuCoAbUuIkndQM+Bo=
cosmossdk.io/client/v2 v2.0.0-beta.5.0.20241121152743-3dad36d9a29e/go.mod h1:4p0P6o0ro+FizakJUYS9SeM94RNbv0thLmkHRw5o5as=
cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=

177
x/epochs/README.md Normal file
View File

@ -0,0 +1,177 @@
---
sidebar_position: 1
---
# `x/epochs`
## Abstract
Often in the SDK, we would like to run certain code every-so often. The
purpose of `epochs` module is to allow other modules to set that they
would like to be signaled once every period. So another module can
specify it wants to execute code once a week, starting at UTC-time = x.
`epochs` creates a generalized epoch interface to other modules so that
they can easily be signaled upon such events.
## Contents
1. **[Concept](#concepts)**
2. **[State](#state)**
3. **[Events](#events)**
4. **[Keeper](#keepers)**
5. **[Hooks](#hooks)**
6. **[Queries](#queries)**
## Concepts
The epochs module defines on-chain timers that execute at fixed time intervals.
Other SDK modules can then register logic to be executed at the timer ticks.
We refer to the period in between two timer ticks as an "epoch".
Every timer has a unique identifier.
Every epoch will have a start time, and an end time, where `end time = start time + timer interval`.
On mainnet, we only utilize one identifier, with a time interval of `one day`.
The timer will tick at the first block whose block time is greater than the timer end time,
and set the start as the prior timer end time. (Notably, it's not set to the block time!)
This means that if the chain has been down for a while, you will get one timer tick per block,
until the timer has caught up.
## State
The Epochs module keeps a single `EpochInfo` per identifier.
This contains the current state of the timer with the corresponding identifier.
Its fields are modified at every timer tick.
EpochInfos are initialized as part of genesis initialization or upgrade logic,
and are only modified on begin blockers.
## Events
The `epochs` module emits the following events:
### BeginBlocker
| Type | Attribute Key | Attribute Value |
| ----------- | ------------- | --------------- |
| epoch_start | epoch_number | {epoch_number} |
| epoch_start | start_time | {start_time} |
### EndBlocker
| Type | Attribute Key | Attribute Value |
| --------- | ------------- | --------------- |
| epoch_end | epoch_number | {epoch_number} |
## Keepers
### Keeper functions
Epochs keeper module provides utility functions to manage epochs.
## Hooks
```go
// the first block whose timestamp is after the duration is counted as the end of the epoch
AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64)
// new epoch is next block of epoch end block
BeforeEpochStart(ctx sdk.Context, epochIdentifier string, epochNumber int64)
```
### How modules receive hooks
On hook receiver function of other modules, they need to filter
`epochIdentifier` and only do executions for only specific
epochIdentifier. Filtering epochIdentifier could be in `Params` of other
modules so that they can be modified by governance.
This is the standard dev UX of this:
```golang
func (k MyModuleKeeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64) {
params := k.GetParams(ctx)
if epochIdentifier == params.DistrEpochIdentifier {
// my logic
}
}
```
### Panic isolation
If a given epoch hook panics, its state update is reverted, but we keep
proceeding through the remaining hooks. This allows more advanced epoch
logic to be used, without concern over state machine halting, or halting
subsequent modules.
This does mean that if there is behavior you expect from a prior epoch
hook, and that epoch hook reverted, your hook may also have an issue. So
do keep in mind "what if a prior hook didn't get executed" in the safety
checks you consider for a new epoch hook.
## Queries
The Epochs module provides the following queries to check the module's state.
```protobuf
service Query {
// EpochInfos provide running epochInfos
rpc EpochInfos(QueryEpochsInfoRequest) returns (QueryEpochsInfoResponse) {}
// CurrentEpoch provide current epoch of specified identifier
rpc CurrentEpoch(QueryCurrentEpochRequest) returns (QueryCurrentEpochResponse) {}
}
```
### Epoch Infos
Query the currently running epochInfos
```sh
<appd> query epochs epoch-infos
```
:::details Example
An example output:
```sh
epochs:
- current_epoch: "183"
current_epoch_start_height: "2438409"
current_epoch_start_time: "2021-12-18T17:16:09.898160996Z"
duration: 86400s
epoch_counting_started: true
identifier: day
start_time: "2021-06-18T17:00:00Z"
- current_epoch: "26"
current_epoch_start_height: "2424854"
current_epoch_start_time: "2021-12-17T17:02:07.229632445Z"
duration: 604800s
epoch_counting_started: true
identifier: week
start_time: "2021-06-18T17:00:00Z"
```
:::
### Current Epoch
Query the current epoch by the specified identifier
```sh
<appd> query epochs current-epoch [identifier]
```
:::details Example
Query the current `day` epoch:
```sh
<appd> query epochs current-epoch day
```
Which in this example outputs:
```sh
current_epoch: "183"
```
:::

27
x/epochs/autocli.go Normal file
View File

@ -0,0 +1,27 @@
package epochs
import (
autocliv1 "cosmossdk.io/api/cosmos/autocli/v1"
epochsv1beta1 "cosmossdk.io/api/cosmos/epochs/v1beta1"
)
// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface.
func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {
return &autocliv1.ModuleOptions{
Query: &autocliv1.ServiceCommandDescriptor{
Service: epochsv1beta1.Query_ServiceDesc.ServiceName,
RpcCommandOptions: []*autocliv1.RpcCommandOptions{
{
RpcMethod: "EpochInfos",
Use: "epoch-infos",
Short: "Query running epoch infos",
},
{
RpcMethod: "CurrentEpoch",
Use: "current-epoch",
Short: "Query current epoch by specified identifier",
},
},
},
}
}

71
x/epochs/depinject.go Normal file
View File

@ -0,0 +1,71 @@
package epochs
import (
"fmt"
"maps"
"slices"
modulev1 "cosmossdk.io/api/cosmos/epochs/module/v1"
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/store"
"cosmossdk.io/depinject"
"cosmossdk.io/depinject/appconfig"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/epochs/keeper"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
var _ depinject.OnePerModuleType = AppModule{}
// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (am AppModule) IsOnePerModuleType() {}
func init() {
appconfig.RegisterModule(&modulev1.Module{},
appconfig.Provide(ProvideModule),
appconfig.Invoke(InvokeSetHooks),
)
}
type ModuleInputs struct {
depinject.In
Config *modulev1.Module
Cdc codec.Codec
StoreService store.KVStoreService
}
type ModuleOutputs struct {
depinject.Out
EpochKeeper keeper.Keeper
Module appmodule.AppModule
}
func ProvideModule(in ModuleInputs) ModuleOutputs {
k := keeper.NewKeeper(in.StoreService, in.Cdc)
m := NewAppModule(in.Cdc, k)
return ModuleOutputs{EpochKeeper: k, Module: m}
}
func InvokeSetHooks(keeper keeper.Keeper, hooks map[string]types.EpochHooksWrapper) error {
if hooks == nil {
return nil
}
// Default ordering is lexical by module name.
// Explicit ordering can be added to the module config if required.
modNames := slices.Sorted(maps.Keys(hooks))
var multiHooks types.MultiEpochHooks
for _, modName := range modNames {
hook, ok := hooks[modName]
if !ok {
return fmt.Errorf("can't find epoch hooks for module %s", modName)
}
multiHooks = append(multiHooks, hook)
}
keeper.SetHooks(multiHooks)
return nil
}

91
x/epochs/keeper/abci.go Normal file
View File

@ -0,0 +1,91 @@
package keeper
import (
"fmt"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
// BeginBlocker of epochs module.
func (k *Keeper) BeginBlocker(ctx sdk.Context) error {
start := telemetry.Now()
defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyBeginBlocker)
header := ctx.BlockHeader()
err := k.EpochInfo.Walk(
ctx,
nil,
func(key string, epochInfo types.EpochInfo) (stop bool, err error) {
// If blocktime < initial epoch start time, return
if header.Time.Before(epochInfo.StartTime) {
return false, nil
}
// if epoch counting hasn't started, signal we need to start.
shouldInitialEpochStart := !epochInfo.EpochCountingStarted
epochEndTime := epochInfo.CurrentEpochStartTime.Add(epochInfo.Duration)
shouldEpochStart := (header.Time.After(epochEndTime)) || shouldInitialEpochStart
if !shouldEpochStart {
return false, nil
}
epochInfo.CurrentEpochStartHeight = header.Height
if shouldInitialEpochStart {
epochInfo.EpochCountingStarted = true
epochInfo.CurrentEpoch = 1
epochInfo.CurrentEpochStartTime = epochInfo.StartTime
ctx.Logger().Debug(fmt.Sprintf("Starting new epoch with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
} else {
err := ctx.EventManager().EmitTypedEvent(&types.EventEpochEnd{
EpochNumber: epochInfo.CurrentEpoch,
})
if err != nil {
return false, err
}
if err != nil {
return false, nil
}
cacheCtx, writeFn := ctx.CacheContext()
if err := k.AfterEpochEnd(cacheCtx, epochInfo.Identifier, epochInfo.CurrentEpoch); err != nil {
// purposely ignoring the error here not to halt the chain if the hook fails
ctx.Logger().Error(fmt.Sprintf("Error after epoch end with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
} else {
writeFn()
}
epochInfo.CurrentEpoch += 1
epochInfo.CurrentEpochStartTime = epochInfo.CurrentEpochStartTime.Add(epochInfo.Duration)
ctx.Logger().Debug(fmt.Sprintf("Starting epoch with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
}
// emit new epoch start event, set epoch info, and run BeforeEpochStart hook
err = ctx.EventManager().EmitTypedEvent(&types.EventEpochStart{
EpochNumber: epochInfo.CurrentEpoch,
EpochStartTime: epochInfo.CurrentEpochStartTime.Unix(),
})
if err != nil {
return false, err
}
err = k.EpochInfo.Set(ctx, epochInfo.Identifier, epochInfo)
if err != nil {
ctx.Logger().Error(fmt.Sprintf("Error set epoch info with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
return false, nil
}
cacheCtx, writeFn := ctx.CacheContext()
if err := k.BeforeEpochStart(cacheCtx, epochInfo.Identifier, epochInfo.CurrentEpoch); err != nil {
// purposely ignoring the error here not to halt the chain if the hook fails
ctx.Logger().Error(fmt.Sprintf("Error before epoch start with identifier %s epoch number %d", epochInfo.Identifier, epochInfo.CurrentEpoch))
} else {
writeFn()
}
return false, nil
},
)
return err
}

View File

@ -0,0 +1,190 @@
package keeper_test
import (
"maps"
"slices"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
// This test is responsible for testing how epochs increment based off
// of their initial conditions, and subsequent block height / times.
func (suite *KeeperTestSuite) TestEpochInfoBeginBlockChanges() {
block1Time := time.Unix(1656907200, 0).UTC()
const defaultIdentifier = "hourly"
const defaultDuration = time.Hour
// eps is short for epsilon - in this case a negligible amount of time.
const eps = time.Nanosecond
tests := map[string]struct {
// if identifier, duration is not set, we make it defaultIdentifier and defaultDuration.
// EpochCountingStarted, if unspecified, is inferred by CurrentEpoch == 0
// StartTime is inferred to be block1Time if left blank.
initialEpochInfo types.EpochInfo
blockHeightTimePairs map[int]time.Time
expEpochInfo types.EpochInfo
}{
"First block running at exactly start time sets epoch tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 1, CurrentEpochStartTime: block1Time, CurrentEpochStartHeight: 1},
},
"First block run sets start time, subsequent blocks within timer interval do not cause timer tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(time.Second), 3: block1Time.Add(time.Minute), 4: block1Time.Add(30 * time.Minute)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 1, CurrentEpochStartTime: block1Time, CurrentEpochStartHeight: 1},
},
"Second block at exactly timer interval later does not tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(defaultDuration)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 1, CurrentEpochStartTime: block1Time, CurrentEpochStartHeight: 1},
},
"Second block at timer interval + epsilon later does tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(defaultDuration).Add(eps)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 2, CurrentEpochStartTime: block1Time.Add(time.Hour), CurrentEpochStartHeight: 2},
},
"Downtime recovery (many intervals), first block causes 1 tick and sets current start time 1 interval ahead": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(24 * time.Hour)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 2, CurrentEpochStartTime: block1Time.Add(time.Hour), CurrentEpochStartHeight: 2},
},
"Downtime recovery (many intervals), second block is at tick 2, w/ start time 2 intervals ahead": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(24 * time.Hour), 3: block1Time.Add(24 * time.Hour).Add(eps)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 3, CurrentEpochStartTime: block1Time.Add(2 * time.Hour), CurrentEpochStartHeight: 3},
},
"Many blocks between first and second tick": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 1, CurrentEpochStartTime: block1Time},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(time.Second), 3: block1Time.Add(2 * time.Second), 4: block1Time.Add(time.Hour).Add(eps)},
expEpochInfo: types.EpochInfo{StartTime: block1Time, CurrentEpoch: 2, CurrentEpochStartTime: block1Time.Add(time.Hour), CurrentEpochStartHeight: 4},
},
"Distinct identifier and duration still works": {
initialEpochInfo: types.EpochInfo{Identifier: "hello", Duration: time.Minute, StartTime: block1Time, CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
blockHeightTimePairs: map[int]time.Time{2: block1Time.Add(time.Second), 3: block1Time.Add(time.Minute).Add(eps)},
expEpochInfo: types.EpochInfo{Identifier: "hello", Duration: time.Minute, StartTime: block1Time, CurrentEpoch: 2, CurrentEpochStartTime: block1Time.Add(time.Minute), CurrentEpochStartHeight: 3},
},
"StartTime in future won't get ticked on first block": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time.Add(time.Second), CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
// currentEpochStartHeight is 1 because that's when the timer was created on-chain
expEpochInfo: types.EpochInfo{StartTime: block1Time.Add(time.Second), CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}, CurrentEpochStartHeight: 1},
},
"StartTime in past will get ticked on first block": {
initialEpochInfo: types.EpochInfo{StartTime: block1Time.Add(-time.Second), CurrentEpoch: 0, CurrentEpochStartTime: time.Time{}},
expEpochInfo: types.EpochInfo{StartTime: block1Time.Add(-time.Second), CurrentEpoch: 1, CurrentEpochStartTime: block1Time.Add(-time.Second), CurrentEpochStartHeight: 1},
},
}
for name, test := range tests {
suite.Run(name, func() {
suite.SetupTest()
suite.Ctx = suite.Ctx.WithBlockHeight(1).WithBlockTime(block1Time)
initialEpoch := initializeBlankEpochInfoFields(test.initialEpochInfo, defaultIdentifier, defaultDuration)
err := suite.EpochsKeeper.AddEpochInfo(suite.Ctx, initialEpoch)
suite.Require().NoError(err)
err = suite.EpochsKeeper.BeginBlocker(suite.Ctx)
suite.Require().NoError(err)
// get sorted heights
heights := slices.SortedFunc(maps.Keys(test.blockHeightTimePairs), func(i, j int) int {
if test.blockHeightTimePairs[i].Before(test.blockHeightTimePairs[j]) {
return -1
} else if test.blockHeightTimePairs[i].After(test.blockHeightTimePairs[j]) {
return 1
}
return 0
})
for _, h := range heights {
// for each height in order, run begin block
suite.Ctx = suite.Ctx.WithBlockHeight(int64(h)).WithBlockTime(test.blockHeightTimePairs[h])
err := suite.EpochsKeeper.BeginBlocker(suite.Ctx)
suite.Require().NoError(err)
}
expEpoch := initializeBlankEpochInfoFields(test.expEpochInfo, initialEpoch.Identifier, initialEpoch.Duration)
actEpoch, err := suite.EpochsKeeper.EpochInfo.Get(suite.Ctx, initialEpoch.Identifier)
suite.Require().NoError(err)
suite.Require().Equal(expEpoch, actEpoch)
})
}
}
// initializeBlankEpochInfoFields set identifier, duration and epochCountingStarted if blank in epoch
func initializeBlankEpochInfoFields(epoch types.EpochInfo, identifier string, duration time.Duration) types.EpochInfo {
if epoch.Identifier == "" {
epoch.Identifier = identifier
}
if epoch.Duration == time.Duration(0) {
epoch.Duration = duration
}
epoch.EpochCountingStarted = (epoch.CurrentEpoch != 0)
return epoch
}
func TestEpochStartingOneMonthAfterInitGenesis(t *testing.T) {
ctx, epochsKeeper := Setup(t)
// On init genesis, default epochs information is set
// To check init genesis again, should make it fresh status
epochInfos, err := epochsKeeper.AllEpochInfos(ctx)
require.NoError(t, err)
for _, epochInfo := range epochInfos {
err := epochsKeeper.EpochInfo.Remove(ctx, epochInfo.Identifier)
require.NoError(t, err)
}
now := time.Now()
week := time.Hour * 24 * 7
month := time.Hour * 24 * 30
initialBlockHeight := int64(1)
ctx = ctx.WithBlockHeight(initialBlockHeight).WithBlockTime(now)
err = epochsKeeper.InitGenesis(ctx, types.GenesisState{
Epochs: []types.EpochInfo{
{
Identifier: "monthly",
StartTime: now.Add(month),
Duration: time.Hour * 24 * 30,
CurrentEpoch: 0,
CurrentEpochStartHeight: ctx.BlockHeight(),
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
},
},
})
require.NoError(t, err)
// epoch not started yet
epochInfo, err := epochsKeeper.EpochInfo.Get(ctx, "monthly")
require.NoError(t, err)
require.Equal(t, epochInfo.CurrentEpoch, int64(0))
require.Equal(t, epochInfo.CurrentEpochStartHeight, initialBlockHeight)
require.Equal(t, epochInfo.CurrentEpochStartTime, time.Time{})
require.Equal(t, epochInfo.EpochCountingStarted, false)
// after 1 week
ctx = ctx.WithBlockHeight(2).WithBlockTime(now.Add(week))
err = epochsKeeper.BeginBlocker(ctx)
require.NoError(t, err)
// epoch not started yet
epochInfo, err = epochsKeeper.EpochInfo.Get(ctx, "monthly")
require.NoError(t, err)
require.Equal(t, epochInfo.CurrentEpoch, int64(0))
require.Equal(t, epochInfo.CurrentEpochStartHeight, initialBlockHeight)
require.Equal(t, epochInfo.CurrentEpochStartTime, time.Time{})
require.Equal(t, epochInfo.EpochCountingStarted, false)
// after 1 month
ctx = ctx.WithBlockHeight(3).WithBlockTime(now.Add(month))
err = epochsKeeper.BeginBlocker(ctx)
require.NoError(t, err)
// epoch started
epochInfo, err = epochsKeeper.EpochInfo.Get(ctx, "monthly")
require.NoError(t, err)
require.Equal(t, epochInfo.CurrentEpoch, int64(1))
require.Equal(t, epochInfo.CurrentEpochStartHeight, ctx.BlockHeight())
require.Equal(t, epochInfo.CurrentEpochStartTime.UTC().String(), now.Add(month).UTC().String())
require.Equal(t, epochInfo.EpochCountingStarted, true)
}

66
x/epochs/keeper/epoch.go Normal file
View File

@ -0,0 +1,66 @@
package keeper
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
// GetEpochInfo returns epoch info by identifier.
func (k *Keeper) GetEpochInfo(ctx sdk.Context, identifier string) (types.EpochInfo, error) {
return k.EpochInfo.Get(ctx, identifier)
}
// AddEpochInfo adds a new epoch info. Will return an error if the epoch fails validation,
// or re-uses an existing identifier.
// This method also sets the start time if left unset, and sets the epoch start height.
func (k *Keeper) AddEpochInfo(ctx sdk.Context, epoch types.EpochInfo) error {
err := epoch.Validate()
if err != nil {
return err
}
// Check if identifier already exists
isExist, err := k.EpochInfo.Has(ctx, epoch.Identifier)
if err != nil {
return err
}
if isExist {
return fmt.Errorf("epoch with identifier %s already exists", epoch.Identifier)
}
// Initialize empty and default epoch values
if epoch.StartTime.IsZero() {
epoch.StartTime = ctx.BlockTime()
}
if epoch.CurrentEpochStartHeight == 0 {
epoch.CurrentEpochStartHeight = ctx.BlockHeight()
}
return k.EpochInfo.Set(ctx, epoch.Identifier, epoch)
}
// AllEpochInfos iterate through epochs to return all epochs info.
func (k *Keeper) AllEpochInfos(ctx sdk.Context) ([]types.EpochInfo, error) {
epochs := []types.EpochInfo{}
err := k.EpochInfo.Walk(
ctx,
nil,
func(key string, value types.EpochInfo) (stop bool, err error) {
epochs = append(epochs, value)
return false, nil
},
)
return epochs, err
}
// NumBlocksSinceEpochStart returns the number of blocks since the epoch started.
// if the epoch started on block N, then calling this during block N (after BeforeEpochStart)
// would return 0.
// Calling it any point in block N+1 (assuming the epoch doesn't increment) would return 1.
func (k *Keeper) NumBlocksSinceEpochStart(ctx sdk.Context, identifier string) (int64, error) {
epoch, err := k.EpochInfo.Get(ctx, identifier)
if err != nil {
return 0, fmt.Errorf("epoch with identifier %s not found", identifier)
}
return ctx.BlockHeight() - epoch.CurrentEpochStartHeight, nil
}

View File

@ -0,0 +1,101 @@
package keeper_test
import (
"time"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
func (s *KeeperTestSuite) TestAddEpochInfo() {
defaultIdentifier := "default_add_epoch_info_id"
defaultDuration := time.Hour
startBlockHeight := int64(100)
startBlockTime := time.Unix(1656907200, 0).UTC()
tests := map[string]struct {
addedEpochInfo types.EpochInfo
expErr bool
expEpochInfo types.EpochInfo
}{
"simple_add": {
addedEpochInfo: types.EpochInfo{
Identifier: defaultIdentifier,
StartTime: time.Time{},
Duration: defaultDuration,
CurrentEpoch: 0,
CurrentEpochStartHeight: 0,
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
},
expErr: false,
expEpochInfo: types.EpochInfo{
Identifier: defaultIdentifier,
StartTime: startBlockTime,
Duration: defaultDuration,
CurrentEpoch: 0,
CurrentEpochStartHeight: startBlockHeight,
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
},
},
"zero_duration": {
addedEpochInfo: types.EpochInfo{
Identifier: defaultIdentifier,
StartTime: time.Time{},
Duration: time.Duration(0),
CurrentEpoch: 0,
CurrentEpochStartHeight: 0,
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
},
expErr: true,
},
}
for name, test := range tests {
s.Run(name, func() {
s.SetupTest()
s.Ctx = s.Ctx.WithBlockHeight(startBlockHeight).WithBlockTime(startBlockTime)
err := s.EpochsKeeper.AddEpochInfo(s.Ctx, test.addedEpochInfo)
if !test.expErr {
s.Require().NoError(err)
actualEpochInfo, err := s.EpochsKeeper.EpochInfo.Get(s.Ctx, test.addedEpochInfo.Identifier)
s.Require().NoError(err)
s.Require().Equal(test.expEpochInfo, actualEpochInfo)
} else {
s.Require().Error(err)
}
})
}
}
func (s *KeeperTestSuite) TestDuplicateAddEpochInfo() {
identifier := "duplicate_add_epoch_info"
epochInfo := types.NewGenesisEpochInfo(identifier, time.Hour*24*30)
err := s.EpochsKeeper.AddEpochInfo(s.Ctx, epochInfo)
s.Require().NoError(err)
err = s.EpochsKeeper.AddEpochInfo(s.Ctx, epochInfo)
s.Require().Error(err)
}
func (s *KeeperTestSuite) TestEpochLifeCycle() {
s.SetupTest()
epochInfo := types.NewGenesisEpochInfo("monthly", time.Hour*24*30)
err := s.EpochsKeeper.AddEpochInfo(s.Ctx, epochInfo)
s.Require().NoError(err)
epochInfoSaved, err := s.EpochsKeeper.EpochInfo.Get(s.Ctx, "monthly")
s.Require().NoError(err)
// setup expected epoch info
expectedEpochInfo := epochInfo
expectedEpochInfo.StartTime = s.Ctx.BlockTime()
expectedEpochInfo.CurrentEpochStartHeight = s.Ctx.BlockHeight()
s.Require().Equal(expectedEpochInfo, epochInfoSaved)
allEpochs, err := s.EpochsKeeper.AllEpochInfos(s.Ctx)
s.Require().NoError(err)
s.Require().Len(allEpochs, 5)
s.Require().Equal(allEpochs[0].Identifier, "day") // alphabetical order
s.Require().Equal(allEpochs[1].Identifier, "hour")
s.Require().Equal(allEpochs[2].Identifier, "minute")
s.Require().Equal(allEpochs[3].Identifier, "monthly")
s.Require().Equal(allEpochs[4].Identifier, "week")
}

View File

@ -0,0 +1,28 @@
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
// InitGenesis sets epoch info from genesis
func (k *Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) error {
for _, epoch := range genState.Epochs {
err := k.AddEpochInfo(ctx, epoch)
if err != nil {
return err
}
}
return nil
}
// ExportGenesis returns the capability module's exported genesis.
func (k *Keeper) ExportGenesis(ctx sdk.Context) (*types.GenesisState, error) {
genesis := types.DefaultGenesis()
epochs, err := k.AllEpochInfos(ctx)
if err != nil {
return nil, err
}
genesis.Epochs = epochs
return genesis, nil
}

View File

@ -0,0 +1,95 @@
package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
func TestEpochsExportGenesis(t *testing.T) {
ctx, epochsKeeper := Setup(t)
chainStartTime := ctx.BlockTime()
chainStartHeight := ctx.BlockHeight()
genesis, err := epochsKeeper.ExportGenesis(ctx)
require.NoError(t, err)
require.Len(t, genesis.Epochs, 4)
expectedEpochs := types.DefaultGenesis().Epochs
for i := 0; i < len(expectedEpochs); i++ {
expectedEpochs[i].CurrentEpochStartHeight = chainStartHeight
expectedEpochs[i].StartTime = chainStartTime
}
require.Equal(t, expectedEpochs, genesis.Epochs)
}
func TestEpochsInitGenesis(t *testing.T) {
ctx, epochsKeeper := Setup(t)
// On init genesis, default epochs information is set
// To check init genesis again, should make it fresh status
epochInfos, err := epochsKeeper.AllEpochInfos(ctx)
require.NoError(t, err)
for _, epochInfo := range epochInfos {
err := epochsKeeper.EpochInfo.Remove(ctx, epochInfo.Identifier)
require.NoError(t, err)
}
// now := time.Now()
ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now().UTC())
// test genesisState validation
genesisState := types.GenesisState{
Epochs: []types.EpochInfo{
{
Identifier: "monthly",
StartTime: time.Time{},
Duration: time.Hour * 24,
CurrentEpoch: 0,
CurrentEpochStartHeight: ctx.BlockHeight(),
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: true,
},
{
Identifier: "monthly",
StartTime: time.Time{},
Duration: time.Hour * 24,
CurrentEpoch: 0,
CurrentEpochStartHeight: ctx.BlockHeight(),
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: true,
},
},
}
require.EqualError(t, genesisState.Validate(), "epoch identifier should be unique")
genesisState = types.GenesisState{
Epochs: []types.EpochInfo{
{
Identifier: "monthly",
StartTime: time.Time{},
Duration: time.Hour * 24,
CurrentEpoch: 0,
CurrentEpochStartHeight: ctx.BlockHeight(),
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: true,
},
},
}
err = epochsKeeper.InitGenesis(ctx, genesisState)
require.NoError(t, err)
epochInfo, err := epochsKeeper.EpochInfo.Get(ctx, "monthly")
require.NoError(t, err)
require.Equal(t, epochInfo.Identifier, "monthly")
require.Equal(t, epochInfo.StartTime.UTC().String(), ctx.BlockTime().UTC().String())
require.Equal(t, epochInfo.Duration, time.Hour*24)
require.Equal(t, epochInfo.CurrentEpoch, int64(0))
require.Equal(t, epochInfo.CurrentEpochStartHeight, ctx.BlockHeight())
require.Equal(t, epochInfo.CurrentEpochStartTime.UTC().String(), time.Time{}.String())
require.Equal(t, epochInfo.EpochCountingStarted, true)
}

View File

@ -0,0 +1,54 @@
package keeper
import (
"context"
"errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
var _ types.QueryServer = Querier{}
// Querier defines a wrapper around the x/epochs keeper providing gRPC method
// handlers.
type Querier struct {
Keeper
}
// NewQuerier initializes new querier.
func NewQuerier(k Keeper) Querier {
return Querier{Keeper: k}
}
// EpochInfos provide running epochInfos.
func (q Querier) EpochInfos(ctx context.Context, _ *types.QueryEpochInfosRequest) (*types.QueryEpochInfosResponse, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
epochs, err := q.Keeper.AllEpochInfos(sdkCtx)
return &types.QueryEpochInfosResponse{
Epochs: epochs,
}, err
}
// CurrentEpoch provides current epoch of specified identifier.
func (q Querier) CurrentEpoch(ctx context.Context, req *types.QueryCurrentEpochRequest) (*types.QueryCurrentEpochResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.Identifier == "" {
return nil, status.Error(codes.InvalidArgument, "identifier is empty")
}
info, err := q.Keeper.EpochInfo.Get(ctx, req.Identifier)
if err != nil {
return nil, errors.New("not available identifier")
}
return &types.QueryCurrentEpochResponse{
CurrentEpoch: info.CurrentEpoch,
}, nil
}

View File

@ -0,0 +1,22 @@
package keeper_test
import (
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
func (s *KeeperTestSuite) TestQueryEpochInfos() {
s.SetupTest()
queryClient := s.queryClient
// Check that querying epoch infos on default genesis returns the default genesis epoch infos
epochInfosResponse, err := queryClient.EpochInfos(s.Ctx, &types.QueryEpochInfosRequest{})
s.Require().NoError(err)
s.Require().Len(epochInfosResponse.Epochs, 4)
expectedEpochs := types.DefaultGenesis().Epochs
for id := range expectedEpochs {
expectedEpochs[id].StartTime = s.Ctx.BlockTime()
expectedEpochs[id].CurrentEpochStartHeight = s.Ctx.BlockHeight()
}
s.Require().Equal(expectedEpochs, epochInfosResponse.Epochs)
}

27
x/epochs/keeper/hooks.go Normal file
View File

@ -0,0 +1,27 @@
package keeper
import (
"context"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
// Hooks gets the hooks for governance Keeper
func (k *Keeper) Hooks() types.EpochHooks {
if k.hooks == nil {
// return a no-op implementation if no hooks are set
return types.MultiEpochHooks{}
}
return k.hooks
}
// AfterEpochEnd gets called at the end of the epoch, end of epoch is the timestamp of first block produced after epoch duration.
func (k *Keeper) AfterEpochEnd(ctx context.Context, identifier string, epochNumber int64) error {
return k.Hooks().AfterEpochEnd(ctx, identifier, epochNumber)
}
// BeforeEpochStart new epoch is next block of epoch end block
func (k *Keeper) BeforeEpochStart(ctx context.Context, identifier string, epochNumber int64) error {
return k.Hooks().BeforeEpochStart(ctx, identifier, epochNumber)
}

45
x/epochs/keeper/keeper.go Normal file
View File

@ -0,0 +1,45 @@
package keeper
import (
"cosmossdk.io/collections"
"cosmossdk.io/core/store"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
type Keeper struct {
storeService store.KVStoreService
cdc codec.BinaryCodec
hooks types.EpochHooks
Schema collections.Schema
EpochInfo collections.Map[string, types.EpochInfo]
}
// NewKeeper returns a new keeper by codec and storeKey inputs.
func NewKeeper(storeService store.KVStoreService, cdc codec.BinaryCodec) Keeper {
sb := collections.NewSchemaBuilder(storeService)
k := Keeper{
storeService: storeService,
cdc: cdc,
EpochInfo: collections.NewMap(sb, types.KeyPrefixEpoch, "epoch_info", collections.StringKey, codec.CollValue[types.EpochInfo](cdc)),
}
schema, err := sb.Build()
if err != nil {
panic(err)
}
k.Schema = schema
return k
}
// SetHooks sets the hooks on the x/epochs keeper.
func (k *Keeper) SetHooks(eh types.EpochHooks) {
if k.hooks != nil {
panic("cannot set epochs hooks twice")
}
k.hooks = eh
}

View File

@ -0,0 +1,89 @@
package keeper_test
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
epochskeeper "github.com/cosmos/cosmos-sdk/x/epochs/keeper"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
type KeeperTestSuite struct {
suite.Suite
Ctx sdk.Context
EpochsKeeper epochskeeper.Keeper
queryClient types.QueryClient
}
func (s *KeeperTestSuite) SetupTest() {
ctx, epochsKeeper := Setup(s.T())
s.Ctx = ctx
s.EpochsKeeper = epochsKeeper
queryRouter := baseapp.NewGRPCQueryRouter()
cfg := module.NewConfigurator(nil, nil, queryRouter)
types.RegisterQueryServer(cfg.QueryServer(), epochskeeper.NewQuerier(s.EpochsKeeper))
grpcQueryService := &baseapp.QueryServiceTestHelper{
GRPCQueryRouter: queryRouter,
Ctx: s.Ctx,
}
encCfg := moduletestutil.MakeTestEncodingConfig()
grpcQueryService.SetInterfaceRegistry(encCfg.InterfaceRegistry)
s.queryClient = types.NewQueryClient(grpcQueryService)
}
func Setup(t *testing.T) (sdk.Context, epochskeeper.Keeper) {
t.Helper()
key := storetypes.NewKVStoreKey(types.StoreKey)
storeService := runtime.NewKVStoreService(key)
testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
ctx := testCtx.Ctx.WithBlockTime(time.Now().UTC())
encCfg := moduletestutil.MakeTestEncodingConfig()
epochsKeeper := epochskeeper.NewKeeper(
storeService,
encCfg.Codec,
)
epochsKeeper.SetHooks(types.NewMultiEpochHooks())
ctx = ctx.WithBlockTime(time.Now().UTC()).WithBlockHeight(1).WithChainID("epochs")
err := epochsKeeper.InitGenesis(ctx, *types.DefaultGenesis())
require.NoError(t, err)
SetEpochStartTime(ctx, epochsKeeper)
return ctx, epochsKeeper
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
func SetEpochStartTime(ctx sdk.Context, epochsKeeper epochskeeper.Keeper) {
epochs, err := epochsKeeper.AllEpochInfos(ctx)
if err != nil {
panic(err)
}
for _, epoch := range epochs {
epoch.StartTime = ctx.BlockTime()
err := epochsKeeper.EpochInfo.Remove(ctx, epoch.Identifier)
if err != nil {
panic(err)
}
err = epochsKeeper.AddEpochInfo(ctx, epoch)
if err != nil {
panic(err)
}
}
}

155
x/epochs/module.go Normal file
View File

@ -0,0 +1,155 @@
package epochs
import (
"context"
"encoding/json"
"fmt"
gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"
"google.golang.org/grpc"
"cosmossdk.io/core/appmodule"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/epochs/keeper"
"github.com/cosmos/cosmos-sdk/x/epochs/simulation"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
var (
_ module.AppModuleSimulation = AppModule{}
_ module.HasGenesis = AppModule{}
_ appmodule.AppModule = AppModule{}
_ appmodule.HasBeginBlocker = AppModule{}
)
const ConsensusVersion = 1
// AppModule implements the AppModule interface for the epochs module.
type AppModule struct {
cdc codec.Codec
keeper keeper.Keeper
}
// NewAppModule creates a new AppModule object.
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule {
return AppModule{
cdc: cdc,
keeper: keeper,
}
}
// IsAppModule implements the appmodule.AppModule interface.
func (am AppModule) IsAppModule() {}
// Name returns the epochs module's name.
// Deprecated: kept for legacy reasons.
func (AppModule) Name() string {
return types.ModuleName
}
// RegisterLegacyAminoCodec registers the epochs module's types for the given codec.
func (AppModule) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) {}
func (AppModule) RegisterInterfaces(_ codectypes.InterfaceRegistry) {}
// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the epochs module.
func (AppModule) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *gwruntime.ServeMux) {
if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
panic(err)
}
}
// RegisterServices registers module services.
func (am AppModule) RegisterServices(registrar grpc.ServiceRegistrar) error {
types.RegisterQueryServer(registrar, keeper.NewQuerier(am.keeper))
return nil
}
// DefaultGenesis returns the epochs module's default genesis state.
func (am AppModule) DefaultGenesis(_ codec.JSONCodec) json.RawMessage {
data, err := am.cdc.MarshalJSON(types.DefaultGenesis())
if err != nil {
panic(err)
}
return data
}
// ValidateGenesis performs genesis state validation for the epochs module.
func (am AppModule) ValidateGenesis(_ codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error {
var gs types.GenesisState
if err := am.cdc.UnmarshalJSON(bz, &gs); err != nil {
return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err)
}
return gs.Validate()
}
// InitGenesis performs the epochs module's genesis initialization
func (am AppModule) InitGenesis(ctx sdk.Context, _ codec.JSONCodec, bz json.RawMessage) {
var gs types.GenesisState
err := am.cdc.UnmarshalJSON(bz, &gs)
if err != nil {
panic(fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err))
}
if err := am.keeper.InitGenesis(ctx, gs); err != nil {
panic(err)
}
}
// ExportGenesis returns the epochs module's exported genesis state as raw JSON bytes.
func (am AppModule) ExportGenesis(ctx sdk.Context, _ codec.JSONCodec) json.RawMessage {
gs, err := am.keeper.ExportGenesis(ctx)
if err != nil {
panic(err)
}
bz, err := am.cdc.MarshalJSON(gs)
if err != nil {
panic(err)
}
return bz
}
// ConsensusVersion implements HasConsensusVersion
func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion }
// BeginBlock executes all ABCI BeginBlock logic respective to the epochs module.
func (am AppModule) BeginBlock(ctx context.Context) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
return am.keeper.BeginBlocker(sdkCtx)
}
// AppModuleSimulation functions
// WeightedOperations is a no-op.
func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation {
return nil
}
// GenerateGenesisState creates a randomized GenState of the epochs module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
}
// RegisterStoreDecoder registers a decoder for epochs module's types
func (am AppModule) RegisterStoreDecoder(sdr simtypes.StoreDecoderRegistry) {
sdr[types.StoreKey] = simtypes.NewStoreDecoderFuncFromCollectionsSchema(am.keeper.Schema)
}
// TODO add when we have collections full support with schema
/*
// ModuleCodec implements schema.HasModuleCodec.
// It allows the indexer to decode the module's KVPairUpdate.
func (am AppModule) ModuleCodec() (schema.ModuleCodec, error) {
return am.keeper.Schema.ModuleCodec(collections.IndexingOptions{})
}
*/

View File

@ -0,0 +1,38 @@
package simulation
import (
"math/rand"
"strconv"
"time"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
// GenDuration randomized GenDuration
func GenDuration(r *rand.Rand) time.Duration {
return time.Hour * time.Duration(r.Intn(168)+1) // between 1 hour to 1 week
}
func RandomizedEpochs(r *rand.Rand) []types.EpochInfo {
// Gen max 10 epoch
n := r.Intn(11)
var epochs []types.EpochInfo
for i := 0; i < n; i++ {
identifier := "identifier-" + strconv.Itoa(i)
duration := GenDuration(r)
epoch := types.NewGenesisEpochInfo(identifier, duration)
epochs = append(epochs, epoch)
}
return epochs
}
// RandomizedGenState generates a random GenesisState for distribution
func RandomizedGenState(simState *module.SimulationState) {
epochs := RandomizedEpochs(simState.Rand)
epochsGenesis := types.GenesisState{
Epochs: epochs,
}
simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(&epochsGenesis)
}

495
x/epochs/types/events.pb.go Normal file
View File

@ -0,0 +1,495 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/epochs/v1beta1/events.proto
package types
import (
fmt "fmt"
proto "github.com/cosmos/gogoproto/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
// EventEpochEnd is an event emitted when an epoch end.
type EventEpochEnd struct {
EpochNumber int64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"`
}
func (m *EventEpochEnd) Reset() { *m = EventEpochEnd{} }
func (m *EventEpochEnd) String() string { return proto.CompactTextString(m) }
func (*EventEpochEnd) ProtoMessage() {}
func (*EventEpochEnd) Descriptor() ([]byte, []int) {
return fileDescriptor_691f9b4b0a500cb4, []int{0}
}
func (m *EventEpochEnd) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *EventEpochEnd) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_EventEpochEnd.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 *EventEpochEnd) XXX_Merge(src proto.Message) {
xxx_messageInfo_EventEpochEnd.Merge(m, src)
}
func (m *EventEpochEnd) XXX_Size() int {
return m.Size()
}
func (m *EventEpochEnd) XXX_DiscardUnknown() {
xxx_messageInfo_EventEpochEnd.DiscardUnknown(m)
}
var xxx_messageInfo_EventEpochEnd proto.InternalMessageInfo
func (m *EventEpochEnd) GetEpochNumber() int64 {
if m != nil {
return m.EpochNumber
}
return 0
}
// EventEpochStart is an event emitted when an epoch start.
type EventEpochStart struct {
EpochNumber int64 `protobuf:"varint,1,opt,name=epoch_number,json=epochNumber,proto3" json:"epoch_number,omitempty"`
EpochStartTime int64 `protobuf:"varint,2,opt,name=epoch_start_time,json=epochStartTime,proto3" json:"epoch_start_time,omitempty"`
}
func (m *EventEpochStart) Reset() { *m = EventEpochStart{} }
func (m *EventEpochStart) String() string { return proto.CompactTextString(m) }
func (*EventEpochStart) ProtoMessage() {}
func (*EventEpochStart) Descriptor() ([]byte, []int) {
return fileDescriptor_691f9b4b0a500cb4, []int{1}
}
func (m *EventEpochStart) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *EventEpochStart) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_EventEpochStart.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 *EventEpochStart) XXX_Merge(src proto.Message) {
xxx_messageInfo_EventEpochStart.Merge(m, src)
}
func (m *EventEpochStart) XXX_Size() int {
return m.Size()
}
func (m *EventEpochStart) XXX_DiscardUnknown() {
xxx_messageInfo_EventEpochStart.DiscardUnknown(m)
}
var xxx_messageInfo_EventEpochStart proto.InternalMessageInfo
func (m *EventEpochStart) GetEpochNumber() int64 {
if m != nil {
return m.EpochNumber
}
return 0
}
func (m *EventEpochStart) GetEpochStartTime() int64 {
if m != nil {
return m.EpochStartTime
}
return 0
}
func init() {
proto.RegisterType((*EventEpochEnd)(nil), "cosmos.epochs.v1beta1.EventEpochEnd")
proto.RegisterType((*EventEpochStart)(nil), "cosmos.epochs.v1beta1.EventEpochStart")
}
func init() {
proto.RegisterFile("cosmos/epochs/v1beta1/events.proto", fileDescriptor_691f9b4b0a500cb4)
}
var fileDescriptor_691f9b4b0a500cb4 = []byte{
// 211 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4a, 0xce, 0x2f, 0xce,
0xcd, 0x2f, 0xd6, 0x4f, 0x2d, 0xc8, 0x4f, 0xce, 0x28, 0xd6, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49,
0x34, 0xd4, 0x4f, 0x2d, 0x4b, 0xcd, 0x2b, 0x29, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12,
0x85, 0xa8, 0xd1, 0x83, 0xa8, 0xd1, 0x83, 0xaa, 0x51, 0x32, 0xe2, 0xe2, 0x75, 0x05, 0x29, 0x73,
0x05, 0x09, 0xbb, 0xe6, 0xa5, 0x08, 0x29, 0x72, 0xf1, 0x80, 0x95, 0xc4, 0xe7, 0x95, 0xe6, 0x26,
0xa5, 0x16, 0x49, 0x30, 0x2a, 0x30, 0x6a, 0x30, 0x07, 0x71, 0x83, 0xc5, 0xfc, 0xc0, 0x42, 0x4a,
0x71, 0x5c, 0xfc, 0x08, 0x3d, 0xc1, 0x25, 0x89, 0x45, 0x25, 0x44, 0xe8, 0x12, 0xd2, 0xe0, 0x12,
0x80, 0x28, 0x29, 0x06, 0xe9, 0x88, 0x2f, 0xc9, 0xcc, 0x4d, 0x95, 0x60, 0x02, 0x2b, 0xe3, 0x4b,
0x85, 0x1b, 0x14, 0x92, 0x99, 0x9b, 0xea, 0xe4, 0x7a, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72,
0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7,
0x72, 0x0c, 0x51, 0xda, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x50,
0x3f, 0x43, 0x28, 0xdd, 0xe2, 0x94, 0x6c, 0xfd, 0x0a, 0x58, 0x00, 0x94, 0x54, 0x16, 0xa4, 0x16,
0x27, 0xb1, 0x81, 0x3d, 0x6e, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x2e, 0xe8, 0x93, 0x1e,
0x01, 0x00, 0x00,
}
func (m *EventEpochEnd) 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 *EventEpochEnd) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *EventEpochEnd) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.EpochNumber != 0 {
i = encodeVarintEvents(dAtA, i, uint64(m.EpochNumber))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *EventEpochStart) 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 *EventEpochStart) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *EventEpochStart) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.EpochStartTime != 0 {
i = encodeVarintEvents(dAtA, i, uint64(m.EpochStartTime))
i--
dAtA[i] = 0x10
}
if m.EpochNumber != 0 {
i = encodeVarintEvents(dAtA, i, uint64(m.EpochNumber))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintEvents(dAtA []byte, offset int, v uint64) int {
offset -= sovEvents(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *EventEpochEnd) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.EpochNumber != 0 {
n += 1 + sovEvents(uint64(m.EpochNumber))
}
return n
}
func (m *EventEpochStart) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.EpochNumber != 0 {
n += 1 + sovEvents(uint64(m.EpochNumber))
}
if m.EpochStartTime != 0 {
n += 1 + sovEvents(uint64(m.EpochStartTime))
}
return n
}
func sovEvents(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozEvents(x uint64) (n int) {
return sovEvents(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *EventEpochEnd) 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 ErrIntOverflowEvents
}
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: EventEpochEnd: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: EventEpochEnd: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType)
}
m.EpochNumber = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvents
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.EpochNumber |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipEvents(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthEvents
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *EventEpochStart) 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 ErrIntOverflowEvents
}
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: EventEpochStart: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: EventEpochStart: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field EpochNumber", wireType)
}
m.EpochNumber = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvents
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.EpochNumber |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field EpochStartTime", wireType)
}
m.EpochStartTime = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvents
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.EpochStartTime |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipEvents(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthEvents
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipEvents(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, ErrIntOverflowEvents
}
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, ErrIntOverflowEvents
}
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, ErrIntOverflowEvents
}
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, ErrInvalidLengthEvents
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupEvents
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthEvents
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthEvents = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowEvents = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupEvents = fmt.Errorf("proto: unexpected end of group")
)

69
x/epochs/types/genesis.go Normal file
View File

@ -0,0 +1,69 @@
package types
import (
"errors"
"time"
)
// DefaultIndex is the default capability global index.
const DefaultIndex uint64 = 1
func NewGenesisState(epochs []EpochInfo) *GenesisState {
return &GenesisState{Epochs: epochs}
}
// DefaultGenesis returns the default Capability genesis state.
func DefaultGenesis() *GenesisState {
epochs := []EpochInfo{
NewGenesisEpochInfo("day", time.Hour*24), // alphabetical order
NewGenesisEpochInfo("hour", time.Hour),
NewGenesisEpochInfo("minute", time.Minute),
NewGenesisEpochInfo("week", time.Hour*24*7),
}
return NewGenesisState(epochs)
}
// Validate performs basic genesis state validation returning an error upon any
// failure.
func (gs GenesisState) Validate() error {
epochIdentifiers := map[string]bool{}
for _, epoch := range gs.Epochs {
if err := epoch.Validate(); err != nil {
return err
}
if epochIdentifiers[epoch.Identifier] {
return errors.New("epoch identifier should be unique")
}
epochIdentifiers[epoch.Identifier] = true
}
return nil
}
// Validate also validates epoch info.
func (epoch EpochInfo) Validate() error {
if epoch.Identifier == "" {
return errors.New("epoch identifier should NOT be empty")
}
if epoch.Duration == 0 {
return errors.New("epoch duration should NOT be 0")
}
if epoch.CurrentEpoch < 0 {
return errors.New("epoch CurrentEpoch must be non-negative")
}
if epoch.CurrentEpochStartHeight < 0 {
return errors.New("epoch CurrentEpochStartHeight must be non-negative")
}
return nil
}
func NewGenesisEpochInfo(identifier string, duration time.Duration) EpochInfo {
return EpochInfo{
Identifier: identifier,
StartTime: time.Time{},
Duration: duration,
CurrentEpoch: 0,
CurrentEpochStartHeight: 0,
CurrentEpochStartTime: time.Time{},
EpochCountingStarted: false,
}
}

View File

@ -0,0 +1,821 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/epochs/v1beta1/genesis.proto
package types
import (
fmt "fmt"
_ "github.com/cosmos/gogoproto/gogoproto"
proto "github.com/cosmos/gogoproto/proto"
github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types"
_ "google.golang.org/protobuf/types/known/durationpb"
_ "google.golang.org/protobuf/types/known/timestamppb"
io "io"
math "math"
math_bits "math/bits"
time "time"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
var _ = time.Kitchen
// 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
// EpochInfo is a struct that describes the data going into
// a timer defined by the x/epochs module.
type EpochInfo struct {
// identifier is a unique reference to this particular timer.
Identifier string `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"`
// start_time is the time at which the timer first ever ticks.
// If start_time is in the future, the epoch will not begin until the start
// time.
StartTime time.Time `protobuf:"bytes,2,opt,name=start_time,json=startTime,proto3,stdtime" json:"start_time"`
// duration is the time in between epoch ticks.
// In order for intended behavior to be met, duration should
// be greater than the chains expected block time.
// Duration must be non-zero.
Duration time.Duration `protobuf:"bytes,3,opt,name=duration,proto3,stdduration" json:"duration,omitempty"`
// current_epoch is the current epoch number, or in other words,
// how many times has the timer 'ticked'.
// The first tick (current_epoch=1) is defined as
// the first block whose blocktime is greater than the EpochInfo start_time.
CurrentEpoch int64 `protobuf:"varint,4,opt,name=current_epoch,json=currentEpoch,proto3" json:"current_epoch,omitempty"`
// current_epoch_start_time describes the start time of the current timer
// interval. The interval is (current_epoch_start_time,
// current_epoch_start_time + duration] When the timer ticks, this is set to
// current_epoch_start_time = last_epoch_start_time + duration only one timer
// tick for a given identifier can occur per block.
//
// NOTE! The current_epoch_start_time may diverge significantly from the
// wall-clock time the epoch began at. Wall-clock time of epoch start may be
// >> current_epoch_start_time. Suppose current_epoch_start_time = 10,
// duration = 5. Suppose the chain goes offline at t=14, and comes back online
// at t=30, and produces blocks at every successive time. (t=31, 32, etc.)
// * The t=30 block will start the epoch for (10, 15]
// * The t=31 block will start the epoch for (15, 20]
// * The t=32 block will start the epoch for (20, 25]
// * The t=33 block will start the epoch for (25, 30]
// * The t=34 block will start the epoch for (30, 35]
// * The **t=36** block will start the epoch for (35, 40]
CurrentEpochStartTime time.Time `protobuf:"bytes,5,opt,name=current_epoch_start_time,json=currentEpochStartTime,proto3,stdtime" json:"current_epoch_start_time"`
// epoch_counting_started is a boolean, that indicates whether this
// epoch timer has began yet.
EpochCountingStarted bool `protobuf:"varint,6,opt,name=epoch_counting_started,json=epochCountingStarted,proto3" json:"epoch_counting_started,omitempty"`
// current_epoch_start_height is the block height at which the current epoch
// started. (The block height at which the timer last ticked)
CurrentEpochStartHeight int64 `protobuf:"varint,8,opt,name=current_epoch_start_height,json=currentEpochStartHeight,proto3" json:"current_epoch_start_height,omitempty"`
}
func (m *EpochInfo) Reset() { *m = EpochInfo{} }
func (m *EpochInfo) String() string { return proto.CompactTextString(m) }
func (*EpochInfo) ProtoMessage() {}
func (*EpochInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_3a3d6d4398875177, []int{0}
}
func (m *EpochInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *EpochInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_EpochInfo.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 *EpochInfo) XXX_Merge(src proto.Message) {
xxx_messageInfo_EpochInfo.Merge(m, src)
}
func (m *EpochInfo) XXX_Size() int {
return m.Size()
}
func (m *EpochInfo) XXX_DiscardUnknown() {
xxx_messageInfo_EpochInfo.DiscardUnknown(m)
}
var xxx_messageInfo_EpochInfo proto.InternalMessageInfo
func (m *EpochInfo) GetIdentifier() string {
if m != nil {
return m.Identifier
}
return ""
}
func (m *EpochInfo) GetStartTime() time.Time {
if m != nil {
return m.StartTime
}
return time.Time{}
}
func (m *EpochInfo) GetDuration() time.Duration {
if m != nil {
return m.Duration
}
return 0
}
func (m *EpochInfo) GetCurrentEpoch() int64 {
if m != nil {
return m.CurrentEpoch
}
return 0
}
func (m *EpochInfo) GetCurrentEpochStartTime() time.Time {
if m != nil {
return m.CurrentEpochStartTime
}
return time.Time{}
}
func (m *EpochInfo) GetEpochCountingStarted() bool {
if m != nil {
return m.EpochCountingStarted
}
return false
}
func (m *EpochInfo) GetCurrentEpochStartHeight() int64 {
if m != nil {
return m.CurrentEpochStartHeight
}
return 0
}
// GenesisState defines the epochs module's genesis state.
type GenesisState struct {
Epochs []EpochInfo `protobuf:"bytes,1,rep,name=epochs,proto3" json:"epochs"`
}
func (m *GenesisState) Reset() { *m = GenesisState{} }
func (m *GenesisState) String() string { return proto.CompactTextString(m) }
func (*GenesisState) ProtoMessage() {}
func (*GenesisState) Descriptor() ([]byte, []int) {
return fileDescriptor_3a3d6d4398875177, []int{1}
}
func (m *GenesisState) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) {
xxx_messageInfo_GenesisState.Merge(m, src)
}
func (m *GenesisState) XXX_Size() int {
return m.Size()
}
func (m *GenesisState) XXX_DiscardUnknown() {
xxx_messageInfo_GenesisState.DiscardUnknown(m)
}
var xxx_messageInfo_GenesisState proto.InternalMessageInfo
func (m *GenesisState) GetEpochs() []EpochInfo {
if m != nil {
return m.Epochs
}
return nil
}
func init() {
proto.RegisterType((*EpochInfo)(nil), "cosmos.epochs.v1beta1.EpochInfo")
proto.RegisterType((*GenesisState)(nil), "cosmos.epochs.v1beta1.GenesisState")
}
func init() {
proto.RegisterFile("cosmos/epochs/v1beta1/genesis.proto", fileDescriptor_3a3d6d4398875177)
}
var fileDescriptor_3a3d6d4398875177 = []byte{
// 445 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x3f, 0x6f, 0xd3, 0x40,
0x1c, 0xcd, 0x91, 0x10, 0x9c, 0x6b, 0x91, 0xd0, 0xa9, 0x05, 0x93, 0xe1, 0x62, 0xb5, 0x8b, 0x25,
0xe0, 0x4e, 0x2d, 0x6c, 0x48, 0x0c, 0x29, 0x15, 0x7f, 0x06, 0x06, 0x07, 0x16, 0x24, 0x14, 0x39,
0xce, 0xe5, 0x7c, 0x02, 0xfb, 0x2c, 0xdf, 0xcf, 0x88, 0x7e, 0x8b, 0x8e, 0x7c, 0x20, 0x86, 0x8e,
0x1d, 0x99, 0x0a, 0x4a, 0x36, 0x3e, 0x05, 0xf2, 0x9d, 0x1d, 0x05, 0x9a, 0xa5, 0x93, 0xed, 0x7b,
0xef, 0xf7, 0xde, 0xbd, 0x9f, 0x1f, 0x3e, 0x4c, 0xb4, 0xc9, 0xb4, 0xe1, 0xa2, 0xd0, 0x49, 0x6a,
0xf8, 0xd7, 0xa3, 0x99, 0x80, 0xf8, 0x88, 0x4b, 0x91, 0x0b, 0xa3, 0x0c, 0x2b, 0x4a, 0x0d, 0x9a,
0xec, 0x3b, 0x12, 0x73, 0x24, 0xd6, 0x90, 0x86, 0x7b, 0x52, 0x4b, 0x6d, 0x19, 0xbc, 0x7e, 0x73,
0xe4, 0x21, 0x95, 0x5a, 0xcb, 0x2f, 0x82, 0xdb, 0xaf, 0x59, 0xb5, 0xe0, 0xf3, 0xaa, 0x8c, 0x41,
0xe9, 0xbc, 0xc1, 0x47, 0xff, 0xe3, 0xa0, 0x32, 0x61, 0x20, 0xce, 0x0a, 0x47, 0x38, 0xf8, 0xd1,
0xc5, 0x83, 0xd3, 0xda, 0xe9, 0x4d, 0xbe, 0xd0, 0x84, 0x62, 0xac, 0xe6, 0x22, 0x07, 0xb5, 0x50,
0xa2, 0xf4, 0x51, 0x80, 0xc2, 0x41, 0xb4, 0x71, 0x42, 0x4e, 0x30, 0x36, 0x10, 0x97, 0x30, 0xad,
0x65, 0xfc, 0x5b, 0x01, 0x0a, 0x77, 0x8e, 0x87, 0xcc, 0x79, 0xb0, 0xd6, 0x83, 0xbd, 0x6f, 0x3d,
0xc6, 0xde, 0xc5, 0xd5, 0xa8, 0x73, 0xfe, 0x6b, 0x84, 0xa2, 0x81, 0x9d, 0xab, 0x11, 0xf2, 0x01,
0x7b, 0xed, 0x2d, 0xfd, 0xae, 0x95, 0x78, 0x78, 0x4d, 0xe2, 0x65, 0x43, 0x18, 0xd3, 0x5a, 0xe1,
0xcf, 0xd5, 0x88, 0xb4, 0x23, 0x8f, 0x75, 0xa6, 0x40, 0x64, 0x05, 0x9c, 0x7d, 0xaf, 0x75, 0xd7,
0x52, 0xe4, 0x10, 0xdf, 0x4d, 0xaa, 0xb2, 0x14, 0x39, 0x4c, 0xed, 0xea, 0xfc, 0x5e, 0x80, 0xc2,
0x6e, 0xb4, 0xdb, 0x1c, 0xda, 0x90, 0xe4, 0x13, 0xf6, 0xff, 0x21, 0x4d, 0x37, 0xe2, 0xdc, 0xbe,
0x41, 0x9c, 0xfd, 0x4d, 0xd5, 0xc9, 0x3a, 0xda, 0x33, 0x7c, 0xdf, 0xc9, 0x26, 0xba, 0xca, 0x41,
0xe5, 0xd2, 0xe9, 0x8b, 0xb9, 0xdf, 0x0f, 0x50, 0xe8, 0x45, 0x7b, 0x16, 0x3d, 0x69, 0xc0, 0x89,
0xc3, 0xc8, 0x73, 0x3c, 0xdc, 0x76, 0xa9, 0x54, 0x28, 0x99, 0x82, 0xef, 0xd9, 0x18, 0x0f, 0xae,
0x19, 0xbe, 0xb6, 0xf0, 0xdb, 0x9e, 0x77, 0xe7, 0x9e, 0x77, 0xf0, 0x0e, 0xef, 0xbe, 0x72, 0x2d,
0x9a, 0x40, 0x0c, 0x82, 0xbc, 0xc0, 0x7d, 0xd7, 0x1f, 0x1f, 0x05, 0xdd, 0x70, 0xe7, 0x38, 0x60,
0x5b, 0x5b, 0xc5, 0xd6, 0xbf, 0x7e, 0xdc, 0xab, 0xb3, 0x45, 0xcd, 0xd4, 0xf8, 0xf4, 0x62, 0x49,
0xd1, 0xe5, 0x92, 0xa2, 0xdf, 0x4b, 0x8a, 0xce, 0x57, 0xb4, 0x73, 0xb9, 0xa2, 0x9d, 0x9f, 0x2b,
0xda, 0xf9, 0xf8, 0x48, 0x2a, 0x48, 0xab, 0x19, 0x4b, 0x74, 0xc6, 0x9b, 0x3a, 0xbb, 0xc7, 0x13,
0x33, 0xff, 0xcc, 0xbf, 0xb5, 0xdd, 0x86, 0xb3, 0x42, 0x98, 0x59, 0xdf, 0x2e, 0xf1, 0xe9, 0xdf,
0x00, 0x00, 0x00, 0xff, 0xff, 0x71, 0xa8, 0x51, 0xe8, 0xf9, 0x02, 0x00, 0x00,
}
func (m *EpochInfo) 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 *EpochInfo) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *EpochInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.CurrentEpochStartHeight != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.CurrentEpochStartHeight))
i--
dAtA[i] = 0x40
}
if m.EpochCountingStarted {
i--
if m.EpochCountingStarted {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x30
}
n1, err1 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CurrentEpochStartTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CurrentEpochStartTime):])
if err1 != nil {
return 0, err1
}
i -= n1
i = encodeVarintGenesis(dAtA, i, uint64(n1))
i--
dAtA[i] = 0x2a
if m.CurrentEpoch != 0 {
i = encodeVarintGenesis(dAtA, i, uint64(m.CurrentEpoch))
i--
dAtA[i] = 0x20
}
n2, err2 := github_com_cosmos_gogoproto_types.StdDurationMarshalTo(m.Duration, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.Duration):])
if err2 != nil {
return 0, err2
}
i -= n2
i = encodeVarintGenesis(dAtA, i, uint64(n2))
i--
dAtA[i] = 0x1a
n3, err3 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.StartTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.StartTime):])
if err3 != nil {
return 0, err3
}
i -= n3
i = encodeVarintGenesis(dAtA, i, uint64(n3))
i--
dAtA[i] = 0x12
if len(m.Identifier) > 0 {
i -= len(m.Identifier)
copy(dAtA[i:], m.Identifier)
i = encodeVarintGenesis(dAtA, i, uint64(len(m.Identifier)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Epochs) > 0 {
for iNdEx := len(m.Epochs) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Epochs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintGenesis(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int {
offset -= sovGenesis(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *EpochInfo) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Identifier)
if l > 0 {
n += 1 + l + sovGenesis(uint64(l))
}
l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.StartTime)
n += 1 + l + sovGenesis(uint64(l))
l = github_com_cosmos_gogoproto_types.SizeOfStdDuration(m.Duration)
n += 1 + l + sovGenesis(uint64(l))
if m.CurrentEpoch != 0 {
n += 1 + sovGenesis(uint64(m.CurrentEpoch))
}
l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CurrentEpochStartTime)
n += 1 + l + sovGenesis(uint64(l))
if m.EpochCountingStarted {
n += 2
}
if m.CurrentEpochStartHeight != 0 {
n += 1 + sovGenesis(uint64(m.CurrentEpochStartHeight))
}
return n
}
func (m *GenesisState) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Epochs) > 0 {
for _, e := range m.Epochs {
l = e.Size()
n += 1 + l + sovGenesis(uint64(l))
}
}
return n
}
func sovGenesis(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozGenesis(x uint64) (n int) {
return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *EpochInfo) 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 ErrIntOverflowGenesis
}
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: EpochInfo: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: EpochInfo: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Identifier", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Identifier = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field StartTime", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.StartTime, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Duration", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_cosmos_gogoproto_types.StdDurationUnmarshal(&m.Duration, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpoch", wireType)
}
m.CurrentEpoch = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CurrentEpoch |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 5:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpochStartTime", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.CurrentEpochStartTime, dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field EpochCountingStarted", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.EpochCountingStarted = bool(v != 0)
case 8:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpochStartHeight", wireType)
}
m.CurrentEpochStartHeight = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CurrentEpochStartHeight |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *GenesisState) 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 ErrIntOverflowGenesis
}
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: GenesisState: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Epochs", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenesis
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthGenesis
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthGenesis
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Epochs = append(m.Epochs, EpochInfo{})
if err := m.Epochs[len(m.Epochs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipGenesis(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthGenesis
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGenesis(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, ErrIntOverflowGenesis
}
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, ErrIntOverflowGenesis
}
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, ErrIntOverflowGenesis
}
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, ErrInvalidLengthGenesis
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupGenesis
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthGenesis
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group")
)

46
x/epochs/types/hooks.go Normal file
View File

@ -0,0 +1,46 @@
package types
import (
"context"
"errors"
)
type EpochHooks interface {
// the first block whose timestamp is after the duration is counted as the end of the epoch
AfterEpochEnd(ctx context.Context, epochIdentifier string, epochNumber int64) error
// new epoch is next block of epoch end block
BeforeEpochStart(ctx context.Context, epochIdentifier string, epochNumber int64) error
}
var _ EpochHooks = MultiEpochHooks{}
// combine multiple gamm hooks, all hook functions are run in array sequence.
type MultiEpochHooks []EpochHooks
func NewMultiEpochHooks(hooks ...EpochHooks) MultiEpochHooks {
return hooks
}
// AfterEpochEnd is called when epoch is going to be ended, epochNumber is the number of epoch that is ending.
func (h MultiEpochHooks) AfterEpochEnd(ctx context.Context, epochIdentifier string, epochNumber int64) error {
var errs error
for i := range h {
errs = errors.Join(errs, h[i].AfterEpochEnd(ctx, epochIdentifier, epochNumber))
}
return errs
}
// BeforeEpochStart is called when epoch is going to be started, epochNumber is the number of epoch that is starting.
func (h MultiEpochHooks) BeforeEpochStart(ctx context.Context, epochIdentifier string, epochNumber int64) error {
var errs error
for i := range h {
errs = errors.Join(errs, h[i].BeforeEpochStart(ctx, epochIdentifier, epochNumber))
}
return errs
}
// EpochHooksWrapper is a wrapper for modules to inject EpochHooks using depinject.
type EpochHooksWrapper struct{ EpochHooks }
// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (EpochHooksWrapper) IsOnePerModuleType() {}

View File

@ -0,0 +1,111 @@
package types_test
import (
"context"
"testing"
"github.com/stretchr/testify/suite"
"cosmossdk.io/errors"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/epochs/types"
)
type KeeperTestSuite struct {
suite.Suite
Ctx sdk.Context
}
func TestKeeperTestSuite(t *testing.T) {
suite.Run(t, new(KeeperTestSuite))
}
func (s *KeeperTestSuite) SetupTest() {
s.Ctx = testutil.DefaultContext(storetypes.NewKVStoreKey(types.StoreKey), storetypes.NewTransientStoreKey("transient_test"))
}
var dummyErr = errors.New("9", 9, "dummyError")
// dummyEpochHook is a struct satisfying the epoch hook interface,
// that maintains a counter for how many times its been successfully called,
// and a boolean for whether it should panic during its execution.
type dummyEpochHook struct {
successCounter int
shouldError bool
}
func (hook *dummyEpochHook) AfterEpochEnd(ctx context.Context, epochIdentifier string, epochNumber int64) error {
if hook.shouldError {
return dummyErr
}
hook.successCounter += 1
return nil
}
func (hook *dummyEpochHook) BeforeEpochStart(ctx context.Context, epochIdentifier string, epochNumber int64) error {
if hook.shouldError {
return dummyErr
}
hook.successCounter += 1
return nil
}
func (hook *dummyEpochHook) Clone() *dummyEpochHook {
newHook := dummyEpochHook{successCounter: hook.successCounter, shouldError: hook.shouldError}
return &newHook
}
var _ types.EpochHooks = &dummyEpochHook{}
func (s *KeeperTestSuite) TestHooksPanicRecovery() {
errorHook := dummyEpochHook{shouldError: true}
noErrorHook := dummyEpochHook{shouldError: false}
simpleHooks := []dummyEpochHook{errorHook, noErrorHook}
tests := []struct {
hooks []dummyEpochHook
expectedCounterValues []int
lenEvents int
expErr bool
}{
{[]dummyEpochHook{errorHook}, []int{0}, 0, true},
{simpleHooks, []int{0, 1, 0, 1}, 2, true},
}
for tcIndex, tc := range tests {
for epochActionSelector := 0; epochActionSelector < 2; epochActionSelector++ {
s.SetupTest()
hookRefs := []types.EpochHooks{}
for _, hook := range tc.hooks {
hookRefs = append(hookRefs, hook.Clone())
}
hooks := types.NewMultiEpochHooks(hookRefs...)
if epochActionSelector == 0 {
err := hooks.BeforeEpochStart(s.Ctx, "id", 0)
if tc.expErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
}
} else if epochActionSelector == 1 {
err := hooks.AfterEpochEnd(s.Ctx, "id", 0)
if tc.expErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
}
}
for i := 0; i < len(hooks); i++ {
epochHook := hookRefs[i].(*dummyEpochHook)
s.Require().Equal(tc.expectedCounterValues[i], epochHook.successCounter, "test case index %d", tcIndex)
}
}
}
}

16
x/epochs/types/keys.go Normal file
View File

@ -0,0 +1,16 @@
package types
import (
"cosmossdk.io/collections"
)
const (
// ModuleName defines the module name.
ModuleName = "epochs"
// StoreKey defines the primary module store key.
StoreKey = ModuleName
)
// KeyPrefixEpoch defines prefix key for storing epochs.
var KeyPrefixEpoch = collections.NewPrefix(1)

919
x/epochs/types/query.pb.go Normal file
View File

@ -0,0 +1,919 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cosmos/epochs/v1beta1/query.proto
package types
import (
context "context"
fmt "fmt"
_ "github.com/cosmos/gogoproto/gogoproto"
grpc1 "github.com/cosmos/gogoproto/grpc"
proto "github.com/cosmos/gogoproto/proto"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
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
// QueryEpochInfosRequest defines the gRPC request structure for
// querying all epoch info.
type QueryEpochInfosRequest struct {
}
func (m *QueryEpochInfosRequest) Reset() { *m = QueryEpochInfosRequest{} }
func (m *QueryEpochInfosRequest) String() string { return proto.CompactTextString(m) }
func (*QueryEpochInfosRequest) ProtoMessage() {}
func (*QueryEpochInfosRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_dacbc976c75f2414, []int{0}
}
func (m *QueryEpochInfosRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryEpochInfosRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryEpochInfosRequest.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 *QueryEpochInfosRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryEpochInfosRequest.Merge(m, src)
}
func (m *QueryEpochInfosRequest) XXX_Size() int {
return m.Size()
}
func (m *QueryEpochInfosRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryEpochInfosRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryEpochInfosRequest proto.InternalMessageInfo
// QueryEpochInfosRequest defines the gRPC response structure for
// querying all epoch info.
type QueryEpochInfosResponse struct {
Epochs []EpochInfo `protobuf:"bytes,1,rep,name=epochs,proto3" json:"epochs"`
}
func (m *QueryEpochInfosResponse) Reset() { *m = QueryEpochInfosResponse{} }
func (m *QueryEpochInfosResponse) String() string { return proto.CompactTextString(m) }
func (*QueryEpochInfosResponse) ProtoMessage() {}
func (*QueryEpochInfosResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_dacbc976c75f2414, []int{1}
}
func (m *QueryEpochInfosResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryEpochInfosResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryEpochInfosResponse.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 *QueryEpochInfosResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryEpochInfosResponse.Merge(m, src)
}
func (m *QueryEpochInfosResponse) XXX_Size() int {
return m.Size()
}
func (m *QueryEpochInfosResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryEpochInfosResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryEpochInfosResponse proto.InternalMessageInfo
func (m *QueryEpochInfosResponse) GetEpochs() []EpochInfo {
if m != nil {
return m.Epochs
}
return nil
}
// QueryCurrentEpochRequest defines the gRPC request structure for
// querying an epoch by its identifier.
type QueryCurrentEpochRequest struct {
Identifier string `protobuf:"bytes,1,opt,name=identifier,proto3" json:"identifier,omitempty"`
}
func (m *QueryCurrentEpochRequest) Reset() { *m = QueryCurrentEpochRequest{} }
func (m *QueryCurrentEpochRequest) String() string { return proto.CompactTextString(m) }
func (*QueryCurrentEpochRequest) ProtoMessage() {}
func (*QueryCurrentEpochRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_dacbc976c75f2414, []int{2}
}
func (m *QueryCurrentEpochRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryCurrentEpochRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryCurrentEpochRequest.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 *QueryCurrentEpochRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryCurrentEpochRequest.Merge(m, src)
}
func (m *QueryCurrentEpochRequest) XXX_Size() int {
return m.Size()
}
func (m *QueryCurrentEpochRequest) XXX_DiscardUnknown() {
xxx_messageInfo_QueryCurrentEpochRequest.DiscardUnknown(m)
}
var xxx_messageInfo_QueryCurrentEpochRequest proto.InternalMessageInfo
func (m *QueryCurrentEpochRequest) GetIdentifier() string {
if m != nil {
return m.Identifier
}
return ""
}
// QueryCurrentEpochResponse defines the gRPC response structure for
// querying an epoch by its identifier.
type QueryCurrentEpochResponse struct {
CurrentEpoch int64 `protobuf:"varint,1,opt,name=current_epoch,json=currentEpoch,proto3" json:"current_epoch,omitempty"`
}
func (m *QueryCurrentEpochResponse) Reset() { *m = QueryCurrentEpochResponse{} }
func (m *QueryCurrentEpochResponse) String() string { return proto.CompactTextString(m) }
func (*QueryCurrentEpochResponse) ProtoMessage() {}
func (*QueryCurrentEpochResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_dacbc976c75f2414, []int{3}
}
func (m *QueryCurrentEpochResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *QueryCurrentEpochResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_QueryCurrentEpochResponse.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 *QueryCurrentEpochResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_QueryCurrentEpochResponse.Merge(m, src)
}
func (m *QueryCurrentEpochResponse) XXX_Size() int {
return m.Size()
}
func (m *QueryCurrentEpochResponse) XXX_DiscardUnknown() {
xxx_messageInfo_QueryCurrentEpochResponse.DiscardUnknown(m)
}
var xxx_messageInfo_QueryCurrentEpochResponse proto.InternalMessageInfo
func (m *QueryCurrentEpochResponse) GetCurrentEpoch() int64 {
if m != nil {
return m.CurrentEpoch
}
return 0
}
func init() {
proto.RegisterType((*QueryEpochInfosRequest)(nil), "cosmos.epochs.v1beta1.QueryEpochInfosRequest")
proto.RegisterType((*QueryEpochInfosResponse)(nil), "cosmos.epochs.v1beta1.QueryEpochInfosResponse")
proto.RegisterType((*QueryCurrentEpochRequest)(nil), "cosmos.epochs.v1beta1.QueryCurrentEpochRequest")
proto.RegisterType((*QueryCurrentEpochResponse)(nil), "cosmos.epochs.v1beta1.QueryCurrentEpochResponse")
}
func init() { proto.RegisterFile("cosmos/epochs/v1beta1/query.proto", fileDescriptor_dacbc976c75f2414) }
var fileDescriptor_dacbc976c75f2414 = []byte{
// 386 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xcf, 0x4e, 0xe2, 0x40,
0x1c, 0xc7, 0x3b, 0xb0, 0x4b, 0xb2, 0xb3, 0xec, 0x65, 0xb2, 0xbb, 0xd6, 0x46, 0x0b, 0x16, 0x35,
0x24, 0x4a, 0x47, 0xf0, 0xe6, 0xc1, 0x18, 0x0c, 0x07, 0x8f, 0xf6, 0xa6, 0x17, 0x53, 0xca, 0x50,
0x1a, 0x65, 0xa6, 0x74, 0xa6, 0x46, 0xae, 0x3e, 0x81, 0xd1, 0x07, 0xf0, 0x4d, 0x3c, 0x73, 0x24,
0xf1, 0xe2, 0xc9, 0x18, 0xf0, 0x41, 0x0c, 0x33, 0x45, 0x31, 0x16, 0xc3, 0x09, 0x3a, 0xf3, 0xf9,
0xfe, 0xf9, 0xfd, 0x5a, 0xb8, 0xe6, 0x31, 0xde, 0x65, 0x1c, 0x93, 0x90, 0x79, 0x1d, 0x8e, 0x2f,
0xab, 0x4d, 0x22, 0xdc, 0x2a, 0xee, 0xc5, 0x24, 0xea, 0xdb, 0x61, 0xc4, 0x04, 0x43, 0xff, 0x14,
0x62, 0x2b, 0xc4, 0x4e, 0x10, 0xe3, 0xaf, 0xcf, 0x7c, 0x26, 0x09, 0x3c, 0xf9, 0xa7, 0x60, 0x63,
0xc5, 0x67, 0xcc, 0xbf, 0x20, 0xd8, 0x0d, 0x03, 0xec, 0x52, 0xca, 0x84, 0x2b, 0x02, 0x46, 0x79,
0x72, 0x5b, 0x4a, 0x4f, 0xf3, 0x09, 0x25, 0x3c, 0x48, 0x20, 0x4b, 0x87, 0xff, 0x8f, 0x27, 0xf1,
0x8d, 0x09, 0x74, 0x44, 0xdb, 0x8c, 0x3b, 0xa4, 0x17, 0x13, 0x2e, 0xac, 0x13, 0xb8, 0xf4, 0xe5,
0x86, 0x87, 0x8c, 0x72, 0x82, 0xf6, 0x61, 0x4e, 0x99, 0xea, 0xa0, 0x98, 0x2d, 0xff, 0xae, 0x15,
0xed, 0xd4, 0xd6, 0xf6, 0xbb, 0xb4, 0xfe, 0x63, 0xf0, 0x5c, 0xd0, 0x9c, 0x44, 0x65, 0xed, 0x41,
0x5d, 0x5a, 0x1f, 0xc6, 0x51, 0x44, 0xa8, 0x90, 0x58, 0x12, 0x8b, 0x4c, 0x08, 0x83, 0x16, 0xa1,
0x22, 0x68, 0x07, 0x24, 0xd2, 0x41, 0x11, 0x94, 0x7f, 0x39, 0x33, 0x27, 0xd6, 0x01, 0x5c, 0x4e,
0xd1, 0x26, 0xc5, 0x4a, 0xf0, 0x8f, 0xa7, 0xce, 0xcf, 0x64, 0x94, 0xd4, 0x67, 0x9d, 0xbc, 0x37,
0x03, 0xd7, 0x1e, 0x32, 0xf0, 0xa7, 0xb4, 0x40, 0xb7, 0x00, 0xc2, 0x8f, 0xf1, 0x50, 0x65, 0xce,
0x18, 0xe9, 0x0b, 0x32, 0xec, 0x45, 0x71, 0x55, 0xce, 0xda, 0xb8, 0x7e, 0x7c, 0xbd, 0xcb, 0x14,
0xd0, 0x2a, 0x4e, 0x7f, 0x31, 0xea, 0x11, 0xdd, 0x03, 0x98, 0x9f, 0x1d, 0x0e, 0xe1, 0xef, 0x72,
0x52, 0x56, 0x68, 0xec, 0x2c, 0x2e, 0x48, 0xaa, 0x6d, 0xcb, 0x6a, 0x9b, 0x68, 0x7d, 0x4e, 0xb5,
0x4f, 0x4b, 0xad, 0x37, 0x06, 0x23, 0x13, 0x0c, 0x47, 0x26, 0x78, 0x19, 0x99, 0xe0, 0x66, 0x6c,
0x6a, 0xc3, 0xb1, 0xa9, 0x3d, 0x8d, 0x4d, 0xed, 0x74, 0xcb, 0x0f, 0x44, 0x27, 0x6e, 0xda, 0x1e,
0xeb, 0x4e, 0x9d, 0xd4, 0x4f, 0x85, 0xb7, 0xce, 0xf1, 0xd5, 0xd4, 0x56, 0xf4, 0x43, 0xc2, 0x9b,
0x39, 0xf9, 0x05, 0xee, 0xbe, 0x05, 0x00, 0x00, 0xff, 0xff, 0xfa, 0x90, 0xfa, 0x87, 0x16, 0x03,
0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// QueryClient is the client API for Query service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type QueryClient interface {
// EpochInfos provide running epochInfos
EpochInfos(ctx context.Context, in *QueryEpochInfosRequest, opts ...grpc.CallOption) (*QueryEpochInfosResponse, error)
// CurrentEpoch provide current epoch of specified identifier
CurrentEpoch(ctx context.Context, in *QueryCurrentEpochRequest, opts ...grpc.CallOption) (*QueryCurrentEpochResponse, error)
}
type queryClient struct {
cc grpc1.ClientConn
}
func NewQueryClient(cc grpc1.ClientConn) QueryClient {
return &queryClient{cc}
}
func (c *queryClient) EpochInfos(ctx context.Context, in *QueryEpochInfosRequest, opts ...grpc.CallOption) (*QueryEpochInfosResponse, error) {
out := new(QueryEpochInfosResponse)
err := c.cc.Invoke(ctx, "/cosmos.epochs.v1beta1.Query/EpochInfos", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *queryClient) CurrentEpoch(ctx context.Context, in *QueryCurrentEpochRequest, opts ...grpc.CallOption) (*QueryCurrentEpochResponse, error) {
out := new(QueryCurrentEpochResponse)
err := c.cc.Invoke(ctx, "/cosmos.epochs.v1beta1.Query/CurrentEpoch", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// QueryServer is the server API for Query service.
type QueryServer interface {
// EpochInfos provide running epochInfos
EpochInfos(context.Context, *QueryEpochInfosRequest) (*QueryEpochInfosResponse, error)
// CurrentEpoch provide current epoch of specified identifier
CurrentEpoch(context.Context, *QueryCurrentEpochRequest) (*QueryCurrentEpochResponse, error)
}
// UnimplementedQueryServer can be embedded to have forward compatible implementations.
type UnimplementedQueryServer struct {
}
func (*UnimplementedQueryServer) EpochInfos(ctx context.Context, req *QueryEpochInfosRequest) (*QueryEpochInfosResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method EpochInfos not implemented")
}
func (*UnimplementedQueryServer) CurrentEpoch(ctx context.Context, req *QueryCurrentEpochRequest) (*QueryCurrentEpochResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CurrentEpoch not implemented")
}
func RegisterQueryServer(s grpc1.Server, srv QueryServer) {
s.RegisterService(&_Query_serviceDesc, srv)
}
func _Query_EpochInfos_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryEpochInfosRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).EpochInfos(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.epochs.v1beta1.Query/EpochInfos",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).EpochInfos(ctx, req.(*QueryEpochInfosRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Query_CurrentEpoch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(QueryCurrentEpochRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(QueryServer).CurrentEpoch(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/cosmos.epochs.v1beta1.Query/CurrentEpoch",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(QueryServer).CurrentEpoch(ctx, req.(*QueryCurrentEpochRequest))
}
return interceptor(ctx, in, info, handler)
}
var Query_serviceDesc = _Query_serviceDesc
var _Query_serviceDesc = grpc.ServiceDesc{
ServiceName: "cosmos.epochs.v1beta1.Query",
HandlerType: (*QueryServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "EpochInfos",
Handler: _Query_EpochInfos_Handler,
},
{
MethodName: "CurrentEpoch",
Handler: _Query_CurrentEpoch_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "cosmos/epochs/v1beta1/query.proto",
}
func (m *QueryEpochInfosRequest) 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 *QueryEpochInfosRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryEpochInfosRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
return len(dAtA) - i, nil
}
func (m *QueryEpochInfosResponse) 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 *QueryEpochInfosResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryEpochInfosResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Epochs) > 0 {
for iNdEx := len(m.Epochs) - 1; iNdEx >= 0; iNdEx-- {
{
size, err := m.Epochs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintQuery(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *QueryCurrentEpochRequest) 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 *QueryCurrentEpochRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryCurrentEpochRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.Identifier) > 0 {
i -= len(m.Identifier)
copy(dAtA[i:], m.Identifier)
i = encodeVarintQuery(dAtA, i, uint64(len(m.Identifier)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *QueryCurrentEpochResponse) 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 *QueryCurrentEpochResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *QueryCurrentEpochResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.CurrentEpoch != 0 {
i = encodeVarintQuery(dAtA, i, uint64(m.CurrentEpoch))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func encodeVarintQuery(dAtA []byte, offset int, v uint64) int {
offset -= sovQuery(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *QueryEpochInfosRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
return n
}
func (m *QueryEpochInfosResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Epochs) > 0 {
for _, e := range m.Epochs {
l = e.Size()
n += 1 + l + sovQuery(uint64(l))
}
}
return n
}
func (m *QueryCurrentEpochRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Identifier)
if l > 0 {
n += 1 + l + sovQuery(uint64(l))
}
return n
}
func (m *QueryCurrentEpochResponse) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.CurrentEpoch != 0 {
n += 1 + sovQuery(uint64(m.CurrentEpoch))
}
return n
}
func sovQuery(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozQuery(x uint64) (n int) {
return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *QueryEpochInfosRequest) 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 ErrIntOverflowQuery
}
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: QueryEpochInfosRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryEpochInfosRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *QueryEpochInfosResponse) 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 ErrIntOverflowQuery
}
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: QueryEpochInfosResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryEpochInfosResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Epochs", 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
}
m.Epochs = append(m.Epochs, EpochInfo{})
if err := m.Epochs[len(m.Epochs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *QueryCurrentEpochRequest) 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 ErrIntOverflowQuery
}
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: QueryCurrentEpochRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryCurrentEpochRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Identifier", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthQuery
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthQuery
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Identifier = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *QueryCurrentEpochResponse) 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 ErrIntOverflowQuery
}
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: QueryCurrentEpochResponse: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: QueryCurrentEpochResponse: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpoch", wireType)
}
m.CurrentEpoch = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowQuery
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CurrentEpoch |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipQuery(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthQuery
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipQuery(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, ErrIntOverflowQuery
}
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, ErrIntOverflowQuery
}
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, ErrIntOverflowQuery
}
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, ErrInvalidLengthQuery
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupQuery
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthQuery
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group")
)

View File

@ -0,0 +1,236 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: cosmos/epochs/v1beta1/query.proto
/*
Package types is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package types
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
var _ = metadata.Join
func request_Query_EpochInfos_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryEpochInfosRequest
var metadata runtime.ServerMetadata
msg, err := client.EpochInfos(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_EpochInfos_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryEpochInfosRequest
var metadata runtime.ServerMetadata
msg, err := server.EpochInfos(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_Query_CurrentEpoch_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_Query_CurrentEpoch_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryCurrentEpochRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_CurrentEpoch_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.CurrentEpoch(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_CurrentEpoch_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryCurrentEpochRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_CurrentEpoch_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.CurrentEpoch(ctx, &protoReq)
return msg, metadata, err
}
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead.
func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error {
mux.Handle("GET", pattern_Query_EpochInfos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_EpochInfos_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_EpochInfos_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_CurrentEpoch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_CurrentEpoch_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_CurrentEpoch_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterQueryHandler(ctx, mux, conn)
}
// RegisterQueryHandler registers the http handlers for service Query to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn))
}
// RegisterQueryHandlerClient registers the http handlers for service Query
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "QueryClient" to call the correct interceptors.
func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error {
mux.Handle("GET", pattern_Query_EpochInfos_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_EpochInfos_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_EpochInfos_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_CurrentEpoch_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_CurrentEpoch_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_CurrentEpoch_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Query_EpochInfos_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1}, []string{"cosmos", "epochs", "v1beta1"}, "", runtime.AssumeColonVerbOpt(false)))
pattern_Query_CurrentEpoch_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "epochs", "v1beta1", "current_epoch"}, "", runtime.AssumeColonVerbOpt(false)))
)
var (
forward_Query_EpochInfos_0 = runtime.ForwardResponseMessage
forward_Query_CurrentEpoch_0 = runtime.ForwardResponseMessage
)

File diff suppressed because it is too large Load Diff