From 8f4df12be9a57174eea304e4934fe9a978189e2d Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 18 Mar 2026 17:01:34 +0530 Subject: [PATCH 01/31] feat(poolrebalancer): add protobuf API and generated types --- .../v1/poolrebalancer.pulsar.go | 4355 +++++++++++++++++ .../evm/poolrebalancer/v1/query.pulsar.go | 3331 +++++++++++++ .../evm/poolrebalancer/v1/query_grpc.pb.go | 189 + api/cosmos/evm/poolrebalancer/v1/tx.pulsar.go | 1099 +++++ .../evm/poolrebalancer/v1/tx_grpc.pb.go | 113 + .../poolrebalancer/v1/poolrebalancer.proto | 75 + .../cosmos/evm/poolrebalancer/v1/query.proto | 69 + proto/cosmos/evm/poolrebalancer/v1/tx.proto | 37 + x/poolrebalancer/types/poolrebalancer.pb.go | 1790 +++++++ x/poolrebalancer/types/query.pb.go | 1426 ++++++ x/poolrebalancer/types/query.pb.gw.go | 319 ++ x/poolrebalancer/types/tx.pb.go | 599 +++ 12 files changed, 13402 insertions(+) create mode 100644 api/cosmos/evm/poolrebalancer/v1/poolrebalancer.pulsar.go create mode 100644 api/cosmos/evm/poolrebalancer/v1/query.pulsar.go create mode 100644 api/cosmos/evm/poolrebalancer/v1/query_grpc.pb.go create mode 100644 api/cosmos/evm/poolrebalancer/v1/tx.pulsar.go create mode 100644 api/cosmos/evm/poolrebalancer/v1/tx_grpc.pb.go create mode 100644 proto/cosmos/evm/poolrebalancer/v1/poolrebalancer.proto create mode 100644 proto/cosmos/evm/poolrebalancer/v1/query.proto create mode 100644 proto/cosmos/evm/poolrebalancer/v1/tx.proto create mode 100644 x/poolrebalancer/types/poolrebalancer.pb.go create mode 100644 x/poolrebalancer/types/query.pb.go create mode 100644 x/poolrebalancer/types/query.pb.gw.go create mode 100644 x/poolrebalancer/types/tx.pb.go diff --git a/api/cosmos/evm/poolrebalancer/v1/poolrebalancer.pulsar.go b/api/cosmos/evm/poolrebalancer/v1/poolrebalancer.pulsar.go new file mode 100644 index 00000000..6c17d64a --- /dev/null +++ b/api/cosmos/evm/poolrebalancer/v1/poolrebalancer.pulsar.go @@ -0,0 +1,4355 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package poolrebalancerv1 + +import ( + v1beta1 "cosmossdk.io/api/cosmos/base/v1beta1" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoiface "google.golang.org/protobuf/runtime/protoiface" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + io "io" + reflect "reflect" + sync "sync" +) + +var ( + md_Params protoreflect.MessageDescriptor + fd_Params_pool_delegator_address protoreflect.FieldDescriptor + fd_Params_max_target_validators protoreflect.FieldDescriptor + fd_Params_rebalance_threshold_bp protoreflect.FieldDescriptor + fd_Params_max_ops_per_block protoreflect.FieldDescriptor + fd_Params_max_move_per_op protoreflect.FieldDescriptor + fd_Params_use_undelegate_fallback protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + md_Params = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("Params") + fd_Params_pool_delegator_address = md_Params.Fields().ByName("pool_delegator_address") + fd_Params_max_target_validators = md_Params.Fields().ByName("max_target_validators") + fd_Params_rebalance_threshold_bp = md_Params.Fields().ByName("rebalance_threshold_bp") + fd_Params_max_ops_per_block = md_Params.Fields().ByName("max_ops_per_block") + fd_Params_max_move_per_op = md_Params.Fields().ByName("max_move_per_op") + fd_Params_use_undelegate_fallback = md_Params.Fields().ByName("use_undelegate_fallback") +} + +var _ protoreflect.Message = (*fastReflection_Params)(nil) + +type fastReflection_Params Params + +func (x *Params) ProtoReflect() protoreflect.Message { + return (*fastReflection_Params)(x) +} + +func (x *Params) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_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_Params_messageType fastReflection_Params_messageType +var _ protoreflect.MessageType = fastReflection_Params_messageType{} + +type fastReflection_Params_messageType struct{} + +func (x fastReflection_Params_messageType) Zero() protoreflect.Message { + return (*fastReflection_Params)(nil) +} +func (x fastReflection_Params_messageType) New() protoreflect.Message { + return new(fastReflection_Params) +} +func (x fastReflection_Params_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_Params) Descriptor() protoreflect.MessageDescriptor { + return md_Params +} + +// 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_Params) Type() protoreflect.MessageType { + return _fastReflection_Params_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_Params) New() protoreflect.Message { + return new(fastReflection_Params) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_Params) Interface() protoreflect.ProtoMessage { + return (*Params)(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_Params) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.PoolDelegatorAddress != "" { + value := protoreflect.ValueOfString(x.PoolDelegatorAddress) + if !f(fd_Params_pool_delegator_address, value) { + return + } + } + if x.MaxTargetValidators != uint32(0) { + value := protoreflect.ValueOfUint32(x.MaxTargetValidators) + if !f(fd_Params_max_target_validators, value) { + return + } + } + if x.RebalanceThresholdBp != uint32(0) { + value := protoreflect.ValueOfUint32(x.RebalanceThresholdBp) + if !f(fd_Params_rebalance_threshold_bp, value) { + return + } + } + if x.MaxOpsPerBlock != uint32(0) { + value := protoreflect.ValueOfUint32(x.MaxOpsPerBlock) + if !f(fd_Params_max_ops_per_block, value) { + return + } + } + if x.MaxMovePerOp != "" { + value := protoreflect.ValueOfString(x.MaxMovePerOp) + if !f(fd_Params_max_move_per_op, value) { + return + } + } + if x.UseUndelegateFallback != false { + value := protoreflect.ValueOfBool(x.UseUndelegateFallback) + if !f(fd_Params_use_undelegate_fallback, value) { + return + } + } +} + +// 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_Params) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + return x.PoolDelegatorAddress != "" + case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + return x.MaxTargetValidators != uint32(0) + case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + return x.RebalanceThresholdBp != uint32(0) + case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + return x.MaxOpsPerBlock != uint32(0) + case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + return x.MaxMovePerOp != "" + case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + return x.UseUndelegateFallback != false + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params 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_Params) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + x.PoolDelegatorAddress = "" + case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + x.MaxTargetValidators = uint32(0) + case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + x.RebalanceThresholdBp = uint32(0) + case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + x.MaxOpsPerBlock = uint32(0) + case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + x.MaxMovePerOp = "" + case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + x.UseUndelegateFallback = false + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params 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_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + value := x.PoolDelegatorAddress + return protoreflect.ValueOfString(value) + case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + value := x.MaxTargetValidators + return protoreflect.ValueOfUint32(value) + case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + value := x.RebalanceThresholdBp + return protoreflect.ValueOfUint32(value) + case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + value := x.MaxOpsPerBlock + return protoreflect.ValueOfUint32(value) + case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + value := x.MaxMovePerOp + return protoreflect.ValueOfString(value) + case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + value := x.UseUndelegateFallback + return protoreflect.ValueOfBool(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params 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_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + x.PoolDelegatorAddress = value.Interface().(string) + case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + x.MaxTargetValidators = uint32(value.Uint()) + case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + x.RebalanceThresholdBp = uint32(value.Uint()) + case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + x.MaxOpsPerBlock = uint32(value.Uint()) + case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + x.MaxMovePerOp = value.Interface().(string) + case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + x.UseUndelegateFallback = value.Bool() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params 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_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + panic(fmt.Errorf("field pool_delegator_address of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) + case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + panic(fmt.Errorf("field max_target_validators of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) + case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + panic(fmt.Errorf("field rebalance_threshold_bp of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) + case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + panic(fmt.Errorf("field max_ops_per_block of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) + case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + panic(fmt.Errorf("field max_move_per_op of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) + case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + panic(fmt.Errorf("field use_undelegate_fallback of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params 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_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + return protoreflect.ValueOfString("") + case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + return protoreflect.ValueOfUint32(uint32(0)) + case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + return protoreflect.ValueOfUint32(uint32(0)) + case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + return protoreflect.ValueOfUint32(uint32(0)) + case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + return protoreflect.ValueOfString("") + case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + return protoreflect.ValueOfBool(false) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params 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_Params) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.Params", 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_Params) 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_Params) 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_Params) 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_Params) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*Params) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.PoolDelegatorAddress) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.MaxTargetValidators != 0 { + n += 1 + runtime.Sov(uint64(x.MaxTargetValidators)) + } + if x.RebalanceThresholdBp != 0 { + n += 1 + runtime.Sov(uint64(x.RebalanceThresholdBp)) + } + if x.MaxOpsPerBlock != 0 { + n += 1 + runtime.Sov(uint64(x.MaxOpsPerBlock)) + } + l = len(x.MaxMovePerOp) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.UseUndelegateFallback { + n += 2 + } + 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().(*Params) + 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 x.UseUndelegateFallback { + i-- + if x.UseUndelegateFallback { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } + if len(x.MaxMovePerOp) > 0 { + i -= len(x.MaxMovePerOp) + copy(dAtA[i:], x.MaxMovePerOp) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.MaxMovePerOp))) + i-- + dAtA[i] = 0x2a + } + if x.MaxOpsPerBlock != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.MaxOpsPerBlock)) + i-- + dAtA[i] = 0x20 + } + if x.RebalanceThresholdBp != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.RebalanceThresholdBp)) + i-- + dAtA[i] = 0x18 + } + if x.MaxTargetValidators != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.MaxTargetValidators)) + i-- + dAtA[i] = 0x10 + } + if len(x.PoolDelegatorAddress) > 0 { + i -= len(x.PoolDelegatorAddress) + copy(dAtA[i:], x.PoolDelegatorAddress) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PoolDelegatorAddress))) + i-- + dAtA[i] = 0xa + } + 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().(*Params) + 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PoolDelegatorAddress", wireType) + } + var stringLen 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++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.PoolDelegatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field MaxTargetValidators", wireType) + } + x.MaxTargetValidators = 0 + 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++ + x.MaxTargetValidators |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field RebalanceThresholdBp", wireType) + } + x.RebalanceThresholdBp = 0 + 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++ + x.RebalanceThresholdBp |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field MaxOpsPerBlock", wireType) + } + x.MaxOpsPerBlock = 0 + 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++ + x.MaxOpsPerBlock |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field MaxMovePerOp", wireType) + } + var stringLen 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++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.MaxMovePerOp = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field UseUndelegateFallback", wireType) + } + var v int + 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++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.UseUndelegateFallback = bool(v != 0) + 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, + } +} + +var ( + md_PendingRedelegation protoreflect.MessageDescriptor + fd_PendingRedelegation_delegator_address protoreflect.FieldDescriptor + fd_PendingRedelegation_src_validator_address protoreflect.FieldDescriptor + fd_PendingRedelegation_dst_validator_address protoreflect.FieldDescriptor + fd_PendingRedelegation_amount protoreflect.FieldDescriptor + fd_PendingRedelegation_completion_time protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + md_PendingRedelegation = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("PendingRedelegation") + fd_PendingRedelegation_delegator_address = md_PendingRedelegation.Fields().ByName("delegator_address") + fd_PendingRedelegation_src_validator_address = md_PendingRedelegation.Fields().ByName("src_validator_address") + fd_PendingRedelegation_dst_validator_address = md_PendingRedelegation.Fields().ByName("dst_validator_address") + fd_PendingRedelegation_amount = md_PendingRedelegation.Fields().ByName("amount") + fd_PendingRedelegation_completion_time = md_PendingRedelegation.Fields().ByName("completion_time") +} + +var _ protoreflect.Message = (*fastReflection_PendingRedelegation)(nil) + +type fastReflection_PendingRedelegation PendingRedelegation + +func (x *PendingRedelegation) ProtoReflect() protoreflect.Message { + return (*fastReflection_PendingRedelegation)(x) +} + +func (x *PendingRedelegation) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[1] + 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_PendingRedelegation_messageType fastReflection_PendingRedelegation_messageType +var _ protoreflect.MessageType = fastReflection_PendingRedelegation_messageType{} + +type fastReflection_PendingRedelegation_messageType struct{} + +func (x fastReflection_PendingRedelegation_messageType) Zero() protoreflect.Message { + return (*fastReflection_PendingRedelegation)(nil) +} +func (x fastReflection_PendingRedelegation_messageType) New() protoreflect.Message { + return new(fastReflection_PendingRedelegation) +} +func (x fastReflection_PendingRedelegation_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_PendingRedelegation +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_PendingRedelegation) Descriptor() protoreflect.MessageDescriptor { + return md_PendingRedelegation +} + +// 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_PendingRedelegation) Type() protoreflect.MessageType { + return _fastReflection_PendingRedelegation_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_PendingRedelegation) New() protoreflect.Message { + return new(fastReflection_PendingRedelegation) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_PendingRedelegation) Interface() protoreflect.ProtoMessage { + return (*PendingRedelegation)(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_PendingRedelegation) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.DelegatorAddress != "" { + value := protoreflect.ValueOfString(x.DelegatorAddress) + if !f(fd_PendingRedelegation_delegator_address, value) { + return + } + } + if x.SrcValidatorAddress != "" { + value := protoreflect.ValueOfString(x.SrcValidatorAddress) + if !f(fd_PendingRedelegation_src_validator_address, value) { + return + } + } + if x.DstValidatorAddress != "" { + value := protoreflect.ValueOfString(x.DstValidatorAddress) + if !f(fd_PendingRedelegation_dst_validator_address, value) { + return + } + } + if x.Amount != nil { + value := protoreflect.ValueOfMessage(x.Amount.ProtoReflect()) + if !f(fd_PendingRedelegation_amount, value) { + return + } + } + if x.CompletionTime != nil { + value := protoreflect.ValueOfMessage(x.CompletionTime.ProtoReflect()) + if !f(fd_PendingRedelegation_completion_time, value) { + return + } + } +} + +// 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_PendingRedelegation) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + return x.DelegatorAddress != "" + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + return x.SrcValidatorAddress != "" + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + return x.DstValidatorAddress != "" + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + return x.Amount != nil + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + return x.CompletionTime != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation 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_PendingRedelegation) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + x.DelegatorAddress = "" + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + x.SrcValidatorAddress = "" + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + x.DstValidatorAddress = "" + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + x.Amount = nil + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + x.CompletionTime = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation 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_PendingRedelegation) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + value := x.DelegatorAddress + return protoreflect.ValueOfString(value) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + value := x.SrcValidatorAddress + return protoreflect.ValueOfString(value) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + value := x.DstValidatorAddress + return protoreflect.ValueOfString(value) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + value := x.Amount + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + value := x.CompletionTime + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation 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_PendingRedelegation) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + x.DelegatorAddress = value.Interface().(string) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + x.SrcValidatorAddress = value.Interface().(string) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + x.DstValidatorAddress = value.Interface().(string) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + x.Amount = value.Message().Interface().(*v1beta1.Coin) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + x.CompletionTime = value.Message().Interface().(*timestamppb.Timestamp) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation 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_PendingRedelegation) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + if x.Amount == nil { + x.Amount = new(v1beta1.Coin) + } + return protoreflect.ValueOfMessage(x.Amount.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + if x.CompletionTime == nil { + x.CompletionTime = new(timestamppb.Timestamp) + } + return protoreflect.ValueOfMessage(x.CompletionTime.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + panic(fmt.Errorf("field delegator_address of message cosmos.evm.poolrebalancer.v1.PendingRedelegation is not mutable")) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + panic(fmt.Errorf("field src_validator_address of message cosmos.evm.poolrebalancer.v1.PendingRedelegation is not mutable")) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + panic(fmt.Errorf("field dst_validator_address of message cosmos.evm.poolrebalancer.v1.PendingRedelegation is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation 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_PendingRedelegation) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + return protoreflect.ValueOfString("") + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + return protoreflect.ValueOfString("") + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + return protoreflect.ValueOfString("") + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + m := new(v1beta1.Coin) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + m := new(timestamppb.Timestamp) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation 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_PendingRedelegation) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.PendingRedelegation", 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_PendingRedelegation) 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_PendingRedelegation) 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_PendingRedelegation) 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_PendingRedelegation) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*PendingRedelegation) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.DelegatorAddress) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.SrcValidatorAddress) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.DstValidatorAddress) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Amount != nil { + l = options.Size(x.Amount) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.CompletionTime != nil { + l = options.Size(x.CompletionTime) + n += 1 + l + runtime.Sov(uint64(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().(*PendingRedelegation) + 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 x.CompletionTime != nil { + encoded, err := options.Marshal(x.CompletionTime) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x2a + } + if x.Amount != nil { + encoded, err := options.Marshal(x.Amount) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x22 + } + if len(x.DstValidatorAddress) > 0 { + i -= len(x.DstValidatorAddress) + copy(dAtA[i:], x.DstValidatorAddress) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.DstValidatorAddress))) + i-- + dAtA[i] = 0x1a + } + if len(x.SrcValidatorAddress) > 0 { + i -= len(x.SrcValidatorAddress) + copy(dAtA[i:], x.SrcValidatorAddress) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.SrcValidatorAddress))) + i-- + dAtA[i] = 0x12 + } + if len(x.DelegatorAddress) > 0 { + i -= len(x.DelegatorAddress) + copy(dAtA[i:], x.DelegatorAddress) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.DelegatorAddress))) + i-- + dAtA[i] = 0xa + } + 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().(*PendingRedelegation) + 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: PendingRedelegation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: PendingRedelegation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DelegatorAddress", wireType) + } + var stringLen 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++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.DelegatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field SrcValidatorAddress", wireType) + } + var stringLen 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++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.SrcValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DstValidatorAddress", wireType) + } + var stringLen 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++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.DstValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Amount == nil { + x.Amount = &v1beta1.Coin{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Amount); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CompletionTime", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.CompletionTime == nil { + x.CompletionTime = ×tamppb.Timestamp{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.CompletionTime); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +var _ protoreflect.List = (*_QueuedRedelegation_1_list)(nil) + +type _QueuedRedelegation_1_list struct { + list *[]*PendingRedelegation +} + +func (x *_QueuedRedelegation_1_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_QueuedRedelegation_1_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_QueuedRedelegation_1_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingRedelegation) + (*x.list)[i] = concreteValue +} + +func (x *_QueuedRedelegation_1_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingRedelegation) + *x.list = append(*x.list, concreteValue) +} + +func (x *_QueuedRedelegation_1_list) AppendMutable() protoreflect.Value { + v := new(PendingRedelegation) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueuedRedelegation_1_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_QueuedRedelegation_1_list) NewElement() protoreflect.Value { + v := new(PendingRedelegation) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueuedRedelegation_1_list) IsValid() bool { + return x.list != nil +} + +var ( + md_QueuedRedelegation protoreflect.MessageDescriptor + fd_QueuedRedelegation_entries protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + md_QueuedRedelegation = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("QueuedRedelegation") + fd_QueuedRedelegation_entries = md_QueuedRedelegation.Fields().ByName("entries") +} + +var _ protoreflect.Message = (*fastReflection_QueuedRedelegation)(nil) + +type fastReflection_QueuedRedelegation QueuedRedelegation + +func (x *QueuedRedelegation) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueuedRedelegation)(x) +} + +func (x *QueuedRedelegation) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[2] + 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_QueuedRedelegation_messageType fastReflection_QueuedRedelegation_messageType +var _ protoreflect.MessageType = fastReflection_QueuedRedelegation_messageType{} + +type fastReflection_QueuedRedelegation_messageType struct{} + +func (x fastReflection_QueuedRedelegation_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueuedRedelegation)(nil) +} +func (x fastReflection_QueuedRedelegation_messageType) New() protoreflect.Message { + return new(fastReflection_QueuedRedelegation) +} +func (x fastReflection_QueuedRedelegation_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueuedRedelegation +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueuedRedelegation) Descriptor() protoreflect.MessageDescriptor { + return md_QueuedRedelegation +} + +// 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_QueuedRedelegation) Type() protoreflect.MessageType { + return _fastReflection_QueuedRedelegation_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueuedRedelegation) New() protoreflect.Message { + return new(fastReflection_QueuedRedelegation) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueuedRedelegation) Interface() protoreflect.ProtoMessage { + return (*QueuedRedelegation)(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_QueuedRedelegation) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Entries) != 0 { + value := protoreflect.ValueOfList(&_QueuedRedelegation_1_list{list: &x.Entries}) + if !f(fd_QueuedRedelegation_entries, value) { + return + } + } +} + +// 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_QueuedRedelegation) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + return len(x.Entries) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation 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_QueuedRedelegation) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + x.Entries = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation 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_QueuedRedelegation) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + if len(x.Entries) == 0 { + return protoreflect.ValueOfList(&_QueuedRedelegation_1_list{}) + } + listValue := &_QueuedRedelegation_1_list{list: &x.Entries} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation 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_QueuedRedelegation) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + lv := value.List() + clv := lv.(*_QueuedRedelegation_1_list) + x.Entries = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation 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_QueuedRedelegation) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + if x.Entries == nil { + x.Entries = []*PendingRedelegation{} + } + value := &_QueuedRedelegation_1_list{list: &x.Entries} + return protoreflect.ValueOfList(value) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation 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_QueuedRedelegation) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + list := []*PendingRedelegation{} + return protoreflect.ValueOfList(&_QueuedRedelegation_1_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation 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_QueuedRedelegation) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueuedRedelegation", 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_QueuedRedelegation) 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_QueuedRedelegation) 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_QueuedRedelegation) 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_QueuedRedelegation) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueuedRedelegation) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if len(x.Entries) > 0 { + for _, e := range x.Entries { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(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().(*QueuedRedelegation) + 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 len(x.Entries) > 0 { + for iNdEx := len(x.Entries) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.Entries[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + } + 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().(*QueuedRedelegation) + 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: QueuedRedelegation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueuedRedelegation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Entries = append(x.Entries, &PendingRedelegation{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Entries[len(x.Entries)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +var ( + md_PendingUndelegation protoreflect.MessageDescriptor + fd_PendingUndelegation_delegator_address protoreflect.FieldDescriptor + fd_PendingUndelegation_validator_address protoreflect.FieldDescriptor + fd_PendingUndelegation_balance protoreflect.FieldDescriptor + fd_PendingUndelegation_completion_time protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + md_PendingUndelegation = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("PendingUndelegation") + fd_PendingUndelegation_delegator_address = md_PendingUndelegation.Fields().ByName("delegator_address") + fd_PendingUndelegation_validator_address = md_PendingUndelegation.Fields().ByName("validator_address") + fd_PendingUndelegation_balance = md_PendingUndelegation.Fields().ByName("balance") + fd_PendingUndelegation_completion_time = md_PendingUndelegation.Fields().ByName("completion_time") +} + +var _ protoreflect.Message = (*fastReflection_PendingUndelegation)(nil) + +type fastReflection_PendingUndelegation PendingUndelegation + +func (x *PendingUndelegation) ProtoReflect() protoreflect.Message { + return (*fastReflection_PendingUndelegation)(x) +} + +func (x *PendingUndelegation) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[3] + 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_PendingUndelegation_messageType fastReflection_PendingUndelegation_messageType +var _ protoreflect.MessageType = fastReflection_PendingUndelegation_messageType{} + +type fastReflection_PendingUndelegation_messageType struct{} + +func (x fastReflection_PendingUndelegation_messageType) Zero() protoreflect.Message { + return (*fastReflection_PendingUndelegation)(nil) +} +func (x fastReflection_PendingUndelegation_messageType) New() protoreflect.Message { + return new(fastReflection_PendingUndelegation) +} +func (x fastReflection_PendingUndelegation_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_PendingUndelegation +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_PendingUndelegation) Descriptor() protoreflect.MessageDescriptor { + return md_PendingUndelegation +} + +// 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_PendingUndelegation) Type() protoreflect.MessageType { + return _fastReflection_PendingUndelegation_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_PendingUndelegation) New() protoreflect.Message { + return new(fastReflection_PendingUndelegation) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_PendingUndelegation) Interface() protoreflect.ProtoMessage { + return (*PendingUndelegation)(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_PendingUndelegation) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.DelegatorAddress != "" { + value := protoreflect.ValueOfString(x.DelegatorAddress) + if !f(fd_PendingUndelegation_delegator_address, value) { + return + } + } + if x.ValidatorAddress != "" { + value := protoreflect.ValueOfString(x.ValidatorAddress) + if !f(fd_PendingUndelegation_validator_address, value) { + return + } + } + if x.Balance != nil { + value := protoreflect.ValueOfMessage(x.Balance.ProtoReflect()) + if !f(fd_PendingUndelegation_balance, value) { + return + } + } + if x.CompletionTime != nil { + value := protoreflect.ValueOfMessage(x.CompletionTime.ProtoReflect()) + if !f(fd_PendingUndelegation_completion_time, value) { + return + } + } +} + +// 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_PendingUndelegation) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + return x.DelegatorAddress != "" + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + return x.ValidatorAddress != "" + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + return x.Balance != nil + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + return x.CompletionTime != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation 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_PendingUndelegation) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + x.DelegatorAddress = "" + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + x.ValidatorAddress = "" + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + x.Balance = nil + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + x.CompletionTime = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation 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_PendingUndelegation) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + value := x.DelegatorAddress + return protoreflect.ValueOfString(value) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + value := x.ValidatorAddress + return protoreflect.ValueOfString(value) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + value := x.Balance + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + value := x.CompletionTime + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation 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_PendingUndelegation) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + x.DelegatorAddress = value.Interface().(string) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + x.ValidatorAddress = value.Interface().(string) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + x.Balance = value.Message().Interface().(*v1beta1.Coin) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + x.CompletionTime = value.Message().Interface().(*timestamppb.Timestamp) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation 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_PendingUndelegation) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + if x.Balance == nil { + x.Balance = new(v1beta1.Coin) + } + return protoreflect.ValueOfMessage(x.Balance.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + if x.CompletionTime == nil { + x.CompletionTime = new(timestamppb.Timestamp) + } + return protoreflect.ValueOfMessage(x.CompletionTime.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + panic(fmt.Errorf("field delegator_address of message cosmos.evm.poolrebalancer.v1.PendingUndelegation is not mutable")) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + panic(fmt.Errorf("field validator_address of message cosmos.evm.poolrebalancer.v1.PendingUndelegation is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation 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_PendingUndelegation) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + return protoreflect.ValueOfString("") + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + return protoreflect.ValueOfString("") + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + m := new(v1beta1.Coin) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + m := new(timestamppb.Timestamp) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation 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_PendingUndelegation) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.PendingUndelegation", 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_PendingUndelegation) 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_PendingUndelegation) 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_PendingUndelegation) 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_PendingUndelegation) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*PendingUndelegation) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.DelegatorAddress) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.ValidatorAddress) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Balance != nil { + l = options.Size(x.Balance) + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.CompletionTime != nil { + l = options.Size(x.CompletionTime) + n += 1 + l + runtime.Sov(uint64(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().(*PendingUndelegation) + 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 x.CompletionTime != nil { + encoded, err := options.Marshal(x.CompletionTime) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x22 + } + if x.Balance != nil { + encoded, err := options.Marshal(x.Balance) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x1a + } + if len(x.ValidatorAddress) > 0 { + i -= len(x.ValidatorAddress) + copy(dAtA[i:], x.ValidatorAddress) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.ValidatorAddress))) + i-- + dAtA[i] = 0x12 + } + if len(x.DelegatorAddress) > 0 { + i -= len(x.DelegatorAddress) + copy(dAtA[i:], x.DelegatorAddress) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.DelegatorAddress))) + i-- + dAtA[i] = 0xa + } + 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().(*PendingUndelegation) + 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: PendingUndelegation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: PendingUndelegation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field DelegatorAddress", wireType) + } + var stringLen 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++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.DelegatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType) + } + var stringLen 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++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.ValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Balance", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Balance == nil { + x.Balance = &v1beta1.Coin{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Balance); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field CompletionTime", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.CompletionTime == nil { + x.CompletionTime = ×tamppb.Timestamp{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.CompletionTime); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +var _ protoreflect.List = (*_QueuedUndelegation_1_list)(nil) + +type _QueuedUndelegation_1_list struct { + list *[]*PendingUndelegation +} + +func (x *_QueuedUndelegation_1_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_QueuedUndelegation_1_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_QueuedUndelegation_1_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingUndelegation) + (*x.list)[i] = concreteValue +} + +func (x *_QueuedUndelegation_1_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingUndelegation) + *x.list = append(*x.list, concreteValue) +} + +func (x *_QueuedUndelegation_1_list) AppendMutable() protoreflect.Value { + v := new(PendingUndelegation) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueuedUndelegation_1_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_QueuedUndelegation_1_list) NewElement() protoreflect.Value { + v := new(PendingUndelegation) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueuedUndelegation_1_list) IsValid() bool { + return x.list != nil +} + +var ( + md_QueuedUndelegation protoreflect.MessageDescriptor + fd_QueuedUndelegation_entries protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + md_QueuedUndelegation = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("QueuedUndelegation") + fd_QueuedUndelegation_entries = md_QueuedUndelegation.Fields().ByName("entries") +} + +var _ protoreflect.Message = (*fastReflection_QueuedUndelegation)(nil) + +type fastReflection_QueuedUndelegation QueuedUndelegation + +func (x *QueuedUndelegation) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueuedUndelegation)(x) +} + +func (x *QueuedUndelegation) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[4] + 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_QueuedUndelegation_messageType fastReflection_QueuedUndelegation_messageType +var _ protoreflect.MessageType = fastReflection_QueuedUndelegation_messageType{} + +type fastReflection_QueuedUndelegation_messageType struct{} + +func (x fastReflection_QueuedUndelegation_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueuedUndelegation)(nil) +} +func (x fastReflection_QueuedUndelegation_messageType) New() protoreflect.Message { + return new(fastReflection_QueuedUndelegation) +} +func (x fastReflection_QueuedUndelegation_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueuedUndelegation +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueuedUndelegation) Descriptor() protoreflect.MessageDescriptor { + return md_QueuedUndelegation +} + +// 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_QueuedUndelegation) Type() protoreflect.MessageType { + return _fastReflection_QueuedUndelegation_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueuedUndelegation) New() protoreflect.Message { + return new(fastReflection_QueuedUndelegation) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueuedUndelegation) Interface() protoreflect.ProtoMessage { + return (*QueuedUndelegation)(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_QueuedUndelegation) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Entries) != 0 { + value := protoreflect.ValueOfList(&_QueuedUndelegation_1_list{list: &x.Entries}) + if !f(fd_QueuedUndelegation_entries, value) { + return + } + } +} + +// 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_QueuedUndelegation) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + return len(x.Entries) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation 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_QueuedUndelegation) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + x.Entries = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation 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_QueuedUndelegation) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + if len(x.Entries) == 0 { + return protoreflect.ValueOfList(&_QueuedUndelegation_1_list{}) + } + listValue := &_QueuedUndelegation_1_list{list: &x.Entries} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation 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_QueuedUndelegation) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + lv := value.List() + clv := lv.(*_QueuedUndelegation_1_list) + x.Entries = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation 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_QueuedUndelegation) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + if x.Entries == nil { + x.Entries = []*PendingUndelegation{} + } + value := &_QueuedUndelegation_1_list{list: &x.Entries} + return protoreflect.ValueOfList(value) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation 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_QueuedUndelegation) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + list := []*PendingUndelegation{} + return protoreflect.ValueOfList(&_QueuedUndelegation_1_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation 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_QueuedUndelegation) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueuedUndelegation", 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_QueuedUndelegation) 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_QueuedUndelegation) 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_QueuedUndelegation) 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_QueuedUndelegation) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueuedUndelegation) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if len(x.Entries) > 0 { + for _, e := range x.Entries { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(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().(*QueuedUndelegation) + 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 len(x.Entries) > 0 { + for iNdEx := len(x.Entries) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.Entries[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + } + 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().(*QueuedUndelegation) + 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: QueuedUndelegation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueuedUndelegation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Entries = append(x.Entries, &PendingUndelegation{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Entries[len(x.Entries)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +var _ protoreflect.List = (*_GenesisState_2_list)(nil) + +type _GenesisState_2_list struct { + list *[]*PendingRedelegation +} + +func (x *_GenesisState_2_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_GenesisState_2_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_GenesisState_2_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingRedelegation) + (*x.list)[i] = concreteValue +} + +func (x *_GenesisState_2_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingRedelegation) + *x.list = append(*x.list, concreteValue) +} + +func (x *_GenesisState_2_list) AppendMutable() protoreflect.Value { + v := new(PendingRedelegation) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_GenesisState_2_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_GenesisState_2_list) NewElement() protoreflect.Value { + v := new(PendingRedelegation) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_GenesisState_2_list) IsValid() bool { + return x.list != nil +} + +var _ protoreflect.List = (*_GenesisState_3_list)(nil) + +type _GenesisState_3_list struct { + list *[]*PendingUndelegation +} + +func (x *_GenesisState_3_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_GenesisState_3_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_GenesisState_3_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingUndelegation) + (*x.list)[i] = concreteValue +} + +func (x *_GenesisState_3_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingUndelegation) + *x.list = append(*x.list, concreteValue) +} + +func (x *_GenesisState_3_list) AppendMutable() protoreflect.Value { + v := new(PendingUndelegation) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_GenesisState_3_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_GenesisState_3_list) NewElement() protoreflect.Value { + v := new(PendingUndelegation) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_GenesisState_3_list) IsValid() bool { + return x.list != nil +} + +var ( + md_GenesisState protoreflect.MessageDescriptor + fd_GenesisState_params protoreflect.FieldDescriptor + fd_GenesisState_pending_redelegations protoreflect.FieldDescriptor + fd_GenesisState_pending_undelegations protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + md_GenesisState = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("GenesisState") + fd_GenesisState_params = md_GenesisState.Fields().ByName("params") + fd_GenesisState_pending_redelegations = md_GenesisState.Fields().ByName("pending_redelegations") + fd_GenesisState_pending_undelegations = md_GenesisState.Fields().ByName("pending_undelegations") +} + +var _ protoreflect.Message = (*fastReflection_GenesisState)(nil) + +type fastReflection_GenesisState GenesisState + +func (x *GenesisState) ProtoReflect() protoreflect.Message { + return (*fastReflection_GenesisState)(x) +} + +func (x *GenesisState) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[5] + 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_GenesisState_messageType fastReflection_GenesisState_messageType +var _ protoreflect.MessageType = fastReflection_GenesisState_messageType{} + +type fastReflection_GenesisState_messageType struct{} + +func (x fastReflection_GenesisState_messageType) Zero() protoreflect.Message { + return (*fastReflection_GenesisState)(nil) +} +func (x fastReflection_GenesisState_messageType) New() protoreflect.Message { + return new(fastReflection_GenesisState) +} +func (x fastReflection_GenesisState_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_GenesisState +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_GenesisState) Descriptor() protoreflect.MessageDescriptor { + return md_GenesisState +} + +// 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_GenesisState) Type() protoreflect.MessageType { + return _fastReflection_GenesisState_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_GenesisState) New() protoreflect.Message { + return new(fastReflection_GenesisState) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_GenesisState) Interface() protoreflect.ProtoMessage { + return (*GenesisState)(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_GenesisState) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_GenesisState_params, value) { + return + } + } + if len(x.PendingRedelegations) != 0 { + value := protoreflect.ValueOfList(&_GenesisState_2_list{list: &x.PendingRedelegations}) + if !f(fd_GenesisState_pending_redelegations, value) { + return + } + } + if len(x.PendingUndelegations) != 0 { + value := protoreflect.ValueOfList(&_GenesisState_3_list{list: &x.PendingUndelegations}) + if !f(fd_GenesisState_pending_undelegations, value) { + return + } + } +} + +// 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_GenesisState) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + return x.Params != nil + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + return len(x.PendingRedelegations) != 0 + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + return len(x.PendingUndelegations) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState 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_GenesisState) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + x.Params = nil + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + x.PendingRedelegations = nil + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + x.PendingUndelegations = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState 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_GenesisState) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + if len(x.PendingRedelegations) == 0 { + return protoreflect.ValueOfList(&_GenesisState_2_list{}) + } + listValue := &_GenesisState_2_list{list: &x.PendingRedelegations} + return protoreflect.ValueOfList(listValue) + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + if len(x.PendingUndelegations) == 0 { + return protoreflect.ValueOfList(&_GenesisState_3_list{}) + } + listValue := &_GenesisState_3_list{list: &x.PendingUndelegations} + return protoreflect.ValueOfList(listValue) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState 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_GenesisState) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + x.Params = value.Message().Interface().(*Params) + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + lv := value.List() + clv := lv.(*_GenesisState_2_list) + x.PendingRedelegations = *clv.list + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + lv := value.List() + clv := lv.(*_GenesisState_3_list) + x.PendingUndelegations = *clv.list + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState 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_GenesisState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + if x.PendingRedelegations == nil { + x.PendingRedelegations = []*PendingRedelegation{} + } + value := &_GenesisState_2_list{list: &x.PendingRedelegations} + return protoreflect.ValueOfList(value) + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + if x.PendingUndelegations == nil { + x.PendingUndelegations = []*PendingUndelegation{} + } + value := &_GenesisState_3_list{list: &x.PendingUndelegations} + return protoreflect.ValueOfList(value) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState 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_GenesisState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + list := []*PendingRedelegation{} + return protoreflect.ValueOfList(&_GenesisState_2_list{list: &list}) + case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + list := []*PendingUndelegation{} + return protoreflect.ValueOfList(&_GenesisState_3_list{list: &list}) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState 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_GenesisState) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.GenesisState", 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_GenesisState) 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_GenesisState) 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_GenesisState) 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_GenesisState) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*GenesisState) + 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.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(l)) + } + if len(x.PendingRedelegations) > 0 { + for _, e := range x.PendingRedelegations { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if len(x.PendingUndelegations) > 0 { + for _, e := range x.PendingUndelegations { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(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().(*GenesisState) + 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 len(x.PendingUndelegations) > 0 { + for iNdEx := len(x.PendingUndelegations) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.PendingUndelegations[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x1a + } + } + if len(x.PendingRedelegations) > 0 { + for iNdEx := len(x.PendingRedelegations) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.PendingRedelegations[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + } + if x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + 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().(*GenesisState) + 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PendingRedelegations", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.PendingRedelegations = append(x.PendingRedelegations, &PendingRedelegation{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.PendingRedelegations[len(x.PendingRedelegations)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PendingUndelegations", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.PendingUndelegations = append(x.PendingUndelegations, &PendingUndelegation{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.PendingUndelegations[len(x.PendingUndelegations)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: cosmos/evm/poolrebalancer/v1/poolrebalancer.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) +) + +// Params defines the parameters for the poolrebalancer module. +type Params struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // pool_delegator_address is the account whose stake is rebalanced. + PoolDelegatorAddress string `protobuf:"bytes,1,opt,name=pool_delegator_address,json=poolDelegatorAddress,proto3" json:"pool_delegator_address,omitempty"` + // max_target_validators caps the bonded validator set size (top N by power). + MaxTargetValidators uint32 `protobuf:"varint,2,opt,name=max_target_validators,json=maxTargetValidators,proto3" json:"max_target_validators,omitempty"` + // rebalance_threshold_bp is the drift threshold in basis points. + RebalanceThresholdBp uint32 `protobuf:"varint,3,opt,name=rebalance_threshold_bp,json=rebalanceThresholdBp,proto3" json:"rebalance_threshold_bp,omitempty"` + // max_ops_per_block caps redelegate/undelegate operations per block. + MaxOpsPerBlock uint32 `protobuf:"varint,4,opt,name=max_ops_per_block,json=maxOpsPerBlock,proto3" json:"max_ops_per_block,omitempty"` + // max_move_per_op caps the amount moved per operation (0 = no cap). + MaxMovePerOp string `protobuf:"bytes,5,opt,name=max_move_per_op,json=maxMovePerOp,proto3" json:"max_move_per_op,omitempty"` + // use_undelegate_fallback enables undelegation when no safe redelegation move exists. + UseUndelegateFallback bool `protobuf:"varint,6,opt,name=use_undelegate_fallback,json=useUndelegateFallback,proto3" json:"use_undelegate_fallback,omitempty"` +} + +func (x *Params) Reset() { + *x = Params{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Params) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Params) ProtoMessage() {} + +// Deprecated: Use Params.ProtoReflect.Descriptor instead. +func (*Params) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{0} +} + +func (x *Params) GetPoolDelegatorAddress() string { + if x != nil { + return x.PoolDelegatorAddress + } + return "" +} + +func (x *Params) GetMaxTargetValidators() uint32 { + if x != nil { + return x.MaxTargetValidators + } + return 0 +} + +func (x *Params) GetRebalanceThresholdBp() uint32 { + if x != nil { + return x.RebalanceThresholdBp + } + return 0 +} + +func (x *Params) GetMaxOpsPerBlock() uint32 { + if x != nil { + return x.MaxOpsPerBlock + } + return 0 +} + +func (x *Params) GetMaxMovePerOp() string { + if x != nil { + return x.MaxMovePerOp + } + return "" +} + +func (x *Params) GetUseUndelegateFallback() bool { + if x != nil { + return x.UseUndelegateFallback + } + return false +} + +// PendingRedelegation is an in-flight redelegation tracked for transitive redelegation safety. +type PendingRedelegation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` + SrcValidatorAddress string `protobuf:"bytes,2,opt,name=src_validator_address,json=srcValidatorAddress,proto3" json:"src_validator_address,omitempty"` + DstValidatorAddress string `protobuf:"bytes,3,opt,name=dst_validator_address,json=dstValidatorAddress,proto3" json:"dst_validator_address,omitempty"` + Amount *v1beta1.Coin `protobuf:"bytes,4,opt,name=amount,proto3" json:"amount,omitempty"` + CompletionTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=completion_time,json=completionTime,proto3" json:"completion_time,omitempty"` +} + +func (x *PendingRedelegation) Reset() { + *x = PendingRedelegation{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PendingRedelegation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PendingRedelegation) ProtoMessage() {} + +// Deprecated: Use PendingRedelegation.ProtoReflect.Descriptor instead. +func (*PendingRedelegation) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{1} +} + +func (x *PendingRedelegation) GetDelegatorAddress() string { + if x != nil { + return x.DelegatorAddress + } + return "" +} + +func (x *PendingRedelegation) GetSrcValidatorAddress() string { + if x != nil { + return x.SrcValidatorAddress + } + return "" +} + +func (x *PendingRedelegation) GetDstValidatorAddress() string { + if x != nil { + return x.DstValidatorAddress + } + return "" +} + +func (x *PendingRedelegation) GetAmount() *v1beta1.Coin { + if x != nil { + return x.Amount + } + return nil +} + +func (x *PendingRedelegation) GetCompletionTime() *timestamppb.Timestamp { + if x != nil { + return x.CompletionTime + } + return nil +} + +// QueuedRedelegation groups redelegations that share the same completion time. +type QueuedRedelegation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Entries []*PendingRedelegation `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` +} + +func (x *QueuedRedelegation) Reset() { + *x = QueuedRedelegation{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueuedRedelegation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueuedRedelegation) ProtoMessage() {} + +// Deprecated: Use QueuedRedelegation.ProtoReflect.Descriptor instead. +func (*QueuedRedelegation) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{2} +} + +func (x *QueuedRedelegation) GetEntries() []*PendingRedelegation { + if x != nil { + return x.Entries + } + return nil +} + +// PendingUndelegation is an in-flight undelegation tracked for later cleanup and (optional) slash handling. +type PendingUndelegation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` + ValidatorAddress string `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` + Balance *v1beta1.Coin `protobuf:"bytes,3,opt,name=balance,proto3" json:"balance,omitempty"` + CompletionTime *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=completion_time,json=completionTime,proto3" json:"completion_time,omitempty"` +} + +func (x *PendingUndelegation) Reset() { + *x = PendingUndelegation{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PendingUndelegation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PendingUndelegation) ProtoMessage() {} + +// Deprecated: Use PendingUndelegation.ProtoReflect.Descriptor instead. +func (*PendingUndelegation) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{3} +} + +func (x *PendingUndelegation) GetDelegatorAddress() string { + if x != nil { + return x.DelegatorAddress + } + return "" +} + +func (x *PendingUndelegation) GetValidatorAddress() string { + if x != nil { + return x.ValidatorAddress + } + return "" +} + +func (x *PendingUndelegation) GetBalance() *v1beta1.Coin { + if x != nil { + return x.Balance + } + return nil +} + +func (x *PendingUndelegation) GetCompletionTime() *timestamppb.Timestamp { + if x != nil { + return x.CompletionTime + } + return nil +} + +// QueuedUndelegation groups undelegations that share the same (completion time, delegator) queue key. +type QueuedUndelegation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Entries []*PendingUndelegation `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` +} + +func (x *QueuedUndelegation) Reset() { + *x = QueuedUndelegation{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueuedUndelegation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueuedUndelegation) ProtoMessage() {} + +// Deprecated: Use QueuedUndelegation.ProtoReflect.Descriptor instead. +func (*QueuedUndelegation) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{4} +} + +func (x *QueuedUndelegation) GetEntries() []*PendingUndelegation { + if x != nil { + return x.Entries + } + return nil +} + +// GenesisState defines the poolrebalancer module's genesis state. +type GenesisState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` + // pending_redelegations and pending_undelegations allow restoring in-flight state on restart. + // They are optional for initial deployments. + PendingRedelegations []*PendingRedelegation `protobuf:"bytes,2,rep,name=pending_redelegations,json=pendingRedelegations,proto3" json:"pending_redelegations,omitempty"` + PendingUndelegations []*PendingUndelegation `protobuf:"bytes,3,rep,name=pending_undelegations,json=pendingUndelegations,proto3" json:"pending_undelegations,omitempty"` +} + +func (x *GenesisState) Reset() { + *x = GenesisState{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenesisState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenesisState) ProtoMessage() {} + +// Deprecated: Use GenesisState.ProtoReflect.Descriptor instead. +func (*GenesisState) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{5} +} + +func (x *GenesisState) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +func (x *GenesisState) GetPendingRedelegations() []*PendingRedelegation { + if x != nil { + return x.PendingRedelegations + } + return nil +} + +func (x *GenesisState) GetPendingUndelegations() []*PendingUndelegation { + if x != nil { + return x.PendingUndelegations + } + return nil +} + +var File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto protoreflect.FileDescriptor + +var file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDesc = []byte{ + 0x0a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, + 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, + 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, + 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x1a, 0x1e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, + 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd1, 0x02, 0x0a, 0x06, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x14, 0x70, 0x6f, 0x6f, 0x6c, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x6d, 0x61, 0x78, + 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, + 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x54, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x34, 0x0a, + 0x16, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, + 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x72, + 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, + 0x64, 0x42, 0x70, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x6f, 0x70, 0x73, 0x5f, 0x70, + 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, + 0x6d, 0x61, 0x78, 0x4f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x44, + 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6f, + 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1d, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, + 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, + 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x4d, 0x6f, 0x76, 0x65, 0x50, + 0x65, 0x72, 0x4f, 0x70, 0x12, 0x36, 0x0a, 0x17, 0x75, 0x73, 0x65, 0x5f, 0x75, 0x6e, 0x64, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x75, 0x73, 0x65, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x22, 0xb2, 0x02, 0x0a, + 0x13, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, + 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x72, 0x63, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x13, 0x73, 0x72, 0x63, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x64, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x61, 0x6d, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x4d, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, + 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, + 0x65, 0x22, 0x67, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x64, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, + 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, + 0x00, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xf9, 0x01, 0x0a, 0x13, 0x50, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, + 0x2b, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x39, 0x0a, 0x07, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x07, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xc8, 0xde, + 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x67, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x75, 0x65, 0x64, + 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x07, + 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, + 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, + 0xae, 0x02, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x42, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, + 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x12, 0x6c, 0x0a, 0x15, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, + 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, + 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x14, 0x70, 0x65, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x6c, 0x0a, 0x15, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, + 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, + 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x14, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x42, 0x8e, 0x02, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x13, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 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, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x6f, 0x6f, 0x6c, + 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, + 0x45, 0x50, 0xaa, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x2e, + 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x56, + 0x31, 0xca, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, + 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, + 0xe2, 0x02, 0x28, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, + 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x43, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x50, 0x6f, 0x6f, 0x6c, 0x72, + 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0xc8, 0xe1, 0x1e, + 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescOnce sync.Once + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescData = file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDesc +) + +func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP() []byte { + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescOnce.Do(func() { + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescData) + }) + return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescData +} + +var file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_goTypes = []interface{}{ + (*Params)(nil), // 0: cosmos.evm.poolrebalancer.v1.Params + (*PendingRedelegation)(nil), // 1: cosmos.evm.poolrebalancer.v1.PendingRedelegation + (*QueuedRedelegation)(nil), // 2: cosmos.evm.poolrebalancer.v1.QueuedRedelegation + (*PendingUndelegation)(nil), // 3: cosmos.evm.poolrebalancer.v1.PendingUndelegation + (*QueuedUndelegation)(nil), // 4: cosmos.evm.poolrebalancer.v1.QueuedUndelegation + (*GenesisState)(nil), // 5: cosmos.evm.poolrebalancer.v1.GenesisState + (*v1beta1.Coin)(nil), // 6: cosmos.base.v1beta1.Coin + (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp +} +var file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_depIdxs = []int32{ + 6, // 0: cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount:type_name -> cosmos.base.v1beta1.Coin + 7, // 1: cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time:type_name -> google.protobuf.Timestamp + 1, // 2: cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries:type_name -> cosmos.evm.poolrebalancer.v1.PendingRedelegation + 6, // 3: cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance:type_name -> cosmos.base.v1beta1.Coin + 7, // 4: cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time:type_name -> google.protobuf.Timestamp + 3, // 5: cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries:type_name -> cosmos.evm.poolrebalancer.v1.PendingUndelegation + 0, // 6: cosmos.evm.poolrebalancer.v1.GenesisState.params:type_name -> cosmos.evm.poolrebalancer.v1.Params + 1, // 7: cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations:type_name -> cosmos.evm.poolrebalancer.v1.PendingRedelegation + 3, // 8: cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations:type_name -> cosmos.evm.poolrebalancer.v1.PendingUndelegation + 9, // [9:9] is the sub-list for method output_type + 9, // [9:9] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() } +func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() { + if File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Params); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PendingRedelegation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueuedRedelegation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PendingUndelegation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueuedUndelegation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GenesisState); 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_evm_poolrebalancer_v1_poolrebalancer_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_goTypes, + DependencyIndexes: file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_depIdxs, + MessageInfos: file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes, + }.Build() + File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto = out.File + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDesc = nil + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_goTypes = nil + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_depIdxs = nil +} diff --git a/api/cosmos/evm/poolrebalancer/v1/query.pulsar.go b/api/cosmos/evm/poolrebalancer/v1/query.pulsar.go new file mode 100644 index 00000000..475c4fbc --- /dev/null +++ b/api/cosmos/evm/poolrebalancer/v1/query.pulsar.go @@ -0,0 +1,3331 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package poolrebalancerv1 + +import ( + _ "cosmossdk.io/api/amino" + v1beta1 "cosmossdk.io/api/cosmos/base/query/v1beta1" + fmt "fmt" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + _ "google.golang.org/genproto/googleapis/api/annotations" + 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_QueryParamsRequest protoreflect.MessageDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_query_proto_init() + md_QueryParamsRequest = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryParamsRequest") +} + +var _ protoreflect.Message = (*fastReflection_QueryParamsRequest)(nil) + +type fastReflection_QueryParamsRequest QueryParamsRequest + +func (x *QueryParamsRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryParamsRequest)(x) +} + +func (x *QueryParamsRequest) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_query_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_QueryParamsRequest_messageType fastReflection_QueryParamsRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryParamsRequest_messageType{} + +type fastReflection_QueryParamsRequest_messageType struct{} + +func (x fastReflection_QueryParamsRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryParamsRequest)(nil) +} +func (x fastReflection_QueryParamsRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryParamsRequest) +} +func (x fastReflection_QueryParamsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryParamsRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsRequest +} + +// 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_QueryParamsRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryParamsRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryParamsRequest) New() protoreflect.Message { + return new(fastReflection_QueryParamsRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryParamsRequest) Interface() protoreflect.ProtoMessage { + return (*QueryParamsRequest)(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_QueryParamsRequest) 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_QueryParamsRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest 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_QueryParamsRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest 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_QueryParamsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest 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_QueryParamsRequest) 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.evm.poolrebalancer.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest 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_QueryParamsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest 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_QueryParamsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest 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_QueryParamsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryParamsRequest", 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_QueryParamsRequest) 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_QueryParamsRequest) 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_QueryParamsRequest) 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_QueryParamsRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryParamsRequest) + 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().(*QueryParamsRequest) + 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().(*QueryParamsRequest) + 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: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsRequest: 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, + } +} + +var ( + md_QueryParamsResponse protoreflect.MessageDescriptor + fd_QueryParamsResponse_params protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_query_proto_init() + md_QueryParamsResponse = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryParamsResponse") + fd_QueryParamsResponse_params = md_QueryParamsResponse.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_QueryParamsResponse)(nil) + +type fastReflection_QueryParamsResponse QueryParamsResponse + +func (x *QueryParamsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryParamsResponse)(x) +} + +func (x *QueryParamsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[1] + 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_QueryParamsResponse_messageType fastReflection_QueryParamsResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryParamsResponse_messageType{} + +type fastReflection_QueryParamsResponse_messageType struct{} + +func (x fastReflection_QueryParamsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryParamsResponse)(nil) +} +func (x fastReflection_QueryParamsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryParamsResponse) +} +func (x fastReflection_QueryParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryParamsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryParamsResponse +} + +// 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_QueryParamsResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryParamsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryParamsResponse) New() protoreflect.Message { + return new(fastReflection_QueryParamsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryParamsResponse) Interface() protoreflect.ProtoMessage { + return (*QueryParamsResponse)(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_QueryParamsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_QueryParamsResponse_params, value) { + return + } + } +} + +// 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_QueryParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse 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_QueryParamsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse 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_QueryParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse 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_QueryParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse 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_QueryParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse 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_QueryParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse 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_QueryParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryParamsResponse", 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_QueryParamsResponse) 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_QueryParamsResponse) 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_QueryParamsResponse) 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_QueryParamsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryParamsResponse) + 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.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(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().(*QueryParamsResponse) + 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 x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + 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().(*QueryParamsResponse) + 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: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +var ( + md_QueryPendingRedelegationsRequest protoreflect.MessageDescriptor + fd_QueryPendingRedelegationsRequest_pagination protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_query_proto_init() + md_QueryPendingRedelegationsRequest = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingRedelegationsRequest") + fd_QueryPendingRedelegationsRequest_pagination = md_QueryPendingRedelegationsRequest.Fields().ByName("pagination") +} + +var _ protoreflect.Message = (*fastReflection_QueryPendingRedelegationsRequest)(nil) + +type fastReflection_QueryPendingRedelegationsRequest QueryPendingRedelegationsRequest + +func (x *QueryPendingRedelegationsRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryPendingRedelegationsRequest)(x) +} + +func (x *QueryPendingRedelegationsRequest) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[2] + 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_QueryPendingRedelegationsRequest_messageType fastReflection_QueryPendingRedelegationsRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryPendingRedelegationsRequest_messageType{} + +type fastReflection_QueryPendingRedelegationsRequest_messageType struct{} + +func (x fastReflection_QueryPendingRedelegationsRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryPendingRedelegationsRequest)(nil) +} +func (x fastReflection_QueryPendingRedelegationsRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryPendingRedelegationsRequest) +} +func (x fastReflection_QueryPendingRedelegationsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryPendingRedelegationsRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryPendingRedelegationsRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryPendingRedelegationsRequest +} + +// 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_QueryPendingRedelegationsRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryPendingRedelegationsRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryPendingRedelegationsRequest) New() protoreflect.Message { + return new(fastReflection_QueryPendingRedelegationsRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryPendingRedelegationsRequest) Interface() protoreflect.ProtoMessage { + return (*QueryPendingRedelegationsRequest)(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_QueryPendingRedelegationsRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Pagination != nil { + value := protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + if !f(fd_QueryPendingRedelegationsRequest_pagination, value) { + return + } + } +} + +// 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_QueryPendingRedelegationsRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + return x.Pagination != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest 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_QueryPendingRedelegationsRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + x.Pagination = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest 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_QueryPendingRedelegationsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + value := x.Pagination + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest 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_QueryPendingRedelegationsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + x.Pagination = value.Message().Interface().(*v1beta1.PageRequest) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest 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_QueryPendingRedelegationsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + if x.Pagination == nil { + x.Pagination = new(v1beta1.PageRequest) + } + return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest 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_QueryPendingRedelegationsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + m := new(v1beta1.PageRequest) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest 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_QueryPendingRedelegationsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest", 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_QueryPendingRedelegationsRequest) 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_QueryPendingRedelegationsRequest) 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_QueryPendingRedelegationsRequest) 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_QueryPendingRedelegationsRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryPendingRedelegationsRequest) + 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.Pagination != nil { + l = options.Size(x.Pagination) + n += 1 + l + runtime.Sov(uint64(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().(*QueryPendingRedelegationsRequest) + 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 x.Pagination != nil { + encoded, err := options.Marshal(x.Pagination) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + 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().(*QueryPendingRedelegationsRequest) + 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: QueryPendingRedelegationsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryPendingRedelegationsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Pagination == nil { + x.Pagination = &v1beta1.PageRequest{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Pagination); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +var _ protoreflect.List = (*_QueryPendingRedelegationsResponse_1_list)(nil) + +type _QueryPendingRedelegationsResponse_1_list struct { + list *[]*PendingRedelegation +} + +func (x *_QueryPendingRedelegationsResponse_1_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_QueryPendingRedelegationsResponse_1_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_QueryPendingRedelegationsResponse_1_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingRedelegation) + (*x.list)[i] = concreteValue +} + +func (x *_QueryPendingRedelegationsResponse_1_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingRedelegation) + *x.list = append(*x.list, concreteValue) +} + +func (x *_QueryPendingRedelegationsResponse_1_list) AppendMutable() protoreflect.Value { + v := new(PendingRedelegation) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueryPendingRedelegationsResponse_1_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_QueryPendingRedelegationsResponse_1_list) NewElement() protoreflect.Value { + v := new(PendingRedelegation) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueryPendingRedelegationsResponse_1_list) IsValid() bool { + return x.list != nil +} + +var ( + md_QueryPendingRedelegationsResponse protoreflect.MessageDescriptor + fd_QueryPendingRedelegationsResponse_redelegations protoreflect.FieldDescriptor + fd_QueryPendingRedelegationsResponse_pagination protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_query_proto_init() + md_QueryPendingRedelegationsResponse = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingRedelegationsResponse") + fd_QueryPendingRedelegationsResponse_redelegations = md_QueryPendingRedelegationsResponse.Fields().ByName("redelegations") + fd_QueryPendingRedelegationsResponse_pagination = md_QueryPendingRedelegationsResponse.Fields().ByName("pagination") +} + +var _ protoreflect.Message = (*fastReflection_QueryPendingRedelegationsResponse)(nil) + +type fastReflection_QueryPendingRedelegationsResponse QueryPendingRedelegationsResponse + +func (x *QueryPendingRedelegationsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryPendingRedelegationsResponse)(x) +} + +func (x *QueryPendingRedelegationsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[3] + 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_QueryPendingRedelegationsResponse_messageType fastReflection_QueryPendingRedelegationsResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryPendingRedelegationsResponse_messageType{} + +type fastReflection_QueryPendingRedelegationsResponse_messageType struct{} + +func (x fastReflection_QueryPendingRedelegationsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryPendingRedelegationsResponse)(nil) +} +func (x fastReflection_QueryPendingRedelegationsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryPendingRedelegationsResponse) +} +func (x fastReflection_QueryPendingRedelegationsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryPendingRedelegationsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryPendingRedelegationsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryPendingRedelegationsResponse +} + +// 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_QueryPendingRedelegationsResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryPendingRedelegationsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryPendingRedelegationsResponse) New() protoreflect.Message { + return new(fastReflection_QueryPendingRedelegationsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryPendingRedelegationsResponse) Interface() protoreflect.ProtoMessage { + return (*QueryPendingRedelegationsResponse)(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_QueryPendingRedelegationsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Redelegations) != 0 { + value := protoreflect.ValueOfList(&_QueryPendingRedelegationsResponse_1_list{list: &x.Redelegations}) + if !f(fd_QueryPendingRedelegationsResponse_redelegations, value) { + return + } + } + if x.Pagination != nil { + value := protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + if !f(fd_QueryPendingRedelegationsResponse_pagination, value) { + return + } + } +} + +// 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_QueryPendingRedelegationsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + return len(x.Redelegations) != 0 + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + return x.Pagination != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse 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_QueryPendingRedelegationsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + x.Redelegations = nil + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + x.Pagination = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse 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_QueryPendingRedelegationsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + if len(x.Redelegations) == 0 { + return protoreflect.ValueOfList(&_QueryPendingRedelegationsResponse_1_list{}) + } + listValue := &_QueryPendingRedelegationsResponse_1_list{list: &x.Redelegations} + return protoreflect.ValueOfList(listValue) + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + value := x.Pagination + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse 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_QueryPendingRedelegationsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + lv := value.List() + clv := lv.(*_QueryPendingRedelegationsResponse_1_list) + x.Redelegations = *clv.list + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + x.Pagination = value.Message().Interface().(*v1beta1.PageResponse) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse 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_QueryPendingRedelegationsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + if x.Redelegations == nil { + x.Redelegations = []*PendingRedelegation{} + } + value := &_QueryPendingRedelegationsResponse_1_list{list: &x.Redelegations} + return protoreflect.ValueOfList(value) + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + if x.Pagination == nil { + x.Pagination = new(v1beta1.PageResponse) + } + return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse 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_QueryPendingRedelegationsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + list := []*PendingRedelegation{} + return protoreflect.ValueOfList(&_QueryPendingRedelegationsResponse_1_list{list: &list}) + case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + m := new(v1beta1.PageResponse) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse 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_QueryPendingRedelegationsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse", 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_QueryPendingRedelegationsResponse) 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_QueryPendingRedelegationsResponse) 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_QueryPendingRedelegationsResponse) 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_QueryPendingRedelegationsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryPendingRedelegationsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if len(x.Redelegations) > 0 { + for _, e := range x.Redelegations { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.Pagination != nil { + l = options.Size(x.Pagination) + n += 1 + l + runtime.Sov(uint64(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().(*QueryPendingRedelegationsResponse) + 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 x.Pagination != nil { + encoded, err := options.Marshal(x.Pagination) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Redelegations) > 0 { + for iNdEx := len(x.Redelegations) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.Redelegations[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + } + 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().(*QueryPendingRedelegationsResponse) + 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: QueryPendingRedelegationsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryPendingRedelegationsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Redelegations", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Redelegations = append(x.Redelegations, &PendingRedelegation{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Redelegations[len(x.Redelegations)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Pagination == nil { + x.Pagination = &v1beta1.PageResponse{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Pagination); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +var ( + md_QueryPendingUndelegationsRequest protoreflect.MessageDescriptor + fd_QueryPendingUndelegationsRequest_pagination protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_query_proto_init() + md_QueryPendingUndelegationsRequest = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingUndelegationsRequest") + fd_QueryPendingUndelegationsRequest_pagination = md_QueryPendingUndelegationsRequest.Fields().ByName("pagination") +} + +var _ protoreflect.Message = (*fastReflection_QueryPendingUndelegationsRequest)(nil) + +type fastReflection_QueryPendingUndelegationsRequest QueryPendingUndelegationsRequest + +func (x *QueryPendingUndelegationsRequest) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryPendingUndelegationsRequest)(x) +} + +func (x *QueryPendingUndelegationsRequest) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[4] + 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_QueryPendingUndelegationsRequest_messageType fastReflection_QueryPendingUndelegationsRequest_messageType +var _ protoreflect.MessageType = fastReflection_QueryPendingUndelegationsRequest_messageType{} + +type fastReflection_QueryPendingUndelegationsRequest_messageType struct{} + +func (x fastReflection_QueryPendingUndelegationsRequest_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryPendingUndelegationsRequest)(nil) +} +func (x fastReflection_QueryPendingUndelegationsRequest_messageType) New() protoreflect.Message { + return new(fastReflection_QueryPendingUndelegationsRequest) +} +func (x fastReflection_QueryPendingUndelegationsRequest_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryPendingUndelegationsRequest +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryPendingUndelegationsRequest) Descriptor() protoreflect.MessageDescriptor { + return md_QueryPendingUndelegationsRequest +} + +// 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_QueryPendingUndelegationsRequest) Type() protoreflect.MessageType { + return _fastReflection_QueryPendingUndelegationsRequest_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryPendingUndelegationsRequest) New() protoreflect.Message { + return new(fastReflection_QueryPendingUndelegationsRequest) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryPendingUndelegationsRequest) Interface() protoreflect.ProtoMessage { + return (*QueryPendingUndelegationsRequest)(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_QueryPendingUndelegationsRequest) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Pagination != nil { + value := protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + if !f(fd_QueryPendingUndelegationsRequest_pagination, value) { + return + } + } +} + +// 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_QueryPendingUndelegationsRequest) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + return x.Pagination != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest 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_QueryPendingUndelegationsRequest) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + x.Pagination = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest 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_QueryPendingUndelegationsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + value := x.Pagination + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest 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_QueryPendingUndelegationsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + x.Pagination = value.Message().Interface().(*v1beta1.PageRequest) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest 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_QueryPendingUndelegationsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + if x.Pagination == nil { + x.Pagination = new(v1beta1.PageRequest) + } + return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest 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_QueryPendingUndelegationsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + m := new(v1beta1.PageRequest) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest 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_QueryPendingUndelegationsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest", 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_QueryPendingUndelegationsRequest) 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_QueryPendingUndelegationsRequest) 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_QueryPendingUndelegationsRequest) 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_QueryPendingUndelegationsRequest) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryPendingUndelegationsRequest) + 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.Pagination != nil { + l = options.Size(x.Pagination) + n += 1 + l + runtime.Sov(uint64(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().(*QueryPendingUndelegationsRequest) + 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 x.Pagination != nil { + encoded, err := options.Marshal(x.Pagination) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + 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().(*QueryPendingUndelegationsRequest) + 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: QueryPendingUndelegationsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryPendingUndelegationsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Pagination == nil { + x.Pagination = &v1beta1.PageRequest{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Pagination); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +var _ protoreflect.List = (*_QueryPendingUndelegationsResponse_1_list)(nil) + +type _QueryPendingUndelegationsResponse_1_list struct { + list *[]*PendingUndelegation +} + +func (x *_QueryPendingUndelegationsResponse_1_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_QueryPendingUndelegationsResponse_1_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) +} + +func (x *_QueryPendingUndelegationsResponse_1_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingUndelegation) + (*x.list)[i] = concreteValue +} + +func (x *_QueryPendingUndelegationsResponse_1_list) Append(value protoreflect.Value) { + valueUnwrapped := value.Message() + concreteValue := valueUnwrapped.Interface().(*PendingUndelegation) + *x.list = append(*x.list, concreteValue) +} + +func (x *_QueryPendingUndelegationsResponse_1_list) AppendMutable() protoreflect.Value { + v := new(PendingUndelegation) + *x.list = append(*x.list, v) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueryPendingUndelegationsResponse_1_list) Truncate(n int) { + for i := n; i < len(*x.list); i++ { + (*x.list)[i] = nil + } + *x.list = (*x.list)[:n] +} + +func (x *_QueryPendingUndelegationsResponse_1_list) NewElement() protoreflect.Value { + v := new(PendingUndelegation) + return protoreflect.ValueOfMessage(v.ProtoReflect()) +} + +func (x *_QueryPendingUndelegationsResponse_1_list) IsValid() bool { + return x.list != nil +} + +var ( + md_QueryPendingUndelegationsResponse protoreflect.MessageDescriptor + fd_QueryPendingUndelegationsResponse_undelegations protoreflect.FieldDescriptor + fd_QueryPendingUndelegationsResponse_pagination protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_query_proto_init() + md_QueryPendingUndelegationsResponse = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingUndelegationsResponse") + fd_QueryPendingUndelegationsResponse_undelegations = md_QueryPendingUndelegationsResponse.Fields().ByName("undelegations") + fd_QueryPendingUndelegationsResponse_pagination = md_QueryPendingUndelegationsResponse.Fields().ByName("pagination") +} + +var _ protoreflect.Message = (*fastReflection_QueryPendingUndelegationsResponse)(nil) + +type fastReflection_QueryPendingUndelegationsResponse QueryPendingUndelegationsResponse + +func (x *QueryPendingUndelegationsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_QueryPendingUndelegationsResponse)(x) +} + +func (x *QueryPendingUndelegationsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[5] + 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_QueryPendingUndelegationsResponse_messageType fastReflection_QueryPendingUndelegationsResponse_messageType +var _ protoreflect.MessageType = fastReflection_QueryPendingUndelegationsResponse_messageType{} + +type fastReflection_QueryPendingUndelegationsResponse_messageType struct{} + +func (x fastReflection_QueryPendingUndelegationsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_QueryPendingUndelegationsResponse)(nil) +} +func (x fastReflection_QueryPendingUndelegationsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_QueryPendingUndelegationsResponse) +} +func (x fastReflection_QueryPendingUndelegationsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_QueryPendingUndelegationsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_QueryPendingUndelegationsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_QueryPendingUndelegationsResponse +} + +// 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_QueryPendingUndelegationsResponse) Type() protoreflect.MessageType { + return _fastReflection_QueryPendingUndelegationsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_QueryPendingUndelegationsResponse) New() protoreflect.Message { + return new(fastReflection_QueryPendingUndelegationsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_QueryPendingUndelegationsResponse) Interface() protoreflect.ProtoMessage { + return (*QueryPendingUndelegationsResponse)(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_QueryPendingUndelegationsResponse) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Undelegations) != 0 { + value := protoreflect.ValueOfList(&_QueryPendingUndelegationsResponse_1_list{list: &x.Undelegations}) + if !f(fd_QueryPendingUndelegationsResponse_undelegations, value) { + return + } + } + if x.Pagination != nil { + value := protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + if !f(fd_QueryPendingUndelegationsResponse_pagination, value) { + return + } + } +} + +// 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_QueryPendingUndelegationsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + return len(x.Undelegations) != 0 + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + return x.Pagination != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse 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_QueryPendingUndelegationsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + x.Undelegations = nil + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + x.Pagination = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse 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_QueryPendingUndelegationsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + if len(x.Undelegations) == 0 { + return protoreflect.ValueOfList(&_QueryPendingUndelegationsResponse_1_list{}) + } + listValue := &_QueryPendingUndelegationsResponse_1_list{list: &x.Undelegations} + return protoreflect.ValueOfList(listValue) + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + value := x.Pagination + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse 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_QueryPendingUndelegationsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + lv := value.List() + clv := lv.(*_QueryPendingUndelegationsResponse_1_list) + x.Undelegations = *clv.list + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + x.Pagination = value.Message().Interface().(*v1beta1.PageResponse) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse 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_QueryPendingUndelegationsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + if x.Undelegations == nil { + x.Undelegations = []*PendingUndelegation{} + } + value := &_QueryPendingUndelegationsResponse_1_list{list: &x.Undelegations} + return protoreflect.ValueOfList(value) + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + if x.Pagination == nil { + x.Pagination = new(v1beta1.PageResponse) + } + return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse 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_QueryPendingUndelegationsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + list := []*PendingUndelegation{} + return protoreflect.ValueOfList(&_QueryPendingUndelegationsResponse_1_list{list: &list}) + case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + m := new(v1beta1.PageResponse) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse 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_QueryPendingUndelegationsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse", 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_QueryPendingUndelegationsResponse) 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_QueryPendingUndelegationsResponse) 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_QueryPendingUndelegationsResponse) 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_QueryPendingUndelegationsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*QueryPendingUndelegationsResponse) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + if len(x.Undelegations) > 0 { + for _, e := range x.Undelegations { + l = options.Size(e) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if x.Pagination != nil { + l = options.Size(x.Pagination) + n += 1 + l + runtime.Sov(uint64(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().(*QueryPendingUndelegationsResponse) + 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 x.Pagination != nil { + encoded, err := options.Marshal(x.Pagination) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Undelegations) > 0 { + for iNdEx := len(x.Undelegations) - 1; iNdEx >= 0; iNdEx-- { + encoded, err := options.Marshal(x.Undelegations[iNdEx]) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + } + } + 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().(*QueryPendingUndelegationsResponse) + 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: QueryPendingUndelegationsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: QueryPendingUndelegationsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Undelegations", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Undelegations = append(x.Undelegations, &PendingUndelegation{}) + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Undelegations[len(x.Undelegations)-1]); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Pagination == nil { + x.Pagination = &v1beta1.PageResponse{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Pagination); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: cosmos/evm/poolrebalancer/v1/query.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) +) + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *QueryParamsRequest) Reset() { + *x = QueryParamsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryParamsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryParamsRequest) ProtoMessage() {} + +// Deprecated: Use QueryParamsRequest.ProtoReflect.Descriptor instead. +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{0} +} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *QueryParamsResponse) Reset() { + *x = QueryParamsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryParamsResponse) ProtoMessage() {} + +// Deprecated: Use QueryParamsResponse.ProtoReflect.Descriptor instead. +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{1} +} + +func (x *QueryParamsResponse) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// QueryPendingRedelegationsRequest is the request type for the Query/PendingRedelegations RPC method. +type QueryPendingRedelegationsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // pagination defines an optional pagination for the request. + Pagination *v1beta1.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (x *QueryPendingRedelegationsRequest) Reset() { + *x = QueryPendingRedelegationsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryPendingRedelegationsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryPendingRedelegationsRequest) ProtoMessage() {} + +// Deprecated: Use QueryPendingRedelegationsRequest.ProtoReflect.Descriptor instead. +func (*QueryPendingRedelegationsRequest) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{2} +} + +func (x *QueryPendingRedelegationsRequest) GetPagination() *v1beta1.PageRequest { + if x != nil { + return x.Pagination + } + return nil +} + +// QueryPendingRedelegationsResponse is the response type for the Query/PendingRedelegations RPC method. +type QueryPendingRedelegationsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Redelegations []*PendingRedelegation `protobuf:"bytes,1,rep,name=redelegations,proto3" json:"redelegations,omitempty"` + Pagination *v1beta1.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (x *QueryPendingRedelegationsResponse) Reset() { + *x = QueryPendingRedelegationsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryPendingRedelegationsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryPendingRedelegationsResponse) ProtoMessage() {} + +// Deprecated: Use QueryPendingRedelegationsResponse.ProtoReflect.Descriptor instead. +func (*QueryPendingRedelegationsResponse) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{3} +} + +func (x *QueryPendingRedelegationsResponse) GetRedelegations() []*PendingRedelegation { + if x != nil { + return x.Redelegations + } + return nil +} + +func (x *QueryPendingRedelegationsResponse) GetPagination() *v1beta1.PageResponse { + if x != nil { + return x.Pagination + } + return nil +} + +// QueryPendingUndelegationsRequest is the request type for the Query/PendingUndelegations RPC method. +type QueryPendingUndelegationsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // pagination defines an optional pagination for the request. + Pagination *v1beta1.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (x *QueryPendingUndelegationsRequest) Reset() { + *x = QueryPendingUndelegationsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryPendingUndelegationsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryPendingUndelegationsRequest) ProtoMessage() {} + +// Deprecated: Use QueryPendingUndelegationsRequest.ProtoReflect.Descriptor instead. +func (*QueryPendingUndelegationsRequest) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{4} +} + +func (x *QueryPendingUndelegationsRequest) GetPagination() *v1beta1.PageRequest { + if x != nil { + return x.Pagination + } + return nil +} + +// QueryPendingUndelegationsResponse is the response type for the Query/PendingUndelegations RPC method. +type QueryPendingUndelegationsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Undelegations []*PendingUndelegation `protobuf:"bytes,1,rep,name=undelegations,proto3" json:"undelegations,omitempty"` + Pagination *v1beta1.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (x *QueryPendingUndelegationsResponse) Reset() { + *x = QueryPendingUndelegationsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QueryPendingUndelegationsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QueryPendingUndelegationsResponse) ProtoMessage() {} + +// Deprecated: Use QueryPendingUndelegationsResponse.ProtoReflect.Descriptor instead. +func (*QueryPendingUndelegationsResponse) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{5} +} + +func (x *QueryPendingUndelegationsResponse) GetUndelegations() []*PendingUndelegation { + if x != nil { + return x.Undelegations + } + return nil +} + +func (x *QueryPendingUndelegationsResponse) GetPagination() *v1beta1.PageResponse { + if x != nil { + return x.Pagination + } + return nil +} + +var File_cosmos_evm_poolrebalancer_v1_query_proto protoreflect.FileDescriptor + +var file_cosmos_evm_poolrebalancer_v1_query_proto_rawDesc = []byte{ + 0x0a, 0x28, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, + 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, + 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, + 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, + 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x14, + 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x06, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x22, 0x6a, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0xd0, 0x01, 0x0a, 0x21, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0d, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, + 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0d, 0x72, 0x65, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x6a, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0xd0, 0x01, 0x0a, 0x21, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0d, 0x75, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0d, 0x75, 0x6e, 0x64, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x32, 0xd3, 0x04, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x9b, 0x01, 0x0a, + 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, + 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, + 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0xd4, 0x01, 0x0a, 0x14, 0x50, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x3e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, + 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, + 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x3f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, + 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, + 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x12, 0x33, 0x2f, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0xd4, 0x01, 0x0a, 0x14, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3e, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3f, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x35, 0x12, 0x33, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, + 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, + 0x76, 0x31, 0x2f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x85, 0x02, 0x0a, 0x20, 0x63, 0x6f, 0x6d, + 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, + 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 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, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x6f, 0x6f, 0x6c, 0x72, + 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x45, + 0x50, 0xaa, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x2e, 0x50, + 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x56, 0x31, + 0xca, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, + 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, + 0x02, 0x28, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, 0x6f, + 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0xc8, 0xe1, 0x1e, 0x00, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescOnce sync.Once + file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescData = file_cosmos_evm_poolrebalancer_v1_query_proto_rawDesc +) + +func file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP() []byte { + file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescOnce.Do(func() { + file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescData) + }) + return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescData +} + +var file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_cosmos_evm_poolrebalancer_v1_query_proto_goTypes = []interface{}{ + (*QueryParamsRequest)(nil), // 0: cosmos.evm.poolrebalancer.v1.QueryParamsRequest + (*QueryParamsResponse)(nil), // 1: cosmos.evm.poolrebalancer.v1.QueryParamsResponse + (*QueryPendingRedelegationsRequest)(nil), // 2: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest + (*QueryPendingRedelegationsResponse)(nil), // 3: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse + (*QueryPendingUndelegationsRequest)(nil), // 4: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest + (*QueryPendingUndelegationsResponse)(nil), // 5: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse + (*Params)(nil), // 6: cosmos.evm.poolrebalancer.v1.Params + (*v1beta1.PageRequest)(nil), // 7: cosmos.base.query.v1beta1.PageRequest + (*PendingRedelegation)(nil), // 8: cosmos.evm.poolrebalancer.v1.PendingRedelegation + (*v1beta1.PageResponse)(nil), // 9: cosmos.base.query.v1beta1.PageResponse + (*PendingUndelegation)(nil), // 10: cosmos.evm.poolrebalancer.v1.PendingUndelegation +} +var file_cosmos_evm_poolrebalancer_v1_query_proto_depIdxs = []int32{ + 6, // 0: cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params:type_name -> cosmos.evm.poolrebalancer.v1.Params + 7, // 1: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 8, // 2: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations:type_name -> cosmos.evm.poolrebalancer.v1.PendingRedelegation + 9, // 3: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 7, // 4: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 10, // 5: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations:type_name -> cosmos.evm.poolrebalancer.v1.PendingUndelegation + 9, // 6: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 0, // 7: cosmos.evm.poolrebalancer.v1.Query.Params:input_type -> cosmos.evm.poolrebalancer.v1.QueryParamsRequest + 2, // 8: cosmos.evm.poolrebalancer.v1.Query.PendingRedelegations:input_type -> cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest + 4, // 9: cosmos.evm.poolrebalancer.v1.Query.PendingUndelegations:input_type -> cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest + 1, // 10: cosmos.evm.poolrebalancer.v1.Query.Params:output_type -> cosmos.evm.poolrebalancer.v1.QueryParamsResponse + 3, // 11: cosmos.evm.poolrebalancer.v1.Query.PendingRedelegations:output_type -> cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse + 5, // 12: cosmos.evm.poolrebalancer.v1.Query.PendingUndelegations:output_type -> cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse + 10, // [10:13] is the sub-list for method output_type + 7, // [7:10] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_cosmos_evm_poolrebalancer_v1_query_proto_init() } +func file_cosmos_evm_poolrebalancer_v1_query_proto_init() { + if File_cosmos_evm_poolrebalancer_v1_query_proto != nil { + return + } + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + if !protoimpl.UnsafeEnabled { + file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryParamsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryParamsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryPendingRedelegationsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryPendingRedelegationsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryPendingUndelegationsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QueryPendingUndelegationsResponse); 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_evm_poolrebalancer_v1_query_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_cosmos_evm_poolrebalancer_v1_query_proto_goTypes, + DependencyIndexes: file_cosmos_evm_poolrebalancer_v1_query_proto_depIdxs, + MessageInfos: file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes, + }.Build() + File_cosmos_evm_poolrebalancer_v1_query_proto = out.File + file_cosmos_evm_poolrebalancer_v1_query_proto_rawDesc = nil + file_cosmos_evm_poolrebalancer_v1_query_proto_goTypes = nil + file_cosmos_evm_poolrebalancer_v1_query_proto_depIdxs = nil +} diff --git a/api/cosmos/evm/poolrebalancer/v1/query_grpc.pb.go b/api/cosmos/evm/poolrebalancer/v1/query_grpc.pb.go new file mode 100644 index 00000000..477d55d5 --- /dev/null +++ b/api/cosmos/evm/poolrebalancer/v1/query_grpc.pb.go @@ -0,0 +1,189 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: cosmos/evm/poolrebalancer/v1/query.proto + +package poolrebalancerv1 + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + Query_Params_FullMethodName = "/cosmos.evm.poolrebalancer.v1.Query/Params" + Query_PendingRedelegations_FullMethodName = "/cosmos.evm.poolrebalancer.v1.Query/PendingRedelegations" + Query_PendingUndelegations_FullMethodName = "/cosmos.evm.poolrebalancer.v1.Query/PendingUndelegations" +) + +// 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. +type QueryClient interface { + // Params returns the poolrebalancer module params. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // PendingRedelegations returns tracked in-flight redelegations. + PendingRedelegations(ctx context.Context, in *QueryPendingRedelegationsRequest, opts ...grpc.CallOption) (*QueryPendingRedelegationsResponse, error) + // PendingUndelegations returns tracked in-flight undelegations. + PendingUndelegations(ctx context.Context, in *QueryPendingUndelegationsRequest, opts ...grpc.CallOption) (*QueryPendingUndelegationsResponse, error) +} + +type queryClient struct { + cc grpc.ClientConnInterface +} + +func NewQueryClient(cc grpc.ClientConnInterface) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, Query_Params_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) PendingRedelegations(ctx context.Context, in *QueryPendingRedelegationsRequest, opts ...grpc.CallOption) (*QueryPendingRedelegationsResponse, error) { + out := new(QueryPendingRedelegationsResponse) + err := c.cc.Invoke(ctx, Query_PendingRedelegations_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) PendingUndelegations(ctx context.Context, in *QueryPendingUndelegationsRequest, opts ...grpc.CallOption) (*QueryPendingUndelegationsResponse, error) { + out := new(QueryPendingUndelegationsResponse) + err := c.cc.Invoke(ctx, Query_PendingUndelegations_FullMethodName, in, out, opts...) + 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 +type QueryServer interface { + // Params returns the poolrebalancer module params. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // PendingRedelegations returns tracked in-flight redelegations. + PendingRedelegations(context.Context, *QueryPendingRedelegationsRequest) (*QueryPendingRedelegationsResponse, error) + // PendingUndelegations returns tracked in-flight undelegations. + PendingUndelegations(context.Context, *QueryPendingUndelegationsRequest) (*QueryPendingUndelegationsResponse, error) + mustEmbedUnimplementedQueryServer() +} + +// UnimplementedQueryServer must be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (UnimplementedQueryServer) PendingRedelegations(context.Context, *QueryPendingRedelegationsRequest) (*QueryPendingRedelegationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PendingRedelegations not implemented") +} +func (UnimplementedQueryServer) PendingUndelegations(context.Context, *QueryPendingUndelegationsRequest) (*QueryPendingUndelegationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PendingUndelegations not implemented") +} +func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {} + +// 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) { + s.RegisterService(&Query_ServiceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_Params_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_PendingRedelegations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryPendingRedelegationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).PendingRedelegations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_PendingRedelegations_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).PendingRedelegations(ctx, req.(*QueryPendingRedelegationsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_PendingUndelegations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryPendingUndelegationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).PendingUndelegations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Query_PendingUndelegations_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).PendingUndelegations(ctx, req.(*QueryPendingUndelegationsRequest)) + } + 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.evm.poolrebalancer.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "PendingRedelegations", + Handler: _Query_PendingRedelegations_Handler, + }, + { + MethodName: "PendingUndelegations", + Handler: _Query_PendingUndelegations_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/evm/poolrebalancer/v1/query.proto", +} diff --git a/api/cosmos/evm/poolrebalancer/v1/tx.pulsar.go b/api/cosmos/evm/poolrebalancer/v1/tx.pulsar.go new file mode 100644 index 00000000..027d29a5 --- /dev/null +++ b/api/cosmos/evm/poolrebalancer/v1/tx.pulsar.go @@ -0,0 +1,1099 @@ +// Code generated by protoc-gen-go-pulsar. DO NOT EDIT. +package poolrebalancerv1 + +import ( + _ "cosmossdk.io/api/amino" + _ "cosmossdk.io/api/cosmos/msg/v1" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + runtime "github.com/cosmos/cosmos-proto/runtime" + _ "github.com/cosmos/gogoproto/gogoproto" + 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_MsgUpdateParams protoreflect.MessageDescriptor + fd_MsgUpdateParams_authority protoreflect.FieldDescriptor + fd_MsgUpdateParams_params protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_tx_proto_init() + md_MsgUpdateParams = File_cosmos_evm_poolrebalancer_v1_tx_proto.Messages().ByName("MsgUpdateParams") + fd_MsgUpdateParams_authority = md_MsgUpdateParams.Fields().ByName("authority") + fd_MsgUpdateParams_params = md_MsgUpdateParams.Fields().ByName("params") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParams)(nil) + +type fastReflection_MsgUpdateParams MsgUpdateParams + +func (x *MsgUpdateParams) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(x) +} + +func (x *MsgUpdateParams) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_tx_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_MsgUpdateParams_messageType fastReflection_MsgUpdateParams_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParams_messageType{} + +type fastReflection_MsgUpdateParams_messageType struct{} + +func (x fastReflection_MsgUpdateParams_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParams)(nil) +} +func (x fastReflection_MsgUpdateParams_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} +func (x fastReflection_MsgUpdateParams_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParams) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParams +} + +// 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_MsgUpdateParams) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParams_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParams) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParams) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParams) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParams)(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_MsgUpdateParams) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Authority != "" { + value := protoreflect.ValueOfString(x.Authority) + if !f(fd_MsgUpdateParams_authority, value) { + return + } + } + if x.Params != nil { + value := protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + if !f(fd_MsgUpdateParams_params, value) { + return + } + } +} + +// 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_MsgUpdateParams) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + return x.Authority != "" + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + return x.Params != nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams 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_MsgUpdateParams) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + x.Authority = "" + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + x.Params = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams 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_MsgUpdateParams) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + value := x.Authority + return protoreflect.ValueOfString(value) + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + value := x.Params + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams 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_MsgUpdateParams) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + x.Authority = value.Interface().(string) + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + x.Params = value.Message().Interface().(*Params) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams 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_MsgUpdateParams) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + if x.Params == nil { + x.Params = new(Params) + } + return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + panic(fmt.Errorf("field authority of message cosmos.evm.poolrebalancer.v1.MsgUpdateParams is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams 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_MsgUpdateParams) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + return protoreflect.ValueOfString("") + case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + m := new(Params) + return protoreflect.ValueOfMessage(m.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams 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_MsgUpdateParams) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.MsgUpdateParams", 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_MsgUpdateParams) 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_MsgUpdateParams) 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_MsgUpdateParams) 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_MsgUpdateParams) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParams) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + l = len(x.Authority) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Params != nil { + l = options.Size(x.Params) + n += 1 + l + runtime.Sov(uint64(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().(*MsgUpdateParams) + 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 x.Params != nil { + encoded, err := options.Marshal(x.Params) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + } + if len(x.Authority) > 0 { + i -= len(x.Authority) + copy(dAtA[i:], x.Authority) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Authority))) + i-- + dAtA[i] = 0xa + } + 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().(*MsgUpdateParams) + 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: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen 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++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + 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++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.Params == nil { + x.Params = &Params{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Params); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex + 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, + } +} + +var ( + md_MsgUpdateParamsResponse protoreflect.MessageDescriptor +) + +func init() { + file_cosmos_evm_poolrebalancer_v1_tx_proto_init() + md_MsgUpdateParamsResponse = File_cosmos_evm_poolrebalancer_v1_tx_proto.Messages().ByName("MsgUpdateParamsResponse") +} + +var _ protoreflect.Message = (*fastReflection_MsgUpdateParamsResponse)(nil) + +type fastReflection_MsgUpdateParamsResponse MsgUpdateParamsResponse + +func (x *MsgUpdateParamsResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(x) +} + +func (x *MsgUpdateParamsResponse) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[1] + 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_MsgUpdateParamsResponse_messageType fastReflection_MsgUpdateParamsResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgUpdateParamsResponse_messageType{} + +type fastReflection_MsgUpdateParamsResponse_messageType struct{} + +func (x fastReflection_MsgUpdateParamsResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgUpdateParamsResponse)(nil) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} +func (x fastReflection_MsgUpdateParamsResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgUpdateParamsResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgUpdateParamsResponse +} + +// 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_MsgUpdateParamsResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgUpdateParamsResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgUpdateParamsResponse) New() protoreflect.Message { + return new(fastReflection_MsgUpdateParamsResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgUpdateParamsResponse) Interface() protoreflect.ProtoMessage { + return (*MsgUpdateParamsResponse)(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_MsgUpdateParamsResponse) 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_MsgUpdateParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) 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.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + } + panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse 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_MsgUpdateParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse", 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_MsgUpdateParamsResponse) 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_MsgUpdateParamsResponse) 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_MsgUpdateParamsResponse) 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_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgUpdateParamsResponse) + 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().(*MsgUpdateParamsResponse) + 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().(*MsgUpdateParamsResponse) + 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: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgUpdateParamsResponse: 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, + } +} + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.0 +// protoc (unknown) +// source: cosmos/evm/poolrebalancer/v1/tx.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) +) + +// MsgUpdateParams defines a Msg for updating the x/poolrebalancer module parameters. +type MsgUpdateParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the x/poolrebalancer parameters to update. + // NOTE: All parameters must be supplied. + Params *Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params,omitempty"` +} + +func (x *MsgUpdateParams) Reset() { + *x = MsgUpdateParams{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParams) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParams.ProtoReflect.Descriptor instead. +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescGZIP(), []int{0} +} + +func (x *MsgUpdateParams) GetAuthority() string { + if x != nil { + return x.Authority + } + return "" +} + +func (x *MsgUpdateParams) GetParams() *Params { + if x != nil { + return x.Params + } + return nil +} + +// MsgUpdateParamsResponse defines the response structure for executing a MsgUpdateParams message. +type MsgUpdateParamsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MsgUpdateParamsResponse) Reset() { + *x = MsgUpdateParamsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgUpdateParamsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgUpdateParamsResponse) ProtoMessage() {} + +// Deprecated: Use MsgUpdateParamsResponse.ProtoReflect.Descriptor instead. +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescGZIP(), []int{1} +} + +var File_cosmos_evm_poolrebalancer_v1_tx_proto protoreflect.FileDescriptor + +var file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDesc = []byte{ + 0x0a, 0x25, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, + 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x74, + 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, + 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd2, 0x01, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, + 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x12, 0x47, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, + 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, + 0x2a, 0x01, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x3e, 0x82, 0xe7, 0xb0, 0x2a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x8a, 0xe7, 0xb0, 0x2a, 0x2b, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, + 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x4d, 0x73, 0x67, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, + 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x82, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x74, 0x0a, + 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2d, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, + 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x35, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xfe, 0x01, 0x0a, 0x20, 0x63, + 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, + 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, + 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 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, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x45, 0x50, + 0xaa, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x2e, 0x50, 0x6f, + 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, + 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, 0x6f, + 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, + 0x28, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, 0x6f, 0x6c, + 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescOnce sync.Once + file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescData = file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDesc +) + +func file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescGZIP() []byte { + file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescOnce.Do(func() { + file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescData) + }) + return file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescData +} + +var file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cosmos_evm_poolrebalancer_v1_tx_proto_goTypes = []interface{}{ + (*MsgUpdateParams)(nil), // 0: cosmos.evm.poolrebalancer.v1.MsgUpdateParams + (*MsgUpdateParamsResponse)(nil), // 1: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse + (*Params)(nil), // 2: cosmos.evm.poolrebalancer.v1.Params +} +var file_cosmos_evm_poolrebalancer_v1_tx_proto_depIdxs = []int32{ + 2, // 0: cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params:type_name -> cosmos.evm.poolrebalancer.v1.Params + 0, // 1: cosmos.evm.poolrebalancer.v1.Msg.UpdateParams:input_type -> cosmos.evm.poolrebalancer.v1.MsgUpdateParams + 1, // 2: cosmos.evm.poolrebalancer.v1.Msg.UpdateParams:output_type -> cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse + 2, // [2:3] is the sub-list for method output_type + 1, // [1:2] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_cosmos_evm_poolrebalancer_v1_tx_proto_init() } +func file_cosmos_evm_poolrebalancer_v1_tx_proto_init() { + if File_cosmos_evm_poolrebalancer_v1_tx_proto != nil { + return + } + file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + if !protoimpl.UnsafeEnabled { + file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParams); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgUpdateParamsResponse); 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_evm_poolrebalancer_v1_tx_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_cosmos_evm_poolrebalancer_v1_tx_proto_goTypes, + DependencyIndexes: file_cosmos_evm_poolrebalancer_v1_tx_proto_depIdxs, + MessageInfos: file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes, + }.Build() + File_cosmos_evm_poolrebalancer_v1_tx_proto = out.File + file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDesc = nil + file_cosmos_evm_poolrebalancer_v1_tx_proto_goTypes = nil + file_cosmos_evm_poolrebalancer_v1_tx_proto_depIdxs = nil +} diff --git a/api/cosmos/evm/poolrebalancer/v1/tx_grpc.pb.go b/api/cosmos/evm/poolrebalancer/v1/tx_grpc.pb.go new file mode 100644 index 00000000..c705597d --- /dev/null +++ b/api/cosmos/evm/poolrebalancer/v1/tx_grpc.pb.go @@ -0,0 +1,113 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc (unknown) +// source: cosmos/evm/poolrebalancer/v1/tx.proto + +package poolrebalancerv1 + +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.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + Msg_UpdateParams_FullMethodName = "/cosmos.evm.poolrebalancer.v1.Msg/UpdateParams" +) + +// MsgClient is the client API for Msg 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. +type MsgClient interface { + // UpdateParams is a governance operation for updating the x/poolrebalancer module parameters. + // The authority is the Cosmos SDK x/gov module account. + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc.ClientConnInterface +} + +func NewMsgClient(cc grpc.ClientConnInterface) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, Msg_UpdateParams_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +// All implementations must embed UnimplementedMsgServer +// for forward compatibility +type MsgServer interface { + // UpdateParams is a governance operation for updating the x/poolrebalancer module parameters. + // The authority is the Cosmos SDK x/gov module account. + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + mustEmbedUnimplementedMsgServer() +} + +// UnimplementedMsgServer must be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} +func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} + +// UnsafeMsgServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MsgServer will +// result in compilation errors. +type UnsafeMsgServer interface { + mustEmbedUnimplementedMsgServer() +} + +func RegisterMsgServer(s grpc.ServiceRegistrar, srv MsgServer) { + s.RegisterService(&Msg_ServiceDesc, srv) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Msg_UpdateParams_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +// Msg_ServiceDesc is the grpc.ServiceDesc for Msg service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Msg_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos.evm.poolrebalancer.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/evm/poolrebalancer/v1/tx.proto", +} diff --git a/proto/cosmos/evm/poolrebalancer/v1/poolrebalancer.proto b/proto/cosmos/evm/poolrebalancer/v1/poolrebalancer.proto new file mode 100644 index 00000000..7b1231ad --- /dev/null +++ b/proto/cosmos/evm/poolrebalancer/v1/poolrebalancer.proto @@ -0,0 +1,75 @@ +syntax = "proto3"; +package cosmos.evm.poolrebalancer.v1; + +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/cosmos/evm/x/poolrebalancer/types"; +option (gogoproto.goproto_getters_all) = false; + +// Params defines the parameters for the poolrebalancer module. +message Params { + // pool_delegator_address is the account whose stake is rebalanced. + string pool_delegator_address = 1; + + // max_target_validators caps the bonded validator set size (top N by power). + uint32 max_target_validators = 2; + + // rebalance_threshold_bp is the drift threshold in basis points. + uint32 rebalance_threshold_bp = 3; + + // max_ops_per_block caps redelegate/undelegate operations per block. + uint32 max_ops_per_block = 4; + + // max_move_per_op caps the amount moved per operation (0 = no cap). + string max_move_per_op = 5 [ + (gogoproto.customtype) = "cosmossdk.io/math.Int", + (gogoproto.nullable) = false + ]; + + // use_undelegate_fallback enables undelegation when no safe redelegation move exists. + bool use_undelegate_fallback = 6; +} + +// PendingRedelegation is an in-flight redelegation tracked for transitive redelegation safety. +message PendingRedelegation { + string delegator_address = 1; + string src_validator_address = 2; + string dst_validator_address = 3; + cosmos.base.v1beta1.Coin amount = 4 [ (gogoproto.nullable) = false ]; + google.protobuf.Timestamp completion_time = 5 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; +} + +// QueuedRedelegation groups redelegations that share the same completion time. +message QueuedRedelegation { + repeated PendingRedelegation entries = 1 [ (gogoproto.nullable) = false ]; +} + +// PendingUndelegation is an in-flight undelegation tracked for later cleanup and (optional) slash handling. +message PendingUndelegation { + string delegator_address = 1; + string validator_address = 2; + cosmos.base.v1beta1.Coin balance = 3 [ (gogoproto.nullable) = false ]; + google.protobuf.Timestamp completion_time = 4 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; +} + +// QueuedUndelegation groups undelegations that share the same (completion time, delegator) queue key. +message QueuedUndelegation { + repeated PendingUndelegation entries = 1 [ (gogoproto.nullable) = false ]; +} + +// GenesisState defines the poolrebalancer module's genesis state. +message GenesisState { + Params params = 1 [ (gogoproto.nullable) = false ]; + + // pending_redelegations and pending_undelegations allow restoring in-flight state on restart. + // They are optional for initial deployments. + repeated PendingRedelegation pending_redelegations = 2 + [ (gogoproto.nullable) = false ]; + repeated PendingUndelegation pending_undelegations = 3 + [ (gogoproto.nullable) = false ]; +} + diff --git a/proto/cosmos/evm/poolrebalancer/v1/query.proto b/proto/cosmos/evm/poolrebalancer/v1/query.proto new file mode 100644 index 00000000..7de90b3f --- /dev/null +++ b/proto/cosmos/evm/poolrebalancer/v1/query.proto @@ -0,0 +1,69 @@ +syntax = "proto3"; +package cosmos.evm.poolrebalancer.v1; + +import "amino/amino.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "cosmos/evm/poolrebalancer/v1/poolrebalancer.proto"; +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; + +option go_package = "github.com/cosmos/evm/x/poolrebalancer/types"; +option (gogoproto.goproto_getters_all) = false; + +// Query defines the gRPC querier service. +service Query { + // Params returns the poolrebalancer module params. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/cosmos/evm/poolrebalancer/v1/params"; + } + + // PendingRedelegations returns tracked in-flight redelegations. + rpc PendingRedelegations(QueryPendingRedelegationsRequest) + returns (QueryPendingRedelegationsResponse) { + option (google.api.http).get = + "/cosmos/evm/poolrebalancer/v1/pending_redelegations"; + } + + // PendingUndelegations returns tracked in-flight undelegations. + rpc PendingUndelegations(QueryPendingUndelegationsRequest) + returns (QueryPendingUndelegationsResponse) { + option (google.api.http).get = + "/cosmos/evm/poolrebalancer/v1/pending_undelegations"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + Params params = 1 + [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ]; +} + +// QueryPendingRedelegationsRequest is the request type for the Query/PendingRedelegations RPC method. +message QueryPendingRedelegationsRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryPendingRedelegationsResponse is the response type for the Query/PendingRedelegations RPC method. +message QueryPendingRedelegationsResponse { + repeated PendingRedelegation redelegations = 1 + [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// QueryPendingUndelegationsRequest is the request type for the Query/PendingUndelegations RPC method. +message QueryPendingUndelegationsRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryPendingUndelegationsResponse is the response type for the Query/PendingUndelegations RPC method. +message QueryPendingUndelegationsResponse { + repeated PendingUndelegation undelegations = 1 + [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + diff --git a/proto/cosmos/evm/poolrebalancer/v1/tx.proto b/proto/cosmos/evm/poolrebalancer/v1/tx.proto new file mode 100644 index 00000000..93b59ed4 --- /dev/null +++ b/proto/cosmos/evm/poolrebalancer/v1/tx.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; +package cosmos.evm.poolrebalancer.v1; + +import "amino/amino.proto"; +import "cosmos/evm/poolrebalancer/v1/poolrebalancer.proto"; +import "cosmos/msg/v1/msg.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/evm/x/poolrebalancer/types"; + +// Msg defines the poolrebalancer Msg service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // UpdateParams is a governance operation for updating the x/poolrebalancer module parameters. + // The authority is the Cosmos SDK x/gov module account. + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgUpdateParams defines a Msg for updating the x/poolrebalancer module parameters. +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + option (amino.name) = "cosmos/evm/x/poolrebalancer/MsgUpdateParams"; + + // authority is the address of the governance account. + string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + // params defines the x/poolrebalancer parameters to update. + // NOTE: All parameters must be supplied. + Params params = 2 + [ (gogoproto.nullable) = false, (amino.dont_omitempty) = true ]; +} + +// MsgUpdateParamsResponse defines the response structure for executing a MsgUpdateParams message. +message MsgUpdateParamsResponse {} + diff --git a/x/poolrebalancer/types/poolrebalancer.pb.go b/x/poolrebalancer/types/poolrebalancer.pb.go new file mode 100644 index 00000000..831b6a58 --- /dev/null +++ b/x/poolrebalancer/types/poolrebalancer.pb.go @@ -0,0 +1,1790 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/evm/poolrebalancer/v1/poolrebalancer.proto + +package types + +import ( + cosmossdk_io_math "cosmossdk.io/math" + fmt "fmt" + types "github.com/cosmos/cosmos-sdk/types" + _ "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/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 + +// Params defines the parameters for the poolrebalancer module. +type Params struct { + // pool_delegator_address is the account whose stake is rebalanced. + PoolDelegatorAddress string `protobuf:"bytes,1,opt,name=pool_delegator_address,json=poolDelegatorAddress,proto3" json:"pool_delegator_address,omitempty"` + // max_target_validators caps the bonded validator set size (top N by power). + MaxTargetValidators uint32 `protobuf:"varint,2,opt,name=max_target_validators,json=maxTargetValidators,proto3" json:"max_target_validators,omitempty"` + // rebalance_threshold_bp is the drift threshold in basis points. + RebalanceThresholdBp uint32 `protobuf:"varint,3,opt,name=rebalance_threshold_bp,json=rebalanceThresholdBp,proto3" json:"rebalance_threshold_bp,omitempty"` + // max_ops_per_block caps redelegate/undelegate operations per block. + MaxOpsPerBlock uint32 `protobuf:"varint,4,opt,name=max_ops_per_block,json=maxOpsPerBlock,proto3" json:"max_ops_per_block,omitempty"` + // max_move_per_op caps the amount moved per operation (0 = no cap). + MaxMovePerOp cosmossdk_io_math.Int `protobuf:"bytes,5,opt,name=max_move_per_op,json=maxMovePerOp,proto3,customtype=cosmossdk.io/math.Int" json:"max_move_per_op"` + // use_undelegate_fallback enables undelegation when no safe redelegation move exists. + UseUndelegateFallback bool `protobuf:"varint,6,opt,name=use_undelegate_fallback,json=useUndelegateFallback,proto3" json:"use_undelegate_fallback,omitempty"` +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_c420feafe1f88946, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.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 *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +// PendingRedelegation is an in-flight redelegation tracked for transitive redelegation safety. +type PendingRedelegation struct { + DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` + SrcValidatorAddress string `protobuf:"bytes,2,opt,name=src_validator_address,json=srcValidatorAddress,proto3" json:"src_validator_address,omitempty"` + DstValidatorAddress string `protobuf:"bytes,3,opt,name=dst_validator_address,json=dstValidatorAddress,proto3" json:"dst_validator_address,omitempty"` + Amount types.Coin `protobuf:"bytes,4,opt,name=amount,proto3" json:"amount"` + CompletionTime time.Time `protobuf:"bytes,5,opt,name=completion_time,json=completionTime,proto3,stdtime" json:"completion_time"` +} + +func (m *PendingRedelegation) Reset() { *m = PendingRedelegation{} } +func (m *PendingRedelegation) String() string { return proto.CompactTextString(m) } +func (*PendingRedelegation) ProtoMessage() {} +func (*PendingRedelegation) Descriptor() ([]byte, []int) { + return fileDescriptor_c420feafe1f88946, []int{1} +} +func (m *PendingRedelegation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PendingRedelegation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PendingRedelegation.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 *PendingRedelegation) XXX_Merge(src proto.Message) { + xxx_messageInfo_PendingRedelegation.Merge(m, src) +} +func (m *PendingRedelegation) XXX_Size() int { + return m.Size() +} +func (m *PendingRedelegation) XXX_DiscardUnknown() { + xxx_messageInfo_PendingRedelegation.DiscardUnknown(m) +} + +var xxx_messageInfo_PendingRedelegation proto.InternalMessageInfo + +// QueuedRedelegation groups redelegations that share the same completion time. +type QueuedRedelegation struct { + Entries []PendingRedelegation `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries"` +} + +func (m *QueuedRedelegation) Reset() { *m = QueuedRedelegation{} } +func (m *QueuedRedelegation) String() string { return proto.CompactTextString(m) } +func (*QueuedRedelegation) ProtoMessage() {} +func (*QueuedRedelegation) Descriptor() ([]byte, []int) { + return fileDescriptor_c420feafe1f88946, []int{2} +} +func (m *QueuedRedelegation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueuedRedelegation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueuedRedelegation.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 *QueuedRedelegation) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueuedRedelegation.Merge(m, src) +} +func (m *QueuedRedelegation) XXX_Size() int { + return m.Size() +} +func (m *QueuedRedelegation) XXX_DiscardUnknown() { + xxx_messageInfo_QueuedRedelegation.DiscardUnknown(m) +} + +var xxx_messageInfo_QueuedRedelegation proto.InternalMessageInfo + +// PendingUndelegation is an in-flight undelegation tracked for later cleanup and (optional) slash handling. +type PendingUndelegation struct { + DelegatorAddress string `protobuf:"bytes,1,opt,name=delegator_address,json=delegatorAddress,proto3" json:"delegator_address,omitempty"` + ValidatorAddress string `protobuf:"bytes,2,opt,name=validator_address,json=validatorAddress,proto3" json:"validator_address,omitempty"` + Balance types.Coin `protobuf:"bytes,3,opt,name=balance,proto3" json:"balance"` + CompletionTime time.Time `protobuf:"bytes,4,opt,name=completion_time,json=completionTime,proto3,stdtime" json:"completion_time"` +} + +func (m *PendingUndelegation) Reset() { *m = PendingUndelegation{} } +func (m *PendingUndelegation) String() string { return proto.CompactTextString(m) } +func (*PendingUndelegation) ProtoMessage() {} +func (*PendingUndelegation) Descriptor() ([]byte, []int) { + return fileDescriptor_c420feafe1f88946, []int{3} +} +func (m *PendingUndelegation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PendingUndelegation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PendingUndelegation.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 *PendingUndelegation) XXX_Merge(src proto.Message) { + xxx_messageInfo_PendingUndelegation.Merge(m, src) +} +func (m *PendingUndelegation) XXX_Size() int { + return m.Size() +} +func (m *PendingUndelegation) XXX_DiscardUnknown() { + xxx_messageInfo_PendingUndelegation.DiscardUnknown(m) +} + +var xxx_messageInfo_PendingUndelegation proto.InternalMessageInfo + +// QueuedUndelegation groups undelegations that share the same (completion time, delegator) queue key. +type QueuedUndelegation struct { + Entries []PendingUndelegation `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries"` +} + +func (m *QueuedUndelegation) Reset() { *m = QueuedUndelegation{} } +func (m *QueuedUndelegation) String() string { return proto.CompactTextString(m) } +func (*QueuedUndelegation) ProtoMessage() {} +func (*QueuedUndelegation) Descriptor() ([]byte, []int) { + return fileDescriptor_c420feafe1f88946, []int{4} +} +func (m *QueuedUndelegation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueuedUndelegation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueuedUndelegation.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 *QueuedUndelegation) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueuedUndelegation.Merge(m, src) +} +func (m *QueuedUndelegation) XXX_Size() int { + return m.Size() +} +func (m *QueuedUndelegation) XXX_DiscardUnknown() { + xxx_messageInfo_QueuedUndelegation.DiscardUnknown(m) +} + +var xxx_messageInfo_QueuedUndelegation proto.InternalMessageInfo + +// GenesisState defines the poolrebalancer module's genesis state. +type GenesisState struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // pending_redelegations and pending_undelegations allow restoring in-flight state on restart. + // They are optional for initial deployments. + PendingRedelegations []PendingRedelegation `protobuf:"bytes,2,rep,name=pending_redelegations,json=pendingRedelegations,proto3" json:"pending_redelegations"` + PendingUndelegations []PendingUndelegation `protobuf:"bytes,3,rep,name=pending_undelegations,json=pendingUndelegations,proto3" json:"pending_undelegations"` +} + +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_c420feafe1f88946, []int{5} +} +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 init() { + proto.RegisterType((*Params)(nil), "cosmos.evm.poolrebalancer.v1.Params") + proto.RegisterType((*PendingRedelegation)(nil), "cosmos.evm.poolrebalancer.v1.PendingRedelegation") + proto.RegisterType((*QueuedRedelegation)(nil), "cosmos.evm.poolrebalancer.v1.QueuedRedelegation") + proto.RegisterType((*PendingUndelegation)(nil), "cosmos.evm.poolrebalancer.v1.PendingUndelegation") + proto.RegisterType((*QueuedUndelegation)(nil), "cosmos.evm.poolrebalancer.v1.QueuedUndelegation") + proto.RegisterType((*GenesisState)(nil), "cosmos.evm.poolrebalancer.v1.GenesisState") +} + +func init() { + proto.RegisterFile("cosmos/evm/poolrebalancer/v1/poolrebalancer.proto", fileDescriptor_c420feafe1f88946) +} + +var fileDescriptor_c420feafe1f88946 = []byte{ + // 703 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x95, 0xcd, 0x6e, 0xd3, 0x4a, + 0x14, 0xc7, 0xe3, 0xa4, 0x37, 0xed, 0x9d, 0xf4, 0xf6, 0xc3, 0x4d, 0xee, 0xcd, 0xad, 0xc0, 0xa9, + 0x22, 0x16, 0x41, 0x45, 0xb6, 0x12, 0x10, 0x88, 0x25, 0xa1, 0x02, 0x81, 0x54, 0x35, 0x0d, 0x85, + 0x05, 0x1b, 0x6b, 0x6c, 0x9f, 0x3a, 0x56, 0x6d, 0xcf, 0x68, 0x66, 0x6c, 0x85, 0xb7, 0xe8, 0x93, + 0xb0, 0xe0, 0x29, 0xba, 0x2c, 0x3b, 0xc4, 0xa2, 0x40, 0xfb, 0x14, 0xec, 0xd0, 0xf8, 0xab, 0x69, + 0x9a, 0xf2, 0x55, 0x76, 0xce, 0xfc, 0xcf, 0x7f, 0x8e, 0xe7, 0x77, 0xfe, 0xf1, 0xa0, 0xae, 0x4d, + 0x78, 0x40, 0xb8, 0x01, 0x71, 0x60, 0x50, 0x42, 0x7c, 0x06, 0x16, 0xf6, 0x71, 0x68, 0x03, 0x33, + 0xe2, 0xee, 0xd4, 0x8a, 0x4e, 0x19, 0x11, 0x44, 0xbd, 0x91, 0x5a, 0x74, 0x88, 0x03, 0x7d, 0xaa, + 0x20, 0xee, 0xae, 0x6b, 0xd9, 0x86, 0x16, 0xe6, 0x60, 0xc4, 0x5d, 0x0b, 0x04, 0xee, 0x1a, 0x36, + 0xf1, 0xc2, 0xd4, 0xbd, 0x5e, 0x77, 0x89, 0x4b, 0x92, 0x47, 0x43, 0x3e, 0x65, 0xab, 0x2d, 0x97, + 0x10, 0xd7, 0x07, 0x23, 0xf9, 0x65, 0x45, 0xfb, 0x86, 0xf0, 0x02, 0xe0, 0x02, 0x07, 0x34, 0x2d, + 0x68, 0xbf, 0x2f, 0xa3, 0xea, 0x00, 0x33, 0x1c, 0x70, 0xf5, 0x1e, 0xfa, 0x57, 0xb6, 0x35, 0x1d, + 0xf0, 0xc1, 0xc5, 0x82, 0x30, 0x13, 0x3b, 0x0e, 0x03, 0xce, 0x9b, 0xca, 0x86, 0xd2, 0xf9, 0x7b, + 0x58, 0x97, 0xea, 0x56, 0x2e, 0x3e, 0x4a, 0x35, 0xb5, 0x87, 0x1a, 0x01, 0x1e, 0x9b, 0x02, 0x33, + 0x17, 0x84, 0x19, 0x63, 0xdf, 0x73, 0xa4, 0xcc, 0x9b, 0xe5, 0x0d, 0xa5, 0xf3, 0xcf, 0x70, 0x2d, + 0xc0, 0xe3, 0xbd, 0x44, 0x7b, 0x55, 0x48, 0xb2, 0x53, 0x71, 0x38, 0x53, 0x8c, 0x18, 0xf0, 0x11, + 0xf1, 0x1d, 0xd3, 0xa2, 0xcd, 0x4a, 0x62, 0xaa, 0x17, 0xea, 0x5e, 0x2e, 0xf6, 0xa9, 0x7a, 0x1b, + 0xad, 0xca, 0x4e, 0x84, 0x72, 0x93, 0x02, 0x33, 0x2d, 0x9f, 0xd8, 0x07, 0xcd, 0xb9, 0xc4, 0xb0, + 0x14, 0xe0, 0xf1, 0x0e, 0xe5, 0x03, 0x60, 0x7d, 0xb9, 0xaa, 0x6e, 0xa1, 0x65, 0x59, 0x1a, 0x90, + 0x18, 0x92, 0x5a, 0x42, 0x9b, 0x7f, 0xc9, 0x33, 0xf4, 0x6f, 0x1e, 0x9d, 0xb4, 0x4a, 0x1f, 0x4f, + 0x5a, 0x8d, 0x94, 0x26, 0x77, 0x0e, 0x74, 0x8f, 0x18, 0x01, 0x16, 0x23, 0xfd, 0x59, 0x28, 0x86, + 0x8b, 0x01, 0x1e, 0x6f, 0x93, 0x18, 0x06, 0xc0, 0x76, 0xa8, 0x7a, 0x1f, 0xfd, 0x17, 0x71, 0x30, + 0xa3, 0x30, 0x23, 0x02, 0xe6, 0x3e, 0xf6, 0x7d, 0x0b, 0xdb, 0x07, 0xcd, 0xea, 0x86, 0xd2, 0x59, + 0x18, 0x36, 0x22, 0x0e, 0x2f, 0x0b, 0xf5, 0x49, 0x26, 0xb6, 0xdf, 0x95, 0xd1, 0xda, 0x00, 0x42, + 0xc7, 0x0b, 0xdd, 0x21, 0x64, 0xaa, 0x47, 0x42, 0x75, 0x13, 0xad, 0x5e, 0xc5, 0x76, 0xc5, 0x99, + 0xc1, 0x95, 0x33, 0xfb, 0x1c, 0x68, 0x61, 0x28, 0x27, 0x86, 0x35, 0xce, 0xec, 0x82, 0xe8, 0x84, + 0xc7, 0xe1, 0x62, 0x86, 0xa7, 0x92, 0x7a, 0x1c, 0x2e, 0x2e, 0x79, 0x1e, 0xa0, 0x2a, 0x0e, 0x48, + 0x14, 0x8a, 0x04, 0x65, 0xad, 0xf7, 0xbf, 0x9e, 0xc5, 0x50, 0x06, 0x4d, 0xcf, 0x82, 0xa6, 0x3f, + 0x26, 0x5e, 0xd8, 0x9f, 0x93, 0xf0, 0x86, 0x59, 0xb9, 0xba, 0x8d, 0x96, 0x6d, 0x12, 0x50, 0x1f, + 0xe4, 0xd9, 0x4c, 0x99, 0xab, 0x84, 0x71, 0xad, 0xb7, 0xae, 0xa7, 0xa1, 0xd3, 0xf3, 0xd0, 0xe9, + 0x7b, 0x79, 0xe8, 0xfa, 0x0b, 0x72, 0x8b, 0xc3, 0x4f, 0x2d, 0x65, 0xb8, 0x74, 0x6e, 0x96, 0x72, + 0xdb, 0x45, 0xea, 0x6e, 0x04, 0x11, 0x38, 0x17, 0x90, 0xed, 0xa2, 0x79, 0x08, 0x05, 0xf3, 0x40, + 0x82, 0xaa, 0x74, 0x6a, 0xbd, 0xae, 0xfe, 0xbd, 0x7f, 0x89, 0x3e, 0x03, 0x7b, 0xf6, 0xda, 0xf9, + 0x3e, 0xed, 0xaf, 0x4a, 0x31, 0x9d, 0x62, 0x76, 0xbf, 0x3c, 0x9d, 0x4d, 0xb4, 0x7a, 0xd5, 0x64, + 0x56, 0xe2, 0x69, 0xc4, 0x0f, 0xd1, 0x7c, 0xf6, 0x8e, 0xc9, 0x20, 0x7e, 0x82, 0x71, 0x5e, 0x3f, + 0x0b, 0xf2, 0xdc, 0x9f, 0x80, 0x7c, 0xe1, 0xe4, 0xbf, 0x09, 0x79, 0x72, 0x8f, 0x69, 0xc8, 0x6f, + 0xcb, 0x68, 0xf1, 0x29, 0x84, 0xc0, 0x3d, 0xfe, 0x42, 0x60, 0x01, 0x6a, 0x1f, 0x55, 0x69, 0xf2, + 0x99, 0x49, 0x90, 0xd6, 0x7a, 0xb7, 0x7e, 0xd0, 0x22, 0xa9, 0xcd, 0x13, 0x97, 0x3a, 0x55, 0x1f, + 0x35, 0x68, 0xda, 0xda, 0x64, 0x13, 0x03, 0x96, 0xe0, 0xaf, 0x15, 0x8d, 0x3a, 0xbd, 0x2c, 0x5d, + 0xe8, 0x16, 0x85, 0x93, 0xdd, 0x2a, 0xd7, 0x63, 0x94, 0x77, 0x9b, 0x94, 0x78, 0xff, 0xf9, 0xd1, + 0x17, 0xad, 0x74, 0x74, 0xaa, 0x29, 0xc7, 0xa7, 0x9a, 0xf2, 0xf9, 0x54, 0x53, 0x0e, 0xcf, 0xb4, + 0xd2, 0xf1, 0x99, 0x56, 0xfa, 0x70, 0xa6, 0x95, 0x5e, 0xdf, 0x71, 0x3d, 0x31, 0x8a, 0x2c, 0xdd, + 0x26, 0x81, 0x31, 0x71, 0xb1, 0x8c, 0xa7, 0xaf, 0x16, 0xf1, 0x86, 0x02, 0xb7, 0xaa, 0x49, 0x26, + 0xee, 0x7e, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xe9, 0x28, 0xe3, 0x84, 0x06, 0x00, 0x00, +} + +func (m *Params) 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 *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UseUndelegateFallback { + i-- + if m.UseUndelegateFallback { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } + { + size := m.MaxMovePerOp.Size() + i -= size + if _, err := m.MaxMovePerOp.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPoolrebalancer(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if m.MaxOpsPerBlock != 0 { + i = encodeVarintPoolrebalancer(dAtA, i, uint64(m.MaxOpsPerBlock)) + i-- + dAtA[i] = 0x20 + } + if m.RebalanceThresholdBp != 0 { + i = encodeVarintPoolrebalancer(dAtA, i, uint64(m.RebalanceThresholdBp)) + i-- + dAtA[i] = 0x18 + } + if m.MaxTargetValidators != 0 { + i = encodeVarintPoolrebalancer(dAtA, i, uint64(m.MaxTargetValidators)) + i-- + dAtA[i] = 0x10 + } + if len(m.PoolDelegatorAddress) > 0 { + i -= len(m.PoolDelegatorAddress) + copy(dAtA[i:], m.PoolDelegatorAddress) + i = encodeVarintPoolrebalancer(dAtA, i, uint64(len(m.PoolDelegatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PendingRedelegation) 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 *PendingRedelegation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PendingRedelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n1, err1 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintPoolrebalancer(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x2a + { + size, err := m.Amount.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPoolrebalancer(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if len(m.DstValidatorAddress) > 0 { + i -= len(m.DstValidatorAddress) + copy(dAtA[i:], m.DstValidatorAddress) + i = encodeVarintPoolrebalancer(dAtA, i, uint64(len(m.DstValidatorAddress))) + i-- + dAtA[i] = 0x1a + } + if len(m.SrcValidatorAddress) > 0 { + i -= len(m.SrcValidatorAddress) + copy(dAtA[i:], m.SrcValidatorAddress) + i = encodeVarintPoolrebalancer(dAtA, i, uint64(len(m.SrcValidatorAddress))) + i-- + dAtA[i] = 0x12 + } + if len(m.DelegatorAddress) > 0 { + i -= len(m.DelegatorAddress) + copy(dAtA[i:], m.DelegatorAddress) + i = encodeVarintPoolrebalancer(dAtA, i, uint64(len(m.DelegatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueuedRedelegation) 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 *QueuedRedelegation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueuedRedelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Entries) > 0 { + for iNdEx := len(m.Entries) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Entries[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPoolrebalancer(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PendingUndelegation) 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 *PendingUndelegation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PendingUndelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n3, err3 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(m.CompletionTime, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime):]) + if err3 != nil { + return 0, err3 + } + i -= n3 + i = encodeVarintPoolrebalancer(dAtA, i, uint64(n3)) + i-- + dAtA[i] = 0x22 + { + size, err := m.Balance.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPoolrebalancer(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.ValidatorAddress) > 0 { + i -= len(m.ValidatorAddress) + copy(dAtA[i:], m.ValidatorAddress) + i = encodeVarintPoolrebalancer(dAtA, i, uint64(len(m.ValidatorAddress))) + i-- + dAtA[i] = 0x12 + } + if len(m.DelegatorAddress) > 0 { + i -= len(m.DelegatorAddress) + copy(dAtA[i:], m.DelegatorAddress) + i = encodeVarintPoolrebalancer(dAtA, i, uint64(len(m.DelegatorAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueuedUndelegation) 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 *QueuedUndelegation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueuedUndelegation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Entries) > 0 { + for iNdEx := len(m.Entries) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Entries[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPoolrebalancer(dAtA, i, uint64(size)) + } + 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.PendingUndelegations) > 0 { + for iNdEx := len(m.PendingUndelegations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PendingUndelegations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPoolrebalancer(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.PendingRedelegations) > 0 { + for iNdEx := len(m.PendingRedelegations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PendingRedelegations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPoolrebalancer(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPoolrebalancer(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintPoolrebalancer(dAtA []byte, offset int, v uint64) int { + offset -= sovPoolrebalancer(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PoolDelegatorAddress) + if l > 0 { + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + if m.MaxTargetValidators != 0 { + n += 1 + sovPoolrebalancer(uint64(m.MaxTargetValidators)) + } + if m.RebalanceThresholdBp != 0 { + n += 1 + sovPoolrebalancer(uint64(m.RebalanceThresholdBp)) + } + if m.MaxOpsPerBlock != 0 { + n += 1 + sovPoolrebalancer(uint64(m.MaxOpsPerBlock)) + } + l = m.MaxMovePerOp.Size() + n += 1 + l + sovPoolrebalancer(uint64(l)) + if m.UseUndelegateFallback { + n += 2 + } + return n +} + +func (m *PendingRedelegation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DelegatorAddress) + if l > 0 { + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + l = len(m.SrcValidatorAddress) + if l > 0 { + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + l = len(m.DstValidatorAddress) + if l > 0 { + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + l = m.Amount.Size() + n += 1 + l + sovPoolrebalancer(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime) + n += 1 + l + sovPoolrebalancer(uint64(l)) + return n +} + +func (m *QueuedRedelegation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Entries) > 0 { + for _, e := range m.Entries { + l = e.Size() + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + } + return n +} + +func (m *PendingUndelegation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.DelegatorAddress) + if l > 0 { + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + l = len(m.ValidatorAddress) + if l > 0 { + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + l = m.Balance.Size() + n += 1 + l + sovPoolrebalancer(uint64(l)) + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(m.CompletionTime) + n += 1 + l + sovPoolrebalancer(uint64(l)) + return n +} + +func (m *QueuedUndelegation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Entries) > 0 { + for _, e := range m.Entries { + l = e.Size() + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + } + return n +} + +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovPoolrebalancer(uint64(l)) + if len(m.PendingRedelegations) > 0 { + for _, e := range m.PendingRedelegations { + l = e.Size() + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + } + if len(m.PendingUndelegations) > 0 { + for _, e := range m.PendingUndelegations { + l = e.Size() + n += 1 + l + sovPoolrebalancer(uint64(l)) + } + } + return n +} + +func sovPoolrebalancer(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozPoolrebalancer(x uint64) (n int) { + return sovPoolrebalancer(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) 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 ErrIntOverflowPoolrebalancer + } + 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PoolDelegatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + 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 ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PoolDelegatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxTargetValidators", wireType) + } + m.MaxTargetValidators = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxTargetValidators |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RebalanceThresholdBp", wireType) + } + m.RebalanceThresholdBp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RebalanceThresholdBp |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxOpsPerBlock", wireType) + } + m.MaxOpsPerBlock = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxOpsPerBlock |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxMovePerOp", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + 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 ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.MaxMovePerOp.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UseUndelegateFallback", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.UseUndelegateFallback = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipPoolrebalancer(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPoolrebalancer + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PendingRedelegation) 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 ErrIntOverflowPoolrebalancer + } + 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: PendingRedelegation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PendingRedelegation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelegatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + 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 ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SrcValidatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + 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 ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SrcValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DstValidatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + 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 ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DstValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CompletionTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.CompletionTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPoolrebalancer(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPoolrebalancer + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueuedRedelegation) 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 ErrIntOverflowPoolrebalancer + } + 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: QueuedRedelegation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueuedRedelegation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Entries = append(m.Entries, PendingRedelegation{}) + if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPoolrebalancer(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPoolrebalancer + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PendingUndelegation) 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 ErrIntOverflowPoolrebalancer + } + 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: PendingUndelegation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PendingUndelegation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DelegatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + 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 ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DelegatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorAddress", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + 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 ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Balance", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Balance.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CompletionTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(&m.CompletionTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPoolrebalancer(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPoolrebalancer + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueuedUndelegation) 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 ErrIntOverflowPoolrebalancer + } + 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: QueuedUndelegation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueuedUndelegation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Entries = append(m.Entries, PendingUndelegation{}) + if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPoolrebalancer(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPoolrebalancer + } + 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 ErrIntOverflowPoolrebalancer + } + 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 Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PendingRedelegations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PendingRedelegations = append(m.PendingRedelegations, PendingRedelegation{}) + if err := m.PendingRedelegations[len(m.PendingRedelegations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PendingUndelegations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPoolrebalancer + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPoolrebalancer + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPoolrebalancer + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PendingUndelegations = append(m.PendingUndelegations, PendingUndelegation{}) + if err := m.PendingUndelegations[len(m.PendingUndelegations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPoolrebalancer(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPoolrebalancer + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPoolrebalancer(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, ErrIntOverflowPoolrebalancer + } + 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, ErrIntOverflowPoolrebalancer + } + 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, ErrIntOverflowPoolrebalancer + } + 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, ErrInvalidLengthPoolrebalancer + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupPoolrebalancer + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthPoolrebalancer + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthPoolrebalancer = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPoolrebalancer = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupPoolrebalancer = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/poolrebalancer/types/query.pb.go b/x/poolrebalancer/types/query.pb.go new file mode 100644 index 00000000..0f9096d5 --- /dev/null +++ b/x/poolrebalancer/types/query.pb.go @@ -0,0 +1,1426 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/evm/poolrebalancer/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + query "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "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 + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_84183c6254b9379b, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.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 *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_84183c6254b9379b, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.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 *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +// QueryPendingRedelegationsRequest is the request type for the Query/PendingRedelegations RPC method. +type QueryPendingRedelegationsRequest struct { + // pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryPendingRedelegationsRequest) Reset() { *m = QueryPendingRedelegationsRequest{} } +func (m *QueryPendingRedelegationsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryPendingRedelegationsRequest) ProtoMessage() {} +func (*QueryPendingRedelegationsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_84183c6254b9379b, []int{2} +} +func (m *QueryPendingRedelegationsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPendingRedelegationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPendingRedelegationsRequest.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 *QueryPendingRedelegationsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPendingRedelegationsRequest.Merge(m, src) +} +func (m *QueryPendingRedelegationsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryPendingRedelegationsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPendingRedelegationsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPendingRedelegationsRequest proto.InternalMessageInfo + +// QueryPendingRedelegationsResponse is the response type for the Query/PendingRedelegations RPC method. +type QueryPendingRedelegationsResponse struct { + Redelegations []PendingRedelegation `protobuf:"bytes,1,rep,name=redelegations,proto3" json:"redelegations"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryPendingRedelegationsResponse) Reset() { *m = QueryPendingRedelegationsResponse{} } +func (m *QueryPendingRedelegationsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryPendingRedelegationsResponse) ProtoMessage() {} +func (*QueryPendingRedelegationsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_84183c6254b9379b, []int{3} +} +func (m *QueryPendingRedelegationsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPendingRedelegationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPendingRedelegationsResponse.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 *QueryPendingRedelegationsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPendingRedelegationsResponse.Merge(m, src) +} +func (m *QueryPendingRedelegationsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryPendingRedelegationsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPendingRedelegationsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPendingRedelegationsResponse proto.InternalMessageInfo + +// QueryPendingUndelegationsRequest is the request type for the Query/PendingUndelegations RPC method. +type QueryPendingUndelegationsRequest struct { + // pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryPendingUndelegationsRequest) Reset() { *m = QueryPendingUndelegationsRequest{} } +func (m *QueryPendingUndelegationsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryPendingUndelegationsRequest) ProtoMessage() {} +func (*QueryPendingUndelegationsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_84183c6254b9379b, []int{4} +} +func (m *QueryPendingUndelegationsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPendingUndelegationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPendingUndelegationsRequest.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 *QueryPendingUndelegationsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPendingUndelegationsRequest.Merge(m, src) +} +func (m *QueryPendingUndelegationsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryPendingUndelegationsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPendingUndelegationsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPendingUndelegationsRequest proto.InternalMessageInfo + +// QueryPendingUndelegationsResponse is the response type for the Query/PendingUndelegations RPC method. +type QueryPendingUndelegationsResponse struct { + Undelegations []PendingUndelegation `protobuf:"bytes,1,rep,name=undelegations,proto3" json:"undelegations"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryPendingUndelegationsResponse) Reset() { *m = QueryPendingUndelegationsResponse{} } +func (m *QueryPendingUndelegationsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryPendingUndelegationsResponse) ProtoMessage() {} +func (*QueryPendingUndelegationsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_84183c6254b9379b, []int{5} +} +func (m *QueryPendingUndelegationsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPendingUndelegationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPendingUndelegationsResponse.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 *QueryPendingUndelegationsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPendingUndelegationsResponse.Merge(m, src) +} +func (m *QueryPendingUndelegationsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryPendingUndelegationsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPendingUndelegationsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPendingUndelegationsResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*QueryParamsRequest)(nil), "cosmos.evm.poolrebalancer.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "cosmos.evm.poolrebalancer.v1.QueryParamsResponse") + proto.RegisterType((*QueryPendingRedelegationsRequest)(nil), "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest") + proto.RegisterType((*QueryPendingRedelegationsResponse)(nil), "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse") + proto.RegisterType((*QueryPendingUndelegationsRequest)(nil), "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest") + proto.RegisterType((*QueryPendingUndelegationsResponse)(nil), "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse") +} + +func init() { + proto.RegisterFile("cosmos/evm/poolrebalancer/v1/query.proto", fileDescriptor_84183c6254b9379b) +} + +var fileDescriptor_84183c6254b9379b = []byte{ + // 514 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x94, 0x41, 0x6b, 0x13, 0x41, + 0x14, 0xc7, 0x77, 0xaa, 0x06, 0x9c, 0xe2, 0xc1, 0x31, 0x87, 0x12, 0xca, 0x1a, 0x97, 0x52, 0x43, + 0x29, 0x33, 0x6e, 0x8a, 0x27, 0x41, 0xa1, 0x07, 0x0b, 0x9e, 0x6a, 0xc0, 0x8b, 0x07, 0x65, 0x36, + 0x7d, 0x8c, 0x2b, 0xd9, 0x99, 0xed, 0xce, 0x66, 0xb1, 0x57, 0x3f, 0x81, 0xe0, 0xd1, 0x2f, 0xe0, + 0xd1, 0x8f, 0x91, 0x63, 0xa0, 0x1e, 0x3c, 0x89, 0x26, 0x82, 0x5f, 0x43, 0xb2, 0x33, 0xd2, 0x9d, + 0x34, 0x6e, 0x4c, 0x10, 0x2f, 0x61, 0x99, 0x9d, 0xf7, 0x7f, 0xff, 0xdf, 0x3f, 0xef, 0x2d, 0xee, + 0xf4, 0x95, 0x4e, 0x94, 0x66, 0x50, 0x24, 0x2c, 0x55, 0x6a, 0x90, 0x41, 0xc4, 0x07, 0x5c, 0xf6, + 0x21, 0x63, 0x45, 0xc8, 0x4e, 0x87, 0x90, 0x9d, 0xd1, 0x34, 0x53, 0xb9, 0x22, 0xdb, 0xe6, 0x26, + 0x85, 0x22, 0xa1, 0xee, 0x4d, 0x5a, 0x84, 0xad, 0x9b, 0x3c, 0x89, 0xa5, 0x62, 0xe5, 0xaf, 0x29, + 0x68, 0xed, 0x59, 0xe9, 0x88, 0x6b, 0x30, 0x4a, 0xac, 0x08, 0x23, 0xc8, 0x79, 0xc8, 0x52, 0x2e, + 0x62, 0xc9, 0xf3, 0x58, 0x49, 0x7b, 0x37, 0xac, 0xb5, 0x31, 0xd7, 0xce, 0x94, 0x34, 0x85, 0x12, + 0xaa, 0x7c, 0x64, 0xb3, 0x27, 0x7b, 0xba, 0x2d, 0x94, 0x12, 0x03, 0x60, 0x3c, 0x8d, 0x19, 0x97, + 0x52, 0xe5, 0x65, 0x17, 0x6d, 0xde, 0x06, 0x4d, 0x4c, 0x9e, 0xce, 0x8c, 0x1c, 0xf3, 0x8c, 0x27, + 0xba, 0x07, 0xa7, 0x43, 0xd0, 0x79, 0xf0, 0x02, 0xdf, 0x72, 0x4e, 0x75, 0xaa, 0xa4, 0x06, 0x72, + 0x84, 0x1b, 0x69, 0x79, 0xb2, 0x85, 0xda, 0xa8, 0xb3, 0xd9, 0xdd, 0xa1, 0x75, 0x09, 0x50, 0x53, + 0x7d, 0x78, 0x7d, 0xf4, 0xf5, 0xb6, 0xf7, 0xf1, 0xe7, 0xa7, 0x3d, 0xd4, 0xb3, 0xe5, 0xc1, 0x6b, + 0xdc, 0x36, 0xfa, 0x20, 0x4f, 0x62, 0x29, 0x7a, 0x70, 0x02, 0x03, 0x10, 0xc6, 0x98, 0xf5, 0x40, + 0x1e, 0x63, 0x7c, 0x11, 0x8a, 0x6d, 0xb8, 0xfb, 0xbb, 0xe1, 0x2c, 0x41, 0x6a, 0xfe, 0x0b, 0x9b, + 0x20, 0x3d, 0xe6, 0x02, 0x6c, 0x6d, 0xaf, 0x52, 0x19, 0x8c, 0x11, 0xbe, 0x53, 0xd3, 0xcc, 0xa2, + 0x45, 0xf8, 0x46, 0x56, 0x7d, 0xb1, 0x85, 0xda, 0x57, 0x3a, 0x9b, 0xdd, 0x70, 0x09, 0xe1, 0x65, + 0xc9, 0x2a, 0xae, 0x2b, 0x49, 0x8e, 0x1c, 0xa2, 0x8d, 0x92, 0xe8, 0xee, 0x52, 0x22, 0x63, 0xd0, + 0x41, 0x9a, 0x8b, 0xef, 0x99, 0xfc, 0x8f, 0xf1, 0xcd, 0x35, 0xbb, 0x88, 0x6f, 0x28, 0xd7, 0x8d, + 0xaf, 0x2a, 0xe9, 0xc4, 0xe7, 0x48, 0xfe, 0xb3, 0xf8, 0xba, 0xe7, 0x57, 0xf1, 0xb5, 0x12, 0x89, + 0x7c, 0x40, 0xb8, 0x61, 0xa6, 0x94, 0xdc, 0xab, 0xb7, 0x7a, 0x79, 0x49, 0x5a, 0xe1, 0x0a, 0x15, + 0xc6, 0x45, 0xb0, 0xff, 0xf6, 0xfc, 0xc7, 0xfb, 0x8d, 0x5d, 0xb2, 0xc3, 0xea, 0xb7, 0xdb, 0x58, + 0xfa, 0x8c, 0x70, 0x73, 0xd1, 0xd0, 0x92, 0x87, 0x7f, 0xd3, 0xf9, 0xcf, 0xab, 0xd5, 0x7a, 0xb4, + 0x76, 0xbd, 0xe5, 0x78, 0x50, 0x72, 0xdc, 0x27, 0x07, 0x4b, 0x38, 0x8c, 0xc6, 0x4b, 0x77, 0x0d, + 0x2a, 0x58, 0xce, 0x30, 0xad, 0x82, 0xb5, 0x68, 0xe4, 0x57, 0xc1, 0x5a, 0x38, 0xc5, 0xab, 0x62, + 0x39, 0xe3, 0x79, 0xf8, 0x64, 0xf4, 0xdd, 0xf7, 0x46, 0x13, 0x1f, 0x8d, 0x27, 0x3e, 0xfa, 0x36, + 0xf1, 0xd1, 0xbb, 0xa9, 0xef, 0x8d, 0xa7, 0xbe, 0xf7, 0x65, 0xea, 0x7b, 0xcf, 0xf7, 0x45, 0x9c, + 0xbf, 0x1a, 0x46, 0xb4, 0xaf, 0x92, 0xaa, 0xf8, 0x9b, 0x79, 0xf9, 0xfc, 0x2c, 0x05, 0x1d, 0x35, + 0xca, 0x8f, 0xf3, 0xc1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x92, 0x79, 0xc7, 0x77, 0x8c, 0x06, + 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 { + // Params returns the poolrebalancer module params. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // PendingRedelegations returns tracked in-flight redelegations. + PendingRedelegations(ctx context.Context, in *QueryPendingRedelegationsRequest, opts ...grpc.CallOption) (*QueryPendingRedelegationsResponse, error) + // PendingUndelegations returns tracked in-flight undelegations. + PendingUndelegations(ctx context.Context, in *QueryPendingUndelegationsRequest, opts ...grpc.CallOption) (*QueryPendingUndelegationsResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/cosmos.evm.poolrebalancer.v1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) PendingRedelegations(ctx context.Context, in *QueryPendingRedelegationsRequest, opts ...grpc.CallOption) (*QueryPendingRedelegationsResponse, error) { + out := new(QueryPendingRedelegationsResponse) + err := c.cc.Invoke(ctx, "/cosmos.evm.poolrebalancer.v1.Query/PendingRedelegations", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) PendingUndelegations(ctx context.Context, in *QueryPendingUndelegationsRequest, opts ...grpc.CallOption) (*QueryPendingUndelegationsResponse, error) { + out := new(QueryPendingUndelegationsResponse) + err := c.cc.Invoke(ctx, "/cosmos.evm.poolrebalancer.v1.Query/PendingUndelegations", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Params returns the poolrebalancer module params. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // PendingRedelegations returns tracked in-flight redelegations. + PendingRedelegations(context.Context, *QueryPendingRedelegationsRequest) (*QueryPendingRedelegationsResponse, error) + // PendingUndelegations returns tracked in-flight undelegations. + PendingUndelegations(context.Context, *QueryPendingUndelegationsRequest) (*QueryPendingUndelegationsResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (*UnimplementedQueryServer) PendingRedelegations(ctx context.Context, req *QueryPendingRedelegationsRequest) (*QueryPendingRedelegationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PendingRedelegations not implemented") +} +func (*UnimplementedQueryServer) PendingUndelegations(ctx context.Context, req *QueryPendingUndelegationsRequest) (*QueryPendingUndelegationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PendingUndelegations not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.evm.poolrebalancer.v1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_PendingRedelegations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryPendingRedelegationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).PendingRedelegations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.evm.poolrebalancer.v1.Query/PendingRedelegations", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).PendingRedelegations(ctx, req.(*QueryPendingRedelegationsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_PendingUndelegations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryPendingUndelegationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).PendingUndelegations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.evm.poolrebalancer.v1.Query/PendingUndelegations", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).PendingUndelegations(ctx, req.(*QueryPendingUndelegationsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos.evm.poolrebalancer.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "PendingRedelegations", + Handler: _Query_PendingRedelegations_Handler, + }, + { + MethodName: "PendingUndelegations", + Handler: _Query_PendingUndelegations_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/evm/poolrebalancer/v1/query.proto", +} + +func (m *QueryParamsRequest) 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 *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) 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 *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.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 *QueryPendingRedelegationsRequest) 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 *QueryPendingRedelegationsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPendingRedelegationsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.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 *QueryPendingRedelegationsResponse) 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 *QueryPendingRedelegationsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPendingRedelegationsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Redelegations) > 0 { + for iNdEx := len(m.Redelegations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Redelegations[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 *QueryPendingUndelegationsRequest) 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 *QueryPendingUndelegationsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPendingUndelegationsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.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 *QueryPendingUndelegationsResponse) 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 *QueryPendingUndelegationsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPendingUndelegationsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Undelegations) > 0 { + for iNdEx := len(m.Undelegations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Undelegations[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 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 *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryPendingRedelegationsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryPendingRedelegationsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Redelegations) > 0 { + for _, e := range m.Redelegations { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryPendingUndelegationsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryPendingUndelegationsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Undelegations) > 0 { + for _, e := range m.Undelegations { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + 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 *QueryParamsRequest) 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: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: 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 *QueryParamsResponse) 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: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.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 *QueryPendingRedelegationsRequest) 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: QueryPendingRedelegationsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPendingRedelegationsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.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 *QueryPendingRedelegationsResponse) 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: QueryPendingRedelegationsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPendingRedelegationsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Redelegations", 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.Redelegations = append(m.Redelegations, PendingRedelegation{}) + if err := m.Redelegations[len(m.Redelegations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.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 *QueryPendingUndelegationsRequest) 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: QueryPendingUndelegationsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPendingUndelegationsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.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 *QueryPendingUndelegationsResponse) 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: QueryPendingUndelegationsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPendingUndelegationsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Undelegations", 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.Undelegations = append(m.Undelegations, PendingUndelegation{}) + if err := m.Undelegations[len(m.Undelegations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.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 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") +) diff --git a/x/poolrebalancer/types/query.pb.gw.go b/x/poolrebalancer/types/query.pb.gw.go new file mode 100644 index 00000000..461b3453 --- /dev/null +++ b/x/poolrebalancer/types/query.pb.gw.go @@ -0,0 +1,319 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: cosmos/evm/poolrebalancer/v1/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_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_PendingRedelegations_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_PendingRedelegations_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPendingRedelegationsRequest + 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_PendingRedelegations_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.PendingRedelegations(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_PendingRedelegations_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPendingRedelegationsRequest + 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_PendingRedelegations_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.PendingRedelegations(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_PendingUndelegations_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_PendingUndelegations_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPendingUndelegationsRequest + 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_PendingUndelegations_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.PendingUndelegations(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_PendingUndelegations_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPendingUndelegationsRequest + 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_PendingUndelegations_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.PendingUndelegations(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_Params_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_Params_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_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_PendingRedelegations_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_PendingRedelegations_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_PendingRedelegations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_PendingUndelegations_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_PendingUndelegations_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_PendingUndelegations_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_Params_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_Params_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_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_PendingRedelegations_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_PendingRedelegations_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_PendingRedelegations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_PendingUndelegations_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_PendingUndelegations_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_PendingUndelegations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmos", "evm", "poolrebalancer", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_PendingRedelegations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmos", "evm", "poolrebalancer", "v1", "pending_redelegations"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_PendingUndelegations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmos", "evm", "poolrebalancer", "v1", "pending_undelegations"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_PendingRedelegations_0 = runtime.ForwardResponseMessage + + forward_Query_PendingUndelegations_0 = runtime.ForwardResponseMessage +) diff --git a/x/poolrebalancer/types/tx.pb.go b/x/poolrebalancer/types/tx.pb.go new file mode 100644 index 00000000..186ec946 --- /dev/null +++ b/x/poolrebalancer/types/tx.pb.go @@ -0,0 +1,599 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/evm/poolrebalancer/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/cosmos-sdk/types/tx/amino" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + 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 + +// MsgUpdateParams defines a Msg for updating the x/poolrebalancer module parameters. +type MsgUpdateParams struct { + // authority is the address of the governance account. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the x/poolrebalancer parameters to update. + // NOTE: All parameters must be supplied. + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } +func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParams) ProtoMessage() {} +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return fileDescriptor_28a11b1e0d968b99, []int{0} +} +func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParams.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 *MsgUpdateParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParams.Merge(m, src) +} +func (m *MsgUpdateParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParams proto.InternalMessageInfo + +func (m *MsgUpdateParams) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func (m *MsgUpdateParams) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +// MsgUpdateParamsResponse defines the response structure for executing a MsgUpdateParams message. +type MsgUpdateParamsResponse struct { +} + +func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse{} } +func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParamsResponse) ProtoMessage() {} +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_28a11b1e0d968b99, []int{1} +} +func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParamsResponse.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 *MsgUpdateParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParamsResponse.Merge(m, src) +} +func (m *MsgUpdateParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgUpdateParams)(nil), "cosmos.evm.poolrebalancer.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse") +} + +func init() { + proto.RegisterFile("cosmos/evm/poolrebalancer/v1/tx.proto", fileDescriptor_28a11b1e0d968b99) +} + +var fileDescriptor_28a11b1e0d968b99 = []byte{ + // 353 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4d, 0xce, 0x2f, 0xce, + 0xcd, 0x2f, 0xd6, 0x4f, 0x2d, 0xcb, 0xd5, 0x2f, 0xc8, 0xcf, 0xcf, 0x29, 0x4a, 0x4d, 0x4a, 0xcc, + 0x49, 0xcc, 0x4b, 0x4e, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, + 0xc9, 0x17, 0x92, 0x81, 0x28, 0xd3, 0x4b, 0x2d, 0xcb, 0xd5, 0x43, 0x55, 0xa6, 0x57, 0x66, 0x28, + 0x25, 0x98, 0x98, 0x9b, 0x99, 0x97, 0xaf, 0x0f, 0x26, 0x21, 0x1a, 0xa4, 0x0c, 0xf1, 0x9a, 0x8b, + 0x66, 0x04, 0x44, 0x8b, 0x38, 0x54, 0x4b, 0x6e, 0x71, 0x3a, 0x48, 0x4d, 0x6e, 0x71, 0x3a, 0x54, + 0x42, 0x12, 0x22, 0x11, 0x0f, 0xe6, 0xe9, 0x43, 0x5d, 0x02, 0x91, 0x12, 0x49, 0xcf, 0x4f, 0xcf, + 0x87, 0x88, 0x83, 0x58, 0x10, 0x51, 0xa5, 0x4b, 0x8c, 0x5c, 0xfc, 0xbe, 0xc5, 0xe9, 0xa1, 0x05, + 0x29, 0x89, 0x25, 0xa9, 0x01, 0x89, 0x45, 0x89, 0xb9, 0xc5, 0x42, 0x66, 0x5c, 0x9c, 0x89, 0xa5, + 0x25, 0x19, 0xf9, 0x45, 0x99, 0x25, 0x95, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x4e, 0x12, 0x97, + 0xb6, 0xe8, 0x8a, 0x40, 0x8d, 0x73, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0x0e, 0x2e, 0x29, 0xca, + 0xcc, 0x4b, 0x0f, 0x42, 0x28, 0x15, 0x72, 0xe7, 0x62, 0x2b, 0x00, 0x9b, 0x20, 0xc1, 0xa4, 0xc0, + 0xa8, 0xc1, 0x6d, 0xa4, 0xa2, 0x87, 0x2f, 0x28, 0xf4, 0x20, 0xb6, 0x39, 0x71, 0x9e, 0xb8, 0x27, + 0xcf, 0xb0, 0xe2, 0xf9, 0x06, 0x2d, 0xc6, 0x20, 0xa8, 0x76, 0x2b, 0xbb, 0xa6, 0xe7, 0x1b, 0xb4, + 0x10, 0x06, 0x77, 0x3d, 0xdf, 0xa0, 0xa5, 0x8d, 0x14, 0x48, 0x15, 0xe8, 0xc1, 0x84, 0xe6, 0x01, + 0x25, 0x49, 0x2e, 0x71, 0x34, 0xa1, 0xa0, 0xd4, 0xe2, 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0xa3, 0x26, + 0x46, 0x2e, 0x66, 0xdf, 0xe2, 0x74, 0xa1, 0x12, 0x2e, 0x1e, 0x14, 0x3f, 0xeb, 0xe2, 0x77, 0x2b, + 0x9a, 0x71, 0x52, 0xa6, 0x24, 0x29, 0x87, 0xd9, 0x2e, 0xc5, 0xda, 0x00, 0xf2, 0xa7, 0x93, 0xdb, + 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, + 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0xe9, 0xa4, 0x67, 0x96, 0x64, 0x94, + 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xe3, 0xf3, 0x71, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, + 0x38, 0x0e, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x37, 0xcc, 0x45, 0x21, 0x9a, 0x02, 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 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // UpdateParams is a governance operation for updating the x/poolrebalancer module parameters. + // The authority is the Cosmos SDK x/gov module account. + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/cosmos.evm.poolrebalancer.v1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // UpdateParams is a governance operation for updating the x/poolrebalancer module parameters. + // The authority is the Cosmos SDK x/gov module account. + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.evm.poolrebalancer.v1.Msg/UpdateParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "cosmos.evm.poolrebalancer.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "cosmos/evm/poolrebalancer/v1/tx.proto", +} + +func (m *MsgUpdateParams) 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 *MsgUpdateParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParamsResponse) 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 *MsgUpdateParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgUpdateParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgUpdateParams) 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 ErrIntOverflowTx + } + 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: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParamsResponse) 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 ErrIntOverflowTx + } + 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: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) From c260a3ad21a57febe7035e2130a8df651e6c353e Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 18 Mar 2026 17:01:48 +0530 Subject: [PATCH 02/31] feat(poolrebalancer): add module types helpers and validation --- x/poolrebalancer/types/codec.go | 39 ++++++++++ x/poolrebalancer/types/errors.go | 14 ++++ x/poolrebalancer/types/helpers.go | 55 +++++++++++++ x/poolrebalancer/types/keys.go | 125 ++++++++++++++++++++++++++++++ x/poolrebalancer/types/msg.go | 22 ++++++ 5 files changed, 255 insertions(+) create mode 100644 x/poolrebalancer/types/codec.go create mode 100644 x/poolrebalancer/types/errors.go create mode 100644 x/poolrebalancer/types/helpers.go create mode 100644 x/poolrebalancer/types/keys.go create mode 100644 x/poolrebalancer/types/msg.go diff --git a/x/poolrebalancer/types/codec.go b/x/poolrebalancer/types/codec.go new file mode 100644 index 00000000..2f920ec8 --- /dev/null +++ b/x/poolrebalancer/types/codec.go @@ -0,0 +1,39 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +var ( + amino = codec.NewLegacyAmino() + + // ModuleCdc is a module-local codec helper. + // Most state and service encoding uses the app's configured codec; this exists mainly for JSON contexts. + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) + + // AminoCdc supports amino JSON for legacy msg encoding. + AminoCdc = codec.NewAminoCodec(amino) //nolint:staticcheck +) + +const ( + updateParamsName = "cosmos/evm/x/poolrebalancer/MsgUpdateParams" +) + +func init() { + RegisterLegacyAminoCodec(amino) + amino.Seal() +} + +// RegisterInterfaces registers the module's interfaces with the registry. +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), &MsgUpdateParams{}) + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +// RegisterLegacyAminoCodec registers the module's types with the LegacyAmino codec. +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgUpdateParams{}, updateParamsName, nil) +} diff --git a/x/poolrebalancer/types/errors.go b/x/poolrebalancer/types/errors.go new file mode 100644 index 00000000..7b164168 --- /dev/null +++ b/x/poolrebalancer/types/errors.go @@ -0,0 +1,14 @@ +package types + +import ( + "cosmossdk.io/errors" +) + +// Sentinel errors for the poolrebalancer module. +var ( + ErrInvalidPoolDelegator = errors.Register(ModuleName, 1, "pool delegator address not set or invalid") + ErrTransitiveRedelegation = errors.Register(ModuleName, 2, "redelegation blocked: immature redelegation to source validator") + ErrSameValidator = errors.Register(ModuleName, 3, "source and destination validator cannot be the same") + ErrInvalidAmount = errors.Register(ModuleName, 4, "amount must be positive") + ErrNoDelegation = errors.Register(ModuleName, 5, "no delegation found for delegator and validator") +) diff --git a/x/poolrebalancer/types/helpers.go b/x/poolrebalancer/types/helpers.go new file mode 100644 index 00000000..304945b2 --- /dev/null +++ b/x/poolrebalancer/types/helpers.go @@ -0,0 +1,55 @@ +package types + +import ( + "fmt" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// DefaultParams returns the default module parameters. +func DefaultParams() Params { + return Params{ + PoolDelegatorAddress: "", // empty = rebalancer disabled until set + MaxTargetValidators: uint32(30), + RebalanceThresholdBp: uint32(50), // 0.5% + MaxOpsPerBlock: uint32(5), + MaxMovePerOp: math.ZeroInt(), // 0 means no cap + UseUndelegateFallback: true, + } +} + +// Validate validates the params. +func (p Params) Validate() error { + if p.PoolDelegatorAddress != "" { + if _, err := sdk.AccAddressFromBech32(p.PoolDelegatorAddress); err != nil { + return fmt.Errorf("invalid pool_delegator_address: %w", err) + } + } + if p.MaxTargetValidators == 0 { + return fmt.Errorf("max_target_validators must be positive") + } + if p.RebalanceThresholdBp > 10_000 { + return fmt.Errorf("rebalance_threshold_bp cannot exceed 10000") + } + if p.MaxOpsPerBlock == 0 { + return fmt.Errorf("max_ops_per_block must be positive") + } + if !p.MaxMovePerOp.IsNil() && p.MaxMovePerOp.IsNegative() { + return fmt.Errorf("max_move_per_op cannot be negative") + } + return nil +} + +// DefaultGenesisState returns a default genesis state. +func DefaultGenesisState() *GenesisState { + return &GenesisState{ + Params: DefaultParams(), + } +} + +// Validate validates the genesis state. +func (gs *GenesisState) Validate() error { + return gs.Params.Validate() +} diff --git a/x/poolrebalancer/types/keys.go b/x/poolrebalancer/types/keys.go new file mode 100644 index 00000000..d509d793 --- /dev/null +++ b/x/poolrebalancer/types/keys.go @@ -0,0 +1,125 @@ +package types + +import ( + "fmt" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" +) + +const ( + // ModuleName is the name of the poolrebalancer module (used in store keys and routing). + ModuleName = "poolrebalancer" + + // StoreKey is the default store key for the poolrebalancer module (same as ModuleName). + StoreKey = ModuleName + + // RouterKey is the top-level router key for the module. + RouterKey = ModuleName +) + +// Store key prefixes (single-byte prefixes). +var ( + ParamsKey = []byte{0x01} // module params + + // Pending redelegation tracking. + // Primary key: (delegator, denom, dstValidator, completionTime) + PendingRedelegationKey = []byte{0x11} + // Index by source validator: (srcValidator, completionTime, denom, dstValidator, delegator) + PendingRedelegationBySrcIndexKey = []byte{0x12} + // Queue by completion time: completionTime -> list of pending redelegation entries + PendingRedelegationQueueKey = []byte{0x13} + + // Pending undelegation tracking. + // Queue: (completionTime, delegator) -> queued undelegation entries + PendingUndelegationQueueKey = []byte{0x21} + // Index by validator: (validator, completionTime, denom, delegator) + PendingUndelegationByValIndexKey = []byte{0x22} +) + +// GetPendingRedelegationKey returns the primary key for a pending redelegation. +// Key format: prefix | lengthPrefixed(delegator) | lengthPrefixed(denom) | lengthPrefixed(dstValidator) | completionTime. +func GetPendingRedelegationKey(del sdk.AccAddress, denom string, dstVal sdk.ValAddress, completion time.Time) []byte { + key := append(PendingRedelegationKey, address.MustLengthPrefix(del)...) + key = append(key, address.MustLengthPrefix([]byte(denom))...) + key = append(key, address.MustLengthPrefix(dstVal)...) + key = append(key, sdk.FormatTimeBytes(completion)...) + return key +} + +// GetPendingRedelegationBySrcIndexKey returns the index key for lookup by source validator. +// Key format: prefix | lengthPrefixed(srcValidator) | lengthPrefixed(completionTime) | lengthPrefixed(denom) | lengthPrefixed(dstVal) | lengthPrefixed(delegator). +func GetPendingRedelegationBySrcIndexKey(srcVal sdk.ValAddress, completion time.Time, denom string, dstVal sdk.ValAddress, del sdk.AccAddress) []byte { + key := append(PendingRedelegationBySrcIndexKey, address.MustLengthPrefix(srcVal)...) + key = append(key, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) + key = append(key, address.MustLengthPrefix([]byte(denom))...) + key = append(key, address.MustLengthPrefix(dstVal)...) + key = append(key, address.MustLengthPrefix(del)...) + return key +} + +// GetPendingRedelegationQueueKey returns the queue key for a given completion time. +// Used to iterate pending redelegations that mature at or before a given time. +func GetPendingRedelegationQueueKey(completion time.Time) []byte { + return append(PendingRedelegationQueueKey, sdk.FormatTimeBytes(completion)...) +} + +// ParsePendingRedelegationQueueKey parses the completion time from a pending redelegation queue key. +// Key format: PendingRedelegationQueueKey (0x13) + FormatTimeBytes(completion). +func ParsePendingRedelegationQueueKey(key []byte) (time.Time, error) { + if len(key) <= len(PendingRedelegationQueueKey) { + return time.Time{}, fmt.Errorf("invalid pending redelegation queue key length") + } + return sdk.ParseTimeBytes(key[len(PendingRedelegationQueueKey):]) +} + +// GetPendingRedelegationPrefix returns the key prefix for (delegator, denom, dstValidator). +// Used by HasImmatureRedelegationTo to prefix-scan all completion times for this triple. +func GetPendingRedelegationPrefix(del sdk.AccAddress, denom string, dstVal sdk.ValAddress) []byte { + key := append(PendingRedelegationKey, address.MustLengthPrefix(del)...) + key = append(key, address.MustLengthPrefix([]byte(denom))...) + key = append(key, address.MustLengthPrefix(dstVal)...) + return key +} + +// GetPendingUndelegationQueueKey returns the queue key for (completionTime, delegator). +// Key format: prefix | lengthPrefixed(completionTime) | lengthPrefixed(delegator). +func GetPendingUndelegationQueueKey(completion time.Time, del sdk.AccAddress) []byte { + key := append(PendingUndelegationQueueKey, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) + key = append(key, address.MustLengthPrefix(del)...) + return key +} + +// GetPendingUndelegationQueueKeyByTime returns the undelegation queue prefix for a given completion time. +// Key format: PendingUndelegationQueueKey (0x21) + lengthPrefixed(FormatTimeBytes(completion)). +// This is used as an end key when iterating all queued undelegations up to a given time. +func GetPendingUndelegationQueueKeyByTime(completion time.Time) []byte { + return append(PendingUndelegationQueueKey, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) +} + +// ParsePendingUndelegationQueueKeyForCompletionTime parses the completion time from a pending undelegation queue key. +// Key format: PendingUndelegationQueueKey (0x21) + lengthPrefixed(timeBytes) + lengthPrefixed(delegator). +func ParsePendingUndelegationQueueKeyForCompletionTime(key []byte) (time.Time, error) { + offset := len(PendingUndelegationQueueKey) + if len(key) <= offset { + return time.Time{}, fmt.Errorf("invalid pending undelegation queue key length") + } + timeLen := int(key[offset]) + offset++ + if len(key) < offset+timeLen { + return time.Time{}, fmt.Errorf("invalid pending undelegation queue key time length") + } + timeBytes := key[offset : offset+timeLen] + return sdk.ParseTimeBytes(timeBytes) +} + +// GetPendingUndelegationByValIndexKey returns the index key for lookup by validator. +// Key format: prefix | lengthPrefixed(validator) | lengthPrefixed(completionTime) | lengthPrefixed(denom) | lengthPrefixed(delegator). +func GetPendingUndelegationByValIndexKey(val sdk.ValAddress, completion time.Time, denom string, del sdk.AccAddress) []byte { + key := append(PendingUndelegationByValIndexKey, address.MustLengthPrefix(val)...) + key = append(key, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) + key = append(key, address.MustLengthPrefix([]byte(denom))...) + key = append(key, address.MustLengthPrefix(del)...) + return key +} diff --git a/x/poolrebalancer/types/msg.go b/x/poolrebalancer/types/msg.go new file mode 100644 index 00000000..5d4f2eeb --- /dev/null +++ b/x/poolrebalancer/types/msg.go @@ -0,0 +1,22 @@ +package types + +import ( + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +var _ sdk.Msg = &MsgUpdateParams{} + +// ValidateBasic validates the message. +func (m *MsgUpdateParams) ValidateBasic() error { + if _, err := sdk.AccAddressFromBech32(m.Authority); err != nil { + return errorsmod.Wrap(err, "invalid authority address") + } + return m.Params.Validate() +} + +// GetSignBytes implements the LegacyMsg interface. +func (m MsgUpdateParams) GetSignBytes() []byte { + return AminoCdc.MustMarshalJSON(&m) +} From 811570dc9785bcdbad401623816f3d938a97756a Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 18 Mar 2026 17:02:05 +0530 Subject: [PATCH 03/31] feat(poolrebalancer): implement keeper state and end blocker --- x/poolrebalancer/abci.go | 21 ++ x/poolrebalancer/genesis.go | 51 ++++ x/poolrebalancer/keeper/genesis.go | 77 +++++ x/poolrebalancer/keeper/keeper.go | 35 +++ x/poolrebalancer/keeper/params.go | 96 ++++++ x/poolrebalancer/keeper/rebalance.go | 382 ++++++++++++++++++++++++ x/poolrebalancer/keeper/redelegation.go | 186 ++++++++++++ x/poolrebalancer/keeper/undelegation.go | 145 +++++++++ 8 files changed, 993 insertions(+) create mode 100644 x/poolrebalancer/abci.go create mode 100644 x/poolrebalancer/genesis.go create mode 100644 x/poolrebalancer/keeper/genesis.go create mode 100644 x/poolrebalancer/keeper/keeper.go create mode 100644 x/poolrebalancer/keeper/params.go create mode 100644 x/poolrebalancer/keeper/rebalance.go create mode 100644 x/poolrebalancer/keeper/redelegation.go create mode 100644 x/poolrebalancer/keeper/undelegation.go diff --git a/x/poolrebalancer/abci.go b/x/poolrebalancer/abci.go new file mode 100644 index 00000000..4fd88711 --- /dev/null +++ b/x/poolrebalancer/abci.go @@ -0,0 +1,21 @@ +package poolrebalancer + +import ( + "github.com/cosmos/evm/x/poolrebalancer/keeper" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// EndBlocker runs at end of block: complete matured redelegations/undelegations, then process rebalance. +func EndBlocker(ctx sdk.Context, k keeper.Keeper) error { + if err := k.CompletePendingRedelegations(ctx); err != nil { + return err + } + if err := k.CompletePendingUndelegations(ctx); err != nil { + return err + } + if err := k.ProcessRebalance(ctx); err != nil { + return err + } + return nil +} diff --git a/x/poolrebalancer/genesis.go b/x/poolrebalancer/genesis.go new file mode 100644 index 00000000..35196489 --- /dev/null +++ b/x/poolrebalancer/genesis.go @@ -0,0 +1,51 @@ +package poolrebalancer + +import ( + "fmt" + + "github.com/cosmos/evm/x/poolrebalancer/keeper" + "github.com/cosmos/evm/x/poolrebalancer/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// InitGenesis initializes module state from genesis. +func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs *types.GenesisState) { + if err := gs.Validate(); err != nil { + panic(fmt.Sprintf("failed to validate %s genesis state: %s", types.ModuleName, err)) + } + if err := k.SetParams(ctx, gs.Params); err != nil { + panic(fmt.Sprintf("failed to set %s params: %s", types.ModuleName, err)) + } + for _, entry := range gs.PendingRedelegations { + if err := k.SetPendingRedelegation(ctx, entry); err != nil { + panic(fmt.Sprintf("failed to restore pending redelegation: %s", err)) + } + } + for _, entry := range gs.PendingUndelegations { + if err := k.SetPendingUndelegation(ctx, entry); err != nil { + panic(fmt.Sprintf("failed to restore pending undelegation: %s", err)) + } + } +} + +// ExportGenesis exports module state to genesis. +func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { + params, err := k.GetParams(ctx) + if err != nil { + panic(fmt.Sprintf("failed to get %s params: %s", types.ModuleName, err)) + } + redelegations, err := k.GetAllPendingRedelegations(ctx) + if err != nil { + panic(fmt.Sprintf("failed to export pending redelegations: %s", err)) + } + undelegations, err := k.GetAllPendingUndelegations(ctx) + if err != nil { + panic(fmt.Sprintf("failed to export pending undelegations: %s", err)) + } + return &types.GenesisState{ + Params: params, + PendingRedelegations: redelegations, + PendingUndelegations: undelegations, + } +} diff --git a/x/poolrebalancer/keeper/genesis.go b/x/poolrebalancer/keeper/genesis.go new file mode 100644 index 00000000..724cf487 --- /dev/null +++ b/x/poolrebalancer/keeper/genesis.go @@ -0,0 +1,77 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/evm/x/poolrebalancer/types" + + storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// SetPendingRedelegation writes a pending redelegation entry to the store, including its queue and index keys. +// This is intended for genesis import/export. +func (k Keeper) SetPendingRedelegation(ctx context.Context, entry types.PendingRedelegation) error { + del, err := sdk.AccAddressFromBech32(entry.DelegatorAddress) + if err != nil { + return err + } + srcVal, err := sdk.ValAddressFromBech32(entry.SrcValidatorAddress) + if err != nil { + return err + } + dstVal, err := sdk.ValAddressFromBech32(entry.DstValidatorAddress) + if err != nil { + return err + } + return k.addPendingRedelegation(ctx, del, srcVal, dstVal, entry.Amount, entry.CompletionTime) +} + +// SetPendingUndelegation writes a pending undelegation entry to the store, including its queue and index keys. +// This is intended for genesis import/export. +func (k Keeper) SetPendingUndelegation(ctx context.Context, entry types.PendingUndelegation) error { + del, err := sdk.AccAddressFromBech32(entry.DelegatorAddress) + if err != nil { + return err + } + val, err := sdk.ValAddressFromBech32(entry.ValidatorAddress) + if err != nil { + return err + } + return k.addPendingUndelegation(ctx, del, val, entry.Balance, entry.CompletionTime) +} + +// GetAllPendingRedelegations returns all pending redelegation entries stored under the primary key prefix. +func (k Keeper) GetAllPendingRedelegations(ctx context.Context) ([]types.PendingRedelegation, error) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + iter := storetypes.KVStorePrefixIterator(store, types.PendingRedelegationKey) + defer iter.Close() //nolint:errcheck + + out := make([]types.PendingRedelegation, 0) + for ; iter.Valid(); iter.Next() { + var entry types.PendingRedelegation + if err := k.cdc.Unmarshal(iter.Value(), &entry); err != nil { + return nil, err + } + out = append(out, entry) + } + return out, nil +} + +// GetAllPendingUndelegations returns all pending undelegation entries by iterating queue keys and flattening entries. +func (k Keeper) GetAllPendingUndelegations(ctx context.Context) ([]types.PendingUndelegation, error) { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + iter := storetypes.KVStorePrefixIterator(store, types.PendingUndelegationQueueKey) + defer iter.Close() //nolint:errcheck + + out := make([]types.PendingUndelegation, 0) + for ; iter.Valid(); iter.Next() { + var queued types.QueuedUndelegation + if err := k.cdc.Unmarshal(iter.Value(), &queued); err != nil { + return nil, err + } + out = append(out, queued.Entries...) + } + return out, nil +} diff --git a/x/poolrebalancer/keeper/keeper.go b/x/poolrebalancer/keeper/keeper.go new file mode 100644 index 00000000..ef6a16a1 --- /dev/null +++ b/x/poolrebalancer/keeper/keeper.go @@ -0,0 +1,35 @@ +package keeper + +import ( + "cosmossdk.io/core/store" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" +) + +// Keeper holds state and dependencies for the pool rebalancer. +type Keeper struct { + storeService store.KVStoreService + cdc codec.BinaryCodec + stakingKeeper *stakingkeeper.Keeper + authority sdk.AccAddress +} + +// NewKeeper returns a new Keeper. +func NewKeeper( + cdc codec.BinaryCodec, + storeService store.KVStoreService, + stakingKeeper *stakingkeeper.Keeper, + authority sdk.AccAddress, +) Keeper { + if err := sdk.VerifyAddressFormat(authority); err != nil { + panic(err) + } + return Keeper{ + storeService: storeService, + cdc: cdc, + stakingKeeper: stakingKeeper, + authority: authority, + } +} diff --git a/x/poolrebalancer/keeper/params.go b/x/poolrebalancer/keeper/params.go new file mode 100644 index 00000000..d3d7a101 --- /dev/null +++ b/x/poolrebalancer/keeper/params.go @@ -0,0 +1,96 @@ +// Package keeper implements the poolrebalancer module keeper. +// +// params.go contains params get/set helpers and typed accessors. +package keeper + +import ( + "context" + + "github.com/cosmos/evm/x/poolrebalancer/types" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// GetParams returns the current module params. +func (k Keeper) GetParams(ctx context.Context) (params types.Params, err error) { + store := k.storeService.OpenKVStore(ctx) + bz, err := store.Get(types.ParamsKey) + if err != nil { + return params, err + } + if bz == nil || len(bz) == 0 { + return types.DefaultParams(), nil + } + if err := k.cdc.Unmarshal(bz, ¶ms); err != nil { + return params, err + } + return params, nil +} + +// SetParams stores the module params. +func (k Keeper) SetParams(ctx context.Context, params types.Params) error { + store := k.storeService.OpenKVStore(ctx) + bz := k.cdc.MustMarshal(¶ms) + return store.Set(types.ParamsKey, bz) +} + +// GetPoolDelegatorAddress returns the configured pool delegator address (empty if not set). +func (k Keeper) GetPoolDelegatorAddress(ctx context.Context) (sdk.AccAddress, error) { + params, err := k.GetParams(ctx) + if err != nil { + return nil, err + } + if params.PoolDelegatorAddress == "" { + return sdk.AccAddress{}, nil + } + return sdk.AccAddressFromBech32(params.PoolDelegatorAddress) +} + +// GetMaxTargetValidators returns MaxTargetValidators from params. +func (k Keeper) GetMaxTargetValidators(ctx context.Context) (uint32, error) { + params, err := k.GetParams(ctx) + if err != nil { + return 0, err + } + return params.MaxTargetValidators, nil +} + +// GetRebalanceThresholdBP returns RebalanceThresholdBP from params. +func (k Keeper) GetRebalanceThresholdBP(ctx context.Context) (uint32, error) { + params, err := k.GetParams(ctx) + if err != nil { + return 0, err + } + return params.RebalanceThresholdBp, nil +} + +// GetMaxOpsPerBlock returns MaxOpsPerBlock from params. +func (k Keeper) GetMaxOpsPerBlock(ctx context.Context) (uint32, error) { + params, err := k.GetParams(ctx) + if err != nil { + return 0, err + } + return params.MaxOpsPerBlock, nil +} + +// GetMaxMovePerOp returns MaxMovePerOp from params (as math.Int; zero means no cap). +func (k Keeper) GetMaxMovePerOp(ctx context.Context) (math.Int, error) { + params, err := k.GetParams(ctx) + if err != nil { + return math.ZeroInt(), err + } + if params.MaxMovePerOp.IsNil() { + return math.ZeroInt(), nil + } + return params.MaxMovePerOp, nil +} + +// GetUseUndelegateFallback returns UseUndelegateFallback from params. +func (k Keeper) GetUseUndelegateFallback(ctx context.Context) (bool, error) { + params, err := k.GetParams(ctx) + if err != nil { + return false, err + } + return params.UseUndelegateFallback, nil +} diff --git a/x/poolrebalancer/keeper/rebalance.go b/x/poolrebalancer/keeper/rebalance.go new file mode 100644 index 00000000..9d725ae5 --- /dev/null +++ b/x/poolrebalancer/keeper/rebalance.go @@ -0,0 +1,382 @@ +package keeper + +import ( + "context" + "fmt" + "sort" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// GetTargetBondedValidators returns the top bonded validators by power. +// The result size is capped by the module param MaxTargetValidators and preserves staking's power ordering. +func (k Keeper) GetTargetBondedValidators(ctx context.Context) ([]sdk.ValAddress, error) { + maxN, err := k.GetMaxTargetValidators(ctx) + if err != nil { + return nil, err + } + if maxN == 0 { + return nil, fmt.Errorf("MaxTargetValidators must be > 0") + } + + vals, err := k.stakingKeeper.GetBondedValidatorsByPower(ctx) + if err != nil { + return nil, err + } + + n := int(maxN) + if n > len(vals) { + n = len(vals) + } + + out := make([]sdk.ValAddress, 0, n) + for i := 0; i < n; i++ { + valAddr, err := sdk.ValAddressFromBech32(vals[i].OperatorAddress) + if err != nil { + return nil, err + } + out = append(out, valAddr) + } + return out, nil +} + +// GetDelegatorStakeByValidator returns the delegator's bonded stake per validator (in tokens, truncated). +// The returned map is keyed by validator operator address (bech32), plus the total across all validators. +func (k Keeper) GetDelegatorStakeByValidator(ctx context.Context, del sdk.AccAddress) (map[string]math.Int, math.Int, error) { + // 0 = no limit (retrieve all) + delegations, err := k.stakingKeeper.GetDelegatorDelegations(ctx, del, 0) + if err != nil { + return nil, math.ZeroInt(), err + } + + stakeByValidator := make(map[string]math.Int, len(delegations)) + total := math.ZeroInt() + + for _, d := range delegations { + valAddr, err := sdk.ValAddressFromBech32(d.ValidatorAddress) + if err != nil { + return nil, math.ZeroInt(), err + } + + val, err := k.stakingKeeper.GetValidator(ctx, valAddr) + if err != nil { + return nil, math.ZeroInt(), err + } + + // Convert shares -> tokens and truncate to integer tokens. + tokensDec := val.TokensFromSharesTruncated(d.Shares) + tokensInt := tokensDec.TruncateInt() + if tokensInt.IsZero() { + continue + } + + key := valAddr.String() + prev, ok := stakeByValidator[key] + if ok { + stakeByValidator[key] = prev.Add(tokensInt) + } else { + stakeByValidator[key] = tokensInt + } + total = total.Add(tokensInt) + } + + return stakeByValidator, total, nil +} + +// EqualWeightTarget computes an equal-weight target distribution across the given validator set. +// Any remainder from integer division is assigned deterministically to the first validators. +func (k Keeper) EqualWeightTarget(totalStake math.Int, targetValidators []sdk.ValAddress) (map[string]math.Int, error) { + n := len(targetValidators) + if n == 0 { + return nil, fmt.Errorf("target validators list is empty") + } + if totalStake.IsNegative() { + return nil, fmt.Errorf("total stake cannot be negative") + } + + nInt := math.NewInt(int64(n)) + base := totalStake.Quo(nInt) + remainderCount := totalStake.Mod(nInt).Int64() + + out := make(map[string]math.Int, n) + for i, val := range targetValidators { + amt := base + if int64(i) < remainderCount { + amt = amt.Add(math.OneInt()) + } + out[val.String()] = amt + } + return out, nil +} + +// ComputeDeltas returns target-current per validator and applies the rebalance threshold. +// Deltas within the threshold are treated as zero. +func (k Keeper) ComputeDeltas(ctx context.Context, target, current map[string]math.Int, totalStake math.Int) (map[string]math.Int, error) { + bp, err := k.GetRebalanceThresholdBP(ctx) + if err != nil { + return nil, err + } + threshold := totalStake.Mul(math.NewInt(int64(bp))).Quo(math.NewInt(10_000)) + + allKeys := make(map[string]struct{}) + for key := range target { + allKeys[key] = struct{}{} + } + for key := range current { + allKeys[key] = struct{}{} + } + + deltas := make(map[string]math.Int, len(allKeys)) + for key := range allKeys { + t := target[key] + if t.IsNil() { + t = math.ZeroInt() + } + c := current[key] + if c.IsNil() { + c = math.ZeroInt() + } + delta := t.Sub(c) + if delta.Abs().LT(threshold) { + delta = math.ZeroInt() + } + deltas[key] = delta + } + return deltas, nil +} + +func minInt(a, b math.Int) math.Int { + if a.LT(b) { + return a + } + return b +} + +// PickBestRedelegation selects a single (src, dst, amount) move based on deltas. +// Ties are broken deterministically by (src,dst) ordering. If maxMove is non-zero, it caps the amount. +func (k Keeper) PickBestRedelegation( + deltas map[string]math.Int, + keys []string, + blocked map[string]map[string]struct{}, + maxMove math.Int, +) (src string, dst string, amt math.Int, ok bool) { + bestAmt := math.ZeroInt() + bestSrc := "" + bestDst := "" + + for _, s := range keys { + ds := deltas[s] + if !ds.IsNegative() { + continue + } + srcOver := ds.Abs() + for _, d := range keys { + dd := deltas[d] + if !dd.IsPositive() { + continue + } + if m, exists := blocked[s]; exists { + if _, isBlocked := m[d]; isBlocked { + continue + } + } + move := minInt(srcOver, dd) + if !maxMove.IsZero() { + move = minInt(move, maxMove) + } + if move.IsZero() { + continue + } + // Prefer larger moves; tie-break deterministically. + if move.GT(bestAmt) || (move.Equal(bestAmt) && (s < bestSrc || (s == bestSrc && d < bestDst))) { + bestAmt = move + bestSrc = s + bestDst = d + } + } + } + + if bestAmt.IsZero() { + return "", "", math.ZeroInt(), false + } + return bestSrc, bestDst, bestAmt, true +} + +// PickResidualUndelegation selects a single undelegation as a fallback when redelegation isn't possible. +// It targets the most overweight validator and caps the amount by MaxMovePerOp (if set). +func (k Keeper) PickResidualUndelegation(ctx context.Context, deltas map[string]math.Int) (val string, amt math.Int, ok bool, err error) { + maxMove, err := k.GetMaxMovePerOp(ctx) + if err != nil { + return "", math.ZeroInt(), false, err + } + + bestVal := "" + bestOver := math.ZeroInt() + + keys := make([]string, 0, len(deltas)) + for k := range deltas { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, k := range keys { + d := deltas[k] + if !d.IsNegative() { + continue + } + over := d.Abs() + if over.GT(bestOver) || (over.Equal(bestOver) && (bestVal == "" || k < bestVal)) { + bestOver = over + bestVal = k + } + } + + if bestVal == "" || bestOver.IsZero() { + return "", math.ZeroInt(), false, nil + } + + move := bestOver + if !maxMove.IsZero() { + move = minInt(move, maxMove) + } + if move.IsZero() { + return "", math.ZeroInt(), false, nil + } + + return bestVal, move, true, nil +} + +// ProcessRebalance compares current stake to target and applies up to MaxOpsPerBlock operations. +// It is intended to be called from EndBlock after pending queues are cleaned up. +func (k Keeper) ProcessRebalance(ctx context.Context) error { + // Fast-path exits: not configured, no targets, or nothing bonded. + del, err := k.GetPoolDelegatorAddress(ctx) + if err != nil { + return err + } + if del.Empty() { + return nil + } + targetVals, err := k.GetTargetBondedValidators(ctx) + if err != nil { + return err + } + if len(targetVals) == 0 { + return nil + } + stakeByValidator, total, err := k.GetDelegatorStakeByValidator(ctx, del) + if err != nil { + return err + } + if total.IsZero() { + return nil + } + + // Compute equal-weight targets and deltas (threshold applied inside ComputeDeltas). + target, err := k.EqualWeightTarget(total, targetVals) + if err != nil { + return err + } + deltas, err := k.ComputeDeltas(ctx, target, stakeByValidator, total) + if err != nil { + return err + } + + // Nothing exceeds the threshold. + allZero := true + for _, d := range deltas { + if !d.IsZero() { + allZero = false + break + } + } + if allZero { + return nil + } + + // Load params for the apply loop. + maxOps, err := k.GetMaxOpsPerBlock(ctx) + if err != nil { + return err + } + useUndel, err := k.GetUseUndelegateFallback(ctx) + if err != nil { + return err + } + bondDenom, err := k.stakingKeeper.BondDenom(ctx) + if err != nil { + return err + } + + // Apply operations (redelegate first, then optional undelegate fallback). + blocked := make(map[string]map[string]struct{}) + keys := make([]string, 0, len(deltas)) + for key := range deltas { + keys = append(keys, key) + } + sort.Strings(keys) + + maxMove, err := k.GetMaxMovePerOp(ctx) + if err != nil { + return err + } + + var opsDone uint32 + for opsDone < maxOps { + srcKey, dstKey, amt, ok := k.PickBestRedelegation(deltas, keys, blocked, maxMove) + + if ok { + srcVal, err := sdk.ValAddressFromBech32(srcKey) + if err != nil { + return err + } + dstVal, err := sdk.ValAddressFromBech32(dstKey) + if err != nil { + return err + } + coin := sdk.NewCoin(bondDenom, amt) + + if k.CanBeginRedelegation(ctx, del, srcVal, dstVal, coin) { + if _, err := k.BeginTrackedRedelegation(ctx, del, srcVal, dstVal, coin); err == nil { + deltas[srcKey] = deltas[srcKey].Add(amt) + deltas[dstKey] = deltas[dstKey].Sub(amt) + opsDone++ + continue + } + } + + if blocked[srcKey] == nil { + blocked[srcKey] = make(map[string]struct{}) + } + blocked[srcKey][dstKey] = struct{}{} + continue + } + + if !useUndel { + break + } + + valKey, undelAmt, ok, err := k.PickResidualUndelegation(ctx, deltas) + if err != nil { + return err + } + if !ok { + break + } + + valAddr, err := sdk.ValAddressFromBech32(valKey) + if err != nil { + return err + } + coin := sdk.NewCoin(bondDenom, undelAmt) + if _, _, err := k.BeginTrackedUndelegation(ctx, del, valAddr, coin); err != nil { + break + } + deltas[valKey] = deltas[valKey].Add(undelAmt) + opsDone++ + } + + return nil +} diff --git a/x/poolrebalancer/keeper/redelegation.go b/x/poolrebalancer/keeper/redelegation.go new file mode 100644 index 00000000..dcd0eb91 --- /dev/null +++ b/x/poolrebalancer/keeper/redelegation.go @@ -0,0 +1,186 @@ +package keeper + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/cosmos/evm/x/poolrebalancer/types" + + storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// addPendingRedelegation records a redelegation until its completion time. +// It writes the primary record, a by-source index record, and appends to the completion-time queue. +func (k Keeper) addPendingRedelegation(ctx context.Context, del sdk.AccAddress, srcVal, dstVal sdk.ValAddress, coin sdk.Coin, completionTime time.Time) error { + store := k.storeService.OpenKVStore(ctx) + denom := coin.Denom + + // Primary key: merge if an entry already exists for the same (del, denom, dst, completion). + primaryKey := types.GetPendingRedelegationKey(del, denom, dstVal, completionTime) + var entry types.PendingRedelegation + if bz, err := store.Get(primaryKey); err == nil && bz != nil && len(bz) > 0 { + if err := k.cdc.Unmarshal(bz, &entry); err != nil { + return err + } + entry.Amount = entry.Amount.Add(coin) + } else { + entry = types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcVal.String(), + DstValidatorAddress: dstVal.String(), + Amount: coin, + CompletionTime: completionTime, + } + } + primaryBz := k.cdc.MustMarshal(&entry) + if err := store.Set(primaryKey, primaryBz); err != nil { + return err + } + + // Index by source validator; value is unused. + indexKey := types.GetPendingRedelegationBySrcIndexKey(srcVal, completionTime, denom, dstVal, del) + if err := store.Set(indexKey, []byte{}); err != nil { + return err + } + + // Append to the completion-time queue. + queueKey := types.GetPendingRedelegationQueueKey(completionTime) + var queued types.QueuedRedelegation + if bz, err := store.Get(queueKey); err == nil && bz != nil && len(bz) > 0 { + if err := k.cdc.Unmarshal(bz, &queued); err != nil { + return err + } + } + queued.Entries = append(queued.Entries, types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcVal.String(), + DstValidatorAddress: dstVal.String(), + Amount: coin, + CompletionTime: completionTime, + }) + queueBz := k.cdc.MustMarshal(&queued) + return store.Set(queueKey, queueBz) +} + +// HasImmatureRedelegationTo reports whether there's any in-flight redelegation to dstVal +// for the given (delegator, denom). This is used to prevent transitive redelegations. +func (k Keeper) HasImmatureRedelegationTo(ctx context.Context, del sdk.AccAddress, dstVal sdk.ValAddress, denom string) bool { + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + prefix := types.GetPendingRedelegationPrefix(del, denom, dstVal) + iter := storetypes.KVStorePrefixIterator(store, prefix) + defer iter.Close() //nolint:errcheck + return iter.Valid() +} + +// CanBeginRedelegation performs local checks before calling the staking keeper. +// It rejects self-redelegations, non-positive amounts, and transitive redelegations. +func (k Keeper) CanBeginRedelegation(ctx context.Context, del sdk.AccAddress, srcVal, dstVal sdk.ValAddress, coin sdk.Coin) bool { + if srcVal.Equals(dstVal) { + return false + } + if !coin.Amount.IsPositive() { + return false + } + if k.HasImmatureRedelegationTo(ctx, del, srcVal, coin.Denom) { + return false + } + return true +} + +// BeginTrackedRedelegation calls the staking keeper and records the redelegation for later cleanup. +func (k Keeper) BeginTrackedRedelegation(ctx context.Context, del sdk.AccAddress, srcVal, dstVal sdk.ValAddress, coin sdk.Coin) (completionTime time.Time, err error) { + unbondingTime, err := k.stakingKeeper.UnbondingTime(ctx) + if err != nil { + return time.Time{}, fmt.Errorf("unbonding time: %w", err) + } + sdkCtx := sdk.UnwrapSDKContext(ctx) + completionTime = sdkCtx.BlockTime().Add(unbondingTime) + + srcValidator, err := k.stakingKeeper.GetValidator(ctx, srcVal) + if err != nil { + return time.Time{}, fmt.Errorf("get source validator: %w", err) + } + shares, err := srcValidator.SharesFromTokens(coin.Amount) + if err != nil { + return time.Time{}, fmt.Errorf("shares from tokens: %w", err) + } + if !shares.IsPositive() { + return time.Time{}, errors.New("shares amount is not positive") + } + + completionTime, err = k.stakingKeeper.BeginRedelegation(ctx, del, srcVal, dstVal, shares) + if err != nil { + return time.Time{}, fmt.Errorf("begin redelegation: %w", err) + } + + if err := k.addPendingRedelegation(ctx, del, srcVal, dstVal, coin, completionTime); err != nil { + return time.Time{}, fmt.Errorf("add pending redelegation: %w", err) + } + return completionTime, nil +} + +// deletePendingRedelegation removes the primary and index records for a pending redelegation. +// Deletes are idempotent: removing a missing key is a no-op. +func (k Keeper) deletePendingRedelegation(ctx context.Context, entry types.PendingRedelegation, completion time.Time) error { + store := k.storeService.OpenKVStore(ctx) + del, err := sdk.AccAddressFromBech32(entry.DelegatorAddress) + if err != nil { + return err + } + srcVal, err := sdk.ValAddressFromBech32(entry.SrcValidatorAddress) + if err != nil { + return err + } + dstVal, err := sdk.ValAddressFromBech32(entry.DstValidatorAddress) + if err != nil { + return err + } + denom := entry.Amount.Denom + + primaryKey := types.GetPendingRedelegationKey(del, denom, dstVal, completion) + if err := store.Delete(primaryKey); err != nil { + return err + } + indexKey := types.GetPendingRedelegationBySrcIndexKey(srcVal, completion, denom, dstVal, del) + return store.Delete(indexKey) +} + +// CompletePendingRedelegations removes matured redelegation records and their indexes. +func (k Keeper) CompletePendingRedelegations(ctx context.Context) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) + blockTime := sdkCtx.BlockTime() + + store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) + start := types.PendingRedelegationQueueKey + end := types.GetPendingRedelegationQueueKey(blockTime) + // Include keys with completionTime <= blockTime by using an exclusive end key immediately after end. + endExclusive := append(append([]byte{}, end...), 0xFF) + + iter := store.Iterator(start, endExclusive) + defer iter.Close() //nolint:errcheck + + for ; iter.Valid(); iter.Next() { + key := iter.Key() + completion, err := types.ParsePendingRedelegationQueueKey(key) + if err != nil { + return err + } + var queued types.QueuedRedelegation + if err := k.cdc.Unmarshal(iter.Value(), &queued); err != nil { + return err + } + for _, entry := range queued.Entries { + if err := k.deletePendingRedelegation(ctx, entry, completion); err != nil { + return err + } + } + store.Delete(key) + } + + return nil +} diff --git a/x/poolrebalancer/keeper/undelegation.go b/x/poolrebalancer/keeper/undelegation.go new file mode 100644 index 00000000..e691b0a3 --- /dev/null +++ b/x/poolrebalancer/keeper/undelegation.go @@ -0,0 +1,145 @@ +package keeper + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/cosmos/evm/x/poolrebalancer/types" + + "github.com/cosmos/cosmos-sdk/runtime" + + "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// addPendingUndelegation records an undelegation until its completion time. +// It appends to the (completionTime, delegator) queue and writes a by-validator index entry. +func (k Keeper) addPendingUndelegation(ctx context.Context, del sdk.AccAddress, val sdk.ValAddress, coin sdk.Coin, completionTime time.Time) error { + store := k.storeService.OpenKVStore(ctx) + denom := coin.Denom + + // Queue entry at (completionTime, delegator). + queueKey := types.GetPendingUndelegationQueueKey(completionTime, del) + var queued types.QueuedUndelegation + if bz, err := store.Get(queueKey); err == nil && bz != nil && len(bz) > 0 { + if err := k.cdc.Unmarshal(bz, &queued); err != nil { + return err + } + } + queued.Entries = append(queued.Entries, types.PendingUndelegation{ + DelegatorAddress: del.String(), + ValidatorAddress: val.String(), + Balance: coin, + CompletionTime: completionTime, + }) + queueBz := k.cdc.MustMarshal(&queued) + if err := store.Set(queueKey, queueBz); err != nil { + return err + } + + // By-validator index; value is unused. + indexKey := types.GetPendingUndelegationByValIndexKey(val, completionTime, denom, del) + return store.Set(indexKey, []byte{}) +} + +// BeginTrackedUndelegation calls the staking keeper and records the undelegation for later cleanup. +func (k Keeper) BeginTrackedUndelegation(ctx context.Context, del sdk.AccAddress, valAddr sdk.ValAddress, coin sdk.Coin) (completionTime time.Time, amountUnbonded math.Int, err error) { + if !coin.Amount.IsPositive() { + return time.Time{}, math.ZeroInt(), errors.New("undelegate amount must be positive") + } + + val, err := k.stakingKeeper.GetValidator(ctx, valAddr) + if err != nil { + return time.Time{}, math.ZeroInt(), fmt.Errorf("get validator: %w", err) + } + shares, err := val.SharesFromTokens(coin.Amount) + if err != nil { + return time.Time{}, math.ZeroInt(), fmt.Errorf("shares from tokens: %w", err) + } + if !shares.IsPositive() { + return time.Time{}, math.ZeroInt(), errors.New("shares amount is not positive") + } + + // Ensure the delegation has at least the requested shares. + delegation, err := k.stakingKeeper.GetDelegation(ctx, del, valAddr) + if err != nil { + return time.Time{}, math.ZeroInt(), fmt.Errorf("get delegation: %w", err) + } + if delegation.Shares.LT(shares) { + return time.Time{}, math.ZeroInt(), fmt.Errorf("insufficient delegation: have %s shares, need %s", delegation.Shares, shares) + } + + completionTime, amountUnbonded, err = k.stakingKeeper.Undelegate(ctx, del, valAddr, shares) + if err != nil { + return time.Time{}, math.ZeroInt(), fmt.Errorf("undelegate: %w", err) + } + + if amountUnbonded.IsZero() { + return completionTime, amountUnbonded, nil + } + + bondDenom, err := k.stakingKeeper.BondDenom(ctx) + if err != nil { + return time.Time{}, math.ZeroInt(), fmt.Errorf("bond denom: %w", err) + } + if err := k.addPendingUndelegation(ctx, del, valAddr, sdk.NewCoin(bondDenom, amountUnbonded), completionTime); err != nil { + return time.Time{}, math.ZeroInt(), fmt.Errorf("add pending undelegation: %w", err) + } + + return completionTime, amountUnbonded, nil +} + +// CompletePendingUndelegations deletes matured pending undelegation queue and index entries. +// The staking module handles actual token payout to the delegator; we only clean up our tracking state. +func (k Keeper) CompletePendingUndelegations(ctx context.Context) error { + sdkCtx := sdk.UnwrapSDKContext(ctx) + blockTime := sdkCtx.BlockTime() + + coreStore := k.storeService.OpenKVStore(ctx) + iterStore := runtime.KVStoreAdapter(coreStore) + + // Iterate all queue entries with completionTime <= blockTime. + start := types.PendingUndelegationQueueKey + end := types.GetPendingUndelegationQueueKeyByTime(blockTime) + endExclusive := append(append([]byte{}, end...), 0xFF) + + iter := iterStore.Iterator(start, endExclusive) + defer iter.Close() //nolint:errcheck + + for ; iter.Valid(); iter.Next() { + key := iter.Key() + completionTime, err := types.ParsePendingUndelegationQueueKeyForCompletionTime(key) + if err != nil { + return err + } + + var queued types.QueuedUndelegation + if err := k.cdc.Unmarshal(iter.Value(), &queued); err != nil { + return err + } + + // Delete by-validator index entries for each queued undelegation entry. + for _, entry := range queued.Entries { + delAddr, err := sdk.AccAddressFromBech32(entry.DelegatorAddress) + if err != nil { + return err + } + valAddr, err := sdk.ValAddressFromBech32(entry.ValidatorAddress) + if err != nil { + return err + } + indexKey := types.GetPendingUndelegationByValIndexKey(valAddr, completionTime, entry.Balance.Denom, delAddr) + if err := coreStore.Delete(indexKey); err != nil { + return err + } + } + + // Delete the queue key itself. + iterStore.Delete(key) + } + + return nil +} From eab1f7506874e75b155bff2f74f6924b52e6f2c1 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 18 Mar 2026 17:02:14 +0530 Subject: [PATCH 04/31] feat(poolrebalancer): wire module services and governance params update --- evmd/app.go | 25 ++++- x/poolrebalancer/client/cli/query.go | 121 ++++++++++++++++++++++ x/poolrebalancer/keeper/grpc_query.go | 83 +++++++++++++++ x/poolrebalancer/keeper/msg_server.go | 31 ++++++ x/poolrebalancer/module.go | 143 ++++++++++++++++++++++++++ 5 files changed, 398 insertions(+), 5 deletions(-) create mode 100644 x/poolrebalancer/client/cli/query.go create mode 100644 x/poolrebalancer/keeper/grpc_query.go create mode 100644 x/poolrebalancer/keeper/msg_server.go create mode 100644 x/poolrebalancer/module.go diff --git a/evmd/app.go b/evmd/app.go index b92e46e5..fb27269c 100644 --- a/evmd/app.go +++ b/evmd/app.go @@ -38,6 +38,9 @@ import ( "github.com/cosmos/evm/x/ibc/transfer" transferkeeper "github.com/cosmos/evm/x/ibc/transfer/keeper" transferv2 "github.com/cosmos/evm/x/ibc/transfer/v2" + "github.com/cosmos/evm/x/poolrebalancer" + poolrebalancerkeeper "github.com/cosmos/evm/x/poolrebalancer/keeper" + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" "github.com/cosmos/evm/x/precisebank" precisebankkeeper "github.com/cosmos/evm/x/precisebank/keeper" precisebanktypes "github.com/cosmos/evm/x/precisebank/types" @@ -182,11 +185,12 @@ type EVMD struct { CallbackKeeper ibccallbackskeeper.ContractKeeper // Cosmos EVM keepers - FeeMarketKeeper feemarketkeeper.Keeper - EVMKeeper *evmkeeper.Keeper - Erc20Keeper erc20keeper.Keeper - PreciseBankKeeper precisebankkeeper.Keeper - EVMMempool *evmmempool.ExperimentalEVMMempool + FeeMarketKeeper feemarketkeeper.Keeper + EVMKeeper *evmkeeper.Keeper + Erc20Keeper erc20keeper.Keeper + PreciseBankKeeper precisebankkeeper.Keeper + PoolRebalancerKeeper poolrebalancerkeeper.Keeper + EVMMempool *evmmempool.ExperimentalEVMMempool // the module manager ModuleManager *module.Manager @@ -238,6 +242,7 @@ func NewExampleApp( ibcexported.StoreKey, ibctransfertypes.StoreKey, // Cosmos EVM store keys evmtypes.StoreKey, feemarkettypes.StoreKey, erc20types.StoreKey, precisebanktypes.StoreKey, + poolrebalancertypes.StoreKey, ) oKeys := storetypes.NewObjectStoreKeys(banktypes.ObjectStoreKey, evmtypes.ObjectKey) @@ -364,6 +369,13 @@ func NewExampleApp( stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), ) + app.PoolRebalancerKeeper = poolrebalancerkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[poolrebalancertypes.StoreKey]), + app.StakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName), + ) + app.AuthzKeeper = authzkeeper.NewKeeper( runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), appCodec, @@ -570,6 +582,7 @@ func NewExampleApp( slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, nil, app.interfaceRegistry), distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, nil), staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, nil), + poolrebalancer.NewAppModule(app.PoolRebalancerKeeper), upgrade.NewAppModule(app.UpgradeKeeper, app.AccountKeeper.AddressCodec()), evidence.NewAppModule(app.EvidenceKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), @@ -641,6 +654,7 @@ func NewExampleApp( banktypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, + poolrebalancertypes.ModuleName, // after staking; rebalances pool delegator stake authtypes.ModuleName, // Cosmos EVM EndBlockers @@ -673,6 +687,7 @@ func NewExampleApp( feemarkettypes.ModuleName, erc20types.ModuleName, precisebanktypes.ModuleName, + poolrebalancertypes.ModuleName, ibctransfertypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName, diff --git a/x/poolrebalancer/client/cli/query.go b/x/poolrebalancer/client/cli/query.go new file mode 100644 index 00000000..773b2fc4 --- /dev/null +++ b/x/poolrebalancer/client/cli/query.go @@ -0,0 +1,121 @@ +package cli + +import ( + "context" + + "github.com/spf13/cobra" + + "github.com/cosmos/evm/x/poolrebalancer/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" +) + +// GetQueryCmd returns the root query command for the poolrebalancer module. +func GetQueryCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Poolrebalancer query commands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + GetParamsCmd(), + GetPendingRedelegationsCmd(), + GetPendingUndelegationsCmd(), + ) + return cmd +} + +func GetParamsCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Query module params", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + return cmd +} + +func GetPendingRedelegationsCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "pending-redelegations", + Short: "List pending redelegations", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := queryClient.PendingRedelegations(context.Background(), &types.QueryPendingRedelegationsRequest{ + Pagination: pageReq, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "pending-redelegations") + return cmd +} + +func GetPendingUndelegationsCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "pending-undelegations", + Short: "List pending undelegations", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, _ []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := queryClient.PendingUndelegations(context.Background(), &types.QueryPendingUndelegationsRequest{ + Pagination: pageReq, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "pending-undelegations") + return cmd +} diff --git a/x/poolrebalancer/keeper/grpc_query.go b/x/poolrebalancer/keeper/grpc_query.go new file mode 100644 index 00000000..f01da788 --- /dev/null +++ b/x/poolrebalancer/keeper/grpc_query.go @@ -0,0 +1,83 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/store/prefix" + + "github.com/cosmos/evm/x/poolrebalancer/types" + + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/types/query" +) + +var _ types.QueryServer = QueryServer{} + +type QueryServer struct { + k Keeper +} + +func NewQueryServer(k Keeper) QueryServer { + return QueryServer{k: k} +} + +func (qs QueryServer) Params(ctx context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + params, err := qs.k.GetParams(ctx) + if err != nil { + return nil, err + } + return &types.QueryParamsResponse{Params: params}, nil +} + +func (qs QueryServer) PendingRedelegations( + ctx context.Context, + req *types.QueryPendingRedelegationsRequest, +) (*types.QueryPendingRedelegationsResponse, error) { + store := runtime.KVStoreAdapter(qs.k.storeService.OpenKVStore(ctx)) + pstore := prefix.NewStore(store, types.PendingRedelegationKey) + + var out []types.PendingRedelegation + pageRes, err := query.Paginate(pstore, req.Pagination, func(key, value []byte) error { + var entry types.PendingRedelegation + if err := qs.k.cdc.Unmarshal(value, &entry); err != nil { + return err + } + out = append(out, entry) + return nil + }) + if err != nil { + return nil, err + } + + return &types.QueryPendingRedelegationsResponse{ + Redelegations: out, + Pagination: pageRes, + }, nil +} + +func (qs QueryServer) PendingUndelegations( + ctx context.Context, + req *types.QueryPendingUndelegationsRequest, +) (*types.QueryPendingUndelegationsResponse, error) { + // Paginate over queue keys (completionTime, delegator); each value is a batch of entries. + store := runtime.KVStoreAdapter(qs.k.storeService.OpenKVStore(ctx)) + pstore := prefix.NewStore(store, types.PendingUndelegationQueueKey) + + var out []types.PendingUndelegation + pageRes, err := query.Paginate(pstore, req.Pagination, func(key, value []byte) error { + var queued types.QueuedUndelegation + if err := qs.k.cdc.Unmarshal(value, &queued); err != nil { + return err + } + out = append(out, queued.Entries...) + return nil + }) + if err != nil { + return nil, err + } + + return &types.QueryPendingUndelegationsResponse{ + Undelegations: out, + Pagination: pageRes, + }, nil +} diff --git a/x/poolrebalancer/keeper/msg_server.go b/x/poolrebalancer/keeper/msg_server.go new file mode 100644 index 00000000..a20864f2 --- /dev/null +++ b/x/poolrebalancer/keeper/msg_server.go @@ -0,0 +1,31 @@ +package keeper + +import ( + "context" + + "github.com/cosmos/evm/x/poolrebalancer/types" + + errorsmod "cosmossdk.io/errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +// UpdateParams updates module params. Caller must be the governance module account. +func (k *Keeper) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if k.authority.String() != req.Authority { + return nil, errorsmod.Wrapf( + govtypes.ErrInvalidSigner, + "invalid authority; expected %s, got %s", + k.authority.String(), + req.Authority, + ) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + if err := k.SetParams(ctx, req.Params); err != nil { + return nil, err + } + + return &types.MsgUpdateParamsResponse{}, nil +} diff --git a/x/poolrebalancer/module.go b/x/poolrebalancer/module.go new file mode 100644 index 00000000..4d260870 --- /dev/null +++ b/x/poolrebalancer/module.go @@ -0,0 +1,143 @@ +package poolrebalancer + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/cometbft/cometbft/abci/types" + + "github.com/cosmos/evm/x/poolrebalancer/client/cli" + "github.com/cosmos/evm/x/poolrebalancer/keeper" + "github.com/cosmos/evm/x/poolrebalancer/types" + + "cosmossdk.io/core/appmodule" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" +) + +// ConsensusVersion defines the current module consensus version. +const ConsensusVersion = 1 + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.HasABCIGenesis = AppModule{} + _ appmodule.AppModule = AppModule{} + _ appmodule.HasEndBlocker = AppModule{} +) + +// AppModuleBasic implements module.AppModuleBasic for the poolrebalancer module. +type AppModuleBasic struct{} + +func NewAppModuleBasic() AppModuleBasic { + return AppModuleBasic{} +} + +// Name returns the module name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the module's types with the LegacyAmino codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} + +// ConsensusVersion returns the consensus state-breaking version for the module. +func (AppModuleBasic) ConsensusVersion() uint64 { + return ConsensusVersion +} + +// RegisterInterfaces registers the module's interface types. +func (AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns default genesis state as raw JSON. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// ValidateGenesis validates the genesis state. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var gs types.GenesisState + if err := cdc.UnmarshalJSON(bz, &gs); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return gs.Validate() +} + +// RegisterGRPCGatewayRoutes registers the module's gRPC-gateway routes. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } +} + +// GetTxCmd returns the root tx command (nil; no user-facing tx CLI). +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return nil +} + +// GetQueryCmd returns the root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// AppModule implements module.AppModule for the poolrebalancer module. +type AppModule struct { + AppModuleBasic + keeper keeper.Keeper +} + +// NewAppModule returns a new AppModule. +func NewAppModule(k keeper.Keeper) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(), + keeper: k, + } +} + +// Name returns the module name. +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// RegisterServices registers the module's gRPC query and msg services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServer(am.keeper)) + types.RegisterMsgServer(cfg.MsgServer(), &am.keeper) +} + +// EndBlock runs the module EndBlocker. +func (am AppModule) EndBlock(ctx context.Context) error { + return EndBlocker(sdk.UnwrapSDKContext(ctx), am.keeper) +} + +// InitGenesis initializes the module from genesis. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { + var genState types.GenesisState + cdc.MustUnmarshalJSON(gs, &genState) + InitGenesis(ctx, am.keeper, &genState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis exports the module state to genesis. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := ExportGenesis(ctx, am.keeper) + return cdc.MustMarshalJSON(genState) +} + +// IsAppModule implements appmodule.AppModule. +func (AppModule) IsAppModule() {} + +// IsOnePerModuleType implements depinject.OnePerModuleType. +func (AppModule) IsOnePerModuleType() {} From 7b8b815473e00afa9b1620aaebd69ec810a2eeca Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 18 Mar 2026 17:02:23 +0530 Subject: [PATCH 05/31] test(poolrebalancer): add keeper, query, msg, and genesis coverage --- x/poolrebalancer/genesis_test.go | 76 +++ x/poolrebalancer/keeper/grpc_query_test.go | 95 ++++ x/poolrebalancer/keeper/msg_server_test.go | 68 +++ x/poolrebalancer/keeper/rebalance_test.go | 459 +++++++++++++++++++ x/poolrebalancer/keeper/redelegation_test.go | 85 ++++ x/poolrebalancer/keeper/test_helpers_test.go | 32 ++ x/poolrebalancer/keeper/undelegation_test.go | 54 +++ 7 files changed, 869 insertions(+) create mode 100644 x/poolrebalancer/genesis_test.go create mode 100644 x/poolrebalancer/keeper/grpc_query_test.go create mode 100644 x/poolrebalancer/keeper/msg_server_test.go create mode 100644 x/poolrebalancer/keeper/rebalance_test.go create mode 100644 x/poolrebalancer/keeper/redelegation_test.go create mode 100644 x/poolrebalancer/keeper/test_helpers_test.go create mode 100644 x/poolrebalancer/keeper/undelegation_test.go diff --git a/x/poolrebalancer/genesis_test.go b/x/poolrebalancer/genesis_test.go new file mode 100644 index 00000000..a01bfa52 --- /dev/null +++ b/x/poolrebalancer/genesis_test.go @@ -0,0 +1,76 @@ +package poolrebalancer + +import ( + "bytes" + "testing" + "time" + + "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + + "github.com/cosmos/evm/x/poolrebalancer/keeper" + "github.com/cosmos/evm/x/poolrebalancer/types" +) + +func TestGenesis_ExportsAndRestoresPendingState(t *testing.T) { + storeKey := storetypes.NewKVStoreKey(types.ModuleName) + tKey := storetypes.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey).WithBlockTime(time.Unix(2_000, 0)) + + storeService := runtime.NewKVStoreService(storeKey) + cdc := moduletestutil.MakeTestEncodingConfig().Codec + stakingK := &stakingkeeper.Keeper{} + authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) + k := keeper.NewKeeper(cdc, storeService, stakingK, authority) + + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + srcVal := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + dstVal := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + + require.NoError(t, k.SetPendingRedelegation(ctx, types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcVal.String(), + DstValidatorAddress: dstVal.String(), + Amount: sdk.NewCoin("stake", math.NewInt(10)), + CompletionTime: ctx.BlockTime().Add(time.Hour), + })) + + require.NoError(t, k.SetPendingUndelegation(ctx, types.PendingUndelegation{ + DelegatorAddress: del.String(), + ValidatorAddress: srcVal.String(), + Balance: sdk.NewCoin("stake", math.NewInt(5)), + CompletionTime: ctx.BlockTime().Add(2 * time.Hour), + })) + + exported := ExportGenesis(ctx, k) + require.NotNil(t, exported) + require.Len(t, exported.PendingRedelegations, 1) + require.Len(t, exported.PendingUndelegations, 1) + + // Restore into a fresh store/keeper. + storeKey2 := storetypes.NewKVStoreKey(types.ModuleName) + tKey2 := storetypes.NewTransientStoreKey("transient_test2") + ctx2 := testutil.DefaultContext(storeKey2, tKey2).WithBlockTime(time.Unix(2_000, 0)) + + storeService2 := runtime.NewKVStoreService(storeKey2) + k2 := keeper.NewKeeper(cdc, storeService2, stakingK, authority) + + InitGenesis(ctx2, k2, exported) + + redels, err := k2.GetAllPendingRedelegations(ctx2) + require.NoError(t, err) + undels, err := k2.GetAllPendingUndelegations(ctx2) + require.NoError(t, err) + + require.Len(t, redels, 1) + require.Len(t, undels, 1) + require.Equal(t, exported.PendingRedelegations[0].DelegatorAddress, redels[0].DelegatorAddress) + require.Equal(t, exported.PendingUndelegations[0].DelegatorAddress, undels[0].DelegatorAddress) +} diff --git a/x/poolrebalancer/keeper/grpc_query_test.go b/x/poolrebalancer/keeper/grpc_query_test.go new file mode 100644 index 00000000..befc6a7a --- /dev/null +++ b/x/poolrebalancer/keeper/grpc_query_test.go @@ -0,0 +1,95 @@ +package keeper + +import ( + "bytes" + "testing" + "time" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkquery "github.com/cosmos/cosmos-sdk/types/query" + + "github.com/cosmos/evm/x/poolrebalancer/types" +) + +func TestQueryParams_RoundTrip(t *testing.T) { + ctx, k := newTestKeeper(t) + + params := types.DefaultParams() + params.MaxOpsPerBlock = 7 + require.NoError(t, k.SetParams(ctx, params)) + + qs := NewQueryServer(k) + res, err := qs.Params(ctx, &types.QueryParamsRequest{}) + require.NoError(t, err) + require.Equal(t, uint32(7), res.Params.MaxOpsPerBlock) +} + +func TestQueryPendingRedelegations_DecodesProtoValues(t *testing.T) { + ctx, k := newTestKeeper(t) + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + srcVal := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + dstVal := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + + entry := types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcVal.String(), + DstValidatorAddress: dstVal.String(), + Amount: sdk.NewCoin("stake", math.NewInt(5)), + CompletionTime: ctx.BlockTime().Add(time.Hour), + } + require.NoError(t, k.SetPendingRedelegation(ctx, entry)) + + qs := NewQueryServer(k) + res, err := qs.PendingRedelegations(ctx, &types.QueryPendingRedelegationsRequest{ + Pagination: &sdkquery.PageRequest{Limit: 1}, + }) + require.NoError(t, err) + require.Len(t, res.Redelegations, 1) + require.Equal(t, entry.DelegatorAddress, res.Redelegations[0].DelegatorAddress) +} + +func TestQueryPendingUndelegations_PaginatesByQueueBuckets(t *testing.T) { + ctx, k := newTestKeeper(t) + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + + // Bucket 1: earlier completion time, two entries in the same queue key. + completion1 := ctx.BlockTime().Add(time.Minute) + require.NoError(t, k.SetPendingUndelegation(ctx, types.PendingUndelegation{ + DelegatorAddress: del.String(), + ValidatorAddress: sdk.ValAddress(bytes.Repeat([]byte{2}, 20)).String(), + Balance: sdk.NewCoin("stake", math.NewInt(1)), + CompletionTime: completion1, + })) + require.NoError(t, k.SetPendingUndelegation(ctx, types.PendingUndelegation{ + DelegatorAddress: del.String(), + ValidatorAddress: sdk.ValAddress(bytes.Repeat([]byte{3}, 20)).String(), + Balance: sdk.NewCoin("stake", math.NewInt(2)), + CompletionTime: completion1, + })) + + // Bucket 2: later completion time. + completion2 := ctx.BlockTime().Add(2 * time.Minute) + require.NoError(t, k.SetPendingUndelegation(ctx, types.PendingUndelegation{ + DelegatorAddress: del.String(), + ValidatorAddress: sdk.ValAddress(bytes.Repeat([]byte{4}, 20)).String(), + Balance: sdk.NewCoin("stake", math.NewInt(3)), + CompletionTime: completion2, + })) + + qs := NewQueryServer(k) + res, err := qs.PendingUndelegations(ctx, &types.QueryPendingUndelegationsRequest{ + Pagination: &sdkquery.PageRequest{Limit: 1}, + }) + require.NoError(t, err) + + // Pagination is over queue keys, not individual entries. With Limit=1, we can still receive + // multiple undelegation entries if the first queue bucket contains more than one entry. + require.GreaterOrEqual(t, len(res.Undelegations), 2) +} diff --git a/x/poolrebalancer/keeper/msg_server_test.go b/x/poolrebalancer/keeper/msg_server_test.go new file mode 100644 index 00000000..6c106fd8 --- /dev/null +++ b/x/poolrebalancer/keeper/msg_server_test.go @@ -0,0 +1,68 @@ +package keeper + +import ( + "bytes" + "testing" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/evm/x/poolrebalancer/types" +) + +func TestUpdateParams_RejectsWrongAuthority(t *testing.T) { + ctx, k := newTestKeeper(t) + + // Current keeper authority is 0x09..09; use a different address. + wrongAuthority := sdk.AccAddress(bytes.Repeat([]byte{8}, 20)).String() + + msg := &types.MsgUpdateParams{ + Authority: wrongAuthority, + Params: types.DefaultParams(), + } + + _, err := k.UpdateParams(ctx, msg) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid authority") +} + +func TestUpdateParams_AcceptsAuthorityAndUpdatesParams(t *testing.T) { + ctx, k := newTestKeeper(t) + + authority := k.authority.String() + + newParams := types.DefaultParams() + newParams.MaxOpsPerBlock = 9 + newParams.MaxMovePerOp = math.NewInt(77) + + msg := &types.MsgUpdateParams{ + Authority: authority, + Params: newParams, + } + + _, err := k.UpdateParams(ctx, msg) + require.NoError(t, err) + + got, err := k.GetParams(ctx) + require.NoError(t, err) + require.Equal(t, uint32(9), got.MaxOpsPerBlock) + require.True(t, got.MaxMovePerOp.Equal(math.NewInt(77))) +} + +func TestMsgUpdateParams_ValidateBasic_RejectsInvalidParams(t *testing.T) { + msg := &types.MsgUpdateParams{ + Authority: sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String(), + Params: types.Params{ + PoolDelegatorAddress: "", + MaxTargetValidators: 0, // invalid + RebalanceThresholdBp: 50, + MaxOpsPerBlock: 5, + MaxMovePerOp: math.ZeroInt(), + UseUndelegateFallback: true, + }, + } + + require.Error(t, msg.ValidateBasic()) +} diff --git a/x/poolrebalancer/keeper/rebalance_test.go b/x/poolrebalancer/keeper/rebalance_test.go new file mode 100644 index 00000000..745b0fbc --- /dev/null +++ b/x/poolrebalancer/keeper/rebalance_test.go @@ -0,0 +1,459 @@ +package keeper_test + +import ( + "bytes" + "sort" + "strconv" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/evm/x/poolrebalancer/keeper" + "github.com/cosmos/evm/x/poolrebalancer/types" + + "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" + + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" +) + +// testKeeperWithParams creates a keeper backed by an in-memory store and seeds its params. +// The staking keeper is a zero value and must not be used by these unit tests. +func testKeeperWithParams(t *testing.T, rebalanceThresholdBP, maxMovePerOp string) (sdk.Context, keeper.Keeper) { + t.Helper() + + storeKey := storetypes.NewKVStoreKey(types.ModuleName) + tKey := storetypes.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + + storeService := runtime.NewKVStoreService(storeKey) + cdc := moduletestutil.MakeTestEncodingConfig().Codec + stakingKeeper := &stakingkeeper.Keeper{} // zero value; do not call staking methods + k := keeper.NewKeeper(cdc, storeService, stakingKeeper, sdk.AccAddress(bytes.Repeat([]byte{9}, 20))) + + bp, err := strconv.ParseUint(rebalanceThresholdBP, 10, 32) + require.NoError(t, err) + + params := types.DefaultParams() + params.RebalanceThresholdBp = uint32(bp) + amt, ok := math.NewIntFromString(maxMovePerOp) + require.True(t, ok, "invalid maxMovePerOp %q", maxMovePerOp) + params.MaxMovePerOp = amt + require.NoError(t, k.SetParams(ctx, params)) + + return ctx, k +} + +// threeValAddrs returns three deterministic validator addresses (for EqualWeightTarget tests). +func threeValAddrs() []sdk.ValAddress { + return []sdk.ValAddress{ + sdk.ValAddress(bytes.Repeat([]byte{1}, 20)), + sdk.ValAddress(bytes.Repeat([]byte{2}, 20)), + sdk.ValAddress(bytes.Repeat([]byte{3}, 20)), + } +} + +// --------------------------------------------------------------------------- +// 3.1 EqualWeightTarget +// --------------------------------------------------------------------------- + +// TestEqualWeightTarget_HappyPath: totalStake=1000, n=3; expect 334, 333, 333 (remainder 1 to first). +func TestEqualWeightTarget_HappyPath(t *testing.T) { + k := keeper.Keeper{} // zero value; method does not use store or staking + totalStake := math.NewInt(1000) + vals := threeValAddrs() + require.Len(t, vals, 3) + + out, err := k.EqualWeightTarget(totalStake, vals) + require.NoError(t, err) + require.Len(t, out, 3) + + // 1000 / 3 = 333, remainder 1 → first validator gets 334, others 333 + sum := math.ZeroInt() + for _, v := range vals { + key := v.String() + amt, ok := out[key] + require.True(t, ok, "missing key %s", key) + sum = sum.Add(amt) + } + require.True(t, sum.Equal(totalStake), "sum %s != totalStake %s", sum, totalStake) + + require.True(t, out[vals[0].String()].Equal(math.NewInt(334)), "first validator should get 334") + require.True(t, out[vals[1].String()].Equal(math.NewInt(333))) + require.True(t, out[vals[2].String()].Equal(math.NewInt(333))) +} + +// TestEqualWeightTarget_RemainderZero: totalStake=999, n=3; expect exactly 333 each. +func TestEqualWeightTarget_RemainderZero(t *testing.T) { + k := keeper.Keeper{} + totalStake := math.NewInt(999) + vals := threeValAddrs() + + out, err := k.EqualWeightTarget(totalStake, vals) + require.NoError(t, err) + require.Len(t, out, 3) + + for _, v := range vals { + require.True(t, out[v.String()].Equal(math.NewInt(333)), "validator %s should get 333", v.String()) + } + sum := math.ZeroInt() + for _, amt := range out { + sum = sum.Add(amt) + } + require.True(t, sum.Equal(totalStake)) +} + +// TestEqualWeightTarget_SingleValidator: n=1; that validator gets full totalStake. +func TestEqualWeightTarget_SingleValidator(t *testing.T) { + k := keeper.Keeper{} + totalStake := math.NewInt(500) + vals := []sdk.ValAddress{sdk.ValAddress(bytes.Repeat([]byte{1}, 20))} + + out, err := k.EqualWeightTarget(totalStake, vals) + require.NoError(t, err) + require.Len(t, out, 1) + require.True(t, out[vals[0].String()].Equal(totalStake)) +} + +// TestEqualWeightTarget_Errors: n=0 or totalStake negative returns error. +func TestEqualWeightTarget_Errors(t *testing.T) { + k := keeper.Keeper{} + vals := threeValAddrs() + + _, err := k.EqualWeightTarget(math.NewInt(1000), nil) + require.Error(t, err) + require.Contains(t, err.Error(), "empty") + + _, err = k.EqualWeightTarget(math.NewInt(1000), []sdk.ValAddress{}) + require.Error(t, err) + require.Contains(t, err.Error(), "empty") + + _, err = k.EqualWeightTarget(math.NewInt(-1), vals) + require.Error(t, err) + require.Contains(t, err.Error(), "negative") +} + +// TestTestKeeperWithParams verifies that testKeeperWithParams sets params and they can be read back. +func TestTestKeeperWithParams(t *testing.T) { + ctx, k := testKeeperWithParams(t, "50", "100") + params, err := k.GetParams(ctx) + require.NoError(t, err) + require.Equal(t, uint32(50), params.RebalanceThresholdBp) + require.True(t, params.MaxMovePerOp.Equal(math.NewInt(100))) +} + +// --------------------------------------------------------------------------- +// 3.2 PickBestRedelegation +// --------------------------------------------------------------------------- + +// helper to build sorted keys from deltas +func sortedKeys(deltas map[string]math.Int) []string { + keys := make([]string, 0, len(deltas)) + for k := range deltas { + keys = append(keys, k) + } + sort.Strings(keys) + return keys +} + +// TestPickBestRedelegation_SinglePair verifies a basic src/dst selection without caps. +func TestPickBestRedelegation_SinglePair(t *testing.T) { + k := keeper.Keeper{} + deltas := map[string]math.Int{ + "src": math.NewInt(-100), + "dst": math.NewInt(50), + } + keys := sortedKeys(deltas) + blocked := make(map[string]map[string]struct{}) + maxMove := math.ZeroInt() // no cap + + src, dst, amt, ok := k.PickBestRedelegation(deltas, keys, blocked, maxMove) + require.True(t, ok) + require.Equal(t, "src", src) + require.Equal(t, "dst", dst) + require.True(t, amt.Equal(math.NewInt(50))) +} + +// TestPickBestRedelegation_MaxMoveCap ensures MaxMovePerOp cap is applied. +func TestPickBestRedelegation_MaxMoveCap(t *testing.T) { + k := keeper.Keeper{} + deltas := map[string]math.Int{ + "src": math.NewInt(-100), + "dst": math.NewInt(50), + } + keys := sortedKeys(deltas) + blocked := make(map[string]map[string]struct{}) + maxMove := math.NewInt(10) + + _, _, amt, ok := k.PickBestRedelegation(deltas, keys, blocked, maxMove) + require.True(t, ok) + require.True(t, amt.Equal(math.NewInt(10))) +} + +// TestPickBestRedelegation_MaxMoveZeroMeansNoCap verifies maxMove=0 does not cap moves. +func TestPickBestRedelegation_MaxMoveZeroMeansNoCap(t *testing.T) { + k := keeper.Keeper{} + deltas := map[string]math.Int{ + "src": math.NewInt(-30), + "dst": math.NewInt(100), + } + keys := sortedKeys(deltas) + blocked := make(map[string]map[string]struct{}) + maxMove := math.ZeroInt() + + _, _, amt, ok := k.PickBestRedelegation(deltas, keys, blocked, maxMove) + require.True(t, ok) + // min(|-30|, 100) = 30 since there is no cap + require.True(t, amt.Equal(math.NewInt(30))) +} + +// TestPickBestRedelegation_BlockedPair skips blocked src/dst pairs. +func TestPickBestRedelegation_BlockedPair(t *testing.T) { + k := keeper.Keeper{} + deltas := map[string]math.Int{ + "src": math.NewInt(-40), + "dst": math.NewInt(40), + } + keys := sortedKeys(deltas) + + // Block the only possible pair. + blocked := map[string]map[string]struct{}{ + "src": {"dst": {}}, + } + maxMove := math.ZeroInt() + + _, _, _, ok := k.PickBestRedelegation(deltas, keys, blocked, maxMove) + require.False(t, ok) +} + +// TestPickBestRedelegation_TieBreak ensures lexicographic tie-break on (src,dst). +func TestPickBestRedelegation_TieBreak(t *testing.T) { + k := keeper.Keeper{} + deltas := map[string]math.Int{ + "a": math.NewInt(-10), + "b": math.NewInt(-10), + "c": math.NewInt(10), + "d": math.NewInt(10), + } + keys := sortedKeys(deltas) + blocked := make(map[string]map[string]struct{}) + maxMove := math.ZeroInt() + + src, dst, amt, ok := k.PickBestRedelegation(deltas, keys, blocked, maxMove) + require.True(t, ok) + // All valid moves have amount 10; lexicographically smallest (src,dst) is ("a","c"). + require.Equal(t, "a", src) + require.Equal(t, "c", dst) + require.True(t, amt.Equal(math.NewInt(10))) +} + +// TestPickBestRedelegation_NoSourceOrDest tests cases where no move is possible. +func TestPickBestRedelegation_NoSourceOrDest(t *testing.T) { + k := keeper.Keeper{} + + // All zero deltas. + deltasAllZero := map[string]math.Int{ + "a": math.ZeroInt(), + "b": math.ZeroInt(), + } + keys := sortedKeys(deltasAllZero) + blocked := make(map[string]map[string]struct{}) + + _, _, _, ok := k.PickBestRedelegation(deltasAllZero, keys, blocked, math.ZeroInt()) + require.False(t, ok) + + // All positive deltas (no overweight src). + deltasAllPositive := map[string]math.Int{ + "a": math.NewInt(10), + "b": math.NewInt(5), + } + keys = sortedKeys(deltasAllPositive) + _, _, _, ok = k.PickBestRedelegation(deltasAllPositive, keys, blocked, math.ZeroInt()) + require.False(t, ok) + + // All negative deltas (no underweight dst). + deltasAllNegative := map[string]math.Int{ + "a": math.NewInt(-10), + "b": math.NewInt(-5), + } + keys = sortedKeys(deltasAllNegative) + _, _, _, ok = k.PickBestRedelegation(deltasAllNegative, keys, blocked, math.ZeroInt()) + require.False(t, ok) +} + +// TestPickBestRedelegation_MultipleValidators picks the move with largest amount. +func TestPickBestRedelegation_MultipleValidators(t *testing.T) { + k := keeper.Keeper{} + deltas := map[string]math.Int{ + "src1": math.NewInt(-100), + "src2": math.NewInt(-20), + "dst1": math.NewInt(50), + "dst2": math.NewInt(60), + } + keys := sortedKeys(deltas) + blocked := make(map[string]map[string]struct{}) + maxMove := math.NewInt(1000) // effectively no cap + + src, dst, amt, ok := k.PickBestRedelegation(deltas, keys, blocked, maxMove) + require.True(t, ok) + // Best move is from src1 (overweight 100) to dst2 (underweight 60): amount 60. + require.Equal(t, "src1", src) + require.Equal(t, "dst2", dst) + require.True(t, amt.Equal(math.NewInt(60))) +} + +// --------------------------------------------------------------------------- +// 3.3 ComputeDeltas +// --------------------------------------------------------------------------- + +// TestComputeDeltas_Basic: target A=100 B=100, current A=120 B=80, totalStake=200; 50 bp threshold = 1. +func TestComputeDeltas_Basic(t *testing.T) { + ctx, k := testKeeperWithParams(t, "50", "0") + target := map[string]math.Int{"A": math.NewInt(100), "B": math.NewInt(100)} + current := map[string]math.Int{"A": math.NewInt(120), "B": math.NewInt(80)} + totalStake := math.NewInt(200) + + deltas, err := k.ComputeDeltas(ctx, target, current, totalStake) + require.NoError(t, err) + require.Len(t, deltas, 2) + // delta = target - current: A = -20, B = +20. Threshold 200*50/10000 = 1; both |delta| >= 1. + require.True(t, deltas["A"].Equal(math.NewInt(-20))) + require.True(t, deltas["B"].Equal(math.NewInt(20))) +} + +// TestComputeDeltas_BelowThreshold: same target/current, high RebalanceThresholdBP so threshold > 20. +func TestComputeDeltas_BelowThreshold(t *testing.T) { + ctx, k := testKeeperWithParams(t, "1500", "0") // 15% -> threshold 200*1500/10000 = 30 + target := map[string]math.Int{"A": math.NewInt(100), "B": math.NewInt(100)} + current := map[string]math.Int{"A": math.NewInt(120), "B": math.NewInt(80)} + totalStake := math.NewInt(200) + + deltas, err := k.ComputeDeltas(ctx, target, current, totalStake) + require.NoError(t, err) + require.Len(t, deltas, 2) + // |delta| 20 < threshold 30 -> both zeroed. + require.True(t, deltas["A"].Equal(math.ZeroInt())) + require.True(t, deltas["B"].Equal(math.ZeroInt())) +} + +// TestComputeDeltas_UnionOfKeys: validator only in target or only in current; all keys present. +func TestComputeDeltas_UnionOfKeys(t *testing.T) { + ctx, k := testKeeperWithParams(t, "50", "0") + target := map[string]math.Int{"A": math.NewInt(100), "B": math.NewInt(100)} + current := map[string]math.Int{"A": math.NewInt(50), "C": math.NewInt(50)} + totalStake := math.NewInt(200) + + deltas, err := k.ComputeDeltas(ctx, target, current, totalStake) + require.NoError(t, err) + require.Len(t, deltas, 3) + // A: 100-50=50; B: 100-0=100; C: 0-50=-50. Threshold 1; all non-zero. + require.True(t, deltas["A"].Equal(math.NewInt(50))) + require.True(t, deltas["B"].Equal(math.NewInt(100))) + require.True(t, deltas["C"].Equal(math.NewInt(-50))) +} + +// TestComputeDeltas_TotalStakeZero: threshold = 0; deltas are not zeroed by threshold. +func TestComputeDeltas_TotalStakeZero(t *testing.T) { + ctx, k := testKeeperWithParams(t, "50", "0") + target := map[string]math.Int{"A": math.NewInt(0), "B": math.NewInt(0)} + current := map[string]math.Int{"A": math.NewInt(0), "B": math.NewInt(0)} + totalStake := math.ZeroInt() + + deltas, err := k.ComputeDeltas(ctx, target, current, totalStake) + require.NoError(t, err) + require.Len(t, deltas, 2) + // threshold = 0; delta A = 0, B = 0 (and 0 is not < 0, so they stay 0). + require.True(t, deltas["A"].Equal(math.ZeroInt())) + require.True(t, deltas["B"].Equal(math.ZeroInt())) +} + +// --------------------------------------------------------------------------- +// 3.4 PickResidualUndelegation +// --------------------------------------------------------------------------- + +// TestPickResidualUndelegation_SingleOverweight: one overweight; maxMove=0 -> full amount, maxMove=10 -> capped. +func TestPickResidualUndelegation_SingleOverweight(t *testing.T) { + deltas := map[string]math.Int{"val": math.NewInt(-100)} + + // maxMove=0 means no cap -> amt = 100 + ctx, k := testKeeperWithParams(t, "50", "0") + val, amt, ok, err := k.PickResidualUndelegation(ctx, deltas) + require.NoError(t, err) + require.True(t, ok) + require.Equal(t, "val", val) + require.True(t, amt.Equal(math.NewInt(100))) + + // maxMove=10 -> amt = 10 + ctx, k = testKeeperWithParams(t, "50", "10") + val, amt, ok, err = k.PickResidualUndelegation(ctx, deltas) + require.NoError(t, err) + require.True(t, ok) + require.Equal(t, "val", val) + require.True(t, amt.Equal(math.NewInt(10))) +} + +// TestPickResidualUndelegation_LargestWins: two overweight; validator with -100 chosen, amount = min(100, maxMove). +func TestPickResidualUndelegation_LargestWins(t *testing.T) { + deltas := map[string]math.Int{ + "valA": math.NewInt(-50), + "valB": math.NewInt(-100), + } + ctx, k := testKeeperWithParams(t, "50", "0") + + val, amt, ok, err := k.PickResidualUndelegation(ctx, deltas) + require.NoError(t, err) + require.True(t, ok) + require.Equal(t, "valB", val) + require.True(t, amt.Equal(math.NewInt(100))) + + // With maxMove=30, amount should be 30 + ctx, k = testKeeperWithParams(t, "50", "30") + _, amt, ok, err = k.PickResidualUndelegation(ctx, deltas) + require.NoError(t, err) + require.True(t, ok) + require.True(t, amt.Equal(math.NewInt(30))) +} + +// TestPickResidualUndelegation_TieBreak: two same negative delta; lexicographically smaller validator chosen. +func TestPickResidualUndelegation_TieBreak(t *testing.T) { + deltas := map[string]math.Int{ + "zebra": math.NewInt(-20), + "alpha": math.NewInt(-20), + } + ctx, k := testKeeperWithParams(t, "50", "0") + + val, amt, ok, err := k.PickResidualUndelegation(ctx, deltas) + require.NoError(t, err) + require.True(t, ok) + require.Equal(t, "alpha", val) + require.True(t, amt.Equal(math.NewInt(20))) +} + +// TestPickResidualUndelegation_NoOverweight: all deltas >= 0 -> ok false. +func TestPickResidualUndelegation_NoOverweight(t *testing.T) { + deltas := map[string]math.Int{ + "a": math.NewInt(10), + "b": math.NewInt(5), + } + ctx, k := testKeeperWithParams(t, "50", "0") + + _, _, ok, err := k.PickResidualUndelegation(ctx, deltas) + require.NoError(t, err) + require.False(t, ok) +} + +// TestPickResidualUndelegation_ZeroDelta: validator with 0 should not be chosen. +func TestPickResidualUndelegation_ZeroDelta(t *testing.T) { + deltas := map[string]math.Int{ + "val": math.ZeroInt(), + } + ctx, k := testKeeperWithParams(t, "50", "0") + + _, _, ok, err := k.PickResidualUndelegation(ctx, deltas) + require.NoError(t, err) + require.False(t, ok) +} diff --git a/x/poolrebalancer/keeper/redelegation_test.go b/x/poolrebalancer/keeper/redelegation_test.go new file mode 100644 index 00000000..65d58142 --- /dev/null +++ b/x/poolrebalancer/keeper/redelegation_test.go @@ -0,0 +1,85 @@ +package keeper + +import ( + "bytes" + "testing" + "time" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/evm/x/poolrebalancer/types" +) + +func TestHasImmatureRedelegationTo_BlocksSrcWhenDstHasIncoming(t *testing.T) { + ctx, k := newTestKeeper(t) + + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + srcVal := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + dstVal := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + denom := "stake" + + entry := types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcVal.String(), + DstValidatorAddress: dstVal.String(), + Amount: sdk.NewCoin(denom, math.NewInt(100)), + CompletionTime: ctx.BlockTime().Add(time.Hour), + } + require.NoError(t, k.SetPendingRedelegation(ctx, entry)) + + require.True(t, k.HasImmatureRedelegationTo(ctx, del, dstVal, denom)) + + otherVal := sdk.ValAddress(bytes.Repeat([]byte{4}, 20)) + require.False(t, k.HasImmatureRedelegationTo(ctx, del, otherVal, denom)) +} + +func TestCompletePendingRedelegations_RemovesPrimaryIndexAndQueue(t *testing.T) { + ctx, k := newTestKeeper(t) + + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + srcVal := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + dstVal := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + denom := "stake" + + completion := ctx.BlockTime().Add(-time.Second) + coin := sdk.NewCoin(denom, math.NewInt(10)) + entry := types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcVal.String(), + DstValidatorAddress: dstVal.String(), + Amount: coin, + CompletionTime: completion, + } + require.NoError(t, k.SetPendingRedelegation(ctx, entry)) + + primaryKey := types.GetPendingRedelegationKey(del, denom, dstVal, completion) + indexKey := types.GetPendingRedelegationBySrcIndexKey(srcVal, completion, denom, dstVal, del) + queueKey := types.GetPendingRedelegationQueueKey(completion) + + store := k.storeService.OpenKVStore(ctx) + bz, err := store.Get(primaryKey) + require.NoError(t, err) + require.NotNil(t, bz) + + require.NoError(t, k.CompletePendingRedelegations(ctx)) + + bz, err = store.Get(primaryKey) + require.NoError(t, err) + require.Nil(t, bz) + + bz, err = store.Get(indexKey) + require.NoError(t, err) + require.Nil(t, bz) + + bz, err = store.Get(queueKey) + require.NoError(t, err) + require.Nil(t, bz) + + // Idempotency: running again should not error. + require.NoError(t, k.CompletePendingRedelegations(ctx)) +} diff --git a/x/poolrebalancer/keeper/test_helpers_test.go b/x/poolrebalancer/keeper/test_helpers_test.go new file mode 100644 index 00000000..ffe89d1f --- /dev/null +++ b/x/poolrebalancer/keeper/test_helpers_test.go @@ -0,0 +1,32 @@ +package keeper + +import ( + "bytes" + "testing" + + storetypes "cosmossdk.io/store/types" + + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + + "github.com/cosmos/evm/x/poolrebalancer/types" +) + +func newTestKeeper(t *testing.T) (sdk.Context, Keeper) { + t.Helper() + + storeKey := storetypes.NewKVStoreKey(types.ModuleName) + tKey := storetypes.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + + storeService := runtime.NewKVStoreService(storeKey) + cdc := moduletestutil.MakeTestEncodingConfig().Codec + stakingKeeper := &stakingkeeper.Keeper{} // zero value; do not call staking methods in unit tests + + authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) + k := NewKeeper(cdc, storeService, stakingKeeper, authority) + return ctx, k +} diff --git a/x/poolrebalancer/keeper/undelegation_test.go b/x/poolrebalancer/keeper/undelegation_test.go new file mode 100644 index 00000000..d12fcb13 --- /dev/null +++ b/x/poolrebalancer/keeper/undelegation_test.go @@ -0,0 +1,54 @@ +package keeper + +import ( + "bytes" + "testing" + "time" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/evm/x/poolrebalancer/types" +) + +func TestCompletePendingUndelegations_RemovesQueueAndIndex(t *testing.T) { + ctx, k := newTestKeeper(t) + + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + val := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + denom := "stake" + + completion := ctx.BlockTime().Add(-time.Second) + coin := sdk.NewCoin(denom, math.NewInt(123)) + entry := types.PendingUndelegation{ + DelegatorAddress: del.String(), + ValidatorAddress: val.String(), + Balance: coin, + CompletionTime: completion, + } + require.NoError(t, k.SetPendingUndelegation(ctx, entry)) + + queueKey := types.GetPendingUndelegationQueueKey(completion, del) + indexKey := types.GetPendingUndelegationByValIndexKey(val, completion, denom, del) + + store := k.storeService.OpenKVStore(ctx) + bz, err := store.Get(queueKey) + require.NoError(t, err) + require.NotNil(t, bz) + + require.NoError(t, k.CompletePendingUndelegations(ctx)) + + bz, err = store.Get(queueKey) + require.NoError(t, err) + require.Nil(t, bz) + + bz, err = store.Get(indexKey) + require.NoError(t, err) + require.Nil(t, bz) + + // Idempotency. + require.NoError(t, k.CompletePendingUndelegations(ctx)) +} From 89692e6c2396ab8f3e704988f8dddd0dc3847f67 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 18 Mar 2026 22:43:18 +0530 Subject: [PATCH 06/31] fix(poolrebalancer): fetch all delegations when computing delegator stake Signed-off-by: Nikhil Sharma --- x/poolrebalancer/keeper/rebalance.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/poolrebalancer/keeper/rebalance.go b/x/poolrebalancer/keeper/rebalance.go index 9d725ae5..3d188c53 100644 --- a/x/poolrebalancer/keeper/rebalance.go +++ b/x/poolrebalancer/keeper/rebalance.go @@ -45,8 +45,7 @@ func (k Keeper) GetTargetBondedValidators(ctx context.Context) ([]sdk.ValAddress // GetDelegatorStakeByValidator returns the delegator's bonded stake per validator (in tokens, truncated). // The returned map is keyed by validator operator address (bech32), plus the total across all validators. func (k Keeper) GetDelegatorStakeByValidator(ctx context.Context, del sdk.AccAddress) (map[string]math.Int, math.Int, error) { - // 0 = no limit (retrieve all) - delegations, err := k.stakingKeeper.GetDelegatorDelegations(ctx, del, 0) + delegations, err := k.stakingKeeper.GetDelegatorDelegations(ctx, del, ^uint16(0)) if err != nil { return nil, math.ZeroInt(), err } From bd9c63e7e958eea3bc63de6eccd2744fe829a7ed Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 18 Mar 2026 23:13:57 +0530 Subject: [PATCH 07/31] test(poolrebalancer): add rebalance localnet E2E and harden localnet startup Signed-off-by: Nikhil Sharma --- multi_node_startup.sh | 19 +- .../poolrebalancer_rebalance_e2e.sh | 363 ++++++++++++++++++ 2 files changed, 379 insertions(+), 3 deletions(-) create mode 100755 scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh diff --git a/multi_node_startup.sh b/multi_node_startup.sh index 211c84c4..fcd3b59b 100755 --- a/multi_node_startup.sh +++ b/multi_node_startup.sh @@ -12,9 +12,9 @@ NODE_NUMBER="${NODE_NUMBER:-}" START_VALIDATOR="${START_VALIDATOR:-false}" GENERATE_GENESIS="${GENERATE_GENESIS:-false}" -VAL0_MNEMONIC="" -VAL1_MNEMONIC="" -VAL2_MNEMONIC="" +VAL0_MNEMONIC="${VAL0_MNEMONIC:-}" +VAL1_MNEMONIC="${VAL1_MNEMONIC:-}" +VAL2_MNEMONIC="${VAL2_MNEMONIC:-}" get_p2p_port() { echo $((26656 + ($1 * 100))); } get_rpc_port() { echo $((26657 + ($1 * 100))); } @@ -94,6 +94,11 @@ apply_config_customizations() { local RPC_PORT=$(get_rpc_port $NODE_NUM) local GRPC_PORT=$(get_grpc_port $NODE_NUM) local JSONRPC_PORT=$(get_jsonrpc_port $NODE_NUM) + local PROM_PORT=$((26660 + NODE_NUM)) + local PPROF_PORT=$((6060 + NODE_NUM)) + local WS_PORT=$((8546 + NODE_NUM)) + local GETH_METRICS_PORT=$((8100 + NODE_NUM)) + local EVM_METRICS_PORT=$((6065 + NODE_NUM)) sed -i.bak 's/timeout_propose = "3s"/timeout_propose = "2s"/g' "$CONFIG_TOML" sed -i.bak 's/timeout_propose_delta = "500ms"/timeout_propose_delta = "200ms"/g' "$CONFIG_TOML" @@ -108,6 +113,10 @@ apply_config_customizations() { sed -i.bak "s|laddr = \"tcp://0.0.0.0:26656\"|laddr = \"tcp://0.0.0.0:${P2P_PORT}\"|g" "$CONFIG_TOML" sed -i.bak 's/prometheus = false/prometheus = true/' "$CONFIG_TOML" + sed -i.bak 's/addr_book_strict = true/addr_book_strict = false/' "$CONFIG_TOML" + sed -i.bak 's/allow_duplicate_ip = false/allow_duplicate_ip = true/' "$CONFIG_TOML" + sed -i.bak "s|prometheus_listen_addr = \":26660\"|prometheus_listen_addr = \":${PROM_PORT}\"|g" "$CONFIG_TOML" + sed -i.bak "s|pprof_laddr = \"localhost:6060\"|pprof_laddr = \"localhost:${PPROF_PORT}\"|g" "$CONFIG_TOML" sed -i.bak 's/prometheus-retention-time = "0"/prometheus-retention-time = "1000000000000"/g' "$APP_TOML" sed -i.bak 's/enabled = false/enabled = true/g' "$APP_TOML" sed -i.bak 's/enable = false/enable = true/g' "$APP_TOML" @@ -119,6 +128,10 @@ apply_config_customizations() { sed -i.bak "s|address = \"127.0.0.1:8545\"|address = \"0.0.0.0:${JSONRPC_PORT}\"|g" "$APP_TOML" sed -i.bak "s|address = \"0.0.0.0:8545\"|address = \"0.0.0.0:${JSONRPC_PORT}\"|g" "$APP_TOML" + sed -i.bak "s|geth-metrics-address = \"127.0.0.1:8100\"|geth-metrics-address = \"127.0.0.1:${GETH_METRICS_PORT}\"|g" "$APP_TOML" + sed -i.bak "s|ws-address = \"127.0.0.1:8546\"|ws-address = \"127.0.0.1:${WS_PORT}\"|g" "$APP_TOML" + sed -i.bak "s|metrics-address = \"127.0.0.1:6065\"|metrics-address = \"127.0.0.1:${EVM_METRICS_PORT}\"|g" "$APP_TOML" + rm -f "$CONFIG_TOML.bak" "$APP_TOML.bak" } diff --git a/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh b/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh new file mode 100755 index 00000000..731ea978 --- /dev/null +++ b/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh @@ -0,0 +1,363 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +BASEDIR="${BASEDIR:-"$HOME/.og-evm-devnet"}" +NODE_RPC="${NODE_RPC:-"tcp://127.0.0.1:26657"}" +CHAIN_ID="${CHAIN_ID:-10740}" +KEYRING="${KEYRING:-test}" +HOME0="$BASEDIR/val0" + +# ---- Test knobs (override via env) ---- +POOLREBALANCER_MAX_TARGET_VALIDATORS="${POOLREBALANCER_MAX_TARGET_VALIDATORS:-3}" +POOLREBALANCER_THRESHOLD_BP="${POOLREBALANCER_THRESHOLD_BP:-1}" +POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-1}" +POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-1000000000000000000}" # 1e18 +POOLREBALANCER_USE_UNDELEGATE_FALLBACK="${POOLREBALANCER_USE_UNDELEGATE_FALLBACK:-true}" + +# staking params for making undelegation fallback observable +STAKING_UNBONDING_TIME="${STAKING_UNBONDING_TIME:-30s}" +STAKING_MAX_ENTRIES="${STAKING_MAX_ENTRIES:-100}" + +TX_FEES="${TX_FEES:-200000000000000ogwei}" # denom will be rewritten after chain start + +# Delegation imbalance amounts (safe under default funding of 1e24 ogwei). +IMBALANCE_MAIN_DELEGATION="${IMBALANCE_MAIN_DELEGATION:-200000000000000000000000ogwei}" # denom rewritten after chain start +IMBALANCE_MINOR_DELEGATION="${IMBALANCE_MINOR_DELEGATION:-100ogwei}" + +POLL_SAMPLES="${POLL_SAMPLES:-25}" +POLL_SLEEP_SECS="${POLL_SLEEP_SECS:-2}" + +usage() { + cat </dev/null 2>&1 || { echo "missing dependency: $1" >&2; exit 1; } +} + +stop_nodes() { + # Be aggressive: localnet nodes are started via `evmd start ...` by multi_node_startup.sh. + pkill -f "evmd start" >/dev/null 2>&1 || true + pkill -f "multi_node_startup.sh" >/dev/null 2>&1 || true + # give the OS a moment to release ports + sleep 1 +} + +wait_for_height() { + local timeout_secs="${1:-30}" + local start + start="$(date +%s)" + while true; do + local h + h="$(curl -sS --max-time 1 http://127.0.0.1:26657/status 2>/dev/null | jq -r '.result.sync_info.latest_block_height' 2>/dev/null || echo 0)" + if [[ "$h" != "0" ]]; then + echo "$h" + return 0 + fi + if (( $(date +%s) - start > timeout_secs )); then + echo "timed out waiting for height > 0" >&2 + return 1 + fi + sleep 1 + done +} + +dev0_address_from_file() { + awk '/^dev0:/{f=1} f && $1=="address:"{print $2; exit}' "$BASEDIR/dev_accounts.txt" +} + +dev0_mnemonic_from_file() { + awk '/^dev0:/{f=1} f && $1=="mnemonic:"{for(i=2;i<=NF;i++){printf (i==2?"":" ") $i} print ""; exit}' "$BASEDIR/dev_accounts.txt" +} + +patch_genesis_poolrebalancer_params() { + local del_addr="$1" + local gen0="$BASEDIR/val0/config/genesis.json" + local tmp="$BASEDIR/val0/config/genesis.tmp.json" + + jq --arg del "$del_addr" \ + --argjson maxTargets "$POOLREBALANCER_MAX_TARGET_VALIDATORS" \ + --argjson thr "$POOLREBALANCER_THRESHOLD_BP" \ + --argjson maxOps "$POOLREBALANCER_MAX_OPS_PER_BLOCK" \ + --arg maxMove "$POOLREBALANCER_MAX_MOVE_PER_OP" \ + --argjson useUndel "$POOLREBALANCER_USE_UNDELEGATE_FALLBACK" \ + ' .app_state.poolrebalancer.params.pool_delegator_address = $del + | .app_state.poolrebalancer.params.max_target_validators = $maxTargets + | .app_state.poolrebalancer.params.rebalance_threshold_bp = $thr + | .app_state.poolrebalancer.params.max_ops_per_block = $maxOps + | .app_state.poolrebalancer.params.max_move_per_op = $maxMove + | .app_state.poolrebalancer.params.use_undelegate_fallback = $useUndel + ' "$gen0" > "$tmp" + + mv "$tmp" "$gen0" + cp "$gen0" "$BASEDIR/val1/config/genesis.json" + cp "$gen0" "$BASEDIR/val2/config/genesis.json" + + evmd genesis validate-genesis --home "$BASEDIR/val0" >/dev/null +} + +patch_genesis_staking_params() { + local gen0="$BASEDIR/val0/config/genesis.json" + local tmp="$BASEDIR/val0/config/genesis.tmp.json" + + jq --arg unbond "$STAKING_UNBONDING_TIME" \ + --argjson maxEntries "$STAKING_MAX_ENTRIES" \ + ' .app_state.staking.params.unbonding_time = $unbond + | .app_state.staking.params.max_entries = $maxEntries + ' "$gen0" > "$tmp" + + mv "$tmp" "$gen0" +} + +import_dev0_key() { + local mnemonic="$1" + (evmd keys delete dev0 -y --keyring-backend "$KEYRING" --home "$HOME0" >/dev/null 2>&1) || true + echo "$mnemonic" | evmd keys add dev0 --recover --keyring-backend "$KEYRING" --home "$HOME0" >/dev/null +} + +wait_tx_included() { + local txhash="$1" + # Prefer CometBFT RPC /tx?hash=0x... which becomes available on commit. + local rpc_http="http://127.0.0.1:26657" + for _ in $(seq 1 40); do + local resp + resp="$(curl -sS --max-time 1 "${rpc_http}/tx?hash=0x${txhash}" 2>/dev/null || true)" + # When not found yet, CometBFT returns an error JSON (still non-empty). Only treat it as committed + # once it has a .result.tx_result object. + if echo "$resp" | jq -e '.result.tx_result' >/dev/null 2>&1; then + # Ensure the tx succeeded (code=0). A failed tx can still be committed and show up in /tx. + local code + code="$(echo "$resp" | jq -r '.result.tx_result.code' 2>/dev/null || echo 1)" + if [[ "$code" == "0" ]]; then + return 0 + fi + echo "tx committed but failed (code=$code): $txhash" >&2 + echo "$resp" | jq -r '.result.tx_result.log' >&2 || true + return 1 + fi + # Fallback to the app query path (may require indexing to be enabled). + if evmd query tx "$txhash" --node "$NODE_RPC" -o json >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + echo "tx not found after waiting: $txhash" >&2 + echo "check logs: $BASEDIR/logs/val0.log" >&2 + return 1 +} + +delegate_with_wait() { + local valoper="$1" + local amount="$2" + # Some CLI versions return txhash even when CheckTx fails. Always check `.code`. + for attempt in 1 2 3; do + local out + out="$(evmd tx staking delegate "$valoper" "$amount" \ + --from dev0 \ + --keyring-backend "$KEYRING" \ + --home "$HOME0" \ + --chain-id "$CHAIN_ID" \ + --node "$NODE_RPC" \ + --gas auto --gas-adjustment 1.3 \ + --fees "$TX_FEES" \ + -b sync -y -o json)" + + local code + code="$(echo "$out" | jq -r '.code // 0')" + local txhash + txhash="$(echo "$out" | jq -r '.txhash')" + + if [[ "$code" != "0" ]]; then + local log + log="$(echo "$out" | jq -r '.raw_log // .log // empty')" + echo "delegate failed (attempt=$attempt code=$code): $log" >&2 + + # Common transient: sequence mismatch if previous tx hasn't fully propagated. + if echo "$log" | grep -qi "account sequence mismatch"; then + sleep 2 + continue + fi + return 1 + fi + + echo "delegate $amount -> $valoper txhash=$txhash" + wait_tx_included "$txhash" >/dev/null + return 0 + done + + echo "delegate failed after retries: $amount -> $valoper" >&2 + return 1 +} + +assert_pending_invariants() { + local json="$1" + local cap="$2" + + local badAmt + badAmt="$(echo "$json" | jq -r --argjson cap "$cap" '[.redelegations[] | (.amount.amount|tonumber) > $cap] | any')" + if [[ "$badAmt" != "false" ]]; then + echo "FAIL: found pending amount > max_move_per_op" >&2 + return 1 + fi + + # Transitive safety: no src is also a dst among in-flight entries. + local badTrans + badTrans="$(echo "$json" | jq -r '([.redelegations[].src_validator_address] | unique) as $srcs | ([.redelegations[].dst_validator_address] | unique) as $dsts | ([ $srcs[] | . as $s | (($dsts | index($s)) != null) ] | any)')" + if [[ "$badTrans" != "false" ]]; then + echo "FAIL: transitive safety violated (src appears in dst set)" >&2 + return 1 + fi +} + +main() { + if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then + usage; exit 0 + fi + + require_bin jq + require_bin curl + require_bin evmd + + if [[ -z "${VAL0_MNEMONIC:-}" || -z "${VAL1_MNEMONIC:-}" || -z "${VAL2_MNEMONIC:-}" ]]; then + echo "VAL0_MNEMONIC/VAL1_MNEMONIC/VAL2_MNEMONIC must be set" >&2 + exit 1 + fi + + echo "==> Stopping any existing localnet" + stop_nodes + + echo "==> Generating genesis (3 validators) at $BASEDIR" + # multi_node_startup.sh prints a lot of init output; silence both stdout/stderr + (cd "$ROOT_DIR" && GENERATE_GENESIS=true ./multi_node_startup.sh -y >/dev/null 2>&1) + + local del_addr + del_addr="$(dev0_address_from_file)" + local del_mnemonic + del_mnemonic="$(dev0_mnemonic_from_file)" + + echo "==> Pool delegator (dev0) = $del_addr" + echo "==> Patching genesis staking params (unbonding_time + max_entries)" + patch_genesis_staking_params + echo "==> Patching genesis poolrebalancer params" + patch_genesis_poolrebalancer_params "$del_addr" + + echo "==> Starting validators" + mkdir -p "$BASEDIR/logs" + (cd "$ROOT_DIR" && START_VALIDATOR=true NODE_NUMBER=0 ./multi_node_startup.sh >"$BASEDIR/logs/val0.log" 2>&1 &) + (cd "$ROOT_DIR" && START_VALIDATOR=true NODE_NUMBER=1 ./multi_node_startup.sh >"$BASEDIR/logs/val1.log" 2>&1 &) + (cd "$ROOT_DIR" && START_VALIDATOR=true NODE_NUMBER=2 ./multi_node_startup.sh >"$BASEDIR/logs/val2.log" 2>&1 &) + + echo "==> Waiting for block production" + local h + h="$(wait_for_height 60)" + echo "height=$h" + + # Discover bond denom for this chain and rewrite denom-bearing knobs to match. + local bond_denom + bond_denom="$(evmd query staking params --node "$NODE_RPC" -o json | jq -r '.params.bond_denom // .bond_denom')" + if [[ -z "$bond_denom" || "$bond_denom" == "null" ]]; then + echo "FAIL: could not determine bond_denom from staking params" >&2 + exit 1 + fi + echo "bond_denom=$bond_denom" + TX_FEES="${TX_FEES%ogwei}${bond_denom}" + IMBALANCE_MAIN_DELEGATION="${IMBALANCE_MAIN_DELEGATION%ogwei}${bond_denom}" + IMBALANCE_MINOR_DELEGATION="${IMBALANCE_MINOR_DELEGATION%ogwei}${bond_denom}" + + echo "==> Importing dev0 key into keyring" + import_dev0_key "$del_mnemonic" + + echo "==> Creating delegation imbalance" + local vals v0 v1 v2 + vals="$(evmd query staking validators --node "$NODE_RPC" -o json | jq -r '.validators[:3] | .[] | .operator_address')" + v0="$(echo "$vals" | sed -n '1p')" + v1="$(echo "$vals" | sed -n '2p')" + v2="$(echo "$vals" | sed -n '3p')" + + delegate_with_wait "$v0" "$IMBALANCE_MAIN_DELEGATION" + delegate_with_wait "$v1" "$IMBALANCE_MINOR_DELEGATION" + delegate_with_wait "$v2" "$IMBALANCE_MINOR_DELEGATION" + + echo "==> Sanity checks (params + delegations)" + local onchain_del + onchain_del="$(evmd query poolrebalancer params --node "$NODE_RPC" -o json | jq -r '.params.pool_delegator_address')" + if [[ "$onchain_del" != "$del_addr" ]]; then + echo "FAIL: poolrebalancer params.pool_delegator_address mismatch" >&2 + echo " expected: $del_addr" >&2 + echo " got: $onchain_del" >&2 + exit 1 + fi + + local del_count + del_count="$(evmd query staking delegations "$del_addr" --node "$NODE_RPC" -o json | jq -r '.delegation_responses | length')" + echo "delegations_count=$del_count" + + local bonded_count + bonded_count="$(evmd query staking validators --node "$NODE_RPC" -o json | jq -r '[.validators[] | select(.status=="BOND_STATUS_BONDED")] | length')" + echo "bonded_validators=$bonded_count" + if (( bonded_count == 0 )); then + echo "FAIL: no bonded validators found; cannot rebalance" >&2 + exit 1 + fi + + echo "==> Observing pending redelegations" + for i in $(seq 1 "$POLL_SAMPLES"); do + local height pending + height="$(curl -s http://127.0.0.1:26657/status | jq -r '.result.sync_info.latest_block_height')" + local j + j="$(evmd query poolrebalancer pending-redelegations --node "$NODE_RPC" -o json)" + pending="$(echo "$j" | jq -r '.redelegations | length')" + echo "sample=$i height=$height pending_redelegations=$pending" + + if (( pending > 0 )); then + assert_pending_invariants "$j" "$POOLREBALANCER_MAX_MOVE_PER_OP" + local pendingUndel + pendingUndel="$(evmd query poolrebalancer pending-undelegations --node "$NODE_RPC" -o json | jq -r '.undelegations | length')" + echo "pending_undelegations=$pendingUndel" + echo "PASS: pending redelegations observed and invariants hold" + exit 0 + fi + sleep "$POLL_SLEEP_SECS" + done + + echo "FAIL: did not observe any pending redelegations within polling window" >&2 + echo "Diagnostics:" >&2 + evmd query poolrebalancer params --node "$NODE_RPC" -o json | jq '.' >&2 || true + evmd query staking validators --node "$NODE_RPC" -o json | jq -r '[.validators[] | {op:.operator_address,status:.status}]' >&2 || true + exit 1 +} + +main "$@" + From cc849735957ebcfb9ff9670d43506743e533cc8f Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Thu, 19 Mar 2026 14:06:39 +0530 Subject: [PATCH 08/31] test(poolrebalancer): add integration tests Signed-off-by: Nikhil Sharma --- .../integration/x_poolrebalancer_test.go | 18 +++ .../poolrebalancer_rebalance_e2e.sh | 27 ++-- .../poolrebalancer/test_case_a_scheduling.go | 44 ++++++ .../poolrebalancer/test_case_b_bounded_ops.go | 39 +++++ .../x/poolrebalancer/test_case_c_threshold.go | 72 +++++++++ .../test_case_d_transitive_safety.go | 130 ++++++++++++++++ .../poolrebalancer/test_case_disabled_noop.go | 31 ++++ .../test_case_e_completion_cleanup.go | 57 +++++++ .../test_case_f_undelegate_fallback.go | 74 +++++++++ .../test_case_param_behavior.go | 100 +++++++++++++ .../test_case_update_params_integration.go | 72 +++++++++ .../x/poolrebalancer/test_endblock_helpers.go | 20 +++ .../x/poolrebalancer/test_helpers.go | 111 ++++++++++++++ .../x/poolrebalancer/test_suite.go | 141 ++++++++++++++++++ 14 files changed, 922 insertions(+), 14 deletions(-) create mode 100644 evmd/tests/integration/x_poolrebalancer_test.go create mode 100644 tests/integration/x/poolrebalancer/test_case_a_scheduling.go create mode 100644 tests/integration/x/poolrebalancer/test_case_b_bounded_ops.go create mode 100644 tests/integration/x/poolrebalancer/test_case_c_threshold.go create mode 100644 tests/integration/x/poolrebalancer/test_case_d_transitive_safety.go create mode 100644 tests/integration/x/poolrebalancer/test_case_disabled_noop.go create mode 100644 tests/integration/x/poolrebalancer/test_case_e_completion_cleanup.go create mode 100644 tests/integration/x/poolrebalancer/test_case_f_undelegate_fallback.go create mode 100644 tests/integration/x/poolrebalancer/test_case_param_behavior.go create mode 100644 tests/integration/x/poolrebalancer/test_case_update_params_integration.go create mode 100644 tests/integration/x/poolrebalancer/test_endblock_helpers.go create mode 100644 tests/integration/x/poolrebalancer/test_helpers.go create mode 100644 tests/integration/x/poolrebalancer/test_suite.go diff --git a/evmd/tests/integration/x_poolrebalancer_test.go b/evmd/tests/integration/x_poolrebalancer_test.go new file mode 100644 index 00000000..4a5a4e29 --- /dev/null +++ b/evmd/tests/integration/x_poolrebalancer_test.go @@ -0,0 +1,18 @@ +package integration + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + evm "github.com/cosmos/evm" + testapp "github.com/cosmos/evm/testutil/app" + + poolrebalancer "github.com/cosmos/evm/tests/integration/x/poolrebalancer" +) + +func TestPoolRebalancerKeeperIntegrationTestSuite(t *testing.T) { + create := testapp.ToEvmAppCreator[evm.IntegrationNetworkApp](CreateEvmd, "evm.IntegrationNetworkApp") + s := poolrebalancer.NewKeeperIntegrationTestSuite(create) + suite.Run(t, s) +} diff --git a/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh b/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh index 731ea978..2975ccd8 100755 --- a/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh +++ b/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh @@ -15,13 +15,13 @@ POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-1}" POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-1000000000000000000}" # 1e18 POOLREBALANCER_USE_UNDELEGATE_FALLBACK="${POOLREBALANCER_USE_UNDELEGATE_FALLBACK:-true}" -# staking params for making undelegation fallback observable +# Staking params tuned so maturity/fallback behavior is visible quickly in local runs. STAKING_UNBONDING_TIME="${STAKING_UNBONDING_TIME:-30s}" STAKING_MAX_ENTRIES="${STAKING_MAX_ENTRIES:-100}" TX_FEES="${TX_FEES:-200000000000000ogwei}" # denom will be rewritten after chain start -# Delegation imbalance amounts (safe under default funding of 1e24 ogwei). +# Delegation amounts used to create a clear imbalance (safe with default dev funding). IMBALANCE_MAIN_DELEGATION="${IMBALANCE_MAIN_DELEGATION:-200000000000000000000000ogwei}" # denom rewritten after chain start IMBALANCE_MINOR_DELEGATION="${IMBALANCE_MINOR_DELEGATION:-100ogwei}" @@ -68,10 +68,10 @@ require_bin() { } stop_nodes() { - # Be aggressive: localnet nodes are started via `evmd start ...` by multi_node_startup.sh. + # Aggressive cleanup: multi_node_startup.sh launches `evmd start` processes directly. pkill -f "evmd start" >/dev/null 2>&1 || true pkill -f "multi_node_startup.sh" >/dev/null 2>&1 || true - # give the OS a moment to release ports + # Give the OS a moment to release RPC/P2P ports. sleep 1 } @@ -149,15 +149,14 @@ import_dev0_key() { wait_tx_included() { local txhash="$1" - # Prefer CometBFT RPC /tx?hash=0x... which becomes available on commit. + # First try CometBFT /tx; it becomes available as soon as tx is committed. local rpc_http="http://127.0.0.1:26657" for _ in $(seq 1 40); do local resp resp="$(curl -sS --max-time 1 "${rpc_http}/tx?hash=0x${txhash}" 2>/dev/null || true)" - # When not found yet, CometBFT returns an error JSON (still non-empty). Only treat it as committed - # once it has a .result.tx_result object. + # Not-found still returns JSON. Treat as committed only when .result.tx_result exists. if echo "$resp" | jq -e '.result.tx_result' >/dev/null 2>&1; then - # Ensure the tx succeeded (code=0). A failed tx can still be committed and show up in /tx. + # Committed does not mean successful; require code=0. local code code="$(echo "$resp" | jq -r '.result.tx_result.code' 2>/dev/null || echo 1)" if [[ "$code" == "0" ]]; then @@ -167,7 +166,7 @@ wait_tx_included() { echo "$resp" | jq -r '.result.tx_result.log' >&2 || true return 1 fi - # Fallback to the app query path (may require indexing to be enabled). + # Fallback query path (depends on tx indexing config). if evmd query tx "$txhash" --node "$NODE_RPC" -o json >/dev/null 2>&1; then return 0 fi @@ -181,7 +180,7 @@ wait_tx_included() { delegate_with_wait() { local valoper="$1" local amount="$2" - # Some CLI versions return txhash even when CheckTx fails. Always check `.code`. + # Some CLI builds return txhash even on CheckTx failure, so always inspect `.code`. for attempt in 1 2 3; do local out out="$(evmd tx staking delegate "$valoper" "$amount" \ @@ -204,7 +203,7 @@ delegate_with_wait() { log="$(echo "$out" | jq -r '.raw_log // .log // empty')" echo "delegate failed (attempt=$attempt code=$code): $log" >&2 - # Common transient: sequence mismatch if previous tx hasn't fully propagated. + # Common transient: sequence mismatch while previous tx is still propagating. if echo "$log" | grep -qi "account sequence mismatch"; then sleep 2 continue @@ -232,7 +231,7 @@ assert_pending_invariants() { return 1 fi - # Transitive safety: no src is also a dst among in-flight entries. + # Transitive safety: no source validator should also appear as destination in-flight. local badTrans badTrans="$(echo "$json" | jq -r '([.redelegations[].src_validator_address] | unique) as $srcs | ([.redelegations[].dst_validator_address] | unique) as $dsts | ([ $srcs[] | . as $s | (($dsts | index($s)) != null) ] | any)')" if [[ "$badTrans" != "false" ]]; then @@ -259,7 +258,7 @@ main() { stop_nodes echo "==> Generating genesis (3 validators) at $BASEDIR" - # multi_node_startup.sh prints a lot of init output; silence both stdout/stderr + # multi_node_startup.sh is verbose during init; silence setup noise here. (cd "$ROOT_DIR" && GENERATE_GENESIS=true ./multi_node_startup.sh -y >/dev/null 2>&1) local del_addr @@ -284,7 +283,7 @@ main() { h="$(wait_for_height 60)" echo "height=$h" - # Discover bond denom for this chain and rewrite denom-bearing knobs to match. + # Resolve chain bond denom and rewrite amount knobs to match this network. local bond_denom bond_denom="$(evmd query staking params --node "$NODE_RPC" -o json | jq -r '.params.bond_denom // .bond_denom')" if [[ -z "$bond_denom" || "$bond_denom" == "null" ]]; then diff --git a/tests/integration/x/poolrebalancer/test_case_a_scheduling.go b/tests/integration/x/poolrebalancer/test_case_a_scheduling.go new file mode 100644 index 00000000..98b83f31 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_a_scheduling.go @@ -0,0 +1,44 @@ +package poolrebalancer + +import ( + sdkmath "cosmossdk.io/math" +) + +// TestSchedulingA_DriftCreatesPendingRedelegations verifies that measurable drift +// produces at least one pending redelegation for the pool delegator. +func (s *KeeperIntegrationTestSuite) TestSchedulingA_DriftCreatesPendingRedelegations() { + // Any drift should schedule with bp=0. + params := s.DefaultEnabledParams( + 0, // rebalance_threshold_bp + 1, // max_ops_per_block + sdkmath.ZeroInt(), + false, + ) + s.EnableRebalancer(params) + + src := s.validators[0] + s.DelegateExtraToValidator(src) + s.T().Logf("scheduling-case: drift pushed to %s", src.OperatorAddress) + + s.Require().NoError(s.RunEndBlock()) + pending := s.PendingRedelegations() + s.T().Logf("scheduling-case: pending redelegations=%d", len(pending)) + + s.Require().NotEmpty(pending, "expected at least one pending redelegation") + + // Spot-check one entry shape. + ctx := s.network.GetContext() + found := false + for _, e := range pending { + if e.DelegatorAddress == s.poolDel.String() { + s.Require().Equal(s.bondDenom, e.Amount.Denom) + s.Require().True(e.CompletionTime.After(ctx.BlockTime())) + found = true + break + } + } + s.Require().True(found, "expected pool delegator entries in pending redelegations") + + s.Require().GreaterOrEqual(len(pending), 1) +} + diff --git a/tests/integration/x/poolrebalancer/test_case_b_bounded_ops.go b/tests/integration/x/poolrebalancer/test_case_b_bounded_ops.go new file mode 100644 index 00000000..8203ba88 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_b_bounded_ops.go @@ -0,0 +1,39 @@ +package poolrebalancer + +import ( + sdkmath "cosmossdk.io/math" +) + +// TestBoundedOpsPerBlock_MaxOpsIsRespected verifies that max_ops_per_block limits +// scheduling to a single operation in one EndBlock pass. +func (s *KeeperIntegrationTestSuite) TestBoundedOpsPerBlock_MaxOpsIsRespected() { + // Keep scheduler aggressive; cap block work at one op. + params := s.DefaultEnabledParams( + 0, // rebalance_threshold_bp + 1, // max_ops_per_block + sdkmath.ZeroInt(), // max_move_per_op = 0 => no cap + false, + ) + + s.EnableRebalancer(params) + + src := s.validators[0] + s.DelegateExtraToValidator(src) + s.T().Logf("bounded-ops: drift pushed to %s with maxOps=%d", src.OperatorAddress, params.MaxOpsPerBlock) + + s.Require().NoError(s.RunEndBlock()) + + pending := s.PendingRedelegations() + s.T().Logf("bounded-ops: pending redelegations=%d", len(pending)) + s.Require().NotEmpty(pending, "expected at least one pending redelegation") + + // With max_ops_per_block=1 and no pre-existing entries, we should queue exactly one op. + // (addPendingRedelegation merges only when dst + completion match; with max_ops=1 it's a single move.) + s.Require().Len(pending, 1, "expected exactly one queued pending redelegation") + + // Quick shape check. + e := pending[0] + s.Require().Equal(s.poolDel.String(), e.DelegatorAddress) + s.Require().Equal(s.bondDenom, e.Amount.Denom) +} + diff --git a/tests/integration/x/poolrebalancer/test_case_c_threshold.go b/tests/integration/x/poolrebalancer/test_case_c_threshold.go new file mode 100644 index 00000000..6f53ac3e --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_c_threshold.go @@ -0,0 +1,72 @@ +package poolrebalancer + +import ( + sdkmath "cosmossdk.io/math" +) + +// TestThresholdBehavior_HighThresholdPreventsScheduling verifies that a very high +// threshold suppresses scheduling even when drift exists. +func (s *KeeperIntegrationTestSuite) TestThresholdBehavior_HighThresholdPreventsScheduling() { + // Keep threshold effectively at "do nothing" level. + params := s.DefaultEnabledParams( + 10000, // rebalance_threshold_bp + 1, // max_ops_per_block + sdkmath.ZeroInt(), + false, // disable undelegate fallback in this test + ) + s.EnableRebalancer(params) + + // Add drift; with this threshold we still expect a no-op. + src := s.validators[0] + s.DelegateExtraToValidator(src) + + s.Require().NoError(s.RunEndBlock()) + + red := s.PendingRedelegations() + und := s.PendingUndelegations() + + s.Require().Len(red, 0, "expected no pending redelegations under high threshold") + s.Require().Len(und, 0, "expected no pending undelegations under high threshold") + +} + +// TestThresholdBehavior_BoundaryPair_NoOpThenSchedules verifies boundary behavior: +// same drift is ignored at high threshold and scheduled after threshold is lowered. +func (s *KeeperIntegrationTestSuite) TestThresholdBehavior_BoundaryPair_NoOpThenSchedules() { + // Same drift, two threshold values. + high := s.DefaultEnabledParams( + 10000, // threshold == total stake (effectively suppresses scheduling) + 1, + sdkmath.ZeroInt(), + false, + ) + s.EnableRebalancer(high) + + src := s.validators[0] + s.DelegateExtraToValidator(src) + s.T().Logf( + "drift injected on %s (bp=%d), pending before: redelegations=%d undelegations=%d", + src.OperatorAddress, high.RebalanceThresholdBp, len(s.PendingRedelegations()), len(s.PendingUndelegations()), + ) + + s.Require().NoError(s.RunEndBlock()) + s.Require().Len(s.PendingRedelegations(), 0, "expected no scheduling under high threshold") + s.Require().Len(s.PendingUndelegations(), 0, "expected no fallback scheduling under high threshold") + s.T().Logf( + "high-threshold pass stayed idle: redelegations=%d undelegations=%d", + len(s.PendingRedelegations()), len(s.PendingUndelegations()), + ) + + // Lower threshold without changing the drift; scheduler should now engage. + low := high + low.RebalanceThresholdBp = 0 + s.EnableRebalancer(low) + + s.Require().NoError(s.RunEndBlock()) + s.Require().NotEmpty(s.PendingRedelegations(), "expected scheduling after lowering threshold") + s.T().Logf( + "after lowering to bp=%d: redelegations=%d undelegations=%d", + low.RebalanceThresholdBp, len(s.PendingRedelegations()), len(s.PendingUndelegations()), + ) +} + diff --git a/tests/integration/x/poolrebalancer/test_case_d_transitive_safety.go b/tests/integration/x/poolrebalancer/test_case_d_transitive_safety.go new file mode 100644 index 00000000..3bfc77e3 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_d_transitive_safety.go @@ -0,0 +1,130 @@ +package poolrebalancer + +import ( + "time" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" +) + +// TestTransitiveSafety_BlockedWhileDstImmature verifies that redelegation from a +// source validator is blocked while an immature redelegation already targets it. +func (s *KeeperIntegrationTestSuite) TestTransitiveSafety_BlockedWhileDstImmature() { + // Keep fallback off so this test only exercises redelegation blocking. + params := s.DefaultEnabledParams( + 0, // threshold + 1, // max ops + sdkmath.ZeroInt(), + false, + ) + s.EnableRebalancer(params) + + xVal := s.validators[0] + yVal := s.validators[1] + xSDKValAddr := s.MustValAddr(xVal.OperatorAddress) + + // Seed immature dst=xVal; any new src=xVal redelegation should be blocked. + immatureCompletion := s.ctx.BlockTime().Add(s.unbondingSec) + s.SeedPendingRedelegation(poolrebalancertypes.PendingRedelegation{ + DelegatorAddress: s.poolDel.String(), + SrcValidatorAddress: yVal.OperatorAddress, + DstValidatorAddress: xVal.OperatorAddress, + Amount: sdk.NewCoin(s.bondDenom, sdkmath.OneInt()), + CompletionTime: immatureCompletion.UTC(), + }) + + // Make xVal overweight so it is a real source candidate. + s.DelegateExtraToValidator(xVal) + + // Guard against vacuous pass: xVal must be overweight and some dst must need stake. + deltas := s.ComputeCurrentDeltas() + xDelta, ok := deltas[xVal.OperatorAddress] + s.Require().True(ok, "expected xVal delta to exist") + s.Require().True(xDelta.IsNegative(), "expected xVal to be overweight/source candidate") + s.Require().True(s.HasPositiveDelta(deltas), "expected at least one underweight destination") + s.T().Logf( + "blocked-case setup: x=%s y=%s xDelta=%s hasDstNeedingStake=%t pendingBefore=%d", + xVal.OperatorAddress, yVal.OperatorAddress, xDelta.String(), s.HasPositiveDelta(deltas), len(s.PendingRedelegations()), + ) + + s.Require().NoError(s.RunEndBlock()) + + pending := s.PendingRedelegations() + + // Core invariant: while dst=xVal is immature, no pending move may use src=xVal. + for _, e := range pending { + s.Require().NotEqual(xVal.OperatorAddress, e.SrcValidatorAddress, "found pending redelegation with src=xVal while dst=xVal is immature") + } + + // Seeded immature entry must still exist. + seedFound := false + for _, e := range pending { + if e.SrcValidatorAddress == yVal.OperatorAddress && e.DstValidatorAddress == xVal.OperatorAddress { + seedFound = true + break + } + } + s.Require().True(seedFound, "expected seeded immature redelegation into xVal to remain") + + // Immature condition should still hold at this point. + s.Require().True(s.poolKeeper.HasImmatureRedelegationTo(s.ctx, s.poolDel, xSDKValAddr, s.bondDenom)) + s.T().Logf("blocked-case result: pendingAfter=%d (no src=%s moves)", len(pending), xVal.OperatorAddress) +} + +// TestTransitiveSafety_UnblocksAfterDstMaturity verifies that once the immature +// destination entry matures, redelegation from that source can be scheduled again. +func (s *KeeperIntegrationTestSuite) TestTransitiveSafety_UnblocksAfterDstMaturity() { + // Same starting setup as blocked case. + params := s.DefaultEnabledParams(0, 1, sdkmath.ZeroInt(), false) + s.EnableRebalancer(params) + + xVal := s.validators[0] + yVal := s.validators[1] + xSDKValAddr := s.MustValAddr(xVal.OperatorAddress) + + immatureCompletion := s.ctx.BlockTime().Add(s.unbondingSec) + s.SeedPendingRedelegation(poolrebalancertypes.PendingRedelegation{ + DelegatorAddress: s.poolDel.String(), + SrcValidatorAddress: yVal.OperatorAddress, + DstValidatorAddress: xVal.OperatorAddress, + Amount: sdk.NewCoin(s.bondDenom, sdkmath.OneInt()), + CompletionTime: immatureCompletion.UTC(), + }) + s.DelegateExtraToValidator(xVal) + + // Guard against vacuous pass before the blocked run. + deltas := s.ComputeCurrentDeltas() + xDelta, ok := deltas[xVal.OperatorAddress] + s.Require().True(ok, "expected xVal delta to exist") + s.Require().True(xDelta.IsNegative(), "expected xVal to be overweight/source candidate") + s.Require().True(s.HasPositiveDelta(deltas), "expected at least one underweight destination") + s.T().Logf( + "unblock-case setup: x=%s y=%s xDelta=%s hasDstNeedingStake=%t pendingBefore=%d", + xVal.OperatorAddress, yVal.OperatorAddress, xDelta.String(), s.HasPositiveDelta(deltas), len(s.PendingRedelegations()), + ) + + // First pass: still blocked by immature dst=xVal. + s.Require().NoError(s.RunEndBlock()) + s.Require().True(s.poolKeeper.HasImmatureRedelegationTo(s.ctx, s.poolDel, xSDKValAddr, s.bondDenom)) + + // Move past completion so the seed can mature and get cleaned up. + s.WithBlockTime(immatureCompletion.Add(1 * time.Second)) + s.Require().NoError(s.RunEndBlock()) + + // Immature block should now be gone. + s.Require().False(s.poolKeeper.HasImmatureRedelegationTo(s.ctx, s.poolDel, xSDKValAddr, s.bondDenom)) + + // Once unblocked, scheduler should be free to pick src=xVal. + pending := s.PendingRedelegations() + srcFound := false + for _, e := range pending { + if e.SrcValidatorAddress == xVal.OperatorAddress { + srcFound = true + break + } + } + s.Require().True(srcFound, "expected module to schedule a redelegation from xVal after maturity") + s.T().Logf("unblock-case result: pendingAfter=%d src=%sScheduled=%t", len(pending), xVal.OperatorAddress, srcFound) +} diff --git a/tests/integration/x/poolrebalancer/test_case_disabled_noop.go b/tests/integration/x/poolrebalancer/test_case_disabled_noop.go new file mode 100644 index 00000000..647eee27 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_disabled_noop.go @@ -0,0 +1,31 @@ +package poolrebalancer + +import ( + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" +) + +// TestDisabledNoOp_NoPendingQueues verifies that an empty pool delegator address +// disables rebalancing and leaves pending queues untouched. +func (s *KeeperIntegrationTestSuite) TestDisabledNoOp_NoPendingQueues() { + ctx := s.network.GetContext() + + // Explicitly disable by clearing pool delegator address. + s.EnableRebalancer(poolrebalancertypes.DefaultParams()) // baseline + p := s.DisabledParams() + s.EnableRebalancer(p) + s.T().Logf("disabled-case: pool delegator=%q", p.PoolDelegatorAddress) + + s.Require().NoError(s.RunEndBlock()) + + red := s.PendingRedelegations() + und := s.PendingUndelegations() + s.T().Logf("disabled-case: pending after EndBlock red=%d und=%d", len(red), len(und)) + s.Require().Len(red, 0) + s.Require().Len(und, 0) + + // Sanity: ensure we did not accidentally enable it. + params, err := s.poolKeeper.GetParams(ctx) + s.Require().NoError(err) + s.Require().Empty(params.PoolDelegatorAddress) +} + diff --git a/tests/integration/x/poolrebalancer/test_case_e_completion_cleanup.go b/tests/integration/x/poolrebalancer/test_case_e_completion_cleanup.go new file mode 100644 index 00000000..1ac5cbed --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_e_completion_cleanup.go @@ -0,0 +1,57 @@ +package poolrebalancer + +import ( + "time" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" +) + +// TestCompletionCleanup_RemovesMatureRedelegationsAndUndelegations verifies that +// mature pending redelegation and undelegation entries are removed during EndBlock. +func (s *KeeperIntegrationTestSuite) TestCompletionCleanup_RemovesMatureRedelegationsAndUndelegations() { + // Disable rebalancer so this test only exercises cleanup paths. + s.EnableRebalancer(s.DisabledParams()) + + xVal := s.validators[0] + yVal := s.validators[1] + + matureCompletion := s.ctx.BlockTime().Add(-1 * time.Second) + + // Seed mature entries (completion already in the past). + s.SeedPendingRedelegation(poolrebalancertypes.PendingRedelegation{ + DelegatorAddress: s.poolDel.String(), + SrcValidatorAddress: yVal.OperatorAddress, + DstValidatorAddress: xVal.OperatorAddress, + Amount: sdk.NewCoin(s.bondDenom, sdkmath.NewInt(5)), + CompletionTime: matureCompletion.UTC(), + }) + + s.SeedPendingUndelegation(poolrebalancertypes.PendingUndelegation{ + DelegatorAddress: s.poolDel.String(), + ValidatorAddress: xVal.OperatorAddress, + Balance: sdk.NewCoin(s.bondDenom, sdkmath.NewInt(7)), + CompletionTime: matureCompletion.UTC(), + }) + + s.Require().NotEmpty(s.PendingRedelegations()) + s.Require().NotEmpty(s.PendingUndelegations()) + s.T().Logf( + "cleanup-case: seeded mature entries red=%d und=%d at %s", + len(s.PendingRedelegations()), len(s.PendingUndelegations()), matureCompletion.Format(time.RFC3339), + ) + + s.Require().NoError(s.RunEndBlock()) + s.T().Logf("cleanup-case: after first EndBlock red=%d und=%d", len(s.PendingRedelegations()), len(s.PendingUndelegations())) + + s.Require().Empty(s.PendingRedelegations(), "expected pending redelegations to be cleaned up") + s.Require().Empty(s.PendingUndelegations(), "expected pending undelegations to be cleaned up") + + // Second pass should stay empty. + s.Require().NoError(s.RunEndBlock()) + s.Require().Empty(s.PendingRedelegations()) + s.Require().Empty(s.PendingUndelegations()) +} + diff --git a/tests/integration/x/poolrebalancer/test_case_f_undelegate_fallback.go b/tests/integration/x/poolrebalancer/test_case_f_undelegate_fallback.go new file mode 100644 index 00000000..fde2a155 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_f_undelegate_fallback.go @@ -0,0 +1,74 @@ +package poolrebalancer + +import ( + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" +) + +// TestUndelegateFallback_FillsPendingUndelegationsWhenRedelegationBlocked verifies +// fallback behavior: undelegations are scheduled when eligible redelegation is blocked. +func (s *KeeperIntegrationTestSuite) TestUndelegateFallback_FillsPendingUndelegationsWhenRedelegationBlocked() { + // Turn fallback on; this test checks the undelegate path when redelegation is blocked. + params := s.DefaultEnabledParams( + 0, // threshold + 1, // max ops + sdkmath.ZeroInt(), // max move per op = 0 => no cap + true, // use undelegate fallback + ) + s.EnableRebalancer(params) + + xVal := s.validators[0] + yVal := s.validators[1] + + // Seed immature dst=xVal so src=xVal redelegations are blocked. + immatureCompletion := s.ctx.BlockTime().Add(s.unbondingSec).UTC() + s.SeedPendingRedelegation(poolrebalancertypes.PendingRedelegation{ + DelegatorAddress: s.poolDel.String(), + SrcValidatorAddress: yVal.OperatorAddress, + DstValidatorAddress: xVal.OperatorAddress, + Amount: sdk.NewCoin(s.bondDenom, sdkmath.OneInt()), + CompletionTime: immatureCompletion, + }) + + // Push extra stake to xVal so it is the natural source candidate. + s.DelegateExtraToValidator(xVal) + + // Guard rails: xVal must be overweight and there must be at least one deficit destination. + deltasBefore := s.ComputeCurrentDeltas() + xDelta, ok := deltasBefore[xVal.OperatorAddress] + s.Require().True(ok, "expected xVal delta to exist") + s.Require().True(xDelta.IsNegative(), "expected xVal to be overweight/source candidate") + s.Require().True(s.HasPositiveDelta(deltasBefore), "expected at least one underweight destination") + overweightBefore := s.OverweightValidatorSet(deltasBefore) + s.T().Logf( + "fallback setup: x=%s y=%s xDelta=%s overweightSet=%d pendingBefore(red=%d,und=%d)", + xVal.OperatorAddress, yVal.OperatorAddress, xDelta.String(), len(overweightBefore), len(s.PendingRedelegations()), len(s.PendingUndelegations()), + ) + + s.Require().NoError(s.RunEndBlock()) + + undelegations := s.PendingUndelegations() + s.Require().NotEmpty(undelegations, "expected pending undelegations to be scheduled by fallback") + + // Fallback undelegations should come from currently overweight validators. + for _, u := range undelegations { + _, exists := overweightBefore[u.ValidatorAddress] + s.Require().True( + exists, + "fallback undelegation validator %s was not overweight before EndBlock", + u.ValidatorAddress, + ) + } + + // Even with fallback, immature dst=xVal must still block src=xVal redelegations. + for _, r := range s.PendingRedelegations() { + s.Require().NotEqual(xVal.OperatorAddress, r.SrcValidatorAddress) + } + s.T().Logf( + "fallback result: pendingAfter(red=%d,und=%d)", + len(s.PendingRedelegations()), len(undelegations), + ) +} + diff --git a/tests/integration/x/poolrebalancer/test_case_param_behavior.go b/tests/integration/x/poolrebalancer/test_case_param_behavior.go new file mode 100644 index 00000000..22b04837 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_param_behavior.go @@ -0,0 +1,100 @@ +package poolrebalancer + +import ( + sdkmath "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" + "github.com/cosmos/cosmos-sdk/runtime" + + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" +) + +// TestMaxMovePerOp_CapsScheduledRedelegationAmount verifies that each queued +// redelegation operation amount respects max_move_per_op. +func (s *KeeperIntegrationTestSuite) TestMaxMovePerOp_CapsScheduledRedelegationAmount() { + // Tiny per-op cap so queue entries are easy to inspect. + maxMove := sdkmath.OneInt() + + params := s.DefaultEnabledParams( + 0, // threshold: schedule on any drift + 5, // multiple ops to validate per-op cap against queue entries + maxMove, // cap + false, // disable fallback to isolate redelegations + ) + s.EnableRebalancer(params) + + src := s.validators[0] + s.DelegateExtraToValidator(src) + s.T().Logf( + "max-move-case: src=%s maxMovePerOp=%s maxOps=%d", + src.OperatorAddress, maxMove.String(), params.MaxOpsPerBlock, + ) + + s.Require().NoError(s.RunEndBlock()) + + // Read queue entries (per-op view), not primary entries (which can merge). + storeService := runtime.NewKVStoreService(s.network.App.GetKey(poolrebalancertypes.StoreKey)) + store := runtime.KVStoreAdapter(storeService.OpenKVStore(s.ctx)) + iter := storetypes.KVStorePrefixIterator(store, poolrebalancertypes.PendingRedelegationQueueKey) + defer iter.Close() //nolint:errcheck + + queueEntries := make([]poolrebalancertypes.PendingRedelegation, 0) + for ; iter.Valid(); iter.Next() { + var queued poolrebalancertypes.QueuedRedelegation + s.Require().NoError(s.network.App.AppCodec().Unmarshal(iter.Value(), &queued)) + queueEntries = append(queueEntries, queued.Entries...) + } + + s.Require().GreaterOrEqual(len(queueEntries), 2, "expected multiple queued redelegation ops") + s.T().Logf("max-move-case: queued ops=%d", len(queueEntries)) + + for _, e := range queueEntries { + s.Require().True( + e.Amount.Amount.LTE(maxMove), + "queue entry amount %s exceeds max_move_per_op %s", + e.Amount.Amount.String(), + maxMove.String(), + ) + } +} + +// TestMaxTargetValidators_LimitsRedelegationDestinationsToTopN verifies that +// scheduled destinations remain inside the configured top-N target validator set. +func (s *KeeperIntegrationTestSuite) TestMaxTargetValidators_LimitsRedelegationDestinationsToTopN() { + // Restrict destinations to top-2 bonded validators. + params := s.DefaultEnabledParams( + 0, // threshold + 3, // allow a few ops in one block + sdkmath.ZeroInt(), + false, + ) + params.MaxTargetValidators = 2 + s.EnableRebalancer(params) + + src := s.validators[0] + s.DelegateExtraToValidator(src) + + targetVals, err := s.poolKeeper.GetTargetBondedValidators(s.ctx) + s.Require().NoError(err) + s.Require().Len(targetVals, 2, "expected target set size to match MaxTargetValidators") + s.T().Logf("target-set-case: src=%s targetSet=%d", src.OperatorAddress, len(targetVals)) + + allowedDst := make(map[string]struct{}, len(targetVals)) + for _, v := range targetVals { + allowedDst[v.String()] = struct{}{} + } + + s.Require().NoError(s.RunEndBlock()) + + pending := s.PendingRedelegations() + s.Require().NotEmpty(pending, "expected pending redelegations to be scheduled") + s.T().Logf("target-set-case: pending redelegations=%d", len(pending)) + + for _, e := range pending { + _, ok := allowedDst[e.DstValidatorAddress] + s.Require().True( + ok, + "found destination %s outside top-N target set", + e.DstValidatorAddress, + ) + } +} diff --git a/tests/integration/x/poolrebalancer/test_case_update_params_integration.go b/tests/integration/x/poolrebalancer/test_case_update_params_integration.go new file mode 100644 index 00000000..53c9eb68 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_update_params_integration.go @@ -0,0 +1,72 @@ +package poolrebalancer + +import ( + "bytes" + + sdkmath "cosmossdk.io/math" + + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" +) + +// TestUpdateParams_RejectsInvalidAuthority verifies that MsgUpdateParams enforces +// module authority and rejects unauthorized callers. +func (s *KeeperIntegrationTestSuite) TestUpdateParams_RejectsInvalidAuthority() { + params := s.DefaultEnabledParams(0, 1, sdkmath.ZeroInt(), false) + + msg := &poolrebalancertypes.MsgUpdateParams{ + Authority: sdk.AccAddress(bytes.Repeat([]byte{8}, 20)).String(), + Params: params, + } + + _, err := s.poolKeeper.UpdateParams(s.ctx, msg) + s.Require().Error(err) + s.Require().Contains(err.Error(), "invalid authority") + s.T().Logf("update-params auth-check: invalid authority rejected as expected") +} + +// TestUpdateParams_ValidAuthorityChangesSchedulingBehavior verifies that a valid +// params update changes runtime scheduling behavior in the same test setup. +func (s *KeeperIntegrationTestSuite) TestUpdateParams_ValidAuthorityChangesSchedulingBehavior() { + authority := authtypes.NewModuleAddress(govtypes.ModuleName).String() + + // Reuse the same drift across both phases. + src := s.validators[0] + s.DelegateExtraToValidator(src) + s.T().Logf("update-params flow: drift pushed to %s", src.OperatorAddress) + + // Phase 1: high threshold, expect no scheduling. + high := s.DefaultEnabledParams( + 10000, // threshold suppresses all scheduling + 1, + sdkmath.ZeroInt(), + false, + ) + _, err := s.poolKeeper.UpdateParams(s.ctx, &poolrebalancertypes.MsgUpdateParams{ + Authority: authority, + Params: high, + }) + s.Require().NoError(err) + + s.Require().NoError(s.RunEndBlock()) + s.Require().Len(s.PendingRedelegations(), 0, "expected no scheduling under high threshold") + s.Require().Len(s.PendingUndelegations(), 0, "expected no fallback scheduling under high threshold") + s.T().Logf("update-params flow: high threshold kept queues empty") + + // Phase 2: lower threshold, same drift should now schedule. + low := high + low.RebalanceThresholdBp = 0 + _, err = s.poolKeeper.UpdateParams(s.ctx, &poolrebalancertypes.MsgUpdateParams{ + Authority: authority, + Params: low, + }) + s.Require().NoError(err) + + s.Require().NoError(s.RunEndBlock()) + s.Require().NotEmpty(s.PendingRedelegations(), "expected scheduling after lowering threshold") + s.T().Logf("update-params flow: low threshold scheduled %d redelegations", len(s.PendingRedelegations())) +} + diff --git a/tests/integration/x/poolrebalancer/test_endblock_helpers.go b/tests/integration/x/poolrebalancer/test_endblock_helpers.go new file mode 100644 index 00000000..97998244 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_endblock_helpers.go @@ -0,0 +1,20 @@ +package poolrebalancer + +import ( + mod "github.com/cosmos/evm/x/poolrebalancer" + "time" +) + +// RunEndBlock executes poolrebalancer EndBlock on the suite context. +// Tests in this package mutate keeper state directly on s.ctx, so we call +// EndBlocker directly to stay on that same context/store view. +func (s *KeeperIntegrationTestSuite) RunEndBlock() error { + return mod.EndBlocker(s.ctx, s.poolKeeper) +} + +// WithBlockTime moves the suite context clock without advancing the full network. +// It is used when we only need time-based maturity behavior. +func (s *KeeperIntegrationTestSuite) WithBlockTime(t time.Time) { + s.ctx = s.ctx.WithBlockTime(t) +} + diff --git a/tests/integration/x/poolrebalancer/test_helpers.go b/tests/integration/x/poolrebalancer/test_helpers.go new file mode 100644 index 00000000..c5394ad1 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_helpers.go @@ -0,0 +1,111 @@ +package poolrebalancer + +import ( + sdkmath "cosmossdk.io/math" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + sdk "github.com/cosmos/cosmos-sdk/types" + + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" +) + +// PendingRedelegations returns all pending redelegations, failing test on query error. +func (s *KeeperIntegrationTestSuite) PendingRedelegations() []poolrebalancertypes.PendingRedelegation { + out, err := s.poolKeeper.GetAllPendingRedelegations(s.ctx) + s.Require().NoError(err) + return out +} + +// PendingUndelegations returns all pending undelegations, failing test on query error. +func (s *KeeperIntegrationTestSuite) PendingUndelegations() []poolrebalancertypes.PendingUndelegation { + out, err := s.poolKeeper.GetAllPendingUndelegations(s.ctx) + s.Require().NoError(err) + return out +} + +// DelegateExtraToValidator creates deterministic drift by adding extra stake on one validator. +// Amount selection tries to be large enough to survive truncation in stake math. +func (s *KeeperIntegrationTestSuite) DelegateExtraToValidator(val stakingtypes.Validator) { + // Rebalancer math uses truncated token amounts; too-small moves can disappear. + free := s.network.App.GetBankKeeper().GetBalance(s.ctx, s.poolDel, s.bondDenom).Amount + s.Require().True(free.IsPositive(), "pool delegator free balance must be > 0") + + stakeByVal, _, err := s.poolKeeper.GetDelegatorStakeByValidator(s.ctx, s.poolDel) + s.Require().NoError(err) + base := stakeByVal[val.OperatorAddress] + s.Require().True(base.IsPositive(), "expected base stake for chosen validator") + + // Use roughly existing stake as drift target, bounded by free balance. + extra := base + if free.LT(extra) { + extra = free + } + + s.Require().True(extra.IsPositive(), "drift delegation amount must be > 0") + + _, err = s.network.App.GetStakingKeeper().Delegate( + s.ctx, + s.poolDel, + extra, + stakingtypes.Unspecified, + val, + true, + ) + s.Require().NoError(err) +} + +// SeedPendingRedelegation inserts a pending redelegation fixture entry. +func (s *KeeperIntegrationTestSuite) SeedPendingRedelegation(entry poolrebalancertypes.PendingRedelegation) { + s.Require().NoError(s.poolKeeper.SetPendingRedelegation(s.ctx, entry)) +} + +// SeedPendingUndelegation inserts a pending undelegation fixture entry. +func (s *KeeperIntegrationTestSuite) SeedPendingUndelegation(entry poolrebalancertypes.PendingUndelegation) { + s.Require().NoError(s.poolKeeper.SetPendingUndelegation(s.ctx, entry)) +} + +// ComputeCurrentDeltas mirrors ProcessRebalance inputs and returns target-current deltas. +func (s *KeeperIntegrationTestSuite) ComputeCurrentDeltas() map[string]sdkmath.Int { + targetVals, err := s.poolKeeper.GetTargetBondedValidators(s.ctx) + s.Require().NoError(err) + s.Require().NotEmpty(targetVals) + + current, total, err := s.poolKeeper.GetDelegatorStakeByValidator(s.ctx, s.poolDel) + s.Require().NoError(err) + s.Require().True(total.IsPositive()) + + target, err := s.poolKeeper.EqualWeightTarget(total, targetVals) + s.Require().NoError(err) + + deltas, err := s.poolKeeper.ComputeDeltas(s.ctx, target, current, total) + s.Require().NoError(err) + return deltas +} + +// HasPositiveDelta reports whether any validator is currently underweight. +func (s *KeeperIntegrationTestSuite) HasPositiveDelta(deltas map[string]sdkmath.Int) bool { + for _, d := range deltas { + if d.IsPositive() { + return true + } + } + return false +} + +// OverweightValidatorSet builds a quick lookup of validators with negative deltas. +func (s *KeeperIntegrationTestSuite) OverweightValidatorSet(deltas map[string]sdkmath.Int) map[string]struct{} { + out := make(map[string]struct{}) + for val, d := range deltas { + if d.IsNegative() { + out[val] = struct{}{} + } + } + return out +} + +// MustValAddr parses valoper bech32 and fails the test on invalid input. +func (s *KeeperIntegrationTestSuite) MustValAddr(bech32 string) sdk.ValAddress { + val, err := sdk.ValAddressFromBech32(bech32) + s.Require().NoError(err) + return val +} + diff --git a/tests/integration/x/poolrebalancer/test_suite.go b/tests/integration/x/poolrebalancer/test_suite.go new file mode 100644 index 00000000..a8e9bd33 --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_suite.go @@ -0,0 +1,141 @@ +package poolrebalancer + +import ( + "time" + + "github.com/stretchr/testify/suite" + + "github.com/cosmos/evm/testutil/integration/evm/network" + testkeyring "github.com/cosmos/evm/testutil/keyring" + + poolrebalancerkeeper "github.com/cosmos/evm/x/poolrebalancer/keeper" + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" + + sdkmath "cosmossdk.io/math" + + "github.com/cosmos/cosmos-sdk/runtime" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +type KeeperIntegrationTestSuite struct { + suite.Suite + + create network.CreateEvmApp + options []network.ConfigOption + + network *network.UnitTestNetwork + keyring testkeyring.Keyring + poolKeeper poolrebalancerkeeper.Keeper + ctx sdk.Context + + poolDel sdk.AccAddress + validators []stakingtypes.Validator + bondDenom string + unbondingSec time.Duration + maxEntries uint32 +} + +// NewKeeperIntegrationTestSuite wires app factory + optional network config for each test case. +func NewKeeperIntegrationTestSuite(create network.CreateEvmApp, options ...network.ConfigOption) *KeeperIntegrationTestSuite { + return &KeeperIntegrationTestSuite{ + create: create, + options: options, + } +} + +func (s *KeeperIntegrationTestSuite) SetupTest() { + if s.create == nil { + panic("Create app must be set") + } + + s.keyring = testkeyring.New(2) + opts := []network.ConfigOption{ + network.WithPreFundedAccounts(s.keyring.GetAllAccAddrs()...), + } + opts = append(opts, s.options...) + + s.network = network.NewUnitTestNetwork(s.create, opts...) + s.ctx = s.network.GetContext() + + // Keep unbonding short so maturity/cleanup tests run quickly. + s.unbondingSec = 30 * time.Second + s.maxEntries = 100 + + s.configureStakingParamsForTests() + s.configurePoolKeeper() + s.captureBaselineInfo() +} + +func (s *KeeperIntegrationTestSuite) configureStakingParamsForTests() { + sk := s.network.App.GetStakingKeeper() + sp, err := sk.GetParams(s.ctx) + s.Require().NoError(err) + sp.UnbondingTime = s.unbondingSec + sp.MaxEntries = s.maxEntries + s.Require().NoError(sk.SetParams(s.ctx, sp)) +} + +// configurePoolKeeper builds a keeper bound to the same stores as the app under test. +func (s *KeeperIntegrationTestSuite) configurePoolKeeper() { + // This keeper shares module KV stores with the app; no mocked state. + poolKey := s.network.App.GetKey(poolrebalancertypes.StoreKey) + storeService := runtime.NewKVStoreService(poolKey) + + authority := authtypes.NewModuleAddress(govtypes.ModuleName) + s.poolKeeper = poolrebalancerkeeper.NewKeeper( + s.network.App.AppCodec(), + storeService, + s.network.App.GetStakingKeeper(), + authority, + ) +} + +// captureBaselineInfo caches common fixtures used by most test cases. +func (s *KeeperIntegrationTestSuite) captureBaselineInfo() { + s.validators = s.network.GetValidators() + s.Require().NotEmpty(s.validators, "network should initialize bonded validators") + + bondDenom, err := s.network.App.GetStakingKeeper().BondDenom(s.ctx) + s.Require().NoError(err) + s.bondDenom = bondDenom + + // UnitTestNetwork seeds delegations for the first test account; use it as pool delegator. + s.poolDel = s.keyring.GetAccAddr(0) + + // Guard rail: no stake means rebalancer has nothing to do. + _, total, err := s.poolKeeper.GetDelegatorStakeByValidator(s.ctx, s.poolDel) + s.Require().NoError(err) + s.Require().True(total.IsPositive(), "expected pool delegator stake to be > 0") +} + +// NextBlock0 advances one block with no extra time offset. +func (s *KeeperIntegrationTestSuite) NextBlock0() { + s.Require().NoError(s.network.NextBlockAfter(0)) +} + +// EnableRebalancer writes module params for the current test. +func (s *KeeperIntegrationTestSuite) EnableRebalancer(params poolrebalancertypes.Params) { + s.Require().NoError(s.poolKeeper.SetParams(s.ctx, params)) +} + +// DisabledParams returns default params with pool delegator cleared. +func (s *KeeperIntegrationTestSuite) DisabledParams() poolrebalancertypes.Params { + p := poolrebalancertypes.DefaultParams() + p.PoolDelegatorAddress = "" + return p +} + +// DefaultEnabledParams returns a baseline enabled config with per-test overrides. +func (s *KeeperIntegrationTestSuite) DefaultEnabledParams(thresholdBP uint32, maxOpsPerBlock uint32, maxMovePerOp sdkmath.Int, useUndelegateFallback bool) poolrebalancertypes.Params { + p := poolrebalancertypes.DefaultParams() + p.PoolDelegatorAddress = s.poolDel.String() + p.MaxTargetValidators = uint32(len(s.validators)) + p.RebalanceThresholdBp = thresholdBP + p.MaxOpsPerBlock = maxOpsPerBlock + p.MaxMovePerOp = maxMovePerOp + p.UseUndelegateFallback = useUndelegateFallback + return p +} From 4dcb6d63e04ec89abfba5f3ca396dba60530f939 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Thu, 19 Mar 2026 16:45:09 +0530 Subject: [PATCH 09/31] fix(poolrebalancer): validate params, add rebalance events, and decouple staking keeper Signed-off-by: Nikhil Sharma --- .../poolrebalancer/test_case_a_scheduling.go | 7 +++ .../test_case_f_undelegate_fallback.go | 4 ++ .../x/poolrebalancer/test_helpers.go | 5 +- x/poolrebalancer/abci.go | 3 ++ x/poolrebalancer/keeper/keeper.go | 6 +-- x/poolrebalancer/keeper/msg_server.go | 8 ++++ x/poolrebalancer/keeper/msg_server_test.go | 25 ++++++++++ x/poolrebalancer/keeper/rebalance.go | 47 ++++++++++++------- x/poolrebalancer/keeper/rebalance_test.go | 16 +++---- x/poolrebalancer/keeper/redelegation.go | 26 ++++++++++ x/poolrebalancer/keeper/undelegation.go | 25 ++++++++++ x/poolrebalancer/types/events.go | 22 +++++++++ x/poolrebalancer/types/interfaces.go | 22 +++++++++ x/poolrebalancer/types/keys.go | 30 +++++++++--- 14 files changed, 209 insertions(+), 37 deletions(-) create mode 100644 x/poolrebalancer/types/events.go create mode 100644 x/poolrebalancer/types/interfaces.go diff --git a/tests/integration/x/poolrebalancer/test_case_a_scheduling.go b/tests/integration/x/poolrebalancer/test_case_a_scheduling.go index 98b83f31..45f0cff7 100644 --- a/tests/integration/x/poolrebalancer/test_case_a_scheduling.go +++ b/tests/integration/x/poolrebalancer/test_case_a_scheduling.go @@ -2,6 +2,9 @@ package poolrebalancer import ( sdkmath "cosmossdk.io/math" + + "github.com/cosmos/evm/testutil/integration/evm/utils" + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" ) // TestSchedulingA_DriftCreatesPendingRedelegations verifies that measurable drift @@ -24,6 +27,10 @@ func (s *KeeperIntegrationTestSuite) TestSchedulingA_DriftCreatesPendingRedelega pending := s.PendingRedelegations() s.T().Logf("scheduling-case: pending redelegations=%d", len(pending)) + events := s.ctx.EventManager().Events().ToABCIEvents() + s.Require().True(utils.ContainsEventType(events, poolrebalancertypes.EventTypeRedelegationStarted)) + s.Require().True(utils.ContainsEventType(events, poolrebalancertypes.EventTypeRebalanceSummary)) + s.Require().NotEmpty(pending, "expected at least one pending redelegation") // Spot-check one entry shape. diff --git a/tests/integration/x/poolrebalancer/test_case_f_undelegate_fallback.go b/tests/integration/x/poolrebalancer/test_case_f_undelegate_fallback.go index fde2a155..12f9ba25 100644 --- a/tests/integration/x/poolrebalancer/test_case_f_undelegate_fallback.go +++ b/tests/integration/x/poolrebalancer/test_case_f_undelegate_fallback.go @@ -4,6 +4,7 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/evm/testutil/integration/evm/utils" poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" ) @@ -51,6 +52,9 @@ func (s *KeeperIntegrationTestSuite) TestUndelegateFallback_FillsPendingUndelega undelegations := s.PendingUndelegations() s.Require().NotEmpty(undelegations, "expected pending undelegations to be scheduled by fallback") + events := s.ctx.EventManager().Events().ToABCIEvents() + s.Require().True(utils.ContainsEventType(events, poolrebalancertypes.EventTypeUndelegationStarted)) + s.Require().True(utils.ContainsEventType(events, poolrebalancertypes.EventTypeRebalanceSummary)) // Fallback undelegations should come from currently overweight validators. for _, u := range undelegations { diff --git a/tests/integration/x/poolrebalancer/test_helpers.go b/tests/integration/x/poolrebalancer/test_helpers.go index c5394ad1..96cdcd46 100644 --- a/tests/integration/x/poolrebalancer/test_helpers.go +++ b/tests/integration/x/poolrebalancer/test_helpers.go @@ -76,7 +76,10 @@ func (s *KeeperIntegrationTestSuite) ComputeCurrentDeltas() map[string]sdkmath.I target, err := s.poolKeeper.EqualWeightTarget(total, targetVals) s.Require().NoError(err) - deltas, err := s.poolKeeper.ComputeDeltas(s.ctx, target, current, total) + params, err := s.poolKeeper.GetParams(s.ctx) + s.Require().NoError(err) + + deltas, err := s.poolKeeper.ComputeDeltas(target, current, total, params.RebalanceThresholdBp) s.Require().NoError(err) return deltas } diff --git a/x/poolrebalancer/abci.go b/x/poolrebalancer/abci.go index 4fd88711..904a5159 100644 --- a/x/poolrebalancer/abci.go +++ b/x/poolrebalancer/abci.go @@ -9,12 +9,15 @@ import ( // EndBlocker runs at end of block: complete matured redelegations/undelegations, then process rebalance. func EndBlocker(ctx sdk.Context, k keeper.Keeper) error { if err := k.CompletePendingRedelegations(ctx); err != nil { + ctx.Logger().Error("poolrebalancer: complete pending redelegations failed", "err", err) return err } if err := k.CompletePendingUndelegations(ctx); err != nil { + ctx.Logger().Error("poolrebalancer: complete pending undelegations failed", "err", err) return err } if err := k.ProcessRebalance(ctx); err != nil { + ctx.Logger().Error("poolrebalancer: process rebalance failed", "err", err) return err } return nil diff --git a/x/poolrebalancer/keeper/keeper.go b/x/poolrebalancer/keeper/keeper.go index ef6a16a1..4102ddcb 100644 --- a/x/poolrebalancer/keeper/keeper.go +++ b/x/poolrebalancer/keeper/keeper.go @@ -2,17 +2,17 @@ package keeper import ( "cosmossdk.io/core/store" + "github.com/cosmos/evm/x/poolrebalancer/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" ) // Keeper holds state and dependencies for the pool rebalancer. type Keeper struct { storeService store.KVStoreService cdc codec.BinaryCodec - stakingKeeper *stakingkeeper.Keeper + stakingKeeper types.StakingKeeper authority sdk.AccAddress } @@ -20,7 +20,7 @@ type Keeper struct { func NewKeeper( cdc codec.BinaryCodec, storeService store.KVStoreService, - stakingKeeper *stakingkeeper.Keeper, + stakingKeeper types.StakingKeeper, authority sdk.AccAddress, ) Keeper { if err := sdk.VerifyAddressFormat(authority); err != nil { diff --git a/x/poolrebalancer/keeper/msg_server.go b/x/poolrebalancer/keeper/msg_server.go index a20864f2..b8005e4c 100644 --- a/x/poolrebalancer/keeper/msg_server.go +++ b/x/poolrebalancer/keeper/msg_server.go @@ -8,11 +8,16 @@ import ( errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) // UpdateParams updates module params. Caller must be the governance module account. func (k *Keeper) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + if req == nil { + return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "empty update params request") + } + if k.authority.String() != req.Authority { return nil, errorsmod.Wrapf( govtypes.ErrInvalidSigner, @@ -23,6 +28,9 @@ func (k *Keeper) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) } ctx := sdk.UnwrapSDKContext(goCtx) + if err := req.Params.Validate(); err != nil { + return nil, err + } if err := k.SetParams(ctx, req.Params); err != nil { return nil, err } diff --git a/x/poolrebalancer/keeper/msg_server_test.go b/x/poolrebalancer/keeper/msg_server_test.go index 6c106fd8..4dece693 100644 --- a/x/poolrebalancer/keeper/msg_server_test.go +++ b/x/poolrebalancer/keeper/msg_server_test.go @@ -28,6 +28,14 @@ func TestUpdateParams_RejectsWrongAuthority(t *testing.T) { require.Contains(t, err.Error(), "invalid authority") } +func TestUpdateParams_RejectsNilRequest(t *testing.T) { + ctx, k := newTestKeeper(t) + + _, err := k.UpdateParams(ctx, nil) + require.Error(t, err) + require.Contains(t, err.Error(), "empty update params request") +} + func TestUpdateParams_AcceptsAuthorityAndUpdatesParams(t *testing.T) { ctx, k := newTestKeeper(t) @@ -51,6 +59,23 @@ func TestUpdateParams_AcceptsAuthorityAndUpdatesParams(t *testing.T) { require.True(t, got.MaxMovePerOp.Equal(math.NewInt(77))) } +func TestUpdateParams_RejectsInvalidParamsWithValidAuthority(t *testing.T) { + ctx, k := newTestKeeper(t) + + authority := k.authority.String() + invalid := types.DefaultParams() + invalid.MaxTargetValidators = 0 + + msg := &types.MsgUpdateParams{ + Authority: authority, + Params: invalid, + } + + _, err := k.UpdateParams(ctx, msg) + require.Error(t, err) + require.Contains(t, err.Error(), "max_target_validators must be positive") +} + func TestMsgUpdateParams_ValidateBasic_RejectsInvalidParams(t *testing.T) { msg := &types.MsgUpdateParams{ Authority: sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String(), diff --git a/x/poolrebalancer/keeper/rebalance.go b/x/poolrebalancer/keeper/rebalance.go index 3d188c53..c83202d2 100644 --- a/x/poolrebalancer/keeper/rebalance.go +++ b/x/poolrebalancer/keeper/rebalance.go @@ -4,6 +4,9 @@ import ( "context" "fmt" "sort" + "strconv" + + "github.com/cosmos/evm/x/poolrebalancer/types" "cosmossdk.io/math" @@ -112,11 +115,7 @@ func (k Keeper) EqualWeightTarget(totalStake math.Int, targetValidators []sdk.Va // ComputeDeltas returns target-current per validator and applies the rebalance threshold. // Deltas within the threshold are treated as zero. -func (k Keeper) ComputeDeltas(ctx context.Context, target, current map[string]math.Int, totalStake math.Int) (map[string]math.Int, error) { - bp, err := k.GetRebalanceThresholdBP(ctx) - if err != nil { - return nil, err - } +func (k Keeper) ComputeDeltas(target, current map[string]math.Int, totalStake math.Int, bp uint32) (map[string]math.Int, error) { threshold := totalStake.Mul(math.NewInt(int64(bp))).Quo(math.NewInt(10_000)) allKeys := make(map[string]struct{}) @@ -273,12 +272,18 @@ func (k Keeper) ProcessRebalance(ctx context.Context) error { return nil } + // Load params once for this rebalance pass. + params, err := k.GetParams(ctx) + if err != nil { + return err + } + // Compute equal-weight targets and deltas (threshold applied inside ComputeDeltas). target, err := k.EqualWeightTarget(total, targetVals) if err != nil { return err } - deltas, err := k.ComputeDeltas(ctx, target, stakeByValidator, total) + deltas, err := k.ComputeDeltas(target, stakeByValidator, total, params.RebalanceThresholdBp) if err != nil { return err } @@ -295,15 +300,9 @@ func (k Keeper) ProcessRebalance(ctx context.Context) error { return nil } - // Load params for the apply loop. - maxOps, err := k.GetMaxOpsPerBlock(ctx) - if err != nil { - return err - } - useUndel, err := k.GetUseUndelegateFallback(ctx) - if err != nil { - return err - } + // Apply params to the operation loop. + maxOps := params.MaxOpsPerBlock + useUndel := params.UseUndelegateFallback bondDenom, err := k.stakingKeeper.BondDenom(ctx) if err != nil { return err @@ -317,9 +316,9 @@ func (k Keeper) ProcessRebalance(ctx context.Context) error { } sort.Strings(keys) - maxMove, err := k.GetMaxMovePerOp(ctx) - if err != nil { - return err + maxMove := params.MaxMovePerOp + if maxMove.IsNil() { + maxMove = math.ZeroInt() } var opsDone uint32 @@ -377,5 +376,17 @@ func (k Keeper) ProcessRebalance(ctx context.Context) error { opsDone++ } + if opsDone > 0 { + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeRebalanceSummary, + sdk.NewAttribute(types.AttributeKeyDelegator, del.String()), + sdk.NewAttribute(types.AttributeKeyOpsDone, strconv.FormatUint(uint64(opsDone), 10)), + sdk.NewAttribute(types.AttributeKeyUseFallback, strconv.FormatBool(useUndel)), + ), + ) + } + return nil } diff --git a/x/poolrebalancer/keeper/rebalance_test.go b/x/poolrebalancer/keeper/rebalance_test.go index 745b0fbc..4162601e 100644 --- a/x/poolrebalancer/keeper/rebalance_test.go +++ b/x/poolrebalancer/keeper/rebalance_test.go @@ -312,12 +312,12 @@ func TestPickBestRedelegation_MultipleValidators(t *testing.T) { // TestComputeDeltas_Basic: target A=100 B=100, current A=120 B=80, totalStake=200; 50 bp threshold = 1. func TestComputeDeltas_Basic(t *testing.T) { - ctx, k := testKeeperWithParams(t, "50", "0") + _, k := testKeeperWithParams(t, "50", "0") target := map[string]math.Int{"A": math.NewInt(100), "B": math.NewInt(100)} current := map[string]math.Int{"A": math.NewInt(120), "B": math.NewInt(80)} totalStake := math.NewInt(200) - deltas, err := k.ComputeDeltas(ctx, target, current, totalStake) + deltas, err := k.ComputeDeltas(target, current, totalStake, 50) require.NoError(t, err) require.Len(t, deltas, 2) // delta = target - current: A = -20, B = +20. Threshold 200*50/10000 = 1; both |delta| >= 1. @@ -327,12 +327,12 @@ func TestComputeDeltas_Basic(t *testing.T) { // TestComputeDeltas_BelowThreshold: same target/current, high RebalanceThresholdBP so threshold > 20. func TestComputeDeltas_BelowThreshold(t *testing.T) { - ctx, k := testKeeperWithParams(t, "1500", "0") // 15% -> threshold 200*1500/10000 = 30 + _, k := testKeeperWithParams(t, "1500", "0") // 15% -> threshold 200*1500/10000 = 30 target := map[string]math.Int{"A": math.NewInt(100), "B": math.NewInt(100)} current := map[string]math.Int{"A": math.NewInt(120), "B": math.NewInt(80)} totalStake := math.NewInt(200) - deltas, err := k.ComputeDeltas(ctx, target, current, totalStake) + deltas, err := k.ComputeDeltas(target, current, totalStake, 1500) require.NoError(t, err) require.Len(t, deltas, 2) // |delta| 20 < threshold 30 -> both zeroed. @@ -342,12 +342,12 @@ func TestComputeDeltas_BelowThreshold(t *testing.T) { // TestComputeDeltas_UnionOfKeys: validator only in target or only in current; all keys present. func TestComputeDeltas_UnionOfKeys(t *testing.T) { - ctx, k := testKeeperWithParams(t, "50", "0") + _, k := testKeeperWithParams(t, "50", "0") target := map[string]math.Int{"A": math.NewInt(100), "B": math.NewInt(100)} current := map[string]math.Int{"A": math.NewInt(50), "C": math.NewInt(50)} totalStake := math.NewInt(200) - deltas, err := k.ComputeDeltas(ctx, target, current, totalStake) + deltas, err := k.ComputeDeltas(target, current, totalStake, 50) require.NoError(t, err) require.Len(t, deltas, 3) // A: 100-50=50; B: 100-0=100; C: 0-50=-50. Threshold 1; all non-zero. @@ -358,12 +358,12 @@ func TestComputeDeltas_UnionOfKeys(t *testing.T) { // TestComputeDeltas_TotalStakeZero: threshold = 0; deltas are not zeroed by threshold. func TestComputeDeltas_TotalStakeZero(t *testing.T) { - ctx, k := testKeeperWithParams(t, "50", "0") + _, k := testKeeperWithParams(t, "50", "0") target := map[string]math.Int{"A": math.NewInt(0), "B": math.NewInt(0)} current := map[string]math.Int{"A": math.NewInt(0), "B": math.NewInt(0)} totalStake := math.ZeroInt() - deltas, err := k.ComputeDeltas(ctx, target, current, totalStake) + deltas, err := k.ComputeDeltas(target, current, totalStake, 50) require.NoError(t, err) require.Len(t, deltas, 2) // threshold = 0; delta A = 0, B = 0 (and 0 is not < 0, so they stay 0). diff --git a/x/poolrebalancer/keeper/redelegation.go b/x/poolrebalancer/keeper/redelegation.go index dcd0eb91..966735f2 100644 --- a/x/poolrebalancer/keeper/redelegation.go +++ b/x/poolrebalancer/keeper/redelegation.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strconv" "time" "github.com/cosmos/evm/x/poolrebalancer/types" @@ -121,6 +122,19 @@ func (k Keeper) BeginTrackedRedelegation(ctx context.Context, del sdk.AccAddress if err := k.addPendingRedelegation(ctx, del, srcVal, dstVal, coin, completionTime); err != nil { return time.Time{}, fmt.Errorf("add pending redelegation: %w", err) } + + sdkCtx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeRedelegationStarted, + sdk.NewAttribute(types.AttributeKeyDelegator, del.String()), + sdk.NewAttribute(types.AttributeKeySrcValidator, srcVal.String()), + sdk.NewAttribute(types.AttributeKeyDstValidator, dstVal.String()), + sdk.NewAttribute(types.AttributeKeyAmount, coin.Amount.String()), + sdk.NewAttribute(types.AttributeKeyDenom, coin.Denom), + sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.UTC().Format(time.RFC3339Nano)), + ), + ) + return completionTime, nil } @@ -154,6 +168,7 @@ func (k Keeper) deletePendingRedelegation(ctx context.Context, entry types.Pendi func (k Keeper) CompletePendingRedelegations(ctx context.Context) error { sdkCtx := sdk.UnwrapSDKContext(ctx) blockTime := sdkCtx.BlockTime() + completed := 0 store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)) start := types.PendingRedelegationQueueKey @@ -178,9 +193,20 @@ func (k Keeper) CompletePendingRedelegations(ctx context.Context) error { if err := k.deletePendingRedelegation(ctx, entry, completion); err != nil { return err } + completed++ } store.Delete(key) } + if completed > 0 { + sdkCtx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeRedelegationsCompleted, + sdk.NewAttribute(types.AttributeKeyCount, strconv.Itoa(completed)), + sdk.NewAttribute(types.AttributeKeyCompletionTime, blockTime.UTC().Format(time.RFC3339Nano)), + ), + ) + } + return nil } diff --git a/x/poolrebalancer/keeper/undelegation.go b/x/poolrebalancer/keeper/undelegation.go index e691b0a3..9c705d0e 100644 --- a/x/poolrebalancer/keeper/undelegation.go +++ b/x/poolrebalancer/keeper/undelegation.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "strconv" "time" "github.com/cosmos/evm/x/poolrebalancer/types" @@ -89,6 +90,18 @@ func (k Keeper) BeginTrackedUndelegation(ctx context.Context, del sdk.AccAddress return time.Time{}, math.ZeroInt(), fmt.Errorf("add pending undelegation: %w", err) } + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeUndelegationStarted, + sdk.NewAttribute(types.AttributeKeyDelegator, del.String()), + sdk.NewAttribute(types.AttributeKeyValidator, valAddr.String()), + sdk.NewAttribute(types.AttributeKeyAmount, amountUnbonded.String()), + sdk.NewAttribute(types.AttributeKeyDenom, bondDenom), + sdk.NewAttribute(types.AttributeKeyCompletionTime, completionTime.UTC().Format(time.RFC3339Nano)), + ), + ) + return completionTime, amountUnbonded, nil } @@ -97,6 +110,7 @@ func (k Keeper) BeginTrackedUndelegation(ctx context.Context, del sdk.AccAddress func (k Keeper) CompletePendingUndelegations(ctx context.Context) error { sdkCtx := sdk.UnwrapSDKContext(ctx) blockTime := sdkCtx.BlockTime() + completed := 0 coreStore := k.storeService.OpenKVStore(ctx) iterStore := runtime.KVStoreAdapter(coreStore) @@ -135,11 +149,22 @@ func (k Keeper) CompletePendingUndelegations(ctx context.Context) error { if err := coreStore.Delete(indexKey); err != nil { return err } + completed++ } // Delete the queue key itself. iterStore.Delete(key) } + if completed > 0 { + sdkCtx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeUndelegationsCompleted, + sdk.NewAttribute(types.AttributeKeyCount, strconv.Itoa(completed)), + sdk.NewAttribute(types.AttributeKeyCompletionTime, blockTime.UTC().Format(time.RFC3339Nano)), + ), + ) + } + return nil } diff --git a/x/poolrebalancer/types/events.go b/x/poolrebalancer/types/events.go new file mode 100644 index 00000000..c2ab49a6 --- /dev/null +++ b/x/poolrebalancer/types/events.go @@ -0,0 +1,22 @@ +package types + +const ( + // Event types. + EventTypeRebalanceSummary = "rebalance_summary" + EventTypeRedelegationStarted = "redelegation_started" + EventTypeUndelegationStarted = "undelegation_started" + EventTypeRedelegationsCompleted = "redelegations_completed" + EventTypeUndelegationsCompleted = "undelegations_completed" + + // Common attributes. + AttributeKeyDelegator = "delegator" + AttributeKeyValidator = "validator" + AttributeKeySrcValidator = "src_validator" + AttributeKeyDstValidator = "dst_validator" + AttributeKeyAmount = "amount" + AttributeKeyDenom = "denom" + AttributeKeyCompletionTime = "completion_time" + AttributeKeyCount = "count" + AttributeKeyOpsDone = "ops_done" + AttributeKeyUseFallback = "use_undelegate_fallback" +) diff --git a/x/poolrebalancer/types/interfaces.go b/x/poolrebalancer/types/interfaces.go new file mode 100644 index 00000000..0a06f008 --- /dev/null +++ b/x/poolrebalancer/types/interfaces.go @@ -0,0 +1,22 @@ +package types + +import ( + "context" + "time" + + sdkmath "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// StakingKeeper defines the subset of staking keeper methods used by poolrebalancer. +type StakingKeeper interface { + GetBondedValidatorsByPower(ctx context.Context) ([]stakingtypes.Validator, error) + GetDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) ([]stakingtypes.Delegation, error) + GetValidator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.Validator, error) + GetDelegation(ctx context.Context, delegatorAddr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.Delegation, error) + BeginRedelegation(ctx context.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdkmath.LegacyDec) (completionTime time.Time, err error) + Undelegate(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdkmath.LegacyDec) (completionTime time.Time, amount sdkmath.Int, err error) + UnbondingTime(ctx context.Context) (time.Duration, error) + BondDenom(ctx context.Context) (string, error) +} diff --git a/x/poolrebalancer/types/keys.go b/x/poolrebalancer/types/keys.go index d509d793..5605443a 100644 --- a/x/poolrebalancer/types/keys.go +++ b/x/poolrebalancer/types/keys.go @@ -41,7 +41,9 @@ var ( // GetPendingRedelegationKey returns the primary key for a pending redelegation. // Key format: prefix | lengthPrefixed(delegator) | lengthPrefixed(denom) | lengthPrefixed(dstValidator) | completionTime. func GetPendingRedelegationKey(del sdk.AccAddress, denom string, dstVal sdk.ValAddress, completion time.Time) []byte { - key := append(PendingRedelegationKey, address.MustLengthPrefix(del)...) + key := make([]byte, 0) + key = append(key, PendingRedelegationKey...) + key = append(key, address.MustLengthPrefix(del)...) key = append(key, address.MustLengthPrefix([]byte(denom))...) key = append(key, address.MustLengthPrefix(dstVal)...) key = append(key, sdk.FormatTimeBytes(completion)...) @@ -51,7 +53,9 @@ func GetPendingRedelegationKey(del sdk.AccAddress, denom string, dstVal sdk.ValA // GetPendingRedelegationBySrcIndexKey returns the index key for lookup by source validator. // Key format: prefix | lengthPrefixed(srcValidator) | lengthPrefixed(completionTime) | lengthPrefixed(denom) | lengthPrefixed(dstVal) | lengthPrefixed(delegator). func GetPendingRedelegationBySrcIndexKey(srcVal sdk.ValAddress, completion time.Time, denom string, dstVal sdk.ValAddress, del sdk.AccAddress) []byte { - key := append(PendingRedelegationBySrcIndexKey, address.MustLengthPrefix(srcVal)...) + key := make([]byte, 0) + key = append(key, PendingRedelegationBySrcIndexKey...) + key = append(key, address.MustLengthPrefix(srcVal)...) key = append(key, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) key = append(key, address.MustLengthPrefix([]byte(denom))...) key = append(key, address.MustLengthPrefix(dstVal)...) @@ -62,7 +66,10 @@ func GetPendingRedelegationBySrcIndexKey(srcVal sdk.ValAddress, completion time. // GetPendingRedelegationQueueKey returns the queue key for a given completion time. // Used to iterate pending redelegations that mature at or before a given time. func GetPendingRedelegationQueueKey(completion time.Time) []byte { - return append(PendingRedelegationQueueKey, sdk.FormatTimeBytes(completion)...) + key := make([]byte, 0) + key = append(key, PendingRedelegationQueueKey...) + key = append(key, sdk.FormatTimeBytes(completion)...) + return key } // ParsePendingRedelegationQueueKey parses the completion time from a pending redelegation queue key. @@ -77,7 +84,9 @@ func ParsePendingRedelegationQueueKey(key []byte) (time.Time, error) { // GetPendingRedelegationPrefix returns the key prefix for (delegator, denom, dstValidator). // Used by HasImmatureRedelegationTo to prefix-scan all completion times for this triple. func GetPendingRedelegationPrefix(del sdk.AccAddress, denom string, dstVal sdk.ValAddress) []byte { - key := append(PendingRedelegationKey, address.MustLengthPrefix(del)...) + key := make([]byte, 0) + key = append(key, PendingRedelegationKey...) + key = append(key, address.MustLengthPrefix(del)...) key = append(key, address.MustLengthPrefix([]byte(denom))...) key = append(key, address.MustLengthPrefix(dstVal)...) return key @@ -86,7 +95,9 @@ func GetPendingRedelegationPrefix(del sdk.AccAddress, denom string, dstVal sdk.V // GetPendingUndelegationQueueKey returns the queue key for (completionTime, delegator). // Key format: prefix | lengthPrefixed(completionTime) | lengthPrefixed(delegator). func GetPendingUndelegationQueueKey(completion time.Time, del sdk.AccAddress) []byte { - key := append(PendingUndelegationQueueKey, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) + key := make([]byte, 0) + key = append(key, PendingUndelegationQueueKey...) + key = append(key, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) key = append(key, address.MustLengthPrefix(del)...) return key } @@ -95,7 +106,10 @@ func GetPendingUndelegationQueueKey(completion time.Time, del sdk.AccAddress) [] // Key format: PendingUndelegationQueueKey (0x21) + lengthPrefixed(FormatTimeBytes(completion)). // This is used as an end key when iterating all queued undelegations up to a given time. func GetPendingUndelegationQueueKeyByTime(completion time.Time) []byte { - return append(PendingUndelegationQueueKey, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) + key := make([]byte, 0) + key = append(key, PendingUndelegationQueueKey...) + key = append(key, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) + return key } // ParsePendingUndelegationQueueKeyForCompletionTime parses the completion time from a pending undelegation queue key. @@ -117,7 +131,9 @@ func ParsePendingUndelegationQueueKeyForCompletionTime(key []byte) (time.Time, e // GetPendingUndelegationByValIndexKey returns the index key for lookup by validator. // Key format: prefix | lengthPrefixed(validator) | lengthPrefixed(completionTime) | lengthPrefixed(denom) | lengthPrefixed(delegator). func GetPendingUndelegationByValIndexKey(val sdk.ValAddress, completion time.Time, denom string, del sdk.AccAddress) []byte { - key := append(PendingUndelegationByValIndexKey, address.MustLengthPrefix(val)...) + key := make([]byte, 0) + key = append(key, PendingUndelegationByValIndexKey...) + key = append(key, address.MustLengthPrefix(val)...) key = append(key, address.MustLengthPrefix(sdk.FormatTimeBytes(completion))...) key = append(key, address.MustLengthPrefix([]byte(denom))...) key = append(key, address.MustLengthPrefix(del)...) From 3e799f76ea1ff4da3b26260d29e836dee6448997 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Thu, 19 Mar 2026 17:26:34 +0530 Subject: [PATCH 10/31] test(poolrebalancer): improve e2e observability and fix capped redelegation tie-break Signed-off-by: Nikhil Sharma --- .../poolrebalancer_rebalance_e2e.sh | 159 ++++++++++++++++-- x/poolrebalancer/keeper/rebalance.go | 10 +- x/poolrebalancer/keeper/rebalance_test.go | 20 +++ 3 files changed, 174 insertions(+), 15 deletions(-) diff --git a/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh b/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh index 2975ccd8..da2d21f0 100755 --- a/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh +++ b/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh @@ -1,6 +1,27 @@ #!/usr/bin/env bash set -euo pipefail +# ----------------------------------------------------------------------------- +# poolrebalancer_rebalance_e2e.sh +# +# Purpose: +# Manual local E2E test for x/poolrebalancer behavior on a 3-validator devnet. +# +# Scope: +# - Local engineer workflow / debugging aid. +# - Not intended as a deterministic CI test harness. +# +# Prerequisites: +# - jq, curl, evmd installed and on PATH. +# - VAL0_MNEMONIC / VAL1_MNEMONIC / VAL2_MNEMONIC exported. +# +# Quick start: +# bash scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh +# +# Live monitor only: +# bash scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh watch +# ----------------------------------------------------------------------------- + ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" BASEDIR="${BASEDIR:-"$HOME/.og-evm-devnet"}" NODE_RPC="${NODE_RPC:-"tcp://127.0.0.1:26657"}" @@ -10,10 +31,15 @@ HOME0="$BASEDIR/val0" # ---- Test knobs (override via env) ---- POOLREBALANCER_MAX_TARGET_VALIDATORS="${POOLREBALANCER_MAX_TARGET_VALIDATORS:-3}" -POOLREBALANCER_THRESHOLD_BP="${POOLREBALANCER_THRESHOLD_BP:-1}" -POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-1}" -POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-1000000000000000000}" # 1e18 -POOLREBALANCER_USE_UNDELEGATE_FALLBACK="${POOLREBALANCER_USE_UNDELEGATE_FALLBACK:-true}" +# Demo profile controls default speed so users can observe behavior. +# slow = very gradual progress (good for watching) +# medium = balanced default for demo +# fast = converges quickly +DEMO_PROFILE="${DEMO_PROFILE:-medium}" +POOLREBALANCER_THRESHOLD_BP="${POOLREBALANCER_THRESHOLD_BP:-0}" +POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-2}" +POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-100000000000000000000}" # 1e20 +POOLREBALANCER_USE_UNDELEGATE_FALLBACK="${POOLREBALANCER_USE_UNDELEGATE_FALLBACK:-false}" # Staking params tuned so maturity/fallback behavior is visible quickly in local runs. STAKING_UNBONDING_TIME="${STAKING_UNBONDING_TIME:-30s}" @@ -27,10 +53,14 @@ IMBALANCE_MINOR_DELEGATION="${IMBALANCE_MINOR_DELEGATION:-100ogwei}" POLL_SAMPLES="${POLL_SAMPLES:-25}" POLL_SLEEP_SECS="${POLL_SLEEP_SECS:-2}" +STREAM_VALIDATOR_LOGS="${STREAM_VALIDATOR_LOGS:-true}" +KEEP_RUNNING="${KEEP_RUNNING:-true}" + +LOG_STREAM_PIDS=() usage() { cat </dev/null 2>&1 || true + done + LOG_STREAM_PIDS=() +} + +start_validator_log_streams() { + mkdir -p "$BASEDIR/logs" + for v in 0 1 2; do + local f="$BASEDIR/logs/val${v}.log" + touch "$f" + tail -n 0 -F "$f" | sed -u "s/^/[val${v}] /" & + LOG_STREAM_PIDS+=("$!") + done +} + wait_for_height() { local timeout_secs="${1:-30}" local start @@ -223,12 +279,22 @@ delegate_with_wait() { assert_pending_invariants() { local json="$1" local cap="$2" - - local badAmt - badAmt="$(echo "$json" | jq -r --argjson cap "$cap" '[.redelegations[] | (.amount.amount|tonumber) > $cap] | any')" - if [[ "$badAmt" != "false" ]]; then - echo "FAIL: found pending amount > max_move_per_op" >&2 - return 1 + local max_ops="$3" + + # Important nuance: + # pending-redelegations query returns primary records that can merge multiple ops + # sharing (delegator, denom, dst, completionTime). With max_ops_per_block > 1, + # a merged record amount can exceed max_move_per_op even if each individual op respected the cap. + # So strict cap assertion is only sound when max_ops_per_block == 1. + if [[ "$cap" != "0" && "$max_ops" == "1" ]]; then + local badAmt + badAmt="$(echo "$json" | jq -r --argjson cap "$cap" '[.redelegations[] | (.amount.amount|tonumber) > $cap] | any')" + if [[ "$badAmt" != "false" ]]; then + echo "FAIL: found pending amount > max_move_per_op" >&2 + return 1 + fi + elif [[ "$cap" != "0" && "$max_ops" != "1" ]]; then + echo "note: skipping strict max_move_per_op check on merged primary entries (max_ops_per_block=$max_ops)" fi # Transitive safety: no source validator should also appear as destination in-flight. @@ -240,7 +306,39 @@ assert_pending_invariants() { fi } +watch_rebalance_status() { + local node="${NODE_RPC:-tcp://127.0.0.1:26657}" + local interval="${POLL_SLEEP_SECS:-2}" + + while true; do + local h params del pr pu + h="$(curl -sS http://127.0.0.1:26657/status | jq -r '.result.sync_info.latest_block_height // "n/a"')" + params="$(evmd query poolrebalancer params --node "$node" -o json 2>/dev/null || echo '{}')" + del="$(echo "$params" | jq -r '.params.pool_delegator_address // empty')" + pr="$(evmd query poolrebalancer pending-redelegations --node "$node" -o json 2>/dev/null | jq -r '.redelegations | length // 0')" + pu="$(evmd query poolrebalancer pending-undelegations --node "$node" -o json 2>/dev/null | jq -r '.undelegations | length // 0')" + + echo "----- rebalance watch -----" + echo "height=$h pending_red=$pr pending_und=$pu" + echo "$params" | jq -r '.params | {pool_delegator_address,max_target_validators,rebalance_threshold_bp,max_ops_per_block,max_move_per_op,use_undelegate_fallback}' + + if [[ -n "$del" ]]; then + evmd query staking delegations "$del" --node "$node" -o json 2>/dev/null | \ + jq -r '.delegation_responses[]? | {validator: .delegation.validator_address, amount: .balance.amount, denom: .balance.denom}' + else + echo "pool delegator not configured" + fi + echo + sleep "$interval" + done +} + main() { + if [[ "${1:-}" == "watch" ]]; then + watch_rebalance_status + exit 0 + fi + if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then usage; exit 0 fi @@ -249,6 +347,24 @@ main() { require_bin curl require_bin evmd + case "$DEMO_PROFILE" in + slow) + POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-1}" + POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-10000000000000000000}" # 1e19 + ;; + medium) + # Defaults already set above. + ;; + fast) + POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-10}" + POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-0}" # no cap + ;; + *) + echo "invalid DEMO_PROFILE: $DEMO_PROFILE (expected: slow|medium|fast)" >&2 + exit 1 + ;; + esac + if [[ -z "${VAL0_MNEMONIC:-}" || -z "${VAL1_MNEMONIC:-}" || -z "${VAL2_MNEMONIC:-}" ]]; then echo "VAL0_MNEMONIC/VAL1_MNEMONIC/VAL2_MNEMONIC must be set" >&2 exit 1 @@ -256,6 +372,7 @@ main() { echo "==> Stopping any existing localnet" stop_nodes + trap cleanup_log_streams EXIT echo "==> Generating genesis (3 validators) at $BASEDIR" # multi_node_startup.sh is verbose during init; silence setup noise here. @@ -267,6 +384,7 @@ main() { del_mnemonic="$(dev0_mnemonic_from_file)" echo "==> Pool delegator (dev0) = $del_addr" + echo "==> DEMO_PROFILE=$DEMO_PROFILE threshold_bp=$POOLREBALANCER_THRESHOLD_BP max_ops_per_block=$POOLREBALANCER_MAX_OPS_PER_BLOCK max_move_per_op=$POOLREBALANCER_MAX_MOVE_PER_OP fallback=$POOLREBALANCER_USE_UNDELEGATE_FALLBACK" echo "==> Patching genesis staking params (unbonding_time + max_entries)" patch_genesis_staking_params echo "==> Patching genesis poolrebalancer params" @@ -277,6 +395,10 @@ main() { (cd "$ROOT_DIR" && START_VALIDATOR=true NODE_NUMBER=0 ./multi_node_startup.sh >"$BASEDIR/logs/val0.log" 2>&1 &) (cd "$ROOT_DIR" && START_VALIDATOR=true NODE_NUMBER=1 ./multi_node_startup.sh >"$BASEDIR/logs/val1.log" 2>&1 &) (cd "$ROOT_DIR" && START_VALIDATOR=true NODE_NUMBER=2 ./multi_node_startup.sh >"$BASEDIR/logs/val2.log" 2>&1 &) + if [[ "$STREAM_VALIDATOR_LOGS" == "true" ]]; then + echo "==> Streaming validator logs (val0/val1/val2)" + start_validator_log_streams + fi echo "==> Waiting for block production" local h @@ -341,12 +463,23 @@ main() { echo "sample=$i height=$height pending_redelegations=$pending" if (( pending > 0 )); then - assert_pending_invariants "$j" "$POOLREBALANCER_MAX_MOVE_PER_OP" + assert_pending_invariants "$j" "$POOLREBALANCER_MAX_MOVE_PER_OP" "$POOLREBALANCER_MAX_OPS_PER_BLOCK" local pendingUndel pendingUndel="$(evmd query poolrebalancer pending-undelegations --node "$NODE_RPC" -o json | jq -r '.undelegations | length')" echo "pending_undelegations=$pendingUndel" echo "PASS: pending redelegations observed and invariants hold" - exit 0 + if [[ "$KEEP_RUNNING" != "true" ]]; then + exit 0 + fi + echo "==> KEEP_RUNNING=true, continuing in monitor mode (Ctrl+C to stop)" + while true; do + local monitorHeight monitorRed monitorUnd + monitorHeight="$(curl -sS http://127.0.0.1:26657/status | jq -r '.result.sync_info.latest_block_height')" + monitorRed="$(evmd query poolrebalancer pending-redelegations --node "$NODE_RPC" -o json | jq -r '.redelegations | length')" + monitorUnd="$(evmd query poolrebalancer pending-undelegations --node "$NODE_RPC" -o json | jq -r '.undelegations | length')" + echo "monitor height=$monitorHeight pending_red=$monitorRed pending_und=$monitorUnd" + sleep "$POLL_SLEEP_SECS" + done fi sleep "$POLL_SLEEP_SECS" done diff --git a/x/poolrebalancer/keeper/rebalance.go b/x/poolrebalancer/keeper/rebalance.go index c83202d2..391ce07d 100644 --- a/x/poolrebalancer/keeper/rebalance.go +++ b/x/poolrebalancer/keeper/rebalance.go @@ -161,6 +161,7 @@ func (k Keeper) PickBestRedelegation( maxMove math.Int, ) (src string, dst string, amt math.Int, ok bool) { bestAmt := math.ZeroInt() + bestDstNeed := math.ZeroInt() bestSrc := "" bestDst := "" @@ -187,9 +188,14 @@ func (k Keeper) PickBestRedelegation( if move.IsZero() { continue } - // Prefer larger moves; tie-break deterministically. - if move.GT(bestAmt) || (move.Equal(bestAmt) && (s < bestSrc || (s == bestSrc && d < bestDst))) { + // Prefer larger moves. + // If move ties (common when capped), prefer destination with larger deficit. + // Final tie-break stays deterministic on (src,dst). + if move.GT(bestAmt) || + (move.Equal(bestAmt) && (dd.GT(bestDstNeed) || + (dd.Equal(bestDstNeed) && (s < bestSrc || (s == bestSrc && d < bestDst))))) { bestAmt = move + bestDstNeed = dd bestSrc = s bestDst = d } diff --git a/x/poolrebalancer/keeper/rebalance_test.go b/x/poolrebalancer/keeper/rebalance_test.go index 4162601e..dad3bae0 100644 --- a/x/poolrebalancer/keeper/rebalance_test.go +++ b/x/poolrebalancer/keeper/rebalance_test.go @@ -251,6 +251,26 @@ func TestPickBestRedelegation_TieBreak(t *testing.T) { require.True(t, amt.Equal(math.NewInt(10))) } +// TestPickBestRedelegation_CappedTiePrefersLargerDstDeficit verifies that when capped move +// amounts tie, destination with larger deficit is selected. +func TestPickBestRedelegation_CappedTiePrefersLargerDstDeficit(t *testing.T) { + k := keeper.Keeper{} + deltas := map[string]math.Int{ + "src": math.NewInt(-100), + "dstA": math.NewInt(1000), + "dstB": math.NewInt(500), + } + keys := sortedKeys(deltas) + blocked := make(map[string]map[string]struct{}) + maxMove := math.NewInt(10) // both candidates cap to move=10 + + src, dst, amt, ok := k.PickBestRedelegation(deltas, keys, blocked, maxMove) + require.True(t, ok) + require.Equal(t, "src", src) + require.Equal(t, "dstA", dst, "larger deficit destination should win tie under cap") + require.True(t, amt.Equal(math.NewInt(10))) +} + // TestPickBestRedelegation_NoSourceOrDest tests cases where no move is possible. func TestPickBestRedelegation_NoSourceOrDest(t *testing.T) { k := keeper.Keeper{} From d73cccdd8736e631005761c988f3480acd6f5390 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Fri, 20 Mar 2026 16:23:18 +0530 Subject: [PATCH 11/31] feat(poolrebalancer-e2e): refactor scenario runner, document params, and harden fallback assertions Signed-off-by: Nikhil Sharma --- multi_node_startup.sh | 67 +- .../poolrebalancer_rebalance_e2e.sh | 495 -------- tests/e2e/poolrebalancer/README.md | 62 + .../rebalance_scenario_runner.sh | 1044 +++++++++++++++++ 4 files changed, 1143 insertions(+), 525 deletions(-) delete mode 100755 scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh create mode 100644 tests/e2e/poolrebalancer/README.md create mode 100755 tests/e2e/poolrebalancer/rebalance_scenario_runner.sh diff --git a/multi_node_startup.sh b/multi_node_startup.sh index fcd3b59b..ca71fc25 100755 --- a/multi_node_startup.sh +++ b/multi_node_startup.sh @@ -7,26 +7,21 @@ KEYALGO="eth_secp256k1" LOGLEVEL="info" BASEFEE=10000000 BASEDIR="${BASEDIR:-"$HOME/.og-evm-devnet"}" +VALIDATOR_COUNT="${VALIDATOR_COUNT:-3}" NODE_NUMBER="${NODE_NUMBER:-}" START_VALIDATOR="${START_VALIDATOR:-false}" GENERATE_GENESIS="${GENERATE_GENESIS:-false}" -VAL0_MNEMONIC="${VAL0_MNEMONIC:-}" -VAL1_MNEMONIC="${VAL1_MNEMONIC:-}" -VAL2_MNEMONIC="${VAL2_MNEMONIC:-}" - get_p2p_port() { echo $((26656 + ($1 * 100))); } get_rpc_port() { echo $((26657 + ($1 * 100))); } get_grpc_port() { echo $((9090 + ($1 * 10))); } get_jsonrpc_port() { echo $((8545 + ($1 * 10))); } get_val_mnemonic() { - case $1 in - 0) echo "$VAL0_MNEMONIC" ;; - 1) echo "$VAL1_MNEMONIC" ;; - 2) echo "$VAL2_MNEMONIC" ;; - esac + local idx="$1" + local var_name="VAL${idx}_MNEMONIC" + echo "${!var_name:-}" } get_home_dir() { echo "$BASEDIR/val$1"; } @@ -39,9 +34,10 @@ usage() { echo "Usage: $0 [options]" echo "" echo "Environment Variables:" - echo " GENERATE_GENESIS=true Generate genesis for all 3 validators" + echo " GENERATE_GENESIS=true Generate genesis for all validators" echo " START_VALIDATOR=true Start a validator" - echo " NODE_NUMBER=0|1|2 Which validator to start" + echo " NODE_NUMBER=0..N-1 Which validator to start" + echo " VALIDATOR_COUNT=3 Validator count for genesis/startup" echo " BASEDIR=path Base directory (default: ~/.og-evm-devnet)" echo "" echo "Options:" @@ -143,7 +139,7 @@ set_persistent_peers() { local CONFIG_TOML="$HOME_DIR/config/config.toml" local PEERS="" - for i in 0 1 2; do + for i in $(seq 0 $((VALIDATOR_COUNT - 1))); do if [[ $i -ne $NODE_NUM ]]; then local PEER_PORT=$(get_p2p_port $i) if [[ -n "$PEERS" ]]; then @@ -203,7 +199,7 @@ generate_dev_accounts() { generate_genesis() { echo "==========================================" - echo "Generating genesis for 3 validators..." + echo "Generating genesis for $VALIDATOR_COUNT validators..." echo "Base directory: $BASEDIR" echo "==========================================" @@ -225,10 +221,15 @@ generate_genesis() { echo "" echo ">>> Step 1: Initializing all validators..." - for i in 0 1 2; do + for i in $(seq 0 $((VALIDATOR_COUNT - 1))); do HOME_DIR=$(get_home_dir $i) MNEMONIC=$(get_val_mnemonic $i) VALKEY="val${i}" + if [[ -z "$MNEMONIC" ]]; then + echo "Error: VAL${i}_MNEMONIC is required for validator $i" + exit 1 + fi + echo "--- Initializing validator $i at $HOME_DIR ---" @@ -251,7 +252,7 @@ generate_genesis() { echo "" echo ">>> Step 3: Adding all validator accounts with initial balances..." - for i in 0 1 2; do + for i in $(seq 0 $((VALIDATOR_COUNT - 1))); do VALKEY="val${i}" VAL_HOME=$(get_home_dir $i) @@ -267,14 +268,14 @@ generate_genesis() { echo "" echo ">>> Step 5: Copying genesis to all validators..." - for i in 1 2; do + for i in $(seq 1 $((VALIDATOR_COUNT - 1))); do cp "$GENESIS" "$(get_home_dir $i)/config/genesis.json" echo "Copied genesis to val$i" done echo "" echo ">>> Step 6: Creating gentx for each validator..." - for i in 0 1 2; do + for i in $(seq 0 $((VALIDATOR_COUNT - 1))); do HOME_DIR=$(get_home_dir $i) VALKEY="val${i}" P2P_PORT=$(get_p2p_port $i) @@ -292,7 +293,7 @@ generate_genesis() { echo "" echo ">>> Step 7: Collecting all gentxs..." GENTX_DIR="$(get_home_dir 0)/config/gentx" - for i in 1 2; do + for i in $(seq 1 $((VALIDATOR_COUNT - 1))); do cp "$(get_home_dir $i)/config/gentx/"*.json "$GENTX_DIR/" echo "Copied gentx from val$i" done @@ -304,22 +305,23 @@ generate_genesis() { echo "" echo ">>> Step 8: Distributing final genesis to all validators..." FINAL_GENESIS="$(get_home_dir 0)/config/genesis.json" - for i in 1 2; do + for i in $(seq 1 $((VALIDATOR_COUNT - 1))); do cp "$FINAL_GENESIS" "$(get_home_dir $i)/config/genesis.json" echo "Copied final genesis to val$i" done echo "" echo ">>> Step 9: Applying config customizations and setting peers..." - for i in 0 1 2; do + for i in $(seq 0 $((VALIDATOR_COUNT - 1))); do HOME_DIR=$(get_home_dir $i) apply_config_customizations "$HOME_DIR" "$i" set_persistent_peers "$HOME_DIR" "$i" "${NODE_IDS[@]}" done - echo "NODE0_ID=${NODE_IDS[0]}" > "$BASEDIR/node_ids.txt" - echo "NODE1_ID=${NODE_IDS[1]}" >> "$BASEDIR/node_ids.txt" - echo "NODE2_ID=${NODE_IDS[2]}" >> "$BASEDIR/node_ids.txt" + : > "$BASEDIR/node_ids.txt" + for i in $(seq 0 $((VALIDATOR_COUNT - 1))); do + echo "NODE${i}_ID=${NODE_IDS[$i]}" >> "$BASEDIR/node_ids.txt" + done echo "" echo "==========================================" @@ -330,14 +332,19 @@ generate_genesis() { echo " $BASEDIR/" echo " ├── val0/ (Validator 0 home)" echo " ├── val1/ (Validator 1 home)" - echo " ├── val2/ (Validator 2 home)" + if (( VALIDATOR_COUNT >= 3 )); then + echo " ├── val2/ (Validator 2 home)" + fi + if (( VALIDATOR_COUNT > 3 )); then + echo " ├── ... (Validator 3..$((VALIDATOR_COUNT - 1)) home)" + fi echo " ├── dev_accounts.txt (10 funded dev accounts)" echo " └── node_ids.txt" echo "" echo "Port mapping:" - echo " val0: P2P=26656, RPC=26657, gRPC=9090, JSON-RPC=8545" - echo " val1: P2P=26756, RPC=26757, gRPC=9091, JSON-RPC=8546" - echo " val2: P2P=26856, RPC=26857, gRPC=9092, JSON-RPC=8547" + for i in $(seq 0 $((VALIDATOR_COUNT - 1))); do + echo " val${i}: P2P=$(get_p2p_port "$i"), RPC=$(get_rpc_port "$i"), gRPC=$(get_grpc_port "$i"), JSON-RPC=$(get_jsonrpc_port "$i")" + done echo "" echo "Validators funded: 100000000000000000000000000ogwei each" echo "Dev accounts funded: 1000000000000000000000000ogwei each" @@ -347,12 +354,12 @@ generate_genesis() { start_validator() { if [[ -z "$NODE_NUMBER" ]]; then - echo "Error: NODE_NUMBER env variable required (0, 1, or 2)" + echo "Error: NODE_NUMBER env variable required (0..$((VALIDATOR_COUNT - 1)))" exit 1 fi - if [[ ! "$NODE_NUMBER" =~ ^[0-2]$ ]]; then - echo "Error: NODE_NUMBER must be 0, 1, or 2" + if [[ ! "$NODE_NUMBER" =~ ^[0-9]+$ ]] || (( NODE_NUMBER < 0 || NODE_NUMBER >= VALIDATOR_COUNT )); then + echo "Error: NODE_NUMBER must be between 0 and $((VALIDATOR_COUNT - 1))" exit 1 fi diff --git a/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh b/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh deleted file mode 100755 index da2d21f0..00000000 --- a/scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh +++ /dev/null @@ -1,495 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# ----------------------------------------------------------------------------- -# poolrebalancer_rebalance_e2e.sh -# -# Purpose: -# Manual local E2E test for x/poolrebalancer behavior on a 3-validator devnet. -# -# Scope: -# - Local engineer workflow / debugging aid. -# - Not intended as a deterministic CI test harness. -# -# Prerequisites: -# - jq, curl, evmd installed and on PATH. -# - VAL0_MNEMONIC / VAL1_MNEMONIC / VAL2_MNEMONIC exported. -# -# Quick start: -# bash scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh -# -# Live monitor only: -# bash scripts/poolrebalancer/poolrebalancer_rebalance_e2e.sh watch -# ----------------------------------------------------------------------------- - -ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" -BASEDIR="${BASEDIR:-"$HOME/.og-evm-devnet"}" -NODE_RPC="${NODE_RPC:-"tcp://127.0.0.1:26657"}" -CHAIN_ID="${CHAIN_ID:-10740}" -KEYRING="${KEYRING:-test}" -HOME0="$BASEDIR/val0" - -# ---- Test knobs (override via env) ---- -POOLREBALANCER_MAX_TARGET_VALIDATORS="${POOLREBALANCER_MAX_TARGET_VALIDATORS:-3}" -# Demo profile controls default speed so users can observe behavior. -# slow = very gradual progress (good for watching) -# medium = balanced default for demo -# fast = converges quickly -DEMO_PROFILE="${DEMO_PROFILE:-medium}" -POOLREBALANCER_THRESHOLD_BP="${POOLREBALANCER_THRESHOLD_BP:-0}" -POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-2}" -POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-100000000000000000000}" # 1e20 -POOLREBALANCER_USE_UNDELEGATE_FALLBACK="${POOLREBALANCER_USE_UNDELEGATE_FALLBACK:-false}" - -# Staking params tuned so maturity/fallback behavior is visible quickly in local runs. -STAKING_UNBONDING_TIME="${STAKING_UNBONDING_TIME:-30s}" -STAKING_MAX_ENTRIES="${STAKING_MAX_ENTRIES:-100}" - -TX_FEES="${TX_FEES:-200000000000000ogwei}" # denom will be rewritten after chain start - -# Delegation amounts used to create a clear imbalance (safe with default dev funding). -IMBALANCE_MAIN_DELEGATION="${IMBALANCE_MAIN_DELEGATION:-200000000000000000000000ogwei}" # denom rewritten after chain start -IMBALANCE_MINOR_DELEGATION="${IMBALANCE_MINOR_DELEGATION:-100ogwei}" - -POLL_SAMPLES="${POLL_SAMPLES:-25}" -POLL_SLEEP_SECS="${POLL_SLEEP_SECS:-2}" -STREAM_VALIDATOR_LOGS="${STREAM_VALIDATOR_LOGS:-true}" -KEEP_RUNNING="${KEEP_RUNNING:-true}" - -LOG_STREAM_PIDS=() - -usage() { - cat </dev/null 2>&1 || { echo "missing dependency: $1" >&2; exit 1; } -} - -stop_nodes() { - # Aggressive cleanup: multi_node_startup.sh launches `evmd start` processes directly. - pkill -f "evmd start" >/dev/null 2>&1 || true - pkill -f "multi_node_startup.sh" >/dev/null 2>&1 || true - # Give the OS a moment to release RPC/P2P ports. - sleep 1 -} - -cleanup_log_streams() { - if (( ${#LOG_STREAM_PIDS[@]} == 0 )); then - return 0 - fi - for pid in "${LOG_STREAM_PIDS[@]}"; do - kill "$pid" >/dev/null 2>&1 || true - done - LOG_STREAM_PIDS=() -} - -start_validator_log_streams() { - mkdir -p "$BASEDIR/logs" - for v in 0 1 2; do - local f="$BASEDIR/logs/val${v}.log" - touch "$f" - tail -n 0 -F "$f" | sed -u "s/^/[val${v}] /" & - LOG_STREAM_PIDS+=("$!") - done -} - -wait_for_height() { - local timeout_secs="${1:-30}" - local start - start="$(date +%s)" - while true; do - local h - h="$(curl -sS --max-time 1 http://127.0.0.1:26657/status 2>/dev/null | jq -r '.result.sync_info.latest_block_height' 2>/dev/null || echo 0)" - if [[ "$h" != "0" ]]; then - echo "$h" - return 0 - fi - if (( $(date +%s) - start > timeout_secs )); then - echo "timed out waiting for height > 0" >&2 - return 1 - fi - sleep 1 - done -} - -dev0_address_from_file() { - awk '/^dev0:/{f=1} f && $1=="address:"{print $2; exit}' "$BASEDIR/dev_accounts.txt" -} - -dev0_mnemonic_from_file() { - awk '/^dev0:/{f=1} f && $1=="mnemonic:"{for(i=2;i<=NF;i++){printf (i==2?"":" ") $i} print ""; exit}' "$BASEDIR/dev_accounts.txt" -} - -patch_genesis_poolrebalancer_params() { - local del_addr="$1" - local gen0="$BASEDIR/val0/config/genesis.json" - local tmp="$BASEDIR/val0/config/genesis.tmp.json" - - jq --arg del "$del_addr" \ - --argjson maxTargets "$POOLREBALANCER_MAX_TARGET_VALIDATORS" \ - --argjson thr "$POOLREBALANCER_THRESHOLD_BP" \ - --argjson maxOps "$POOLREBALANCER_MAX_OPS_PER_BLOCK" \ - --arg maxMove "$POOLREBALANCER_MAX_MOVE_PER_OP" \ - --argjson useUndel "$POOLREBALANCER_USE_UNDELEGATE_FALLBACK" \ - ' .app_state.poolrebalancer.params.pool_delegator_address = $del - | .app_state.poolrebalancer.params.max_target_validators = $maxTargets - | .app_state.poolrebalancer.params.rebalance_threshold_bp = $thr - | .app_state.poolrebalancer.params.max_ops_per_block = $maxOps - | .app_state.poolrebalancer.params.max_move_per_op = $maxMove - | .app_state.poolrebalancer.params.use_undelegate_fallback = $useUndel - ' "$gen0" > "$tmp" - - mv "$tmp" "$gen0" - cp "$gen0" "$BASEDIR/val1/config/genesis.json" - cp "$gen0" "$BASEDIR/val2/config/genesis.json" - - evmd genesis validate-genesis --home "$BASEDIR/val0" >/dev/null -} - -patch_genesis_staking_params() { - local gen0="$BASEDIR/val0/config/genesis.json" - local tmp="$BASEDIR/val0/config/genesis.tmp.json" - - jq --arg unbond "$STAKING_UNBONDING_TIME" \ - --argjson maxEntries "$STAKING_MAX_ENTRIES" \ - ' .app_state.staking.params.unbonding_time = $unbond - | .app_state.staking.params.max_entries = $maxEntries - ' "$gen0" > "$tmp" - - mv "$tmp" "$gen0" -} - -import_dev0_key() { - local mnemonic="$1" - (evmd keys delete dev0 -y --keyring-backend "$KEYRING" --home "$HOME0" >/dev/null 2>&1) || true - echo "$mnemonic" | evmd keys add dev0 --recover --keyring-backend "$KEYRING" --home "$HOME0" >/dev/null -} - -wait_tx_included() { - local txhash="$1" - # First try CometBFT /tx; it becomes available as soon as tx is committed. - local rpc_http="http://127.0.0.1:26657" - for _ in $(seq 1 40); do - local resp - resp="$(curl -sS --max-time 1 "${rpc_http}/tx?hash=0x${txhash}" 2>/dev/null || true)" - # Not-found still returns JSON. Treat as committed only when .result.tx_result exists. - if echo "$resp" | jq -e '.result.tx_result' >/dev/null 2>&1; then - # Committed does not mean successful; require code=0. - local code - code="$(echo "$resp" | jq -r '.result.tx_result.code' 2>/dev/null || echo 1)" - if [[ "$code" == "0" ]]; then - return 0 - fi - echo "tx committed but failed (code=$code): $txhash" >&2 - echo "$resp" | jq -r '.result.tx_result.log' >&2 || true - return 1 - fi - # Fallback query path (depends on tx indexing config). - if evmd query tx "$txhash" --node "$NODE_RPC" -o json >/dev/null 2>&1; then - return 0 - fi - sleep 1 - done - echo "tx not found after waiting: $txhash" >&2 - echo "check logs: $BASEDIR/logs/val0.log" >&2 - return 1 -} - -delegate_with_wait() { - local valoper="$1" - local amount="$2" - # Some CLI builds return txhash even on CheckTx failure, so always inspect `.code`. - for attempt in 1 2 3; do - local out - out="$(evmd tx staking delegate "$valoper" "$amount" \ - --from dev0 \ - --keyring-backend "$KEYRING" \ - --home "$HOME0" \ - --chain-id "$CHAIN_ID" \ - --node "$NODE_RPC" \ - --gas auto --gas-adjustment 1.3 \ - --fees "$TX_FEES" \ - -b sync -y -o json)" - - local code - code="$(echo "$out" | jq -r '.code // 0')" - local txhash - txhash="$(echo "$out" | jq -r '.txhash')" - - if [[ "$code" != "0" ]]; then - local log - log="$(echo "$out" | jq -r '.raw_log // .log // empty')" - echo "delegate failed (attempt=$attempt code=$code): $log" >&2 - - # Common transient: sequence mismatch while previous tx is still propagating. - if echo "$log" | grep -qi "account sequence mismatch"; then - sleep 2 - continue - fi - return 1 - fi - - echo "delegate $amount -> $valoper txhash=$txhash" - wait_tx_included "$txhash" >/dev/null - return 0 - done - - echo "delegate failed after retries: $amount -> $valoper" >&2 - return 1 -} - -assert_pending_invariants() { - local json="$1" - local cap="$2" - local max_ops="$3" - - # Important nuance: - # pending-redelegations query returns primary records that can merge multiple ops - # sharing (delegator, denom, dst, completionTime). With max_ops_per_block > 1, - # a merged record amount can exceed max_move_per_op even if each individual op respected the cap. - # So strict cap assertion is only sound when max_ops_per_block == 1. - if [[ "$cap" != "0" && "$max_ops" == "1" ]]; then - local badAmt - badAmt="$(echo "$json" | jq -r --argjson cap "$cap" '[.redelegations[] | (.amount.amount|tonumber) > $cap] | any')" - if [[ "$badAmt" != "false" ]]; then - echo "FAIL: found pending amount > max_move_per_op" >&2 - return 1 - fi - elif [[ "$cap" != "0" && "$max_ops" != "1" ]]; then - echo "note: skipping strict max_move_per_op check on merged primary entries (max_ops_per_block=$max_ops)" - fi - - # Transitive safety: no source validator should also appear as destination in-flight. - local badTrans - badTrans="$(echo "$json" | jq -r '([.redelegations[].src_validator_address] | unique) as $srcs | ([.redelegations[].dst_validator_address] | unique) as $dsts | ([ $srcs[] | . as $s | (($dsts | index($s)) != null) ] | any)')" - if [[ "$badTrans" != "false" ]]; then - echo "FAIL: transitive safety violated (src appears in dst set)" >&2 - return 1 - fi -} - -watch_rebalance_status() { - local node="${NODE_RPC:-tcp://127.0.0.1:26657}" - local interval="${POLL_SLEEP_SECS:-2}" - - while true; do - local h params del pr pu - h="$(curl -sS http://127.0.0.1:26657/status | jq -r '.result.sync_info.latest_block_height // "n/a"')" - params="$(evmd query poolrebalancer params --node "$node" -o json 2>/dev/null || echo '{}')" - del="$(echo "$params" | jq -r '.params.pool_delegator_address // empty')" - pr="$(evmd query poolrebalancer pending-redelegations --node "$node" -o json 2>/dev/null | jq -r '.redelegations | length // 0')" - pu="$(evmd query poolrebalancer pending-undelegations --node "$node" -o json 2>/dev/null | jq -r '.undelegations | length // 0')" - - echo "----- rebalance watch -----" - echo "height=$h pending_red=$pr pending_und=$pu" - echo "$params" | jq -r '.params | {pool_delegator_address,max_target_validators,rebalance_threshold_bp,max_ops_per_block,max_move_per_op,use_undelegate_fallback}' - - if [[ -n "$del" ]]; then - evmd query staking delegations "$del" --node "$node" -o json 2>/dev/null | \ - jq -r '.delegation_responses[]? | {validator: .delegation.validator_address, amount: .balance.amount, denom: .balance.denom}' - else - echo "pool delegator not configured" - fi - echo - sleep "$interval" - done -} - -main() { - if [[ "${1:-}" == "watch" ]]; then - watch_rebalance_status - exit 0 - fi - - if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then - usage; exit 0 - fi - - require_bin jq - require_bin curl - require_bin evmd - - case "$DEMO_PROFILE" in - slow) - POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-1}" - POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-10000000000000000000}" # 1e19 - ;; - medium) - # Defaults already set above. - ;; - fast) - POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-10}" - POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-0}" # no cap - ;; - *) - echo "invalid DEMO_PROFILE: $DEMO_PROFILE (expected: slow|medium|fast)" >&2 - exit 1 - ;; - esac - - if [[ -z "${VAL0_MNEMONIC:-}" || -z "${VAL1_MNEMONIC:-}" || -z "${VAL2_MNEMONIC:-}" ]]; then - echo "VAL0_MNEMONIC/VAL1_MNEMONIC/VAL2_MNEMONIC must be set" >&2 - exit 1 - fi - - echo "==> Stopping any existing localnet" - stop_nodes - trap cleanup_log_streams EXIT - - echo "==> Generating genesis (3 validators) at $BASEDIR" - # multi_node_startup.sh is verbose during init; silence setup noise here. - (cd "$ROOT_DIR" && GENERATE_GENESIS=true ./multi_node_startup.sh -y >/dev/null 2>&1) - - local del_addr - del_addr="$(dev0_address_from_file)" - local del_mnemonic - del_mnemonic="$(dev0_mnemonic_from_file)" - - echo "==> Pool delegator (dev0) = $del_addr" - echo "==> DEMO_PROFILE=$DEMO_PROFILE threshold_bp=$POOLREBALANCER_THRESHOLD_BP max_ops_per_block=$POOLREBALANCER_MAX_OPS_PER_BLOCK max_move_per_op=$POOLREBALANCER_MAX_MOVE_PER_OP fallback=$POOLREBALANCER_USE_UNDELEGATE_FALLBACK" - echo "==> Patching genesis staking params (unbonding_time + max_entries)" - patch_genesis_staking_params - echo "==> Patching genesis poolrebalancer params" - patch_genesis_poolrebalancer_params "$del_addr" - - echo "==> Starting validators" - mkdir -p "$BASEDIR/logs" - (cd "$ROOT_DIR" && START_VALIDATOR=true NODE_NUMBER=0 ./multi_node_startup.sh >"$BASEDIR/logs/val0.log" 2>&1 &) - (cd "$ROOT_DIR" && START_VALIDATOR=true NODE_NUMBER=1 ./multi_node_startup.sh >"$BASEDIR/logs/val1.log" 2>&1 &) - (cd "$ROOT_DIR" && START_VALIDATOR=true NODE_NUMBER=2 ./multi_node_startup.sh >"$BASEDIR/logs/val2.log" 2>&1 &) - if [[ "$STREAM_VALIDATOR_LOGS" == "true" ]]; then - echo "==> Streaming validator logs (val0/val1/val2)" - start_validator_log_streams - fi - - echo "==> Waiting for block production" - local h - h="$(wait_for_height 60)" - echo "height=$h" - - # Resolve chain bond denom and rewrite amount knobs to match this network. - local bond_denom - bond_denom="$(evmd query staking params --node "$NODE_RPC" -o json | jq -r '.params.bond_denom // .bond_denom')" - if [[ -z "$bond_denom" || "$bond_denom" == "null" ]]; then - echo "FAIL: could not determine bond_denom from staking params" >&2 - exit 1 - fi - echo "bond_denom=$bond_denom" - TX_FEES="${TX_FEES%ogwei}${bond_denom}" - IMBALANCE_MAIN_DELEGATION="${IMBALANCE_MAIN_DELEGATION%ogwei}${bond_denom}" - IMBALANCE_MINOR_DELEGATION="${IMBALANCE_MINOR_DELEGATION%ogwei}${bond_denom}" - - echo "==> Importing dev0 key into keyring" - import_dev0_key "$del_mnemonic" - - echo "==> Creating delegation imbalance" - local vals v0 v1 v2 - vals="$(evmd query staking validators --node "$NODE_RPC" -o json | jq -r '.validators[:3] | .[] | .operator_address')" - v0="$(echo "$vals" | sed -n '1p')" - v1="$(echo "$vals" | sed -n '2p')" - v2="$(echo "$vals" | sed -n '3p')" - - delegate_with_wait "$v0" "$IMBALANCE_MAIN_DELEGATION" - delegate_with_wait "$v1" "$IMBALANCE_MINOR_DELEGATION" - delegate_with_wait "$v2" "$IMBALANCE_MINOR_DELEGATION" - - echo "==> Sanity checks (params + delegations)" - local onchain_del - onchain_del="$(evmd query poolrebalancer params --node "$NODE_RPC" -o json | jq -r '.params.pool_delegator_address')" - if [[ "$onchain_del" != "$del_addr" ]]; then - echo "FAIL: poolrebalancer params.pool_delegator_address mismatch" >&2 - echo " expected: $del_addr" >&2 - echo " got: $onchain_del" >&2 - exit 1 - fi - - local del_count - del_count="$(evmd query staking delegations "$del_addr" --node "$NODE_RPC" -o json | jq -r '.delegation_responses | length')" - echo "delegations_count=$del_count" - - local bonded_count - bonded_count="$(evmd query staking validators --node "$NODE_RPC" -o json | jq -r '[.validators[] | select(.status=="BOND_STATUS_BONDED")] | length')" - echo "bonded_validators=$bonded_count" - if (( bonded_count == 0 )); then - echo "FAIL: no bonded validators found; cannot rebalance" >&2 - exit 1 - fi - - echo "==> Observing pending redelegations" - for i in $(seq 1 "$POLL_SAMPLES"); do - local height pending - height="$(curl -s http://127.0.0.1:26657/status | jq -r '.result.sync_info.latest_block_height')" - local j - j="$(evmd query poolrebalancer pending-redelegations --node "$NODE_RPC" -o json)" - pending="$(echo "$j" | jq -r '.redelegations | length')" - echo "sample=$i height=$height pending_redelegations=$pending" - - if (( pending > 0 )); then - assert_pending_invariants "$j" "$POOLREBALANCER_MAX_MOVE_PER_OP" "$POOLREBALANCER_MAX_OPS_PER_BLOCK" - local pendingUndel - pendingUndel="$(evmd query poolrebalancer pending-undelegations --node "$NODE_RPC" -o json | jq -r '.undelegations | length')" - echo "pending_undelegations=$pendingUndel" - echo "PASS: pending redelegations observed and invariants hold" - if [[ "$KEEP_RUNNING" != "true" ]]; then - exit 0 - fi - echo "==> KEEP_RUNNING=true, continuing in monitor mode (Ctrl+C to stop)" - while true; do - local monitorHeight monitorRed monitorUnd - monitorHeight="$(curl -sS http://127.0.0.1:26657/status | jq -r '.result.sync_info.latest_block_height')" - monitorRed="$(evmd query poolrebalancer pending-redelegations --node "$NODE_RPC" -o json | jq -r '.redelegations | length')" - monitorUnd="$(evmd query poolrebalancer pending-undelegations --node "$NODE_RPC" -o json | jq -r '.undelegations | length')" - echo "monitor height=$monitorHeight pending_red=$monitorRed pending_und=$monitorUnd" - sleep "$POLL_SLEEP_SECS" - done - fi - sleep "$POLL_SLEEP_SECS" - done - - echo "FAIL: did not observe any pending redelegations within polling window" >&2 - echo "Diagnostics:" >&2 - evmd query poolrebalancer params --node "$NODE_RPC" -o json | jq '.' >&2 || true - evmd query staking validators --node "$NODE_RPC" -o json | jq -r '[.validators[] | {op:.operator_address,status:.status}]' >&2 || true - exit 1 -} - -main "$@" - diff --git a/tests/e2e/poolrebalancer/README.md b/tests/e2e/poolrebalancer/README.md new file mode 100644 index 00000000..67b5e8fe --- /dev/null +++ b/tests/e2e/poolrebalancer/README.md @@ -0,0 +1,62 @@ +# Poolrebalancer E2E Scenario Runner + +This document describes how to run manual E2E observation scenarios for `x/poolrebalancer`. + +## Script + +- `tests/e2e/poolrebalancer/rebalance_scenario_runner.sh` + +## Purpose + +- Bootstraps a multi-validator test chain via `multi_node_startup.sh` +- Patches staking and poolrebalancer genesis params for the selected scenario +- Seeds scenario-specific delegation/redelegation state +- Streams validator logs and pending queue state for manual verification + +This runner is intended for contributor workflows and debugging. It is not a strict CI pass/fail harness. + +## Quick Start + +```bash +bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh --help +``` + +```bash +bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh --scenario happy_path --nodes 3 +``` + +```bash +bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh watch +``` + +## Supported Scenarios + +- `happy_path`: baseline rebalance scheduling from a skewed delegation +- `caps`: constrained op/move settings to observe paced scheduling +- `threshold_boundary`: small drift with high threshold (often little/no scheduling) +- `fallback`: constrained redelegation conditions to observe undelegation fallback behavior +- `expansion`: 5-validator setup seeded on 3 validators to observe target-set expansion + +## Parameter Precedence + +When running a scenario, parameter resolution is: + +1. Explicit environment variables (highest priority) +2. Scenario defaults (for knobs not explicitly set) +3. Script baseline defaults + +Example: + +```bash +POOLREBALANCER_MAX_TARGET_VALIDATORS=5 \ +POOLREBALANCER_MAX_OPS_PER_BLOCK=100 \ +bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh --scenario expansion +``` + +## Operational Notes + +- Use `Ctrl+C` to stop. The script traps interrupts and cleans up processes it started. +- If observed behavior differs from expectation, inspect: + - `evmd query poolrebalancer params ...` + - `evmd query poolrebalancer pending-redelegations ...` + - `evmd query poolrebalancer pending-undelegations ...` diff --git a/tests/e2e/poolrebalancer/rebalance_scenario_runner.sh b/tests/e2e/poolrebalancer/rebalance_scenario_runner.sh new file mode 100755 index 00000000..c398876c --- /dev/null +++ b/tests/e2e/poolrebalancer/rebalance_scenario_runner.sh @@ -0,0 +1,1044 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ============================================================================ +# rebalance_scenario_runner.sh +# +# Purpose: +# Manual E2E scenario runner for x/poolrebalancer on a multi-validator test chain. +# +# Scope: +# - Local engineer test workflow for exercising rebalance behavior. +# - Scenario-driven integration-style validation, not a generic chain utility. +# - Not intended as a deterministic CI harness. +# +# What this script helps observe: +# - Pool delegator params are wired correctly in genesis. +# - Rebalance scheduling is created as pending operations in module state. +# - Per-block safety caps are respected: +# * max_ops_per_block +# * max_move_per_op +# - Scenario-specific behavior: +# * normal rebalance (happy_path) +# * cap pressure behavior (caps) +# * threshold no-op behavior (threshold_boundary) +# * undelegation fallback behavior (fallback) +# * dynamic target-set expansion (expansion) +# +# How to read output: +# - "phase=..." lines show the high-level state machine in this script. +# - "pending_red" is pending redelegations in x/poolrebalancer. +# - "pending_und" is pending undelegations in x/poolrebalancer. +# - Log lines are informational and meant for manual inspection. +# +# Test setup patched by this script: +# - staking.params: +# * unbonding_time (default: 30s) +# * max_entries (default: 100, scenario may override) +# - poolrebalancer.params: +# * pool_delegator_address (dev0) +# * max_target_validators +# * rebalance_threshold_bp +# * max_ops_per_block +# * max_move_per_op +# * use_undelegate_fallback +# +# Prerequisites: +# - jq, curl, evmd installed and on PATH. +# - Validator mnemonics are auto-generated for missing VAL{N}_MNEMONIC vars. +# +# Quick start: +# bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh +# +# Watch-only mode: +# bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh watch +# ============================================================================ + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)" +BASEDIR="${BASEDIR:-"$HOME/.og-evm-devnet"}" +NODE_RPC="${NODE_RPC:-"tcp://127.0.0.1:26657"}" +CHAIN_ID="${CHAIN_ID:-10740}" +KEYRING="${KEYRING:-test}" +HOME0="$BASEDIR/val0" + +# ----------------------------------------------------------------------------- +# Runtime knobs (env vars take precedence) +# ----------------------------------------------------------------------------- +# Track which knobs were explicitly provided via environment so scenario defaults +# can apply only when not set by the user. +USER_SET_MAX_TARGET_VALIDATORS=false +[[ -n "${POOLREBALANCER_MAX_TARGET_VALIDATORS+x}" ]] && USER_SET_MAX_TARGET_VALIDATORS=true +USER_SET_THRESHOLD_BP=false +[[ -n "${POOLREBALANCER_THRESHOLD_BP+x}" ]] && USER_SET_THRESHOLD_BP=true +USER_SET_MAX_OPS_PER_BLOCK=false +[[ -n "${POOLREBALANCER_MAX_OPS_PER_BLOCK+x}" ]] && USER_SET_MAX_OPS_PER_BLOCK=true +USER_SET_MAX_MOVE_PER_OP=false +[[ -n "${POOLREBALANCER_MAX_MOVE_PER_OP+x}" ]] && USER_SET_MAX_MOVE_PER_OP=true +USER_SET_USE_UNDELEGATE_FALLBACK=false +[[ -n "${POOLREBALANCER_USE_UNDELEGATE_FALLBACK+x}" ]] && USER_SET_USE_UNDELEGATE_FALLBACK=true +USER_SET_STAKING_MAX_ENTRIES=false +[[ -n "${STAKING_MAX_ENTRIES+x}" ]] && USER_SET_STAKING_MAX_ENTRIES=true +USER_SET_IMBALANCE_MINOR_DELEGATION=false +[[ -n "${IMBALANCE_MINOR_DELEGATION+x}" ]] && USER_SET_IMBALANCE_MINOR_DELEGATION=true + +SCENARIO="${SCENARIO:-happy_path}" +VALIDATOR_COUNT="${VALIDATOR_COUNT:-}" +POOLREBALANCER_MAX_TARGET_VALIDATORS="${POOLREBALANCER_MAX_TARGET_VALIDATORS:-3}" +# Demo profile controls default speed so users can observe behavior. +# slow = very gradual progress (good for watching) +# medium = balanced default for demo +# fast = converges quickly +DEMO_PROFILE="${DEMO_PROFILE:-medium}" +POOLREBALANCER_THRESHOLD_BP="${POOLREBALANCER_THRESHOLD_BP:-0}" +POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-2}" +POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-100000000000000000000}" # 1e20 +POOLREBALANCER_USE_UNDELEGATE_FALLBACK="${POOLREBALANCER_USE_UNDELEGATE_FALLBACK:-false}" + +# Tune staking params so maturity/fallback behavior is visible in test runs. +STAKING_UNBONDING_TIME="${STAKING_UNBONDING_TIME:-30s}" +STAKING_MAX_ENTRIES="${STAKING_MAX_ENTRIES:-100}" + +TX_FEES="${TX_FEES:-200000000000000ogwei}" # denom will be rewritten after chain start + +# Seed amounts used to create a clear imbalance (safe with default dev funding). +IMBALANCE_MAIN_DELEGATION="${IMBALANCE_MAIN_DELEGATION:-200000000000000000000000ogwei}" # denom rewritten after chain start +IMBALANCE_MINOR_DELEGATION="${IMBALANCE_MINOR_DELEGATION:-100ogwei}" + +POLL_SAMPLES="${POLL_SAMPLES:-25}" +POLL_SLEEP_SECS="${POLL_SLEEP_SECS:-2}" +# Always-on observability/runtime behavior for CLI usage. +STREAM_VALIDATOR_LOGS="true" +KEEP_RUNNING="true" +WATCH_COMPACT="${WATCH_COMPACT:-false}" + +LOG_STREAM_PIDS=() +CURRENT_PHASE="init" +SETUP_STARTED="false" +EXPANSION_MISSING_DSTS=() +EXPANSION_OBSERVED_DSTS_TEXT="" +EXPANSION_INITIAL_DELEGATED=() +FALLBACK_SEEN_REDELEGATION="false" +FALLBACK_UND_DEADLINE_SAMPLES="${FALLBACK_UND_DEADLINE_SAMPLES:-15}" + +on_interrupt() { + echo + echo "==> Interrupt received, stopping test setup..." + # Stop child processes spawned by this script first. + pkill -TERM -P "$$" >/dev/null 2>&1 || true + cleanup_on_exit + exit 130 +} + +cleanup_on_exit() { + cleanup_log_streams + if [[ "$SETUP_STARTED" == "true" ]]; then + stop_nodes + fi +} + +usage() { + cat < + - max_target_validators=$POOLREBALANCER_MAX_TARGET_VALIDATORS + - rebalance_threshold_bp=$POOLREBALANCER_THRESHOLD_BP + - max_ops_per_block=$POOLREBALANCER_MAX_OPS_PER_BLOCK + - max_move_per_op=$POOLREBALANCER_MAX_MOVE_PER_OP + - use_undelegate_fallback=$POOLREBALANCER_USE_UNDELEGATE_FALLBACK + +Parameter precedence: + 1) Explicit environment variables (highest priority) + 2) Scenario defaults (applied only for knobs not explicitly set) + 3) Script baseline defaults + +Commands: + run (default) Full test setup + scenario execution + watch Live monitor for an already running test chain + help Show this help + +CLI options: + -n, --nodes Number of validators/nodes to run + -s, --scenario Scenario name (same as SCENARIO env var) + -p, --profile Demo profile: slow|medium|fast + -h, --help Show this help + +Scenarios: + happy_path + Goal: baseline rebalance scheduling from a heavily skewed delegation. + Setup: delegate mostly to validator[0], tiny amounts to validator[1]/[2]. + Params: uses baseline defaults (unless overridden by environment). + Watch for: pending redelegations to underweight validators. + + caps + Goal: verify scheduling respects max_ops_per_block and max_move_per_op. + Setup: same skew as happy_path, but with tight scheduling caps. + Params: default poolrebalancer max_ops_per_block=1, max_move_per_op=1e18. + Watch for: capped move sizes and slower progression. + + threshold_boundary + Goal: verify tiny drift is ignored when threshold is high enough. + Setup: create only a small imbalance and set threshold boundary params. + Params: default poolrebalancer rebalance_threshold_bp=5000. + Watch for: little or no scheduling when drift stays below threshold. + + fallback + Goal: verify undelegation fallback is used when redelegation path is constrained. + Setup: source-heavy skew + fallback enabled + low staking max_entries + transitive blocker. + Params: default poolrebalancer use_undelegate_fallback=true; default staking max_entries=1. + Watch for: pending undelegations appearing alongside or after redelegations. + + expansion + Goal: verify target set can expand to additional bonded validators. + Setup: 5 validators total, seed initial delegation to only 3 validators. + Params: default poolrebalancer max_target_validators=5, max_ops_per_block=1, max_move_per_op=1e19. + Watch for: redelegations moving stake toward validators outside the initial delegated set. + +Profiles: + slow max_ops_per_block=1, capped move per op + medium default balancing profile + fast more ops per block, no move cap + +Environment variables: + BASEDIR Test chain base dir (default: $HOME/.og-evm-devnet) + NODE_RPC RPC endpoint (default: tcp://127.0.0.1:26657) + CHAIN_ID Chain ID (default: 10740) + TX_FEES Fees for txs (default: $TX_FEES) + + VAL0_MNEMONIC ... VALN_MNEMONIC Optional explicit mnemonics. Any missing values are auto-generated. + + POOLREBALANCER_MAX_TARGET_VALIDATORS + SCENARIO happy_path|caps|threshold_boundary|fallback|expansion + VALIDATOR_COUNT Number of validators to start (default: 3; scenario may override) + DEMO_PROFILE slow|medium|fast tuning for rebalance visibility (default: medium) + POOLREBALANCER_THRESHOLD_BP + POOLREBALANCER_MAX_OPS_PER_BLOCK + POOLREBALANCER_MAX_MOVE_PER_OP + POOLREBALANCER_USE_UNDELEGATE_FALLBACK + + STAKING_UNBONDING_TIME Reduce so pending queues mature quickly (default: 30s) + STAKING_MAX_ENTRIES Raise/lower redelegation/undelegation entry pressure (default: 100) + + IMBALANCE_MAIN_DELEGATION Large delegation to validator[0] + IMBALANCE_MINOR_DELEGATION Small delegations to validator[1], validator[2] + WATCH_COMPACT Compact watch output (single-line summaries, default: false) + FALLBACK_UND_DEADLINE_SAMPLES Fallback deadline (samples) to observe pending undelegations (default: 15) + +Note: + Any variable set explicitly in the environment overrides scenario defaults. + +Examples: + # Standard rebalance flow + bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh --scenario happy_path --nodes 3 --profile medium + + # Cap-focused behavior + bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh --scenario caps --nodes 3 --profile slow + + # Threshold gating (expect no scheduling for small drift) + bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh --scenario threshold_boundary --nodes 3 + + # Fallback-focused profile + bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh --scenario fallback --nodes 3 --profile slow + + # 5-validator expansion + bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh --scenario expansion --nodes 5 + + # Watch only + bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh watch + +EOF +} + +parse_cli_args() { + local subcommand="" + while [[ $# -gt 0 ]]; do + case "$1" in + watch) + subcommand="watch" + shift + ;; + help) + subcommand="help" + shift + ;; + -n|--nodes) + if [[ $# -lt 2 ]]; then + echo "missing value for $1" >&2 + exit 1 + fi + VALIDATOR_COUNT="$2" + shift 2 + ;; + -s|--scenario) + if [[ $# -lt 2 ]]; then + echo "missing value for $1" >&2 + exit 1 + fi + SCENARIO="$2" + shift 2 + ;; + -p|--profile) + if [[ $# -lt 2 ]]; then + echo "missing value for $1" >&2 + exit 1 + fi + DEMO_PROFILE="$2" + shift 2 + ;; + -h|--help) + subcommand="help" + shift + ;; + --) + shift + break + ;; + run) + # Explicit no-op command for readability. + shift + ;; + *) + echo "unknown argument: $1" >&2 + return 1 + ;; + esac + done + PARSED_SUBCOMMAND="$subcommand" + return 0 +} + +require_bin() { + command -v "$1" >/dev/null 2>&1 || { echo "missing dependency: $1" >&2; exit 1; } +} + +stop_nodes() { + # Aggressive cleanup: multi_node_startup.sh launches `evmd start` processes directly. + pkill -f "evmd start" >/dev/null 2>&1 || true + pkill -f "multi_node_startup.sh" >/dev/null 2>&1 || true + # Give the OS a moment to release RPC/P2P ports. + sleep 1 +} + +cleanup_log_streams() { + if (( ${#LOG_STREAM_PIDS[@]} == 0 )); then + return 0 + fi + for pid in "${LOG_STREAM_PIDS[@]}"; do + kill "$pid" >/dev/null 2>&1 || true + done + LOG_STREAM_PIDS=() +} + +start_validator_log_streams() { + mkdir -p "$BASEDIR/logs" + for v in $(seq 0 $((VALIDATOR_COUNT - 1))); do + local f="$BASEDIR/logs/val${v}.log" + touch "$f" + tail -n 0 -F "$f" | sed -u "s/^/[val${v}] /" & + LOG_STREAM_PIDS+=("$!") + done +} + +wait_for_height() { + local timeout_secs="${1:-30}" + local start + start="$(date +%s)" + while true; do + local h + h="$(curl -sS --max-time 1 http://127.0.0.1:26657/status 2>/dev/null | jq -r '.result.sync_info.latest_block_height' 2>/dev/null || echo 0)" + if [[ "$h" != "0" ]]; then + echo "$h" + return 0 + fi + if (( $(date +%s) - start > timeout_secs )); then + echo "timed out waiting for height > 0" >&2 + return 1 + fi + sleep 1 + done +} + +dev0_address_from_file() { + awk '/^dev0:/{f=1} f && $1=="address:"{print $2; exit}' "$BASEDIR/dev_accounts.txt" +} + +dev0_mnemonic_from_file() { + awk '/^dev0:/{f=1} f && $1=="mnemonic:"{for(i=2;i<=NF;i++){printf (i==2?"":" ") $i} print ""; exit}' "$BASEDIR/dev_accounts.txt" +} + +auto_generate_validator_mnemonic() { + local idx="$1" + local tmp_home + local key_name + local out + local mnemonic + + tmp_home="$(mktemp -d "${TMPDIR:-/tmp}/poolrebalancer-mnemonic-${idx}-XXXXXX")" + key_name="autoval${idx}" + out="$(evmd keys add "$key_name" --keyring-backend test --algo eth_secp256k1 --home "$tmp_home" 2>&1)" + mnemonic="$(echo "$out" | awk 'NF{line=$0} END{print line}')" + rm -rf "$tmp_home" + + if [[ -z "$mnemonic" ]]; then + echo "failed to auto-generate mnemonic for validator $idx" >&2 + return 1 + fi + echo "$mnemonic" +} + +resolve_mnemonics() { + local missing=() + local need="$VALIDATOR_COUNT" + + for i in $(seq 0 $((need - 1))); do + local name="VAL${i}_MNEMONIC" + local current="${!name:-}" + if [[ -z "$current" ]]; then + current="$(auto_generate_validator_mnemonic "$i" || true)" + if [[ -n "$current" ]]; then + export "$name=$current" + fi + fi + if [[ -z "${!name:-}" ]]; then + missing+=("$name") + fi + done + + if (( ${#missing[@]} > 0 )); then + echo "missing required mnemonics: ${missing[*]}" >&2 + echo "set them in env or ensure \$BASEDIR/dev_accounts.txt contains dev0..dev$((need - 1)) entries" >&2 + exit 1 + fi +} + +patch_genesis_poolrebalancer_params() { + local del_addr="$1" + local gen0="$BASEDIR/val0/config/genesis.json" + local tmp="$BASEDIR/val0/config/genesis.tmp.json" + + jq --arg del "$del_addr" \ + --argjson maxTargets "$POOLREBALANCER_MAX_TARGET_VALIDATORS" \ + --argjson thr "$POOLREBALANCER_THRESHOLD_BP" \ + --argjson maxOps "$POOLREBALANCER_MAX_OPS_PER_BLOCK" \ + --arg maxMove "$POOLREBALANCER_MAX_MOVE_PER_OP" \ + --argjson useUndel "$POOLREBALANCER_USE_UNDELEGATE_FALLBACK" \ + ' .app_state.poolrebalancer.params.pool_delegator_address = $del + | .app_state.poolrebalancer.params.max_target_validators = $maxTargets + | .app_state.poolrebalancer.params.rebalance_threshold_bp = $thr + | .app_state.poolrebalancer.params.max_ops_per_block = $maxOps + | .app_state.poolrebalancer.params.max_move_per_op = $maxMove + | .app_state.poolrebalancer.params.use_undelegate_fallback = $useUndel + ' "$gen0" > "$tmp" + + mv "$tmp" "$gen0" + for v in $(seq 1 $((VALIDATOR_COUNT - 1))); do + cp "$gen0" "$BASEDIR/val${v}/config/genesis.json" + done + + evmd genesis validate-genesis --home "$BASEDIR/val0" >/dev/null +} + +patch_genesis_staking_params() { + local gen0="$BASEDIR/val0/config/genesis.json" + local tmp="$BASEDIR/val0/config/genesis.tmp.json" + + jq --arg unbond "$STAKING_UNBONDING_TIME" \ + --argjson maxEntries "$STAKING_MAX_ENTRIES" \ + ' .app_state.staking.params.unbonding_time = $unbond + | .app_state.staking.params.max_entries = $maxEntries + ' "$gen0" > "$tmp" + + mv "$tmp" "$gen0" +} + +import_dev0_key() { + local mnemonic="$1" + (evmd keys delete dev0 -y --keyring-backend "$KEYRING" --home "$HOME0" >/dev/null 2>&1) || true + echo "$mnemonic" | evmd keys add dev0 --recover --keyring-backend "$KEYRING" --home "$HOME0" >/dev/null +} + +wait_tx_included() { + local txhash="$1" + # First try CometBFT /tx; it becomes available as soon as tx is committed. + local rpc_http="http://127.0.0.1:26657" + for _ in $(seq 1 40); do + local resp + resp="$(curl -sS --max-time 1 "${rpc_http}/tx?hash=0x${txhash}" 2>/dev/null || true)" + # Not-found still returns JSON. Treat as committed only when .result.tx_result exists. + if echo "$resp" | jq -e '.result.tx_result' >/dev/null 2>&1; then + # Committed does not mean successful; require code=0. + local code + code="$(echo "$resp" | jq -r '.result.tx_result.code' 2>/dev/null || echo 1)" + if [[ "$code" == "0" ]]; then + return 0 + fi + echo "tx committed but failed (code=$code): $txhash" >&2 + echo "$resp" | jq -r '.result.tx_result.log' >&2 || true + return 1 + fi + # Fallback query path (depends on tx indexing config). + if evmd query tx "$txhash" --node "$NODE_RPC" -o json >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + echo "tx not found after waiting: $txhash" >&2 + echo "check logs: $BASEDIR/logs/val0.log" >&2 + return 1 +} + +delegate_with_wait() { + local valoper="$1" + local amount="$2" + # Some CLI builds return txhash even on CheckTx failure; always inspect `.code`. + for attempt in 1 2 3; do + local out + out="$(evmd tx staking delegate "$valoper" "$amount" \ + --from dev0 \ + --keyring-backend "$KEYRING" \ + --home "$HOME0" \ + --chain-id "$CHAIN_ID" \ + --node "$NODE_RPC" \ + --gas auto --gas-adjustment 1.3 \ + --fees "$TX_FEES" \ + -b sync -y -o json)" + + local code + code="$(echo "$out" | jq -r '.code // 0')" + local txhash + txhash="$(echo "$out" | jq -r '.txhash')" + + if [[ "$code" != "0" ]]; then + local log + log="$(echo "$out" | jq -r '.raw_log // .log // empty')" + echo "delegate failed (attempt=$attempt code=$code): $log" >&2 + + # Common transient: sequence mismatch while previous tx is still propagating. + if echo "$log" | grep -qi "account sequence mismatch"; then + sleep 2 + continue + fi + return 1 + fi + + echo "delegate $amount -> $valoper txhash=$txhash" + wait_tx_included "$txhash" >/dev/null + return 0 + done + + echo "delegate failed after retries: $amount -> $valoper" >&2 + return 1 +} + +redelegate_with_wait() { + local src_valoper="$1" + local dst_valoper="$2" + local amount="$3" + # Some CLI builds return txhash even on CheckTx failure, so always inspect `.code`. + for attempt in 1 2 3; do + local out + out="$(evmd tx staking redelegate "$src_valoper" "$dst_valoper" "$amount" \ + --from dev0 \ + --keyring-backend "$KEYRING" \ + --home "$HOME0" \ + --chain-id "$CHAIN_ID" \ + --node "$NODE_RPC" \ + --gas auto --gas-adjustment 1.3 \ + --fees "$TX_FEES" \ + -b sync -y -o json 2>&1 || true)" + + local code + code="$(echo "$out" | jq -r '.code // 0' 2>/dev/null || echo 1)" + local txhash + txhash="$(echo "$out" | jq -r '.txhash // empty' 2>/dev/null || true)" + + if [[ "$code" != "0" ]]; then + local log + log="$(echo "$out" | jq -r '.raw_log // .log // empty' 2>/dev/null || true)" + if [[ -z "$log" ]]; then + log="$out" + fi + if echo "$log" | rg -qi "redelegation to this validator already in progress"; then + echo "redelegate precondition already satisfied: incoming redelegation exists for $dst_valoper" + return 0 + fi + echo "redelegate failed (attempt=$attempt code=$code): $log" >&2 + if echo "$log" | rg -qi "account sequence mismatch"; then + sleep 2 + continue + fi + return 1 + fi + + echo "redelegate $amount $src_valoper -> $dst_valoper txhash=$txhash" + wait_tx_included "$txhash" >/dev/null + return 0 + done + + echo "redelegate failed after retries: $amount $src_valoper -> $dst_valoper" >&2 + return 1 +} + +check_pending_invariants() { + local json="$1" + local cap="$2" + local max_ops="$3" + + # Important nuance: + # pending-redelegations query returns primary records that can merge multiple ops + # sharing (delegator, denom, dst, completionTime). With max_ops_per_block > 1, + # a merged record amount can exceed max_move_per_op even if each individual op respected the cap. + # So strict cap checking is only sound when max_ops_per_block == 1. + if [[ "$cap" != "0" && "$max_ops" == "1" ]]; then + local badAmt + badAmt="$(echo "$json" | jq -r --argjson cap "$cap" '[.redelegations[] | (.amount.amount|tonumber) > $cap] | any')" + if [[ "$badAmt" != "false" ]]; then + echo "warning: found pending amount > max_move_per_op" >&2 + return 1 + fi + elif [[ "$cap" != "0" && "$max_ops" != "1" ]]; then + echo "note: skipping strict max_move_per_op check on merged primary entries (max_ops_per_block=$max_ops)" + fi + + # Transitive safety: a source validator must not also be an in-flight destination. + local badTrans + badTrans="$(echo "$json" | jq -r '([.redelegations[].src_validator_address] | unique) as $srcs | ([.redelegations[].dst_validator_address] | unique) as $dsts | ([ $srcs[] | . as $s | (($dsts | index($s)) != null) ] | any)')" + if [[ "$badTrans" != "false" ]]; then + echo "warning: transitive safety violated (src appears in dst set)" >&2 + return 1 + fi +} + +watch_rebalance_status() { + # Read-only watch mode for an already running test chain. + # Use this to inspect params/pending queues without re-running setup. + local node="${NODE_RPC:-tcp://127.0.0.1:26657}" + local interval="${POLL_SLEEP_SECS:-2}" + + while true; do + local h params del pr pu + h="$(curl -sS http://127.0.0.1:26657/status | jq -r '.result.sync_info.latest_block_height // "n/a"')" + params="$(evmd query poolrebalancer params --node "$node" -o json 2>/dev/null || echo '{}')" + del="$(echo "$params" | jq -r '.params.pool_delegator_address // empty')" + pr="$(evmd query poolrebalancer pending-redelegations --node "$node" -o json 2>/dev/null | jq -r '.redelegations | length // 0')" + pu="$(evmd query poolrebalancer pending-undelegations --node "$node" -o json 2>/dev/null | jq -r '.undelegations | length // 0')" + + if [[ "$WATCH_COMPACT" == "true" ]]; then + echo "watch phase=$CURRENT_PHASE height=$h pending_red=$pr pending_und=$pu scenario=$SCENARIO" + else + echo "----- rebalance watch -----" + echo "phase=$CURRENT_PHASE height=$h pending_red=$pr pending_und=$pu" + echo "$params" | jq -r '.params | {pool_delegator_address,max_target_validators,rebalance_threshold_bp,max_ops_per_block,max_move_per_op,use_undelegate_fallback}' + + if [[ -n "$del" ]]; then + evmd query staking delegations "$del" --node "$node" -o json 2>/dev/null | \ + jq -r '.delegation_responses[]? | {validator: .delegation.validator_address, amount: .balance.amount, denom: .balance.denom}' + else + echo "pool delegator not configured" + fi + echo + fi + sleep "$interval" + done +} + +setup_localnet() { + CURRENT_PHASE="setup_localnet" + SETUP_STARTED="true" + echo "==> Stopping any existing test chain" + stop_nodes + + echo "==> Generating test genesis ($VALIDATOR_COUNT validators) at $BASEDIR" + # multi_node_startup.sh is verbose during init; silence setup noise here. + (cd "$ROOT_DIR" && VALIDATOR_COUNT="$VALIDATOR_COUNT" GENERATE_GENESIS=true ./multi_node_startup.sh -y >/dev/null 2>&1) + + POOL_DEL_ADDR="$(dev0_address_from_file)" + POOL_DEL_MNEMONIC="$(dev0_mnemonic_from_file)" +} + +configure_genesis_params() { + CURRENT_PHASE="configure_genesis" + echo "==> Pool delegator (dev0) = $POOL_DEL_ADDR" + echo "==> SCENARIO=$SCENARIO VALIDATOR_COUNT=$VALIDATOR_COUNT DEMO_PROFILE=$DEMO_PROFILE threshold_bp=$POOLREBALANCER_THRESHOLD_BP max_target_validators=$POOLREBALANCER_MAX_TARGET_VALIDATORS max_ops_per_block=$POOLREBALANCER_MAX_OPS_PER_BLOCK max_move_per_op=$POOLREBALANCER_MAX_MOVE_PER_OP fallback=$POOLREBALANCER_USE_UNDELEGATE_FALLBACK" + echo "==> Patching genesis staking params (unbonding_time + max_entries)" + patch_genesis_staking_params + echo "==> Patching genesis poolrebalancer params" + patch_genesis_poolrebalancer_params "$POOL_DEL_ADDR" +} + +start_validators() { + CURRENT_PHASE="start_validators" + echo "==> Starting validators" + mkdir -p "$BASEDIR/logs" + for v in $(seq 0 $((VALIDATOR_COUNT - 1))); do + (cd "$ROOT_DIR" && VALIDATOR_COUNT="$VALIDATOR_COUNT" START_VALIDATOR=true NODE_NUMBER="$v" ./multi_node_startup.sh >"$BASEDIR/logs/val${v}.log" 2>&1 &) + done + if [[ "$STREAM_VALIDATOR_LOGS" == "true" ]]; then + echo "==> Streaming validator logs (val0..val$((VALIDATOR_COUNT - 1)))" + start_validator_log_streams + fi +} + +wait_chain_ready() { + CURRENT_PHASE="wait_chain_ready" + echo "==> Waiting for block production" + local h + h="$(wait_for_height 60)" + echo "height=$h" + + # Resolve chain bond denom and rewrite amount knobs to match this network. + BOND_DENOM="$(evmd query staking params --node "$NODE_RPC" -o json | jq -r '.params.bond_denom // .bond_denom')" + if [[ -z "$BOND_DENOM" || "$BOND_DENOM" == "null" ]]; then + echo "error: could not determine bond_denom from staking params" >&2 + exit 1 + fi + echo "bond_denom=$BOND_DENOM" + TX_FEES="${TX_FEES%ogwei}${BOND_DENOM}" + IMBALANCE_MAIN_DELEGATION="${IMBALANCE_MAIN_DELEGATION%ogwei}${BOND_DENOM}" + IMBALANCE_MINOR_DELEGATION="${IMBALANCE_MINOR_DELEGATION%ogwei}${BOND_DENOM}" +} + +seed_initial_imbalance() { + CURRENT_PHASE="seed_initial_imbalance" + echo "==> Importing dev0 key into keyring" + import_dev0_key "$POOL_DEL_MNEMONIC" + + echo "==> Creating delegation imbalance (scenario=$SCENARIO)" + local vals v0 v1 v2 + vals="$(evmd query staking validators --node "$NODE_RPC" -o json | jq -r '.validators[:3] | .[] | .operator_address')" + v0="$(echo "$vals" | sed -n '1p')" + v1="$(echo "$vals" | sed -n '2p')" + v2="$(echo "$vals" | sed -n '3p')" + + case "$SCENARIO" in + happy_path|caps|expansion) + delegate_with_wait "$v0" "$IMBALANCE_MAIN_DELEGATION" + delegate_with_wait "$v1" "$IMBALANCE_MINOR_DELEGATION" + delegate_with_wait "$v2" "$IMBALANCE_MINOR_DELEGATION" + if [[ "$SCENARIO" == "expansion" ]]; then + EXPANSION_INITIAL_DELEGATED=("$v0" "$v1" "$v2") + fi + ;; + threshold_boundary) + # Keep drift tiny so threshold gating can suppress scheduling. + delegate_with_wait "$v0" "$IMBALANCE_MINOR_DELEGATION" + ;; + fallback) + # Keep source-heavy skew; fallback path is enabled by scenario defaults. + delegate_with_wait "$v0" "$IMBALANCE_MAIN_DELEGATION" + delegate_with_wait "$v1" "$IMBALANCE_MINOR_DELEGATION" + delegate_with_wait "$v2" "$IMBALANCE_MINOR_DELEGATION" + # Force fallback sooner: + # create an in-flight incoming redelegation to v0, which blocks using v0 + # as a redelegation source via transitive safety + # (HasImmatureRedelegationTo(src=v0)). + # With v0 as the main overweight source, fallback undelegation appears quickly. + redelegate_with_wait "$v1" "$v0" "$IMBALANCE_MINOR_DELEGATION" + ;; + *) + echo "error: unsupported SCENARIO in seed_initial_imbalance: $SCENARIO" >&2 + exit 1 + ;; + esac +} + +run_sanity_checks() { + CURRENT_PHASE="run_sanity_checks" + echo "==> Sanity checks (params + delegations)" + local onchain_del + onchain_del="$(evmd query poolrebalancer params --node "$NODE_RPC" -o json | jq -r '.params.pool_delegator_address')" + if [[ "$onchain_del" != "$POOL_DEL_ADDR" ]]; then + echo "error: poolrebalancer params.pool_delegator_address mismatch" >&2 + echo " expected: $POOL_DEL_ADDR" >&2 + echo " got: $onchain_del" >&2 + exit 1 + fi + + local del_count + del_count="$(evmd query staking delegations "$POOL_DEL_ADDR" --node "$NODE_RPC" -o json | jq -r '.delegation_responses | length')" + echo "delegations_count=$del_count" + + local bonded_count + bonded_count="$(evmd query staking validators --node "$NODE_RPC" -o json | jq -r '[.validators[] | select(.status=="BOND_STATUS_BONDED")] | length')" + echo "bonded_validators=$bonded_count" + if (( bonded_count == 0 )); then + echo "error: no bonded validators found; cannot rebalance" >&2 + exit 1 + fi + + if [[ "$SCENARIO" == "expansion" ]]; then + if (( bonded_count < 5 )); then + echo "error: expected at least 5 bonded validators for scenario=target_set_expansion_5val, got $bonded_count" >&2 + exit 1 + fi + + if (( ${#EXPANSION_INITIAL_DELEGATED[@]} != 3 )); then + echo "error: expansion initial seeded validator set is not ready (expected 3 validators)" >&2 + exit 1 + fi + + local bonded_json + bonded_json="$(evmd query staking validators --node "$NODE_RPC" -o json | jq -r '[.validators[] | select(.status=="BOND_STATUS_BONDED") | .operator_address] | unique')" + local seeded_json + seeded_json="$(printf '%s\n' "${EXPANSION_INITIAL_DELEGATED[@]}" | jq -R . | jq -s 'unique')" + EXPANSION_MISSING_DSTS=() + while IFS= read -r val; do + [[ -z "$val" ]] && continue + EXPANSION_MISSING_DSTS+=("$val") + done < <(jq -n -r --argjson bonded "$bonded_json" --argjson delegated "$seeded_json" '$bonded - $delegated | .[]') + + if (( ${#EXPANSION_MISSING_DSTS[@]} < 2 )); then + echo "error: expansion expects at least 2 bonded validators outside initial pool delegation set, got ${#EXPANSION_MISSING_DSTS[@]}" >&2 + exit 1 + fi + + EXPANSION_OBSERVED_DSTS_TEXT="" + echo "scenario_check: bonded_validators=$bonded_count initial_seeded=${#EXPANSION_INITIAL_DELEGATED[@]} missing_targets=${#EXPANSION_MISSING_DSTS[@]}" + fi +} + +update_expansion_observed_dsts() { + local pending_json="$1" + if [[ "$SCENARIO" != "expansion" ]]; then + return 0 + fi + + local dst target + while IFS= read -r dst; do + [[ -z "$dst" ]] && continue + for target in "${EXPANSION_MISSING_DSTS[@]}"; do + if [[ "$dst" == "$target" ]]; then + if ! printf '%s\n' "$EXPANSION_OBSERVED_DSTS_TEXT" | rg -F -x --quiet "$dst"; then + if [[ -n "$EXPANSION_OBSERVED_DSTS_TEXT" ]]; then + EXPANSION_OBSERVED_DSTS_TEXT="${EXPANSION_OBSERVED_DSTS_TEXT}"$'\n'"$dst" + else + EXPANSION_OBSERVED_DSTS_TEXT="$dst" + fi + fi + break + fi + done + done < <(echo "$pending_json" | jq -r '.redelegations[]?.dst_validator_address') +} + +expansion_observed_count() { + local count=0 + local target + for target in "${EXPANSION_MISSING_DSTS[@]}"; do + if printf '%s\n' "$EXPANSION_OBSERVED_DSTS_TEXT" | rg -F -x --quiet "$target"; then + count=$((count + 1)) + fi + done + echo "$count" +} + +observe_and_monitor() { + CURRENT_PHASE="observe_and_monitor" + echo "==> Observing pending operations (scenario=$SCENARIO)" + # Poll loop used for observation: + # - collect pending queue state + # - wait until any pending operations appear + # - validate generic invariants + for i in $(seq 1 "$POLL_SAMPLES"); do + local height pending pendingUndel + height="$(curl -s http://127.0.0.1:26657/status | jq -r '.result.sync_info.latest_block_height')" + local j + j="$(evmd query poolrebalancer pending-redelegations --node "$NODE_RPC" -o json)" + update_expansion_observed_dsts "$j" + pending="$(echo "$j" | jq -r '.redelegations | length')" + pendingUndel="$(evmd query poolrebalancer pending-undelegations --node "$NODE_RPC" -o json | jq -r '.undelegations | length')" + if [[ "$WATCH_COMPACT" == "true" ]]; then + echo "sample=$i phase=$CURRENT_PHASE height=$height pending_red=$pending pending_und=$pendingUndel scenario=$SCENARIO" + else + echo "sample=$i phase=$CURRENT_PHASE height=$height pending_red=$pending pending_und=$pendingUndel" + fi + if [[ "$SCENARIO" == "expansion" ]]; then + local seen expected + seen="$(expansion_observed_count)" + expected="${#EXPANSION_MISSING_DSTS[@]}" + echo "expansion_progress: observed_new_destinations=$seen/$expected" + elif [[ "$SCENARIO" == "fallback" ]]; then + if (( pending > 0 )); then + FALLBACK_SEEN_REDELEGATION="true" + fi + echo "fallback_progress: seen_redelegation=$FALLBACK_SEEN_REDELEGATION undelegations=$pendingUndel deadline_sample=$FALLBACK_UND_DEADLINE_SAMPLES" + fi + + if (( pending > 0 || pendingUndel > 0 )); then + if (( pending > 0 )); then + check_pending_invariants "$j" "$POOLREBALANCER_MAX_MOVE_PER_OP" "$POOLREBALANCER_MAX_OPS_PER_BLOCK" + fi + echo "info: pending operations observed; continuing monitor" + if [[ "$KEEP_RUNNING" != "true" ]]; then + exit 0 + fi + CURRENT_PHASE="steady_monitor" + echo "==> KEEP_RUNNING=true, continuing in monitor mode (Ctrl+C to stop)" + while true; do + local monitorHeight monitorRed monitorUnd + monitorHeight="$(curl -sS http://127.0.0.1:26657/status | jq -r '.result.sync_info.latest_block_height')" + monitorRed="$(evmd query poolrebalancer pending-redelegations --node "$NODE_RPC" -o json | jq -r '.redelegations | length')" + monitorUnd="$(evmd query poolrebalancer pending-undelegations --node "$NODE_RPC" -o json | jq -r '.undelegations | length')" + if [[ "$WATCH_COMPACT" == "true" ]]; then + echo "monitor phase=$CURRENT_PHASE height=$monitorHeight pending_red=$monitorRed pending_und=$monitorUnd scenario=$SCENARIO" + else + echo "monitor phase=$CURRENT_PHASE height=$monitorHeight pending_red=$monitorRed pending_und=$monitorUnd" + fi + sleep "$POLL_SLEEP_SECS" + done + fi + sleep "$POLL_SLEEP_SECS" + done + + echo "info: no pending operations observed within polling window" >&2 + echo "note: this can be expected when drift is below threshold or the system is already balanced" >&2 + exit 0 +} + +apply_scenario_defaults() { + # Scenario defaults encode engineer-friendly test behavior. + # They are applied only when the corresponding env var was not explicitly set. + case "$SCENARIO" in + # Canonical scenarios + happy_path) + if [[ -z "$VALIDATOR_COUNT" ]]; then VALIDATOR_COUNT=3; fi + ;; + caps) + if [[ -z "$VALIDATOR_COUNT" ]]; then VALIDATOR_COUNT=3; fi + if [[ "$USER_SET_MAX_OPS_PER_BLOCK" != "true" ]]; then POOLREBALANCER_MAX_OPS_PER_BLOCK=1; fi + if [[ "$USER_SET_MAX_MOVE_PER_OP" != "true" ]]; then POOLREBALANCER_MAX_MOVE_PER_OP=1000000000000000000; fi + ;; + threshold_boundary) + if [[ -z "$VALIDATOR_COUNT" ]]; then VALIDATOR_COUNT=3; fi + if [[ "$USER_SET_THRESHOLD_BP" != "true" ]]; then POOLREBALANCER_THRESHOLD_BP=5000; fi + if [[ "$USER_SET_MAX_OPS_PER_BLOCK" != "true" ]]; then POOLREBALANCER_MAX_OPS_PER_BLOCK=2; fi + if [[ "$USER_SET_MAX_MOVE_PER_OP" != "true" ]]; then POOLREBALANCER_MAX_MOVE_PER_OP=100000000000000000000; fi + ;; + fallback) + if [[ -z "$VALIDATOR_COUNT" ]]; then VALIDATOR_COUNT=3; fi + if [[ "$USER_SET_USE_UNDELEGATE_FALLBACK" != "true" ]]; then POOLREBALANCER_USE_UNDELEGATE_FALLBACK=true; fi + # Small cap + single-op profile makes fallback behavior easy to observe. + if [[ "$USER_SET_MAX_OPS_PER_BLOCK" != "true" ]]; then POOLREBALANCER_MAX_OPS_PER_BLOCK=1; fi + if [[ "$USER_SET_MAX_MOVE_PER_OP" != "true" ]]; then POOLREBALANCER_MAX_MOVE_PER_OP=1000000000000000000; fi + # Tight staking entry limit blocks repeated redelegations quickly and + # makes fallback undelegations appear sooner in local runs. + if [[ "$USER_SET_STAKING_MAX_ENTRIES" != "true" ]]; then STAKING_MAX_ENTRIES=1; fi + ;; + expansion) + if [[ -z "$VALIDATOR_COUNT" ]]; then VALIDATOR_COUNT=5; fi + if [[ "$USER_SET_MAX_TARGET_VALIDATORS" != "true" ]]; then POOLREBALANCER_MAX_TARGET_VALIDATORS=5; fi + # Make expansion visually clearer: + # - start with a meaningful baseline on initially delegated validators + # - move in smaller steps so newly introduced validators ramp up gradually + if [[ "$USER_SET_MAX_OPS_PER_BLOCK" != "true" ]]; then POOLREBALANCER_MAX_OPS_PER_BLOCK=1; fi + if [[ "$USER_SET_MAX_MOVE_PER_OP" != "true" ]]; then POOLREBALANCER_MAX_MOVE_PER_OP=10000000000000000000; fi + if [[ "$USER_SET_IMBALANCE_MINOR_DELEGATION" != "true" ]]; then IMBALANCE_MINOR_DELEGATION=1000000000000000000000ogwei; fi + ;; + # Backward-compatible aliases + baseline_3val) + SCENARIO="happy_path" + if [[ -z "$VALIDATOR_COUNT" ]]; then VALIDATOR_COUNT=3; fi + ;; + max_target_gt_bonded_3val) + SCENARIO="happy_path" + if [[ -z "$VALIDATOR_COUNT" ]]; then VALIDATOR_COUNT=3; fi + if [[ "$USER_SET_MAX_TARGET_VALIDATORS" != "true" ]]; then POOLREBALANCER_MAX_TARGET_VALIDATORS=5; fi + ;; + fallback_path_3val) + SCENARIO="fallback" + if [[ -z "$VALIDATOR_COUNT" ]]; then VALIDATOR_COUNT=3; fi + if [[ "$USER_SET_USE_UNDELEGATE_FALLBACK" != "true" ]]; then POOLREBALANCER_USE_UNDELEGATE_FALLBACK=true; fi + if [[ "$USER_SET_MAX_OPS_PER_BLOCK" != "true" ]]; then POOLREBALANCER_MAX_OPS_PER_BLOCK=1; fi + if [[ "$USER_SET_MAX_MOVE_PER_OP" != "true" ]]; then POOLREBALANCER_MAX_MOVE_PER_OP=1000000000000000000; fi + ;; + target_set_expansion_5val) + SCENARIO="expansion" + if [[ -z "$VALIDATOR_COUNT" ]]; then VALIDATOR_COUNT=5; fi + if [[ "$USER_SET_MAX_TARGET_VALIDATORS" != "true" ]]; then POOLREBALANCER_MAX_TARGET_VALIDATORS=5; fi + ;; + *) + echo "invalid SCENARIO: $SCENARIO" >&2 + echo "expected: happy_path|caps|threshold_boundary|fallback|expansion" >&2 + exit 1 + ;; + esac +} + +main() { + trap on_interrupt INT TERM + trap cleanup_on_exit EXIT + PARSED_SUBCOMMAND="" + if ! parse_cli_args "$@"; then + usage + exit 1 + fi + + if [[ "$PARSED_SUBCOMMAND" == "watch" ]]; then + watch_rebalance_status + exit 0 + fi + if [[ "$PARSED_SUBCOMMAND" == "help" ]]; then + usage + exit 0 + fi + + require_bin jq + require_bin curl + require_bin evmd + + apply_scenario_defaults + if [[ ! "$VALIDATOR_COUNT" =~ ^[0-9]+$ ]] || (( VALIDATOR_COUNT < 1 )); then + echo "invalid --nodes/VALIDATOR_COUNT: $VALIDATOR_COUNT (expected positive integer)" >&2 + exit 1 + fi + + case "$DEMO_PROFILE" in + slow) + POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-1}" + POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-10000000000000000000}" # 1e19 + ;; + medium) + # Defaults already set above. + ;; + fast) + POOLREBALANCER_MAX_OPS_PER_BLOCK="${POOLREBALANCER_MAX_OPS_PER_BLOCK:-10}" + POOLREBALANCER_MAX_MOVE_PER_OP="${POOLREBALANCER_MAX_MOVE_PER_OP:-0}" # no cap + ;; + *) + echo "invalid DEMO_PROFILE: $DEMO_PROFILE (expected: slow|medium|fast)" >&2 + exit 1 + ;; + esac + + # Execution flow: + # 1) test chain setup and genesis patching + # 2) scenario seeding + # 3) sanity checks + # 4) observe-and-monitor loop + steady monitor + resolve_mnemonics + setup_localnet + configure_genesis_params + start_validators + wait_chain_ready + seed_initial_imbalance + run_sanity_checks + observe_and_monitor +} + +main "$@" + From b04f6c3f0e05f5de93bb1a9ca6f1f26a3728a2a8 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Fri, 20 Mar 2026 16:50:20 +0530 Subject: [PATCH 12/31] refactor(proto): migrate poolrebalancer proto and generated API paths to cosmos/poolrebalancer/v1 Signed-off-by: Nikhil Sharma --- .../v1/poolrebalancer.pulsar.go | 787 +++++++++--------- .../poolrebalancer/v1/query.pulsar.go | 609 +++++++------- .../poolrebalancer/v1/query_grpc.pb.go | 12 +- .../{evm => }/poolrebalancer/v1/tx.pulsar.go | 258 +++--- .../{evm => }/poolrebalancer/v1/tx_grpc.pb.go | 8 +- .../poolrebalancer/v1/poolrebalancer.proto | 2 +- .../{evm => }/poolrebalancer/v1/query.proto | 10 +- .../{evm => }/poolrebalancer/v1/tx.proto | 6 +- x/poolrebalancer/types/poolrebalancer.pb.go | 120 +-- x/poolrebalancer/types/query.pb.go | 117 ++- x/poolrebalancer/types/query.pb.gw.go | 8 +- x/poolrebalancer/types/tx.pb.go | 77 +- 12 files changed, 999 insertions(+), 1015 deletions(-) rename api/cosmos/{evm => }/poolrebalancer/v1/poolrebalancer.pulsar.go (80%) rename api/cosmos/{evm => }/poolrebalancer/v1/query.pulsar.go (80%) rename api/cosmos/{evm => }/poolrebalancer/v1/query_grpc.pb.go (93%) rename api/cosmos/{evm => }/poolrebalancer/v1/tx.pulsar.go (76%) rename api/cosmos/{evm => }/poolrebalancer/v1/tx_grpc.pb.go (94%) rename proto/cosmos/{evm => }/poolrebalancer/v1/poolrebalancer.proto (98%) rename proto/cosmos/{evm => }/poolrebalancer/v1/query.proto (88%) rename proto/cosmos/{evm => }/poolrebalancer/v1/tx.proto (87%) diff --git a/api/cosmos/evm/poolrebalancer/v1/poolrebalancer.pulsar.go b/api/cosmos/poolrebalancer/v1/poolrebalancer.pulsar.go similarity index 80% rename from api/cosmos/evm/poolrebalancer/v1/poolrebalancer.pulsar.go rename to api/cosmos/poolrebalancer/v1/poolrebalancer.pulsar.go index 6c17d64a..9123fafe 100644 --- a/api/cosmos/evm/poolrebalancer/v1/poolrebalancer.pulsar.go +++ b/api/cosmos/poolrebalancer/v1/poolrebalancer.pulsar.go @@ -26,8 +26,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() - md_Params = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("Params") + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() + md_Params = File_cosmos_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("Params") fd_Params_pool_delegator_address = md_Params.Fields().ByName("pool_delegator_address") fd_Params_max_target_validators = md_Params.Fields().ByName("max_target_validators") fd_Params_rebalance_threshold_bp = md_Params.Fields().ByName("rebalance_threshold_bp") @@ -45,7 +45,7 @@ func (x *Params) ProtoReflect() protoreflect.Message { } func (x *Params) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[0] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -152,23 +152,23 @@ func (x *fastReflection_Params) Range(f func(protoreflect.FieldDescriptor, proto // a repeated field is populated if it is non-empty. func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + case "cosmos.poolrebalancer.v1.Params.pool_delegator_address": return x.PoolDelegatorAddress != "" - case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + case "cosmos.poolrebalancer.v1.Params.max_target_validators": return x.MaxTargetValidators != uint32(0) - case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + case "cosmos.poolrebalancer.v1.Params.rebalance_threshold_bp": return x.RebalanceThresholdBp != uint32(0) - case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + case "cosmos.poolrebalancer.v1.Params.max_ops_per_block": return x.MaxOpsPerBlock != uint32(0) - case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + case "cosmos.poolrebalancer.v1.Params.max_move_per_op": return x.MaxMovePerOp != "" - case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + case "cosmos.poolrebalancer.v1.Params.use_undelegate_fallback": return x.UseUndelegateFallback != false default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.Params")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) } } @@ -180,23 +180,23 @@ func (x *fastReflection_Params) Has(fd protoreflect.FieldDescriptor) bool { // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + case "cosmos.poolrebalancer.v1.Params.pool_delegator_address": x.PoolDelegatorAddress = "" - case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + case "cosmos.poolrebalancer.v1.Params.max_target_validators": x.MaxTargetValidators = uint32(0) - case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + case "cosmos.poolrebalancer.v1.Params.rebalance_threshold_bp": x.RebalanceThresholdBp = uint32(0) - case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + case "cosmos.poolrebalancer.v1.Params.max_ops_per_block": x.MaxOpsPerBlock = uint32(0) - case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + case "cosmos.poolrebalancer.v1.Params.max_move_per_op": x.MaxMovePerOp = "" - case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + case "cosmos.poolrebalancer.v1.Params.use_undelegate_fallback": x.UseUndelegateFallback = false default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.Params")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) } } @@ -208,29 +208,29 @@ func (x *fastReflection_Params) Clear(fd protoreflect.FieldDescriptor) { // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + case "cosmos.poolrebalancer.v1.Params.pool_delegator_address": value := x.PoolDelegatorAddress return protoreflect.ValueOfString(value) - case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + case "cosmos.poolrebalancer.v1.Params.max_target_validators": value := x.MaxTargetValidators return protoreflect.ValueOfUint32(value) - case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + case "cosmos.poolrebalancer.v1.Params.rebalance_threshold_bp": value := x.RebalanceThresholdBp return protoreflect.ValueOfUint32(value) - case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + case "cosmos.poolrebalancer.v1.Params.max_ops_per_block": value := x.MaxOpsPerBlock return protoreflect.ValueOfUint32(value) - case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + case "cosmos.poolrebalancer.v1.Params.max_move_per_op": value := x.MaxMovePerOp return protoreflect.ValueOfString(value) - case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + case "cosmos.poolrebalancer.v1.Params.use_undelegate_fallback": value := x.UseUndelegateFallback return protoreflect.ValueOfBool(value) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.Params")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.Params does not contain field %s", descriptor.FullName())) } } @@ -246,23 +246,23 @@ func (x *fastReflection_Params) Get(descriptor protoreflect.FieldDescriptor) pro // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + case "cosmos.poolrebalancer.v1.Params.pool_delegator_address": x.PoolDelegatorAddress = value.Interface().(string) - case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + case "cosmos.poolrebalancer.v1.Params.max_target_validators": x.MaxTargetValidators = uint32(value.Uint()) - case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + case "cosmos.poolrebalancer.v1.Params.rebalance_threshold_bp": x.RebalanceThresholdBp = uint32(value.Uint()) - case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + case "cosmos.poolrebalancer.v1.Params.max_ops_per_block": x.MaxOpsPerBlock = uint32(value.Uint()) - case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + case "cosmos.poolrebalancer.v1.Params.max_move_per_op": x.MaxMovePerOp = value.Interface().(string) - case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + case "cosmos.poolrebalancer.v1.Params.use_undelegate_fallback": x.UseUndelegateFallback = value.Bool() default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.Params")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) } } @@ -278,23 +278,23 @@ func (x *fastReflection_Params) Set(fd protoreflect.FieldDescriptor, value proto // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": - panic(fmt.Errorf("field pool_delegator_address of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) - case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": - panic(fmt.Errorf("field max_target_validators of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) - case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": - panic(fmt.Errorf("field rebalance_threshold_bp of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) - case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": - panic(fmt.Errorf("field max_ops_per_block of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) - case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": - panic(fmt.Errorf("field max_move_per_op of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) - case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": - panic(fmt.Errorf("field use_undelegate_fallback of message cosmos.evm.poolrebalancer.v1.Params is not mutable")) + case "cosmos.poolrebalancer.v1.Params.pool_delegator_address": + panic(fmt.Errorf("field pool_delegator_address of message cosmos.poolrebalancer.v1.Params is not mutable")) + case "cosmos.poolrebalancer.v1.Params.max_target_validators": + panic(fmt.Errorf("field max_target_validators of message cosmos.poolrebalancer.v1.Params is not mutable")) + case "cosmos.poolrebalancer.v1.Params.rebalance_threshold_bp": + panic(fmt.Errorf("field rebalance_threshold_bp of message cosmos.poolrebalancer.v1.Params is not mutable")) + case "cosmos.poolrebalancer.v1.Params.max_ops_per_block": + panic(fmt.Errorf("field max_ops_per_block of message cosmos.poolrebalancer.v1.Params is not mutable")) + case "cosmos.poolrebalancer.v1.Params.max_move_per_op": + panic(fmt.Errorf("field max_move_per_op of message cosmos.poolrebalancer.v1.Params is not mutable")) + case "cosmos.poolrebalancer.v1.Params.use_undelegate_fallback": + panic(fmt.Errorf("field use_undelegate_fallback of message cosmos.poolrebalancer.v1.Params is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.Params")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) } } @@ -303,23 +303,23 @@ func (x *fastReflection_Params) Mutable(fd protoreflect.FieldDescriptor) protore // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.Params.pool_delegator_address": + case "cosmos.poolrebalancer.v1.Params.pool_delegator_address": return protoreflect.ValueOfString("") - case "cosmos.evm.poolrebalancer.v1.Params.max_target_validators": + case "cosmos.poolrebalancer.v1.Params.max_target_validators": return protoreflect.ValueOfUint32(uint32(0)) - case "cosmos.evm.poolrebalancer.v1.Params.rebalance_threshold_bp": + case "cosmos.poolrebalancer.v1.Params.rebalance_threshold_bp": return protoreflect.ValueOfUint32(uint32(0)) - case "cosmos.evm.poolrebalancer.v1.Params.max_ops_per_block": + case "cosmos.poolrebalancer.v1.Params.max_ops_per_block": return protoreflect.ValueOfUint32(uint32(0)) - case "cosmos.evm.poolrebalancer.v1.Params.max_move_per_op": + case "cosmos.poolrebalancer.v1.Params.max_move_per_op": return protoreflect.ValueOfString("") - case "cosmos.evm.poolrebalancer.v1.Params.use_undelegate_fallback": + case "cosmos.poolrebalancer.v1.Params.use_undelegate_fallback": return protoreflect.ValueOfBool(false) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.Params")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.Params")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.Params does not contain field %s", fd.FullName())) } } @@ -329,7 +329,7 @@ func (x *fastReflection_Params) NewField(fd protoreflect.FieldDescriptor) protor func (x *fastReflection_Params) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.Params", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.Params", d.FullName())) } panic("unreachable") } @@ -707,8 +707,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() - md_PendingRedelegation = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("PendingRedelegation") + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() + md_PendingRedelegation = File_cosmos_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("PendingRedelegation") fd_PendingRedelegation_delegator_address = md_PendingRedelegation.Fields().ByName("delegator_address") fd_PendingRedelegation_src_validator_address = md_PendingRedelegation.Fields().ByName("src_validator_address") fd_PendingRedelegation_dst_validator_address = md_PendingRedelegation.Fields().ByName("dst_validator_address") @@ -725,7 +725,7 @@ func (x *PendingRedelegation) ProtoReflect() protoreflect.Message { } func (x *PendingRedelegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[1] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -826,21 +826,21 @@ func (x *fastReflection_PendingRedelegation) Range(f func(protoreflect.FieldDesc // a repeated field is populated if it is non-empty. func (x *fastReflection_PendingRedelegation) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.delegator_address": return x.DelegatorAddress != "" - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.src_validator_address": return x.SrcValidatorAddress != "" - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.dst_validator_address": return x.DstValidatorAddress != "" - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + case "cosmos.poolrebalancer.v1.PendingRedelegation.amount": return x.Amount != nil - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingRedelegation.completion_time": return x.CompletionTime != nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) } } @@ -852,21 +852,21 @@ func (x *fastReflection_PendingRedelegation) Has(fd protoreflect.FieldDescriptor // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_PendingRedelegation) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.delegator_address": x.DelegatorAddress = "" - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.src_validator_address": x.SrcValidatorAddress = "" - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.dst_validator_address": x.DstValidatorAddress = "" - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + case "cosmos.poolrebalancer.v1.PendingRedelegation.amount": x.Amount = nil - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingRedelegation.completion_time": x.CompletionTime = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) } } @@ -878,26 +878,26 @@ func (x *fastReflection_PendingRedelegation) Clear(fd protoreflect.FieldDescript // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_PendingRedelegation) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.delegator_address": value := x.DelegatorAddress return protoreflect.ValueOfString(value) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.src_validator_address": value := x.SrcValidatorAddress return protoreflect.ValueOfString(value) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.dst_validator_address": value := x.DstValidatorAddress return protoreflect.ValueOfString(value) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + case "cosmos.poolrebalancer.v1.PendingRedelegation.amount": value := x.Amount return protoreflect.ValueOfMessage(value.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingRedelegation.completion_time": value := x.CompletionTime return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingRedelegation does not contain field %s", descriptor.FullName())) } } @@ -913,21 +913,21 @@ func (x *fastReflection_PendingRedelegation) Get(descriptor protoreflect.FieldDe // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_PendingRedelegation) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.delegator_address": x.DelegatorAddress = value.Interface().(string) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.src_validator_address": x.SrcValidatorAddress = value.Interface().(string) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.dst_validator_address": x.DstValidatorAddress = value.Interface().(string) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + case "cosmos.poolrebalancer.v1.PendingRedelegation.amount": x.Amount = value.Message().Interface().(*v1beta1.Coin) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingRedelegation.completion_time": x.CompletionTime = value.Message().Interface().(*timestamppb.Timestamp) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) } } @@ -943,27 +943,27 @@ func (x *fastReflection_PendingRedelegation) Set(fd protoreflect.FieldDescriptor // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_PendingRedelegation) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + case "cosmos.poolrebalancer.v1.PendingRedelegation.amount": if x.Amount == nil { x.Amount = new(v1beta1.Coin) } return protoreflect.ValueOfMessage(x.Amount.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingRedelegation.completion_time": if x.CompletionTime == nil { x.CompletionTime = new(timestamppb.Timestamp) } return protoreflect.ValueOfMessage(x.CompletionTime.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": - panic(fmt.Errorf("field delegator_address of message cosmos.evm.poolrebalancer.v1.PendingRedelegation is not mutable")) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": - panic(fmt.Errorf("field src_validator_address of message cosmos.evm.poolrebalancer.v1.PendingRedelegation is not mutable")) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": - panic(fmt.Errorf("field dst_validator_address of message cosmos.evm.poolrebalancer.v1.PendingRedelegation is not mutable")) + case "cosmos.poolrebalancer.v1.PendingRedelegation.delegator_address": + panic(fmt.Errorf("field delegator_address of message cosmos.poolrebalancer.v1.PendingRedelegation is not mutable")) + case "cosmos.poolrebalancer.v1.PendingRedelegation.src_validator_address": + panic(fmt.Errorf("field src_validator_address of message cosmos.poolrebalancer.v1.PendingRedelegation is not mutable")) + case "cosmos.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + panic(fmt.Errorf("field dst_validator_address of message cosmos.poolrebalancer.v1.PendingRedelegation is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) } } @@ -972,23 +972,23 @@ func (x *fastReflection_PendingRedelegation) Mutable(fd protoreflect.FieldDescri // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_PendingRedelegation) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.delegator_address": return protoreflect.ValueOfString("") - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.src_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.src_validator_address": return protoreflect.ValueOfString("") - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.dst_validator_address": + case "cosmos.poolrebalancer.v1.PendingRedelegation.dst_validator_address": return protoreflect.ValueOfString("") - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount": + case "cosmos.poolrebalancer.v1.PendingRedelegation.amount": m := new(v1beta1.Coin) return protoreflect.ValueOfMessage(m.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingRedelegation.completion_time": m := new(timestamppb.Timestamp) return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingRedelegation does not contain field %s", fd.FullName())) } } @@ -998,7 +998,7 @@ func (x *fastReflection_PendingRedelegation) NewField(fd protoreflect.FieldDescr func (x *fastReflection_PendingRedelegation) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.PendingRedelegation", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.PendingRedelegation", d.FullName())) } panic("unreachable") } @@ -1460,8 +1460,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() - md_QueuedRedelegation = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("QueuedRedelegation") + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() + md_QueuedRedelegation = File_cosmos_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("QueuedRedelegation") fd_QueuedRedelegation_entries = md_QueuedRedelegation.Fields().ByName("entries") } @@ -1474,7 +1474,7 @@ func (x *QueuedRedelegation) ProtoReflect() protoreflect.Message { } func (x *QueuedRedelegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[2] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1551,13 +1551,13 @@ func (x *fastReflection_QueuedRedelegation) Range(f func(protoreflect.FieldDescr // a repeated field is populated if it is non-empty. func (x *fastReflection_QueuedRedelegation) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedRedelegation.entries": return len(x.Entries) != 0 default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) } } @@ -1569,13 +1569,13 @@ func (x *fastReflection_QueuedRedelegation) Has(fd protoreflect.FieldDescriptor) // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueuedRedelegation) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedRedelegation.entries": x.Entries = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) } } @@ -1587,7 +1587,7 @@ func (x *fastReflection_QueuedRedelegation) Clear(fd protoreflect.FieldDescripto // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_QueuedRedelegation) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedRedelegation.entries": if len(x.Entries) == 0 { return protoreflect.ValueOfList(&_QueuedRedelegation_1_list{}) } @@ -1595,9 +1595,9 @@ func (x *fastReflection_QueuedRedelegation) Get(descriptor protoreflect.FieldDes return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedRedelegation does not contain field %s", descriptor.FullName())) } } @@ -1613,15 +1613,15 @@ func (x *fastReflection_QueuedRedelegation) Get(descriptor protoreflect.FieldDes // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueuedRedelegation) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedRedelegation.entries": lv := value.List() clv := lv.(*_QueuedRedelegation_1_list) x.Entries = *clv.list default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) } } @@ -1637,7 +1637,7 @@ func (x *fastReflection_QueuedRedelegation) Set(fd protoreflect.FieldDescriptor, // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueuedRedelegation) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedRedelegation.entries": if x.Entries == nil { x.Entries = []*PendingRedelegation{} } @@ -1645,9 +1645,9 @@ func (x *fastReflection_QueuedRedelegation) Mutable(fd protoreflect.FieldDescrip return protoreflect.ValueOfList(value) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) } } @@ -1656,14 +1656,14 @@ func (x *fastReflection_QueuedRedelegation) Mutable(fd protoreflect.FieldDescrip // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_QueuedRedelegation) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedRedelegation.entries": list := []*PendingRedelegation{} return protoreflect.ValueOfList(&_QueuedRedelegation_1_list{list: &list}) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedRedelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedRedelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedRedelegation does not contain field %s", fd.FullName())) } } @@ -1673,7 +1673,7 @@ func (x *fastReflection_QueuedRedelegation) NewField(fd protoreflect.FieldDescri func (x *fastReflection_QueuedRedelegation) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueuedRedelegation", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.QueuedRedelegation", d.FullName())) } panic("unreachable") } @@ -1906,8 +1906,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() - md_PendingUndelegation = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("PendingUndelegation") + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() + md_PendingUndelegation = File_cosmos_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("PendingUndelegation") fd_PendingUndelegation_delegator_address = md_PendingUndelegation.Fields().ByName("delegator_address") fd_PendingUndelegation_validator_address = md_PendingUndelegation.Fields().ByName("validator_address") fd_PendingUndelegation_balance = md_PendingUndelegation.Fields().ByName("balance") @@ -1923,7 +1923,7 @@ func (x *PendingUndelegation) ProtoReflect() protoreflect.Message { } func (x *PendingUndelegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[3] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2018,19 +2018,19 @@ func (x *fastReflection_PendingUndelegation) Range(f func(protoreflect.FieldDesc // a repeated field is populated if it is non-empty. func (x *fastReflection_PendingUndelegation) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.delegator_address": return x.DelegatorAddress != "" - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.validator_address": return x.ValidatorAddress != "" - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + case "cosmos.poolrebalancer.v1.PendingUndelegation.balance": return x.Balance != nil - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingUndelegation.completion_time": return x.CompletionTime != nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) } } @@ -2042,19 +2042,19 @@ func (x *fastReflection_PendingUndelegation) Has(fd protoreflect.FieldDescriptor // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_PendingUndelegation) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.delegator_address": x.DelegatorAddress = "" - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.validator_address": x.ValidatorAddress = "" - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + case "cosmos.poolrebalancer.v1.PendingUndelegation.balance": x.Balance = nil - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingUndelegation.completion_time": x.CompletionTime = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) } } @@ -2066,23 +2066,23 @@ func (x *fastReflection_PendingUndelegation) Clear(fd protoreflect.FieldDescript // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_PendingUndelegation) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.delegator_address": value := x.DelegatorAddress return protoreflect.ValueOfString(value) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.validator_address": value := x.ValidatorAddress return protoreflect.ValueOfString(value) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + case "cosmos.poolrebalancer.v1.PendingUndelegation.balance": value := x.Balance return protoreflect.ValueOfMessage(value.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingUndelegation.completion_time": value := x.CompletionTime return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingUndelegation does not contain field %s", descriptor.FullName())) } } @@ -2098,19 +2098,19 @@ func (x *fastReflection_PendingUndelegation) Get(descriptor protoreflect.FieldDe // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_PendingUndelegation) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.delegator_address": x.DelegatorAddress = value.Interface().(string) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.validator_address": x.ValidatorAddress = value.Interface().(string) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + case "cosmos.poolrebalancer.v1.PendingUndelegation.balance": x.Balance = value.Message().Interface().(*v1beta1.Coin) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingUndelegation.completion_time": x.CompletionTime = value.Message().Interface().(*timestamppb.Timestamp) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) } } @@ -2126,25 +2126,25 @@ func (x *fastReflection_PendingUndelegation) Set(fd protoreflect.FieldDescriptor // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_PendingUndelegation) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + case "cosmos.poolrebalancer.v1.PendingUndelegation.balance": if x.Balance == nil { x.Balance = new(v1beta1.Coin) } return protoreflect.ValueOfMessage(x.Balance.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingUndelegation.completion_time": if x.CompletionTime == nil { x.CompletionTime = new(timestamppb.Timestamp) } return protoreflect.ValueOfMessage(x.CompletionTime.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": - panic(fmt.Errorf("field delegator_address of message cosmos.evm.poolrebalancer.v1.PendingUndelegation is not mutable")) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": - panic(fmt.Errorf("field validator_address of message cosmos.evm.poolrebalancer.v1.PendingUndelegation is not mutable")) + case "cosmos.poolrebalancer.v1.PendingUndelegation.delegator_address": + panic(fmt.Errorf("field delegator_address of message cosmos.poolrebalancer.v1.PendingUndelegation is not mutable")) + case "cosmos.poolrebalancer.v1.PendingUndelegation.validator_address": + panic(fmt.Errorf("field validator_address of message cosmos.poolrebalancer.v1.PendingUndelegation is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) } } @@ -2153,21 +2153,21 @@ func (x *fastReflection_PendingUndelegation) Mutable(fd protoreflect.FieldDescri // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_PendingUndelegation) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.delegator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.delegator_address": return protoreflect.ValueOfString("") - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.validator_address": + case "cosmos.poolrebalancer.v1.PendingUndelegation.validator_address": return protoreflect.ValueOfString("") - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance": + case "cosmos.poolrebalancer.v1.PendingUndelegation.balance": m := new(v1beta1.Coin) return protoreflect.ValueOfMessage(m.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time": + case "cosmos.poolrebalancer.v1.PendingUndelegation.completion_time": m := new(timestamppb.Timestamp) return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.PendingUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.PendingUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.PendingUndelegation does not contain field %s", fd.FullName())) } } @@ -2177,7 +2177,7 @@ func (x *fastReflection_PendingUndelegation) NewField(fd protoreflect.FieldDescr func (x *fastReflection_PendingUndelegation) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.PendingUndelegation", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.PendingUndelegation", d.FullName())) } panic("unreachable") } @@ -2596,8 +2596,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() - md_QueuedUndelegation = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("QueuedUndelegation") + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() + md_QueuedUndelegation = File_cosmos_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("QueuedUndelegation") fd_QueuedUndelegation_entries = md_QueuedUndelegation.Fields().ByName("entries") } @@ -2610,7 +2610,7 @@ func (x *QueuedUndelegation) ProtoReflect() protoreflect.Message { } func (x *QueuedUndelegation) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[4] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2687,13 +2687,13 @@ func (x *fastReflection_QueuedUndelegation) Range(f func(protoreflect.FieldDescr // a repeated field is populated if it is non-empty. func (x *fastReflection_QueuedUndelegation) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedUndelegation.entries": return len(x.Entries) != 0 default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) } } @@ -2705,13 +2705,13 @@ func (x *fastReflection_QueuedUndelegation) Has(fd protoreflect.FieldDescriptor) // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueuedUndelegation) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedUndelegation.entries": x.Entries = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) } } @@ -2723,7 +2723,7 @@ func (x *fastReflection_QueuedUndelegation) Clear(fd protoreflect.FieldDescripto // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_QueuedUndelegation) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedUndelegation.entries": if len(x.Entries) == 0 { return protoreflect.ValueOfList(&_QueuedUndelegation_1_list{}) } @@ -2731,9 +2731,9 @@ func (x *fastReflection_QueuedUndelegation) Get(descriptor protoreflect.FieldDes return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedUndelegation does not contain field %s", descriptor.FullName())) } } @@ -2749,15 +2749,15 @@ func (x *fastReflection_QueuedUndelegation) Get(descriptor protoreflect.FieldDes // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueuedUndelegation) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedUndelegation.entries": lv := value.List() clv := lv.(*_QueuedUndelegation_1_list) x.Entries = *clv.list default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) } } @@ -2773,7 +2773,7 @@ func (x *fastReflection_QueuedUndelegation) Set(fd protoreflect.FieldDescriptor, // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueuedUndelegation) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedUndelegation.entries": if x.Entries == nil { x.Entries = []*PendingUndelegation{} } @@ -2781,9 +2781,9 @@ func (x *fastReflection_QueuedUndelegation) Mutable(fd protoreflect.FieldDescrip return protoreflect.ValueOfList(value) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) } } @@ -2792,14 +2792,14 @@ func (x *fastReflection_QueuedUndelegation) Mutable(fd protoreflect.FieldDescrip // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_QueuedUndelegation) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries": + case "cosmos.poolrebalancer.v1.QueuedUndelegation.entries": list := []*PendingUndelegation{} return protoreflect.ValueOfList(&_QueuedUndelegation_1_list{list: &list}) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueuedUndelegation")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueuedUndelegation")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueuedUndelegation does not contain field %s", fd.FullName())) } } @@ -2809,7 +2809,7 @@ func (x *fastReflection_QueuedUndelegation) NewField(fd protoreflect.FieldDescri func (x *fastReflection_QueuedUndelegation) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueuedUndelegation", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.QueuedUndelegation", d.FullName())) } panic("unreachable") } @@ -3143,8 +3143,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() - md_GenesisState = File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("GenesisState") + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() + md_GenesisState = File_cosmos_poolrebalancer_v1_poolrebalancer_proto.Messages().ByName("GenesisState") fd_GenesisState_params = md_GenesisState.Fields().ByName("params") fd_GenesisState_pending_redelegations = md_GenesisState.Fields().ByName("pending_redelegations") fd_GenesisState_pending_undelegations = md_GenesisState.Fields().ByName("pending_undelegations") @@ -3159,7 +3159,7 @@ func (x *GenesisState) ProtoReflect() protoreflect.Message { } func (x *GenesisState) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[5] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3248,17 +3248,17 @@ func (x *fastReflection_GenesisState) Range(f func(protoreflect.FieldDescriptor, // a repeated field is populated if it is non-empty. func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + case "cosmos.poolrebalancer.v1.GenesisState.params": return x.Params != nil - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_redelegations": return len(x.PendingRedelegations) != 0 - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_undelegations": return len(x.PendingUndelegations) != 0 default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.GenesisState")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) } } @@ -3270,17 +3270,17 @@ func (x *fastReflection_GenesisState) Has(fd protoreflect.FieldDescriptor) bool // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + case "cosmos.poolrebalancer.v1.GenesisState.params": x.Params = nil - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_redelegations": x.PendingRedelegations = nil - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_undelegations": x.PendingUndelegations = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.GenesisState")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) } } @@ -3292,16 +3292,16 @@ func (x *fastReflection_GenesisState) Clear(fd protoreflect.FieldDescriptor) { // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + case "cosmos.poolrebalancer.v1.GenesisState.params": value := x.Params return protoreflect.ValueOfMessage(value.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_redelegations": if len(x.PendingRedelegations) == 0 { return protoreflect.ValueOfList(&_GenesisState_2_list{}) } listValue := &_GenesisState_2_list{list: &x.PendingRedelegations} return protoreflect.ValueOfList(listValue) - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_undelegations": if len(x.PendingUndelegations) == 0 { return protoreflect.ValueOfList(&_GenesisState_3_list{}) } @@ -3309,9 +3309,9 @@ func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescripto return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.GenesisState")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.GenesisState does not contain field %s", descriptor.FullName())) } } @@ -3327,21 +3327,21 @@ func (x *fastReflection_GenesisState) Get(descriptor protoreflect.FieldDescripto // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + case "cosmos.poolrebalancer.v1.GenesisState.params": x.Params = value.Message().Interface().(*Params) - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_redelegations": lv := value.List() clv := lv.(*_GenesisState_2_list) x.PendingRedelegations = *clv.list - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_undelegations": lv := value.List() clv := lv.(*_GenesisState_3_list) x.PendingUndelegations = *clv.list default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.GenesisState")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) } } @@ -3357,18 +3357,18 @@ func (x *fastReflection_GenesisState) Set(fd protoreflect.FieldDescriptor, value // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + case "cosmos.poolrebalancer.v1.GenesisState.params": if x.Params == nil { x.Params = new(Params) } return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_redelegations": if x.PendingRedelegations == nil { x.PendingRedelegations = []*PendingRedelegation{} } value := &_GenesisState_2_list{list: &x.PendingRedelegations} return protoreflect.ValueOfList(value) - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_undelegations": if x.PendingUndelegations == nil { x.PendingUndelegations = []*PendingUndelegation{} } @@ -3376,9 +3376,9 @@ func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) p return protoreflect.ValueOfList(value) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.GenesisState")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) } } @@ -3387,20 +3387,20 @@ func (x *fastReflection_GenesisState) Mutable(fd protoreflect.FieldDescriptor) p // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.GenesisState.params": + case "cosmos.poolrebalancer.v1.GenesisState.params": m := new(Params) return protoreflect.ValueOfMessage(m.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_redelegations": list := []*PendingRedelegation{} return protoreflect.ValueOfList(&_GenesisState_2_list{list: &list}) - case "cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations": + case "cosmos.poolrebalancer.v1.GenesisState.pending_undelegations": list := []*PendingUndelegation{} return protoreflect.ValueOfList(&_GenesisState_3_list{list: &list}) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.GenesisState")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.GenesisState")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.GenesisState does not contain field %s", fd.FullName())) } } @@ -3410,7 +3410,7 @@ func (x *fastReflection_GenesisState) NewField(fd protoreflect.FieldDescriptor) func (x *fastReflection_GenesisState) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.GenesisState", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.GenesisState", d.FullName())) } panic("unreachable") } @@ -3748,7 +3748,7 @@ func (x *fastReflection_GenesisState) ProtoMethods() *protoiface.Methods { // versions: // protoc-gen-go v1.27.0 // protoc (unknown) -// source: cosmos/evm/poolrebalancer/v1/poolrebalancer.proto +// source: cosmos/poolrebalancer/v1/poolrebalancer.proto const ( // Verify that this generated code is sufficiently up-to-date. @@ -3780,7 +3780,7 @@ type Params struct { func (x *Params) Reset() { *x = Params{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[0] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3794,7 +3794,7 @@ func (*Params) ProtoMessage() {} // Deprecated: Use Params.ProtoReflect.Descriptor instead. func (*Params) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{0} + return file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{0} } func (x *Params) GetPoolDelegatorAddress() string { @@ -3855,7 +3855,7 @@ type PendingRedelegation struct { func (x *PendingRedelegation) Reset() { *x = PendingRedelegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[1] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3869,7 +3869,7 @@ func (*PendingRedelegation) ProtoMessage() {} // Deprecated: Use PendingRedelegation.ProtoReflect.Descriptor instead. func (*PendingRedelegation) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{1} + return file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{1} } func (x *PendingRedelegation) GetDelegatorAddress() string { @@ -3919,7 +3919,7 @@ type QueuedRedelegation struct { func (x *QueuedRedelegation) Reset() { *x = QueuedRedelegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[2] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3933,7 +3933,7 @@ func (*QueuedRedelegation) ProtoMessage() {} // Deprecated: Use QueuedRedelegation.ProtoReflect.Descriptor instead. func (*QueuedRedelegation) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{2} + return file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{2} } func (x *QueuedRedelegation) GetEntries() []*PendingRedelegation { @@ -3958,7 +3958,7 @@ type PendingUndelegation struct { func (x *PendingUndelegation) Reset() { *x = PendingUndelegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[3] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3972,7 +3972,7 @@ func (*PendingUndelegation) ProtoMessage() {} // Deprecated: Use PendingUndelegation.ProtoReflect.Descriptor instead. func (*PendingUndelegation) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{3} + return file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{3} } func (x *PendingUndelegation) GetDelegatorAddress() string { @@ -4015,7 +4015,7 @@ type QueuedUndelegation struct { func (x *QueuedUndelegation) Reset() { *x = QueuedUndelegation{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[4] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4029,7 +4029,7 @@ func (*QueuedUndelegation) ProtoMessage() {} // Deprecated: Use QueuedUndelegation.ProtoReflect.Descriptor instead. func (*QueuedUndelegation) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{4} + return file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{4} } func (x *QueuedUndelegation) GetEntries() []*PendingUndelegation { @@ -4055,7 +4055,7 @@ type GenesisState struct { func (x *GenesisState) Reset() { *x = GenesisState{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[5] + mi := &file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4069,7 +4069,7 @@ func (*GenesisState) ProtoMessage() {} // Deprecated: Use GenesisState.ProtoReflect.Descriptor instead. func (*GenesisState) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{5} + return file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP(), []int{5} } func (x *GenesisState) GetParams() *Params { @@ -4093,161 +4093,158 @@ func (x *GenesisState) GetPendingUndelegations() []*PendingUndelegation { return nil } -var File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto protoreflect.FileDescriptor - -var file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDesc = []byte{ - 0x0a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, - 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, - 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, - 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, - 0x31, 0x1a, 0x1e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, - 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd1, 0x02, 0x0a, 0x06, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x70, 0x6f, 0x6f, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x14, 0x70, 0x6f, 0x6f, 0x6c, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x6d, 0x61, 0x78, - 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, - 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x54, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x34, 0x0a, - 0x16, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, - 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x72, - 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, - 0x64, 0x42, 0x70, 0x12, 0x29, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x5f, 0x6f, 0x70, 0x73, 0x5f, 0x70, - 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, - 0x6d, 0x61, 0x78, 0x4f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x44, - 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6f, - 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1d, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, - 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, - 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x4d, 0x6f, 0x76, 0x65, 0x50, - 0x65, 0x72, 0x4f, 0x70, 0x12, 0x36, 0x0a, 0x17, 0x75, 0x73, 0x65, 0x5f, 0x75, 0x6e, 0x64, 0x65, - 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x66, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x75, 0x73, 0x65, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x65, 0x46, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x22, 0xb2, 0x02, 0x0a, - 0x13, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, - 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x72, 0x63, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x13, 0x73, 0x72, 0x63, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x64, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x61, 0x6d, 0x6f, - 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x4d, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, - 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, - 0x65, 0x22, 0x67, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x75, 0x65, 0x64, 0x52, 0x65, 0x64, 0x65, 0x6c, - 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, - 0x00, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xf9, 0x01, 0x0a, 0x13, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, - 0x2b, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x39, 0x0a, 0x07, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x07, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xc8, 0xde, - 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, - 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x67, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x75, 0x65, 0x64, - 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x51, 0x0a, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, +var File_cosmos_poolrebalancer_v1_poolrebalancer_proto protoreflect.FileDescriptor + +var file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDesc = []byte{ + 0x0a, 0x2d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, + 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x18, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x1e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, + 0x6f, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xd1, 0x02, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x70, + 0x6f, 0x6f, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x70, 0x6f, 0x6f, + 0x6c, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x32, 0x0a, 0x15, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x13, 0x6d, 0x61, 0x78, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x61, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x5f, 0x62, 0x70, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x42, 0x70, 0x12, 0x29, 0x0a, 0x11, 0x6d, + 0x61, 0x78, 0x5f, 0x6f, 0x70, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x4f, 0x70, 0x73, 0x50, 0x65, + 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x44, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x6f, + 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6f, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x1d, 0xc8, 0xde, 0x1f, 0x00, 0xda, 0xde, 0x1f, 0x15, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, + 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x6d, 0x61, 0x74, 0x68, 0x2e, 0x49, 0x6e, 0x74, 0x52, 0x0c, + 0x6d, 0x61, 0x78, 0x4d, 0x6f, 0x76, 0x65, 0x50, 0x65, 0x72, 0x4f, 0x70, 0x12, 0x36, 0x0a, 0x17, + 0x75, 0x73, 0x65, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x5f, 0x66, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x75, + 0x73, 0x65, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x65, 0x46, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x22, 0xb2, 0x02, 0x0a, 0x13, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, + 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x72, 0x63, + 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x72, 0x63, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, + 0x15, 0x64, 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x64, 0x73, + 0x74, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x37, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, + 0x1f, 0x00, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x4d, 0x0a, 0x0f, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, + 0x08, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x63, 0x0a, 0x12, 0x51, 0x75, 0x65, + 0x75, 0x65, 0x64, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x4d, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, + 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0xf9, + 0x01, 0x0a, 0x13, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, + 0x74, 0x6f, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x10, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x39, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x04, 0xc8, 0xde, + 0x1f, 0x00, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x0f, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x42, 0x08, 0xc8, 0xde, 0x1f, 0x00, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x63, 0x0a, 0x12, 0x51, 0x75, + 0x65, 0x75, 0x65, 0x64, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x4d, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, - 0xae, 0x02, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x42, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, - 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x12, 0x6c, 0x0a, 0x15, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, - 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, - 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x14, 0x70, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x6c, 0x0a, 0x15, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, - 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, - 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x14, 0x70, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x42, 0x8e, 0x02, 0x0a, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0xa2, 0x02, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x73, 0x69, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x12, 0x3e, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, + 0x12, 0x68, 0x0a, 0x15, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x64, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, + 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x14, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x68, 0x0a, 0x15, 0x70, 0x65, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x04, 0xc8, 0xde, 0x1f, 0x00, 0x52, 0x14, + 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x42, 0xf5, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x13, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x63, 0x6f, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 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, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x6f, 0x6f, 0x6c, - 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, - 0x45, 0x50, 0xaa, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x2e, - 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x56, - 0x31, 0xca, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, - 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, - 0xe2, 0x02, 0x28, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x50, 0x58, 0xaa, 0x02, + 0x18, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x5c, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x24, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x43, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x50, 0x6f, 0x6f, 0x6c, 0x72, - 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0xc8, 0xe1, 0x1e, - 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x43, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0xc8, 0xe1, 0x1e, 0x00, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescOnce sync.Once - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescData = file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDesc + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescOnce sync.Once + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescData = file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDesc ) -func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP() []byte { - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescOnce.Do(func() { - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescData) +func file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescGZIP() []byte { + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescOnce.Do(func() { + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescData) }) - return file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDescData + return file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDescData } -var file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_goTypes = []interface{}{ - (*Params)(nil), // 0: cosmos.evm.poolrebalancer.v1.Params - (*PendingRedelegation)(nil), // 1: cosmos.evm.poolrebalancer.v1.PendingRedelegation - (*QueuedRedelegation)(nil), // 2: cosmos.evm.poolrebalancer.v1.QueuedRedelegation - (*PendingUndelegation)(nil), // 3: cosmos.evm.poolrebalancer.v1.PendingUndelegation - (*QueuedUndelegation)(nil), // 4: cosmos.evm.poolrebalancer.v1.QueuedUndelegation - (*GenesisState)(nil), // 5: cosmos.evm.poolrebalancer.v1.GenesisState +var file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_cosmos_poolrebalancer_v1_poolrebalancer_proto_goTypes = []interface{}{ + (*Params)(nil), // 0: cosmos.poolrebalancer.v1.Params + (*PendingRedelegation)(nil), // 1: cosmos.poolrebalancer.v1.PendingRedelegation + (*QueuedRedelegation)(nil), // 2: cosmos.poolrebalancer.v1.QueuedRedelegation + (*PendingUndelegation)(nil), // 3: cosmos.poolrebalancer.v1.PendingUndelegation + (*QueuedUndelegation)(nil), // 4: cosmos.poolrebalancer.v1.QueuedUndelegation + (*GenesisState)(nil), // 5: cosmos.poolrebalancer.v1.GenesisState (*v1beta1.Coin)(nil), // 6: cosmos.base.v1beta1.Coin (*timestamppb.Timestamp)(nil), // 7: google.protobuf.Timestamp } -var file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_depIdxs = []int32{ - 6, // 0: cosmos.evm.poolrebalancer.v1.PendingRedelegation.amount:type_name -> cosmos.base.v1beta1.Coin - 7, // 1: cosmos.evm.poolrebalancer.v1.PendingRedelegation.completion_time:type_name -> google.protobuf.Timestamp - 1, // 2: cosmos.evm.poolrebalancer.v1.QueuedRedelegation.entries:type_name -> cosmos.evm.poolrebalancer.v1.PendingRedelegation - 6, // 3: cosmos.evm.poolrebalancer.v1.PendingUndelegation.balance:type_name -> cosmos.base.v1beta1.Coin - 7, // 4: cosmos.evm.poolrebalancer.v1.PendingUndelegation.completion_time:type_name -> google.protobuf.Timestamp - 3, // 5: cosmos.evm.poolrebalancer.v1.QueuedUndelegation.entries:type_name -> cosmos.evm.poolrebalancer.v1.PendingUndelegation - 0, // 6: cosmos.evm.poolrebalancer.v1.GenesisState.params:type_name -> cosmos.evm.poolrebalancer.v1.Params - 1, // 7: cosmos.evm.poolrebalancer.v1.GenesisState.pending_redelegations:type_name -> cosmos.evm.poolrebalancer.v1.PendingRedelegation - 3, // 8: cosmos.evm.poolrebalancer.v1.GenesisState.pending_undelegations:type_name -> cosmos.evm.poolrebalancer.v1.PendingUndelegation +var file_cosmos_poolrebalancer_v1_poolrebalancer_proto_depIdxs = []int32{ + 6, // 0: cosmos.poolrebalancer.v1.PendingRedelegation.amount:type_name -> cosmos.base.v1beta1.Coin + 7, // 1: cosmos.poolrebalancer.v1.PendingRedelegation.completion_time:type_name -> google.protobuf.Timestamp + 1, // 2: cosmos.poolrebalancer.v1.QueuedRedelegation.entries:type_name -> cosmos.poolrebalancer.v1.PendingRedelegation + 6, // 3: cosmos.poolrebalancer.v1.PendingUndelegation.balance:type_name -> cosmos.base.v1beta1.Coin + 7, // 4: cosmos.poolrebalancer.v1.PendingUndelegation.completion_time:type_name -> google.protobuf.Timestamp + 3, // 5: cosmos.poolrebalancer.v1.QueuedUndelegation.entries:type_name -> cosmos.poolrebalancer.v1.PendingUndelegation + 0, // 6: cosmos.poolrebalancer.v1.GenesisState.params:type_name -> cosmos.poolrebalancer.v1.Params + 1, // 7: cosmos.poolrebalancer.v1.GenesisState.pending_redelegations:type_name -> cosmos.poolrebalancer.v1.PendingRedelegation + 3, // 8: cosmos.poolrebalancer.v1.GenesisState.pending_undelegations:type_name -> cosmos.poolrebalancer.v1.PendingUndelegation 9, // [9:9] is the sub-list for method output_type 9, // [9:9] is the sub-list for method input_type 9, // [9:9] is the sub-list for extension type_name @@ -4255,13 +4252,13 @@ var file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_depIdxs = []int32{ 0, // [0:9] is the sub-list for field type_name } -func init() { file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() } -func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() { - if File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto != nil { +func init() { file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() } +func file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() { + if File_cosmos_poolrebalancer_v1_poolrebalancer_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Params); i { case 0: return &v.state @@ -4273,7 +4270,7 @@ func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PendingRedelegation); i { case 0: return &v.state @@ -4285,7 +4282,7 @@ func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueuedRedelegation); i { case 0: return &v.state @@ -4297,7 +4294,7 @@ func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PendingUndelegation); i { case 0: return &v.state @@ -4309,7 +4306,7 @@ func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueuedUndelegation); i { case 0: return &v.state @@ -4321,7 +4318,7 @@ func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*GenesisState); i { case 0: return &v.state @@ -4338,18 +4335,18 @@ func file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDesc, + RawDescriptor: file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDesc, NumEnums: 0, NumMessages: 6, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_goTypes, - DependencyIndexes: file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_depIdxs, - MessageInfos: file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_msgTypes, + GoTypes: file_cosmos_poolrebalancer_v1_poolrebalancer_proto_goTypes, + DependencyIndexes: file_cosmos_poolrebalancer_v1_poolrebalancer_proto_depIdxs, + MessageInfos: file_cosmos_poolrebalancer_v1_poolrebalancer_proto_msgTypes, }.Build() - File_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto = out.File - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_rawDesc = nil - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_goTypes = nil - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_depIdxs = nil + File_cosmos_poolrebalancer_v1_poolrebalancer_proto = out.File + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_rawDesc = nil + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_goTypes = nil + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_depIdxs = nil } diff --git a/api/cosmos/evm/poolrebalancer/v1/query.pulsar.go b/api/cosmos/poolrebalancer/v1/query.pulsar.go similarity index 80% rename from api/cosmos/evm/poolrebalancer/v1/query.pulsar.go rename to api/cosmos/poolrebalancer/v1/query.pulsar.go index 475c4fbc..7a1c2dc4 100644 --- a/api/cosmos/evm/poolrebalancer/v1/query.pulsar.go +++ b/api/cosmos/poolrebalancer/v1/query.pulsar.go @@ -21,8 +21,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_query_proto_init() - md_QueryParamsRequest = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryParamsRequest") + file_cosmos_poolrebalancer_v1_query_proto_init() + md_QueryParamsRequest = File_cosmos_poolrebalancer_v1_query_proto.Messages().ByName("QueryParamsRequest") } var _ protoreflect.Message = (*fastReflection_QueryParamsRequest)(nil) @@ -34,7 +34,7 @@ func (x *QueryParamsRequest) ProtoReflect() protoreflect.Message { } func (x *QueryParamsRequest) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[0] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -107,9 +107,9 @@ func (x *fastReflection_QueryParamsRequest) Has(fd protoreflect.FieldDescriptor) switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) } } @@ -123,9 +123,9 @@ func (x *fastReflection_QueryParamsRequest) Clear(fd protoreflect.FieldDescripto switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) } } @@ -139,9 +139,9 @@ func (x *fastReflection_QueryParamsRequest) Get(descriptor protoreflect.FieldDes switch descriptor.FullName() { default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsRequest does not contain field %s", descriptor.FullName())) } } @@ -159,9 +159,9 @@ func (x *fastReflection_QueryParamsRequest) Set(fd protoreflect.FieldDescriptor, switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) } } @@ -179,9 +179,9 @@ func (x *fastReflection_QueryParamsRequest) Mutable(fd protoreflect.FieldDescrip switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) } } @@ -192,9 +192,9 @@ func (x *fastReflection_QueryParamsRequest) NewField(fd protoreflect.FieldDescri switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsRequest does not contain field %s", fd.FullName())) } } @@ -204,7 +204,7 @@ func (x *fastReflection_QueryParamsRequest) NewField(fd protoreflect.FieldDescri func (x *fastReflection_QueryParamsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryParamsRequest", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.QueryParamsRequest", d.FullName())) } panic("unreachable") } @@ -378,8 +378,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_query_proto_init() - md_QueryParamsResponse = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryParamsResponse") + file_cosmos_poolrebalancer_v1_query_proto_init() + md_QueryParamsResponse = File_cosmos_poolrebalancer_v1_query_proto.Messages().ByName("QueryParamsResponse") fd_QueryParamsResponse_params = md_QueryParamsResponse.Fields().ByName("params") } @@ -392,7 +392,7 @@ func (x *QueryParamsResponse) ProtoReflect() protoreflect.Message { } func (x *QueryParamsResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[1] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -469,13 +469,13 @@ func (x *fastReflection_QueryParamsResponse) Range(f func(protoreflect.FieldDesc // a repeated field is populated if it is non-empty. func (x *fastReflection_QueryParamsResponse) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + case "cosmos.poolrebalancer.v1.QueryParamsResponse.params": return x.Params != nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) } } @@ -487,13 +487,13 @@ func (x *fastReflection_QueryParamsResponse) Has(fd protoreflect.FieldDescriptor // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryParamsResponse) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + case "cosmos.poolrebalancer.v1.QueryParamsResponse.params": x.Params = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) } } @@ -505,14 +505,14 @@ func (x *fastReflection_QueryParamsResponse) Clear(fd protoreflect.FieldDescript // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_QueryParamsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + case "cosmos.poolrebalancer.v1.QueryParamsResponse.params": value := x.Params return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsResponse does not contain field %s", descriptor.FullName())) } } @@ -528,13 +528,13 @@ func (x *fastReflection_QueryParamsResponse) Get(descriptor protoreflect.FieldDe // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryParamsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + case "cosmos.poolrebalancer.v1.QueryParamsResponse.params": x.Params = value.Message().Interface().(*Params) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) } } @@ -550,16 +550,16 @@ func (x *fastReflection_QueryParamsResponse) Set(fd protoreflect.FieldDescriptor // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryParamsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + case "cosmos.poolrebalancer.v1.QueryParamsResponse.params": if x.Params == nil { x.Params = new(Params) } return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) } } @@ -568,14 +568,14 @@ func (x *fastReflection_QueryParamsResponse) Mutable(fd protoreflect.FieldDescri // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_QueryParamsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params": + case "cosmos.poolrebalancer.v1.QueryParamsResponse.params": m := new(Params) return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryParamsResponse does not contain field %s", fd.FullName())) } } @@ -585,7 +585,7 @@ func (x *fastReflection_QueryParamsResponse) NewField(fd protoreflect.FieldDescr func (x *fastReflection_QueryParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryParamsResponse", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.QueryParamsResponse", d.FullName())) } panic("unreachable") } @@ -813,8 +813,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_query_proto_init() - md_QueryPendingRedelegationsRequest = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingRedelegationsRequest") + file_cosmos_poolrebalancer_v1_query_proto_init() + md_QueryPendingRedelegationsRequest = File_cosmos_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingRedelegationsRequest") fd_QueryPendingRedelegationsRequest_pagination = md_QueryPendingRedelegationsRequest.Fields().ByName("pagination") } @@ -827,7 +827,7 @@ func (x *QueryPendingRedelegationsRequest) ProtoReflect() protoreflect.Message { } func (x *QueryPendingRedelegationsRequest) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[2] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -904,13 +904,13 @@ func (x *fastReflection_QueryPendingRedelegationsRequest) Range(f func(protorefl // a repeated field is populated if it is non-empty. func (x *fastReflection_QueryPendingRedelegationsRequest) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": return x.Pagination != nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) } } @@ -922,13 +922,13 @@ func (x *fastReflection_QueryPendingRedelegationsRequest) Has(fd protoreflect.Fi // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingRedelegationsRequest) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": x.Pagination = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) } } @@ -940,14 +940,14 @@ func (x *fastReflection_QueryPendingRedelegationsRequest) Clear(fd protoreflect. // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_QueryPendingRedelegationsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": value := x.Pagination return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", descriptor.FullName())) } } @@ -963,13 +963,13 @@ func (x *fastReflection_QueryPendingRedelegationsRequest) Get(descriptor protore // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingRedelegationsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": x.Pagination = value.Message().Interface().(*v1beta1.PageRequest) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) } } @@ -985,16 +985,16 @@ func (x *fastReflection_QueryPendingRedelegationsRequest) Set(fd protoreflect.Fi // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingRedelegationsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": if x.Pagination == nil { x.Pagination = new(v1beta1.PageRequest) } return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) } } @@ -1003,14 +1003,14 @@ func (x *fastReflection_QueryPendingRedelegationsRequest) Mutable(fd protoreflec // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_QueryPendingRedelegationsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination": m := new(v1beta1.PageRequest) return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest does not contain field %s", fd.FullName())) } } @@ -1020,7 +1020,7 @@ func (x *fastReflection_QueryPendingRedelegationsRequest) NewField(fd protorefle func (x *fastReflection_QueryPendingRedelegationsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest", d.FullName())) } panic("unreachable") } @@ -1300,8 +1300,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_query_proto_init() - md_QueryPendingRedelegationsResponse = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingRedelegationsResponse") + file_cosmos_poolrebalancer_v1_query_proto_init() + md_QueryPendingRedelegationsResponse = File_cosmos_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingRedelegationsResponse") fd_QueryPendingRedelegationsResponse_redelegations = md_QueryPendingRedelegationsResponse.Fields().ByName("redelegations") fd_QueryPendingRedelegationsResponse_pagination = md_QueryPendingRedelegationsResponse.Fields().ByName("pagination") } @@ -1315,7 +1315,7 @@ func (x *QueryPendingRedelegationsResponse) ProtoReflect() protoreflect.Message } func (x *QueryPendingRedelegationsResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[3] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1398,15 +1398,15 @@ func (x *fastReflection_QueryPendingRedelegationsResponse) Range(f func(protoref // a repeated field is populated if it is non-empty. func (x *fastReflection_QueryPendingRedelegationsResponse) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": return len(x.Redelegations) != 0 - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": return x.Pagination != nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) } } @@ -1418,15 +1418,15 @@ func (x *fastReflection_QueryPendingRedelegationsResponse) Has(fd protoreflect.F // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingRedelegationsResponse) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": x.Redelegations = nil - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": x.Pagination = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) } } @@ -1438,20 +1438,20 @@ func (x *fastReflection_QueryPendingRedelegationsResponse) Clear(fd protoreflect // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_QueryPendingRedelegationsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": if len(x.Redelegations) == 0 { return protoreflect.ValueOfList(&_QueryPendingRedelegationsResponse_1_list{}) } listValue := &_QueryPendingRedelegationsResponse_1_list{list: &x.Redelegations} return protoreflect.ValueOfList(listValue) - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": value := x.Pagination return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", descriptor.FullName())) } } @@ -1467,17 +1467,17 @@ func (x *fastReflection_QueryPendingRedelegationsResponse) Get(descriptor protor // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingRedelegationsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": lv := value.List() clv := lv.(*_QueryPendingRedelegationsResponse_1_list) x.Redelegations = *clv.list - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": x.Pagination = value.Message().Interface().(*v1beta1.PageResponse) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) } } @@ -1493,22 +1493,22 @@ func (x *fastReflection_QueryPendingRedelegationsResponse) Set(fd protoreflect.F // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingRedelegationsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": if x.Redelegations == nil { x.Redelegations = []*PendingRedelegation{} } value := &_QueryPendingRedelegationsResponse_1_list{list: &x.Redelegations} return protoreflect.ValueOfList(value) - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": if x.Pagination == nil { x.Pagination = new(v1beta1.PageResponse) } return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) } } @@ -1517,17 +1517,17 @@ func (x *fastReflection_QueryPendingRedelegationsResponse) Mutable(fd protorefle // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_QueryPendingRedelegationsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations": list := []*PendingRedelegation{} return protoreflect.ValueOfList(&_QueryPendingRedelegationsResponse_1_list{list: &list}) - case "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination": m := new(v1beta1.PageResponse) return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse does not contain field %s", fd.FullName())) } } @@ -1537,7 +1537,7 @@ func (x *fastReflection_QueryPendingRedelegationsResponse) NewField(fd protorefl func (x *fastReflection_QueryPendingRedelegationsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse", d.FullName())) } panic("unreachable") } @@ -1821,8 +1821,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_query_proto_init() - md_QueryPendingUndelegationsRequest = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingUndelegationsRequest") + file_cosmos_poolrebalancer_v1_query_proto_init() + md_QueryPendingUndelegationsRequest = File_cosmos_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingUndelegationsRequest") fd_QueryPendingUndelegationsRequest_pagination = md_QueryPendingUndelegationsRequest.Fields().ByName("pagination") } @@ -1835,7 +1835,7 @@ func (x *QueryPendingUndelegationsRequest) ProtoReflect() protoreflect.Message { } func (x *QueryPendingUndelegationsRequest) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[4] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1912,13 +1912,13 @@ func (x *fastReflection_QueryPendingUndelegationsRequest) Range(f func(protorefl // a repeated field is populated if it is non-empty. func (x *fastReflection_QueryPendingUndelegationsRequest) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": return x.Pagination != nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) } } @@ -1930,13 +1930,13 @@ func (x *fastReflection_QueryPendingUndelegationsRequest) Has(fd protoreflect.Fi // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingUndelegationsRequest) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": x.Pagination = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) } } @@ -1948,14 +1948,14 @@ func (x *fastReflection_QueryPendingUndelegationsRequest) Clear(fd protoreflect. // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_QueryPendingUndelegationsRequest) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": value := x.Pagination return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", descriptor.FullName())) } } @@ -1971,13 +1971,13 @@ func (x *fastReflection_QueryPendingUndelegationsRequest) Get(descriptor protore // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingUndelegationsRequest) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": x.Pagination = value.Message().Interface().(*v1beta1.PageRequest) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) } } @@ -1993,16 +1993,16 @@ func (x *fastReflection_QueryPendingUndelegationsRequest) Set(fd protoreflect.Fi // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingUndelegationsRequest) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": if x.Pagination == nil { x.Pagination = new(v1beta1.PageRequest) } return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) } } @@ -2011,14 +2011,14 @@ func (x *fastReflection_QueryPendingUndelegationsRequest) Mutable(fd protoreflec // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_QueryPendingUndelegationsRequest) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination": m := new(v1beta1.PageRequest) return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest does not contain field %s", fd.FullName())) } } @@ -2028,7 +2028,7 @@ func (x *fastReflection_QueryPendingUndelegationsRequest) NewField(fd protorefle func (x *fastReflection_QueryPendingUndelegationsRequest) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest", d.FullName())) } panic("unreachable") } @@ -2308,8 +2308,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_query_proto_init() - md_QueryPendingUndelegationsResponse = File_cosmos_evm_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingUndelegationsResponse") + file_cosmos_poolrebalancer_v1_query_proto_init() + md_QueryPendingUndelegationsResponse = File_cosmos_poolrebalancer_v1_query_proto.Messages().ByName("QueryPendingUndelegationsResponse") fd_QueryPendingUndelegationsResponse_undelegations = md_QueryPendingUndelegationsResponse.Fields().ByName("undelegations") fd_QueryPendingUndelegationsResponse_pagination = md_QueryPendingUndelegationsResponse.Fields().ByName("pagination") } @@ -2323,7 +2323,7 @@ func (x *QueryPendingUndelegationsResponse) ProtoReflect() protoreflect.Message } func (x *QueryPendingUndelegationsResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[5] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2406,15 +2406,15 @@ func (x *fastReflection_QueryPendingUndelegationsResponse) Range(f func(protoref // a repeated field is populated if it is non-empty. func (x *fastReflection_QueryPendingUndelegationsResponse) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": return len(x.Undelegations) != 0 - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": return x.Pagination != nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) } } @@ -2426,15 +2426,15 @@ func (x *fastReflection_QueryPendingUndelegationsResponse) Has(fd protoreflect.F // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingUndelegationsResponse) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": x.Undelegations = nil - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": x.Pagination = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) } } @@ -2446,20 +2446,20 @@ func (x *fastReflection_QueryPendingUndelegationsResponse) Clear(fd protoreflect // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_QueryPendingUndelegationsResponse) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": if len(x.Undelegations) == 0 { return protoreflect.ValueOfList(&_QueryPendingUndelegationsResponse_1_list{}) } listValue := &_QueryPendingUndelegationsResponse_1_list{list: &x.Undelegations} return protoreflect.ValueOfList(listValue) - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": value := x.Pagination return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", descriptor.FullName())) } } @@ -2475,17 +2475,17 @@ func (x *fastReflection_QueryPendingUndelegationsResponse) Get(descriptor protor // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingUndelegationsResponse) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": lv := value.List() clv := lv.(*_QueryPendingUndelegationsResponse_1_list) x.Undelegations = *clv.list - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": x.Pagination = value.Message().Interface().(*v1beta1.PageResponse) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) } } @@ -2501,22 +2501,22 @@ func (x *fastReflection_QueryPendingUndelegationsResponse) Set(fd protoreflect.F // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_QueryPendingUndelegationsResponse) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": if x.Undelegations == nil { x.Undelegations = []*PendingUndelegation{} } value := &_QueryPendingUndelegationsResponse_1_list{list: &x.Undelegations} return protoreflect.ValueOfList(value) - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": if x.Pagination == nil { x.Pagination = new(v1beta1.PageResponse) } return protoreflect.ValueOfMessage(x.Pagination.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) } } @@ -2525,17 +2525,17 @@ func (x *fastReflection_QueryPendingUndelegationsResponse) Mutable(fd protorefle // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_QueryPendingUndelegationsResponse) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations": list := []*PendingUndelegation{} return protoreflect.ValueOfList(&_QueryPendingUndelegationsResponse_1_list{list: &list}) - case "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": + case "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination": m := new(v1beta1.PageResponse) return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse does not contain field %s", fd.FullName())) } } @@ -2545,7 +2545,7 @@ func (x *fastReflection_QueryPendingUndelegationsResponse) NewField(fd protorefl func (x *fastReflection_QueryPendingUndelegationsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse", d.FullName())) } panic("unreachable") } @@ -2827,7 +2827,7 @@ func (x *fastReflection_QueryPendingUndelegationsResponse) ProtoMethods() *proto // versions: // protoc-gen-go v1.27.0 // protoc (unknown) -// source: cosmos/evm/poolrebalancer/v1/query.proto +// source: cosmos/poolrebalancer/v1/query.proto const ( // Verify that this generated code is sufficiently up-to-date. @@ -2846,7 +2846,7 @@ type QueryParamsRequest struct { func (x *QueryParamsRequest) Reset() { *x = QueryParamsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[0] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2860,7 +2860,7 @@ func (*QueryParamsRequest) ProtoMessage() {} // Deprecated: Use QueryParamsRequest.ProtoReflect.Descriptor instead. func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{0} + return file_cosmos_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{0} } // QueryParamsResponse is the response type for the Query/Params RPC method. @@ -2875,7 +2875,7 @@ type QueryParamsResponse struct { func (x *QueryParamsResponse) Reset() { *x = QueryParamsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[1] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2889,7 +2889,7 @@ func (*QueryParamsResponse) ProtoMessage() {} // Deprecated: Use QueryParamsResponse.ProtoReflect.Descriptor instead. func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{1} + return file_cosmos_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{1} } func (x *QueryParamsResponse) GetParams() *Params { @@ -2912,7 +2912,7 @@ type QueryPendingRedelegationsRequest struct { func (x *QueryPendingRedelegationsRequest) Reset() { *x = QueryPendingRedelegationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[2] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2926,7 +2926,7 @@ func (*QueryPendingRedelegationsRequest) ProtoMessage() {} // Deprecated: Use QueryPendingRedelegationsRequest.ProtoReflect.Descriptor instead. func (*QueryPendingRedelegationsRequest) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{2} + return file_cosmos_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{2} } func (x *QueryPendingRedelegationsRequest) GetPagination() *v1beta1.PageRequest { @@ -2949,7 +2949,7 @@ type QueryPendingRedelegationsResponse struct { func (x *QueryPendingRedelegationsResponse) Reset() { *x = QueryPendingRedelegationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[3] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2963,7 +2963,7 @@ func (*QueryPendingRedelegationsResponse) ProtoMessage() {} // Deprecated: Use QueryPendingRedelegationsResponse.ProtoReflect.Descriptor instead. func (*QueryPendingRedelegationsResponse) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{3} + return file_cosmos_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{3} } func (x *QueryPendingRedelegationsResponse) GetRedelegations() []*PendingRedelegation { @@ -2993,7 +2993,7 @@ type QueryPendingUndelegationsRequest struct { func (x *QueryPendingUndelegationsRequest) Reset() { *x = QueryPendingUndelegationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[4] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3007,7 +3007,7 @@ func (*QueryPendingUndelegationsRequest) ProtoMessage() {} // Deprecated: Use QueryPendingUndelegationsRequest.ProtoReflect.Descriptor instead. func (*QueryPendingUndelegationsRequest) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{4} + return file_cosmos_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{4} } func (x *QueryPendingUndelegationsRequest) GetPagination() *v1beta1.PageRequest { @@ -3030,7 +3030,7 @@ type QueryPendingUndelegationsResponse struct { func (x *QueryPendingUndelegationsResponse) Reset() { *x = QueryPendingUndelegationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[5] + mi := &file_cosmos_poolrebalancer_v1_query_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3044,7 +3044,7 @@ func (*QueryPendingUndelegationsResponse) ProtoMessage() {} // Deprecated: Use QueryPendingUndelegationsResponse.ProtoReflect.Descriptor instead. func (*QueryPendingUndelegationsResponse) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{5} + return file_cosmos_poolrebalancer_v1_query_proto_rawDescGZIP(), []int{5} } func (x *QueryPendingUndelegationsResponse) GetUndelegations() []*PendingUndelegation { @@ -3061,29 +3061,28 @@ func (x *QueryPendingUndelegationsResponse) GetPagination() *v1beta1.PageRespons return nil } -var File_cosmos_evm_poolrebalancer_v1_query_proto protoreflect.FileDescriptor - -var file_cosmos_evm_poolrebalancer_v1_query_proto_rawDesc = []byte{ - 0x0a, 0x28, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, - 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, - 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, - 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x14, - 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x22, 0x5e, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x06, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, +var File_cosmos_poolrebalancer_v1_query_proto protoreflect.FileDescriptor + +var file_cosmos_poolrebalancer_v1_query_proto_rawDesc = []byte{ + 0x0a, 0x24, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, + 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, + 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, + 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x2d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, + 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, + 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x14, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x5a, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x43, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x20, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x6a, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, @@ -3093,136 +3092,132 @@ var file_cosmos_evm_poolrebalancer_v1_query_proto_rawDesc = []byte{ 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0xd0, 0x01, 0x0a, 0x21, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, + 0x22, 0xcc, 0x01, 0x0a, 0x21, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0d, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, - 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, - 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0d, 0x72, 0x65, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, - 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, - 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0x6a, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0xd0, 0x01, 0x0a, 0x21, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0d, 0x75, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, - 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0d, 0x75, 0x6e, 0x64, 0x65, - 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x32, 0xd3, 0x04, 0x0a, 0x05, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x9b, 0x01, 0x0a, - 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x30, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x0d, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, 0xde, + 0x1f, 0x00, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x0d, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x6a, 0x0a, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, + 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, + 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xcc, 0x01, 0x0a, 0x21, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x5e, 0x0a, 0x0d, 0x75, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, + 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, + 0x2a, 0x01, 0x52, 0x0d, 0x75, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xaf, 0x04, 0x0a, 0x05, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x8f, 0x01, 0x0a, 0x06, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, + 0x2c, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, - 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, - 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0xd4, 0x01, 0x0a, 0x14, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x3e, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, - 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x3f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, - 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, - 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x12, 0x33, 0x2f, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, + 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0xc8, 0x01, 0x0a, 0x14, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x3a, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, + 0x12, 0x2f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0xd4, 0x01, 0x0a, 0x14, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, - 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3e, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3f, 0x2e, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x35, 0x12, 0x33, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, - 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, - 0x76, 0x31, 0x2f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x6e, 0x64, 0x65, 0x6c, - 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x85, 0x02, 0x0a, 0x20, 0x63, 0x6f, 0x6d, - 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, + 0x73, 0x12, 0xc8, 0x01, 0x0a, 0x14, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x64, + 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3a, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x55, 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x6e, + 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x37, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x31, 0x12, 0x2f, 0x2f, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, + 0x6e, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0xec, 0x01, 0x0a, + 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, 0x0a, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x63, 0x6f, 0x73, + 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 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, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x6f, 0x6f, 0x6c, 0x72, - 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x45, - 0x50, 0xaa, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x2e, 0x50, - 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x56, 0x31, - 0xca, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, - 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, - 0x02, 0x28, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x50, 0x58, 0xaa, 0x02, 0x18, + 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x43, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x5c, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, + 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x24, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0xc8, 0xe1, 0x1e, 0x00, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0xc8, 0xe1, 0x1e, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( - file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescOnce sync.Once - file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescData = file_cosmos_evm_poolrebalancer_v1_query_proto_rawDesc + file_cosmos_poolrebalancer_v1_query_proto_rawDescOnce sync.Once + file_cosmos_poolrebalancer_v1_query_proto_rawDescData = file_cosmos_poolrebalancer_v1_query_proto_rawDesc ) -func file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescGZIP() []byte { - file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescOnce.Do(func() { - file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescData) +func file_cosmos_poolrebalancer_v1_query_proto_rawDescGZIP() []byte { + file_cosmos_poolrebalancer_v1_query_proto_rawDescOnce.Do(func() { + file_cosmos_poolrebalancer_v1_query_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_poolrebalancer_v1_query_proto_rawDescData) }) - return file_cosmos_evm_poolrebalancer_v1_query_proto_rawDescData -} - -var file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 6) -var file_cosmos_evm_poolrebalancer_v1_query_proto_goTypes = []interface{}{ - (*QueryParamsRequest)(nil), // 0: cosmos.evm.poolrebalancer.v1.QueryParamsRequest - (*QueryParamsResponse)(nil), // 1: cosmos.evm.poolrebalancer.v1.QueryParamsResponse - (*QueryPendingRedelegationsRequest)(nil), // 2: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest - (*QueryPendingRedelegationsResponse)(nil), // 3: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse - (*QueryPendingUndelegationsRequest)(nil), // 4: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest - (*QueryPendingUndelegationsResponse)(nil), // 5: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse - (*Params)(nil), // 6: cosmos.evm.poolrebalancer.v1.Params + return file_cosmos_poolrebalancer_v1_query_proto_rawDescData +} + +var file_cosmos_poolrebalancer_v1_query_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_cosmos_poolrebalancer_v1_query_proto_goTypes = []interface{}{ + (*QueryParamsRequest)(nil), // 0: cosmos.poolrebalancer.v1.QueryParamsRequest + (*QueryParamsResponse)(nil), // 1: cosmos.poolrebalancer.v1.QueryParamsResponse + (*QueryPendingRedelegationsRequest)(nil), // 2: cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest + (*QueryPendingRedelegationsResponse)(nil), // 3: cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse + (*QueryPendingUndelegationsRequest)(nil), // 4: cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest + (*QueryPendingUndelegationsResponse)(nil), // 5: cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse + (*Params)(nil), // 6: cosmos.poolrebalancer.v1.Params (*v1beta1.PageRequest)(nil), // 7: cosmos.base.query.v1beta1.PageRequest - (*PendingRedelegation)(nil), // 8: cosmos.evm.poolrebalancer.v1.PendingRedelegation + (*PendingRedelegation)(nil), // 8: cosmos.poolrebalancer.v1.PendingRedelegation (*v1beta1.PageResponse)(nil), // 9: cosmos.base.query.v1beta1.PageResponse - (*PendingUndelegation)(nil), // 10: cosmos.evm.poolrebalancer.v1.PendingUndelegation -} -var file_cosmos_evm_poolrebalancer_v1_query_proto_depIdxs = []int32{ - 6, // 0: cosmos.evm.poolrebalancer.v1.QueryParamsResponse.params:type_name -> cosmos.evm.poolrebalancer.v1.Params - 7, // 1: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest - 8, // 2: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations:type_name -> cosmos.evm.poolrebalancer.v1.PendingRedelegation - 9, // 3: cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 7, // 4: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest - 10, // 5: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations:type_name -> cosmos.evm.poolrebalancer.v1.PendingUndelegation - 9, // 6: cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse - 0, // 7: cosmos.evm.poolrebalancer.v1.Query.Params:input_type -> cosmos.evm.poolrebalancer.v1.QueryParamsRequest - 2, // 8: cosmos.evm.poolrebalancer.v1.Query.PendingRedelegations:input_type -> cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest - 4, // 9: cosmos.evm.poolrebalancer.v1.Query.PendingUndelegations:input_type -> cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest - 1, // 10: cosmos.evm.poolrebalancer.v1.Query.Params:output_type -> cosmos.evm.poolrebalancer.v1.QueryParamsResponse - 3, // 11: cosmos.evm.poolrebalancer.v1.Query.PendingRedelegations:output_type -> cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse - 5, // 12: cosmos.evm.poolrebalancer.v1.Query.PendingUndelegations:output_type -> cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse + (*PendingUndelegation)(nil), // 10: cosmos.poolrebalancer.v1.PendingUndelegation +} +var file_cosmos_poolrebalancer_v1_query_proto_depIdxs = []int32{ + 6, // 0: cosmos.poolrebalancer.v1.QueryParamsResponse.params:type_name -> cosmos.poolrebalancer.v1.Params + 7, // 1: cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 8, // 2: cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.redelegations:type_name -> cosmos.poolrebalancer.v1.PendingRedelegation + 9, // 3: cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 7, // 4: cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest.pagination:type_name -> cosmos.base.query.v1beta1.PageRequest + 10, // 5: cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.undelegations:type_name -> cosmos.poolrebalancer.v1.PendingUndelegation + 9, // 6: cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse.pagination:type_name -> cosmos.base.query.v1beta1.PageResponse + 0, // 7: cosmos.poolrebalancer.v1.Query.Params:input_type -> cosmos.poolrebalancer.v1.QueryParamsRequest + 2, // 8: cosmos.poolrebalancer.v1.Query.PendingRedelegations:input_type -> cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest + 4, // 9: cosmos.poolrebalancer.v1.Query.PendingUndelegations:input_type -> cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest + 1, // 10: cosmos.poolrebalancer.v1.Query.Params:output_type -> cosmos.poolrebalancer.v1.QueryParamsResponse + 3, // 11: cosmos.poolrebalancer.v1.Query.PendingRedelegations:output_type -> cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse + 5, // 12: cosmos.poolrebalancer.v1.Query.PendingUndelegations:output_type -> cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse 10, // [10:13] is the sub-list for method output_type 7, // [7:10] is the sub-list for method input_type 7, // [7:7] is the sub-list for extension type_name @@ -3230,14 +3225,14 @@ var file_cosmos_evm_poolrebalancer_v1_query_proto_depIdxs = []int32{ 0, // [0:7] is the sub-list for field type_name } -func init() { file_cosmos_evm_poolrebalancer_v1_query_proto_init() } -func file_cosmos_evm_poolrebalancer_v1_query_proto_init() { - if File_cosmos_evm_poolrebalancer_v1_query_proto != nil { +func init() { file_cosmos_poolrebalancer_v1_query_proto_init() } +func file_cosmos_poolrebalancer_v1_query_proto_init() { + if File_cosmos_poolrebalancer_v1_query_proto != nil { return } - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() if !protoimpl.UnsafeEnabled { - file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_query_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryParamsRequest); i { case 0: return &v.state @@ -3249,7 +3244,7 @@ func file_cosmos_evm_poolrebalancer_v1_query_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_query_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryParamsResponse); i { case 0: return &v.state @@ -3261,7 +3256,7 @@ func file_cosmos_evm_poolrebalancer_v1_query_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_query_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryPendingRedelegationsRequest); i { case 0: return &v.state @@ -3273,7 +3268,7 @@ func file_cosmos_evm_poolrebalancer_v1_query_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_query_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryPendingRedelegationsResponse); i { case 0: return &v.state @@ -3285,7 +3280,7 @@ func file_cosmos_evm_poolrebalancer_v1_query_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_query_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryPendingUndelegationsRequest); i { case 0: return &v.state @@ -3297,7 +3292,7 @@ func file_cosmos_evm_poolrebalancer_v1_query_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_query_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*QueryPendingUndelegationsResponse); i { case 0: return &v.state @@ -3314,18 +3309,18 @@ func file_cosmos_evm_poolrebalancer_v1_query_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cosmos_evm_poolrebalancer_v1_query_proto_rawDesc, + RawDescriptor: file_cosmos_poolrebalancer_v1_query_proto_rawDesc, NumEnums: 0, NumMessages: 6, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_cosmos_evm_poolrebalancer_v1_query_proto_goTypes, - DependencyIndexes: file_cosmos_evm_poolrebalancer_v1_query_proto_depIdxs, - MessageInfos: file_cosmos_evm_poolrebalancer_v1_query_proto_msgTypes, + GoTypes: file_cosmos_poolrebalancer_v1_query_proto_goTypes, + DependencyIndexes: file_cosmos_poolrebalancer_v1_query_proto_depIdxs, + MessageInfos: file_cosmos_poolrebalancer_v1_query_proto_msgTypes, }.Build() - File_cosmos_evm_poolrebalancer_v1_query_proto = out.File - file_cosmos_evm_poolrebalancer_v1_query_proto_rawDesc = nil - file_cosmos_evm_poolrebalancer_v1_query_proto_goTypes = nil - file_cosmos_evm_poolrebalancer_v1_query_proto_depIdxs = nil + File_cosmos_poolrebalancer_v1_query_proto = out.File + file_cosmos_poolrebalancer_v1_query_proto_rawDesc = nil + file_cosmos_poolrebalancer_v1_query_proto_goTypes = nil + file_cosmos_poolrebalancer_v1_query_proto_depIdxs = nil } diff --git a/api/cosmos/evm/poolrebalancer/v1/query_grpc.pb.go b/api/cosmos/poolrebalancer/v1/query_grpc.pb.go similarity index 93% rename from api/cosmos/evm/poolrebalancer/v1/query_grpc.pb.go rename to api/cosmos/poolrebalancer/v1/query_grpc.pb.go index 477d55d5..9d8f44fe 100644 --- a/api/cosmos/evm/poolrebalancer/v1/query_grpc.pb.go +++ b/api/cosmos/poolrebalancer/v1/query_grpc.pb.go @@ -2,7 +2,7 @@ // versions: // - protoc-gen-go-grpc v1.3.0 // - protoc (unknown) -// source: cosmos/evm/poolrebalancer/v1/query.proto +// source: cosmos/poolrebalancer/v1/query.proto package poolrebalancerv1 @@ -19,9 +19,9 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - Query_Params_FullMethodName = "/cosmos.evm.poolrebalancer.v1.Query/Params" - Query_PendingRedelegations_FullMethodName = "/cosmos.evm.poolrebalancer.v1.Query/PendingRedelegations" - Query_PendingUndelegations_FullMethodName = "/cosmos.evm.poolrebalancer.v1.Query/PendingUndelegations" + Query_Params_FullMethodName = "/cosmos.poolrebalancer.v1.Query/Params" + Query_PendingRedelegations_FullMethodName = "/cosmos.poolrebalancer.v1.Query/PendingRedelegations" + Query_PendingUndelegations_FullMethodName = "/cosmos.poolrebalancer.v1.Query/PendingUndelegations" ) // QueryClient is the client API for Query service. @@ -168,7 +168,7 @@ func _Query_PendingUndelegations_Handler(srv interface{}, ctx context.Context, d // 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.evm.poolrebalancer.v1.Query", + ServiceName: "cosmos.poolrebalancer.v1.Query", HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ { @@ -185,5 +185,5 @@ var Query_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "cosmos/evm/poolrebalancer/v1/query.proto", + Metadata: "cosmos/poolrebalancer/v1/query.proto", } diff --git a/api/cosmos/evm/poolrebalancer/v1/tx.pulsar.go b/api/cosmos/poolrebalancer/v1/tx.pulsar.go similarity index 76% rename from api/cosmos/evm/poolrebalancer/v1/tx.pulsar.go rename to api/cosmos/poolrebalancer/v1/tx.pulsar.go index 027d29a5..b2065bdd 100644 --- a/api/cosmos/evm/poolrebalancer/v1/tx.pulsar.go +++ b/api/cosmos/poolrebalancer/v1/tx.pulsar.go @@ -23,8 +23,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_tx_proto_init() - md_MsgUpdateParams = File_cosmos_evm_poolrebalancer_v1_tx_proto.Messages().ByName("MsgUpdateParams") + file_cosmos_poolrebalancer_v1_tx_proto_init() + md_MsgUpdateParams = File_cosmos_poolrebalancer_v1_tx_proto.Messages().ByName("MsgUpdateParams") fd_MsgUpdateParams_authority = md_MsgUpdateParams.Fields().ByName("authority") fd_MsgUpdateParams_params = md_MsgUpdateParams.Fields().ByName("params") } @@ -38,7 +38,7 @@ func (x *MsgUpdateParams) ProtoReflect() protoreflect.Message { } func (x *MsgUpdateParams) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[0] + mi := &file_cosmos_poolrebalancer_v1_tx_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -121,15 +121,15 @@ func (x *fastReflection_MsgUpdateParams) Range(f func(protoreflect.FieldDescript // a repeated field is populated if it is non-empty. func (x *fastReflection_MsgUpdateParams) Has(fd protoreflect.FieldDescriptor) bool { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.authority": return x.Authority != "" - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.params": return x.Params != nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParams")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) } } @@ -141,15 +141,15 @@ func (x *fastReflection_MsgUpdateParams) Has(fd protoreflect.FieldDescriptor) bo // Clear is a mutating operation and unsafe for concurrent use. func (x *fastReflection_MsgUpdateParams) Clear(fd protoreflect.FieldDescriptor) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.authority": x.Authority = "" - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.params": x.Params = nil default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParams")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) } } @@ -161,17 +161,17 @@ func (x *fastReflection_MsgUpdateParams) Clear(fd protoreflect.FieldDescriptor) // of the value; to obtain a mutable reference, use Mutable. func (x *fastReflection_MsgUpdateParams) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { switch descriptor.FullName() { - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.authority": value := x.Authority return protoreflect.ValueOfString(value) - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.params": value := x.Params return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParams")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParams does not contain field %s", descriptor.FullName())) } } @@ -187,15 +187,15 @@ func (x *fastReflection_MsgUpdateParams) Get(descriptor protoreflect.FieldDescri // Set is a mutating operation and unsafe for concurrent use. func (x *fastReflection_MsgUpdateParams) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.authority": x.Authority = value.Interface().(string) - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.params": x.Params = value.Message().Interface().(*Params) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParams")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) } } @@ -211,18 +211,18 @@ func (x *fastReflection_MsgUpdateParams) Set(fd protoreflect.FieldDescriptor, va // Mutable is a mutating operation and unsafe for concurrent use. func (x *fastReflection_MsgUpdateParams) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.params": if x.Params == nil { x.Params = new(Params) } return protoreflect.ValueOfMessage(x.Params.ProtoReflect()) - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": - panic(fmt.Errorf("field authority of message cosmos.evm.poolrebalancer.v1.MsgUpdateParams is not mutable")) + case "cosmos.poolrebalancer.v1.MsgUpdateParams.authority": + panic(fmt.Errorf("field authority of message cosmos.poolrebalancer.v1.MsgUpdateParams is not mutable")) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParams")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) } } @@ -231,16 +231,16 @@ func (x *fastReflection_MsgUpdateParams) Mutable(fd protoreflect.FieldDescriptor // For lists, maps, and messages, this returns a new, empty, mutable value. func (x *fastReflection_MsgUpdateParams) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { switch fd.FullName() { - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.authority": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.authority": return protoreflect.ValueOfString("") - case "cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params": + case "cosmos.poolrebalancer.v1.MsgUpdateParams.params": m := new(Params) return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParams")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParams")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParams does not contain field %s", fd.FullName())) } } @@ -250,7 +250,7 @@ func (x *fastReflection_MsgUpdateParams) NewField(fd protoreflect.FieldDescripto func (x *fastReflection_MsgUpdateParams) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.MsgUpdateParams", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.MsgUpdateParams", d.FullName())) } panic("unreachable") } @@ -520,8 +520,8 @@ var ( ) func init() { - file_cosmos_evm_poolrebalancer_v1_tx_proto_init() - md_MsgUpdateParamsResponse = File_cosmos_evm_poolrebalancer_v1_tx_proto.Messages().ByName("MsgUpdateParamsResponse") + file_cosmos_poolrebalancer_v1_tx_proto_init() + md_MsgUpdateParamsResponse = File_cosmos_poolrebalancer_v1_tx_proto.Messages().ByName("MsgUpdateParamsResponse") } var _ protoreflect.Message = (*fastReflection_MsgUpdateParamsResponse)(nil) @@ -533,7 +533,7 @@ func (x *MsgUpdateParamsResponse) ProtoReflect() protoreflect.Message { } func (x *MsgUpdateParamsResponse) slowProtoReflect() protoreflect.Message { - mi := &file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[1] + mi := &file_cosmos_poolrebalancer_v1_tx_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -606,9 +606,9 @@ func (x *fastReflection_MsgUpdateParamsResponse) Has(fd protoreflect.FieldDescri switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) } } @@ -622,9 +622,9 @@ func (x *fastReflection_MsgUpdateParamsResponse) Clear(fd protoreflect.FieldDesc switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) } } @@ -638,9 +638,9 @@ func (x *fastReflection_MsgUpdateParamsResponse) Get(descriptor protoreflect.Fie switch descriptor.FullName() { default: if descriptor.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", descriptor.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", descriptor.FullName())) } } @@ -658,9 +658,9 @@ func (x *fastReflection_MsgUpdateParamsResponse) Set(fd protoreflect.FieldDescri switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) } } @@ -678,9 +678,9 @@ func (x *fastReflection_MsgUpdateParamsResponse) Mutable(fd protoreflect.FieldDe switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) } } @@ -691,9 +691,9 @@ func (x *fastReflection_MsgUpdateParamsResponse) NewField(fd protoreflect.FieldD switch fd.FullName() { default: if fd.IsExtension() { - panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse")) + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.poolrebalancer.v1.MsgUpdateParamsResponse")) } - panic(fmt.Errorf("message cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) + panic(fmt.Errorf("message cosmos.poolrebalancer.v1.MsgUpdateParamsResponse does not contain field %s", fd.FullName())) } } @@ -703,7 +703,7 @@ func (x *fastReflection_MsgUpdateParamsResponse) NewField(fd protoreflect.FieldD func (x *fastReflection_MsgUpdateParamsResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { switch d.FullName() { default: - panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse", d.FullName())) + panic(fmt.Errorf("%s is not a oneof field in cosmos.poolrebalancer.v1.MsgUpdateParamsResponse", d.FullName())) } panic("unreachable") } @@ -875,7 +875,7 @@ func (x *fastReflection_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Meth // versions: // protoc-gen-go v1.27.0 // protoc (unknown) -// source: cosmos/evm/poolrebalancer/v1/tx.proto +// source: cosmos/poolrebalancer/v1/tx.proto const ( // Verify that this generated code is sufficiently up-to-date. @@ -900,7 +900,7 @@ type MsgUpdateParams struct { func (x *MsgUpdateParams) Reset() { *x = MsgUpdateParams{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[0] + mi := &file_cosmos_poolrebalancer_v1_tx_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -914,7 +914,7 @@ func (*MsgUpdateParams) ProtoMessage() {} // Deprecated: Use MsgUpdateParams.ProtoReflect.Descriptor instead. func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescGZIP(), []int{0} + return file_cosmos_poolrebalancer_v1_tx_proto_rawDescGZIP(), []int{0} } func (x *MsgUpdateParams) GetAuthority() string { @@ -941,7 +941,7 @@ type MsgUpdateParamsResponse struct { func (x *MsgUpdateParamsResponse) Reset() { *x = MsgUpdateParamsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[1] + mi := &file_cosmos_poolrebalancer_v1_tx_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -955,90 +955,86 @@ func (*MsgUpdateParamsResponse) ProtoMessage() {} // Deprecated: Use MsgUpdateParamsResponse.ProtoReflect.Descriptor instead. func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescGZIP(), []int{1} + return file_cosmos_poolrebalancer_v1_tx_proto_rawDescGZIP(), []int{1} } -var File_cosmos_evm_poolrebalancer_v1_tx_proto protoreflect.FileDescriptor - -var file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDesc = []byte{ - 0x0a, 0x25, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, - 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x74, - 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, - 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, - 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x31, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, 0x73, 0x67, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x67, 0x6f, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd2, 0x01, 0x0a, 0x0f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, 0x09, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, - 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x12, 0x47, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, +var File_cosmos_poolrebalancer_v1_tx_proto protoreflect.FileDescriptor + +var file_cosmos_poolrebalancer_v1_tx_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x78, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, + 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x1a, 0x11, 0x61, + 0x6d, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x6d, 0x69, 0x6e, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x2d, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, + 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x17, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x6d, 0x73, 0x67, 0x2f, 0x76, 0x31, 0x2f, 0x6d, + 0x73, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x67, 0x6f, 0x67, 0x6f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, + 0x6f, 0x67, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xcb, 0x01, 0x0a, 0x0f, 0x4d, 0x73, + 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x36, 0x0a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x42, 0x09, 0xc8, 0xde, 0x1f, 0x00, 0xa8, 0xe7, 0xb0, - 0x2a, 0x01, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x3e, 0x82, 0xe7, 0xb0, 0x2a, - 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x8a, 0xe7, 0xb0, 0x2a, 0x2b, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, - 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x4d, 0x73, 0x67, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, - 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x82, 0x01, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x74, 0x0a, - 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x2d, 0x2e, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, - 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x35, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xfe, 0x01, 0x0a, 0x20, 0x63, - 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x70, 0x6f, + 0x2a, 0x01, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x3b, 0x82, 0xe7, 0xb0, 0x2a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x8a, 0xe7, 0xb0, 0x2a, 0x28, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x4d, 0x73, 0x67, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x32, 0x7a, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x6c, 0x0a, 0x0c, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x31, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, + 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xe5, + 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x76, 0x31, 0x42, - 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3e, 0x63, 0x6f, 0x73, 0x6d, + 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 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, 0x76, 0x6d, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, - 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x45, 0x50, - 0xaa, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x2e, 0x50, 0x6f, - 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, - 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, 0x6f, - 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0xe2, 0x02, - 0x28, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x50, 0x6f, 0x6f, 0x6c, + 0x6d, 0x6f, 0x73, 0x2f, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x72, 0x2f, 0x76, 0x31, 0x3b, 0x70, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x72, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x50, 0x58, 0xaa, 0x02, 0x18, 0x43, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, + 0x6e, 0x63, 0x65, 0x72, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x18, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x5c, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, + 0x56, 0x31, 0xe2, 0x02, 0x24, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1f, 0x43, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, - 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1a, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x3a, 0x3a, 0x50, 0x6f, 0x6f, 0x6c, 0x72, 0x65, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescOnce sync.Once - file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescData = file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDesc + file_cosmos_poolrebalancer_v1_tx_proto_rawDescOnce sync.Once + file_cosmos_poolrebalancer_v1_tx_proto_rawDescData = file_cosmos_poolrebalancer_v1_tx_proto_rawDesc ) -func file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescGZIP() []byte { - file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescOnce.Do(func() { - file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescData) +func file_cosmos_poolrebalancer_v1_tx_proto_rawDescGZIP() []byte { + file_cosmos_poolrebalancer_v1_tx_proto_rawDescOnce.Do(func() { + file_cosmos_poolrebalancer_v1_tx_proto_rawDescData = protoimpl.X.CompressGZIP(file_cosmos_poolrebalancer_v1_tx_proto_rawDescData) }) - return file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDescData + return file_cosmos_poolrebalancer_v1_tx_proto_rawDescData } -var file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_cosmos_evm_poolrebalancer_v1_tx_proto_goTypes = []interface{}{ - (*MsgUpdateParams)(nil), // 0: cosmos.evm.poolrebalancer.v1.MsgUpdateParams - (*MsgUpdateParamsResponse)(nil), // 1: cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse - (*Params)(nil), // 2: cosmos.evm.poolrebalancer.v1.Params +var file_cosmos_poolrebalancer_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cosmos_poolrebalancer_v1_tx_proto_goTypes = []interface{}{ + (*MsgUpdateParams)(nil), // 0: cosmos.poolrebalancer.v1.MsgUpdateParams + (*MsgUpdateParamsResponse)(nil), // 1: cosmos.poolrebalancer.v1.MsgUpdateParamsResponse + (*Params)(nil), // 2: cosmos.poolrebalancer.v1.Params } -var file_cosmos_evm_poolrebalancer_v1_tx_proto_depIdxs = []int32{ - 2, // 0: cosmos.evm.poolrebalancer.v1.MsgUpdateParams.params:type_name -> cosmos.evm.poolrebalancer.v1.Params - 0, // 1: cosmos.evm.poolrebalancer.v1.Msg.UpdateParams:input_type -> cosmos.evm.poolrebalancer.v1.MsgUpdateParams - 1, // 2: cosmos.evm.poolrebalancer.v1.Msg.UpdateParams:output_type -> cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse +var file_cosmos_poolrebalancer_v1_tx_proto_depIdxs = []int32{ + 2, // 0: cosmos.poolrebalancer.v1.MsgUpdateParams.params:type_name -> cosmos.poolrebalancer.v1.Params + 0, // 1: cosmos.poolrebalancer.v1.Msg.UpdateParams:input_type -> cosmos.poolrebalancer.v1.MsgUpdateParams + 1, // 2: cosmos.poolrebalancer.v1.Msg.UpdateParams:output_type -> cosmos.poolrebalancer.v1.MsgUpdateParamsResponse 2, // [2:3] is the sub-list for method output_type 1, // [1:2] is the sub-list for method input_type 1, // [1:1] is the sub-list for extension type_name @@ -1046,14 +1042,14 @@ var file_cosmos_evm_poolrebalancer_v1_tx_proto_depIdxs = []int32{ 0, // [0:1] is the sub-list for field type_name } -func init() { file_cosmos_evm_poolrebalancer_v1_tx_proto_init() } -func file_cosmos_evm_poolrebalancer_v1_tx_proto_init() { - if File_cosmos_evm_poolrebalancer_v1_tx_proto != nil { +func init() { file_cosmos_poolrebalancer_v1_tx_proto_init() } +func file_cosmos_poolrebalancer_v1_tx_proto_init() { + if File_cosmos_poolrebalancer_v1_tx_proto != nil { return } - file_cosmos_evm_poolrebalancer_v1_poolrebalancer_proto_init() + file_cosmos_poolrebalancer_v1_poolrebalancer_proto_init() if !protoimpl.UnsafeEnabled { - file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_tx_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MsgUpdateParams); i { case 0: return &v.state @@ -1065,7 +1061,7 @@ func file_cosmos_evm_poolrebalancer_v1_tx_proto_init() { return nil } } - file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_cosmos_poolrebalancer_v1_tx_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MsgUpdateParamsResponse); i { case 0: return &v.state @@ -1082,18 +1078,18 @@ func file_cosmos_evm_poolrebalancer_v1_tx_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDesc, + RawDescriptor: file_cosmos_poolrebalancer_v1_tx_proto_rawDesc, NumEnums: 0, NumMessages: 2, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_cosmos_evm_poolrebalancer_v1_tx_proto_goTypes, - DependencyIndexes: file_cosmos_evm_poolrebalancer_v1_tx_proto_depIdxs, - MessageInfos: file_cosmos_evm_poolrebalancer_v1_tx_proto_msgTypes, + GoTypes: file_cosmos_poolrebalancer_v1_tx_proto_goTypes, + DependencyIndexes: file_cosmos_poolrebalancer_v1_tx_proto_depIdxs, + MessageInfos: file_cosmos_poolrebalancer_v1_tx_proto_msgTypes, }.Build() - File_cosmos_evm_poolrebalancer_v1_tx_proto = out.File - file_cosmos_evm_poolrebalancer_v1_tx_proto_rawDesc = nil - file_cosmos_evm_poolrebalancer_v1_tx_proto_goTypes = nil - file_cosmos_evm_poolrebalancer_v1_tx_proto_depIdxs = nil + File_cosmos_poolrebalancer_v1_tx_proto = out.File + file_cosmos_poolrebalancer_v1_tx_proto_rawDesc = nil + file_cosmos_poolrebalancer_v1_tx_proto_goTypes = nil + file_cosmos_poolrebalancer_v1_tx_proto_depIdxs = nil } diff --git a/api/cosmos/evm/poolrebalancer/v1/tx_grpc.pb.go b/api/cosmos/poolrebalancer/v1/tx_grpc.pb.go similarity index 94% rename from api/cosmos/evm/poolrebalancer/v1/tx_grpc.pb.go rename to api/cosmos/poolrebalancer/v1/tx_grpc.pb.go index c705597d..3ec45d6f 100644 --- a/api/cosmos/evm/poolrebalancer/v1/tx_grpc.pb.go +++ b/api/cosmos/poolrebalancer/v1/tx_grpc.pb.go @@ -2,7 +2,7 @@ // versions: // - protoc-gen-go-grpc v1.3.0 // - protoc (unknown) -// source: cosmos/evm/poolrebalancer/v1/tx.proto +// source: cosmos/poolrebalancer/v1/tx.proto package poolrebalancerv1 @@ -19,7 +19,7 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - Msg_UpdateParams_FullMethodName = "/cosmos.evm.poolrebalancer.v1.Msg/UpdateParams" + Msg_UpdateParams_FullMethodName = "/cosmos.poolrebalancer.v1.Msg/UpdateParams" ) // MsgClient is the client API for Msg service. @@ -100,7 +100,7 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var Msg_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "cosmos.evm.poolrebalancer.v1.Msg", + ServiceName: "cosmos.poolrebalancer.v1.Msg", HandlerType: (*MsgServer)(nil), Methods: []grpc.MethodDesc{ { @@ -109,5 +109,5 @@ var Msg_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "cosmos/evm/poolrebalancer/v1/tx.proto", + Metadata: "cosmos/poolrebalancer/v1/tx.proto", } diff --git a/proto/cosmos/evm/poolrebalancer/v1/poolrebalancer.proto b/proto/cosmos/poolrebalancer/v1/poolrebalancer.proto similarity index 98% rename from proto/cosmos/evm/poolrebalancer/v1/poolrebalancer.proto rename to proto/cosmos/poolrebalancer/v1/poolrebalancer.proto index 7b1231ad..f81eea6d 100644 --- a/proto/cosmos/evm/poolrebalancer/v1/poolrebalancer.proto +++ b/proto/cosmos/poolrebalancer/v1/poolrebalancer.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -package cosmos.evm.poolrebalancer.v1; +package cosmos.poolrebalancer.v1; import "cosmos/base/v1beta1/coin.proto"; import "gogoproto/gogo.proto"; diff --git a/proto/cosmos/evm/poolrebalancer/v1/query.proto b/proto/cosmos/poolrebalancer/v1/query.proto similarity index 88% rename from proto/cosmos/evm/poolrebalancer/v1/query.proto rename to proto/cosmos/poolrebalancer/v1/query.proto index 7de90b3f..7253a66c 100644 --- a/proto/cosmos/evm/poolrebalancer/v1/query.proto +++ b/proto/cosmos/poolrebalancer/v1/query.proto @@ -1,9 +1,9 @@ syntax = "proto3"; -package cosmos.evm.poolrebalancer.v1; +package cosmos.poolrebalancer.v1; import "amino/amino.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; -import "cosmos/evm/poolrebalancer/v1/poolrebalancer.proto"; +import "cosmos/poolrebalancer/v1/poolrebalancer.proto"; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; @@ -14,21 +14,21 @@ option (gogoproto.goproto_getters_all) = false; service Query { // Params returns the poolrebalancer module params. rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { - option (google.api.http).get = "/cosmos/evm/poolrebalancer/v1/params"; + option (google.api.http).get = "/cosmos/poolrebalancer/v1/params"; } // PendingRedelegations returns tracked in-flight redelegations. rpc PendingRedelegations(QueryPendingRedelegationsRequest) returns (QueryPendingRedelegationsResponse) { option (google.api.http).get = - "/cosmos/evm/poolrebalancer/v1/pending_redelegations"; + "/cosmos/poolrebalancer/v1/pending_redelegations"; } // PendingUndelegations returns tracked in-flight undelegations. rpc PendingUndelegations(QueryPendingUndelegationsRequest) returns (QueryPendingUndelegationsResponse) { option (google.api.http).get = - "/cosmos/evm/poolrebalancer/v1/pending_undelegations"; + "/cosmos/poolrebalancer/v1/pending_undelegations"; } } diff --git a/proto/cosmos/evm/poolrebalancer/v1/tx.proto b/proto/cosmos/poolrebalancer/v1/tx.proto similarity index 87% rename from proto/cosmos/evm/poolrebalancer/v1/tx.proto rename to proto/cosmos/poolrebalancer/v1/tx.proto index 93b59ed4..df0eac25 100644 --- a/proto/cosmos/evm/poolrebalancer/v1/tx.proto +++ b/proto/cosmos/poolrebalancer/v1/tx.proto @@ -1,8 +1,8 @@ syntax = "proto3"; -package cosmos.evm.poolrebalancer.v1; +package cosmos.poolrebalancer.v1; import "amino/amino.proto"; -import "cosmos/evm/poolrebalancer/v1/poolrebalancer.proto"; +import "cosmos/poolrebalancer/v1/poolrebalancer.proto"; import "cosmos/msg/v1/msg.proto"; import "cosmos_proto/cosmos.proto"; import "gogoproto/gogo.proto"; @@ -21,7 +21,7 @@ service Msg { // MsgUpdateParams defines a Msg for updating the x/poolrebalancer module parameters. message MsgUpdateParams { option (cosmos.msg.v1.signer) = "authority"; - option (amino.name) = "cosmos/evm/x/poolrebalancer/MsgUpdateParams"; + option (amino.name) = "cosmos/poolrebalancer/v1/MsgUpdateParams"; // authority is the address of the governance account. string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; diff --git a/x/poolrebalancer/types/poolrebalancer.pb.go b/x/poolrebalancer/types/poolrebalancer.pb.go index 831b6a58..7fd032d2 100644 --- a/x/poolrebalancer/types/poolrebalancer.pb.go +++ b/x/poolrebalancer/types/poolrebalancer.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: cosmos/evm/poolrebalancer/v1/poolrebalancer.proto +// source: cosmos/poolrebalancer/v1/poolrebalancer.proto package types @@ -49,7 +49,7 @@ func (m *Params) Reset() { *m = Params{} } func (m *Params) String() string { return proto.CompactTextString(m) } func (*Params) ProtoMessage() {} func (*Params) Descriptor() ([]byte, []int) { - return fileDescriptor_c420feafe1f88946, []int{0} + return fileDescriptor_3fcdfba81f65d424, []int{0} } func (m *Params) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -91,7 +91,7 @@ func (m *PendingRedelegation) Reset() { *m = PendingRedelegation{} } func (m *PendingRedelegation) String() string { return proto.CompactTextString(m) } func (*PendingRedelegation) ProtoMessage() {} func (*PendingRedelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_c420feafe1f88946, []int{1} + return fileDescriptor_3fcdfba81f65d424, []int{1} } func (m *PendingRedelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -129,7 +129,7 @@ func (m *QueuedRedelegation) Reset() { *m = QueuedRedelegation{} } func (m *QueuedRedelegation) String() string { return proto.CompactTextString(m) } func (*QueuedRedelegation) ProtoMessage() {} func (*QueuedRedelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_c420feafe1f88946, []int{2} + return fileDescriptor_3fcdfba81f65d424, []int{2} } func (m *QueuedRedelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -170,7 +170,7 @@ func (m *PendingUndelegation) Reset() { *m = PendingUndelegation{} } func (m *PendingUndelegation) String() string { return proto.CompactTextString(m) } func (*PendingUndelegation) ProtoMessage() {} func (*PendingUndelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_c420feafe1f88946, []int{3} + return fileDescriptor_3fcdfba81f65d424, []int{3} } func (m *PendingUndelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -208,7 +208,7 @@ func (m *QueuedUndelegation) Reset() { *m = QueuedUndelegation{} } func (m *QueuedUndelegation) String() string { return proto.CompactTextString(m) } func (*QueuedUndelegation) ProtoMessage() {} func (*QueuedUndelegation) Descriptor() ([]byte, []int) { - return fileDescriptor_c420feafe1f88946, []int{4} + return fileDescriptor_3fcdfba81f65d424, []int{4} } func (m *QueuedUndelegation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -250,7 +250,7 @@ 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_c420feafe1f88946, []int{5} + return fileDescriptor_3fcdfba81f65d424, []int{5} } func (m *GenesisState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -280,64 +280,64 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo func init() { - proto.RegisterType((*Params)(nil), "cosmos.evm.poolrebalancer.v1.Params") - proto.RegisterType((*PendingRedelegation)(nil), "cosmos.evm.poolrebalancer.v1.PendingRedelegation") - proto.RegisterType((*QueuedRedelegation)(nil), "cosmos.evm.poolrebalancer.v1.QueuedRedelegation") - proto.RegisterType((*PendingUndelegation)(nil), "cosmos.evm.poolrebalancer.v1.PendingUndelegation") - proto.RegisterType((*QueuedUndelegation)(nil), "cosmos.evm.poolrebalancer.v1.QueuedUndelegation") - proto.RegisterType((*GenesisState)(nil), "cosmos.evm.poolrebalancer.v1.GenesisState") + proto.RegisterType((*Params)(nil), "cosmos.poolrebalancer.v1.Params") + proto.RegisterType((*PendingRedelegation)(nil), "cosmos.poolrebalancer.v1.PendingRedelegation") + proto.RegisterType((*QueuedRedelegation)(nil), "cosmos.poolrebalancer.v1.QueuedRedelegation") + proto.RegisterType((*PendingUndelegation)(nil), "cosmos.poolrebalancer.v1.PendingUndelegation") + proto.RegisterType((*QueuedUndelegation)(nil), "cosmos.poolrebalancer.v1.QueuedUndelegation") + proto.RegisterType((*GenesisState)(nil), "cosmos.poolrebalancer.v1.GenesisState") } func init() { - proto.RegisterFile("cosmos/evm/poolrebalancer/v1/poolrebalancer.proto", fileDescriptor_c420feafe1f88946) + proto.RegisterFile("cosmos/poolrebalancer/v1/poolrebalancer.proto", fileDescriptor_3fcdfba81f65d424) } -var fileDescriptor_c420feafe1f88946 = []byte{ - // 703 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x95, 0xcd, 0x6e, 0xd3, 0x4a, - 0x14, 0xc7, 0xe3, 0xa4, 0x37, 0xed, 0x9d, 0xf4, 0xf6, 0xc3, 0x4d, 0xee, 0xcd, 0xad, 0xc0, 0xa9, - 0x22, 0x16, 0x41, 0x45, 0xb6, 0x12, 0x10, 0x88, 0x25, 0xa1, 0x02, 0x81, 0x54, 0x35, 0x0d, 0x85, - 0x05, 0x1b, 0x6b, 0x6c, 0x9f, 0x3a, 0x56, 0x6d, 0xcf, 0x68, 0x66, 0x6c, 0x85, 0xb7, 0xe8, 0x93, - 0xb0, 0xe0, 0x29, 0xba, 0x2c, 0x3b, 0xc4, 0xa2, 0x40, 0xfb, 0x14, 0xec, 0xd0, 0xf8, 0xab, 0x69, - 0x9a, 0xf2, 0x55, 0x76, 0xce, 0xfc, 0xcf, 0x7f, 0x8e, 0xe7, 0x77, 0xfe, 0xf1, 0xa0, 0xae, 0x4d, - 0x78, 0x40, 0xb8, 0x01, 0x71, 0x60, 0x50, 0x42, 0x7c, 0x06, 0x16, 0xf6, 0x71, 0x68, 0x03, 0x33, - 0xe2, 0xee, 0xd4, 0x8a, 0x4e, 0x19, 0x11, 0x44, 0xbd, 0x91, 0x5a, 0x74, 0x88, 0x03, 0x7d, 0xaa, - 0x20, 0xee, 0xae, 0x6b, 0xd9, 0x86, 0x16, 0xe6, 0x60, 0xc4, 0x5d, 0x0b, 0x04, 0xee, 0x1a, 0x36, - 0xf1, 0xc2, 0xd4, 0xbd, 0x5e, 0x77, 0x89, 0x4b, 0x92, 0x47, 0x43, 0x3e, 0x65, 0xab, 0x2d, 0x97, - 0x10, 0xd7, 0x07, 0x23, 0xf9, 0x65, 0x45, 0xfb, 0x86, 0xf0, 0x02, 0xe0, 0x02, 0x07, 0x34, 0x2d, - 0x68, 0xbf, 0x2f, 0xa3, 0xea, 0x00, 0x33, 0x1c, 0x70, 0xf5, 0x1e, 0xfa, 0x57, 0xb6, 0x35, 0x1d, - 0xf0, 0xc1, 0xc5, 0x82, 0x30, 0x13, 0x3b, 0x0e, 0x03, 0xce, 0x9b, 0xca, 0x86, 0xd2, 0xf9, 0x7b, - 0x58, 0x97, 0xea, 0x56, 0x2e, 0x3e, 0x4a, 0x35, 0xb5, 0x87, 0x1a, 0x01, 0x1e, 0x9b, 0x02, 0x33, - 0x17, 0x84, 0x19, 0x63, 0xdf, 0x73, 0xa4, 0xcc, 0x9b, 0xe5, 0x0d, 0xa5, 0xf3, 0xcf, 0x70, 0x2d, - 0xc0, 0xe3, 0xbd, 0x44, 0x7b, 0x55, 0x48, 0xb2, 0x53, 0x71, 0x38, 0x53, 0x8c, 0x18, 0xf0, 0x11, - 0xf1, 0x1d, 0xd3, 0xa2, 0xcd, 0x4a, 0x62, 0xaa, 0x17, 0xea, 0x5e, 0x2e, 0xf6, 0xa9, 0x7a, 0x1b, - 0xad, 0xca, 0x4e, 0x84, 0x72, 0x93, 0x02, 0x33, 0x2d, 0x9f, 0xd8, 0x07, 0xcd, 0xb9, 0xc4, 0xb0, - 0x14, 0xe0, 0xf1, 0x0e, 0xe5, 0x03, 0x60, 0x7d, 0xb9, 0xaa, 0x6e, 0xa1, 0x65, 0x59, 0x1a, 0x90, - 0x18, 0x92, 0x5a, 0x42, 0x9b, 0x7f, 0xc9, 0x33, 0xf4, 0x6f, 0x1e, 0x9d, 0xb4, 0x4a, 0x1f, 0x4f, - 0x5a, 0x8d, 0x94, 0x26, 0x77, 0x0e, 0x74, 0x8f, 0x18, 0x01, 0x16, 0x23, 0xfd, 0x59, 0x28, 0x86, - 0x8b, 0x01, 0x1e, 0x6f, 0x93, 0x18, 0x06, 0xc0, 0x76, 0xa8, 0x7a, 0x1f, 0xfd, 0x17, 0x71, 0x30, - 0xa3, 0x30, 0x23, 0x02, 0xe6, 0x3e, 0xf6, 0x7d, 0x0b, 0xdb, 0x07, 0xcd, 0xea, 0x86, 0xd2, 0x59, - 0x18, 0x36, 0x22, 0x0e, 0x2f, 0x0b, 0xf5, 0x49, 0x26, 0xb6, 0xdf, 0x95, 0xd1, 0xda, 0x00, 0x42, - 0xc7, 0x0b, 0xdd, 0x21, 0x64, 0xaa, 0x47, 0x42, 0x75, 0x13, 0xad, 0x5e, 0xc5, 0x76, 0xc5, 0x99, - 0xc1, 0x95, 0x33, 0xfb, 0x1c, 0x68, 0x61, 0x28, 0x27, 0x86, 0x35, 0xce, 0xec, 0x82, 0xe8, 0x84, - 0xc7, 0xe1, 0x62, 0x86, 0xa7, 0x92, 0x7a, 0x1c, 0x2e, 0x2e, 0x79, 0x1e, 0xa0, 0x2a, 0x0e, 0x48, - 0x14, 0x8a, 0x04, 0x65, 0xad, 0xf7, 0xbf, 0x9e, 0xc5, 0x50, 0x06, 0x4d, 0xcf, 0x82, 0xa6, 0x3f, - 0x26, 0x5e, 0xd8, 0x9f, 0x93, 0xf0, 0x86, 0x59, 0xb9, 0xba, 0x8d, 0x96, 0x6d, 0x12, 0x50, 0x1f, - 0xe4, 0xd9, 0x4c, 0x99, 0xab, 0x84, 0x71, 0xad, 0xb7, 0xae, 0xa7, 0xa1, 0xd3, 0xf3, 0xd0, 0xe9, - 0x7b, 0x79, 0xe8, 0xfa, 0x0b, 0x72, 0x8b, 0xc3, 0x4f, 0x2d, 0x65, 0xb8, 0x74, 0x6e, 0x96, 0x72, - 0xdb, 0x45, 0xea, 0x6e, 0x04, 0x11, 0x38, 0x17, 0x90, 0xed, 0xa2, 0x79, 0x08, 0x05, 0xf3, 0x40, - 0x82, 0xaa, 0x74, 0x6a, 0xbd, 0xae, 0xfe, 0xbd, 0x7f, 0x89, 0x3e, 0x03, 0x7b, 0xf6, 0xda, 0xf9, - 0x3e, 0xed, 0xaf, 0x4a, 0x31, 0x9d, 0x62, 0x76, 0xbf, 0x3c, 0x9d, 0x4d, 0xb4, 0x7a, 0xd5, 0x64, - 0x56, 0xe2, 0x69, 0xc4, 0x0f, 0xd1, 0x7c, 0xf6, 0x8e, 0xc9, 0x20, 0x7e, 0x82, 0x71, 0x5e, 0x3f, - 0x0b, 0xf2, 0xdc, 0x9f, 0x80, 0x7c, 0xe1, 0xe4, 0xbf, 0x09, 0x79, 0x72, 0x8f, 0x69, 0xc8, 0x6f, - 0xcb, 0x68, 0xf1, 0x29, 0x84, 0xc0, 0x3d, 0xfe, 0x42, 0x60, 0x01, 0x6a, 0x1f, 0x55, 0x69, 0xf2, - 0x99, 0x49, 0x90, 0xd6, 0x7a, 0xb7, 0x7e, 0xd0, 0x22, 0xa9, 0xcd, 0x13, 0x97, 0x3a, 0x55, 0x1f, - 0x35, 0x68, 0xda, 0xda, 0x64, 0x13, 0x03, 0x96, 0xe0, 0xaf, 0x15, 0x8d, 0x3a, 0xbd, 0x2c, 0x5d, - 0xe8, 0x16, 0x85, 0x93, 0xdd, 0x2a, 0xd7, 0x63, 0x94, 0x77, 0x9b, 0x94, 0x78, 0xff, 0xf9, 0xd1, - 0x17, 0xad, 0x74, 0x74, 0xaa, 0x29, 0xc7, 0xa7, 0x9a, 0xf2, 0xf9, 0x54, 0x53, 0x0e, 0xcf, 0xb4, - 0xd2, 0xf1, 0x99, 0x56, 0xfa, 0x70, 0xa6, 0x95, 0x5e, 0xdf, 0x71, 0x3d, 0x31, 0x8a, 0x2c, 0xdd, - 0x26, 0x81, 0x31, 0x71, 0xb1, 0x8c, 0xa7, 0xaf, 0x16, 0xf1, 0x86, 0x02, 0xb7, 0xaa, 0x49, 0x26, - 0xee, 0x7e, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xe9, 0x28, 0xe3, 0x84, 0x06, 0x00, 0x00, +var fileDescriptor_3fcdfba81f65d424 = []byte{ + // 701 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x95, 0xcf, 0x6e, 0xd3, 0x4a, + 0x14, 0xc6, 0xe3, 0xa4, 0x37, 0xed, 0x9d, 0xf4, 0xf6, 0x8f, 0x9b, 0xdc, 0x9b, 0x5b, 0x09, 0x27, + 0xca, 0x2a, 0xa8, 0xd4, 0x56, 0x02, 0x02, 0xb1, 0x41, 0x22, 0x54, 0x20, 0x90, 0xaa, 0x86, 0x50, + 0x58, 0xb0, 0xb1, 0xc6, 0xf6, 0xa9, 0x63, 0xd5, 0xf6, 0x8c, 0x66, 0xc6, 0x56, 0x78, 0x8b, 0x3e, + 0x03, 0x8f, 0xc0, 0x53, 0x74, 0x59, 0x76, 0x88, 0x45, 0x81, 0xf6, 0x29, 0xd8, 0xa1, 0xf1, 0xbf, + 0xa6, 0x69, 0x8a, 0xa0, 0x62, 0xe7, 0xcc, 0x77, 0xbe, 0x39, 0x9e, 0xdf, 0xf9, 0x32, 0x46, 0xdb, + 0x36, 0xe1, 0x01, 0xe1, 0x06, 0x25, 0xc4, 0x67, 0x60, 0x61, 0x1f, 0x87, 0x36, 0x30, 0x23, 0xee, + 0xcd, 0xac, 0xe8, 0x94, 0x11, 0x41, 0xd4, 0x66, 0x5a, 0xae, 0xcf, 0x88, 0x71, 0x6f, 0x53, 0xcb, + 0x36, 0xb2, 0x30, 0x07, 0x23, 0xee, 0x59, 0x20, 0x70, 0xcf, 0xb0, 0x89, 0x17, 0xa6, 0xce, 0xcd, + 0xba, 0x4b, 0x5c, 0x92, 0x3c, 0x1a, 0xf2, 0x29, 0x5b, 0x6d, 0xb9, 0x84, 0xb8, 0x3e, 0x18, 0xc9, + 0x2f, 0x2b, 0x3a, 0x30, 0x84, 0x17, 0x00, 0x17, 0x38, 0xa0, 0x69, 0x41, 0xe7, 0x63, 0x19, 0x55, + 0x87, 0x98, 0xe1, 0x80, 0xab, 0xf7, 0xd0, 0xbf, 0xb2, 0xad, 0xe9, 0x80, 0x0f, 0x2e, 0x16, 0x84, + 0x99, 0xd8, 0x71, 0x18, 0x70, 0xde, 0x54, 0xda, 0x4a, 0xf7, 0xef, 0x51, 0x5d, 0xaa, 0x3b, 0xb9, + 0xf8, 0x38, 0xd5, 0xd4, 0x3e, 0x6a, 0x04, 0x78, 0x62, 0x0a, 0xcc, 0x5c, 0x10, 0x66, 0x8c, 0x7d, + 0xcf, 0x91, 0x32, 0x6f, 0x96, 0xdb, 0x4a, 0xf7, 0x9f, 0xd1, 0x46, 0x80, 0x27, 0xfb, 0x89, 0xf6, + 0xa6, 0x90, 0x64, 0xa7, 0xe2, 0x70, 0xa6, 0x18, 0x33, 0xe0, 0x63, 0xe2, 0x3b, 0xa6, 0x45, 0x9b, + 0x95, 0xc4, 0x54, 0x2f, 0xd4, 0xfd, 0x5c, 0x1c, 0x50, 0xf5, 0x36, 0x5a, 0x97, 0x9d, 0x08, 0xe5, + 0x26, 0x05, 0x66, 0x5a, 0x3e, 0xb1, 0x0f, 0x9b, 0x0b, 0x89, 0x61, 0x25, 0xc0, 0x93, 0x3d, 0xca, + 0x87, 0xc0, 0x06, 0x72, 0x55, 0xdd, 0x41, 0xab, 0xb2, 0x34, 0x20, 0x31, 0x24, 0xb5, 0x84, 0x36, + 0xff, 0x92, 0x67, 0x18, 0xdc, 0x3a, 0x3e, 0x6d, 0x95, 0x3e, 0x9f, 0xb6, 0x1a, 0x29, 0x4d, 0xee, + 0x1c, 0xea, 0x1e, 0x31, 0x02, 0x2c, 0xc6, 0xfa, 0xf3, 0x50, 0x8c, 0x96, 0x03, 0x3c, 0xd9, 0x25, + 0x31, 0x0c, 0x81, 0xed, 0x51, 0xf5, 0x3e, 0xfa, 0x2f, 0xe2, 0x60, 0x46, 0x61, 0x46, 0x04, 0xcc, + 0x03, 0xec, 0xfb, 0x16, 0xb6, 0x0f, 0x9b, 0xd5, 0xb6, 0xd2, 0x5d, 0x1a, 0x35, 0x22, 0x0e, 0xaf, + 0x0b, 0xf5, 0x69, 0x26, 0x76, 0x3e, 0x94, 0xd1, 0xc6, 0x10, 0x42, 0xc7, 0x0b, 0xdd, 0x11, 0x64, + 0xaa, 0x47, 0x42, 0x75, 0x0b, 0xad, 0x5f, 0xc7, 0x76, 0xcd, 0x99, 0xc3, 0x95, 0x33, 0xfb, 0x02, + 0x68, 0x61, 0x28, 0x27, 0x86, 0x0d, 0xce, 0xec, 0x82, 0xe8, 0x94, 0xc7, 0xe1, 0x62, 0x8e, 0xa7, + 0x92, 0x7a, 0x1c, 0x2e, 0xae, 0x78, 0x1e, 0xa0, 0x2a, 0x0e, 0x48, 0x14, 0x8a, 0x04, 0x65, 0xad, + 0xff, 0xbf, 0x9e, 0x45, 0x50, 0x06, 0x4d, 0xcf, 0x82, 0xa6, 0x3f, 0x21, 0x5e, 0x38, 0x58, 0x90, + 0xf0, 0x46, 0x59, 0xb9, 0xba, 0x8b, 0x56, 0x6d, 0x12, 0x50, 0x1f, 0xe4, 0xd9, 0x4c, 0x99, 0xab, + 0x84, 0x71, 0xad, 0xbf, 0xa9, 0xa7, 0xa1, 0xd3, 0xf3, 0xd0, 0xe9, 0xfb, 0x79, 0xe8, 0x06, 0x4b, + 0x72, 0x8b, 0xa3, 0x2f, 0x2d, 0x65, 0xb4, 0x72, 0x61, 0x96, 0x72, 0xc7, 0x46, 0xea, 0xcb, 0x08, + 0x22, 0x70, 0x2e, 0x21, 0xdb, 0x45, 0x8b, 0x10, 0x0a, 0xe6, 0x81, 0x04, 0x55, 0xe9, 0xd6, 0xfa, + 0xdb, 0xfa, 0x75, 0xff, 0x10, 0x7d, 0x0e, 0xf2, 0xec, 0x95, 0xf3, 0x3d, 0x3a, 0xdf, 0x95, 0x62, + 0x32, 0xc5, 0xdc, 0x7e, 0x7b, 0x32, 0x5b, 0x68, 0xfd, 0xba, 0xa9, 0xac, 0xc5, 0xb3, 0x78, 0x1f, + 0xa2, 0xc5, 0xec, 0x1d, 0x93, 0x21, 0xfc, 0x02, 0xdf, 0xbc, 0x7e, 0x1e, 0xe0, 0x85, 0x3f, 0x01, + 0xf8, 0xd2, 0xc9, 0x6f, 0x00, 0x78, 0xda, 0x3f, 0x0b, 0xf8, 0x7d, 0x19, 0x2d, 0x3f, 0x83, 0x10, + 0xb8, 0xc7, 0x5f, 0x09, 0x2c, 0x40, 0x7d, 0x84, 0xaa, 0x34, 0xb9, 0x5e, 0x12, 0x9c, 0xb5, 0x7e, + 0xfb, 0x27, 0xdb, 0x27, 0x75, 0x79, 0xca, 0x52, 0x97, 0x3a, 0x46, 0x0d, 0x9a, 0xb6, 0x35, 0xd9, + 0xd4, 0x60, 0x25, 0xf0, 0x1b, 0xc7, 0xa1, 0x4e, 0xaf, 0x4a, 0x97, 0x3a, 0x45, 0xe1, 0x74, 0xa7, + 0xca, 0xcd, 0xb9, 0xe4, 0x9d, 0xa6, 0x25, 0x3e, 0x78, 0x71, 0xfc, 0x4d, 0x2b, 0x1d, 0x9f, 0x69, + 0xca, 0xc9, 0x99, 0xa6, 0x7c, 0x3d, 0xd3, 0x94, 0xa3, 0x73, 0xad, 0x74, 0x72, 0xae, 0x95, 0x3e, + 0x9d, 0x6b, 0xa5, 0xb7, 0x77, 0x5c, 0x4f, 0x8c, 0x23, 0x4b, 0xb7, 0x49, 0x60, 0x64, 0x77, 0x3e, + 0xc4, 0x81, 0x31, 0x99, 0xfd, 0x84, 0x88, 0x77, 0x14, 0xb8, 0x55, 0x4d, 0x32, 0x70, 0xf7, 0x47, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xf6, 0x87, 0xb4, 0xf2, 0x68, 0x06, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { diff --git a/x/poolrebalancer/types/query.pb.go b/x/poolrebalancer/types/query.pb.go index 0f9096d5..eeb6d44a 100644 --- a/x/poolrebalancer/types/query.pb.go +++ b/x/poolrebalancer/types/query.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: cosmos/evm/poolrebalancer/v1/query.proto +// source: cosmos/poolrebalancer/v1/query.proto package types @@ -39,7 +39,7 @@ func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } func (*QueryParamsRequest) ProtoMessage() {} func (*QueryParamsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_84183c6254b9379b, []int{0} + return fileDescriptor_882dee8c3ee6b12d, []int{0} } func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -77,7 +77,7 @@ func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } func (*QueryParamsResponse) ProtoMessage() {} func (*QueryParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_84183c6254b9379b, []int{1} + return fileDescriptor_882dee8c3ee6b12d, []int{1} } func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -116,7 +116,7 @@ func (m *QueryPendingRedelegationsRequest) Reset() { *m = QueryPendingRe func (m *QueryPendingRedelegationsRequest) String() string { return proto.CompactTextString(m) } func (*QueryPendingRedelegationsRequest) ProtoMessage() {} func (*QueryPendingRedelegationsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_84183c6254b9379b, []int{2} + return fileDescriptor_882dee8c3ee6b12d, []int{2} } func (m *QueryPendingRedelegationsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -155,7 +155,7 @@ func (m *QueryPendingRedelegationsResponse) Reset() { *m = QueryPendingR func (m *QueryPendingRedelegationsResponse) String() string { return proto.CompactTextString(m) } func (*QueryPendingRedelegationsResponse) ProtoMessage() {} func (*QueryPendingRedelegationsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_84183c6254b9379b, []int{3} + return fileDescriptor_882dee8c3ee6b12d, []int{3} } func (m *QueryPendingRedelegationsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -194,7 +194,7 @@ func (m *QueryPendingUndelegationsRequest) Reset() { *m = QueryPendingUn func (m *QueryPendingUndelegationsRequest) String() string { return proto.CompactTextString(m) } func (*QueryPendingUndelegationsRequest) ProtoMessage() {} func (*QueryPendingUndelegationsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_84183c6254b9379b, []int{4} + return fileDescriptor_882dee8c3ee6b12d, []int{4} } func (m *QueryPendingUndelegationsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -233,7 +233,7 @@ func (m *QueryPendingUndelegationsResponse) Reset() { *m = QueryPendingU func (m *QueryPendingUndelegationsResponse) String() string { return proto.CompactTextString(m) } func (*QueryPendingUndelegationsResponse) ProtoMessage() {} func (*QueryPendingUndelegationsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_84183c6254b9379b, []int{5} + return fileDescriptor_882dee8c3ee6b12d, []int{5} } func (m *QueryPendingUndelegationsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -263,53 +263,52 @@ func (m *QueryPendingUndelegationsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryPendingUndelegationsResponse proto.InternalMessageInfo func init() { - proto.RegisterType((*QueryParamsRequest)(nil), "cosmos.evm.poolrebalancer.v1.QueryParamsRequest") - proto.RegisterType((*QueryParamsResponse)(nil), "cosmos.evm.poolrebalancer.v1.QueryParamsResponse") - proto.RegisterType((*QueryPendingRedelegationsRequest)(nil), "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsRequest") - proto.RegisterType((*QueryPendingRedelegationsResponse)(nil), "cosmos.evm.poolrebalancer.v1.QueryPendingRedelegationsResponse") - proto.RegisterType((*QueryPendingUndelegationsRequest)(nil), "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsRequest") - proto.RegisterType((*QueryPendingUndelegationsResponse)(nil), "cosmos.evm.poolrebalancer.v1.QueryPendingUndelegationsResponse") + proto.RegisterType((*QueryParamsRequest)(nil), "cosmos.poolrebalancer.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "cosmos.poolrebalancer.v1.QueryParamsResponse") + proto.RegisterType((*QueryPendingRedelegationsRequest)(nil), "cosmos.poolrebalancer.v1.QueryPendingRedelegationsRequest") + proto.RegisterType((*QueryPendingRedelegationsResponse)(nil), "cosmos.poolrebalancer.v1.QueryPendingRedelegationsResponse") + proto.RegisterType((*QueryPendingUndelegationsRequest)(nil), "cosmos.poolrebalancer.v1.QueryPendingUndelegationsRequest") + proto.RegisterType((*QueryPendingUndelegationsResponse)(nil), "cosmos.poolrebalancer.v1.QueryPendingUndelegationsResponse") } func init() { - proto.RegisterFile("cosmos/evm/poolrebalancer/v1/query.proto", fileDescriptor_84183c6254b9379b) -} - -var fileDescriptor_84183c6254b9379b = []byte{ - // 514 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x94, 0x41, 0x6b, 0x13, 0x41, - 0x14, 0xc7, 0x77, 0xaa, 0x06, 0x9c, 0xe2, 0xc1, 0x31, 0x87, 0x12, 0xca, 0x1a, 0x97, 0x52, 0x43, - 0x29, 0x33, 0x6e, 0x8a, 0x27, 0x41, 0xa1, 0x07, 0x0b, 0x9e, 0x6a, 0xc0, 0x8b, 0x07, 0x65, 0x36, - 0x7d, 0x8c, 0x2b, 0xd9, 0x99, 0xed, 0xce, 0x66, 0xb1, 0x57, 0x3f, 0x81, 0xe0, 0xd1, 0x2f, 0xe0, - 0xd1, 0x8f, 0x91, 0x63, 0xa0, 0x1e, 0x3c, 0x89, 0x26, 0x82, 0x5f, 0x43, 0xb2, 0x33, 0xd2, 0x9d, - 0x34, 0x6e, 0x4c, 0x10, 0x2f, 0x61, 0x99, 0x9d, 0xf7, 0x7f, 0xff, 0xdf, 0x3f, 0xef, 0x2d, 0xee, - 0xf4, 0x95, 0x4e, 0x94, 0x66, 0x50, 0x24, 0x2c, 0x55, 0x6a, 0x90, 0x41, 0xc4, 0x07, 0x5c, 0xf6, - 0x21, 0x63, 0x45, 0xc8, 0x4e, 0x87, 0x90, 0x9d, 0xd1, 0x34, 0x53, 0xb9, 0x22, 0xdb, 0xe6, 0x26, - 0x85, 0x22, 0xa1, 0xee, 0x4d, 0x5a, 0x84, 0xad, 0x9b, 0x3c, 0x89, 0xa5, 0x62, 0xe5, 0xaf, 0x29, - 0x68, 0xed, 0x59, 0xe9, 0x88, 0x6b, 0x30, 0x4a, 0xac, 0x08, 0x23, 0xc8, 0x79, 0xc8, 0x52, 0x2e, - 0x62, 0xc9, 0xf3, 0x58, 0x49, 0x7b, 0x37, 0xac, 0xb5, 0x31, 0xd7, 0xce, 0x94, 0x34, 0x85, 0x12, - 0xaa, 0x7c, 0x64, 0xb3, 0x27, 0x7b, 0xba, 0x2d, 0x94, 0x12, 0x03, 0x60, 0x3c, 0x8d, 0x19, 0x97, - 0x52, 0xe5, 0x65, 0x17, 0x6d, 0xde, 0x06, 0x4d, 0x4c, 0x9e, 0xce, 0x8c, 0x1c, 0xf3, 0x8c, 0x27, - 0xba, 0x07, 0xa7, 0x43, 0xd0, 0x79, 0xf0, 0x02, 0xdf, 0x72, 0x4e, 0x75, 0xaa, 0xa4, 0x06, 0x72, - 0x84, 0x1b, 0x69, 0x79, 0xb2, 0x85, 0xda, 0xa8, 0xb3, 0xd9, 0xdd, 0xa1, 0x75, 0x09, 0x50, 0x53, - 0x7d, 0x78, 0x7d, 0xf4, 0xf5, 0xb6, 0xf7, 0xf1, 0xe7, 0xa7, 0x3d, 0xd4, 0xb3, 0xe5, 0xc1, 0x6b, - 0xdc, 0x36, 0xfa, 0x20, 0x4f, 0x62, 0x29, 0x7a, 0x70, 0x02, 0x03, 0x10, 0xc6, 0x98, 0xf5, 0x40, - 0x1e, 0x63, 0x7c, 0x11, 0x8a, 0x6d, 0xb8, 0xfb, 0xbb, 0xe1, 0x2c, 0x41, 0x6a, 0xfe, 0x0b, 0x9b, - 0x20, 0x3d, 0xe6, 0x02, 0x6c, 0x6d, 0xaf, 0x52, 0x19, 0x8c, 0x11, 0xbe, 0x53, 0xd3, 0xcc, 0xa2, - 0x45, 0xf8, 0x46, 0x56, 0x7d, 0xb1, 0x85, 0xda, 0x57, 0x3a, 0x9b, 0xdd, 0x70, 0x09, 0xe1, 0x65, - 0xc9, 0x2a, 0xae, 0x2b, 0x49, 0x8e, 0x1c, 0xa2, 0x8d, 0x92, 0xe8, 0xee, 0x52, 0x22, 0x63, 0xd0, - 0x41, 0x9a, 0x8b, 0xef, 0x99, 0xfc, 0x8f, 0xf1, 0xcd, 0x35, 0xbb, 0x88, 0x6f, 0x28, 0xd7, 0x8d, - 0xaf, 0x2a, 0xe9, 0xc4, 0xe7, 0x48, 0xfe, 0xb3, 0xf8, 0xba, 0xe7, 0x57, 0xf1, 0xb5, 0x12, 0x89, - 0x7c, 0x40, 0xb8, 0x61, 0xa6, 0x94, 0xdc, 0xab, 0xb7, 0x7a, 0x79, 0x49, 0x5a, 0xe1, 0x0a, 0x15, - 0xc6, 0x45, 0xb0, 0xff, 0xf6, 0xfc, 0xc7, 0xfb, 0x8d, 0x5d, 0xb2, 0xc3, 0xea, 0xb7, 0xdb, 0x58, - 0xfa, 0x8c, 0x70, 0x73, 0xd1, 0xd0, 0x92, 0x87, 0x7f, 0xd3, 0xf9, 0xcf, 0xab, 0xd5, 0x7a, 0xb4, - 0x76, 0xbd, 0xe5, 0x78, 0x50, 0x72, 0xdc, 0x27, 0x07, 0x4b, 0x38, 0x8c, 0xc6, 0x4b, 0x77, 0x0d, - 0x2a, 0x58, 0xce, 0x30, 0xad, 0x82, 0xb5, 0x68, 0xe4, 0x57, 0xc1, 0x5a, 0x38, 0xc5, 0xab, 0x62, - 0x39, 0xe3, 0x79, 0xf8, 0x64, 0xf4, 0xdd, 0xf7, 0x46, 0x13, 0x1f, 0x8d, 0x27, 0x3e, 0xfa, 0x36, - 0xf1, 0xd1, 0xbb, 0xa9, 0xef, 0x8d, 0xa7, 0xbe, 0xf7, 0x65, 0xea, 0x7b, 0xcf, 0xf7, 0x45, 0x9c, - 0xbf, 0x1a, 0x46, 0xb4, 0xaf, 0x92, 0xaa, 0xf8, 0x9b, 0x79, 0xf9, 0xfc, 0x2c, 0x05, 0x1d, 0x35, - 0xca, 0x8f, 0xf3, 0xc1, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x92, 0x79, 0xc7, 0x77, 0x8c, 0x06, - 0x00, 0x00, + proto.RegisterFile("cosmos/poolrebalancer/v1/query.proto", fileDescriptor_882dee8c3ee6b12d) +} + +var fileDescriptor_882dee8c3ee6b12d = []byte{ + // 507 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x54, 0xcf, 0x6a, 0x13, 0x41, + 0x18, 0xdf, 0xa9, 0x1a, 0x70, 0x8a, 0x07, 0xc7, 0x1c, 0x42, 0x90, 0x75, 0x5d, 0x44, 0x43, 0x69, + 0x76, 0xd8, 0x78, 0x10, 0xf4, 0x56, 0x41, 0xc1, 0x53, 0x0d, 0x78, 0xe9, 0x41, 0x99, 0x4d, 0x3f, + 0xc6, 0x95, 0xec, 0xcc, 0x76, 0x67, 0x13, 0xec, 0xd5, 0x17, 0x50, 0xf0, 0x25, 0xbc, 0xe9, 0x63, + 0xe4, 0xe0, 0xa1, 0xe0, 0xc5, 0x93, 0x68, 0x22, 0xf8, 0x1a, 0x92, 0x99, 0x29, 0xdd, 0x49, 0xb3, + 0x69, 0x2c, 0xd2, 0x4b, 0x58, 0x66, 0xbe, 0xef, 0xf7, 0x8f, 0xdf, 0x04, 0xdf, 0x19, 0x48, 0x95, + 0x49, 0x45, 0x73, 0x29, 0x87, 0x05, 0x24, 0x6c, 0xc8, 0xc4, 0x00, 0x0a, 0x3a, 0x8e, 0xe9, 0xc1, + 0x08, 0x8a, 0xc3, 0x28, 0x2f, 0x64, 0x29, 0x49, 0xcb, 0x4c, 0x45, 0xee, 0x54, 0x34, 0x8e, 0xdb, + 0xd7, 0x59, 0x96, 0x0a, 0x49, 0xf5, 0xaf, 0x19, 0x6e, 0x6f, 0x59, 0xc8, 0x84, 0x29, 0x30, 0x28, + 0x74, 0x1c, 0x27, 0x50, 0xb2, 0x98, 0xe6, 0x8c, 0xa7, 0x82, 0x95, 0xa9, 0x14, 0x76, 0xb6, 0x5b, + 0x4b, 0xbf, 0x40, 0x65, 0xc6, 0x9b, 0x5c, 0x72, 0xa9, 0x3f, 0xe9, 0xfc, 0xcb, 0x9e, 0xde, 0xe4, + 0x52, 0xf2, 0x21, 0x50, 0x96, 0xa7, 0x94, 0x09, 0x21, 0x4b, 0xcd, 0xa0, 0xcc, 0x6d, 0xd8, 0xc4, + 0xe4, 0xf9, 0x5c, 0xc4, 0x2e, 0x2b, 0x58, 0xa6, 0xfa, 0x70, 0x30, 0x02, 0x55, 0x86, 0x7b, 0xf8, + 0x86, 0x73, 0xaa, 0x72, 0x29, 0x14, 0x90, 0xc7, 0xb8, 0x91, 0xeb, 0x93, 0x16, 0x0a, 0x50, 0x67, + 0xb3, 0x17, 0x44, 0x75, 0xce, 0x23, 0xb3, 0xb9, 0x73, 0x75, 0xf2, 0xe3, 0x96, 0xf7, 0xe9, 0xcf, + 0x97, 0x2d, 0xd4, 0xb7, 0xab, 0xe1, 0x1b, 0x1c, 0x18, 0x6c, 0x10, 0xfb, 0xa9, 0xe0, 0x7d, 0xd8, + 0x87, 0x21, 0x70, 0x23, 0xca, 0xf2, 0x93, 0x27, 0x18, 0x9f, 0x84, 0x61, 0xc9, 0xee, 0x1e, 0x93, + 0xcd, 0x93, 0x8b, 0x4c, 0xfe, 0x36, 0xb9, 0x68, 0x97, 0x71, 0xb0, 0xbb, 0xfd, 0xca, 0x66, 0xf8, + 0x15, 0xe1, 0xdb, 0x2b, 0xc8, 0xac, 0xad, 0x97, 0xf8, 0x5a, 0x51, 0xbd, 0x68, 0xa1, 0xe0, 0x52, + 0x67, 0xb3, 0xd7, 0x5d, 0xe1, 0xee, 0x34, 0x5c, 0xd5, 0xaa, 0x0b, 0x47, 0x9e, 0x3a, 0x6e, 0x36, + 0xb4, 0x9b, 0x7b, 0x67, 0xba, 0x31, 0xe2, 0x1c, 0x3b, 0x0b, 0xd1, 0xbd, 0x10, 0x17, 0x18, 0xdd, + 0x02, 0xd9, 0x49, 0x74, 0x23, 0x71, 0x9e, 0xe8, 0xaa, 0x70, 0x4e, 0x74, 0x0e, 0xdc, 0x7f, 0x8b, + 0xae, 0xf7, 0xf9, 0x32, 0xbe, 0xa2, 0xed, 0x90, 0xf7, 0x08, 0x37, 0x4c, 0x3b, 0xc9, 0x76, 0xbd, + 0xcc, 0xd3, 0x8f, 0xa2, 0xdd, 0x5d, 0x73, 0xda, 0xb0, 0x87, 0x9d, 0x77, 0xdf, 0x7e, 0x7f, 0xdc, + 0x08, 0x49, 0x40, 0xeb, 0x5f, 0xb1, 0x91, 0x31, 0x41, 0xb8, 0xb9, 0xac, 0xa0, 0xe4, 0xe1, 0x59, + 0x8c, 0xf5, 0x4f, 0xa8, 0xfd, 0xe8, 0x5c, 0xbb, 0x56, 0xfb, 0x03, 0xad, 0x3d, 0x26, 0x74, 0x85, + 0x76, 0xb3, 0xff, 0xca, 0xad, 0x7a, 0xc5, 0x8a, 0x53, 0x98, 0x75, 0xad, 0x2c, 0xab, 0xf4, 0xba, + 0x56, 0x96, 0x36, 0xf4, 0x5f, 0xac, 0x38, 0xd5, 0xdb, 0x79, 0x36, 0xf9, 0xe5, 0x7b, 0x93, 0xa9, + 0x8f, 0x8e, 0xa6, 0x3e, 0xfa, 0x39, 0xf5, 0xd1, 0x87, 0x99, 0xef, 0x1d, 0xcd, 0x7c, 0xef, 0xfb, + 0xcc, 0xf7, 0xf6, 0xb6, 0x79, 0x5a, 0xbe, 0x1e, 0x25, 0xd1, 0x40, 0x66, 0xc7, 0xc0, 0x30, 0xce, + 0xe8, 0xdb, 0x45, 0xf8, 0xf2, 0x30, 0x07, 0x95, 0x34, 0xf4, 0x9f, 0xed, 0xfd, 0xbf, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x84, 0x2c, 0xe3, 0xda, 0x50, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -342,7 +341,7 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { out := new(QueryParamsResponse) - err := c.cc.Invoke(ctx, "/cosmos.evm.poolrebalancer.v1.Query/Params", in, out, opts...) + err := c.cc.Invoke(ctx, "/cosmos.poolrebalancer.v1.Query/Params", in, out, opts...) if err != nil { return nil, err } @@ -351,7 +350,7 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts . func (c *queryClient) PendingRedelegations(ctx context.Context, in *QueryPendingRedelegationsRequest, opts ...grpc.CallOption) (*QueryPendingRedelegationsResponse, error) { out := new(QueryPendingRedelegationsResponse) - err := c.cc.Invoke(ctx, "/cosmos.evm.poolrebalancer.v1.Query/PendingRedelegations", in, out, opts...) + err := c.cc.Invoke(ctx, "/cosmos.poolrebalancer.v1.Query/PendingRedelegations", in, out, opts...) if err != nil { return nil, err } @@ -360,7 +359,7 @@ func (c *queryClient) PendingRedelegations(ctx context.Context, in *QueryPending func (c *queryClient) PendingUndelegations(ctx context.Context, in *QueryPendingUndelegationsRequest, opts ...grpc.CallOption) (*QueryPendingUndelegationsResponse, error) { out := new(QueryPendingUndelegationsResponse) - err := c.cc.Invoke(ctx, "/cosmos.evm.poolrebalancer.v1.Query/PendingUndelegations", in, out, opts...) + err := c.cc.Invoke(ctx, "/cosmos.poolrebalancer.v1.Query/PendingUndelegations", in, out, opts...) if err != nil { return nil, err } @@ -405,7 +404,7 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/cosmos.evm.poolrebalancer.v1.Query/Params", + FullMethod: "/cosmos.poolrebalancer.v1.Query/Params", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) @@ -423,7 +422,7 @@ func _Query_PendingRedelegations_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/cosmos.evm.poolrebalancer.v1.Query/PendingRedelegations", + FullMethod: "/cosmos.poolrebalancer.v1.Query/PendingRedelegations", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QueryServer).PendingRedelegations(ctx, req.(*QueryPendingRedelegationsRequest)) @@ -441,7 +440,7 @@ func _Query_PendingUndelegations_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/cosmos.evm.poolrebalancer.v1.Query/PendingUndelegations", + FullMethod: "/cosmos.poolrebalancer.v1.Query/PendingUndelegations", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(QueryServer).PendingUndelegations(ctx, req.(*QueryPendingUndelegationsRequest)) @@ -450,7 +449,7 @@ func _Query_PendingUndelegations_Handler(srv interface{}, ctx context.Context, d } var _Query_serviceDesc = grpc.ServiceDesc{ - ServiceName: "cosmos.evm.poolrebalancer.v1.Query", + ServiceName: "cosmos.poolrebalancer.v1.Query", HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ { @@ -467,7 +466,7 @@ var _Query_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "cosmos/evm/poolrebalancer/v1/query.proto", + Metadata: "cosmos/poolrebalancer/v1/query.proto", } func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { diff --git a/x/poolrebalancer/types/query.pb.gw.go b/x/poolrebalancer/types/query.pb.gw.go index 461b3453..64d73acb 100644 --- a/x/poolrebalancer/types/query.pb.gw.go +++ b/x/poolrebalancer/types/query.pb.gw.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: cosmos/evm/poolrebalancer/v1/query.proto +// source: cosmos/poolrebalancer/v1/query.proto /* Package types is a reverse proxy. @@ -303,11 +303,11 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmos", "evm", "poolrebalancer", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "poolrebalancer", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_PendingRedelegations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmos", "evm", "poolrebalancer", "v1", "pending_redelegations"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_PendingRedelegations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "poolrebalancer", "v1", "pending_redelegations"}, "", runtime.AssumeColonVerbOpt(false))) - pattern_Query_PendingUndelegations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"cosmos", "evm", "poolrebalancer", "v1", "pending_undelegations"}, "", runtime.AssumeColonVerbOpt(false))) + pattern_Query_PendingUndelegations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "poolrebalancer", "v1", "pending_undelegations"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( diff --git a/x/poolrebalancer/types/tx.pb.go b/x/poolrebalancer/types/tx.pb.go index 186ec946..6681b85f 100644 --- a/x/poolrebalancer/types/tx.pb.go +++ b/x/poolrebalancer/types/tx.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: cosmos/evm/poolrebalancer/v1/tx.proto +// source: cosmos/poolrebalancer/v1/tx.proto package types @@ -44,7 +44,7 @@ func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParams) ProtoMessage() {} func (*MsgUpdateParams) Descriptor() ([]byte, []int) { - return fileDescriptor_28a11b1e0d968b99, []int{0} + return fileDescriptor_33319066f5e58215, []int{0} } func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -95,7 +95,7 @@ func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } func (*MsgUpdateParamsResponse) ProtoMessage() {} func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_28a11b1e0d968b99, []int{1} + return fileDescriptor_33319066f5e58215, []int{1} } func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -125,39 +125,36 @@ func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo func init() { - proto.RegisterType((*MsgUpdateParams)(nil), "cosmos.evm.poolrebalancer.v1.MsgUpdateParams") - proto.RegisterType((*MsgUpdateParamsResponse)(nil), "cosmos.evm.poolrebalancer.v1.MsgUpdateParamsResponse") -} - -func init() { - proto.RegisterFile("cosmos/evm/poolrebalancer/v1/tx.proto", fileDescriptor_28a11b1e0d968b99) -} - -var fileDescriptor_28a11b1e0d968b99 = []byte{ - // 353 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4d, 0xce, 0x2f, 0xce, - 0xcd, 0x2f, 0xd6, 0x4f, 0x2d, 0xcb, 0xd5, 0x2f, 0xc8, 0xcf, 0xcf, 0x29, 0x4a, 0x4d, 0x4a, 0xcc, - 0x49, 0xcc, 0x4b, 0x4e, 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, - 0xc9, 0x17, 0x92, 0x81, 0x28, 0xd3, 0x4b, 0x2d, 0xcb, 0xd5, 0x43, 0x55, 0xa6, 0x57, 0x66, 0x28, - 0x25, 0x98, 0x98, 0x9b, 0x99, 0x97, 0xaf, 0x0f, 0x26, 0x21, 0x1a, 0xa4, 0x0c, 0xf1, 0x9a, 0x8b, - 0x66, 0x04, 0x44, 0x8b, 0x38, 0x54, 0x4b, 0x6e, 0x71, 0x3a, 0x48, 0x4d, 0x6e, 0x71, 0x3a, 0x54, - 0x42, 0x12, 0x22, 0x11, 0x0f, 0xe6, 0xe9, 0x43, 0x5d, 0x02, 0x91, 0x12, 0x49, 0xcf, 0x4f, 0xcf, - 0x87, 0x88, 0x83, 0x58, 0x10, 0x51, 0xa5, 0x4b, 0x8c, 0x5c, 0xfc, 0xbe, 0xc5, 0xe9, 0xa1, 0x05, - 0x29, 0x89, 0x25, 0xa9, 0x01, 0x89, 0x45, 0x89, 0xb9, 0xc5, 0x42, 0x66, 0x5c, 0x9c, 0x89, 0xa5, - 0x25, 0x19, 0xf9, 0x45, 0x99, 0x25, 0x95, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x4e, 0x12, 0x97, - 0xb6, 0xe8, 0x8a, 0x40, 0x8d, 0x73, 0x4c, 0x49, 0x29, 0x4a, 0x2d, 0x2e, 0x0e, 0x2e, 0x29, 0xca, - 0xcc, 0x4b, 0x0f, 0x42, 0x28, 0x15, 0x72, 0xe7, 0x62, 0x2b, 0x00, 0x9b, 0x20, 0xc1, 0xa4, 0xc0, - 0xa8, 0xc1, 0x6d, 0xa4, 0xa2, 0x87, 0x2f, 0x28, 0xf4, 0x20, 0xb6, 0x39, 0x71, 0x9e, 0xb8, 0x27, - 0xcf, 0xb0, 0xe2, 0xf9, 0x06, 0x2d, 0xc6, 0x20, 0xa8, 0x76, 0x2b, 0xbb, 0xa6, 0xe7, 0x1b, 0xb4, - 0x10, 0x06, 0x77, 0x3d, 0xdf, 0xa0, 0xa5, 0x8d, 0x14, 0x48, 0x15, 0xe8, 0xc1, 0x84, 0xe6, 0x01, - 0x25, 0x49, 0x2e, 0x71, 0x34, 0xa1, 0xa0, 0xd4, 0xe2, 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0xa3, 0x26, - 0x46, 0x2e, 0x66, 0xdf, 0xe2, 0x74, 0xa1, 0x12, 0x2e, 0x1e, 0x14, 0x3f, 0xeb, 0xe2, 0x77, 0x2b, - 0x9a, 0x71, 0x52, 0xa6, 0x24, 0x29, 0x87, 0xd9, 0x2e, 0xc5, 0xda, 0x00, 0xf2, 0xa7, 0x93, 0xdb, - 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, - 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0xe9, 0xa4, 0x67, 0x96, 0x64, 0x94, - 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0xe3, 0xf3, 0x71, 0x49, 0x65, 0x41, 0x6a, 0x71, 0x12, 0x1b, - 0x38, 0x0e, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x37, 0xcc, 0x45, 0x21, 0x9a, 0x02, 0x00, - 0x00, + proto.RegisterType((*MsgUpdateParams)(nil), "cosmos.poolrebalancer.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "cosmos.poolrebalancer.v1.MsgUpdateParamsResponse") +} + +func init() { proto.RegisterFile("cosmos/poolrebalancer/v1/tx.proto", fileDescriptor_33319066f5e58215) } + +var fileDescriptor_33319066f5e58215 = []byte{ + // 348 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x4c, 0xce, 0x2f, 0xce, + 0xcd, 0x2f, 0xd6, 0x2f, 0xc8, 0xcf, 0xcf, 0x29, 0x4a, 0x4d, 0x4a, 0xcc, 0x49, 0xcc, 0x4b, 0x4e, + 0x2d, 0xd2, 0x2f, 0x33, 0xd4, 0x2f, 0xa9, 0xd0, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x80, + 0x28, 0xd1, 0x43, 0x55, 0xa2, 0x57, 0x66, 0x28, 0x25, 0x98, 0x98, 0x9b, 0x99, 0x97, 0xaf, 0x0f, + 0x26, 0x21, 0x8a, 0xa5, 0x74, 0x71, 0x9a, 0x87, 0xa6, 0x1d, 0xa2, 0x5c, 0x1c, 0xaa, 0x3c, 0xb7, + 0x38, 0x1d, 0xa4, 0x26, 0xb7, 0x38, 0x1d, 0x2a, 0x21, 0x09, 0x91, 0x88, 0x07, 0xf3, 0xf4, 0x61, + 0x2e, 0x00, 0x4b, 0x89, 0xa4, 0xe7, 0xa7, 0xe7, 0x43, 0xc4, 0x41, 0x2c, 0x88, 0xa8, 0xd2, 0x69, + 0x46, 0x2e, 0x7e, 0xdf, 0xe2, 0xf4, 0xd0, 0x82, 0x94, 0xc4, 0x92, 0xd4, 0x80, 0xc4, 0xa2, 0xc4, + 0xdc, 0x62, 0x21, 0x33, 0x2e, 0xce, 0xc4, 0xd2, 0x92, 0x8c, 0xfc, 0xa2, 0xcc, 0x92, 0x4a, 0x09, + 0x46, 0x05, 0x46, 0x0d, 0x4e, 0x27, 0x89, 0x4b, 0x5b, 0x74, 0x45, 0xa0, 0xc6, 0x39, 0xa6, 0xa4, + 0x14, 0xa5, 0x16, 0x17, 0x07, 0x97, 0x14, 0x65, 0xe6, 0xa5, 0x07, 0x21, 0x94, 0x0a, 0x39, 0x73, + 0xb1, 0x15, 0x80, 0x4d, 0x90, 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x36, 0x52, 0xd0, 0xc3, 0x15, 0x04, + 0x7a, 0x10, 0x9b, 0x9c, 0x38, 0x4f, 0xdc, 0x93, 0x67, 0x58, 0xf1, 0x7c, 0x83, 0x16, 0x63, 0x10, + 0x54, 0xab, 0x95, 0x75, 0xd3, 0xf3, 0x0d, 0x5a, 0x08, 0x43, 0xbb, 0x9e, 0x6f, 0xd0, 0xd2, 0xc0, + 0x19, 0x38, 0x68, 0x2e, 0x57, 0x92, 0xe4, 0x12, 0x47, 0x13, 0x0a, 0x4a, 0x2d, 0x2e, 0xc8, 0xcf, + 0x2b, 0x4e, 0x35, 0xaa, 0xe2, 0x62, 0xf6, 0x2d, 0x4e, 0x17, 0xca, 0xe1, 0xe2, 0x41, 0xf1, 0xab, + 0x26, 0x6e, 0x37, 0xa2, 0x99, 0x24, 0x65, 0x48, 0xb4, 0x52, 0x98, 0xa5, 0x52, 0xac, 0x0d, 0x20, + 0xbf, 0x39, 0xb9, 0x9d, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, + 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, 0x4e, 0x7a, + 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0x2e, 0x34, 0xb6, 0xf4, 0x53, 0xcb, 0x72, 0xf5, + 0x2b, 0xd0, 0xfd, 0x5a, 0x52, 0x59, 0x90, 0x5a, 0x9c, 0xc4, 0x06, 0x8e, 0x33, 0x63, 0x40, 0x00, + 0x00, 0x00, 0xff, 0xff, 0xa5, 0xe7, 0x91, 0x58, 0x7e, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -187,7 +184,7 @@ func NewMsgClient(cc grpc1.ClientConn) MsgClient { func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { out := new(MsgUpdateParamsResponse) - err := c.cc.Invoke(ctx, "/cosmos.evm.poolrebalancer.v1.Msg/UpdateParams", in, out, opts...) + err := c.cc.Invoke(ctx, "/cosmos.poolrebalancer.v1.Msg/UpdateParams", in, out, opts...) if err != nil { return nil, err } @@ -223,7 +220,7 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/cosmos.evm.poolrebalancer.v1.Msg/UpdateParams", + FullMethod: "/cosmos.poolrebalancer.v1.Msg/UpdateParams", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) @@ -232,7 +229,7 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in } var _Msg_serviceDesc = grpc.ServiceDesc{ - ServiceName: "cosmos.evm.poolrebalancer.v1.Msg", + ServiceName: "cosmos.poolrebalancer.v1.Msg", HandlerType: (*MsgServer)(nil), Methods: []grpc.MethodDesc{ { @@ -241,7 +238,7 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "cosmos/evm/poolrebalancer/v1/tx.proto", + Metadata: "cosmos/poolrebalancer/v1/tx.proto", } func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { From 7dab76967f6b00f5229ef3ea2586e692b6b7f81e Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Fri, 27 Mar 2026 20:29:30 +0530 Subject: [PATCH 13/31] fix(poolrebalancer): harden EndBlock handling and add rebalance failure observability Signed-off-by: Nikhil Sharma --- tests/e2e/poolrebalancer/README.md | 19 ++ x/poolrebalancer/abci.go | 4 +- x/poolrebalancer/abci_test.go | 60 +++++ x/poolrebalancer/keeper/msg_server_test.go | 11 + x/poolrebalancer/keeper/params.go | 3 + x/poolrebalancer/keeper/rebalance.go | 32 +++ .../keeper/rebalance_events_test.go | 71 +++++ .../keeper/rebalance_process_test.go | 247 ++++++++++++++++++ x/poolrebalancer/types/events.go | 3 + 9 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 x/poolrebalancer/abci_test.go create mode 100644 x/poolrebalancer/keeper/rebalance_events_test.go create mode 100644 x/poolrebalancer/keeper/rebalance_process_test.go diff --git a/tests/e2e/poolrebalancer/README.md b/tests/e2e/poolrebalancer/README.md index 67b5e8fe..0914c687 100644 --- a/tests/e2e/poolrebalancer/README.md +++ b/tests/e2e/poolrebalancer/README.md @@ -60,3 +60,22 @@ bash tests/e2e/poolrebalancer/rebalance_scenario_runner.sh --scenario expansion - `evmd query poolrebalancer params ...` - `evmd query poolrebalancer pending-redelegations ...` - `evmd query poolrebalancer pending-undelegations ...` + +## Event Signals to Watch + +The rebalancer emits these event types during EndBlock processing: + +- `rebalance_summary`: successful operations were scheduled in this block. +- `redelegation_started`: a redelegation was initiated and tracked. +- `undelegation_started`: an undelegation fallback operation was initiated and tracked. +- `redelegation_failed`: a candidate redelegation failed and was skipped for this pass. +- `undelegation_failed`: undelegation fallback failed and the fallback loop stopped for this pass. +- `redelegations_completed`: matured pending redelegation tracking entries were cleaned. +- `undelegations_completed`: matured pending undelegation tracking entries were cleaned. + +For failure events, the `reason` attribute contains the underlying error string. + +## EndBlock Failure Policy + +- Cleanup phases (`CompletePendingRedelegations`, `CompletePendingUndelegations`) are strict; failures return an error. +- `ProcessRebalance` is best-effort; failures are logged and retried on the next block. diff --git a/x/poolrebalancer/abci.go b/x/poolrebalancer/abci.go index 904a5159..a0034a0a 100644 --- a/x/poolrebalancer/abci.go +++ b/x/poolrebalancer/abci.go @@ -8,6 +8,7 @@ import ( // EndBlocker runs at end of block: complete matured redelegations/undelegations, then process rebalance. func EndBlocker(ctx sdk.Context, k keeper.Keeper) error { + // Keep cleanup strict to avoid queue/index drift from staking state. if err := k.CompletePendingRedelegations(ctx); err != nil { ctx.Logger().Error("poolrebalancer: complete pending redelegations failed", "err", err) return err @@ -16,9 +17,10 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) error { ctx.Logger().Error("poolrebalancer: complete pending undelegations failed", "err", err) return err } + // Rebalance is best-effort; operational failures are retried next block. if err := k.ProcessRebalance(ctx); err != nil { ctx.Logger().Error("poolrebalancer: process rebalance failed", "err", err) - return err + return nil } return nil } diff --git a/x/poolrebalancer/abci_test.go b/x/poolrebalancer/abci_test.go new file mode 100644 index 00000000..0cd455fd --- /dev/null +++ b/x/poolrebalancer/abci_test.go @@ -0,0 +1,60 @@ +package poolrebalancer + +import ( + "bytes" + "testing" + "time" + + storetypes "cosmossdk.io/store/types" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + + "github.com/cosmos/evm/x/poolrebalancer/keeper" + "github.com/cosmos/evm/x/poolrebalancer/types" +) + +func newEndBlockerTestKeeper(t *testing.T) (sdk.Context, keeper.Keeper, *storetypes.KVStoreKey) { + t.Helper() + + storeKey := storetypes.NewKVStoreKey(types.ModuleName) + tKey := storetypes.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + + storeService := runtime.NewKVStoreService(storeKey) + cdc := moduletestutil.MakeTestEncodingConfig().Codec + stakingKeeper := &stakingkeeper.Keeper{} // zero value; tests avoid staking calls + authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) + + k := keeper.NewKeeper(cdc, storeService, stakingKeeper, authority) + return ctx, k, storeKey +} + +func TestEndBlocker_ProcessRebalanceErrorIsNonHalting(t *testing.T) { + ctx, k, storeKey := newEndBlockerTestKeeper(t) + + // Inject malformed params directly to force an operational ProcessRebalance error + // (GetParams unmarshal failure), while keeping cleanup paths healthy. + ctx.KVStore(storeKey).Set(types.ParamsKey, []byte("not-a-valid-proto")) + + err := EndBlocker(ctx, k) + require.NoError(t, err, "ProcessRebalance errors should not halt EndBlocker") +} + +func TestEndBlocker_CleanupErrorRemainsHalting(t *testing.T) { + ctx, k, storeKey := newEndBlockerTestKeeper(t) + now := time.Now().UTC() + ctx = ctx.WithBlockTime(now) + + // Seed an invalid queued redelegation value so cleanup fails on unmarshal. + maturedKey := types.GetPendingRedelegationQueueKey(now.Add(-time.Second)) + ctx.KVStore(storeKey).Set(maturedKey, []byte("not-a-valid-proto")) + + err := EndBlocker(ctx, k) + require.Error(t, err, "cleanup failures should remain halting") +} + diff --git a/x/poolrebalancer/keeper/msg_server_test.go b/x/poolrebalancer/keeper/msg_server_test.go index 4dece693..2f6ae9f7 100644 --- a/x/poolrebalancer/keeper/msg_server_test.go +++ b/x/poolrebalancer/keeper/msg_server_test.go @@ -91,3 +91,14 @@ func TestMsgUpdateParams_ValidateBasic_RejectsInvalidParams(t *testing.T) { require.Error(t, msg.ValidateBasic()) } + +func TestSetParams_RejectsInvalidParamsDirectly(t *testing.T) { + ctx, k := newTestKeeper(t) + + invalid := types.DefaultParams() + invalid.MaxTargetValidators = 0 + + err := k.SetParams(ctx, invalid) + require.Error(t, err) + require.Contains(t, err.Error(), "max_target_validators must be positive") +} diff --git a/x/poolrebalancer/keeper/params.go b/x/poolrebalancer/keeper/params.go index d3d7a101..e550845b 100644 --- a/x/poolrebalancer/keeper/params.go +++ b/x/poolrebalancer/keeper/params.go @@ -30,6 +30,9 @@ func (k Keeper) GetParams(ctx context.Context) (params types.Params, err error) // SetParams stores the module params. func (k Keeper) SetParams(ctx context.Context, params types.Params) error { + if err := params.Validate(); err != nil { + return err + } store := k.storeService.OpenKVStore(ctx) bz := k.cdc.MustMarshal(¶ms) return store.Set(types.ParamsKey, bz) diff --git a/x/poolrebalancer/keeper/rebalance.go b/x/poolrebalancer/keeper/rebalance.go index 391ce07d..46f4ae81 100644 --- a/x/poolrebalancer/keeper/rebalance.go +++ b/x/poolrebalancer/keeper/rebalance.go @@ -152,6 +152,35 @@ func minInt(a, b math.Int) math.Int { return b } +func (k Keeper) emitRedelegationFailureEvent(ctx context.Context, del sdk.AccAddress, srcVal, dstVal sdk.ValAddress, coin sdk.Coin, reason string) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeRedelegationFailed, + sdk.NewAttribute(types.AttributeKeyDelegator, del.String()), + sdk.NewAttribute(types.AttributeKeySrcValidator, srcVal.String()), + sdk.NewAttribute(types.AttributeKeyDstValidator, dstVal.String()), + sdk.NewAttribute(types.AttributeKeyAmount, coin.Amount.String()), + sdk.NewAttribute(types.AttributeKeyDenom, coin.Denom), + sdk.NewAttribute(types.AttributeKeyReason, reason), + ), + ) +} + +func (k Keeper) emitUndelegationFailureEvent(ctx context.Context, del sdk.AccAddress, val sdk.ValAddress, coin sdk.Coin, reason string) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + sdkCtx.EventManager().EmitEvent( + sdk.NewEvent( + types.EventTypeUndelegationFailed, + sdk.NewAttribute(types.AttributeKeyDelegator, del.String()), + sdk.NewAttribute(types.AttributeKeyValidator, val.String()), + sdk.NewAttribute(types.AttributeKeyAmount, coin.Amount.String()), + sdk.NewAttribute(types.AttributeKeyDenom, coin.Denom), + sdk.NewAttribute(types.AttributeKeyReason, reason), + ), + ) +} + // PickBestRedelegation selects a single (src, dst, amount) move based on deltas. // Ties are broken deterministically by (src,dst) ordering. If maxMove is non-zero, it caps the amount. func (k Keeper) PickBestRedelegation( @@ -348,6 +377,8 @@ func (k Keeper) ProcessRebalance(ctx context.Context) error { deltas[dstKey] = deltas[dstKey].Sub(amt) opsDone++ continue + } else { + k.emitRedelegationFailureEvent(ctx, del, srcVal, dstVal, coin, err.Error()) } } @@ -376,6 +407,7 @@ func (k Keeper) ProcessRebalance(ctx context.Context) error { } coin := sdk.NewCoin(bondDenom, undelAmt) if _, _, err := k.BeginTrackedUndelegation(ctx, del, valAddr, coin); err != nil { + k.emitUndelegationFailureEvent(ctx, del, valAddr, coin, err.Error()) break } deltas[valKey] = deltas[valKey].Add(undelAmt) diff --git a/x/poolrebalancer/keeper/rebalance_events_test.go b/x/poolrebalancer/keeper/rebalance_events_test.go new file mode 100644 index 00000000..9d0fa673 --- /dev/null +++ b/x/poolrebalancer/keeper/rebalance_events_test.go @@ -0,0 +1,71 @@ +package keeper + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/evm/x/poolrebalancer/types" +) + +func TestEmitRedelegationFailureEvent(t *testing.T) { + ctx, k := newTestKeeper(t) + + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + src := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + dst := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + coin := sdk.NewInt64Coin("stake", 42) + reason := "begin redelegation failed" + + k.emitRedelegationFailureEvent(ctx, del, src, dst, coin, reason) + + events := sdk.UnwrapSDKContext(ctx).EventManager().Events() + require.NotEmpty(t, events) + + ev := events[len(events)-1] + require.Equal(t, types.EventTypeRedelegationFailed, ev.Type) + + attrs := map[string]string{} + for _, attr := range ev.Attributes { + attrs[string(attr.Key)] = string(attr.Value) + } + + require.Equal(t, del.String(), attrs[types.AttributeKeyDelegator]) + require.Equal(t, src.String(), attrs[types.AttributeKeySrcValidator]) + require.Equal(t, dst.String(), attrs[types.AttributeKeyDstValidator]) + require.Equal(t, coin.Amount.String(), attrs[types.AttributeKeyAmount]) + require.Equal(t, coin.Denom, attrs[types.AttributeKeyDenom]) + require.Equal(t, reason, attrs[types.AttributeKeyReason]) +} + +func TestEmitUndelegationFailureEvent(t *testing.T) { + ctx, k := newTestKeeper(t) + + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + val := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + coin := sdk.NewInt64Coin("stake", 21) + reason := "begin undelegation failed" + + k.emitUndelegationFailureEvent(ctx, del, val, coin, reason) + + events := sdk.UnwrapSDKContext(ctx).EventManager().Events() + require.NotEmpty(t, events) + + ev := events[len(events)-1] + require.Equal(t, types.EventTypeUndelegationFailed, ev.Type) + + attrs := map[string]string{} + for _, attr := range ev.Attributes { + attrs[string(attr.Key)] = string(attr.Value) + } + + require.Equal(t, del.String(), attrs[types.AttributeKeyDelegator]) + require.Equal(t, val.String(), attrs[types.AttributeKeyValidator]) + require.Equal(t, coin.Amount.String(), attrs[types.AttributeKeyAmount]) + require.Equal(t, coin.Denom, attrs[types.AttributeKeyDenom]) + require.Equal(t, reason, attrs[types.AttributeKeyReason]) +} + diff --git a/x/poolrebalancer/keeper/rebalance_process_test.go b/x/poolrebalancer/keeper/rebalance_process_test.go new file mode 100644 index 00000000..915142eb --- /dev/null +++ b/x/poolrebalancer/keeper/rebalance_process_test.go @@ -0,0 +1,247 @@ +package keeper + +import ( + "bytes" + "context" + "errors" + "testing" + "time" + + abci "github.com/cometbft/cometbft/abci/types" + storetypes "cosmossdk.io/store/types" + "github.com/stretchr/testify/require" + + "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/cosmos/evm/x/poolrebalancer/types" +) + +type mockStakingKeeper struct { + vals []stakingtypes.Validator + validatorByAddr map[string]stakingtypes.Validator + delegations []stakingtypes.Delegation + delegationByValAddr map[string]stakingtypes.Delegation + failBeginRedelegation bool + failUndelegate bool +} + +func (m *mockStakingKeeper) GetBondedValidatorsByPower(ctx context.Context) ([]stakingtypes.Validator, error) { + return m.vals, nil +} + +func (m *mockStakingKeeper) GetDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) ([]stakingtypes.Delegation, error) { + return m.delegations, nil +} + +func (m *mockStakingKeeper) GetValidator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.Validator, error) { + val, ok := m.validatorByAddr[addr.String()] + if !ok { + return stakingtypes.Validator{}, errors.New("validator not found") + } + return val, nil +} + +func (m *mockStakingKeeper) GetDelegation(ctx context.Context, delegatorAddr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.Delegation, error) { + delegation, ok := m.delegationByValAddr[valAddr.String()] + if !ok { + return stakingtypes.Delegation{}, errors.New("delegation not found") + } + return delegation, nil +} + +func (m *mockStakingKeeper) BeginRedelegation(ctx context.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount math.LegacyDec) (completionTime time.Time, err error) { + if m.failBeginRedelegation { + return time.Time{}, errors.New("mock begin redelegation failed") + } + return sdk.UnwrapSDKContext(ctx).BlockTime().Add(time.Hour), nil +} + +func (m *mockStakingKeeper) Undelegate(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount math.LegacyDec) (completionTime time.Time, amount math.Int, err error) { + if m.failUndelegate { + return time.Time{}, math.ZeroInt(), errors.New("mock undelegate failed") + } + return sdk.UnwrapSDKContext(ctx).BlockTime().Add(time.Hour), sharesAmount.TruncateInt(), nil +} + +func (m *mockStakingKeeper) UnbondingTime(ctx context.Context) (time.Duration, error) { + return time.Hour, nil +} + +func (m *mockStakingKeeper) BondDenom(ctx context.Context) (string, error) { + return "stake", nil +} + +func newProcessRebalanceKeeper(t *testing.T, sk types.StakingKeeper) (sdk.Context, Keeper) { + t.Helper() + + storeKey := storetypes.NewKVStoreKey(types.ModuleName) + tKey := storetypes.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + ctx = ctx.WithBlockTime(time.Now().UTC()) + + storeService := runtime.NewKVStoreService(storeKey) + cdc := moduletestutil.MakeTestEncodingConfig().Codec + authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) + k := NewKeeper(cdc, storeService, sk, authority) + + return ctx, k +} + +func setupBasicRebalanceState(t *testing.T, ctx sdk.Context, k Keeper) (sdk.AccAddress, sdk.ValAddress, sdk.ValAddress) { + t.Helper() + + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + srcVal := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + dstVal := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + + params := types.DefaultParams() + params.PoolDelegatorAddress = del.String() + params.MaxTargetValidators = 2 + params.RebalanceThresholdBp = 0 + params.MaxOpsPerBlock = 1 + params.MaxMovePerOp = math.ZeroInt() + require.NoError(t, k.SetParams(ctx, params)) + + return del, srcVal, dstVal +} + +func attrsToMap(attrs []abci.EventAttribute) map[string]string { + out := make(map[string]string, len(attrs)) + for _, attr := range attrs { + out[attr.Key] = attr.Value + } + return out +} + +func TestProcessRebalance_EmitsRedelegationFailedEvent(t *testing.T) { + srcVal := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + dstVal := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + + srcValidator := stakingtypes.Validator{ + OperatorAddress: srcVal.String(), + Tokens: math.NewInt(100), + DelegatorShares: math.LegacyNewDec(100), + } + dstValidator := stakingtypes.Validator{ + OperatorAddress: dstVal.String(), + Tokens: math.NewInt(100), + DelegatorShares: math.LegacyNewDec(100), + } + + sk := &mockStakingKeeper{ + vals: []stakingtypes.Validator{srcValidator, dstValidator}, + validatorByAddr: map[string]stakingtypes.Validator{ + srcVal.String(): srcValidator, + dstVal.String(): dstValidator, + }, + delegations: []stakingtypes.Delegation{ + { + DelegatorAddress: sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String(), + ValidatorAddress: srcVal.String(), + Shares: math.LegacyNewDec(100), + }, + }, + delegationByValAddr: map[string]stakingtypes.Delegation{ + srcVal.String(): { + DelegatorAddress: sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String(), + ValidatorAddress: srcVal.String(), + Shares: math.LegacyNewDec(100), + }, + }, + failBeginRedelegation: true, + } + + ctx, k := newProcessRebalanceKeeper(t, sk) + del, _, _ := setupBasicRebalanceState(t, ctx, k) + + require.NoError(t, k.ProcessRebalance(ctx)) + + events := sdk.UnwrapSDKContext(ctx).EventManager().Events() + found := false + for _, ev := range events { + if ev.Type != types.EventTypeRedelegationFailed { + continue + } + found = true + attrs := attrsToMap(ev.Attributes) + require.Equal(t, del.String(), attrs[types.AttributeKeyDelegator]) + require.Equal(t, srcVal.String(), attrs[types.AttributeKeySrcValidator]) + require.Equal(t, dstVal.String(), attrs[types.AttributeKeyDstValidator]) + require.Equal(t, "50", attrs[types.AttributeKeyAmount]) + require.Equal(t, "stake", attrs[types.AttributeKeyDenom]) + require.Contains(t, attrs[types.AttributeKeyReason], "mock begin redelegation failed") + } + require.True(t, found, "expected redelegation failure event") +} + +func TestProcessRebalance_EmitsUndelegationFailedEvent(t *testing.T) { + srcVal := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + dstVal := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + + srcValidator := stakingtypes.Validator{ + OperatorAddress: srcVal.String(), + Tokens: math.NewInt(100), + DelegatorShares: math.LegacyNewDec(100), + } + dstValidator := stakingtypes.Validator{ + OperatorAddress: dstVal.String(), + Tokens: math.NewInt(100), + DelegatorShares: math.LegacyNewDec(100), + } + + sk := &mockStakingKeeper{ + vals: []stakingtypes.Validator{srcValidator, dstValidator}, + validatorByAddr: map[string]stakingtypes.Validator{ + srcVal.String(): srcValidator, + dstVal.String(): dstValidator, + }, + delegations: []stakingtypes.Delegation{ + { + DelegatorAddress: sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String(), + ValidatorAddress: srcVal.String(), + Shares: math.LegacyNewDec(100), + }, + }, + delegationByValAddr: map[string]stakingtypes.Delegation{ + srcVal.String(): { + DelegatorAddress: sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String(), + ValidatorAddress: srcVal.String(), + Shares: math.LegacyNewDec(100), + }, + }, + failBeginRedelegation: true, + failUndelegate: true, + } + + ctx, k := newProcessRebalanceKeeper(t, sk) + del, _, _ := setupBasicRebalanceState(t, ctx, k) + + params, err := k.GetParams(ctx) + require.NoError(t, err) + params.UseUndelegateFallback = true + require.NoError(t, k.SetParams(ctx, params)) + + require.NoError(t, k.ProcessRebalance(ctx)) + + events := sdk.UnwrapSDKContext(ctx).EventManager().Events() + found := false + for _, ev := range events { + if ev.Type != types.EventTypeUndelegationFailed { + continue + } + found = true + attrs := attrsToMap(ev.Attributes) + require.Equal(t, del.String(), attrs[types.AttributeKeyDelegator]) + require.Equal(t, srcVal.String(), attrs[types.AttributeKeyValidator]) + require.Equal(t, "50", attrs[types.AttributeKeyAmount]) + require.Equal(t, "stake", attrs[types.AttributeKeyDenom]) + require.Contains(t, attrs[types.AttributeKeyReason], "mock undelegate failed") + } + require.True(t, found, "expected undelegation failure event") +} + diff --git a/x/poolrebalancer/types/events.go b/x/poolrebalancer/types/events.go index c2ab49a6..b66a7b2b 100644 --- a/x/poolrebalancer/types/events.go +++ b/x/poolrebalancer/types/events.go @@ -4,7 +4,9 @@ const ( // Event types. EventTypeRebalanceSummary = "rebalance_summary" EventTypeRedelegationStarted = "redelegation_started" + EventTypeRedelegationFailed = "redelegation_failed" EventTypeUndelegationStarted = "undelegation_started" + EventTypeUndelegationFailed = "undelegation_failed" EventTypeRedelegationsCompleted = "redelegations_completed" EventTypeUndelegationsCompleted = "undelegations_completed" @@ -19,4 +21,5 @@ const ( AttributeKeyCount = "count" AttributeKeyOpsDone = "ops_done" AttributeKeyUseFallback = "use_undelegate_fallback" + AttributeKeyReason = "reason" ) From 7d977d80a33f2ef37792be3c5911868d31b98c64 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 1 Apr 2026 00:12:48 +0530 Subject: [PATCH 14/31] fix(poolrebalancer): include src validator in pending redelegation key to prevent source merge collisions Signed-off-by: Nikhil Sharma --- x/poolrebalancer/keeper/redelegation.go | 6 +-- x/poolrebalancer/keeper/redelegation_test.go | 43 +++++++++++++++++++- x/poolrebalancer/types/keys.go | 7 ++-- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/x/poolrebalancer/keeper/redelegation.go b/x/poolrebalancer/keeper/redelegation.go index 966735f2..7d63ceda 100644 --- a/x/poolrebalancer/keeper/redelegation.go +++ b/x/poolrebalancer/keeper/redelegation.go @@ -21,8 +21,8 @@ func (k Keeper) addPendingRedelegation(ctx context.Context, del sdk.AccAddress, store := k.storeService.OpenKVStore(ctx) denom := coin.Denom - // Primary key: merge if an entry already exists for the same (del, denom, dst, completion). - primaryKey := types.GetPendingRedelegationKey(del, denom, dstVal, completionTime) + // Primary key: merge if an entry already exists for the same (del, denom, src, dst, completion). + primaryKey := types.GetPendingRedelegationKey(del, denom, srcVal, dstVal, completionTime) var entry types.PendingRedelegation if bz, err := store.Get(primaryKey); err == nil && bz != nil && len(bz) > 0 { if err := k.cdc.Unmarshal(bz, &entry); err != nil { @@ -156,7 +156,7 @@ func (k Keeper) deletePendingRedelegation(ctx context.Context, entry types.Pendi } denom := entry.Amount.Denom - primaryKey := types.GetPendingRedelegationKey(del, denom, dstVal, completion) + primaryKey := types.GetPendingRedelegationKey(del, denom, srcVal, dstVal, completion) if err := store.Delete(primaryKey); err != nil { return err } diff --git a/x/poolrebalancer/keeper/redelegation_test.go b/x/poolrebalancer/keeper/redelegation_test.go index 65d58142..55b33e9e 100644 --- a/x/poolrebalancer/keeper/redelegation_test.go +++ b/x/poolrebalancer/keeper/redelegation_test.go @@ -57,7 +57,7 @@ func TestCompletePendingRedelegations_RemovesPrimaryIndexAndQueue(t *testing.T) } require.NoError(t, k.SetPendingRedelegation(ctx, entry)) - primaryKey := types.GetPendingRedelegationKey(del, denom, dstVal, completion) + primaryKey := types.GetPendingRedelegationKey(del, denom, srcVal, dstVal, completion) indexKey := types.GetPendingRedelegationBySrcIndexKey(srcVal, completion, denom, dstVal, del) queueKey := types.GetPendingRedelegationQueueKey(completion) @@ -83,3 +83,44 @@ func TestCompletePendingRedelegations_RemovesPrimaryIndexAndQueue(t *testing.T) // Idempotency: running again should not error. require.NoError(t, k.CompletePendingRedelegations(ctx)) } + +func TestSetPendingRedelegation_DistinctSourcesDoNotMerge(t *testing.T) { + ctx, k := newTestKeeper(t) + + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + srcA := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + srcB := sdk.ValAddress(bytes.Repeat([]byte{4}, 20)) + dstVal := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + denom := "stake" + completion := ctx.BlockTime().Add(time.Hour) + + entryA := types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcA.String(), + DstValidatorAddress: dstVal.String(), + Amount: sdk.NewCoin(denom, math.NewInt(10)), + CompletionTime: completion, + } + entryB := types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcB.String(), + DstValidatorAddress: dstVal.String(), + Amount: sdk.NewCoin(denom, math.NewInt(15)), + CompletionTime: completion, + } + require.NoError(t, k.SetPendingRedelegation(ctx, entryA)) + require.NoError(t, k.SetPendingRedelegation(ctx, entryB)) + + store := k.storeService.OpenKVStore(ctx) + keyA := types.GetPendingRedelegationKey(del, denom, srcA, dstVal, completion) + keyB := types.GetPendingRedelegationKey(del, denom, srcB, dstVal, completion) + + bzA, err := store.Get(keyA) + require.NoError(t, err) + require.NotNil(t, bzA) + + bzB, err := store.Get(keyB) + require.NoError(t, err) + require.NotNil(t, bzB) +} diff --git a/x/poolrebalancer/types/keys.go b/x/poolrebalancer/types/keys.go index 5605443a..50b504a9 100644 --- a/x/poolrebalancer/types/keys.go +++ b/x/poolrebalancer/types/keys.go @@ -24,7 +24,7 @@ var ( ParamsKey = []byte{0x01} // module params // Pending redelegation tracking. - // Primary key: (delegator, denom, dstValidator, completionTime) + // Primary key: (delegator, denom, dstValidator, srcValidator, completionTime) PendingRedelegationKey = []byte{0x11} // Index by source validator: (srcValidator, completionTime, denom, dstValidator, delegator) PendingRedelegationBySrcIndexKey = []byte{0x12} @@ -39,13 +39,14 @@ var ( ) // GetPendingRedelegationKey returns the primary key for a pending redelegation. -// Key format: prefix | lengthPrefixed(delegator) | lengthPrefixed(denom) | lengthPrefixed(dstValidator) | completionTime. -func GetPendingRedelegationKey(del sdk.AccAddress, denom string, dstVal sdk.ValAddress, completion time.Time) []byte { +// Key format: prefix | lengthPrefixed(delegator) | lengthPrefixed(denom) | lengthPrefixed(dstValidator) | lengthPrefixed(srcValidator) | completionTime. +func GetPendingRedelegationKey(del sdk.AccAddress, denom string, srcVal, dstVal sdk.ValAddress, completion time.Time) []byte { key := make([]byte, 0) key = append(key, PendingRedelegationKey...) key = append(key, address.MustLengthPrefix(del)...) key = append(key, address.MustLengthPrefix([]byte(denom))...) key = append(key, address.MustLengthPrefix(dstVal)...) + key = append(key, address.MustLengthPrefix(srcVal)...) key = append(key, sdk.FormatTimeBytes(completion)...) return key } From dfb875ef27ea1eee579f53da9114dfba49d4f657 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 1 Apr 2026 14:00:24 +0530 Subject: [PATCH 15/31] fix(poolrebalancer): return InvalidArgument for nil pending query requests --- x/poolrebalancer/keeper/grpc_query.go | 8 ++++++++ x/poolrebalancer/keeper/grpc_query_test.go | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/x/poolrebalancer/keeper/grpc_query.go b/x/poolrebalancer/keeper/grpc_query.go index f01da788..3aa58f9e 100644 --- a/x/poolrebalancer/keeper/grpc_query.go +++ b/x/poolrebalancer/keeper/grpc_query.go @@ -9,6 +9,8 @@ import ( "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/types/query" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var _ types.QueryServer = QueryServer{} @@ -33,6 +35,9 @@ func (qs QueryServer) PendingRedelegations( ctx context.Context, req *types.QueryPendingRedelegationsRequest, ) (*types.QueryPendingRedelegationsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } store := runtime.KVStoreAdapter(qs.k.storeService.OpenKVStore(ctx)) pstore := prefix.NewStore(store, types.PendingRedelegationKey) @@ -59,6 +64,9 @@ func (qs QueryServer) PendingUndelegations( ctx context.Context, req *types.QueryPendingUndelegationsRequest, ) (*types.QueryPendingUndelegationsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "empty request") + } // Paginate over queue keys (completionTime, delegator); each value is a batch of entries. store := runtime.KVStoreAdapter(qs.k.storeService.OpenKVStore(ctx)) pstore := prefix.NewStore(store, types.PendingUndelegationQueueKey) diff --git a/x/poolrebalancer/keeper/grpc_query_test.go b/x/poolrebalancer/keeper/grpc_query_test.go index befc6a7a..b7462732 100644 --- a/x/poolrebalancer/keeper/grpc_query_test.go +++ b/x/poolrebalancer/keeper/grpc_query_test.go @@ -10,6 +10,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkquery "github.com/cosmos/cosmos-sdk/types/query" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/cosmos/evm/x/poolrebalancer/types" ) @@ -93,3 +95,21 @@ func TestQueryPendingUndelegations_PaginatesByQueueBuckets(t *testing.T) { // multiple undelegation entries if the first queue bucket contains more than one entry. require.GreaterOrEqual(t, len(res.Undelegations), 2) } + +func TestQueryPendingRedelegations_NilRequest(t *testing.T) { + ctx, k := newTestKeeper(t) + qs := NewQueryServer(k) + + _, err := qs.PendingRedelegations(ctx, nil) + require.Error(t, err) + require.Equal(t, codes.InvalidArgument, status.Code(err)) +} + +func TestQueryPendingUndelegations_NilRequest(t *testing.T) { + ctx, k := newTestKeeper(t) + qs := NewQueryServer(k) + + _, err := qs.PendingUndelegations(ctx, nil) + require.Error(t, err) + require.Equal(t, codes.InvalidArgument, status.Code(err)) +} From c1fb504b3ab1212f53edc8ce59a688995b7f5327 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 1 Apr 2026 14:00:24 +0530 Subject: [PATCH 16/31] test(poolrebalancer): add convergence and broaden unit/integration coverage --- .../poolrebalancer/test_case_a_scheduling.go | 28 +++++ .../test_case_g_long_horizon_convergence.go | 114 ++++++++++++++++++ .../test_case_param_behavior.go | 59 +++++++++ x/poolrebalancer/genesis_test.go | 58 +++++++++ x/poolrebalancer/types/helpers_test.go | 53 ++++++++ 5 files changed, 312 insertions(+) create mode 100644 tests/integration/x/poolrebalancer/test_case_g_long_horizon_convergence.go create mode 100644 x/poolrebalancer/types/helpers_test.go diff --git a/tests/integration/x/poolrebalancer/test_case_a_scheduling.go b/tests/integration/x/poolrebalancer/test_case_a_scheduling.go index 45f0cff7..8fa5e18e 100644 --- a/tests/integration/x/poolrebalancer/test_case_a_scheduling.go +++ b/tests/integration/x/poolrebalancer/test_case_a_scheduling.go @@ -49,3 +49,31 @@ func (s *KeeperIntegrationTestSuite) TestSchedulingA_DriftCreatesPendingRedelega s.Require().GreaterOrEqual(len(pending), 1) } +// TestSchedulingA_ReducesSourceOverweightInStakingState verifies a successful scheduling +// pass reduces overweight stake on the drifted source validator in staking state. +func (s *KeeperIntegrationTestSuite) TestSchedulingA_ReducesSourceOverweightInStakingState() { + params := s.DefaultEnabledParams(0, 1, sdkmath.ZeroInt(), false) + s.EnableRebalancer(params) + + src := s.validators[0] + srcAddr := src.OperatorAddress + s.DelegateExtraToValidator(src) + + before, _, err := s.poolKeeper.GetDelegatorStakeByValidator(s.ctx, s.poolDel) + s.Require().NoError(err) + beforeSrc := before[srcAddr] + s.Require().True(beforeSrc.IsPositive(), "expected positive source stake before scheduling") + + s.Require().NoError(s.RunEndBlock()) + + after, _, err := s.poolKeeper.GetDelegatorStakeByValidator(s.ctx, s.poolDel) + s.Require().NoError(err) + afterSrc := after[srcAddr] + s.Require().True( + afterSrc.LT(beforeSrc), + "expected source stake to decrease after one rebalance op; before=%s after=%s", + beforeSrc.String(), + afterSrc.String(), + ) +} + diff --git a/tests/integration/x/poolrebalancer/test_case_g_long_horizon_convergence.go b/tests/integration/x/poolrebalancer/test_case_g_long_horizon_convergence.go new file mode 100644 index 00000000..73c94b9e --- /dev/null +++ b/tests/integration/x/poolrebalancer/test_case_g_long_horizon_convergence.go @@ -0,0 +1,114 @@ +package poolrebalancer + +import ( + "time" + + sdkmath "cosmossdk.io/math" +) + +// maxAbsDelta returns max(|delta|) across all validators. +func maxAbsDelta(deltas map[string]sdkmath.Int) sdkmath.Int { + max := sdkmath.ZeroInt() + for _, d := range deltas { + abs := d.Abs() + if abs.GT(max) { + max = abs + } + } + return max +} + +// TestLongHorizonConvergence_RedelegationOnly verifies that repeated EndBlock passes +// with periodic maturity windows reduce drift to a small tolerance using redelegations only. +func (s *KeeperIntegrationTestSuite) TestLongHorizonConvergence_RedelegationOnly() { + params := s.DefaultEnabledParams( + 0, // threshold: schedule on any drift + 1, // force gradual per-pass progress to exercise long-horizon behavior + sdkmath.NewInt(100000000000000000), // cap per-op movement to require multiple iterations + false, // redelegation-only mode + ) + s.EnableRebalancer(params) + + // Create deterministic overweight drift on one source validator. + src := s.validators[0] + s.DelegateExtraToValidator(src) + + const ( + maxIters = 60 + maturityJumpEvery = 5 + // Keep practical tolerance to absorb truncation/rounding residue. + convergenceTolerance = int64(10) + // Guard against vacuous success: start from a non-trivial drift. + minInitialDrift = int64(1000) + // Ensure this is a long-horizon behavior test, not a one-iteration pass. + minItersBeforeConverged = 3 + ) + tol := sdkmath.NewInt(convergenceTolerance) + minStart := sdkmath.NewInt(minInitialDrift) + + initialDeltas := s.ComputeCurrentDeltas() + initialMaxAbs := maxAbsDelta(initialDeltas) + s.Require().True(initialMaxAbs.IsPositive(), "expected initial non-zero drift") + s.Require().True( + initialMaxAbs.GTE(minStart), + "expected non-trivial initial drift; got %s want >= %s", + initialMaxAbs.String(), + minStart.String(), + ) + + converged := false + convergedAt := 0 + sawProgress := false + for i := 1; i <= maxIters; i++ { + s.Require().NoError(s.RunEndBlock()) + + // Periodically move past unbonding window so queued ops can mature and cleanup can proceed. + if i%maturityJumpEvery == 0 { + s.WithBlockTime(s.ctx.BlockTime().Add(s.unbondingSec + time.Second)) + } + + deltas := s.ComputeCurrentDeltas() + curMaxAbs := maxAbsDelta(deltas) + pendingRed := len(s.PendingRedelegations()) + pendingUnd := len(s.PendingUndelegations()) + s.T().Logf( + "convergence iter=%d maxAbsDelta=%s tol=%s pending(red=%d,und=%d)", + i, curMaxAbs.String(), tol.String(), pendingRed, pendingUnd, + ) + + if curMaxAbs.LT(initialMaxAbs) { + sawProgress = true + } + + if curMaxAbs.LTE(tol) { + converged = true + convergedAt = i + break + } + } + + s.Require().True( + converged, + "expected convergence within %d iterations (initial maxAbs=%s, tolerance=%s)", + maxIters, + initialMaxAbs.String(), + tol.String(), + ) + s.Require().GreaterOrEqual( + convergedAt, + minItersBeforeConverged, + "converged too quickly at iter=%d; expected long-horizon behavior (>= %d iters)", + convergedAt, + minItersBeforeConverged, + ) + s.Require().True( + sawProgress, + "expected at least one measurable improvement from initial maxAbsDelta=%s", + initialMaxAbs.String(), + ) + + // Final maturity pass to ensure no stale queue buildup remains. + s.WithBlockTime(s.ctx.BlockTime().Add(s.unbondingSec + time.Second)) + s.Require().NoError(s.RunEndBlock()) + s.Require().Empty(s.PendingUndelegations(), "undelegation queue should remain empty in redelegation-only mode") +} diff --git a/tests/integration/x/poolrebalancer/test_case_param_behavior.go b/tests/integration/x/poolrebalancer/test_case_param_behavior.go index 22b04837..8a98add3 100644 --- a/tests/integration/x/poolrebalancer/test_case_param_behavior.go +++ b/tests/integration/x/poolrebalancer/test_case_param_behavior.go @@ -4,7 +4,10 @@ import ( sdkmath "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/runtime" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkquery "github.com/cosmos/cosmos-sdk/types/query" + poolrebalancerkeeper "github.com/cosmos/evm/x/poolrebalancer/keeper" poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" ) @@ -98,3 +101,59 @@ func (s *KeeperIntegrationTestSuite) TestMaxTargetValidators_LimitsRedelegationD ) } } + +// TestPendingRedelegationsQuery_PaginatesAndReturnsEntries verifies the gRPC query server +// path returns pending entries with pagination in an integration environment. +func (s *KeeperIntegrationTestSuite) TestPendingRedelegationsQuery_PaginatesAndReturnsEntries() { + params := s.DefaultEnabledParams(0, 2, sdkmath.ZeroInt(), false) + s.EnableRebalancer(params) + + src := s.validators[0] + s.DelegateExtraToValidator(src) + s.Require().NoError(s.RunEndBlock()) + + qs := poolrebalancerkeeper.NewQueryServer(s.poolKeeper) + res, err := qs.PendingRedelegations(s.ctx, &poolrebalancertypes.QueryPendingRedelegationsRequest{ + Pagination: &sdkquery.PageRequest{Limit: 1}, + }) + s.Require().NoError(err) + s.Require().NotNil(res) + s.Require().NotEmpty(res.Redelegations, "expected paginated query to return at least one pending redelegation") + s.Require().NotNil(res.Pagination, "expected pagination response metadata") +} + +func (s *KeeperIntegrationTestSuite) TestPendingUndelegationsAndParamsQuery_IntegrationPaths() { + params := s.DefaultEnabledParams(0, 1, sdkmath.ZeroInt(), true) + s.EnableRebalancer(params) + + // Create fallback conditions: immature incoming redelegation to x blocks src=x use. + xVal := s.validators[0] + yVal := s.validators[1] + immatureCompletion := s.ctx.BlockTime().Add(s.unbondingSec).UTC() + s.SeedPendingRedelegation(poolrebalancertypes.PendingRedelegation{ + DelegatorAddress: s.poolDel.String(), + SrcValidatorAddress: yVal.OperatorAddress, + DstValidatorAddress: xVal.OperatorAddress, + Amount: sdk.NewCoin(s.bondDenom, sdkmath.OneInt()), + CompletionTime: immatureCompletion, + }) + s.DelegateExtraToValidator(xVal) + s.Require().NoError(s.RunEndBlock()) + + qs := poolrebalancerkeeper.NewQueryServer(s.poolKeeper) + + // Params query: verifies the client-facing params contract in integration. + pres, err := qs.Params(s.ctx, &poolrebalancertypes.QueryParamsRequest{}) + s.Require().NoError(err) + s.Require().Equal(uint32(1), pres.Params.MaxOpsPerBlock) + s.Require().True(pres.Params.UseUndelegateFallback) + + // PendingUndelegations query: verifies paginated decode path. + ures, err := qs.PendingUndelegations(s.ctx, &poolrebalancertypes.QueryPendingUndelegationsRequest{ + Pagination: &sdkquery.PageRequest{Limit: 1}, + }) + s.Require().NoError(err) + s.Require().NotNil(ures) + s.Require().NotEmpty(ures.Undelegations, "expected at least one pending undelegation from fallback path") + s.Require().NotNil(ures.Pagination, "expected pagination metadata") +} diff --git a/x/poolrebalancer/genesis_test.go b/x/poolrebalancer/genesis_test.go index a01bfa52..ff38c8eb 100644 --- a/x/poolrebalancer/genesis_test.go +++ b/x/poolrebalancer/genesis_test.go @@ -74,3 +74,61 @@ func TestGenesis_ExportsAndRestoresPendingState(t *testing.T) { require.Equal(t, exported.PendingRedelegations[0].DelegatorAddress, redels[0].DelegatorAddress) require.Equal(t, exported.PendingUndelegations[0].DelegatorAddress, undels[0].DelegatorAddress) } + +func TestGenesis_RoundTripPreservesDistinctRedelegationSources(t *testing.T) { + storeKey := storetypes.NewKVStoreKey(types.ModuleName) + tKey := storetypes.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey).WithBlockTime(time.Unix(3_000, 0)) + + storeService := runtime.NewKVStoreService(storeKey) + cdc := moduletestutil.MakeTestEncodingConfig().Codec + stakingK := &stakingkeeper.Keeper{} + authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) + k := keeper.NewKeeper(cdc, storeService, stakingK, authority) + + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + srcA := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + srcB := sdk.ValAddress(bytes.Repeat([]byte{4}, 20)) + dst := sdk.ValAddress(bytes.Repeat([]byte{3}, 20)) + completion := ctx.BlockTime().Add(time.Hour) + + require.NoError(t, k.SetPendingRedelegation(ctx, types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcA.String(), + DstValidatorAddress: dst.String(), + Amount: sdk.NewCoin("stake", math.NewInt(10)), + CompletionTime: completion, + })) + require.NoError(t, k.SetPendingRedelegation(ctx, types.PendingRedelegation{ + DelegatorAddress: del.String(), + SrcValidatorAddress: srcB.String(), + DstValidatorAddress: dst.String(), + Amount: sdk.NewCoin("stake", math.NewInt(15)), + CompletionTime: completion, + })) + + exported := ExportGenesis(ctx, k) + require.Len(t, exported.PendingRedelegations, 2) + + // Restore into a fresh store/keeper and ensure both source-specific entries survive. + storeKey2 := storetypes.NewKVStoreKey(types.ModuleName) + tKey2 := storetypes.NewTransientStoreKey("transient_test2") + ctx2 := testutil.DefaultContext(storeKey2, tKey2).WithBlockTime(time.Unix(3_000, 0)) + k2 := keeper.NewKeeper(cdc, runtime.NewKVStoreService(storeKey2), stakingK, authority) + InitGenesis(ctx2, k2, exported) + + redels, err := k2.GetAllPendingRedelegations(ctx2) + require.NoError(t, err) + require.Len(t, redels, 2) + + srcSet := map[string]struct{}{} + for _, e := range redels { + srcSet[e.SrcValidatorAddress] = struct{}{} + require.Equal(t, dst.String(), e.DstValidatorAddress) + require.Equal(t, completion.UTC(), e.CompletionTime.UTC()) + } + _, hasA := srcSet[srcA.String()] + _, hasB := srcSet[srcB.String()] + require.True(t, hasA) + require.True(t, hasB) +} diff --git a/x/poolrebalancer/types/helpers_test.go b/x/poolrebalancer/types/helpers_test.go new file mode 100644 index 00000000..43f6afa0 --- /dev/null +++ b/x/poolrebalancer/types/helpers_test.go @@ -0,0 +1,53 @@ +package types + +import ( + "testing" + + "cosmossdk.io/math" + "github.com/stretchr/testify/require" +) + +func TestParamsValidate_RejectsThresholdAbove10000(t *testing.T) { + p := DefaultParams() + p.RebalanceThresholdBp = 10001 + + err := p.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "rebalance_threshold_bp") +} + +func TestParamsValidate_RejectsNegativeMaxMovePerOp(t *testing.T) { + p := DefaultParams() + p.MaxMovePerOp = math.NewInt(-1) + + err := p.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "max_move_per_op") +} + +func TestParamsValidate_RejectsInvalidPoolDelegatorAddress(t *testing.T) { + p := DefaultParams() + p.PoolDelegatorAddress = "not-a-valid-bech32" + + err := p.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "pool_delegator_address") +} + +func TestParamsValidate_RejectsZeroMaxOpsPerBlock(t *testing.T) { + p := DefaultParams() + p.MaxOpsPerBlock = 0 + + err := p.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "max_ops_per_block") +} + +func TestParamsValidate_RejectsZeroMaxTargetValidators(t *testing.T) { + p := DefaultParams() + p.MaxTargetValidators = 0 + + err := p.Validate() + require.Error(t, err) + require.Contains(t, err.Error(), "max_target_validators") +} From ba39cc6ba6c7ae76518443dc843ffaaf792f1296 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Tue, 24 Mar 2026 13:41:40 +0530 Subject: [PATCH 17/31] feat(pool-contract): add community pool contract Signed-off-by: Nikhil Sharma --- contracts/solidity/pool/CommunityPool.sol | 320 ++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 contracts/solidity/pool/CommunityPool.sol diff --git a/contracts/solidity/pool/CommunityPool.sol b/contracts/solidity/pool/CommunityPool.sol new file mode 100644 index 00000000..414c275a --- /dev/null +++ b/contracts/solidity/pool/CommunityPool.sol @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity >=0.8.17; + +import "../precompiles/erc20/IERC20.sol"; +import "../precompiles/staking/StakingI.sol" as staking; +import "../precompiles/distribution/DistributionI.sol" as distribution; + +/// @title CommunityPool +/// @notice Pooled staking contract with internal ownership units. +/// @dev +/// - Users deposit `bondToken` and receive pool units (`unitsOf`) representing proportional ownership. +/// - Pool assets are tracked as: liquid token balance + `totalStaked` accounting value. +/// - `totalStaked` is accounting-only and can drift from real chain state (e.g. slashing), so +/// owner can reconcile it via `syncTotalStaked`. +/// - Withdrawals are liquid-only in this MVP: if liquid funds are insufficient, withdrawal reverts. +contract CommunityPool { + string private constant BONDED_STATUS = "BOND_STATUS_BONDED"; + + /// @dev Native token contract used for deposits/withdrawals. + IERC20 public immutable bondToken; + + address public owner; + /// @dev Total ownership units minted by the pool. + uint256 public totalUnits; + /// @dev Accounting value of delegated principal (not auto-reconciled with staking state). + uint256 public totalStaked; + uint32 public maxRetrieve; + uint32 public maxValidators; + uint256 public minStakeAmount; + + /// @dev Units held per user. User ownership fraction = unitsOf[user] / totalUnits. + mapping(address => uint256) public unitsOf; + + /// @dev Minimal reentrancy guard state (0=not entered, 1=entered). + uint256 private _entered; + + error Unauthorized(); + error InvalidAddress(); + error InvalidAmount(); + error InvalidUnits(); + error InvalidConfig(); + error NoValidators(); + error InsufficientLiquid(uint256 requested, uint256 available); + error TokenTransferFailed(); + error TokenTransferFromFailed(); + error DelegateFailed(string validator, uint256 amount); + error HarvestFailed(); + error ZeroMintedUnits(); + + event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + event ConfigUpdated(uint32 maxRetrieve, uint32 maxValidators, uint256 minStakeAmount); + event Deposit(address indexed user, uint256 amount, uint256 mintedUnits, uint256 totalUnitsAfter); + event Withdraw(address indexed user, uint256 burnedUnits, uint256 amountOut, uint256 totalUnitsAfter); + event StakeDelegated(string validator, uint256 amount); + event Stake(uint256 liquidBefore, uint256 delegatedAmount, uint256 validatorsCount, uint256 totalStakedAfter); + event Harvest(uint256 liquidBefore, uint256 liquidAfter, uint256 harvestedAmount); + event TotalStakedSynced(uint256 previousTotalStaked, uint256 newTotalStaked); + + modifier onlyOwner() { + if (msg.sender != owner) { + revert Unauthorized(); + } + _; + } + + modifier nonReentrant() { + require(_entered == 0, "reentrancy"); + _entered = 1; + _; + _entered = 0; + } + + constructor( + address bondToken_, + uint32 maxRetrieve_, + uint32 maxValidators_, + uint256 minStakeAmount_, + address owner_ + ) { + if (bondToken_ == address(0) || owner_ == address(0)) { + revert InvalidAddress(); + } + if (maxValidators_ == 0) { + revert InvalidConfig(); + } + + bondToken = IERC20(bondToken_); + maxRetrieve = maxRetrieve_; + maxValidators = maxValidators_; + minStakeAmount = minStakeAmount_; + owner = owner_; + } + + /// @notice Transfers owner privileges to a new address. + function transferOwnership(address newOwner) external onlyOwner { + if (newOwner == address(0)) { + revert InvalidAddress(); + } + + address previousOwner = owner; + owner = newOwner; + emit OwnershipTransferred(previousOwner, newOwner); + } + + /// @notice Updates operational parameters used by stake/harvest. + /// @param newMaxRetrieve Max validator rewards to claim per harvest call. + /// @param newMaxValidators Max bonded validators to target in one stake call. + /// @param newMinStakeAmount Minimum liquid threshold required to run `stake`. + function setConfig( + uint32 newMaxRetrieve, + uint32 newMaxValidators, + uint256 newMinStakeAmount + ) external onlyOwner { + if (newMaxValidators == 0) { + revert InvalidConfig(); + } + + maxRetrieve = newMaxRetrieve; + maxValidators = newMaxValidators; + minStakeAmount = newMinStakeAmount; + emit ConfigUpdated(newMaxRetrieve, newMaxValidators, newMinStakeAmount); + } + + /// @notice Manual reconciliation hook for staking accounting drift. + /// @dev Intended for operational correction after slashing/reconciliation. + function syncTotalStaked(uint256 newTotalStaked) external onlyOwner { + uint256 previous = totalStaked; + totalStaked = newTotalStaked; + emit TotalStakedSynced(previous, newTotalStaked); + } + + /// @notice Current liquid token balance owned by the contract. + function liquidBalance() public view returns (uint256) { + return bondToken.balanceOf(address(this)); + } + + /// @notice Total pool assets used for share pricing. + /// @dev This excludes unclaimed rewards until `harvest` is called. + function poolAssets() public view returns (uint256) { + return liquidBalance() + totalStaked; + } + + /// @notice Returns 1e18-scaled token value per ownership unit. + function pricePerUnit() external view returns (uint256) { + if (totalUnits == 0) { + return 1e18; + } + return (poolAssets() * 1e18) / totalUnits; + } + + /// @notice Deposits tokens and mints proportional pool units. + /// @dev + /// - First deposit mints 1:1 units. + /// - Later deposits mint: floor(amount * totalUnits / poolAssets). + /// - Floor rounding avoids over-minting; tiny deposits that would mint 0 units revert. + function deposit(uint256 amount) external nonReentrant returns (uint256 mintedUnits) { + if (amount == 0) { + revert InvalidAmount(); + } + + uint256 assetsBefore = poolAssets(); + if (totalUnits == 0 || assetsBefore == 0) { + mintedUnits = amount; + } else { + mintedUnits = (amount * totalUnits) / assetsBefore; + } + + if (mintedUnits == 0) { + revert ZeroMintedUnits(); + } + + if (!bondToken.transferFrom(msg.sender, address(this), amount)) { + revert TokenTransferFromFailed(); + } + + unitsOf[msg.sender] += mintedUnits; + totalUnits += mintedUnits; + + emit Deposit(msg.sender, amount, mintedUnits, totalUnits); + } + + /// @notice Burns user units and withdraws proportional assets from liquid balance. + /// @dev Reverts with `InsufficientLiquid` if the proportional claim exceeds liquid funds. + function withdraw(uint256 userUnits) external nonReentrant returns (uint256 amountOut) { + if (userUnits == 0) { + revert InvalidUnits(); + } + + uint256 userBalanceUnits = unitsOf[msg.sender]; + if (userUnits > userBalanceUnits || totalUnits == 0) { + revert InvalidUnits(); + } + + amountOut = (userUnits * poolAssets()) / totalUnits; + uint256 liquid = liquidBalance(); + if (amountOut > liquid) { + revert InsufficientLiquid(amountOut, liquid); + } + + unitsOf[msg.sender] = userBalanceUnits - userUnits; + totalUnits -= userUnits; + + if (!bondToken.transfer(msg.sender, amountOut)) { + revert TokenTransferFailed(); + } + + emit Withdraw(msg.sender, userUnits, amountOut, totalUnits); + } + + /// @notice Delegates available liquid to bonded validators discovered on-chain. + /// @dev + /// - Uses staking precompile `validators(BOND_STATUS_BONDED, pageRequest)`. + /// - Splits liquid evenly, and assigns remainder (+1) to first validators deterministically. + /// - Increases `totalStaked` by delegated amount as accounting update. + function stake() external nonReentrant returns (uint256 delegatedAmount) { + uint256 liquidBefore = liquidBalance(); + if (liquidBefore < minStakeAmount) { + return 0; + } + + string[] memory validators = _getBondedValidators(maxValidators); + uint256 validatorCount = validators.length; + uint256 perValidator = liquidBefore / validatorCount; + uint256 remainder = liquidBefore % validatorCount; + + for (uint256 i = 0; i < validatorCount; i++) { + uint256 amount = perValidator; + if (i < remainder) { + amount += 1; + } + if (amount == 0) { + continue; + } + + bool success = staking.STAKING_CONTRACT.delegate( + address(this), + validators[i], + amount + ); + if (!success) { + revert DelegateFailed(validators[i], amount); + } + + delegatedAmount += amount; + emit StakeDelegated(validators[i], amount); + } + + totalStaked += delegatedAmount; + emit Stake(liquidBefore, delegatedAmount, validatorCount, totalStaked); + } + + /// @notice Claims staking rewards to this contract's liquid balance. + /// @dev Does not modify `totalStaked` because rewards are liquid yield, not principal. + function harvest() external nonReentrant returns (uint256 harvestedAmount) { + uint256 liquidBefore = liquidBalance(); + bool success = distribution.DISTRIBUTION_CONTRACT.claimRewards( + address(this), + maxRetrieve + ); + if (!success) { + revert HarvestFailed(); + } + + uint256 liquidAfter = liquidBalance(); + harvestedAmount = liquidAfter > liquidBefore ? liquidAfter - liquidBefore : 0; + emit Harvest(liquidBefore, liquidAfter, harvestedAmount); + } + + /// @dev Reads bonded validators from staking precompile with pagination. + /// Stops when cap is reached or there is no next page. + function _getBondedValidators(uint32 cap) internal view returns (string[] memory out) { + if (cap == 0) { + revert InvalidConfig(); + } + + string[] memory tmp = new string[](cap); + uint256 count = 0; + bytes memory pageKey; + + while (count < cap) { + staking.PageRequest memory page = staking.PageRequest({ + key: pageKey, + offset: 0, + limit: uint64(cap - count), + countTotal: false, + reverse: false + }); + + ( + staking.Validator[] memory validatorsPage, + staking.PageResponse memory pageResponse + ) = staking.STAKING_CONTRACT.validators(BONDED_STATUS, page); + + uint256 pageLen = validatorsPage.length; + if (pageLen == 0) { + break; + } + + for (uint256 i = 0; i < pageLen && count < cap; i++) { + tmp[count] = validatorsPage[i].operatorAddress; + count++; + } + + if (pageResponse.nextKey.length == 0) { + break; + } + pageKey = pageResponse.nextKey; + } + + if (count == 0) { + revert NoValidators(); + } + + out = new string[](count); + for (uint256 i = 0; i < count; i++) { + out[i] = tmp[i]; + } + } +} + From cf5aa82840a7ab34d8bbcd068bb38692e7169668 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Thu, 26 Mar 2026 17:06:11 +0530 Subject: [PATCH 18/31] test(communitypool): add integration suite, harness, and contract artifact Signed-off-by: Nikhil Sharma --- contracts/community_pool.go | 12 + contracts/solidity/pool/CommunityPool.json | 658 ++++++++++++++++++ contracts/solidity/pool/CommunityPool.sol | 56 +- .../precompile_communitypool_test.go | 16 + .../communitypool/TEST_ASSUMPTIONS.md | 36 + .../communitypool/test_integration.go | 645 +++++++++++++++++ .../precompiles/communitypool/test_setup.go | 91 +++ .../precompiles/communitypool/test_utils.go | 123 ++++ 8 files changed, 1633 insertions(+), 4 deletions(-) create mode 100644 contracts/community_pool.go create mode 100644 contracts/solidity/pool/CommunityPool.json create mode 100644 evmd/tests/integration/precompiles/communitypool/precompile_communitypool_test.go create mode 100644 tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md create mode 100644 tests/integration/precompiles/communitypool/test_integration.go create mode 100644 tests/integration/precompiles/communitypool/test_setup.go create mode 100644 tests/integration/precompiles/communitypool/test_utils.go diff --git a/contracts/community_pool.go b/contracts/community_pool.go new file mode 100644 index 00000000..807509af --- /dev/null +++ b/contracts/community_pool.go @@ -0,0 +1,12 @@ +package contracts + +import ( + contractutils "github.com/cosmos/evm/contracts/utils" + evmtypes "github.com/cosmos/evm/x/vm/types" +) + +// LoadCommunityPool loads the compiled CommunityPool contract artifact. +func LoadCommunityPool() (evmtypes.CompiledContract, error) { + return contractutils.LoadContractFromJSONFile("solidity/pool/CommunityPool.json") +} + diff --git a/contracts/solidity/pool/CommunityPool.json b/contracts/solidity/pool/CommunityPool.json new file mode 100644 index 00000000..ff745b3c --- /dev/null +++ b/contracts/solidity/pool/CommunityPool.json @@ -0,0 +1,658 @@ +{ + "_format": "hh3-artifact-1", + "contractName": "CommunityPool", + "sourceName": "solidity/pool/CommunityPool.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "bondToken_", + "type": "address" + }, + { + "internalType": "uint32", + "name": "maxRetrieve_", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "maxValidators_", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "minStakeAmount_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "owner_", + "type": "address" + }, + { + "internalType": "string", + "name": "validatorPrefix_", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "validator", + "type": "string" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DelegateFailed", + "type": "error" + }, + { + "inputs": [], + "name": "HarvestFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "available", + "type": "uint256" + } + ], + "name": "InsufficientLiquid", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAddress", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidConfig", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidUnits", + "type": "error" + }, + { + "inputs": [], + "name": "NoValidators", + "type": "error" + }, + { + "inputs": [], + "name": "TokenTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "TokenTransferFromFailed", + "type": "error" + }, + { + "inputs": [], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroMintedUnits", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint32", + "name": "maxRetrieve", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "maxValidators", + "type": "uint32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "minStakeAmount", + "type": "uint256" + } + ], + "name": "ConfigUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintedUnits", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalUnitsAfter", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "liquidBefore", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "liquidAfter", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "harvestedAmount", + "type": "uint256" + } + ], + "name": "Harvest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "liquidBefore", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "delegatedAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "validatorsCount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalStakedAfter", + "type": "uint256" + } + ], + "name": "Stake", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "validator", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "StakeDelegated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "previousTotalStaked", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalStaked", + "type": "uint256" + } + ], + "name": "TotalStakedSynced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "previousPrefix", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "newPrefix", + "type": "string" + } + ], + "name": "ValidatorPrefixUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "burnedUnits", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalUnitsAfter", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [], + "name": "bondToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "mintedUnits", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "harvest", + "outputs": [ + { + "internalType": "uint256", + "name": "harvestedAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxRetrieve", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxValidators", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minStakeAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "poolAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pricePerUnit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "newMaxRetrieve", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "newMaxValidators", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "newMinStakeAmount", + "type": "uint256" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newPrefix", + "type": "string" + } + ], + "name": "setValidatorPrefix", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stake", + "outputs": [ + { + "internalType": "uint256", + "name": "delegatedAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newTotalStaked", + "type": "uint256" + } + ], + "name": "syncTotalStaked", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalStaked", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalUnits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "unitsOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "validatorPrefix", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "userUnits", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x604060a0815234620003015762001d7c803803806200001e8162000305565b92833981019060c08183031262000301576200003a816200032b565b9060206200004a81830162000340565b926200005886840162000340565b9060608401516200006c608086016200032b565b60a08601516001600160401b039691929187821162000301570196601f9489868a01121562000301578851888111620002ab57601f1999620000b48289018c168a0162000305565b9b828d52898383010111620003015788905f5b838110620002ec5750505f918c0101526001600160a01b0394851680158015620002e1575b620002d05763ffffffff9081831615620002bf578b5115620002bf57608052600380546001600160401b031916919093161790871b67ffffffff00000000161790556004555f80546001600160a01b031916929091169190911790558451928311620002ab576005948554926001938481811c91168015620002a0575b828210146200028c5783811162000246575b5080928511600114620001e15750839450908392915f94620001d5575b50501b915f199060031b1c19161790555b51611a29908162000353823960805181818161021f015281816103140152818161095d0152610d360152f35b015192505f8062000198565b929484908116875f52845f20945f905b888383106200022b575050501062000212575b505050811b019055620001a9565b01515f1960f88460031b161c191690555f808062000204565b858701518855909601959485019487935090810190620001f1565b875f52815f20848088018a1c82019284891062000282575b01891c019085905b828110620002765750506200017b565b5f815501859062000266565b925081926200025e565b634e487b7160e01b5f52602260045260245ffd5b90607f169062000169565b634e487b7160e01b5f52604160045260245ffd5b8c516306b7c75960e31b8152600490fd5b8b5163e6c4247b60e01b8152600490fd5b5085851615620000ec565b818101830151818f018401528a9201620000c7565b5f80fd5b6040519190601f01601f191682016001600160401b03811183821017620002ab57604052565b51906001600160a01b03821682036200030157565b519063ffffffff82168203620003015756fe6080604081815260049081361015610015575f80fd5b5f92833560e01c90816308ac525614610b6e575080630eccc70814610b345780631a0a253c14610a6c5780632e1a7d4d146108a35780633a4b66f11461086a5780634641257d14610741578063635bea2a146107215780636d86acc4146107025780637cbba4651461050f578063817b1cd2146104f05780638da5cb5b146104c8578063a8c7914714610459578063b6b55f2514610290578063b7ec1a3314610273578063bbe9a0701461024e578063c28f43921461020a578063cd61546a146101d5578063e66825c3146101ad578063f18876841461018f5763f2fde38b146100fd575f80fd5b3461018b57602036600319011261018b576001600160a01b03823581811693908490036101875784549182169283330361017b57841561016e5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b50903461018b578260031936011261018b5760209250549051908152f35b8382346101d157816003193601126101d1576020906101ca610dfc565b9051908152f35b5080fd5b8382346101d157816003193601126101d157610206906101f3610c1a565b9051918291602083526020830190610cf6565b0390f35b8382346101d157816003193601126101d157517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b8382346101d157816003193601126101d15760209063ffffffff600354169051908152f35b8382346101d157816003193601126101d1576020906101ca610d1b565b503461018b57602092836003193601126104565782356102b260075415610e44565b60016007558015610447576102d16102c8610d1b565b60025490610daa565b600154908115801561043f575b1561042757505080935b84156104195783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190811561040f5784916103d6575b50156103c8575033825260068552828220610368858254610daa565b90557f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e6103bc61039a86600154610daa565b6001819055855193845260208401879052604084015233929081906060820190565b0390a260075551908152f35b835163be24f3c560e01b8152fd5b90508681813d8311610408575b6103ed8183610bf9565b81010312610404576103fe90610e7d565b5f61034c565b8380fd5b503d6103e3565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6104346104399284610dcb565b610dde565b936102e8565b5080156102de565b50505163162908e360e11b8152fd5b80fd5b50903461018b57602036600319011261018b578254813591906001600160a01b031633036104bb5750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b8382346101d157816003193601126101d157905490516001600160a01b039091168152602090f35b8382346101d157816003193601126101d1576020906002549051908152f35b508290346101d15760208060031936011261018b576001600160401b039184358381116101875736602382011215610187578086013593841161018757602495368786840101116106fe5785546001600160a01b031633036104bb5784156106f0575061057a610c1a565b9360056105878154610b92565b601f81116106af575b5086601f83116001146106275797829182828a9b7f4e078e5553e283423298b75f183265474fa61da0c06cbd3508a8fbb983db7acd9b9261061a575b50508360011b905f198560031b1c19161790555b6105f38551978689978852870190610cf6565b938585038787015282855201858401378181018401879052601f01601f191601030190a180f35b870101359050828c6105cc565b81885285882090601f198416895b818110610696575091849391847f4e078e5553e283423298b75f183265474fa61da0c06cbd3508a8fbb983db7acd9b9c941061067b575b5050600183811b0190556105e0565b86018301355f19600386901b60f8161c191690558a8061066c565b919288600181928e878b01013581550194019201610635565b818852858820601f8401831c8101918785106106e6575b601f01831c01905b8181106106db5750610590565b8881556001016106ce565b90915081906106c6565b82516306b7c75960e31b8152fd5b8580fd5b8382346101d157816003193601126101d1576020906001549051908152f35b8382346101d157816003193601126101d1576020906101ca6102c8610d1b565b508290346101d157816003193601126101d15761076060075415610e44565b600160075561076d610d1b565b9163ffffffff60035416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610860578291610827575b501561081757602093507f4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721de6107db610d1b565b84811115610810576107ed8582610e8e565b945b8451908152602081019190915260408101859052606090a160075551908152f35b82946107ef565b8151630d599dd960e11b81528490fd5b90506020813d8211610858575b8161084160209383610bf9565b810103126101d15761085290610e7d565b856107a8565b3d9150610834565b83513d84823e3d90fd5b8382346101d157816003193601126101d1579060209161088c60075415610e44565b6001600755610899610f2f565b9160075551908152f35b503461018b57602092836003193601126104565782356108c560075415610e44565b6001806007558115610a5c573383526006865283832054948583118015610a53575b610a455761090a6109026108fc6102c8610d1b565b85610dcb565b835490610dde565b95610913610d1b565b808811610a2957508361092591610e8e565b338552600688528585205561093b838354610e8e565b8255845163a9059cbb60e01b81523382820152602481018790528781604481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610a1f5785916109ea575b50156109dc575054835191825260208201859052604082015233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949080606081016103bc565b845163022e258160e11b8152fd5b90508781813d8311610a18575b610a018183610bf9565b8101031261018757610a1290610e7d565b5f610995565b503d6109f7565b86513d87823e3d90fd5b82604491898951926382b3a56560e01b84528301526024820152fd5b8451630e433c2360e31b8152fd5b508154156108e7565b50505051630e433c2360e31b8152fd5b50903461018b57606036600319011261018b5780359163ffffffff9182841680940361018757602435928316908184036106fe57855460443594906001600160a01b03163303610b26578215610b17576003805467ffffffffffffffff19168717602092831b67ffffffff00000000161790559084905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b5082516306b7c75960e31b8152fd5b5082516282b42960e81b8152fd5b50903461018b57602036600319011261018b57356001600160a01b0381169081900361018b57828291602094526006845220549051908152f35b8490346101d157816003193601126101d15760209063ffffffff600354831c168152f35b90600182811c92168015610bc0575b6020831014610bac57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610ba1565b60a081019081106001600160401b03821117610be557604052565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b03821117610be557604052565b604051905f8260055491610c2d83610b92565b808352600193808516908115610cb45750600114610c55575b50610c5392500383610bf9565b565b60055f9081527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db094602093509091905b818310610c9c575050610c5393508201015f610c46565b85548884018501529485019487945091830191610c85565b9050610c5394506020925060ff191682840152151560051b8201015f610c46565b5f5b838110610ce65750505f910152565b8181015183820152602001610cd7565b90602091610d0f81518092818552858086019101610cd5565b601f01601f1916010190565b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610d9f575f91610d71575090565b906020823d8211610d97575b81610d8a60209383610bf9565b8101031261045657505190565b3d9150610d7d565b6040513d5f823e3d90fd5b91908201809211610db757565b634e487b7160e01b5f52601160045260245ffd5b81810292918115918404141715610db757565b8115610de8570490565b634e487b7160e01b5f52601260045260245ffd5b6001548015610e3757610e106102c8610d1b565b90670de0b6b3a764000091828102928184041490151715610db757610e3491610dde565b90565b50670de0b6b3a764000090565b15610e4b57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b51908115158203610e8a57565b5f80fd5b91908203918211610db757565b5f198114610db75760010190565b8051821015610ebd5760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b909291926001600160401b038111610be55760405191610efb601f8301601f191660200184610bf9565b829482845282820111610e8a576020610c53930190610cd5565b9080601f83011215610e8a578151610e3492602001610ed1565b5f90610f39610d1b565b600454811061197f5763ffffffff60035460201c16801561196d57610f5d8161199c565b905f9060605b818310611417575b5050801561140557610f7c8161199c565b915f5b8281106113d657505050805190610f968284610dde565b908215610de8575f5b838110610ff8575050507f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f691608091610fda86600254610daa565b908160025560405192835286602084015260408301526060820152a1565b829684860682106113c3575b87156113b8576110148284610ea9565b5190815191602a9283811490811591611395575b508015611342575b61130f57915f926002915b80831061126657505060408051633e562a6360e21b81526001600160a01b039094166004850152602484015250600580545f9184919061107a82610b92565b918260448501526001811690815f146112465750600114611206575b5050805f920381836104005af1918215610d9f575f926111c3575b506040516353266bbb60e01b815230600482015260606024820152602081806110dd6064820187610cf6565b8d604483015203815f6108005af1908115610d9f575f91611189575b501561115a5761114761115593926111328b7f9a4001bdb3452b060fc06c64fbf07b16cf6e9e5f5d67f9e7507331983d2de21894610daa565b9a604051928392604084526040840190610cf6565b9060208301520390a1610e9b565b610f9f565b60408051639f3289cf60e01b81526004810191909152808a61117f6044830186610cf6565b9060248301520390fd5b90506020813d6020116111bb575b816111a460209383610bf9565b81010312610e8a576111b590610e7d565b5f6110f9565b3d9150611197565b9091503d90815f823e6111d68282610bf9565b6020818381010312610e8a5780516001600160401b038111610e8a576111ff9282019101610f15565b905f6110b1565b915091505f528260205f20915f925b81841061122c5750508060645f9382010192611096565b805460648588010152602090930192859250600101611215565b9190505f9450839260649260ff1916838501521515901b82010192611096565b9091938251851015610ebd576020858401015160f81c603081101580611337575b156112bf57602f19019060ff8211610db75760ff6112b8925b60049290921b6010600160a01b031691161794610e9b565b919061103b565b60418110158061132c575b156112e757603619019060ff8211610db75760ff6112b8926112a0565b606181101580611321575b1561130f57605619019060ff8211610db75760ff6112b8926112a0565b60405163e6c4247b60e01b8152600490fd5b5060668111156112f2565b5060468111156112ca565b506039811115611287565b508051600190811015610ebd576021820180516001600160f81b0319908116600f60fb1b14159283611377575b505050611030565b9091925083511115610ebd57905116600b60fb1b14155f808061136f565b905015610ebd5760208101516001600160f81b031916600360fc1b14155f611028565b965061115590610e9b565b965060018301808411610db75796611004565b806113e46114009284610ea9565b516113ef8287610ea9565b526113fa8186610ea9565b50610e9b565b610f7f565b6040516313f8a3a760e31b8152600490fd5b92936001600160401b0361143084849894999599610e8e565b166040519461143e86610bca565b85525f602086015260408501525f60608501525f6080850152604051604081018181106001600160401b03821117610be5575f916114bb9160405260128152711093d39117d4d510551554d7d093d391115160721b6020820152604051968792839263186b216760e01b8452604060048501526044840190610cf6565b6003198382030160248401526080806114dd845160a0855260a0850190610cf6565b936001600160401b0360208201511660208501526001600160401b0360408201511660408501526060810151151560608501520151151591015203816108005afa8015610d9f575f945f916115aa575b50845196871561159b575f985b888a1080611592575b1561157c57611570611576916115598c8a610ea9565b5151611565828c610ea9565b526113fa818b610ea9565b99610e9b565b9861153a565b94985092965090949350518051610f6357610f6b565b50818110611543565b50509392819550959195610f6b565b9450503d805f863e6115bc8186610bf9565b6040858281010312610e8a578451906001600160401b038211610e8a57808601601f838801011215610e8a5781860151916115f683611985565b926116046040519485610bf9565b8084526020840183890160208360051b858c01010111610e8a576020838a0101905b60208360051b858c01010182106116ca575050505060208601516001600160401b038111610e8a5786016040818389010312610e8a5760405196604088018881106001600160401b03821117610be55760405281516001600160401b038111610e8a578201838201601f82011215610e8a5780516020946116aa9301918501610ed1565b875201516001600160401b0381168103610e8a576020860152935f61152d565b81516001600160401b038111610e8a57610160858c018201878d0103601f190112610e8a5760405191826101608101106001600160401b0361016085011117610be557602082878e6101608701604052010101516001600160401b038111610e8a5782878e61174760409460208d84019186868601010101610f15565b8752010101516001600160401b038111610e8a5782878e61177660809460208d84019186868601010101610f15565b602088015261178b6060848484010101610e7d565b6040880152010101516004811015610e8a5760608401528b8601820160a081810151608086015260c08201519085015260e00151906001600160401b038211610e8a5760a0878e0184018301898f0103601f190112610e8a578c93602083858a604051986117f88a610bca565b01010101516001600160401b038111610e8a57838f8a8161182b6040958f6020908c960191878787870101010101610f15565b8a5201010101516001600160401b038111610e8a57838f8a816118606060958f6020908c960191878787870101010101610f15565b60208b015201010101516001600160401b038111610e8a57838f8a816118986080958f6020908c960191878787870101010101610f15565b60408b015201010101516001600160401b038111610e8a57838f8a816118d060a0958f6020908c960191878787870101010101610f15565b60608b01520101010151946001600160401b038611610e8a576101608f91956020979661190e8c8a8f9a819b9a86839c8a01948a0101010101610f15565b608082015260c08501528a6101009361192c858484840101016119e5565b60e087015261012094611944868585850101016119e5565b908701526101409485848484010101519087015201010151908201528152019201919050611626565b6040516306b7c75960e31b8152600490fd5b505f9150565b6001600160401b038111610be55760051b60200190565b906119a682611985565b6119b36040519182610bf9565b82815280926119c4601f1991611985565b01905f5b8281106119d457505050565b8060606020809385010152016119c8565b51908160070b8203610e8a5756fea26469706673582212203d49af80e36bb94f2c2371d94c17db456854f54ebdbaa3bf92732408776f654364736f6c63430008140033", + "deployedBytecode": "0x6080604081815260049081361015610015575f80fd5b5f92833560e01c90816308ac525614610b6e575080630eccc70814610b345780631a0a253c14610a6c5780632e1a7d4d146108a35780633a4b66f11461086a5780634641257d14610741578063635bea2a146107215780636d86acc4146107025780637cbba4651461050f578063817b1cd2146104f05780638da5cb5b146104c8578063a8c7914714610459578063b6b55f2514610290578063b7ec1a3314610273578063bbe9a0701461024e578063c28f43921461020a578063cd61546a146101d5578063e66825c3146101ad578063f18876841461018f5763f2fde38b146100fd575f80fd5b3461018b57602036600319011261018b576001600160a01b03823581811693908490036101875784549182169283330361017b57841561016e5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b50903461018b578260031936011261018b5760209250549051908152f35b8382346101d157816003193601126101d1576020906101ca610dfc565b9051908152f35b5080fd5b8382346101d157816003193601126101d157610206906101f3610c1a565b9051918291602083526020830190610cf6565b0390f35b8382346101d157816003193601126101d157517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b8382346101d157816003193601126101d15760209063ffffffff600354169051908152f35b8382346101d157816003193601126101d1576020906101ca610d1b565b503461018b57602092836003193601126104565782356102b260075415610e44565b60016007558015610447576102d16102c8610d1b565b60025490610daa565b600154908115801561043f575b1561042757505080935b84156104195783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190811561040f5784916103d6575b50156103c8575033825260068552828220610368858254610daa565b90557f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e6103bc61039a86600154610daa565b6001819055855193845260208401879052604084015233929081906060820190565b0390a260075551908152f35b835163be24f3c560e01b8152fd5b90508681813d8311610408575b6103ed8183610bf9565b81010312610404576103fe90610e7d565b5f61034c565b8380fd5b503d6103e3565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6104346104399284610dcb565b610dde565b936102e8565b5080156102de565b50505163162908e360e11b8152fd5b80fd5b50903461018b57602036600319011261018b578254813591906001600160a01b031633036104bb5750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b8382346101d157816003193601126101d157905490516001600160a01b039091168152602090f35b8382346101d157816003193601126101d1576020906002549051908152f35b508290346101d15760208060031936011261018b576001600160401b039184358381116101875736602382011215610187578086013593841161018757602495368786840101116106fe5785546001600160a01b031633036104bb5784156106f0575061057a610c1a565b9360056105878154610b92565b601f81116106af575b5086601f83116001146106275797829182828a9b7f4e078e5553e283423298b75f183265474fa61da0c06cbd3508a8fbb983db7acd9b9261061a575b50508360011b905f198560031b1c19161790555b6105f38551978689978852870190610cf6565b938585038787015282855201858401378181018401879052601f01601f191601030190a180f35b870101359050828c6105cc565b81885285882090601f198416895b818110610696575091849391847f4e078e5553e283423298b75f183265474fa61da0c06cbd3508a8fbb983db7acd9b9c941061067b575b5050600183811b0190556105e0565b86018301355f19600386901b60f8161c191690558a8061066c565b919288600181928e878b01013581550194019201610635565b818852858820601f8401831c8101918785106106e6575b601f01831c01905b8181106106db5750610590565b8881556001016106ce565b90915081906106c6565b82516306b7c75960e31b8152fd5b8580fd5b8382346101d157816003193601126101d1576020906001549051908152f35b8382346101d157816003193601126101d1576020906101ca6102c8610d1b565b508290346101d157816003193601126101d15761076060075415610e44565b600160075561076d610d1b565b9163ffffffff60035416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610860578291610827575b501561081757602093507f4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721de6107db610d1b565b84811115610810576107ed8582610e8e565b945b8451908152602081019190915260408101859052606090a160075551908152f35b82946107ef565b8151630d599dd960e11b81528490fd5b90506020813d8211610858575b8161084160209383610bf9565b810103126101d15761085290610e7d565b856107a8565b3d9150610834565b83513d84823e3d90fd5b8382346101d157816003193601126101d1579060209161088c60075415610e44565b6001600755610899610f2f565b9160075551908152f35b503461018b57602092836003193601126104565782356108c560075415610e44565b6001806007558115610a5c573383526006865283832054948583118015610a53575b610a455761090a6109026108fc6102c8610d1b565b85610dcb565b835490610dde565b95610913610d1b565b808811610a2957508361092591610e8e565b338552600688528585205561093b838354610e8e565b8255845163a9059cbb60e01b81523382820152602481018790528781604481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610a1f5785916109ea575b50156109dc575054835191825260208201859052604082015233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949080606081016103bc565b845163022e258160e11b8152fd5b90508781813d8311610a18575b610a018183610bf9565b8101031261018757610a1290610e7d565b5f610995565b503d6109f7565b86513d87823e3d90fd5b82604491898951926382b3a56560e01b84528301526024820152fd5b8451630e433c2360e31b8152fd5b508154156108e7565b50505051630e433c2360e31b8152fd5b50903461018b57606036600319011261018b5780359163ffffffff9182841680940361018757602435928316908184036106fe57855460443594906001600160a01b03163303610b26578215610b17576003805467ffffffffffffffff19168717602092831b67ffffffff00000000161790559084905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b5082516306b7c75960e31b8152fd5b5082516282b42960e81b8152fd5b50903461018b57602036600319011261018b57356001600160a01b0381169081900361018b57828291602094526006845220549051908152f35b8490346101d157816003193601126101d15760209063ffffffff600354831c168152f35b90600182811c92168015610bc0575b6020831014610bac57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610ba1565b60a081019081106001600160401b03821117610be557604052565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b03821117610be557604052565b604051905f8260055491610c2d83610b92565b808352600193808516908115610cb45750600114610c55575b50610c5392500383610bf9565b565b60055f9081527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db094602093509091905b818310610c9c575050610c5393508201015f610c46565b85548884018501529485019487945091830191610c85565b9050610c5394506020925060ff191682840152151560051b8201015f610c46565b5f5b838110610ce65750505f910152565b8181015183820152602001610cd7565b90602091610d0f81518092818552858086019101610cd5565b601f01601f1916010190565b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610d9f575f91610d71575090565b906020823d8211610d97575b81610d8a60209383610bf9565b8101031261045657505190565b3d9150610d7d565b6040513d5f823e3d90fd5b91908201809211610db757565b634e487b7160e01b5f52601160045260245ffd5b81810292918115918404141715610db757565b8115610de8570490565b634e487b7160e01b5f52601260045260245ffd5b6001548015610e3757610e106102c8610d1b565b90670de0b6b3a764000091828102928184041490151715610db757610e3491610dde565b90565b50670de0b6b3a764000090565b15610e4b57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b51908115158203610e8a57565b5f80fd5b91908203918211610db757565b5f198114610db75760010190565b8051821015610ebd5760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b909291926001600160401b038111610be55760405191610efb601f8301601f191660200184610bf9565b829482845282820111610e8a576020610c53930190610cd5565b9080601f83011215610e8a578151610e3492602001610ed1565b5f90610f39610d1b565b600454811061197f5763ffffffff60035460201c16801561196d57610f5d8161199c565b905f9060605b818310611417575b5050801561140557610f7c8161199c565b915f5b8281106113d657505050805190610f968284610dde565b908215610de8575f5b838110610ff8575050507f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f691608091610fda86600254610daa565b908160025560405192835286602084015260408301526060820152a1565b829684860682106113c3575b87156113b8576110148284610ea9565b5190815191602a9283811490811591611395575b508015611342575b61130f57915f926002915b80831061126657505060408051633e562a6360e21b81526001600160a01b039094166004850152602484015250600580545f9184919061107a82610b92565b918260448501526001811690815f146112465750600114611206575b5050805f920381836104005af1918215610d9f575f926111c3575b506040516353266bbb60e01b815230600482015260606024820152602081806110dd6064820187610cf6565b8d604483015203815f6108005af1908115610d9f575f91611189575b501561115a5761114761115593926111328b7f9a4001bdb3452b060fc06c64fbf07b16cf6e9e5f5d67f9e7507331983d2de21894610daa565b9a604051928392604084526040840190610cf6565b9060208301520390a1610e9b565b610f9f565b60408051639f3289cf60e01b81526004810191909152808a61117f6044830186610cf6565b9060248301520390fd5b90506020813d6020116111bb575b816111a460209383610bf9565b81010312610e8a576111b590610e7d565b5f6110f9565b3d9150611197565b9091503d90815f823e6111d68282610bf9565b6020818381010312610e8a5780516001600160401b038111610e8a576111ff9282019101610f15565b905f6110b1565b915091505f528260205f20915f925b81841061122c5750508060645f9382010192611096565b805460648588010152602090930192859250600101611215565b9190505f9450839260649260ff1916838501521515901b82010192611096565b9091938251851015610ebd576020858401015160f81c603081101580611337575b156112bf57602f19019060ff8211610db75760ff6112b8925b60049290921b6010600160a01b031691161794610e9b565b919061103b565b60418110158061132c575b156112e757603619019060ff8211610db75760ff6112b8926112a0565b606181101580611321575b1561130f57605619019060ff8211610db75760ff6112b8926112a0565b60405163e6c4247b60e01b8152600490fd5b5060668111156112f2565b5060468111156112ca565b506039811115611287565b508051600190811015610ebd576021820180516001600160f81b0319908116600f60fb1b14159283611377575b505050611030565b9091925083511115610ebd57905116600b60fb1b14155f808061136f565b905015610ebd5760208101516001600160f81b031916600360fc1b14155f611028565b965061115590610e9b565b965060018301808411610db75796611004565b806113e46114009284610ea9565b516113ef8287610ea9565b526113fa8186610ea9565b50610e9b565b610f7f565b6040516313f8a3a760e31b8152600490fd5b92936001600160401b0361143084849894999599610e8e565b166040519461143e86610bca565b85525f602086015260408501525f60608501525f6080850152604051604081018181106001600160401b03821117610be5575f916114bb9160405260128152711093d39117d4d510551554d7d093d391115160721b6020820152604051968792839263186b216760e01b8452604060048501526044840190610cf6565b6003198382030160248401526080806114dd845160a0855260a0850190610cf6565b936001600160401b0360208201511660208501526001600160401b0360408201511660408501526060810151151560608501520151151591015203816108005afa8015610d9f575f945f916115aa575b50845196871561159b575f985b888a1080611592575b1561157c57611570611576916115598c8a610ea9565b5151611565828c610ea9565b526113fa818b610ea9565b99610e9b565b9861153a565b94985092965090949350518051610f6357610f6b565b50818110611543565b50509392819550959195610f6b565b9450503d805f863e6115bc8186610bf9565b6040858281010312610e8a578451906001600160401b038211610e8a57808601601f838801011215610e8a5781860151916115f683611985565b926116046040519485610bf9565b8084526020840183890160208360051b858c01010111610e8a576020838a0101905b60208360051b858c01010182106116ca575050505060208601516001600160401b038111610e8a5786016040818389010312610e8a5760405196604088018881106001600160401b03821117610be55760405281516001600160401b038111610e8a578201838201601f82011215610e8a5780516020946116aa9301918501610ed1565b875201516001600160401b0381168103610e8a576020860152935f61152d565b81516001600160401b038111610e8a57610160858c018201878d0103601f190112610e8a5760405191826101608101106001600160401b0361016085011117610be557602082878e6101608701604052010101516001600160401b038111610e8a5782878e61174760409460208d84019186868601010101610f15565b8752010101516001600160401b038111610e8a5782878e61177660809460208d84019186868601010101610f15565b602088015261178b6060848484010101610e7d565b6040880152010101516004811015610e8a5760608401528b8601820160a081810151608086015260c08201519085015260e00151906001600160401b038211610e8a5760a0878e0184018301898f0103601f190112610e8a578c93602083858a604051986117f88a610bca565b01010101516001600160401b038111610e8a57838f8a8161182b6040958f6020908c960191878787870101010101610f15565b8a5201010101516001600160401b038111610e8a57838f8a816118606060958f6020908c960191878787870101010101610f15565b60208b015201010101516001600160401b038111610e8a57838f8a816118986080958f6020908c960191878787870101010101610f15565b60408b015201010101516001600160401b038111610e8a57838f8a816118d060a0958f6020908c960191878787870101010101610f15565b60608b01520101010151946001600160401b038611610e8a576101608f91956020979661190e8c8a8f9a819b9a86839c8a01948a0101010101610f15565b608082015260c08501528a6101009361192c858484840101016119e5565b60e087015261012094611944868585850101016119e5565b908701526101409485848484010101519087015201010151908201528152019201919050611626565b6040516306b7c75960e31b8152600490fd5b505f9150565b6001600160401b038111610be55760051b60200190565b906119a682611985565b6119b36040519182610bf9565b82815280926119c4601f1991611985565b01905f5b8281106119d457505050565b8060606020809385010152016119c8565b51908160070b8203610e8a5756fea26469706673582212203d49af80e36bb94f2c2371d94c17db456854f54ebdbaa3bf92732408776f654364736f6c63430008140033", + "linkReferences": {}, + "deployedLinkReferences": {}, + "immutableReferences": { + "13": [ + { + "length": 32, + "start": 543 + }, + { + "length": 32, + "start": 788 + }, + { + "length": 32, + "start": 2397 + }, + { + "length": 32, + "start": 3382 + } + ] + }, + "inputSourceName": "project/solidity/pool/CommunityPool.sol", + "buildInfoId": "solc-0_8_20-764ee487806caff476736ab9b208906c0233ec72" +} \ No newline at end of file diff --git a/contracts/solidity/pool/CommunityPool.sol b/contracts/solidity/pool/CommunityPool.sol index 414c275a..06c2a754 100644 --- a/contracts/solidity/pool/CommunityPool.sol +++ b/contracts/solidity/pool/CommunityPool.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.17; import "../precompiles/erc20/IERC20.sol"; import "../precompiles/staking/StakingI.sol" as staking; import "../precompiles/distribution/DistributionI.sol" as distribution; +import "../precompiles/bech32/Bech32I.sol"; /// @title CommunityPool /// @notice Pooled staking contract with internal ownership units. @@ -27,6 +28,7 @@ contract CommunityPool { uint32 public maxRetrieve; uint32 public maxValidators; uint256 public minStakeAmount; + string public validatorPrefix; /// @dev Units held per user. User ownership fraction = unitsOf[user] / totalUnits. mapping(address => uint256) public unitsOf; @@ -55,6 +57,7 @@ contract CommunityPool { event Stake(uint256 liquidBefore, uint256 delegatedAmount, uint256 validatorsCount, uint256 totalStakedAfter); event Harvest(uint256 liquidBefore, uint256 liquidAfter, uint256 harvestedAmount); event TotalStakedSynced(uint256 previousTotalStaked, uint256 newTotalStaked); + event ValidatorPrefixUpdated(string previousPrefix, string newPrefix); modifier onlyOwner() { if (msg.sender != owner) { @@ -75,7 +78,8 @@ contract CommunityPool { uint32 maxRetrieve_, uint32 maxValidators_, uint256 minStakeAmount_, - address owner_ + address owner_, + string memory validatorPrefix_ ) { if (bondToken_ == address(0) || owner_ == address(0)) { revert InvalidAddress(); @@ -83,12 +87,16 @@ contract CommunityPool { if (maxValidators_ == 0) { revert InvalidConfig(); } + if (bytes(validatorPrefix_).length == 0) { + revert InvalidConfig(); + } bondToken = IERC20(bondToken_); maxRetrieve = maxRetrieve_; maxValidators = maxValidators_; minStakeAmount = minStakeAmount_; owner = owner_; + validatorPrefix = validatorPrefix_; } /// @notice Transfers owner privileges to a new address. @@ -129,6 +137,16 @@ contract CommunityPool { emit TotalStakedSynced(previous, newTotalStaked); } + /// @notice Updates the validator bech32 prefix used by stake conversion. + function setValidatorPrefix(string calldata newPrefix) external onlyOwner { + if (bytes(newPrefix).length == 0) { + revert InvalidConfig(); + } + string memory previous = validatorPrefix; + validatorPrefix = newPrefix; + emit ValidatorPrefixUpdated(previous, newPrefix); + } + /// @notice Current liquid token balance owned by the contract. function liquidBalance() public view returns (uint256) { return bondToken.balanceOf(address(this)); @@ -232,17 +250,23 @@ contract CommunityPool { continue; } + address validatorHex = _parseHexAddress(validators[i]); + string memory validatorBech32 = BECH32_CONTRACT.hexToBech32( + validatorHex, + validatorPrefix + ); + bool success = staking.STAKING_CONTRACT.delegate( address(this), - validators[i], + validatorBech32, amount ); if (!success) { - revert DelegateFailed(validators[i], amount); + revert DelegateFailed(validatorBech32, amount); } delegatedAmount += amount; - emit StakeDelegated(validators[i], amount); + emit StakeDelegated(validatorBech32, amount); } totalStaked += delegatedAmount; @@ -316,5 +340,29 @@ contract CommunityPool { out[i] = tmp[i]; } } + + function _parseHexAddress(string memory value) internal pure returns (address out) { + bytes memory str = bytes(value); + if (str.length != 42 || str[0] != "0" || (str[1] != "x" && str[1] != "X")) { + revert InvalidAddress(); + } + + uint160 result = 0; + for (uint256 i = 2; i < 42; i++) { + uint8 c = uint8(str[i]); + uint8 nibble; + if (c >= 48 && c <= 57) { + nibble = c - 48; + } else if (c >= 65 && c <= 70) { + nibble = c - 55; + } else if (c >= 97 && c <= 102) { + nibble = c - 87; + } else { + revert InvalidAddress(); + } + result = (result << 4) | uint160(nibble); + } + out = address(result); + } } diff --git a/evmd/tests/integration/precompiles/communitypool/precompile_communitypool_test.go b/evmd/tests/integration/precompiles/communitypool/precompile_communitypool_test.go new file mode 100644 index 00000000..c687cf64 --- /dev/null +++ b/evmd/tests/integration/precompiles/communitypool/precompile_communitypool_test.go @@ -0,0 +1,16 @@ +package communitypool + +import ( + "testing" + + evm "github.com/cosmos/evm" + "github.com/cosmos/evm/evmd/tests/integration" + communitypooltests "github.com/cosmos/evm/tests/integration/precompiles/communitypool" + testapp "github.com/cosmos/evm/testutil/app" +) + +func TestCommunityPoolPrecompileIntegrationTestSuite(t *testing.T) { + create := testapp.ToEvmAppCreator[evm.Erc20IntegrationApp](integration.CreateEvmd, "evm.Erc20IntegrationApp") + communitypooltests.TestCommunityPoolIntegrationSuite(t, create) +} + diff --git a/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md b/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md new file mode 100644 index 00000000..3fbd8ca6 --- /dev/null +++ b/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md @@ -0,0 +1,36 @@ +# CommunityPool Integration Test Assumptions + +This document captures assumptions that the `communitypool` integration suite depends on for deterministic behavior. + +## Environment assumptions + +- The suite runs against the standard integration test network created by `network.NewUnitTestNetwork`. +- The chain has a valid staking bond denom and an ERC20 token pair for that denom. +- At least one active validator exists in the network validator set. + +## Contract + artifact assumptions + +- `contracts/solidity/pool/CommunityPool.json` matches the current `CommunityPool.sol` implementation. +- The artifact includes the owner-only `setStakeValidators(string[])` method used by staking/harvest tests. +- `contracts/community_pool.go` successfully loads that artifact via `LoadCommunityPool()`. + +## Test helper assumptions + +- Read-only contract checks use `QueryContract(...)` (not tx execution), so nonce state is not mutated by view calls. +- Successful tx helper (`execTxExpectSuccess`) sets a default gas limit when none is provided, to avoid estimator/limit edge cases in precompile-heavy paths (for example, `harvest`). +- Tests commit blocks (`network.NextBlock()`) between state-changing calls that require finalized state for subsequent reads/assertions. + +## Behavioral assumptions under test + +- Deposit/withdraw accounting uses floor rounding and must never over-mint shares. +- Dust deposits that mint zero units must revert and preserve unit state. +- Owner-gated methods (`setConfig`, `syncTotalStaked`, `transferOwnership`, `setStakeValidators`) enforce access control. +- `stake()` and `harvest()` are callable in the current implementation and are tested as operational actions, not owner-only actions. +- `stake()` uses configured bech32 validator operator addresses set through `setStakeValidators`. +- `syncTotalStaked` is accounting-only and must not create staking side effects. + +## Stability notes + +- If staking precompile output format for validators changes (for example, address encoding), staking-path tests may fail and need contract or test adaptation. +- If default gas behavior changes in factory or precompiles, tx helper gas defaults may need adjustment. +- If ownership/permissions policy changes (for example, restricting `stake`/`harvest`), tests must be updated to reflect the new access model. diff --git a/tests/integration/precompiles/communitypool/test_integration.go b/tests/integration/precompiles/communitypool/test_integration.go new file mode 100644 index 00000000..e8c7b116 --- /dev/null +++ b/tests/integration/precompiles/communitypool/test_integration.go @@ -0,0 +1,645 @@ +package communitypool + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + + //nolint:revive // dot imports are fine for Ginkgo + . "github.com/onsi/ginkgo/v2" + //nolint:revive // dot imports are fine for Ginkgo + . "github.com/onsi/gomega" + + "github.com/cosmos/evm/precompiles/testutil" + "github.com/cosmos/evm/testutil/integration/evm/network" + testutiltypes "github.com/cosmos/evm/testutil/types" + evmtypes "github.com/cosmos/evm/x/vm/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// TestCommunityPoolIntegrationSuite scaffolds the CommunityPool integration suite. +// Detailed behavior scenarios are implemented in subsequent test steps. +func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp, options ...network.ConfigOption) { + _ = Describe("CommunityPool integration scaffold", func() { + var s *IntegrationTestSuite + var err error + + BeforeEach(func() { + s = NewIntegrationTestSuite(create, options...) + s.SetupTest() + }) + + It("sets up suite dependencies for CommunityPool tests", func() { + Expect(s.network).ToNot(BeNil()) + Expect(s.factory).ToNot(BeNil()) + Expect(s.grpcHandler).ToNot(BeNil()) + Expect(s.keyring).ToNot(BeNil()) + Expect(s.bondDenom).ToNot(BeEmpty()) + Expect(s.bondTokenAddr).ToNot(Equal([20]byte{})) + Expect(s.communityPoolContract.Bin).ToNot(BeEmpty()) + }) + + It("rejects constructor with invalid maxValidators", func() { + owner := s.keyring.GetKey(0) + _, err := s.factory.DeployContract( + owner.Priv, + evmtypes.EvmTxArgs{}, + testutiltypes.ContractDeploymentData{ + Contract: s.communityPoolContract, + ConstructorArgs: []interface{}{ + s.bondTokenAddr, + uint32(10), + uint32(0), // invalid + big.NewInt(1), + owner.Addr, + }, + }, + ) + Expect(err).To(HaveOccurred()) + }) + + It("reverts on deposit(0)", func() { + owner := s.keyring.GetKey(0) + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + + txArgs := buildTxArgs(poolAddr) + callArgs := buildCallArgs(s.communityPoolContract, "deposit", big.NewInt(0)) + check := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) + _, _, err := s.factory.CallContractAndCheckLogs(owner.Priv, txArgs, callArgs, check) + Expect(err).To(BeNil()) + }) + + It("mints 1:1 units on first deposit", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + depositor := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + depositor.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + userUnits := s.queryPoolUint(1, poolAddr, "unitsOf", depositor.Addr) + totalUnits := s.queryPoolUint(1, poolAddr, "totalUnits") + Expect(userUnits.String()).To(Equal(depositAmount.String())) + Expect(totalUnits.String()).To(Equal(depositAmount.String())) + }) + + It("mints proportional units on subsequent deposit", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + user1 := s.keyring.GetKey(1) + user2 := s.keyring.GetKey(2) + + firstDeposit := big.NewInt(1000) + secondDeposit := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, firstDeposit) + s.approveBondToken(2, poolAddr, secondDeposit) + + s.execTxExpectSuccess( + user1.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", firstDeposit), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(1000)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user2.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", secondDeposit), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + user2Units := s.queryPoolUint(2, poolAddr, "unitsOf", user2.Addr) + totalUnits := s.queryPoolUint(0, poolAddr, "totalUnits") + Expect(user2Units.String()).To(Equal("500")) + Expect(totalUnits.String()).To(Equal("1500")) + }) + + It("withdraws successfully when enough liquid is available", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + + depositAmount := big.NewInt(1000) + withdrawUnits := big.NewInt(400) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", withdrawUnits), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + remainingUnits := s.queryPoolUint(1, poolAddr, "unitsOf", user.Addr) + totalUnits := s.queryPoolUint(1, poolAddr, "totalUnits") + Expect(remainingUnits.String()).To(Equal("600")) + Expect(totalUnits.String()).To(Equal("600")) + }) + + It("reverts withdraw when proportional claim exceeds liquid balance", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + user := s.keyring.GetKey(1) + + depositAmount := big.NewInt(1000) + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + // Inflate accounting assets without adding liquid balance. + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(1000)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + check := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) + _, _, err = s.factory.CallContractAndCheckLogs( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", big.NewInt(1000)), + check, + ) + Expect(err).To(BeNil()) + }) + + It("returns expected pricePerUnit for empty and adjusted pool", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + user := s.keyring.GetKey(1) + + // Empty pool price is defined as 1e18. + emptyPPU := s.queryPoolUint(0, poolAddr, "pricePerUnit") + Expect(emptyPPU.String()).To(Equal("1000000000000000000")) + + amount := big.NewInt(1000) + s.approveBondToken(1, poolAddr, amount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", amount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + // poolAssets=2000, totalUnits=1000 => pricePerUnit=2e18. + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(1000)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + updatedPPU := s.queryPoolUint(0, poolAddr, "pricePerUnit") + Expect(updatedPPU.String()).To(Equal("2000000000000000000")) + }) + + It("restricts owner-only methods to owner account", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + nonOwner := s.keyring.GetKey(1) + + revertCheck := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) + + _, _, err := s.factory.CallContractAndCheckLogs( + nonOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setConfig", uint32(20), uint32(7), big.NewInt(2)), + revertCheck, + ) + Expect(err).To(BeNil()) + + _, _, err = s.factory.CallContractAndCheckLogs( + nonOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(123)), + revertCheck, + ) + Expect(err).To(BeNil()) + + _, _, err = s.factory.CallContractAndCheckLogs( + nonOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "transferOwnership", nonOwner.Addr), + revertCheck, + ) + Expect(err).To(BeNil()) + + // Owner can still execute privileged actions. + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setConfig", uint32(20), uint32(7), big.NewInt(2)), + ) + }) + + It("reverts dust deposit that would mint zero units", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + user1 := s.keyring.GetKey(1) + user2 := s.keyring.GetKey(2) + + s.approveBondToken(1, poolAddr, big.NewInt(1000)) + s.approveBondToken(2, poolAddr, big.NewInt(1)) + + s.execTxExpectSuccess( + user1.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", big.NewInt(1000)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + // Inflate asset accounting so a 1-token deposit maps to 0 units: + // minted = floor(1 * 1000 / 2000) = 0. + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(1000)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + beforeUser2Units := s.queryPoolUint(2, poolAddr, "unitsOf", user2.Addr) + beforeTotalUnits := s.queryPoolUint(2, poolAddr, "totalUnits") + + _, _, err = s.factory.CallContractAndCheckLogs( + user2.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", big.NewInt(1)), + testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()), + ) + Expect(err).To(BeNil()) + + afterUser2Units := s.queryPoolUint(2, poolAddr, "unitsOf", user2.Addr) + afterTotalUnits := s.queryPoolUint(2, poolAddr, "totalUnits") + Expect(afterUser2Units.String()).To(Equal(beforeUser2Units.String())) + Expect(afterTotalUnits.String()).To(Equal(beforeTotalUnits.String())) + }) + + It("transfers ownership and updates privileged access", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + oldOwner := s.keyring.GetKey(0) + newOwner := s.keyring.GetKey(1) + + s.execTxExpectSuccess( + oldOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "transferOwnership", newOwner.Addr), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + revertCheck := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) + + // Old owner should now be blocked. + _, _, err = s.factory.CallContractAndCheckLogs( + oldOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setConfig", uint32(99), uint32(9), big.NewInt(3)), + revertCheck, + ) + Expect(err).To(BeNil()) + + // New owner should now be allowed. + s.execTxExpectSuccess( + newOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setConfig", uint32(99), uint32(9), big.NewInt(3)), + ) + }) + + It("rejects transferOwnership to zero address", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + + zeroAddr := common.Address{} + _, _, err := s.factory.CallContractAndCheckLogs( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "transferOwnership", zeroAddr), + testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()), + ) + Expect(err).To(BeNil()) + }) + + It("allows owner to call all privileged methods", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setConfig", uint32(11), uint32(6), big.NewInt(2)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(321)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + maxValidators := s.queryPoolUint(0, poolAddr, "maxValidators") + totalStaked := s.queryPoolUint(0, poolAddr, "totalStaked") + Expect(maxValidators.String()).To(Equal("6")) + Expect(totalStaked.String()).To(Equal("321")) + }) + + It("blocks old owner from syncTotalStaked after ownership transfer", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + oldOwner := s.keyring.GetKey(0) + newOwner := s.keyring.GetKey(1) + + s.execTxExpectSuccess( + oldOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "transferOwnership", newOwner.Addr), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + revertCheck := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) + + _, _, err = s.factory.CallContractAndCheckLogs( + oldOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(500)), + revertCheck, + ) + Expect(err).To(BeNil()) + + s.execTxExpectSuccess( + newOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(500)), + ) + }) + + It("keeps unit state unchanged when withdraw reverts on insufficient liquid", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + user := s.keyring.GetKey(1) + + amount := big.NewInt(1000) + s.approveBondToken(1, poolAddr, amount) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", amount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(1000)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + beforeUserUnits := s.queryPoolUint(1, poolAddr, "unitsOf", user.Addr) + beforeTotalUnits := s.queryPoolUint(1, poolAddr, "totalUnits") + + _, _, err = s.factory.CallContractAndCheckLogs( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", amount), + testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()), + ) + Expect(err).To(BeNil()) + + afterUserUnits := s.queryPoolUint(1, poolAddr, "unitsOf", user.Addr) + afterTotalUnits := s.queryPoolUint(1, poolAddr, "totalUnits") + Expect(afterUserUnits.String()).To(Equal(beforeUserUnits.String())) + Expect(afterTotalUnits.String()).To(Equal(beforeTotalUnits.String())) + }) + + It("stake is a no-op when liquid is below minStakeAmount", func() { + // minStakeAmount is intentionally set above deposit. + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(2000)) + user := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + totalStaked := s.queryPoolUint(1, poolAddr, "totalStaked") + Expect(totalStaked.Sign()).To(Equal(0)) + }) + + It("stake delegates liquid and updates totalStaked accounting", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + totalStaked := s.queryPoolUint(1, poolAddr, "totalStaked") + Expect(totalStaked.String()).To(Equal(depositAmount.String())) + }) + + It("stake creates on-chain delegation for pool contract delegator", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + firstVal := s.network.GetValidators()[0].OperatorAddress + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + poolDelegator := sdk.AccAddress(poolAddr.Bytes()).String() + delRes, err := s.grpcHandler.GetDelegation(poolDelegator, firstVal) + Expect(err).To(BeNil()) + Expect(delRes).ToNot(BeNil()) + Expect(delRes.DelegationResponse).ToNot(BeNil()) + Expect(delRes.DelegationResponse.Balance.Amount.IsPositive()).To(BeTrue()) + }) + + It("harvest executes successfully after staking", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "harvest"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + }) + + It("harvest does not modify totalStaked accounting", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + beforeTotalStaked := s.queryPoolUint(1, poolAddr, "totalStaked") + beforeLiquid := s.queryPoolUint(1, poolAddr, "liquidBalance") + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "harvest"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + afterTotalStaked := s.queryPoolUint(1, poolAddr, "totalStaked") + afterLiquid := s.queryPoolUint(1, poolAddr, "liquidBalance") + + // Core invariant: harvest only affects liquid rewards, not delegated principal accounting. + Expect(afterTotalStaked.String()).To(Equal(beforeTotalStaked.String())) + // In no-reward conditions this can stay equal; with rewards it should increase. + Expect(afterLiquid.Cmp(beforeLiquid)).To(BeNumerically(">=", 0)) + }) + + It("syncTotalStaked updates accounting views (poolAssets and pricePerUnit)", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + user := s.keyring.GetKey(1) + + depositAmount := big.NewInt(1000) + s.approveBondToken(1, poolAddr, depositAmount) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + beforeAssets := s.queryPoolUint(0, poolAddr, "poolAssets") + beforePPU := s.queryPoolUint(0, poolAddr, "pricePerUnit") + + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(1000)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + afterAssets := s.queryPoolUint(0, poolAddr, "poolAssets") + afterPPU := s.queryPoolUint(0, poolAddr, "pricePerUnit") + + Expect(beforeAssets.String()).To(Equal("1000")) + Expect(beforePPU.String()).To(Equal("1000000000000000000")) + Expect(afterAssets.String()).To(Equal("2000")) + Expect(afterPPU.String()).To(Equal("2000000000000000000")) + }) + + It("syncTotalStaked does not create staking delegation side effects", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + + poolDelegator := sdk.AccAddress(poolAddr.Bytes()).String() + firstVal := s.network.GetValidators()[0].OperatorAddress + + _, err := s.grpcHandler.GetDelegation(poolDelegator, firstVal) + Expect(err).ToNot(BeNil(), "expected no delegation before any staking action") + + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(999)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + _, err = s.grpcHandler.GetDelegation(poolDelegator, firstVal) + Expect(err).ToNot(BeNil(), "syncTotalStaked must not create staking delegation") + }) + }) + + RegisterFailHandler(Fail) + RunSpecs(t, "CommunityPool Integration Suite") +} + diff --git a/tests/integration/precompiles/communitypool/test_setup.go b/tests/integration/precompiles/communitypool/test_setup.go new file mode 100644 index 00000000..14cdd7c8 --- /dev/null +++ b/tests/integration/precompiles/communitypool/test_setup.go @@ -0,0 +1,91 @@ +package communitypool + +import ( + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/suite" + . "github.com/onsi/gomega" + + compiledcontracts "github.com/cosmos/evm/contracts" + "github.com/cosmos/evm/precompiles/erc20" + "github.com/cosmos/evm/testutil/integration/evm/factory" + "github.com/cosmos/evm/testutil/integration/evm/grpc" + "github.com/cosmos/evm/testutil/integration/evm/network" + "github.com/cosmos/evm/testutil/integration/evm/utils" + testkeyring "github.com/cosmos/evm/testutil/keyring" + evmtypes "github.com/cosmos/evm/x/vm/types" +) + +// IntegrationTestSuite contains shared setup/state for CommunityPool integration tests. +type IntegrationTestSuite struct { + suite.Suite + + create network.CreateEvmApp + options []network.ConfigOption + + network *network.UnitTestNetwork + factory factory.TxFactory + grpcHandler grpc.Handler + keyring testkeyring.Keyring + + bondDenom string + bondTokenAddr common.Address + bondTokenPC *erc20.Precompile + validatorPrefix string + + communityPoolContract evmtypes.CompiledContract +} + +func NewIntegrationTestSuite(create network.CreateEvmApp, options ...network.ConfigOption) *IntegrationTestSuite { + return &IntegrationTestSuite{ + create: create, + options: options, + } +} + +func (s *IntegrationTestSuite) SetupTest() { + keys := testkeyring.New(3) + genesis := utils.CreateGenesisWithTokenPairs(keys) + + opts := []network.ConfigOption{ + network.WithPreFundedAccounts(keys.GetAllAccAddrs()...), + network.WithCustomGenesis(genesis), + } + opts = append(opts, s.options...) + + nw := network.NewUnitTestNetwork(s.create, opts...) + gh := grpc.NewIntegrationHandler(nw) + tf := factory.New(nw, gh) + + ctx := nw.GetContext() + sk := nw.App.GetStakingKeeper() + bondDenom, err := sk.BondDenom(ctx) + Expect(err).To(BeNil(), "failed to get bond denom") + Expect(bondDenom).ToNot(BeEmpty(), "bond denom cannot be empty") + + tokenPairID := nw.App.GetErc20Keeper().GetTokenPairID(ctx, bondDenom) + tokenPair, found := nw.App.GetErc20Keeper().GetTokenPair(ctx, tokenPairID) + Expect(found).To(BeTrue(), "failed to find token pair for bond denom") + bondTokenPC := erc20.NewPrecompile( + tokenPair, + nw.App.GetBankKeeper(), + nw.App.GetErc20Keeper(), + nw.App.GetTransferKeeper(), + ) + + poolContract, err := compiledcontracts.LoadCommunityPool() + Expect(err).To(BeNil(), "failed to load CommunityPool compiled contract") + + s.network = nw + s.factory = tf + s.grpcHandler = gh + s.keyring = keys + s.bondDenom = bondDenom + s.bondTokenAddr = tokenPair.GetERC20Contract() + s.bondTokenPC = bondTokenPC + firstVal := nw.GetValidators()[0].OperatorAddress + s.validatorPrefix = strings.Split(firstVal, "1")[0] + s.communityPoolContract = poolContract +} + diff --git a/tests/integration/precompiles/communitypool/test_utils.go b/tests/integration/precompiles/communitypool/test_utils.go new file mode 100644 index 00000000..b1cc304f --- /dev/null +++ b/tests/integration/precompiles/communitypool/test_utils.go @@ -0,0 +1,123 @@ +package communitypool + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + . "github.com/onsi/gomega" + + "github.com/cosmos/evm/precompiles/erc20" + testutiltypes "github.com/cosmos/evm/testutil/types" + evmtypes "github.com/cosmos/evm/x/vm/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" +) + +// deployCommunityPool deploys CommunityPool with deterministic defaults used in tests. +func (s *IntegrationTestSuite) deployCommunityPool( + ownerIdx int, + maxRetrieve uint32, + maxValidators uint32, + minStakeAmount *big.Int, +) common.Address { + owner := s.keyring.GetKey(ownerIdx) + addr, err := s.factory.DeployContract( + owner.Priv, + evmtypes.EvmTxArgs{}, + testutiltypes.ContractDeploymentData{ + Contract: s.communityPoolContract, + ConstructorArgs: []interface{}{ + s.bondTokenAddr, + maxRetrieve, + maxValidators, + minStakeAmount, + owner.Addr, + s.validatorPrefix, + }, + }, + ) + Expect(err).To(BeNil(), "failed to deploy CommunityPool") + Expect(s.network.NextBlock()).To(BeNil(), "failed to commit deployment block") + return addr +} + +func buildCallArgs(contract evmtypes.CompiledContract, method string, args ...interface{}) testutiltypes.CallArgs { + return testutiltypes.CallArgs{ + ContractABI: contract.ABI, + MethodName: method, + Args: args, + } +} + +func buildTxArgs(contractAddr common.Address) evmtypes.EvmTxArgs { + return evmtypes.EvmTxArgs{ + To: &contractAddr, + } +} + +func (s *IntegrationTestSuite) approveBondToken( + ownerIdx int, + spender common.Address, + amount *big.Int, +) { + owner := s.keyring.GetKey(ownerIdx) + txArgs := buildTxArgs(s.bondTokenAddr) + callArgs := testutiltypes.CallArgs{ + ContractABI: s.bondTokenPC.ABI, + MethodName: erc20.ApproveMethod, + Args: []interface{}{spender, amount}, + } + + s.execTxExpectSuccess(owner.Priv, txArgs, callArgs) + Expect(s.network.NextBlock()).To(BeNil(), "failed to commit approve tx") +} + +func (s *IntegrationTestSuite) queryPoolUint( + callerIdx int, + contractAddr common.Address, + method string, + args ...interface{}, +) *big.Int { + _ = callerIdx + txArgs := buildTxArgs(contractAddr) + callArgs := buildCallArgs(s.communityPoolContract, method, args...) + + ethRes, err := s.factory.QueryContract(txArgs, callArgs, 0) + Expect(err).To(BeNil(), "query call failed") + + out, err := s.communityPoolContract.ABI.Unpack(method, ethRes.Ret) + Expect(err).To(BeNil(), "failed to unpack query output") + Expect(out).ToNot(BeEmpty(), "empty query output") + + switch value := out[0].(type) { + case *big.Int: + return value + case uint8: + return new(big.Int).SetUint64(uint64(value)) + case uint16: + return new(big.Int).SetUint64(uint64(value)) + case uint32: + return new(big.Int).SetUint64(uint64(value)) + case uint64: + return new(big.Int).SetUint64(value) + default: + Expect(false).To(BeTrue(), "unexpected query output type") + return nil + } +} + +func (s *IntegrationTestSuite) execTxExpectSuccess( + priv cryptotypes.PrivKey, + txArgs evmtypes.EvmTxArgs, + callArgs testutiltypes.CallArgs, +) { + if txArgs.GasLimit == 0 { + txArgs.GasLimit = 2_000_000 + } + res, err := s.factory.ExecuteContractCall(priv, txArgs, callArgs) + Expect(err).To(BeNil(), "expected tx execution success") + + ethRes, err := evmtypes.DecodeTxResponse(res.Data) + Expect(err).To(BeNil(), "failed to decode ethereum tx response") + Expect(ethRes.VmError).To(BeEmpty(), "unexpected EVM execution revert") +} + From a30f5c1cef101c83b9f15850e9422c5bf271fb5c Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Thu, 26 Mar 2026 17:06:46 +0530 Subject: [PATCH 19/31] feat(staking-precompile): add delegateToBondedValidators tx and integration coverage Signed-off-by: Nikhil Sharma --- .../solidity/precompiles/staking/StakingI.sol | 12 ++ precompiles/staking/abi.json | 34 ++++ precompiles/staking/staking.go | 4 + precompiles/staking/tx.go | 101 +++++++++++ precompiles/staking/types.go | 43 +++++ .../precompiles/staking/test_integration.go | 168 ++++++++++++++++++ 6 files changed, 362 insertions(+) diff --git a/contracts/solidity/precompiles/staking/StakingI.sol b/contracts/solidity/precompiles/staking/StakingI.sol index 3c55d0d9..03ae3c35 100644 --- a/contracts/solidity/precompiles/staking/StakingI.sol +++ b/contracts/solidity/precompiles/staking/StakingI.sol @@ -174,6 +174,18 @@ interface StakingI { uint256 amount ) external returns (bool success); + /// @dev Defines a method for delegating a total amount across bonded validators equally. + /// @param delegatorAddress The address of the delegator. + /// @param amount The total amount of bond denomination to delegate. + /// @param maxValidators Max bonded validators to include (first N in precompile order). + /// @return delegatedAmount The total amount actually delegated. + /// @return validatorsUsed Number of validators used for the split. + function delegateToBondedValidators( + address delegatorAddress, + uint256 amount, + uint32 maxValidators + ) external returns (uint256 delegatedAmount, uint32 validatorsUsed); + /// @dev Defines a method for performing an undelegation from a delegate and a validator. /// @param delegatorAddress The address of the delegator /// @param validatorAddress The address of the validator diff --git a/precompiles/staking/abi.json b/precompiles/staking/abi.json index 7871943d..0df77bea 100644 --- a/precompiles/staking/abi.json +++ b/precompiles/staking/abi.json @@ -295,6 +295,40 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatorAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "maxValidators", + "type": "uint32" + } + ], + "name": "delegateToBondedValidators", + "outputs": [ + { + "internalType": "uint256", + "name": "delegatedAmount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "validatorsUsed", + "type": "uint32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/precompiles/staking/staking.go b/precompiles/staking/staking.go index 624fafab..3a1283e7 100644 --- a/precompiles/staking/staking.go +++ b/precompiles/staking/staking.go @@ -114,6 +114,8 @@ func (p Precompile) Execute(ctx sdk.Context, stateDB vm.StateDB, contract *vm.Co bz, err = p.EditValidator(ctx, contract, stateDB, method, args) case DelegateMethod: bz, err = p.Delegate(ctx, contract, stateDB, method, args) + case DelegateToBondedValidatorsMethod: + bz, err = p.DelegateToBondedValidators(ctx, contract, stateDB, method, args) case UndelegateMethod: bz, err = p.Undelegate(ctx, contract, stateDB, method, args) case RedelegateMethod: @@ -146,6 +148,7 @@ func (p Precompile) Execute(ctx sdk.Context, stateDB vm.StateDB, contract *vm.Co // - CreateValidator // - EditValidator // - Delegate +// - DelegateToBondedValidators // - Undelegate // - Redelegate // - CancelUnbondingDelegation @@ -154,6 +157,7 @@ func (Precompile) IsTransaction(method *abi.Method) bool { case CreateValidatorMethod, EditValidatorMethod, DelegateMethod, + DelegateToBondedValidatorsMethod, UndelegateMethod, RedelegateMethod, CancelUnbondingDelegationMethod: diff --git a/precompiles/staking/tx.go b/precompiles/staking/tx.go index 6ab7996e..f48a80a7 100644 --- a/precompiles/staking/tx.go +++ b/precompiles/staking/tx.go @@ -3,6 +3,7 @@ package staking import ( "errors" "fmt" + "math/big" "github.com/ethereum/go-ethereum/accounts/abi" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -10,7 +11,11 @@ import ( cmn "github.com/cosmos/evm/precompiles/common" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" ) const ( @@ -21,6 +26,9 @@ const ( // DelegateMethod defines the ABI method name for the staking Delegate // transaction. DelegateMethod = "delegate" + // DelegateToBondedValidatorsMethod defines the ABI method name for delegating + // equally across the bonded validator set in a single transaction. + DelegateToBondedValidatorsMethod = "delegateToBondedValidators" // UndelegateMethod defines the ABI method name for the staking Undelegate // transaction. UndelegateMethod = "undelegate" @@ -185,6 +193,99 @@ func (p *Precompile) Delegate( return method.Outputs.Pack(true) } +// DelegateToBondedValidators delegates equally across bonded validators. +func (p *Precompile) DelegateToBondedValidators( + ctx sdk.Context, + contract *vm.Contract, + stateDB vm.StateDB, + method *abi.Method, + args []interface{}, +) ([]byte, error) { + input, err := NewDelegateToBondedValidatorsArgs(args) + if err != nil { + return nil, err + } + + msgSender := contract.Caller() + if msgSender != input.DelegatorAddress { + return nil, fmt.Errorf(cmn.ErrRequesterIsNotMsgSender, msgSender.String(), input.DelegatorAddress.String()) + } + + bondDenom, err := p.stakingKeeper.BondDenom(ctx) + if err != nil { + return nil, err + } + + res, err := p.stakingQuerier.Validators(ctx, &stakingtypes.QueryValidatorsRequest{ + Status: stakingtypes.BondStatusBonded, + Pagination: &query.PageRequest{ + Limit: uint64(input.MaxValidators), + }, + }) + if err != nil { + return nil, err + } + if len(res.Validators) == 0 { + return nil, errors.New("no bonded validators found") + } + + delegatorAddrStr, err := p.addrCdc.BytesToString(input.DelegatorAddress.Bytes()) + if err != nil { + return nil, fmt.Errorf("failed to decode delegator address: %w", err) + } + + validatorCount := uint32(len(res.Validators)) + baseAmount := new(big.Int).Div(input.Amount, big.NewInt(int64(validatorCount))) + remainder := new(big.Int).Mod(input.Amount, big.NewInt(int64(validatorCount))).Uint64() + + totalDelegated := big.NewInt(0) + validatorsUsed := uint32(0) + for i := uint32(0); i < validatorCount; i++ { + perValidator := new(big.Int).Set(baseAmount) + if uint64(i) < remainder { + perValidator = perValidator.Add(perValidator, big.NewInt(1)) + } + // Skip zero-amount delegates (e.g. amount < validatorCount). + if perValidator.Sign() == 0 { + continue + } + + msg := &stakingtypes.MsgDelegate{ + DelegatorAddress: delegatorAddrStr, + ValidatorAddress: res.Validators[i].OperatorAddress, + Amount: sdk.Coin{ + Denom: bondDenom, + Amount: math.NewIntFromBigInt(perValidator), + }, + } + + if _, err = p.stakingMsgServer.Delegate(ctx, msg); err != nil { + return nil, err + } + if err = p.EmitDelegateEvent(ctx, stateDB, msg, input.DelegatorAddress); err != nil { + return nil, err + } + + totalDelegated.Add(totalDelegated, perValidator) + validatorsUsed++ + } + + p.Logger(ctx).Debug( + "tx called", + "method", method.Name, + "args", fmt.Sprintf( + "{ delegator_address: %s, amount: %s, max_validators: %d, delegated_amount: %s, validators_used: %d }", + input.DelegatorAddress, + input.Amount, + input.MaxValidators, + totalDelegated, + validatorsUsed, + ), + ) + + return method.Outputs.Pack(totalDelegated, validatorsUsed) +} + // Undelegate performs the undelegation of coins from a validator for a delegate. // The provided amount cannot be negative. This is validated in the msg.ValidateBasic() function. func (p Precompile) Undelegate( diff --git a/precompiles/staking/types.go b/precompiles/staking/types.go index 7c8baae5..88db9e5b 100644 --- a/precompiles/staking/types.go +++ b/precompiles/staking/types.go @@ -76,6 +76,14 @@ type EventCancelUnbonding struct { CreationHeight *big.Int } +// DelegateToBondedValidatorsArgs is the parsed input for delegating across +// bonded validators. +type DelegateToBondedValidatorsArgs struct { + DelegatorAddress common.Address + Amount *big.Int + MaxValidators uint32 +} + // Description defines a validator description. type Description = struct { Moniker string `json:"moniker"` @@ -376,6 +384,41 @@ func NewMsgCancelUnbondingDelegation(args []interface{}, denom string, addrCdc a return msg, delegatorAddr, nil } +// NewDelegateToBondedValidatorsArgs validates and parses arguments for the +// delegateToBondedValidators transaction. +func NewDelegateToBondedValidatorsArgs(args []interface{}) (*DelegateToBondedValidatorsArgs, error) { + if len(args) != 3 { + return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 3, len(args)) + } + + delegatorAddr, ok := args[0].(common.Address) + if !ok || delegatorAddr == (common.Address{}) { + return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) + } + + amount, ok := args[1].(*big.Int) + if !ok { + return nil, fmt.Errorf(cmn.ErrInvalidAmount, args[1]) + } + if amount.Sign() <= 0 { + return nil, errors.New("amount must be greater than zero") + } + + maxValidators, ok := args[2].(uint32) + if !ok { + return nil, fmt.Errorf(cmn.ErrInvalidType, "maxValidators", "uint32", args[2]) + } + if maxValidators == 0 { + return nil, errors.New("maxValidators must be greater than zero") + } + + return &DelegateToBondedValidatorsArgs{ + DelegatorAddress: delegatorAddr, + Amount: amount, + MaxValidators: maxValidators, + }, nil +} + // NewDelegationRequest creates a new QueryDelegationRequest instance and does sanity checks // on the given arguments before populating the request. func NewDelegationRequest(args []interface{}, addrCdc address.Codec) (*stakingtypes.QueryDelegationRequest, error) { diff --git a/tests/integration/precompiles/staking/test_integration.go b/tests/integration/precompiles/staking/test_integration.go index 085a8852..e0473dcd 100644 --- a/tests/integration/precompiles/staking/test_integration.go +++ b/tests/integration/precompiles/staking/test_integration.go @@ -546,6 +546,174 @@ func TestPrecompileIntegrationTestSuite(t *testing.T, create network.CreateEvmAp }) }) + Describe("to delegate equally to bonded validators", func() { + BeforeEach(func() { + callArgs.MethodName = staking.DelegateToBondedValidatorsMethod + }) + + It("should delegate with equal split and deterministic remainder", func() { + newAddr, newAddrPriv := testutiltx.NewAccAddressAndKey() + err := utils.FundAccountWithBaseDenom(s.factory, s.network, s.keyring.GetKey(0), newAddr, math.NewInt(2e18)) + Expect(err).To(BeNil(), "error while funding account") + Expect(s.network.NextBlock()).To(BeNil()) + + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + big.NewInt(5), + uint32(2), + } + logCheckArgs := passCheck.WithExpEvents(staking.EventTypeDelegate, staking.EventTypeDelegate) + + _, ethRes, err := s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + logCheckArgs, + ) + Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) + Expect(s.network.NextBlock()).To(BeNil()) + + unpacked, err := s.precompile.ABI.Unpack(staking.DelegateToBondedValidatorsMethod, ethRes.Ret) + Expect(err).To(BeNil(), "error while unpacking tx output") + Expect(unpacked).To(HaveLen(2)) + + delegatedAmount, ok := unpacked[0].(*big.Int) + Expect(ok).To(BeTrue(), "expected delegatedAmount to be *big.Int") + validatorsUsed, ok := unpacked[1].(uint32) + Expect(ok).To(BeTrue(), "expected validatorsUsed to be uint32") + Expect(delegatedAmount).To(Equal(big.NewInt(5))) + Expect(validatorsUsed).To(Equal(uint32(2))) + + qc := s.network.GetStakingClient() + valsRes, err := qc.Validators(s.network.GetContext(), &stakingtypes.QueryValidatorsRequest{ + Status: stakingtypes.BondStatusBonded, + Pagination: &query.PageRequest{ + Limit: 2, + }, + }) + Expect(err).To(BeNil()) + Expect(valsRes.Validators).To(HaveLen(2)) + + // deterministic remainder policy: for amount=5 and n=2 => [3,2] + exp := []int64{3, 2} + for i, v := range valsRes.Validators { + delRes, delErr := s.grpcHandler.GetDelegation(newAddr.String(), v.OperatorAddress) + Expect(delErr).To(BeNil(), "expected delegation for validator %s", v.OperatorAddress) + Expect(delRes.DelegationResponse.Balance.Amount.Int64()).To(Equal(exp[i])) + } + }) + + It("should honor maxValidators cap", func() { + newAddr, newAddrPriv := testutiltx.NewAccAddressAndKey() + err := utils.FundAccountWithBaseDenom(s.factory, s.network, s.keyring.GetKey(0), newAddr, math.NewInt(2e18)) + Expect(err).To(BeNil(), "error while funding account") + Expect(s.network.NextBlock()).To(BeNil()) + + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + big.NewInt(9), + uint32(1), + } + logCheckArgs := passCheck.WithExpEvents(staking.EventTypeDelegate) + + _, ethRes, err := s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + logCheckArgs, + ) + Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) + Expect(s.network.NextBlock()).To(BeNil()) + + unpacked, err := s.precompile.ABI.Unpack(staking.DelegateToBondedValidatorsMethod, ethRes.Ret) + Expect(err).To(BeNil(), "error while unpacking tx output") + delegatedAmount, ok := unpacked[0].(*big.Int) + Expect(ok).To(BeTrue()) + validatorsUsed, ok := unpacked[1].(uint32) + Expect(ok).To(BeTrue()) + Expect(delegatedAmount).To(Equal(big.NewInt(9))) + Expect(validatorsUsed).To(Equal(uint32(1))) + }) + + It("should fail when caller is different from delegator address", func() { + delegator := s.keyring.GetKey(0) + differentAddr := testutiltx.GenerateAddress() + + callArgs.Args = []interface{}{ + differentAddr, + big.NewInt(10), + uint32(2), + } + logCheckArgs := defaultLogCheck.WithErrContains( + fmt.Sprintf(cmn.ErrRequesterIsNotMsgSender, delegator.Addr, differentAddr), + ) + + _, _, err := s.factory.CallContractAndCheckLogs( + delegator.Priv, + txArgs, + callArgs, + logCheckArgs, + ) + Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) + }) + + It("should fail when maxValidators is zero", func() { + delegator := s.keyring.GetKey(0) + + callArgs.Args = []interface{}{ + delegator.Addr, + big.NewInt(10), + uint32(0), + } + logCheckArgs := defaultLogCheck.WithErrContains("maxValidators must be greater than zero") + + _, _, err := s.factory.CallContractAndCheckLogs( + delegator.Priv, + txArgs, + callArgs, + logCheckArgs, + ) + Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) + }) + + It("should fail when account balance is insufficient", func() { + newAddr, newAddrPriv := testutiltx.NewAccAddressAndKey() + err := utils.FundAccountWithBaseDenom(s.factory, s.network, s.keyring.GetKey(0), newAddr, math.NewInt(1)) + Expect(err).To(BeNil(), "error while funding account") + Expect(s.network.NextBlock()).To(BeNil()) + + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + big.NewInt(2), + uint32(2), + } + logCheckArgs := defaultLogCheck.WithErrContains("insufficient funds") + + _, _, err = s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + logCheckArgs, + ) + Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) + + // Atomicity assertion: failed call must not persist any delegation state. + qc := s.network.GetStakingClient() + valsRes, qErr := qc.Validators(s.network.GetContext(), &stakingtypes.QueryValidatorsRequest{ + Status: stakingtypes.BondStatusBonded, + Pagination: &query.PageRequest{ + Limit: 2, + }, + }) + Expect(qErr).To(BeNil()) + Expect(valsRes.Validators).To(HaveLen(2)) + for _, v := range valsRes.Validators { + _, delErr := s.grpcHandler.GetDelegation(newAddr.String(), v.OperatorAddress) + Expect(delErr).ToNot(BeNil(), "expected no delegation persisted for validator %s", v.OperatorAddress) + } + }) + }) + Describe("to redelegate", func() { BeforeEach(func() { callArgs.MethodName = staking.RedelegateMethod From cb57304655887dd2e1bb79539e22fcf1a72a6bfc Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Thu, 26 Mar 2026 17:07:32 +0530 Subject: [PATCH 20/31] refactor(communitypool): route stake through delegateToBondedValidators and update docs Signed-off-by: Nikhil Sharma --- contracts/solidity/pool/CommunityPool.json | 106 +------------ contracts/solidity/pool/CommunityPool.sol | 147 ++---------------- precompiles/staking/README.md | 15 ++ .../communitypool/TEST_ASSUMPTIONS.md | 10 +- .../precompiles/communitypool/test_setup.go | 5 - .../precompiles/communitypool/test_utils.go | 1 - 6 files changed, 39 insertions(+), 245 deletions(-) diff --git a/contracts/solidity/pool/CommunityPool.json b/contracts/solidity/pool/CommunityPool.json index ff745b3c..658f3239 100644 --- a/contracts/solidity/pool/CommunityPool.json +++ b/contracts/solidity/pool/CommunityPool.json @@ -29,32 +29,11 @@ "internalType": "address", "name": "owner_", "type": "address" - }, - { - "internalType": "string", - "name": "validatorPrefix_", - "type": "string" } ], "stateMutability": "nonpayable", "type": "constructor" }, - { - "inputs": [ - { - "internalType": "string", - "name": "validator", - "type": "string" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "DelegateFailed", - "type": "error" - }, { "inputs": [], "name": "HarvestFailed", @@ -96,11 +75,6 @@ "name": "InvalidUnits", "type": "error" }, - { - "inputs": [], - "name": "NoValidators", - "type": "error" - }, { "inputs": [], "name": "TokenTransferFailed", @@ -252,25 +226,6 @@ "name": "Stake", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "validator", - "type": "string" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "StakeDelegated", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -290,25 +245,6 @@ "name": "TotalStakedSynced", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "previousPrefix", - "type": "string" - }, - { - "indexed": false, - "internalType": "string", - "name": "newPrefix", - "type": "string" - } - ], - "name": "ValidatorPrefixUpdated", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -499,19 +435,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "string", - "name": "newPrefix", - "type": "string" - } - ], - "name": "setValidatorPrefix", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [], "name": "stake", @@ -596,19 +519,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "validatorPrefix", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -629,30 +539,30 @@ "type": "function" } ], - "bytecode": "0x604060a0815234620003015762001d7c803803806200001e8162000305565b92833981019060c08183031262000301576200003a816200032b565b9060206200004a81830162000340565b926200005886840162000340565b9060608401516200006c608086016200032b565b60a08601516001600160401b039691929187821162000301570196601f9489868a01121562000301578851888111620002ab57601f1999620000b48289018c168a0162000305565b9b828d52898383010111620003015788905f5b838110620002ec5750505f918c0101526001600160a01b0394851680158015620002e1575b620002d05763ffffffff9081831615620002bf578b5115620002bf57608052600380546001600160401b031916919093161790871b67ffffffff00000000161790556004555f80546001600160a01b031916929091169190911790558451928311620002ab576005948554926001938481811c91168015620002a0575b828210146200028c5783811162000246575b5080928511600114620001e15750839450908392915f94620001d5575b50501b915f199060031b1c19161790555b51611a29908162000353823960805181818161021f015281816103140152818161095d0152610d360152f35b015192505f8062000198565b929484908116875f52845f20945f905b888383106200022b575050501062000212575b505050811b019055620001a9565b01515f1960f88460031b161c191690555f808062000204565b858701518855909601959485019487935090810190620001f1565b875f52815f20848088018a1c82019284891062000282575b01891c019085905b828110620002765750506200017b565b5f815501859062000266565b925081926200025e565b634e487b7160e01b5f52602260045260245ffd5b90607f169062000169565b634e487b7160e01b5f52604160045260245ffd5b8c516306b7c75960e31b8152600490fd5b8b5163e6c4247b60e01b8152600490fd5b5085851615620000ec565b818101830151818f018401528a9201620000c7565b5f80fd5b6040519190601f01601f191682016001600160401b03811183821017620002ab57604052565b51906001600160a01b03821682036200030157565b519063ffffffff82168203620003015756fe6080604081815260049081361015610015575f80fd5b5f92833560e01c90816308ac525614610b6e575080630eccc70814610b345780631a0a253c14610a6c5780632e1a7d4d146108a35780633a4b66f11461086a5780634641257d14610741578063635bea2a146107215780636d86acc4146107025780637cbba4651461050f578063817b1cd2146104f05780638da5cb5b146104c8578063a8c7914714610459578063b6b55f2514610290578063b7ec1a3314610273578063bbe9a0701461024e578063c28f43921461020a578063cd61546a146101d5578063e66825c3146101ad578063f18876841461018f5763f2fde38b146100fd575f80fd5b3461018b57602036600319011261018b576001600160a01b03823581811693908490036101875784549182169283330361017b57841561016e5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b50903461018b578260031936011261018b5760209250549051908152f35b8382346101d157816003193601126101d1576020906101ca610dfc565b9051908152f35b5080fd5b8382346101d157816003193601126101d157610206906101f3610c1a565b9051918291602083526020830190610cf6565b0390f35b8382346101d157816003193601126101d157517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b8382346101d157816003193601126101d15760209063ffffffff600354169051908152f35b8382346101d157816003193601126101d1576020906101ca610d1b565b503461018b57602092836003193601126104565782356102b260075415610e44565b60016007558015610447576102d16102c8610d1b565b60025490610daa565b600154908115801561043f575b1561042757505080935b84156104195783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190811561040f5784916103d6575b50156103c8575033825260068552828220610368858254610daa565b90557f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e6103bc61039a86600154610daa565b6001819055855193845260208401879052604084015233929081906060820190565b0390a260075551908152f35b835163be24f3c560e01b8152fd5b90508681813d8311610408575b6103ed8183610bf9565b81010312610404576103fe90610e7d565b5f61034c565b8380fd5b503d6103e3565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6104346104399284610dcb565b610dde565b936102e8565b5080156102de565b50505163162908e360e11b8152fd5b80fd5b50903461018b57602036600319011261018b578254813591906001600160a01b031633036104bb5750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b8382346101d157816003193601126101d157905490516001600160a01b039091168152602090f35b8382346101d157816003193601126101d1576020906002549051908152f35b508290346101d15760208060031936011261018b576001600160401b039184358381116101875736602382011215610187578086013593841161018757602495368786840101116106fe5785546001600160a01b031633036104bb5784156106f0575061057a610c1a565b9360056105878154610b92565b601f81116106af575b5086601f83116001146106275797829182828a9b7f4e078e5553e283423298b75f183265474fa61da0c06cbd3508a8fbb983db7acd9b9261061a575b50508360011b905f198560031b1c19161790555b6105f38551978689978852870190610cf6565b938585038787015282855201858401378181018401879052601f01601f191601030190a180f35b870101359050828c6105cc565b81885285882090601f198416895b818110610696575091849391847f4e078e5553e283423298b75f183265474fa61da0c06cbd3508a8fbb983db7acd9b9c941061067b575b5050600183811b0190556105e0565b86018301355f19600386901b60f8161c191690558a8061066c565b919288600181928e878b01013581550194019201610635565b818852858820601f8401831c8101918785106106e6575b601f01831c01905b8181106106db5750610590565b8881556001016106ce565b90915081906106c6565b82516306b7c75960e31b8152fd5b8580fd5b8382346101d157816003193601126101d1576020906001549051908152f35b8382346101d157816003193601126101d1576020906101ca6102c8610d1b565b508290346101d157816003193601126101d15761076060075415610e44565b600160075561076d610d1b565b9163ffffffff60035416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610860578291610827575b501561081757602093507f4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721de6107db610d1b565b84811115610810576107ed8582610e8e565b945b8451908152602081019190915260408101859052606090a160075551908152f35b82946107ef565b8151630d599dd960e11b81528490fd5b90506020813d8211610858575b8161084160209383610bf9565b810103126101d15761085290610e7d565b856107a8565b3d9150610834565b83513d84823e3d90fd5b8382346101d157816003193601126101d1579060209161088c60075415610e44565b6001600755610899610f2f565b9160075551908152f35b503461018b57602092836003193601126104565782356108c560075415610e44565b6001806007558115610a5c573383526006865283832054948583118015610a53575b610a455761090a6109026108fc6102c8610d1b565b85610dcb565b835490610dde565b95610913610d1b565b808811610a2957508361092591610e8e565b338552600688528585205561093b838354610e8e565b8255845163a9059cbb60e01b81523382820152602481018790528781604481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610a1f5785916109ea575b50156109dc575054835191825260208201859052604082015233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949080606081016103bc565b845163022e258160e11b8152fd5b90508781813d8311610a18575b610a018183610bf9565b8101031261018757610a1290610e7d565b5f610995565b503d6109f7565b86513d87823e3d90fd5b82604491898951926382b3a56560e01b84528301526024820152fd5b8451630e433c2360e31b8152fd5b508154156108e7565b50505051630e433c2360e31b8152fd5b50903461018b57606036600319011261018b5780359163ffffffff9182841680940361018757602435928316908184036106fe57855460443594906001600160a01b03163303610b26578215610b17576003805467ffffffffffffffff19168717602092831b67ffffffff00000000161790559084905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b5082516306b7c75960e31b8152fd5b5082516282b42960e81b8152fd5b50903461018b57602036600319011261018b57356001600160a01b0381169081900361018b57828291602094526006845220549051908152f35b8490346101d157816003193601126101d15760209063ffffffff600354831c168152f35b90600182811c92168015610bc0575b6020831014610bac57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610ba1565b60a081019081106001600160401b03821117610be557604052565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b03821117610be557604052565b604051905f8260055491610c2d83610b92565b808352600193808516908115610cb45750600114610c55575b50610c5392500383610bf9565b565b60055f9081527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db094602093509091905b818310610c9c575050610c5393508201015f610c46565b85548884018501529485019487945091830191610c85565b9050610c5394506020925060ff191682840152151560051b8201015f610c46565b5f5b838110610ce65750505f910152565b8181015183820152602001610cd7565b90602091610d0f81518092818552858086019101610cd5565b601f01601f1916010190565b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610d9f575f91610d71575090565b906020823d8211610d97575b81610d8a60209383610bf9565b8101031261045657505190565b3d9150610d7d565b6040513d5f823e3d90fd5b91908201809211610db757565b634e487b7160e01b5f52601160045260245ffd5b81810292918115918404141715610db757565b8115610de8570490565b634e487b7160e01b5f52601260045260245ffd5b6001548015610e3757610e106102c8610d1b565b90670de0b6b3a764000091828102928184041490151715610db757610e3491610dde565b90565b50670de0b6b3a764000090565b15610e4b57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b51908115158203610e8a57565b5f80fd5b91908203918211610db757565b5f198114610db75760010190565b8051821015610ebd5760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b909291926001600160401b038111610be55760405191610efb601f8301601f191660200184610bf9565b829482845282820111610e8a576020610c53930190610cd5565b9080601f83011215610e8a578151610e3492602001610ed1565b5f90610f39610d1b565b600454811061197f5763ffffffff60035460201c16801561196d57610f5d8161199c565b905f9060605b818310611417575b5050801561140557610f7c8161199c565b915f5b8281106113d657505050805190610f968284610dde565b908215610de8575f5b838110610ff8575050507f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f691608091610fda86600254610daa565b908160025560405192835286602084015260408301526060820152a1565b829684860682106113c3575b87156113b8576110148284610ea9565b5190815191602a9283811490811591611395575b508015611342575b61130f57915f926002915b80831061126657505060408051633e562a6360e21b81526001600160a01b039094166004850152602484015250600580545f9184919061107a82610b92565b918260448501526001811690815f146112465750600114611206575b5050805f920381836104005af1918215610d9f575f926111c3575b506040516353266bbb60e01b815230600482015260606024820152602081806110dd6064820187610cf6565b8d604483015203815f6108005af1908115610d9f575f91611189575b501561115a5761114761115593926111328b7f9a4001bdb3452b060fc06c64fbf07b16cf6e9e5f5d67f9e7507331983d2de21894610daa565b9a604051928392604084526040840190610cf6565b9060208301520390a1610e9b565b610f9f565b60408051639f3289cf60e01b81526004810191909152808a61117f6044830186610cf6565b9060248301520390fd5b90506020813d6020116111bb575b816111a460209383610bf9565b81010312610e8a576111b590610e7d565b5f6110f9565b3d9150611197565b9091503d90815f823e6111d68282610bf9565b6020818381010312610e8a5780516001600160401b038111610e8a576111ff9282019101610f15565b905f6110b1565b915091505f528260205f20915f925b81841061122c5750508060645f9382010192611096565b805460648588010152602090930192859250600101611215565b9190505f9450839260649260ff1916838501521515901b82010192611096565b9091938251851015610ebd576020858401015160f81c603081101580611337575b156112bf57602f19019060ff8211610db75760ff6112b8925b60049290921b6010600160a01b031691161794610e9b565b919061103b565b60418110158061132c575b156112e757603619019060ff8211610db75760ff6112b8926112a0565b606181101580611321575b1561130f57605619019060ff8211610db75760ff6112b8926112a0565b60405163e6c4247b60e01b8152600490fd5b5060668111156112f2565b5060468111156112ca565b506039811115611287565b508051600190811015610ebd576021820180516001600160f81b0319908116600f60fb1b14159283611377575b505050611030565b9091925083511115610ebd57905116600b60fb1b14155f808061136f565b905015610ebd5760208101516001600160f81b031916600360fc1b14155f611028565b965061115590610e9b565b965060018301808411610db75796611004565b806113e46114009284610ea9565b516113ef8287610ea9565b526113fa8186610ea9565b50610e9b565b610f7f565b6040516313f8a3a760e31b8152600490fd5b92936001600160401b0361143084849894999599610e8e565b166040519461143e86610bca565b85525f602086015260408501525f60608501525f6080850152604051604081018181106001600160401b03821117610be5575f916114bb9160405260128152711093d39117d4d510551554d7d093d391115160721b6020820152604051968792839263186b216760e01b8452604060048501526044840190610cf6565b6003198382030160248401526080806114dd845160a0855260a0850190610cf6565b936001600160401b0360208201511660208501526001600160401b0360408201511660408501526060810151151560608501520151151591015203816108005afa8015610d9f575f945f916115aa575b50845196871561159b575f985b888a1080611592575b1561157c57611570611576916115598c8a610ea9565b5151611565828c610ea9565b526113fa818b610ea9565b99610e9b565b9861153a565b94985092965090949350518051610f6357610f6b565b50818110611543565b50509392819550959195610f6b565b9450503d805f863e6115bc8186610bf9565b6040858281010312610e8a578451906001600160401b038211610e8a57808601601f838801011215610e8a5781860151916115f683611985565b926116046040519485610bf9565b8084526020840183890160208360051b858c01010111610e8a576020838a0101905b60208360051b858c01010182106116ca575050505060208601516001600160401b038111610e8a5786016040818389010312610e8a5760405196604088018881106001600160401b03821117610be55760405281516001600160401b038111610e8a578201838201601f82011215610e8a5780516020946116aa9301918501610ed1565b875201516001600160401b0381168103610e8a576020860152935f61152d565b81516001600160401b038111610e8a57610160858c018201878d0103601f190112610e8a5760405191826101608101106001600160401b0361016085011117610be557602082878e6101608701604052010101516001600160401b038111610e8a5782878e61174760409460208d84019186868601010101610f15565b8752010101516001600160401b038111610e8a5782878e61177660809460208d84019186868601010101610f15565b602088015261178b6060848484010101610e7d565b6040880152010101516004811015610e8a5760608401528b8601820160a081810151608086015260c08201519085015260e00151906001600160401b038211610e8a5760a0878e0184018301898f0103601f190112610e8a578c93602083858a604051986117f88a610bca565b01010101516001600160401b038111610e8a57838f8a8161182b6040958f6020908c960191878787870101010101610f15565b8a5201010101516001600160401b038111610e8a57838f8a816118606060958f6020908c960191878787870101010101610f15565b60208b015201010101516001600160401b038111610e8a57838f8a816118986080958f6020908c960191878787870101010101610f15565b60408b015201010101516001600160401b038111610e8a57838f8a816118d060a0958f6020908c960191878787870101010101610f15565b60608b01520101010151946001600160401b038611610e8a576101608f91956020979661190e8c8a8f9a819b9a86839c8a01948a0101010101610f15565b608082015260c08501528a6101009361192c858484840101016119e5565b60e087015261012094611944868585850101016119e5565b908701526101409485848484010101519087015201010151908201528152019201919050611626565b6040516306b7c75960e31b8152600490fd5b505f9150565b6001600160401b038111610be55760051b60200190565b906119a682611985565b6119b36040519182610bf9565b82815280926119c4601f1991611985565b01905f5b8281106119d457505050565b8060606020809385010152016119c8565b51908160070b8203610e8a5756fea26469706673582212203d49af80e36bb94f2c2371d94c17db456854f54ebdbaa3bf92732408776f654364736f6c63430008140033", - "deployedBytecode": "0x6080604081815260049081361015610015575f80fd5b5f92833560e01c90816308ac525614610b6e575080630eccc70814610b345780631a0a253c14610a6c5780632e1a7d4d146108a35780633a4b66f11461086a5780634641257d14610741578063635bea2a146107215780636d86acc4146107025780637cbba4651461050f578063817b1cd2146104f05780638da5cb5b146104c8578063a8c7914714610459578063b6b55f2514610290578063b7ec1a3314610273578063bbe9a0701461024e578063c28f43921461020a578063cd61546a146101d5578063e66825c3146101ad578063f18876841461018f5763f2fde38b146100fd575f80fd5b3461018b57602036600319011261018b576001600160a01b03823581811693908490036101875784549182169283330361017b57841561016e5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b50903461018b578260031936011261018b5760209250549051908152f35b8382346101d157816003193601126101d1576020906101ca610dfc565b9051908152f35b5080fd5b8382346101d157816003193601126101d157610206906101f3610c1a565b9051918291602083526020830190610cf6565b0390f35b8382346101d157816003193601126101d157517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b8382346101d157816003193601126101d15760209063ffffffff600354169051908152f35b8382346101d157816003193601126101d1576020906101ca610d1b565b503461018b57602092836003193601126104565782356102b260075415610e44565b60016007558015610447576102d16102c8610d1b565b60025490610daa565b600154908115801561043f575b1561042757505080935b84156104195783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af190811561040f5784916103d6575b50156103c8575033825260068552828220610368858254610daa565b90557f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e6103bc61039a86600154610daa565b6001819055855193845260208401879052604084015233929081906060820190565b0390a260075551908152f35b835163be24f3c560e01b8152fd5b90508681813d8311610408575b6103ed8183610bf9565b81010312610404576103fe90610e7d565b5f61034c565b8380fd5b503d6103e3565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6104346104399284610dcb565b610dde565b936102e8565b5080156102de565b50505163162908e360e11b8152fd5b80fd5b50903461018b57602036600319011261018b578254813591906001600160a01b031633036104bb5750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b8382346101d157816003193601126101d157905490516001600160a01b039091168152602090f35b8382346101d157816003193601126101d1576020906002549051908152f35b508290346101d15760208060031936011261018b576001600160401b039184358381116101875736602382011215610187578086013593841161018757602495368786840101116106fe5785546001600160a01b031633036104bb5784156106f0575061057a610c1a565b9360056105878154610b92565b601f81116106af575b5086601f83116001146106275797829182828a9b7f4e078e5553e283423298b75f183265474fa61da0c06cbd3508a8fbb983db7acd9b9261061a575b50508360011b905f198560031b1c19161790555b6105f38551978689978852870190610cf6565b938585038787015282855201858401378181018401879052601f01601f191601030190a180f35b870101359050828c6105cc565b81885285882090601f198416895b818110610696575091849391847f4e078e5553e283423298b75f183265474fa61da0c06cbd3508a8fbb983db7acd9b9c941061067b575b5050600183811b0190556105e0565b86018301355f19600386901b60f8161c191690558a8061066c565b919288600181928e878b01013581550194019201610635565b818852858820601f8401831c8101918785106106e6575b601f01831c01905b8181106106db5750610590565b8881556001016106ce565b90915081906106c6565b82516306b7c75960e31b8152fd5b8580fd5b8382346101d157816003193601126101d1576020906001549051908152f35b8382346101d157816003193601126101d1576020906101ca6102c8610d1b565b508290346101d157816003193601126101d15761076060075415610e44565b600160075561076d610d1b565b9163ffffffff60035416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610860578291610827575b501561081757602093507f4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721de6107db610d1b565b84811115610810576107ed8582610e8e565b945b8451908152602081019190915260408101859052606090a160075551908152f35b82946107ef565b8151630d599dd960e11b81528490fd5b90506020813d8211610858575b8161084160209383610bf9565b810103126101d15761085290610e7d565b856107a8565b3d9150610834565b83513d84823e3d90fd5b8382346101d157816003193601126101d1579060209161088c60075415610e44565b6001600755610899610f2f565b9160075551908152f35b503461018b57602092836003193601126104565782356108c560075415610e44565b6001806007558115610a5c573383526006865283832054948583118015610a53575b610a455761090a6109026108fc6102c8610d1b565b85610dcb565b835490610dde565b95610913610d1b565b808811610a2957508361092591610e8e565b338552600688528585205561093b838354610e8e565b8255845163a9059cbb60e01b81523382820152602481018790528781604481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610a1f5785916109ea575b50156109dc575054835191825260208201859052604082015233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca949080606081016103bc565b845163022e258160e11b8152fd5b90508781813d8311610a18575b610a018183610bf9565b8101031261018757610a1290610e7d565b5f610995565b503d6109f7565b86513d87823e3d90fd5b82604491898951926382b3a56560e01b84528301526024820152fd5b8451630e433c2360e31b8152fd5b508154156108e7565b50505051630e433c2360e31b8152fd5b50903461018b57606036600319011261018b5780359163ffffffff9182841680940361018757602435928316908184036106fe57855460443594906001600160a01b03163303610b26578215610b17576003805467ffffffffffffffff19168717602092831b67ffffffff00000000161790559084905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b5082516306b7c75960e31b8152fd5b5082516282b42960e81b8152fd5b50903461018b57602036600319011261018b57356001600160a01b0381169081900361018b57828291602094526006845220549051908152f35b8490346101d157816003193601126101d15760209063ffffffff600354831c168152f35b90600182811c92168015610bc0575b6020831014610bac57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610ba1565b60a081019081106001600160401b03821117610be557604052565b634e487b7160e01b5f52604160045260245ffd5b90601f801991011681019081106001600160401b03821117610be557604052565b604051905f8260055491610c2d83610b92565b808352600193808516908115610cb45750600114610c55575b50610c5392500383610bf9565b565b60055f9081527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db094602093509091905b818310610c9c575050610c5393508201015f610c46565b85548884018501529485019487945091830191610c85565b9050610c5394506020925060ff191682840152151560051b8201015f610c46565b5f5b838110610ce65750505f910152565b8181015183820152602001610cd7565b90602091610d0f81518092818552858086019101610cd5565b601f01601f1916010190565b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610d9f575f91610d71575090565b906020823d8211610d97575b81610d8a60209383610bf9565b8101031261045657505190565b3d9150610d7d565b6040513d5f823e3d90fd5b91908201809211610db757565b634e487b7160e01b5f52601160045260245ffd5b81810292918115918404141715610db757565b8115610de8570490565b634e487b7160e01b5f52601260045260245ffd5b6001548015610e3757610e106102c8610d1b565b90670de0b6b3a764000091828102928184041490151715610db757610e3491610dde565b90565b50670de0b6b3a764000090565b15610e4b57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b51908115158203610e8a57565b5f80fd5b91908203918211610db757565b5f198114610db75760010190565b8051821015610ebd5760209160051b010190565b634e487b7160e01b5f52603260045260245ffd5b909291926001600160401b038111610be55760405191610efb601f8301601f191660200184610bf9565b829482845282820111610e8a576020610c53930190610cd5565b9080601f83011215610e8a578151610e3492602001610ed1565b5f90610f39610d1b565b600454811061197f5763ffffffff60035460201c16801561196d57610f5d8161199c565b905f9060605b818310611417575b5050801561140557610f7c8161199c565b915f5b8281106113d657505050805190610f968284610dde565b908215610de8575f5b838110610ff8575050507f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f691608091610fda86600254610daa565b908160025560405192835286602084015260408301526060820152a1565b829684860682106113c3575b87156113b8576110148284610ea9565b5190815191602a9283811490811591611395575b508015611342575b61130f57915f926002915b80831061126657505060408051633e562a6360e21b81526001600160a01b039094166004850152602484015250600580545f9184919061107a82610b92565b918260448501526001811690815f146112465750600114611206575b5050805f920381836104005af1918215610d9f575f926111c3575b506040516353266bbb60e01b815230600482015260606024820152602081806110dd6064820187610cf6565b8d604483015203815f6108005af1908115610d9f575f91611189575b501561115a5761114761115593926111328b7f9a4001bdb3452b060fc06c64fbf07b16cf6e9e5f5d67f9e7507331983d2de21894610daa565b9a604051928392604084526040840190610cf6565b9060208301520390a1610e9b565b610f9f565b60408051639f3289cf60e01b81526004810191909152808a61117f6044830186610cf6565b9060248301520390fd5b90506020813d6020116111bb575b816111a460209383610bf9565b81010312610e8a576111b590610e7d565b5f6110f9565b3d9150611197565b9091503d90815f823e6111d68282610bf9565b6020818381010312610e8a5780516001600160401b038111610e8a576111ff9282019101610f15565b905f6110b1565b915091505f528260205f20915f925b81841061122c5750508060645f9382010192611096565b805460648588010152602090930192859250600101611215565b9190505f9450839260649260ff1916838501521515901b82010192611096565b9091938251851015610ebd576020858401015160f81c603081101580611337575b156112bf57602f19019060ff8211610db75760ff6112b8925b60049290921b6010600160a01b031691161794610e9b565b919061103b565b60418110158061132c575b156112e757603619019060ff8211610db75760ff6112b8926112a0565b606181101580611321575b1561130f57605619019060ff8211610db75760ff6112b8926112a0565b60405163e6c4247b60e01b8152600490fd5b5060668111156112f2565b5060468111156112ca565b506039811115611287565b508051600190811015610ebd576021820180516001600160f81b0319908116600f60fb1b14159283611377575b505050611030565b9091925083511115610ebd57905116600b60fb1b14155f808061136f565b905015610ebd5760208101516001600160f81b031916600360fc1b14155f611028565b965061115590610e9b565b965060018301808411610db75796611004565b806113e46114009284610ea9565b516113ef8287610ea9565b526113fa8186610ea9565b50610e9b565b610f7f565b6040516313f8a3a760e31b8152600490fd5b92936001600160401b0361143084849894999599610e8e565b166040519461143e86610bca565b85525f602086015260408501525f60608501525f6080850152604051604081018181106001600160401b03821117610be5575f916114bb9160405260128152711093d39117d4d510551554d7d093d391115160721b6020820152604051968792839263186b216760e01b8452604060048501526044840190610cf6565b6003198382030160248401526080806114dd845160a0855260a0850190610cf6565b936001600160401b0360208201511660208501526001600160401b0360408201511660408501526060810151151560608501520151151591015203816108005afa8015610d9f575f945f916115aa575b50845196871561159b575f985b888a1080611592575b1561157c57611570611576916115598c8a610ea9565b5151611565828c610ea9565b526113fa818b610ea9565b99610e9b565b9861153a565b94985092965090949350518051610f6357610f6b565b50818110611543565b50509392819550959195610f6b565b9450503d805f863e6115bc8186610bf9565b6040858281010312610e8a578451906001600160401b038211610e8a57808601601f838801011215610e8a5781860151916115f683611985565b926116046040519485610bf9565b8084526020840183890160208360051b858c01010111610e8a576020838a0101905b60208360051b858c01010182106116ca575050505060208601516001600160401b038111610e8a5786016040818389010312610e8a5760405196604088018881106001600160401b03821117610be55760405281516001600160401b038111610e8a578201838201601f82011215610e8a5780516020946116aa9301918501610ed1565b875201516001600160401b0381168103610e8a576020860152935f61152d565b81516001600160401b038111610e8a57610160858c018201878d0103601f190112610e8a5760405191826101608101106001600160401b0361016085011117610be557602082878e6101608701604052010101516001600160401b038111610e8a5782878e61174760409460208d84019186868601010101610f15565b8752010101516001600160401b038111610e8a5782878e61177660809460208d84019186868601010101610f15565b602088015261178b6060848484010101610e7d565b6040880152010101516004811015610e8a5760608401528b8601820160a081810151608086015260c08201519085015260e00151906001600160401b038211610e8a5760a0878e0184018301898f0103601f190112610e8a578c93602083858a604051986117f88a610bca565b01010101516001600160401b038111610e8a57838f8a8161182b6040958f6020908c960191878787870101010101610f15565b8a5201010101516001600160401b038111610e8a57838f8a816118606060958f6020908c960191878787870101010101610f15565b60208b015201010101516001600160401b038111610e8a57838f8a816118986080958f6020908c960191878787870101010101610f15565b60408b015201010101516001600160401b038111610e8a57838f8a816118d060a0958f6020908c960191878787870101010101610f15565b60608b01520101010151946001600160401b038611610e8a576101608f91956020979661190e8c8a8f9a819b9a86839c8a01948a0101010101610f15565b608082015260c08501528a6101009361192c858484840101016119e5565b60e087015261012094611944868585850101016119e5565b908701526101409485848484010101519087015201010151908201528152019201919050611626565b6040516306b7c75960e31b8152600490fd5b505f9150565b6001600160401b038111610be55760051b60200190565b906119a682611985565b6119b36040519182610bf9565b82815280926119c4601f1991611985565b01905f5b8281106119d457505050565b8060606020809385010152016119c8565b51908160070b8203610e8a5756fea26469706673582212203d49af80e36bb94f2c2371d94c17db456854f54ebdbaa3bf92732408776f654364736f6c63430008140033", + "bytecode": "0x60a03461012e57601f610d8138819003918201601f19168301916001600160401b038311848410176101325780849260a09460405283398101031261012e5761004781610146565b906100546020820161015a565b906100616040820161015a565b91610073608060608401519301610146565b6001600160a01b0394909390851680158015610124575b6101125763ffffffff90818316156101005760805267ffffffff000000006003549260201b1692169060018060401b03191617176003556004551660018060a01b03195f5416175f55604051610c15908161016c82396080518181816101d4015281816102c9015281816106f8015261096a0152f35b6040516306b7c75960e31b8152600490fd5b60405163e6c4247b60e01b8152600490fd5b508585161561008a565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b038216820361012e57565b519063ffffffff8216820361012e5756fe6080604081815260049081361015610015575f80fd5b5f92833560e01c90816308ac5256146108f5575080630eccc708146108bb5780631a0a253c146107ef5780632e1a7d4d1461063e5780633a4b66f1146106055780634641257d146104f7578063635bea2a146104d75780636d86acc4146104b8578063817b1cd2146104995780638da5cb5b14610471578063a8c7914714610402578063b6b55f2514610245578063b7ec1a3314610228578063bbe9a07014610203578063c28f4392146101bf578063e66825c314610197578063f1887684146101795763f2fde38b146100e7575f80fd5b34610175576020366003190112610175576001600160a01b0382358181169390849003610171578454918216928333036101655784156101585750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b50903461017557826003193601126101755760209250549051908152f35b8382346101bb57816003193601126101bb576020906101b4610a30565b9051908152f35b5080fd5b8382346101bb57816003193601126101bb57517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b8382346101bb57816003193601126101bb5760209063ffffffff600354169051908152f35b8382346101bb57816003193601126101bb576020906101b461094f565b503461017557602092836003193601126103ff57823561026760065415610a78565b600160065580156103f05761028661027d61094f565b600254906109de565b60015490811580156103e8575b156103d057505080935b84156103c25783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156103b857849161038b575b501561037d57503382526005855282822061031d8582546109de565b90557f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e61037161034f866001546109de565b6001819055855193845260208401879052604084015233929081906060820190565b0390a260065551908152f35b835163be24f3c560e01b8152fd5b6103ab9150873d89116103b1575b6103a38183610919565b810190610ab1565b5f610301565b503d610399565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6103dd6103e292846109ff565b610a12565b9361029d565b508015610293565b50505163162908e360e11b8152fd5b80fd5b509034610175576020366003190112610175578254813591906001600160a01b031633036104645750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b8382346101bb57816003193601126101bb57905490516001600160a01b039091168152602090f35b8382346101bb57816003193601126101bb576020906002549051908152f35b8382346101bb57816003193601126101bb576020906001549051908152f35b8382346101bb57816003193601126101bb576020906101b461027d61094f565b508290346101bb57816003193601126101bb5761051660065415610a78565b600160065561052361094f565b9163ffffffff60035416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af19081156105fb5782916105dd575b50156105cd57602093507f4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721de61059161094f565b848111156105c6576105a38582610acd565b945b8451908152602081019190915260408101859052606090a160065551908152f35b82946105a5565b8151630d599dd960e11b81528490fd5b6105f5915060203d81116103b1576103a38183610919565b8561055e565b83513d84823e3d90fd5b8382346101bb57816003193601126101bb579060209161062760065415610a78565b6001600655610634610ada565b9160065551908152f35b503461017557602092836003193601126103ff57823561066060065415610a78565b60018060065581156107df5733835260058652838320549485831180156107d6575b6107c8576106a561069d61069761027d61094f565b856109ff565b835490610a12565b956106ae61094f565b8088116107ac5750836106c091610acd565b33855260058852858520556106d6838354610acd565b8255845163a9059cbb60e01b81523382820152602481018790528781604481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156107a2578591610785575b5015610777575054835191825260208201859052604082015233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94908060608101610371565b845163022e258160e11b8152fd5b61079c9150883d8a116103b1576103a38183610919565b5f610730565b86513d87823e3d90fd5b82604491898951926382b3a56560e01b84528301526024820152fd5b8451630e433c2360e31b8152fd5b50815415610682565b50505051630e433c2360e31b8152fd5b5090346101755760603660031901126101755780359163ffffffff9182841680940361017157602435928316908184036108b757855460443594906001600160a01b031633036108a957821561089a576003805467ffffffffffffffff19168717602092831b67ffffffff00000000161790559084905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b5082516306b7c75960e31b8152fd5b5082516282b42960e81b8152fd5b8580fd5b50903461017557602036600319011261017557356001600160a01b0381169081900361017557828291602094526005845220549051908152f35b8490346101bb57816003193601126101bb5760209063ffffffff600354831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761093b57604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156109d3575f916109a5575090565b906020823d82116109cb575b816109be60209383610919565b810103126103ff57505190565b3d91506109b1565b6040513d5f823e3d90fd5b919082018092116109eb57565b634e487b7160e01b5f52601160045260245ffd5b818102929181159184041417156109eb57565b8115610a1c570490565b634e487b7160e01b5f52601260045260245ffd5b6001548015610a6b57610a4461027d61094f565b90670de0b6b3a7640000918281029281840414901517156109eb57610a6891610a12565b90565b50670de0b6b3a764000090565b15610a7f57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312610ac957518015158103610ac95790565b5f80fd5b919082039182116109eb57565b610ae261094f565b906004548210610bda5760035491604080519062141ed760e41b825230600483015282602483015263ffffffff809560201c1660448301525f948183606481896108005af1958615610bcf5780938197610b8a575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f693916080938297610b6e846002546109de565b93846002558351958652602086015216908301526060820152a1565b91965092508181813d8111610bc8575b610ba48183610919565b8101031261017557602081519101519286841684036103ff57509194816080610b37565b503d610b9a565b8251903d90823e3d90fd5b5f915056fea26469706673582212209fdff7701bd430cab462c994d74424fd4e2601d9b9945cb35fb4b553603e3d9564736f6c63430008140033", + "deployedBytecode": "0x6080604081815260049081361015610015575f80fd5b5f92833560e01c90816308ac5256146108f5575080630eccc708146108bb5780631a0a253c146107ef5780632e1a7d4d1461063e5780633a4b66f1146106055780634641257d146104f7578063635bea2a146104d75780636d86acc4146104b8578063817b1cd2146104995780638da5cb5b14610471578063a8c7914714610402578063b6b55f2514610245578063b7ec1a3314610228578063bbe9a07014610203578063c28f4392146101bf578063e66825c314610197578063f1887684146101795763f2fde38b146100e7575f80fd5b34610175576020366003190112610175576001600160a01b0382358181169390849003610171578454918216928333036101655784156101585750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b50903461017557826003193601126101755760209250549051908152f35b8382346101bb57816003193601126101bb576020906101b4610a30565b9051908152f35b5080fd5b8382346101bb57816003193601126101bb57517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b8382346101bb57816003193601126101bb5760209063ffffffff600354169051908152f35b8382346101bb57816003193601126101bb576020906101b461094f565b503461017557602092836003193601126103ff57823561026760065415610a78565b600160065580156103f05761028661027d61094f565b600254906109de565b60015490811580156103e8575b156103d057505080935b84156103c25783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156103b857849161038b575b501561037d57503382526005855282822061031d8582546109de565b90557f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e61037161034f866001546109de565b6001819055855193845260208401879052604084015233929081906060820190565b0390a260065551908152f35b835163be24f3c560e01b8152fd5b6103ab9150873d89116103b1575b6103a38183610919565b810190610ab1565b5f610301565b503d610399565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6103dd6103e292846109ff565b610a12565b9361029d565b508015610293565b50505163162908e360e11b8152fd5b80fd5b509034610175576020366003190112610175578254813591906001600160a01b031633036104645750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b8382346101bb57816003193601126101bb57905490516001600160a01b039091168152602090f35b8382346101bb57816003193601126101bb576020906002549051908152f35b8382346101bb57816003193601126101bb576020906001549051908152f35b8382346101bb57816003193601126101bb576020906101b461027d61094f565b508290346101bb57816003193601126101bb5761051660065415610a78565b600160065561052361094f565b9163ffffffff60035416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af19081156105fb5782916105dd575b50156105cd57602093507f4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721de61059161094f565b848111156105c6576105a38582610acd565b945b8451908152602081019190915260408101859052606090a160065551908152f35b82946105a5565b8151630d599dd960e11b81528490fd5b6105f5915060203d81116103b1576103a38183610919565b8561055e565b83513d84823e3d90fd5b8382346101bb57816003193601126101bb579060209161062760065415610a78565b6001600655610634610ada565b9160065551908152f35b503461017557602092836003193601126103ff57823561066060065415610a78565b60018060065581156107df5733835260058652838320549485831180156107d6575b6107c8576106a561069d61069761027d61094f565b856109ff565b835490610a12565b956106ae61094f565b8088116107ac5750836106c091610acd565b33855260058852858520556106d6838354610acd565b8255845163a9059cbb60e01b81523382820152602481018790528781604481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156107a2578591610785575b5015610777575054835191825260208201859052604082015233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94908060608101610371565b845163022e258160e11b8152fd5b61079c9150883d8a116103b1576103a38183610919565b5f610730565b86513d87823e3d90fd5b82604491898951926382b3a56560e01b84528301526024820152fd5b8451630e433c2360e31b8152fd5b50815415610682565b50505051630e433c2360e31b8152fd5b5090346101755760603660031901126101755780359163ffffffff9182841680940361017157602435928316908184036108b757855460443594906001600160a01b031633036108a957821561089a576003805467ffffffffffffffff19168717602092831b67ffffffff00000000161790559084905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b5082516306b7c75960e31b8152fd5b5082516282b42960e81b8152fd5b8580fd5b50903461017557602036600319011261017557356001600160a01b0381169081900361017557828291602094526005845220549051908152f35b8490346101bb57816003193601126101bb5760209063ffffffff600354831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761093b57604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156109d3575f916109a5575090565b906020823d82116109cb575b816109be60209383610919565b810103126103ff57505190565b3d91506109b1565b6040513d5f823e3d90fd5b919082018092116109eb57565b634e487b7160e01b5f52601160045260245ffd5b818102929181159184041417156109eb57565b8115610a1c570490565b634e487b7160e01b5f52601260045260245ffd5b6001548015610a6b57610a4461027d61094f565b90670de0b6b3a7640000918281029281840414901517156109eb57610a6891610a12565b90565b50670de0b6b3a764000090565b15610a7f57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312610ac957518015158103610ac95790565b5f80fd5b919082039182116109eb57565b610ae261094f565b906004548210610bda5760035491604080519062141ed760e41b825230600483015282602483015263ffffffff809560201c1660448301525f948183606481896108005af1958615610bcf5780938197610b8a575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f693916080938297610b6e846002546109de565b93846002558351958652602086015216908301526060820152a1565b91965092508181813d8111610bc8575b610ba48183610919565b8101031261017557602081519101519286841684036103ff57509194816080610b37565b503d610b9a565b8251903d90823e3d90fd5b5f915056fea26469706673582212209fdff7701bd430cab462c994d74424fd4e2601d9b9945cb35fb4b553603e3d9564736f6c63430008140033", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": { - "13": [ + "3877": [ { "length": 32, - "start": 543 + "start": 468 }, { "length": 32, - "start": 788 + "start": 713 }, { "length": 32, - "start": 2397 + "start": 1784 }, { "length": 32, - "start": 3382 + "start": 2410 } ] }, "inputSourceName": "project/solidity/pool/CommunityPool.sol", - "buildInfoId": "solc-0_8_20-764ee487806caff476736ab9b208906c0233ec72" + "buildInfoId": "solc-0_8_20-a811408d247f4050efe5537fb7107e02e5e2869f" } \ No newline at end of file diff --git a/contracts/solidity/pool/CommunityPool.sol b/contracts/solidity/pool/CommunityPool.sol index 06c2a754..81adc488 100644 --- a/contracts/solidity/pool/CommunityPool.sol +++ b/contracts/solidity/pool/CommunityPool.sol @@ -4,7 +4,6 @@ pragma solidity >=0.8.17; import "../precompiles/erc20/IERC20.sol"; import "../precompiles/staking/StakingI.sol" as staking; import "../precompiles/distribution/DistributionI.sol" as distribution; -import "../precompiles/bech32/Bech32I.sol"; /// @title CommunityPool /// @notice Pooled staking contract with internal ownership units. @@ -15,8 +14,6 @@ import "../precompiles/bech32/Bech32I.sol"; /// owner can reconcile it via `syncTotalStaked`. /// - Withdrawals are liquid-only in this MVP: if liquid funds are insufficient, withdrawal reverts. contract CommunityPool { - string private constant BONDED_STATUS = "BOND_STATUS_BONDED"; - /// @dev Native token contract used for deposits/withdrawals. IERC20 public immutable bondToken; @@ -28,7 +25,6 @@ contract CommunityPool { uint32 public maxRetrieve; uint32 public maxValidators; uint256 public minStakeAmount; - string public validatorPrefix; /// @dev Units held per user. User ownership fraction = unitsOf[user] / totalUnits. mapping(address => uint256) public unitsOf; @@ -41,11 +37,9 @@ contract CommunityPool { error InvalidAmount(); error InvalidUnits(); error InvalidConfig(); - error NoValidators(); error InsufficientLiquid(uint256 requested, uint256 available); error TokenTransferFailed(); error TokenTransferFromFailed(); - error DelegateFailed(string validator, uint256 amount); error HarvestFailed(); error ZeroMintedUnits(); @@ -53,11 +47,9 @@ contract CommunityPool { event ConfigUpdated(uint32 maxRetrieve, uint32 maxValidators, uint256 minStakeAmount); event Deposit(address indexed user, uint256 amount, uint256 mintedUnits, uint256 totalUnitsAfter); event Withdraw(address indexed user, uint256 burnedUnits, uint256 amountOut, uint256 totalUnitsAfter); - event StakeDelegated(string validator, uint256 amount); event Stake(uint256 liquidBefore, uint256 delegatedAmount, uint256 validatorsCount, uint256 totalStakedAfter); event Harvest(uint256 liquidBefore, uint256 liquidAfter, uint256 harvestedAmount); event TotalStakedSynced(uint256 previousTotalStaked, uint256 newTotalStaked); - event ValidatorPrefixUpdated(string previousPrefix, string newPrefix); modifier onlyOwner() { if (msg.sender != owner) { @@ -78,8 +70,7 @@ contract CommunityPool { uint32 maxRetrieve_, uint32 maxValidators_, uint256 minStakeAmount_, - address owner_, - string memory validatorPrefix_ + address owner_ ) { if (bondToken_ == address(0) || owner_ == address(0)) { revert InvalidAddress(); @@ -87,16 +78,12 @@ contract CommunityPool { if (maxValidators_ == 0) { revert InvalidConfig(); } - if (bytes(validatorPrefix_).length == 0) { - revert InvalidConfig(); - } bondToken = IERC20(bondToken_); maxRetrieve = maxRetrieve_; maxValidators = maxValidators_; minStakeAmount = minStakeAmount_; owner = owner_; - validatorPrefix = validatorPrefix_; } /// @notice Transfers owner privileges to a new address. @@ -137,16 +124,6 @@ contract CommunityPool { emit TotalStakedSynced(previous, newTotalStaked); } - /// @notice Updates the validator bech32 prefix used by stake conversion. - function setValidatorPrefix(string calldata newPrefix) external onlyOwner { - if (bytes(newPrefix).length == 0) { - revert InvalidConfig(); - } - string memory previous = validatorPrefix; - validatorPrefix = newPrefix; - emit ValidatorPrefixUpdated(previous, newPrefix); - } - /// @notice Current liquid token balance owned by the contract. function liquidBalance() public view returns (uint256) { return bondToken.balanceOf(address(this)); @@ -225,52 +202,22 @@ contract CommunityPool { emit Withdraw(msg.sender, userUnits, amountOut, totalUnits); } - /// @notice Delegates available liquid to bonded validators discovered on-chain. - /// @dev - /// - Uses staking precompile `validators(BOND_STATUS_BONDED, pageRequest)`. - /// - Splits liquid evenly, and assigns remainder (+1) to first validators deterministically. - /// - Increases `totalStaked` by delegated amount as accounting update. + /// @notice Delegates available liquid to bonded validators via staking precompile. + /// @dev Uses a single precompile call that performs bonded-set selection and equal split. function stake() external nonReentrant returns (uint256 delegatedAmount) { uint256 liquidBefore = liquidBalance(); if (liquidBefore < minStakeAmount) { return 0; } - - string[] memory validators = _getBondedValidators(maxValidators); - uint256 validatorCount = validators.length; - uint256 perValidator = liquidBefore / validatorCount; - uint256 remainder = liquidBefore % validatorCount; - - for (uint256 i = 0; i < validatorCount; i++) { - uint256 amount = perValidator; - if (i < remainder) { - amount += 1; - } - if (amount == 0) { - continue; - } - - address validatorHex = _parseHexAddress(validators[i]); - string memory validatorBech32 = BECH32_CONTRACT.hexToBech32( - validatorHex, - validatorPrefix - ); - - bool success = staking.STAKING_CONTRACT.delegate( - address(this), - validatorBech32, - amount - ); - if (!success) { - revert DelegateFailed(validatorBech32, amount); - } - - delegatedAmount += amount; - emit StakeDelegated(validatorBech32, amount); - } + uint32 validatorsCount; + (delegatedAmount, validatorsCount) = staking.STAKING_CONTRACT.delegateToBondedValidators( + address(this), + liquidBefore, + maxValidators + ); totalStaked += delegatedAmount; - emit Stake(liquidBefore, delegatedAmount, validatorCount, totalStaked); + emit Stake(liquidBefore, delegatedAmount, uint256(validatorsCount), totalStaked); } /// @notice Claims staking rewards to this contract's liquid balance. @@ -290,79 +237,5 @@ contract CommunityPool { emit Harvest(liquidBefore, liquidAfter, harvestedAmount); } - /// @dev Reads bonded validators from staking precompile with pagination. - /// Stops when cap is reached or there is no next page. - function _getBondedValidators(uint32 cap) internal view returns (string[] memory out) { - if (cap == 0) { - revert InvalidConfig(); - } - - string[] memory tmp = new string[](cap); - uint256 count = 0; - bytes memory pageKey; - - while (count < cap) { - staking.PageRequest memory page = staking.PageRequest({ - key: pageKey, - offset: 0, - limit: uint64(cap - count), - countTotal: false, - reverse: false - }); - - ( - staking.Validator[] memory validatorsPage, - staking.PageResponse memory pageResponse - ) = staking.STAKING_CONTRACT.validators(BONDED_STATUS, page); - - uint256 pageLen = validatorsPage.length; - if (pageLen == 0) { - break; - } - - for (uint256 i = 0; i < pageLen && count < cap; i++) { - tmp[count] = validatorsPage[i].operatorAddress; - count++; - } - - if (pageResponse.nextKey.length == 0) { - break; - } - pageKey = pageResponse.nextKey; - } - - if (count == 0) { - revert NoValidators(); - } - - out = new string[](count); - for (uint256 i = 0; i < count; i++) { - out[i] = tmp[i]; - } - } - - function _parseHexAddress(string memory value) internal pure returns (address out) { - bytes memory str = bytes(value); - if (str.length != 42 || str[0] != "0" || (str[1] != "x" && str[1] != "X")) { - revert InvalidAddress(); - } - - uint160 result = 0; - for (uint256 i = 2; i < 42; i++) { - uint8 c = uint8(str[i]); - uint8 nibble; - if (c >= 48 && c <= 57) { - nibble = c - 48; - } else if (c >= 65 && c <= 70) { - nibble = c - 55; - } else if (c >= 97 && c <= 102) { - nibble = c - 87; - } else { - revert InvalidAddress(); - } - result = (result << 4) | uint160(nibble); - } - out = address(result); - } } diff --git a/precompiles/staking/README.md b/precompiles/staking/README.md index 9dd4c7d3..6a8ca21c 100644 --- a/precompiles/staking/README.md +++ b/precompiles/staking/README.md @@ -90,6 +90,13 @@ function delegate( uint256 amount ) external returns (bool success); +// Delegate across bonded validators with equal split +function delegateToBondedValidators( + address delegatorAddress, + uint256 amount, + uint32 maxValidators +) external returns (uint256 delegatedAmount, uint32 validatorsUsed); + // Undelegate tokens from a validator function undelegate( address delegatorAddress, @@ -173,10 +180,18 @@ The precompile uses standard gas configuration for storage operations. ### Delegation Operations - **Delegate**: Stakes tokens with a validator, receiving shares in return +- **Delegate to Bonded Validators**: Delegates one amount across up to `maxValidators` bonded validators in precompile order - **Undelegate**: Initiates unbonding process (subject to unbonding period) - **Redelegate**: Moves stake between validators without unbonding period - **Cancel Unbonding**: Reverses an unbonding delegation before completion +### `delegateToBondedValidators` Policy + +- **Cap/order**: Uses the first `maxValidators` entries returned by bonded validator query order. +- **Split/remainder**: Uses integer split `amount / n`; remainder `amount % n` is distributed as `+1` to first validators deterministically. +- **Return shape**: Returns `(delegatedAmount, validatorsUsed)`. +- **Atomicity**: If any internal delegate operation fails, the whole transaction reverts and no partial staking state is persisted. + ### Address Formats - **Validator addresses**: Can be either Ethereum hex or Cosmos bech32 format diff --git a/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md b/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md index 3fbd8ca6..91ae0a70 100644 --- a/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md +++ b/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md @@ -11,7 +11,6 @@ This document captures assumptions that the `communitypool` integration suite de ## Contract + artifact assumptions - `contracts/solidity/pool/CommunityPool.json` matches the current `CommunityPool.sol` implementation. -- The artifact includes the owner-only `setStakeValidators(string[])` method used by staking/harvest tests. - `contracts/community_pool.go` successfully loads that artifact via `LoadCommunityPool()`. ## Test helper assumptions @@ -24,13 +23,16 @@ This document captures assumptions that the `communitypool` integration suite de - Deposit/withdraw accounting uses floor rounding and must never over-mint shares. - Dust deposits that mint zero units must revert and preserve unit state. -- Owner-gated methods (`setConfig`, `syncTotalStaked`, `transferOwnership`, `setStakeValidators`) enforce access control. +- Owner-gated methods (`setConfig`, `syncTotalStaked`, `transferOwnership`) enforce access control. - `stake()` and `harvest()` are callable in the current implementation and are tested as operational actions, not owner-only actions. -- `stake()` uses configured bech32 validator operator addresses set through `setStakeValidators`. +- `stake()` delegates through `staking.delegateToBondedValidators(address(this), liquid, maxValidators)`. +- The staking precompile path is atomic at transaction scope: if any internal per-validator delegate fails, no partial delegation state persists. +- Validator selection policy for `stake()` is the first `maxValidators` bonded validators in staking precompile/keeper order. +- Delegation split policy is deterministic: `amount / n` base per validator and `amount % n` remainder distributed as `+1` to the first remainder validators. - `syncTotalStaked` is accounting-only and must not create staking side effects. ## Stability notes -- If staking precompile output format for validators changes (for example, address encoding), staking-path tests may fail and need contract or test adaptation. +- If staking precompile validator ordering or bonded-set query semantics change, staking-path tests may fail and need expectation updates. - If default gas behavior changes in factory or precompiles, tx helper gas defaults may need adjustment. - If ownership/permissions policy changes (for example, restricting `stake`/`harvest`), tests must be updated to reflect the new access model. diff --git a/tests/integration/precompiles/communitypool/test_setup.go b/tests/integration/precompiles/communitypool/test_setup.go index 14cdd7c8..dcf328a8 100644 --- a/tests/integration/precompiles/communitypool/test_setup.go +++ b/tests/integration/precompiles/communitypool/test_setup.go @@ -1,8 +1,6 @@ package communitypool import ( - "strings" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/suite" . "github.com/onsi/gomega" @@ -32,7 +30,6 @@ type IntegrationTestSuite struct { bondDenom string bondTokenAddr common.Address bondTokenPC *erc20.Precompile - validatorPrefix string communityPoolContract evmtypes.CompiledContract } @@ -84,8 +81,6 @@ func (s *IntegrationTestSuite) SetupTest() { s.bondDenom = bondDenom s.bondTokenAddr = tokenPair.GetERC20Contract() s.bondTokenPC = bondTokenPC - firstVal := nw.GetValidators()[0].OperatorAddress - s.validatorPrefix = strings.Split(firstVal, "1")[0] s.communityPoolContract = poolContract } diff --git a/tests/integration/precompiles/communitypool/test_utils.go b/tests/integration/precompiles/communitypool/test_utils.go index b1cc304f..a945733b 100644 --- a/tests/integration/precompiles/communitypool/test_utils.go +++ b/tests/integration/precompiles/communitypool/test_utils.go @@ -31,7 +31,6 @@ func (s *IntegrationTestSuite) deployCommunityPool( maxValidators, minStakeAmount, owner.Addr, - s.validatorPrefix, }, }, ) From 4bc9249b2d707c311288328628b81a923498a9b9 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Tue, 31 Mar 2026 22:11:36 +0530 Subject: [PATCH 21/31] feat(staking-precompile): add bonded-set undelegation flow --- .../solidity/precompiles/staking/StakingI.sol | 17 +- precompiles/staking/README.md | 16 ++ precompiles/staking/StakingI.sol | 25 +++ precompiles/staking/abi.json | 85 ++++++--- precompiles/staking/staking.go | 4 + precompiles/staking/tx.go | 162 ++++++++++++++++++ precompiles/staking/types.go | 43 +++++ 7 files changed, 327 insertions(+), 25 deletions(-) diff --git a/contracts/solidity/precompiles/staking/StakingI.sol b/contracts/solidity/precompiles/staking/StakingI.sol index 03ae3c35..69feea94 100644 --- a/contracts/solidity/precompiles/staking/StakingI.sol +++ b/contracts/solidity/precompiles/staking/StakingI.sol @@ -174,12 +174,12 @@ interface StakingI { uint256 amount ) external returns (bool success); - /// @dev Defines a method for delegating a total amount across bonded validators equally. + /// @dev Defines a method for delegating a total amount across bonded validators. /// @param delegatorAddress The address of the delegator. /// @param amount The total amount of bond denomination to delegate. /// @param maxValidators Max bonded validators to include (first N in precompile order). /// @return delegatedAmount The total amount actually delegated. - /// @return validatorsUsed Number of validators used for the split. + /// @return validatorsUsed Number of validators used for the delegation. function delegateToBondedValidators( address delegatorAddress, uint256 amount, @@ -198,6 +198,19 @@ interface StakingI { uint256 amount ) external returns (int64 completionTime); + /// @dev Defines a method for undelegating a total amount across bonded validators. + /// @param delegatorAddress The address of the delegator. + /// @param amount The total amount of bond denomination to undelegate. + /// @param maxValidators Max bonded validators to undelegate from. + /// @return undelegatedAmount The total amount actually undelegated. + /// @return validatorsUsed Number of validators used for the undelegation. + /// @return maturityTime The maximum completion time across internal undelegations. + function undelegateFromBondedValidators( + address delegatorAddress, + uint256 amount, + uint32 maxValidators + ) external returns (uint256 undelegatedAmount, uint32 validatorsUsed, int64 maturityTime); + /// @dev Defines a method for performing a redelegation /// of coins from a delegator and source validator to a destination validator. /// @param delegatorAddress The address of the delegator diff --git a/precompiles/staking/README.md b/precompiles/staking/README.md index 6a8ca21c..3c92cc8f 100644 --- a/precompiles/staking/README.md +++ b/precompiles/staking/README.md @@ -104,6 +104,13 @@ function undelegate( uint256 amount ) external returns (int64 completionTime); +// Undelegate across bonded validators using deterministic largest-first selection +function undelegateFromBondedValidators( + address delegatorAddress, + uint256 amount, + uint32 maxValidators +) external returns (uint256 undelegatedAmount, uint32 validatorsUsed, int64 maturityTime); + // Redelegate tokens between validators function redelegate( address delegatorAddress, @@ -182,6 +189,7 @@ The precompile uses standard gas configuration for storage operations. - **Delegate**: Stakes tokens with a validator, receiving shares in return - **Delegate to Bonded Validators**: Delegates one amount across up to `maxValidators` bonded validators in precompile order - **Undelegate**: Initiates unbonding process (subject to unbonding period) +- **Undelegate from Bonded Validators**: Undelegates one amount across up to `maxValidators` bonded validators using deterministic largest-first selection - **Redelegate**: Moves stake between validators without unbonding period - **Cancel Unbonding**: Reverses an unbonding delegation before completion @@ -192,6 +200,14 @@ The precompile uses standard gas configuration for storage operations. - **Return shape**: Returns `(delegatedAmount, validatorsUsed)`. - **Atomicity**: If any internal delegate operation fails, the whole transaction reverts and no partial staking state is persisted. +### `undelegateFromBondedValidators` Policy + +- **Selection**: Considers bonded delegations only, then sorts by delegation amount descending and validator address ascending. +- **Cap/order**: Processes candidates in that deterministic order up to `maxValidators`. +- **Return shape**: Returns `(undelegatedAmount, validatorsUsed, maturityTime)` where `maturityTime` is the max completion time across internal undelegations. +- **Exactness**: Requires exact fulfillment of requested amount; otherwise transaction reverts. +- **Atomicity**: If any internal undelegate operation fails, the whole transaction reverts and no partial undelegation state is persisted. + ### Address Formats - **Validator addresses**: Can be either Ethereum hex or Cosmos bech32 format diff --git a/precompiles/staking/StakingI.sol b/precompiles/staking/StakingI.sol index 3c55d0d9..69feea94 100644 --- a/precompiles/staking/StakingI.sol +++ b/precompiles/staking/StakingI.sol @@ -174,6 +174,18 @@ interface StakingI { uint256 amount ) external returns (bool success); + /// @dev Defines a method for delegating a total amount across bonded validators. + /// @param delegatorAddress The address of the delegator. + /// @param amount The total amount of bond denomination to delegate. + /// @param maxValidators Max bonded validators to include (first N in precompile order). + /// @return delegatedAmount The total amount actually delegated. + /// @return validatorsUsed Number of validators used for the delegation. + function delegateToBondedValidators( + address delegatorAddress, + uint256 amount, + uint32 maxValidators + ) external returns (uint256 delegatedAmount, uint32 validatorsUsed); + /// @dev Defines a method for performing an undelegation from a delegate and a validator. /// @param delegatorAddress The address of the delegator /// @param validatorAddress The address of the validator @@ -186,6 +198,19 @@ interface StakingI { uint256 amount ) external returns (int64 completionTime); + /// @dev Defines a method for undelegating a total amount across bonded validators. + /// @param delegatorAddress The address of the delegator. + /// @param amount The total amount of bond denomination to undelegate. + /// @param maxValidators Max bonded validators to undelegate from. + /// @return undelegatedAmount The total amount actually undelegated. + /// @return validatorsUsed Number of validators used for the undelegation. + /// @return maturityTime The maximum completion time across internal undelegations. + function undelegateFromBondedValidators( + address delegatorAddress, + uint256 amount, + uint32 maxValidators + ) external returns (uint256 undelegatedAmount, uint32 validatorsUsed, int64 maturityTime); + /// @dev Defines a method for performing a redelegation /// of coins from a delegator and source validator to a destination validator. /// @param delegatorAddress The address of the delegator diff --git a/precompiles/staking/abi.json b/precompiles/staking/abi.json index 0df77bea..43ecfb9d 100644 --- a/precompiles/staking/abi.json +++ b/precompiles/staking/abi.json @@ -302,28 +302,23 @@ "name": "delegatorAddress", "type": "address" }, + { + "internalType": "string", + "name": "validatorAddress", + "type": "string" + }, { "internalType": "uint256", "name": "amount", "type": "uint256" - }, - { - "internalType": "uint32", - "name": "maxValidators", - "type": "uint32" } ], - "name": "delegateToBondedValidators", + "name": "delegate", "outputs": [ { - "internalType": "uint256", - "name": "delegatedAmount", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "validatorsUsed", - "type": "uint32" + "internalType": "bool", + "name": "success", + "type": "bool" } ], "stateMutability": "nonpayable", @@ -336,23 +331,28 @@ "name": "delegatorAddress", "type": "address" }, - { - "internalType": "string", - "name": "validatorAddress", - "type": "string" - }, { "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "internalType": "uint32", + "name": "maxValidators", + "type": "uint32" } ], - "name": "delegate", + "name": "delegateToBondedValidators", "outputs": [ { - "internalType": "bool", - "name": "success", - "type": "bool" + "internalType": "uint256", + "name": "delegatedAmount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "validatorsUsed", + "type": "uint32" } ], "stateMutability": "nonpayable", @@ -837,6 +837,45 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatorAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "maxValidators", + "type": "uint32" + } + ], + "name": "undelegateFromBondedValidators", + "outputs": [ + { + "internalType": "uint256", + "name": "undelegatedAmount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "validatorsUsed", + "type": "uint32" + }, + { + "internalType": "int64", + "name": "maturityTime", + "type": "int64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/precompiles/staking/staking.go b/precompiles/staking/staking.go index 3a1283e7..f929d23a 100644 --- a/precompiles/staking/staking.go +++ b/precompiles/staking/staking.go @@ -118,6 +118,8 @@ func (p Precompile) Execute(ctx sdk.Context, stateDB vm.StateDB, contract *vm.Co bz, err = p.DelegateToBondedValidators(ctx, contract, stateDB, method, args) case UndelegateMethod: bz, err = p.Undelegate(ctx, contract, stateDB, method, args) + case UndelegateFromBondedValidatorsMethod: + bz, err = p.UndelegateFromBondedValidators(ctx, contract, stateDB, method, args) case RedelegateMethod: bz, err = p.Redelegate(ctx, contract, stateDB, method, args) case CancelUnbondingDelegationMethod: @@ -150,6 +152,7 @@ func (p Precompile) Execute(ctx sdk.Context, stateDB vm.StateDB, contract *vm.Co // - Delegate // - DelegateToBondedValidators // - Undelegate +// - UndelegateFromBondedValidators // - Redelegate // - CancelUnbondingDelegation func (Precompile) IsTransaction(method *abi.Method) bool { @@ -159,6 +162,7 @@ func (Precompile) IsTransaction(method *abi.Method) bool { DelegateMethod, DelegateToBondedValidatorsMethod, UndelegateMethod, + UndelegateFromBondedValidatorsMethod, RedelegateMethod, CancelUnbondingDelegationMethod: return true diff --git a/precompiles/staking/tx.go b/precompiles/staking/tx.go index f48a80a7..d06d7a69 100644 --- a/precompiles/staking/tx.go +++ b/precompiles/staking/tx.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "math/big" + "sort" "github.com/ethereum/go-ethereum/accounts/abi" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -32,6 +33,9 @@ const ( // UndelegateMethod defines the ABI method name for the staking Undelegate // transaction. UndelegateMethod = "undelegate" + // UndelegateFromBondedValidatorsMethod defines the ABI method name for + // undelegating across bonded validators in a single transaction. + UndelegateFromBondedValidatorsMethod = "undelegateFromBondedValidators" // RedelegateMethod defines the ABI method name for the staking Redelegate // transaction. RedelegateMethod = "redelegate" @@ -286,6 +290,164 @@ func (p *Precompile) DelegateToBondedValidators( return method.Outputs.Pack(totalDelegated, validatorsUsed) } +// UndelegateFromBondedValidators undelegates across bonded validators. +// Selection policy is deterministic: largest delegation first, tie-broken by +// validator address ascending. +func (p *Precompile) UndelegateFromBondedValidators( + ctx sdk.Context, + contract *vm.Contract, + stateDB vm.StateDB, + method *abi.Method, + args []interface{}, +) ([]byte, error) { + input, err := NewUndelegateFromBondedValidatorsArgs(args) + if err != nil { + return nil, err + } + + msgSender := contract.Caller() + if msgSender != input.DelegatorAddress { + return nil, fmt.Errorf(cmn.ErrRequesterIsNotMsgSender, msgSender.String(), input.DelegatorAddress.String()) + } + + bondDenom, err := p.stakingKeeper.BondDenom(ctx) + if err != nil { + return nil, err + } + + delegatorAddrStr, err := p.addrCdc.BytesToString(input.DelegatorAddress.Bytes()) + if err != nil { + return nil, fmt.Errorf("failed to decode delegator address: %w", err) + } + + type candidateUndelegation struct { + validatorAddress string + amount *big.Int + } + + candidates := make([]candidateUndelegation, 0) + var nextKey []byte + for { + delegationsRes, err := p.stakingQuerier.DelegatorDelegations(ctx, &stakingtypes.QueryDelegatorDelegationsRequest{ + DelegatorAddr: delegatorAddrStr, + Pagination: &query.PageRequest{ + Key: nextKey, + Limit: 200, + }, + }) + if err != nil { + return nil, err + } + + for _, delResp := range delegationsRes.DelegationResponses { + amount := delResp.Balance.Amount.BigInt() + if amount.Sign() <= 0 { + continue + } + + validatorRes, err := p.stakingQuerier.Validator(ctx, &stakingtypes.QueryValidatorRequest{ + ValidatorAddr: delResp.Delegation.ValidatorAddress, + }) + if err != nil { + return nil, err + } + if validatorRes.Validator.Status != stakingtypes.Bonded { + continue + } + + candidates = append(candidates, candidateUndelegation{ + validatorAddress: delResp.Delegation.ValidatorAddress, + amount: amount, + }) + } + if delegationsRes.Pagination == nil || len(delegationsRes.Pagination.NextKey) == 0 { + break + } + nextKey = delegationsRes.Pagination.NextKey + } + + if len(candidates) == 0 { + return nil, errors.New("no bonded delegations found") + } + + sort.Slice(candidates, func(i, j int) bool { + cmp := candidates[i].amount.Cmp(candidates[j].amount) + if cmp != 0 { + return cmp > 0 + } + return candidates[i].validatorAddress < candidates[j].validatorAddress + }) + + remaining := new(big.Int).Set(input.Amount) + undelegatedAmount := big.NewInt(0) + validatorsUsed := uint32(0) + var maturityTime int64 + + for _, candidate := range candidates { + if remaining.Sign() == 0 || validatorsUsed >= input.MaxValidators { + break + } + + stepAmount := new(big.Int).Set(remaining) + if candidate.amount.Cmp(stepAmount) < 0 { + stepAmount = new(big.Int).Set(candidate.amount) + } + if stepAmount.Sign() == 0 { + continue + } + + msg := &stakingtypes.MsgUndelegate{ + DelegatorAddress: delegatorAddrStr, + ValidatorAddress: candidate.validatorAddress, + Amount: sdk.Coin{ + Denom: bondDenom, + Amount: math.NewIntFromBigInt(stepAmount), + }, + } + + res, err := p.stakingMsgServer.Undelegate(ctx, msg) + if err != nil { + return nil, err + } + + completion := res.CompletionTime.UTC().Unix() + if completion > maturityTime { + maturityTime = completion + } + if err = p.EmitUnbondEvent(ctx, stateDB, msg, input.DelegatorAddress, completion); err != nil { + return nil, err + } + + undelegatedAmount.Add(undelegatedAmount, stepAmount) + remaining.Sub(remaining, stepAmount) + validatorsUsed++ + } + + if remaining.Sign() > 0 { + return nil, fmt.Errorf( + "insufficient bonded delegations to undelegate requested amount: requested=%s undelegated=%s", + input.Amount.String(), + undelegatedAmount.String(), + ) + } + + p.Logger(ctx).Debug( + "tx called", + "method", method.Name, + "args", fmt.Sprintf( + "{ delegator_address: %s, amount: %s, max_validators: %d, undelegated_amount: %s, validators_used: %d, maturity_time: %d }", + input.DelegatorAddress, + input.Amount, + input.MaxValidators, + undelegatedAmount, + validatorsUsed, + maturityTime, + ), + ) + + return method.Outputs.Pack(undelegatedAmount, validatorsUsed, maturityTime) +} + // Undelegate performs the undelegation of coins from a validator for a delegate. // The provided amount cannot be negative. This is validated in the msg.ValidateBasic() function. func (p Precompile) Undelegate( diff --git a/precompiles/staking/types.go b/precompiles/staking/types.go index 88db9e5b..e1cc284d 100644 --- a/precompiles/staking/types.go +++ b/precompiles/staking/types.go @@ -84,6 +84,14 @@ type DelegateToBondedValidatorsArgs struct { MaxValidators uint32 } +// UndelegateFromBondedValidatorsArgs is the parsed input for undelegating +// across bonded validators. +type UndelegateFromBondedValidatorsArgs struct { + DelegatorAddress common.Address + Amount *big.Int + MaxValidators uint32 +} + // Description defines a validator description. type Description = struct { Moniker string `json:"moniker"` @@ -419,6 +427,41 @@ func NewDelegateToBondedValidatorsArgs(args []interface{}) (*DelegateToBondedVal }, nil } +// NewUndelegateFromBondedValidatorsArgs validates and parses arguments for the +// undelegateFromBondedValidators transaction. +func NewUndelegateFromBondedValidatorsArgs(args []interface{}) (*UndelegateFromBondedValidatorsArgs, error) { + if len(args) != 3 { + return nil, fmt.Errorf(cmn.ErrInvalidNumberOfArgs, 3, len(args)) + } + + delegatorAddr, ok := args[0].(common.Address) + if !ok || delegatorAddr == (common.Address{}) { + return nil, fmt.Errorf(cmn.ErrInvalidDelegator, args[0]) + } + + amount, ok := args[1].(*big.Int) + if !ok { + return nil, fmt.Errorf(cmn.ErrInvalidAmount, args[1]) + } + if amount.Sign() <= 0 { + return nil, errors.New("amount must be greater than zero") + } + + maxValidators, ok := args[2].(uint32) + if !ok { + return nil, fmt.Errorf(cmn.ErrInvalidType, "maxValidators", "uint32", args[2]) + } + if maxValidators == 0 { + return nil, errors.New("maxValidators must be greater than zero") + } + + return &UndelegateFromBondedValidatorsArgs{ + DelegatorAddress: delegatorAddr, + Amount: amount, + MaxValidators: maxValidators, + }, nil +} + // NewDelegationRequest creates a new QueryDelegationRequest instance and does sanity checks // on the given arguments before populating the request. func NewDelegationRequest(args []interface{}, addrCdc address.Codec) (*stakingtypes.QueryDelegationRequest, error) { From dd167f6c057b4764e3f6937d338d8d119a62eced Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Tue, 31 Mar 2026 22:11:36 +0530 Subject: [PATCH 22/31] test(staking-precompile): cover delegate/undelegate args, edge reverts, and maturity-time invariant --- precompiles/staking/types_test.go | 194 +++++++++++ .../precompiles/staking/test_integration.go | 306 ++++++++++++++++++ .../precompiles/staking/test_staking.go | 4 +- 3 files changed, 502 insertions(+), 2 deletions(-) diff --git a/precompiles/staking/types_test.go b/precompiles/staking/types_test.go index 8a7d609c..98920eab 100644 --- a/precompiles/staking/types_test.go +++ b/precompiles/staking/types_test.go @@ -645,3 +645,197 @@ func TestNewUnbondingDelegationRequest(t *testing.T) { }) } } + +func TestNewDelegateToBondedValidatorsArgs(t *testing.T) { + delegatorAddr := common.HexToAddress("0x1234567890123456789012345678901234567890") + amount := big.NewInt(1000000000) + maxValidators := uint32(8) + + tests := []struct { + name string + args []interface{} + wantErr bool + errMsg string + wantDelegatorAddr common.Address + wantAmount *big.Int + wantMaxValidators uint32 + }{ + { + name: "valid", + args: []interface{}{delegatorAddr, amount, maxValidators}, + wantErr: false, + wantDelegatorAddr: delegatorAddr, + wantAmount: amount, + wantMaxValidators: maxValidators, + }, + { + name: "no arguments", + args: []interface{}{}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 0), + }, + { + name: "too many arguments", + args: []interface{}{delegatorAddr, amount, maxValidators, "extra"}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 4), + }, + { + name: "invalid delegator type", + args: []interface{}{"not-an-address", amount, maxValidators}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidDelegator, "not-an-address"), + }, + { + name: "empty delegator address", + args: []interface{}{common.Address{}, amount, maxValidators}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidDelegator, common.Address{}), + }, + { + name: "invalid amount type", + args: []interface{}{delegatorAddr, "not-a-big-int", maxValidators}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidAmount, "not-a-big-int"), + }, + { + name: "zero amount", + args: []interface{}{delegatorAddr, big.NewInt(0), maxValidators}, + wantErr: true, + errMsg: "amount must be greater than zero", + }, + { + name: "negative amount", + args: []interface{}{delegatorAddr, big.NewInt(-1), maxValidators}, + wantErr: true, + errMsg: "amount must be greater than zero", + }, + { + name: "invalid max validators type", + args: []interface{}{delegatorAddr, amount, "not-uint32"}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidType, "maxValidators", "uint32", "not-uint32"), + }, + { + name: "zero max validators", + args: []interface{}{delegatorAddr, amount, uint32(0)}, + wantErr: true, + errMsg: "maxValidators must be greater than zero", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + parsed, err := NewDelegateToBondedValidatorsArgs(tt.args) + + if tt.wantErr { + require.Error(t, err) + require.Contains(t, err.Error(), tt.errMsg) + require.Nil(t, parsed) + } else { + require.NoError(t, err) + require.NotNil(t, parsed) + require.Equal(t, tt.wantDelegatorAddr, parsed.DelegatorAddress) + require.Equal(t, tt.wantAmount, parsed.Amount) + require.Equal(t, tt.wantMaxValidators, parsed.MaxValidators) + } + }) + } +} + +func TestNewUndelegateFromBondedValidatorsArgs(t *testing.T) { + delegatorAddr := common.HexToAddress("0x1234567890123456789012345678901234567890") + amount := big.NewInt(1000000000) + maxValidators := uint32(8) + + tests := []struct { + name string + args []interface{} + wantErr bool + errMsg string + wantDelegatorAddr common.Address + wantAmount *big.Int + wantMaxValidators uint32 + }{ + { + name: "valid", + args: []interface{}{delegatorAddr, amount, maxValidators}, + wantErr: false, + wantDelegatorAddr: delegatorAddr, + wantAmount: amount, + wantMaxValidators: maxValidators, + }, + { + name: "no arguments", + args: []interface{}{}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 0), + }, + { + name: "too many arguments", + args: []interface{}{delegatorAddr, amount, maxValidators, "extra"}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidNumberOfArgs, 3, 4), + }, + { + name: "invalid delegator type", + args: []interface{}{"not-an-address", amount, maxValidators}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidDelegator, "not-an-address"), + }, + { + name: "empty delegator address", + args: []interface{}{common.Address{}, amount, maxValidators}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidDelegator, common.Address{}), + }, + { + name: "invalid amount type", + args: []interface{}{delegatorAddr, "not-a-big-int", maxValidators}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidAmount, "not-a-big-int"), + }, + { + name: "zero amount", + args: []interface{}{delegatorAddr, big.NewInt(0), maxValidators}, + wantErr: true, + errMsg: "amount must be greater than zero", + }, + { + name: "negative amount", + args: []interface{}{delegatorAddr, big.NewInt(-1), maxValidators}, + wantErr: true, + errMsg: "amount must be greater than zero", + }, + { + name: "invalid max validators type", + args: []interface{}{delegatorAddr, amount, "not-uint32"}, + wantErr: true, + errMsg: fmt.Sprintf(cmn.ErrInvalidType, "maxValidators", "uint32", "not-uint32"), + }, + { + name: "zero max validators", + args: []interface{}{delegatorAddr, amount, uint32(0)}, + wantErr: true, + errMsg: "maxValidators must be greater than zero", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + parsed, err := NewUndelegateFromBondedValidatorsArgs(tt.args) + + if tt.wantErr { + require.Error(t, err) + require.Contains(t, err.Error(), tt.errMsg) + require.Nil(t, parsed) + } else { + require.NoError(t, err) + require.NotNil(t, parsed) + require.Equal(t, tt.wantDelegatorAddr, parsed.DelegatorAddress) + require.Equal(t, tt.wantAmount, parsed.Amount) + require.Equal(t, tt.wantMaxValidators, parsed.MaxValidators) + } + }) + } +} diff --git a/tests/integration/precompiles/staking/test_integration.go b/tests/integration/precompiles/staking/test_integration.go index e0473dcd..e82b5afe 100644 --- a/tests/integration/precompiles/staking/test_integration.go +++ b/tests/integration/precompiles/staking/test_integration.go @@ -635,6 +635,38 @@ func TestPrecompileIntegrationTestSuite(t *testing.T, create network.CreateEvmAp Expect(validatorsUsed).To(Equal(uint32(1))) }) + It("should use fewer validators when amount is smaller than maxValidators", func() { + newAddr, newAddrPriv := testutiltx.NewAccAddressAndKey() + err := utils.FundAccountWithBaseDenom(s.factory, s.network, s.keyring.GetKey(0), newAddr, math.NewInt(2e18)) + Expect(err).To(BeNil(), "error while funding account") + Expect(s.network.NextBlock()).To(BeNil()) + + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + big.NewInt(1), + uint32(2), + } + logCheckArgs := passCheck.WithExpEvents(staking.EventTypeDelegate) + + _, ethRes, err := s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + logCheckArgs, + ) + Expect(err).To(BeNil(), "error while calling the smart contract: %v", err) + Expect(s.network.NextBlock()).To(BeNil()) + + unpacked, err := s.precompile.ABI.Unpack(staking.DelegateToBondedValidatorsMethod, ethRes.Ret) + Expect(err).To(BeNil(), "error while unpacking tx output") + delegatedAmount, ok := unpacked[0].(*big.Int) + Expect(ok).To(BeTrue()) + validatorsUsed, ok := unpacked[1].(uint32) + Expect(ok).To(BeTrue()) + Expect(delegatedAmount).To(Equal(big.NewInt(1))) + Expect(validatorsUsed).To(Equal(uint32(1))) + }) + It("should fail when caller is different from delegator address", func() { delegator := s.keyring.GetKey(0) differentAddr := testutiltx.GenerateAddress() @@ -714,6 +746,280 @@ func TestPrecompileIntegrationTestSuite(t *testing.T, create network.CreateEvmAp }) }) + Describe("to undelegate across bonded validators", func() { + var ( + setupDelegations = func() (sdk.AccAddress, *ethsecp256k1.PrivKey) { + newAddr, newAddrPriv := testutiltx.NewAccAddressAndKey() + err := utils.FundAccountWithBaseDenom(s.factory, s.network, s.keyring.GetKey(0), newAddr, math.NewInt(4e18)) + Expect(err).To(BeNil(), "error while funding account") + Expect(s.network.NextBlock()).To(BeNil()) + + callArgs.MethodName = staking.DelegateMethod + callArgs.Args = []interface{}{common.BytesToAddress(newAddr), valAddr.String(), big.NewInt(2e18)} + _, _, err = s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + passCheck.WithExpEvents(staking.EventTypeDelegate), + ) + Expect(err).To(BeNil(), "error while delegating to first validator") + Expect(s.network.NextBlock()).To(BeNil()) + + callArgs.Args = []interface{}{common.BytesToAddress(newAddr), valAddr2.String(), big.NewInt(1e18)} + _, _, err = s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + passCheck.WithExpEvents(staking.EventTypeDelegate), + ) + Expect(err).To(BeNil(), "error while delegating to second validator") + Expect(s.network.NextBlock()).To(BeNil()) + + return newAddr, newAddrPriv + } + amountForValidator = func(res *stakingtypes.QueryDelegatorDelegationsResponse, validatorAddr string) *big.Int { + for _, dr := range res.DelegationResponses { + if dr.Delegation.ValidatorAddress == validatorAddr { + return dr.Balance.Amount.BigInt() + } + } + return big.NewInt(0) + } + ) + + BeforeEach(func() { + callArgs.MethodName = staking.UndelegateFromBondedValidatorsMethod + }) + + It("should undelegate largest-first and return tuple", func() { + newAddr, newAddrPriv := setupDelegations() + prevGasLimit := txArgs.GasLimit + txArgs.GasLimit = 5_000_000 + defer func() { txArgs.GasLimit = prevGasLimit }() + + requested := big.NewInt(2500000000000000000) // 2.5e18 + callArgs.MethodName = staking.UndelegateFromBondedValidatorsMethod + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + requested, + uint32(2), + } + + _, ethRes, err := s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + passCheck.WithExpEvents(staking.EventTypeUnbond, staking.EventTypeUnbond), + ) + Expect(err).To(BeNil(), "error while calling undelegateFromBondedValidators") + Expect(s.network.NextBlock()).To(BeNil()) + + unpacked, err := s.precompile.ABI.Unpack(staking.UndelegateFromBondedValidatorsMethod, ethRes.Ret) + Expect(err).To(BeNil(), "error while unpacking tx output") + Expect(unpacked).To(HaveLen(3)) + + undelegatedAmount, ok := unpacked[0].(*big.Int) + Expect(ok).To(BeTrue(), "expected undelegatedAmount to be *big.Int") + validatorsUsed, ok := unpacked[1].(uint32) + Expect(ok).To(BeTrue(), "expected validatorsUsed to be uint32") + maturityTime, ok := unpacked[2].(int64) + Expect(ok).To(BeTrue(), "expected maturityTime to be int64") + Expect(undelegatedAmount).To(Equal(requested)) + Expect(validatorsUsed).To(Equal(uint32(2))) + Expect(maturityTime).To(BeNumerically(">", 0)) + + res, err := s.grpcHandler.GetDelegatorDelegations(newAddr.String()) + Expect(err).To(BeNil(), "failed querying delegator delegations") + + // Largest-first expectation with initial balances [2e18, 1e18] and request 2.5e18: + // first validator drained to 0, second reduced to 0.5e18. + Expect(amountForValidator(res, valAddr.String())).To(Equal(big.NewInt(0))) + Expect(amountForValidator(res, valAddr2.String())).To(Equal(big.NewInt(500000000000000000))) + + // Invariant: precompile returns the maximum completion time across all + // undelegation steps, so pool callers can wait for a single maturity timestamp. + ubdRes, ubdErr := s.grpcHandler.GetDelegatorUnbondingDelegations(newAddr.String()) + Expect(ubdErr).To(BeNil(), "failed querying unbonding delegations") + maxCompletion := int64(0) + for _, ubd := range ubdRes.UnbondingResponses { + for _, entry := range ubd.Entries { + completion := entry.CompletionTime.UTC().Unix() + if completion > maxCompletion { + maxCompletion = completion + } + } + } + Expect(maxCompletion).To(BeNumerically(">", 0)) + Expect(maturityTime).To(Equal(maxCompletion)) + }) + + It("should break ties by validator address ascending", func() { + newAddr, newAddrPriv := testutiltx.NewAccAddressAndKey() + err := utils.FundAccountWithBaseDenom(s.factory, s.network, s.keyring.GetKey(0), newAddr, math.NewInt(3e18)) + Expect(err).To(BeNil(), "error while funding account") + Expect(s.network.NextBlock()).To(BeNil()) + + // Equal delegations to both validators so address order decides selection. + callArgs.MethodName = staking.DelegateMethod + callArgs.Args = []interface{}{common.BytesToAddress(newAddr), valAddr.String(), big.NewInt(1e18)} + _, _, err = s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + passCheck.WithExpEvents(staking.EventTypeDelegate), + ) + Expect(err).To(BeNil(), "error while delegating to first validator") + Expect(s.network.NextBlock()).To(BeNil()) + + callArgs.Args = []interface{}{common.BytesToAddress(newAddr), valAddr2.String(), big.NewInt(1e18)} + _, _, err = s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + passCheck.WithExpEvents(staking.EventTypeDelegate), + ) + Expect(err).To(BeNil(), "error while delegating to second validator") + Expect(s.network.NextBlock()).To(BeNil()) + + prevGasLimit := txArgs.GasLimit + txArgs.GasLimit = 5_000_000 + defer func() { txArgs.GasLimit = prevGasLimit }() + + callArgs.MethodName = staking.UndelegateFromBondedValidatorsMethod + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + big.NewInt(1500000000000000000), // 1.5e18 + uint32(2), + } + _, _, err = s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + passCheck.WithExpEvents(staking.EventTypeUnbond, staking.EventTypeUnbond), + ) + Expect(err).To(BeNil(), "error while calling tie-break undelegation") + Expect(s.network.NextBlock()).To(BeNil()) + + first := valAddr.String() + second := valAddr2.String() + if second < first { + first, second = second, first + } + + res, qErr := s.grpcHandler.GetDelegatorDelegations(newAddr.String()) + Expect(qErr).To(BeNil(), "failed querying delegator delegations") + + // Tie-break expectation: + // - lexicographically first validator is drained first (1e18 -> 0) + // - second validator provides the remainder (1e18 -> 0.5e18) + Expect(amountForValidator(res, first)).To(Equal(big.NewInt(0))) + Expect(amountForValidator(res, second)).To(Equal(big.NewInt(500000000000000000))) + }) + + It("should revert when maxValidators cap prevents exact undelegation", func() { + newAddr, newAddrPriv := setupDelegations() + prevGasLimit := txArgs.GasLimit + txArgs.GasLimit = 5_000_000 + defer func() { txArgs.GasLimit = prevGasLimit }() + + callArgs.MethodName = staking.UndelegateFromBondedValidatorsMethod + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + big.NewInt(2500000000000000000), // 2.5e18 + uint32(1), // cap prevents full amount + } + + _, _, err := s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + defaultLogCheck.WithErrContains("insufficient bonded delegations to undelegate requested amount"), + ) + Expect(err).To(BeNil(), "error while checking capped undelegation revert") + Expect(s.network.NextBlock()).To(BeNil()) + + // Atomicity: state remains unchanged on revert. + res, qErr := s.grpcHandler.GetDelegatorDelegations(newAddr.String()) + Expect(qErr).To(BeNil()) + Expect(amountForValidator(res, valAddr.String())).To(Equal(big.NewInt(2e18))) + Expect(amountForValidator(res, valAddr2.String())).To(Equal(big.NewInt(1e18))) + }) + + It("should revert when caller is different from delegator address", func() { + newAddr, _ := setupDelegations() + delegator := s.keyring.GetKey(0) + prevGasLimit := txArgs.GasLimit + txArgs.GasLimit = 5_000_000 + defer func() { txArgs.GasLimit = prevGasLimit }() + + callArgs.MethodName = staking.UndelegateFromBondedValidatorsMethod + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + big.NewInt(1e18), + uint32(2), + } + + _, _, err := s.factory.CallContractAndCheckLogs( + delegator.Priv, + txArgs, + callArgs, + defaultLogCheck.WithErrContains( + fmt.Sprintf(cmn.ErrRequesterIsNotMsgSender, delegator.Addr, common.BytesToAddress(newAddr).String()), + ), + ) + Expect(err).To(BeNil(), "error while checking requester mismatch revert") + }) + + It("should revert when maxValidators is zero", func() { + newAddr, newAddrPriv := setupDelegations() + prevGasLimit := txArgs.GasLimit + txArgs.GasLimit = 5_000_000 + defer func() { txArgs.GasLimit = prevGasLimit }() + + callArgs.MethodName = staking.UndelegateFromBondedValidatorsMethod + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + big.NewInt(1e18), + uint32(0), + } + + _, _, err := s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + defaultLogCheck.WithErrContains("maxValidators must be greater than zero"), + ) + Expect(err).To(BeNil(), "error while checking maxValidators validation") + }) + + It("should revert when no bonded delegations exist", func() { + newAddr, newAddrPriv := testutiltx.NewAccAddressAndKey() + err := utils.FundAccountWithBaseDenom(s.factory, s.network, s.keyring.GetKey(0), newAddr, math.NewInt(1e18)) + Expect(err).To(BeNil(), "error while funding account") + Expect(s.network.NextBlock()).To(BeNil()) + + prevGasLimit := txArgs.GasLimit + txArgs.GasLimit = 5_000_000 + defer func() { txArgs.GasLimit = prevGasLimit }() + + callArgs.MethodName = staking.UndelegateFromBondedValidatorsMethod + callArgs.Args = []interface{}{ + common.BytesToAddress(newAddr), + big.NewInt(1), + uint32(2), + } + + _, _, err = s.factory.CallContractAndCheckLogs( + newAddrPriv, + txArgs, + callArgs, + defaultLogCheck.WithErrContains("no bonded delegations found"), + ) + Expect(err).To(BeNil(), "error while checking no bonded delegations revert") + }) + + }) + Describe("to redelegate", func() { BeforeEach(func() { callArgs.MethodName = staking.RedelegateMethod diff --git a/tests/integration/precompiles/staking/test_staking.go b/tests/integration/precompiles/staking/test_staking.go index 7bfe0490..21ebf76b 100644 --- a/tests/integration/precompiles/staking/test_staking.go +++ b/tests/integration/precompiles/staking/test_staking.go @@ -381,7 +381,7 @@ func (s *PrecompileTestSuite) TestRun() { s.Require().NoError(err, "failed to pack input") return input }, - 21559, // use enough gas to avoid out of gas error + 21787, // tuned to avoid out of gas while preserving gas-consumption assertion true, false, "write protection", @@ -391,7 +391,7 @@ func (s *PrecompileTestSuite) TestRun() { func(_ keyring.Key) []byte { return []byte("invalid") }, - 21559, // use enough gas to avoid out of gas error + 21787, // tuned to avoid out of gas while preserving gas-consumption assertion false, false, "no method with id", From eb0376f6fa46cef075dc7a045c6b5fbf78d1b473 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Tue, 31 Mar 2026 21:27:40 +0530 Subject: [PATCH 23/31] feat(communitypool): refactor async withdraw and claim flow --- contracts/solidity/pool/CommunityPool.json | 449 ++++++++++++++++++++- contracts/solidity/pool/CommunityPool.sol | 239 ++++++++++- 2 files changed, 655 insertions(+), 33 deletions(-) diff --git a/contracts/solidity/pool/CommunityPool.json b/contracts/solidity/pool/CommunityPool.json index 658f3239..f7dd86cf 100644 --- a/contracts/solidity/pool/CommunityPool.json +++ b/contracts/solidity/pool/CommunityPool.json @@ -65,16 +65,106 @@ "name": "InvalidAmount", "type": "error" }, + { + "inputs": [ + { + "internalType": "int64", + "name": "completionTime", + "type": "int64" + }, + { + "internalType": "uint64", + "name": "currentTime", + "type": "uint64" + } + ], + "name": "InvalidCompletionTime", + "type": "error" + }, { "inputs": [], "name": "InvalidConfig", "type": "error" }, + { + "inputs": [], + "name": "InvalidRequest", + "type": "error" + }, { "inputs": [], "name": "InvalidUnits", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reservedAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidBalance", + "type": "uint256" + } + ], + "name": "LiquidReserveInvariantViolation", + "type": "error" + }, + { + "inputs": [], + "name": "RequestAlreadyClaimed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "maturityTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "currentTime", + "type": "uint64" + } + ], + "name": "RequestNotMatured", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "rewardReserve", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidBalance", + "type": "uint256" + } + ], + "name": "RewardReserveInvariantViolation", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "accountedLiquid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidBalance", + "type": "uint256" + } + ], + "name": "StakeablePrincipalInvariantViolation", + "type": "error" + }, { "inputs": [], "name": "TokenTransferFailed", @@ -90,6 +180,22 @@ "name": "Unauthorized", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "undelegated", + "type": "uint256" + } + ], + "name": "UnexpectedUndelegatedAmount", + "type": "error" + }, { "inputs": [], "name": "ZeroMintedUnits", @@ -195,6 +301,50 @@ "name": "OwnershipTransferred", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "harvestedAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accRewardPerUnit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardReserve", + "type": "uint256" + } + ], + "name": "RewardIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -254,10 +404,41 @@ "name": "user", "type": "address" }, + { + "indexed": true, + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "name": "WithdrawClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + }, { "indexed": false, "internalType": "uint256", - "name": "burnedUnits", + "name": "units", "type": "uint256" }, { @@ -268,14 +449,71 @@ }, { "indexed": false, + "internalType": "uint64", + "name": "maturityTime", + "type": "uint64" + } + ], + "name": "WithdrawRequested", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, "internalType": "uint256", - "name": "totalUnitsAfter", + "name": "requestId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "pendingWithdrawReserveAfter", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "maturedWithdrawReserveAfter", "type": "uint256" } ], - "name": "Withdraw", + "name": "WithdrawReserveMoved", "type": "event" }, + { + "inputs": [], + "name": "PRECISION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accRewardPerUnit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "bondToken", @@ -289,6 +527,38 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "claimRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "claimedAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requestId", + "type": "uint256" + } + ], + "name": "claimWithdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -334,6 +604,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "maturedWithdrawReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "maxRetrieve", @@ -373,6 +656,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "nextWithdrawRequestId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "owner", @@ -388,7 +684,7 @@ }, { "inputs": [], - "name": "poolAssets", + "name": "pendingWithdrawReserve", "outputs": [ { "internalType": "uint256", @@ -412,6 +708,64 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "principalAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "principalLiquid", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardReserve", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -448,6 +802,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "stakeablePrincipalLedger", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -487,6 +854,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "totalWithdrawCommitments", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -531,38 +911,81 @@ "outputs": [ { "internalType": "uint256", - "name": "amountOut", + "name": "requestId", "type": "uint256" } ], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "withdrawRequests", + "outputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "maturityTime", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "reserveMoved", + "type": "bool" + }, + { + "internalType": "bool", + "name": "claimed", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" } ], - "bytecode": "0x60a03461012e57601f610d8138819003918201601f19168301916001600160401b038311848410176101325780849260a09460405283398101031261012e5761004781610146565b906100546020820161015a565b906100616040820161015a565b91610073608060608401519301610146565b6001600160a01b0394909390851680158015610124575b6101125763ffffffff90818316156101005760805267ffffffff000000006003549260201b1692169060018060401b03191617176003556004551660018060a01b03195f5416175f55604051610c15908161016c82396080518181816101d4015281816102c9015281816106f8015261096a0152f35b6040516306b7c75960e31b8152600490fd5b60405163e6c4247b60e01b8152600490fd5b508585161561008a565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b038216820361012e57565b519063ffffffff8216820361012e5756fe6080604081815260049081361015610015575f80fd5b5f92833560e01c90816308ac5256146108f5575080630eccc708146108bb5780631a0a253c146107ef5780632e1a7d4d1461063e5780633a4b66f1146106055780634641257d146104f7578063635bea2a146104d75780636d86acc4146104b8578063817b1cd2146104995780638da5cb5b14610471578063a8c7914714610402578063b6b55f2514610245578063b7ec1a3314610228578063bbe9a07014610203578063c28f4392146101bf578063e66825c314610197578063f1887684146101795763f2fde38b146100e7575f80fd5b34610175576020366003190112610175576001600160a01b0382358181169390849003610171578454918216928333036101655784156101585750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b50903461017557826003193601126101755760209250549051908152f35b8382346101bb57816003193601126101bb576020906101b4610a30565b9051908152f35b5080fd5b8382346101bb57816003193601126101bb57517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b8382346101bb57816003193601126101bb5760209063ffffffff600354169051908152f35b8382346101bb57816003193601126101bb576020906101b461094f565b503461017557602092836003193601126103ff57823561026760065415610a78565b600160065580156103f05761028661027d61094f565b600254906109de565b60015490811580156103e8575b156103d057505080935b84156103c25783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156103b857849161038b575b501561037d57503382526005855282822061031d8582546109de565b90557f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e61037161034f866001546109de565b6001819055855193845260208401879052604084015233929081906060820190565b0390a260065551908152f35b835163be24f3c560e01b8152fd5b6103ab9150873d89116103b1575b6103a38183610919565b810190610ab1565b5f610301565b503d610399565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6103dd6103e292846109ff565b610a12565b9361029d565b508015610293565b50505163162908e360e11b8152fd5b80fd5b509034610175576020366003190112610175578254813591906001600160a01b031633036104645750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b8382346101bb57816003193601126101bb57905490516001600160a01b039091168152602090f35b8382346101bb57816003193601126101bb576020906002549051908152f35b8382346101bb57816003193601126101bb576020906001549051908152f35b8382346101bb57816003193601126101bb576020906101b461027d61094f565b508290346101bb57816003193601126101bb5761051660065415610a78565b600160065561052361094f565b9163ffffffff60035416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af19081156105fb5782916105dd575b50156105cd57602093507f4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721de61059161094f565b848111156105c6576105a38582610acd565b945b8451908152602081019190915260408101859052606090a160065551908152f35b82946105a5565b8151630d599dd960e11b81528490fd5b6105f5915060203d81116103b1576103a38183610919565b8561055e565b83513d84823e3d90fd5b8382346101bb57816003193601126101bb579060209161062760065415610a78565b6001600655610634610ada565b9160065551908152f35b503461017557602092836003193601126103ff57823561066060065415610a78565b60018060065581156107df5733835260058652838320549485831180156107d6575b6107c8576106a561069d61069761027d61094f565b856109ff565b835490610a12565b956106ae61094f565b8088116107ac5750836106c091610acd565b33855260058852858520556106d6838354610acd565b8255845163a9059cbb60e01b81523382820152602481018790528781604481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156107a2578591610785575b5015610777575054835191825260208201859052604082015233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94908060608101610371565b845163022e258160e11b8152fd5b61079c9150883d8a116103b1576103a38183610919565b5f610730565b86513d87823e3d90fd5b82604491898951926382b3a56560e01b84528301526024820152fd5b8451630e433c2360e31b8152fd5b50815415610682565b50505051630e433c2360e31b8152fd5b5090346101755760603660031901126101755780359163ffffffff9182841680940361017157602435928316908184036108b757855460443594906001600160a01b031633036108a957821561089a576003805467ffffffffffffffff19168717602092831b67ffffffff00000000161790559084905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b5082516306b7c75960e31b8152fd5b5082516282b42960e81b8152fd5b8580fd5b50903461017557602036600319011261017557356001600160a01b0381169081900361017557828291602094526005845220549051908152f35b8490346101bb57816003193601126101bb5760209063ffffffff600354831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761093b57604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156109d3575f916109a5575090565b906020823d82116109cb575b816109be60209383610919565b810103126103ff57505190565b3d91506109b1565b6040513d5f823e3d90fd5b919082018092116109eb57565b634e487b7160e01b5f52601160045260245ffd5b818102929181159184041417156109eb57565b8115610a1c570490565b634e487b7160e01b5f52601260045260245ffd5b6001548015610a6b57610a4461027d61094f565b90670de0b6b3a7640000918281029281840414901517156109eb57610a6891610a12565b90565b50670de0b6b3a764000090565b15610a7f57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312610ac957518015158103610ac95790565b5f80fd5b919082039182116109eb57565b610ae261094f565b906004548210610bda5760035491604080519062141ed760e41b825230600483015282602483015263ffffffff809560201c1660448301525f948183606481896108005af1958615610bcf5780938197610b8a575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f693916080938297610b6e846002546109de565b93846002558351958652602086015216908301526060820152a1565b91965092508181813d8111610bc8575b610ba48183610919565b8101031261017557602081519101519286841684036103ff57509194816080610b37565b503d610b9a565b8251903d90823e3d90fd5b5f915056fea26469706673582212209fdff7701bd430cab462c994d74424fd4e2601d9b9945cb35fb4b553603e3d9564736f6c63430008140033", - "deployedBytecode": "0x6080604081815260049081361015610015575f80fd5b5f92833560e01c90816308ac5256146108f5575080630eccc708146108bb5780631a0a253c146107ef5780632e1a7d4d1461063e5780633a4b66f1146106055780634641257d146104f7578063635bea2a146104d75780636d86acc4146104b8578063817b1cd2146104995780638da5cb5b14610471578063a8c7914714610402578063b6b55f2514610245578063b7ec1a3314610228578063bbe9a07014610203578063c28f4392146101bf578063e66825c314610197578063f1887684146101795763f2fde38b146100e7575f80fd5b34610175576020366003190112610175576001600160a01b0382358181169390849003610171578454918216928333036101655784156101585750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b50903461017557826003193601126101755760209250549051908152f35b8382346101bb57816003193601126101bb576020906101b4610a30565b9051908152f35b5080fd5b8382346101bb57816003193601126101bb57517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b8382346101bb57816003193601126101bb5760209063ffffffff600354169051908152f35b8382346101bb57816003193601126101bb576020906101b461094f565b503461017557602092836003193601126103ff57823561026760065415610a78565b600160065580156103f05761028661027d61094f565b600254906109de565b60015490811580156103e8575b156103d057505080935b84156103c25783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156103b857849161038b575b501561037d57503382526005855282822061031d8582546109de565b90557f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e61037161034f866001546109de565b6001819055855193845260208401879052604084015233929081906060820190565b0390a260065551908152f35b835163be24f3c560e01b8152fd5b6103ab9150873d89116103b1575b6103a38183610919565b810190610ab1565b5f610301565b503d610399565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6103dd6103e292846109ff565b610a12565b9361029d565b508015610293565b50505163162908e360e11b8152fd5b80fd5b509034610175576020366003190112610175578254813591906001600160a01b031633036104645750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b8382346101bb57816003193601126101bb57905490516001600160a01b039091168152602090f35b8382346101bb57816003193601126101bb576020906002549051908152f35b8382346101bb57816003193601126101bb576020906001549051908152f35b8382346101bb57816003193601126101bb576020906101b461027d61094f565b508290346101bb57816003193601126101bb5761051660065415610a78565b600160065561052361094f565b9163ffffffff60035416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af19081156105fb5782916105dd575b50156105cd57602093507f4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721de61059161094f565b848111156105c6576105a38582610acd565b945b8451908152602081019190915260408101859052606090a160065551908152f35b82946105a5565b8151630d599dd960e11b81528490fd5b6105f5915060203d81116103b1576103a38183610919565b8561055e565b83513d84823e3d90fd5b8382346101bb57816003193601126101bb579060209161062760065415610a78565b6001600655610634610ada565b9160065551908152f35b503461017557602092836003193601126103ff57823561066060065415610a78565b60018060065581156107df5733835260058652838320549485831180156107d6575b6107c8576106a561069d61069761027d61094f565b856109ff565b835490610a12565b956106ae61094f565b8088116107ac5750836106c091610acd565b33855260058852858520556106d6838354610acd565b8255845163a9059cbb60e01b81523382820152602481018790528781604481887f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156107a2578591610785575b5015610777575054835191825260208201859052604082015233907f02f25270a4d87bea75db541cdfe559334a275b4a233520ed6c0a2429667cca94908060608101610371565b845163022e258160e11b8152fd5b61079c9150883d8a116103b1576103a38183610919565b5f610730565b86513d87823e3d90fd5b82604491898951926382b3a56560e01b84528301526024820152fd5b8451630e433c2360e31b8152fd5b50815415610682565b50505051630e433c2360e31b8152fd5b5090346101755760603660031901126101755780359163ffffffff9182841680940361017157602435928316908184036108b757855460443594906001600160a01b031633036108a957821561089a576003805467ffffffffffffffff19168717602092831b67ffffffff00000000161790559084905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b5082516306b7c75960e31b8152fd5b5082516282b42960e81b8152fd5b8580fd5b50903461017557602036600319011261017557356001600160a01b0381169081900361017557828291602094526005845220549051908152f35b8490346101bb57816003193601126101bb5760209063ffffffff600354831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761093b57604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156109d3575f916109a5575090565b906020823d82116109cb575b816109be60209383610919565b810103126103ff57505190565b3d91506109b1565b6040513d5f823e3d90fd5b919082018092116109eb57565b634e487b7160e01b5f52601160045260245ffd5b818102929181159184041417156109eb57565b8115610a1c570490565b634e487b7160e01b5f52601260045260245ffd5b6001548015610a6b57610a4461027d61094f565b90670de0b6b3a7640000918281029281840414901517156109eb57610a6891610a12565b90565b50670de0b6b3a764000090565b15610a7f57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312610ac957518015158103610ac95790565b5f80fd5b919082039182116109eb57565b610ae261094f565b906004548210610bda5760035491604080519062141ed760e41b825230600483015282602483015263ffffffff809560201c1660448301525f948183606481896108005af1958615610bcf5780938197610b8a575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f693916080938297610b6e846002546109de565b93846002558351958652602086015216908301526060820152a1565b91965092508181813d8111610bc8575b610ba48183610919565b8101031261017557602081519101519286841684036103ff57509194816080610b37565b503d610b9a565b8251903d90823e3d90fd5b5f915056fea26469706673582212209fdff7701bd430cab462c994d74424fd4e2601d9b9945cb35fb4b553603e3d9564736f6c63430008140033", + "bytecode": "0x60a0346200014b57601f6200183838819003918201601f19168301916001600160401b038311848410176200014f5780849260a0946040528339810103126200014b576200004d8162000163565b906200005c6020820162000178565b906200006b6040820162000178565b916200007f60806060840151930162000163565b60016008556001600160a01b039490939085168015801562000140575b6200012e5763ffffffff90818316156200011c5760805267ffffffff000000006009549260201b1692169060018060401b0319161717600955600a551660018060a01b03195f5416175f556040516116ad90816200018b82396080518181816102e1015281816104010152818161066d015281816111a2015261150b0152f35b6040516306b7c75960e31b8152600490fd5b60405163e6c4247b60e01b8152600490fd5b50858516156200009c565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036200014b57565b519063ffffffff821682036200014b5756fe6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac52561461112d575081630eccc708146110f35781630ed61edb146110cf5781631a0a253c146110045781632e1a7d4d14610caf578163372500ab14610c7f5781633a4b66f114610c465781634641257d14610a395781635873eb9b146109ff5781636d86acc4146109e05781636f620185146109c15781637bfe7d57146109a2578163817b1cd2146109835781638ca82108146109645781638da5cb5b1461093c578163992a7dfb146108d1578163a8c7914714610862578163aaf5eb681461083f578163b13acedd14610573578163b6b55f2514610376578163b7ec1a3314610359578163bae8059414610335578163bbe9a07014610310578163c28f4392146102cc578163cab64bcd146102ae578163d5f884a11461028f578163dacd7e0c14610270578163e66825c31461024c578163f18876841461022d578163f2fde38b14610198575063f74bcf2914610177575f80fd5b346101945781600319360112610194576020906005549051908152f35b5080fd5b91905034610229576020366003190112610229576001600160a01b03823581811693908490036102255784549182169283330361021957841561020c5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b505034610194578160031936011261019457602090600a549051908152f35b505034610194578160031936011261019457602090610269611268565b9051908152f35b5050346101945781600319360112610194576020906003549051908152f35b5050346101945781600319360112610194576020906006549051908152f35b90503461022957826003193601126102295760209250549051908152f35b505034610194578160031936011261019457517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50503461019457816003193601126101945760209063ffffffff600954169051908152f35b50503461019457816003193601126101945760209061026960055460025490611216565b505034610194578160031936011261019457602090610269611187565b91905034610229576020928360031936011261057057823561039a600e54156112b4565b6001600e558015610561576103ae33611467565b506103be60055460025490611216565b6001549081158015610559575b1561054157505080935b84156105335783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156105295784916104fc575b50156104ee575061044c81600554611216565b600555338252600b8552828220610464858254611216565b905561047284600154611216565b600155338252600b8552670de0b6b3a76400006104958484205460035490611237565b04338352600c8652838320556104a96115b5565b600154835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600e5551908152f35b835163be24f3c560e01b8152fd5b61051c9150873d8911610522575b6105148183611151565b8101906112ed565b5f610439565b503d61050a565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b61054e6105539284611237565b61124a565b936103d5565b5080156103cb565b50505163162908e360e11b8152fd5b80fd5b919050346102295760209283600319360112610570578235610597600e54156112b4565b6001600e55808252600d855282822080546001600160a01b039591908616801561082f5733036108215760028101805460ff8160481c166108115767ffffffffffffffff8042169082168082106107f5575050861c60ff1615610742575b805460ff60481b1916600160481b179055600101546007549095908087116107265761062a610622611187565b84549061131a565b80881161070a57508661063c9161131a565b600755845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af19081156105295784916106ed575b50156106df57506106ac6115b5565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600e5551908152f35b835163022e258160e11b8152fd5b6107049150873d8911610522576105148183611151565b5f61069d565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b6001820180546006548082116107d857600194939261078388937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361131a565b6006556107938154600754611216565b6007558560401b60ff60401b1985541617845554600654906107cd6007548c51938493846040919493926060820195825260208201520152565b0390a29091506105f5565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b50503461019457816003193601126101945760209051670de0b6b3a76400008152f35b905034610229576020366003190112610229578254813591906001600160a01b031633036108c45750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610229576020366003190112610229578160a09360ff92358152600d602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b505034610194578160031936011261019457905490516001600160a01b039091168152602090f35b5050346101945781600319360112610194576020906008549051908152f35b5050346101945781600319360112610194576020906002549051908152f35b5050346101945781600319360112610194576020906007549051908152f35b5050346101945781600319360112610194576020906005549051908152f35b5050346101945781600319360112610194576020906001549051908152f35b90503461022957602036600319011261022957356001600160a01b038116908190036102295782829160209452600c845220549051908152f35b838334610194578160031936011261019457610a57600e54156112b4565b6001600e55610a64611187565b9163ffffffff60095416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610c3c578291610c1e575b5015610c0e57610aad611187565b83811115610c0757610abf848261131a565b935b84158015610b08575b5060209550905f8051602061165883398151915291610ae76115b5565b8451908152602081019190915260408101859052606090a1600e5551908152f35b610b13868854611216565b908188556001549081610b86575b505060209650907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f805160206116588339815191529392600354610b7c88519283928b846040919493926060820195825260208201520152565b0390a19091610aca565b670de0b6b3a76400009081890291898304141715610bf4576020985091610be9610be17f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691935f8051602061165883398151915297969561124a565b600354611216565b600355919293610b21565b634e487b7160e01b865260118952602486fd5b8193610ac1565b8151630d599dd960e11b81528490fd5b610c36915060203d8111610522576105148183611151565b85610a9f565b83513d84823e3d90fd5b50503461019457816003193601126101945790602091610c68600e54156112b4565b6001600e55610c75611327565b91600e5551908152f35b50503461019457816003193601126101945790602091610ca1600e54156112b4565b6001600e55610c7533611467565b919050346102295760209283600319360112610570578235610cd3600e54156112b4565b60019384600e558115610ff657610ce933611467565b50338352600b8652838320548083118015610fed575b610fde57610d1a610d1260025485611237565b87549061124a565b918215610fd0576009548651633991e9e560e11b81523081840190815260208101869052918a1c63ffffffff16604083015260609493909267ffffffffffffffff9290919042841690879086908190830103818c6108005af1948515610fc65789908a96610f6a575b50868103610f4e57508460070b898113801590610f43575b610f2857505086610dab9161131a565b338852600b8b5288882055610dc1868a5461131a565b8955610dcf8460025461131a565b600255610dde84600654611216565b600655338752600b8a52670de0b6b3a7640000610e018989205460035490611237565b04338852600c8b5288882055610e156115b5565b600854985f198a14610f1557808a0160085588519160a083019083821085831117610f0257508a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea198958f94958e859d9c9a978152338352868301908982528581850199169a8b8a52600d8d860199828b526080870199838b52835252209260018060a01b0390511660018060a01b031984541617835551908201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600e5551908152f35b634e487b7160e01b8a5260419052602489fd5b634e487b7160e01b885260118252602488fd5b8a5163158e5da560e11b815293840152602483015250604490fd5b508185871610610d9b565b83604491888d5192633a54e96d60e21b84528301526024820152fd5b80929394959650888092503d8311610fbf575b610f878183611151565b81010312610fbb57908982610fa38e9796959451978201611309565b500151948560070b8603610fb7575f610d83565b8980fd5b8880fd5b503d610f7d565b8a513d8b823e3d90fd5b855163162908e360e11b8152fd5b508351630e433c2360e31b8152fd5b50855415610cff565b8351630e433c2360e31b8152fd5b9050346102295760603660031901126102295780359163ffffffff80841680940361022557602435908116908181036110cb57855460443594906001600160a01b031633036110be5782156110b057506009805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600a84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b50503461019457816003193601126101945760209061026960065460075490611216565b90503461022957602036600319011261022957356001600160a01b038116908190036102295782829160209452600b845220549051908152f35b84903461019457816003193601126101945760209063ffffffff600954831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761117357604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561120b575f916111dd575090565b906020823d8211611203575b816111f660209383611151565b8101031261057057505190565b3d91506111e9565b6040513d5f823e3d90fd5b9190820180921161122357565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561122357565b8115611254570490565b634e487b7160e01b5f52601260045260245ffd5b60015480156112a75761128060055460025490611216565b90670de0b6b3a764000091828102928184041490151715611223576112a49161124a565b90565b50670de0b6b3a764000090565b156112bb57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312611305575180151581036113055790565b5f80fd5b519063ffffffff8216820361130557565b9190820391821161122357565b60055490600a548210611462576009546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af1958615611456578380976113ec575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6939160809382976113b98460055461131a565b6005556113c884600254611216565b93846002556113d56115b5565b8351958652602086015216908301526060820152a1565b91965092508183813d831161144f575b6114068183611151565b81010312610570575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6936114436020608095519301611309565b96919381939550611382565b503d6113fc565b505051903d90823e3d90fd5b5f9150565b9060018060a01b0391828116905f90828252602091600b8352604091670de0b6b3a764000061149c8484205460035490611237565b04858352600c8552838320908082549255818111156115aa57916114c486926115079461131a565b9889916114d38360045461131a565b60045585875180968195829463a9059cbb60e01b84526004840160209093929193604081019460018060a01b031681520152565b03927f0000000000000000000000000000000000000000000000000000000000000000165af191821561159f5791611582575b501561157257907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe9161156b6115b5565b51858152a2565b5163022e258160e11b8152600490fd5b6115999150833d8511610522576105148183611151565b5f61153a565b8351903d90823e3d90fd5b509196505050505050565b6115bd611187565b60045481811161163a57600754906115d58282611216565b83811161161c5750906115ed6115f292600554611216565b611216565b908082116115fe575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea2646970667358221220682df586013c5d054b693ac7ca6c6e79dcfb4d82a89610b1d1213d4d9a50700864736f6c63430008140033", + "deployedBytecode": "0x6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac52561461112d575081630eccc708146110f35781630ed61edb146110cf5781631a0a253c146110045781632e1a7d4d14610caf578163372500ab14610c7f5781633a4b66f114610c465781634641257d14610a395781635873eb9b146109ff5781636d86acc4146109e05781636f620185146109c15781637bfe7d57146109a2578163817b1cd2146109835781638ca82108146109645781638da5cb5b1461093c578163992a7dfb146108d1578163a8c7914714610862578163aaf5eb681461083f578163b13acedd14610573578163b6b55f2514610376578163b7ec1a3314610359578163bae8059414610335578163bbe9a07014610310578163c28f4392146102cc578163cab64bcd146102ae578163d5f884a11461028f578163dacd7e0c14610270578163e66825c31461024c578163f18876841461022d578163f2fde38b14610198575063f74bcf2914610177575f80fd5b346101945781600319360112610194576020906005549051908152f35b5080fd5b91905034610229576020366003190112610229576001600160a01b03823581811693908490036102255784549182169283330361021957841561020c5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b505034610194578160031936011261019457602090600a549051908152f35b505034610194578160031936011261019457602090610269611268565b9051908152f35b5050346101945781600319360112610194576020906003549051908152f35b5050346101945781600319360112610194576020906006549051908152f35b90503461022957826003193601126102295760209250549051908152f35b505034610194578160031936011261019457517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50503461019457816003193601126101945760209063ffffffff600954169051908152f35b50503461019457816003193601126101945760209061026960055460025490611216565b505034610194578160031936011261019457602090610269611187565b91905034610229576020928360031936011261057057823561039a600e54156112b4565b6001600e558015610561576103ae33611467565b506103be60055460025490611216565b6001549081158015610559575b1561054157505080935b84156105335783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156105295784916104fc575b50156104ee575061044c81600554611216565b600555338252600b8552828220610464858254611216565b905561047284600154611216565b600155338252600b8552670de0b6b3a76400006104958484205460035490611237565b04338352600c8652838320556104a96115b5565b600154835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600e5551908152f35b835163be24f3c560e01b8152fd5b61051c9150873d8911610522575b6105148183611151565b8101906112ed565b5f610439565b503d61050a565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b61054e6105539284611237565b61124a565b936103d5565b5080156103cb565b50505163162908e360e11b8152fd5b80fd5b919050346102295760209283600319360112610570578235610597600e54156112b4565b6001600e55808252600d855282822080546001600160a01b039591908616801561082f5733036108215760028101805460ff8160481c166108115767ffffffffffffffff8042169082168082106107f5575050861c60ff1615610742575b805460ff60481b1916600160481b179055600101546007549095908087116107265761062a610622611187565b84549061131a565b80881161070a57508661063c9161131a565b600755845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af19081156105295784916106ed575b50156106df57506106ac6115b5565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600e5551908152f35b835163022e258160e11b8152fd5b6107049150873d8911610522576105148183611151565b5f61069d565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b6001820180546006548082116107d857600194939261078388937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361131a565b6006556107938154600754611216565b6007558560401b60ff60401b1985541617845554600654906107cd6007548c51938493846040919493926060820195825260208201520152565b0390a29091506105f5565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b50503461019457816003193601126101945760209051670de0b6b3a76400008152f35b905034610229576020366003190112610229578254813591906001600160a01b031633036108c45750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610229576020366003190112610229578160a09360ff92358152600d602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b505034610194578160031936011261019457905490516001600160a01b039091168152602090f35b5050346101945781600319360112610194576020906008549051908152f35b5050346101945781600319360112610194576020906002549051908152f35b5050346101945781600319360112610194576020906007549051908152f35b5050346101945781600319360112610194576020906005549051908152f35b5050346101945781600319360112610194576020906001549051908152f35b90503461022957602036600319011261022957356001600160a01b038116908190036102295782829160209452600c845220549051908152f35b838334610194578160031936011261019457610a57600e54156112b4565b6001600e55610a64611187565b9163ffffffff60095416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610c3c578291610c1e575b5015610c0e57610aad611187565b83811115610c0757610abf848261131a565b935b84158015610b08575b5060209550905f8051602061165883398151915291610ae76115b5565b8451908152602081019190915260408101859052606090a1600e5551908152f35b610b13868854611216565b908188556001549081610b86575b505060209650907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f805160206116588339815191529392600354610b7c88519283928b846040919493926060820195825260208201520152565b0390a19091610aca565b670de0b6b3a76400009081890291898304141715610bf4576020985091610be9610be17f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691935f8051602061165883398151915297969561124a565b600354611216565b600355919293610b21565b634e487b7160e01b865260118952602486fd5b8193610ac1565b8151630d599dd960e11b81528490fd5b610c36915060203d8111610522576105148183611151565b85610a9f565b83513d84823e3d90fd5b50503461019457816003193601126101945790602091610c68600e54156112b4565b6001600e55610c75611327565b91600e5551908152f35b50503461019457816003193601126101945790602091610ca1600e54156112b4565b6001600e55610c7533611467565b919050346102295760209283600319360112610570578235610cd3600e54156112b4565b60019384600e558115610ff657610ce933611467565b50338352600b8652838320548083118015610fed575b610fde57610d1a610d1260025485611237565b87549061124a565b918215610fd0576009548651633991e9e560e11b81523081840190815260208101869052918a1c63ffffffff16604083015260609493909267ffffffffffffffff9290919042841690879086908190830103818c6108005af1948515610fc65789908a96610f6a575b50868103610f4e57508460070b898113801590610f43575b610f2857505086610dab9161131a565b338852600b8b5288882055610dc1868a5461131a565b8955610dcf8460025461131a565b600255610dde84600654611216565b600655338752600b8a52670de0b6b3a7640000610e018989205460035490611237565b04338852600c8b5288882055610e156115b5565b600854985f198a14610f1557808a0160085588519160a083019083821085831117610f0257508a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea198958f94958e859d9c9a978152338352868301908982528581850199169a8b8a52600d8d860199828b526080870199838b52835252209260018060a01b0390511660018060a01b031984541617835551908201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600e5551908152f35b634e487b7160e01b8a5260419052602489fd5b634e487b7160e01b885260118252602488fd5b8a5163158e5da560e11b815293840152602483015250604490fd5b508185871610610d9b565b83604491888d5192633a54e96d60e21b84528301526024820152fd5b80929394959650888092503d8311610fbf575b610f878183611151565b81010312610fbb57908982610fa38e9796959451978201611309565b500151948560070b8603610fb7575f610d83565b8980fd5b8880fd5b503d610f7d565b8a513d8b823e3d90fd5b855163162908e360e11b8152fd5b508351630e433c2360e31b8152fd5b50855415610cff565b8351630e433c2360e31b8152fd5b9050346102295760603660031901126102295780359163ffffffff80841680940361022557602435908116908181036110cb57855460443594906001600160a01b031633036110be5782156110b057506009805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600a84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b50503461019457816003193601126101945760209061026960065460075490611216565b90503461022957602036600319011261022957356001600160a01b038116908190036102295782829160209452600b845220549051908152f35b84903461019457816003193601126101945760209063ffffffff600954831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761117357604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561120b575f916111dd575090565b906020823d8211611203575b816111f660209383611151565b8101031261057057505190565b3d91506111e9565b6040513d5f823e3d90fd5b9190820180921161122357565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561122357565b8115611254570490565b634e487b7160e01b5f52601260045260245ffd5b60015480156112a75761128060055460025490611216565b90670de0b6b3a764000091828102928184041490151715611223576112a49161124a565b90565b50670de0b6b3a764000090565b156112bb57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312611305575180151581036113055790565b5f80fd5b519063ffffffff8216820361130557565b9190820391821161122357565b60055490600a548210611462576009546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af1958615611456578380976113ec575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6939160809382976113b98460055461131a565b6005556113c884600254611216565b93846002556113d56115b5565b8351958652602086015216908301526060820152a1565b91965092508183813d831161144f575b6114068183611151565b81010312610570575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6936114436020608095519301611309565b96919381939550611382565b503d6113fc565b505051903d90823e3d90fd5b5f9150565b9060018060a01b0391828116905f90828252602091600b8352604091670de0b6b3a764000061149c8484205460035490611237565b04858352600c8552838320908082549255818111156115aa57916114c486926115079461131a565b9889916114d38360045461131a565b60045585875180968195829463a9059cbb60e01b84526004840160209093929193604081019460018060a01b031681520152565b03927f0000000000000000000000000000000000000000000000000000000000000000165af191821561159f5791611582575b501561157257907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe9161156b6115b5565b51858152a2565b5163022e258160e11b8152600490fd5b6115999150833d8511610522576105148183611151565b5f61153a565b8351903d90823e3d90fd5b509196505050505050565b6115bd611187565b60045481811161163a57600754906115d58282611216565b83811161161c5750906115ed6115f292600554611216565b611216565b908082116115fe575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea2646970667358221220682df586013c5d054b693ac7ca6c6e79dcfb4d82a89610b1d1213d4d9a50700864736f6c63430008140033", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": { - "3877": [ + "3943": [ + { + "length": 32, + "start": 737 + }, { "length": 32, - "start": 468 + "start": 1025 }, { "length": 32, - "start": 713 + "start": 1645 }, { "length": 32, - "start": 1784 + "start": 4514 }, { "length": 32, - "start": 2410 + "start": 5387 } ] }, "inputSourceName": "project/solidity/pool/CommunityPool.sol", - "buildInfoId": "solc-0_8_20-a811408d247f4050efe5537fb7107e02e5e2869f" + "buildInfoId": "solc-0_8_20-976e47a1ebd979fc766a2ad9b546f4ca71dab7dd" } \ No newline at end of file diff --git a/contracts/solidity/pool/CommunityPool.sol b/contracts/solidity/pool/CommunityPool.sol index 81adc488..555a817d 100644 --- a/contracts/solidity/pool/CommunityPool.sol +++ b/contracts/solidity/pool/CommunityPool.sol @@ -9,29 +9,59 @@ import "../precompiles/distribution/DistributionI.sol" as distribution; /// @notice Pooled staking contract with internal ownership units. /// @dev /// - Users deposit `bondToken` and receive pool units (`unitsOf`) representing proportional ownership. -/// - Pool assets are tracked as: liquid token balance + `totalStaked` accounting value. +/// - Principal accounting separates: +/// (a) liquid principal available for staking/deposit pricing, +/// (b) staked principal tracked in `totalStaked`, +/// (c) pending unbonding reserve, and +/// (d) matured withdraw reserve reserved for claims. /// - `totalStaked` is accounting-only and can drift from real chain state (e.g. slashing), so /// owner can reconcile it via `syncTotalStaked`. -/// - Withdrawals are liquid-only in this MVP: if liquid funds are insufficient, withdrawal reverts. +/// - Withdrawals are async and staked-only in this MVP: requests undelegate first, then users claim after maturity. contract CommunityPool { /// @dev Native token contract used for deposits/withdrawals. IERC20 public immutable bondToken; + /// @dev Fixed-point precision used for reward index math. + uint256 public constant PRECISION = 1e18; address public owner; /// @dev Total ownership units minted by the pool. uint256 public totalUnits; /// @dev Accounting value of delegated principal (not auto-reconciled with staking state). uint256 public totalStaked; + /// @dev Accumulated rewards per ownership unit (scaled by PRECISION). + uint256 public accRewardPerUnit; + /// @dev Total liquid rewards reserved for reward claims. + uint256 public rewardReserve; + /// @dev Principal liquid explicitly tracked as stake-eligible balance. + uint256 public stakeablePrincipalLedger; + /// @dev Principal requested for withdraw and not yet moved into matured-withdraw reserve. + uint256 public pendingWithdrawReserve; + /// @dev Liquid principal reserved for matured-but-unclaimed withdraw requests. + uint256 public maturedWithdrawReserve; + /// @dev Monotonic identifier for withdraw requests. + uint256 public nextWithdrawRequestId = 1; uint32 public maxRetrieve; uint32 public maxValidators; uint256 public minStakeAmount; /// @dev Units held per user. User ownership fraction = unitsOf[user] / totalUnits. mapping(address => uint256) public unitsOf; + /// @dev User reward checkpoint for index accounting. + mapping(address => uint256) public rewardDebt; + /// @dev Async principal withdraw requests keyed by request id. + mapping(uint256 => WithdrawRequest) public withdrawRequests; /// @dev Minimal reentrancy guard state (0=not entered, 1=entered). uint256 private _entered; + struct WithdrawRequest { + address owner; + uint256 amountOut; + uint64 maturityTime; + bool reserveMoved; + bool claimed; + } + error Unauthorized(); error InvalidAddress(); error InvalidAmount(); @@ -42,13 +72,36 @@ contract CommunityPool { error TokenTransferFromFailed(); error HarvestFailed(); error ZeroMintedUnits(); + error RequestAlreadyClaimed(); + error RequestNotMatured(uint64 maturityTime, uint64 currentTime); + error InvalidRequest(); + error InvalidCompletionTime(int64 completionTime, uint64 currentTime); + error UnexpectedUndelegatedAmount(uint256 requested, uint256 undelegated); + error RewardReserveInvariantViolation(uint256 rewardReserve, uint256 liquidBalance); + error LiquidReserveInvariantViolation(uint256 reservedAmount, uint256 liquidBalance); + error StakeablePrincipalInvariantViolation(uint256 accountedLiquid, uint256 liquidBalance); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event ConfigUpdated(uint32 maxRetrieve, uint32 maxValidators, uint256 minStakeAmount); event Deposit(address indexed user, uint256 amount, uint256 mintedUnits, uint256 totalUnitsAfter); - event Withdraw(address indexed user, uint256 burnedUnits, uint256 amountOut, uint256 totalUnitsAfter); event Stake(uint256 liquidBefore, uint256 delegatedAmount, uint256 validatorsCount, uint256 totalStakedAfter); event Harvest(uint256 liquidBefore, uint256 liquidAfter, uint256 harvestedAmount); + event RewardIndexUpdated(uint256 harvestedAmount, uint256 accRewardPerUnit, uint256 rewardReserve); + event RewardsClaimed(address indexed user, uint256 amount); + event WithdrawRequested( + address indexed user, + uint256 indexed requestId, + uint256 units, + uint256 amountOut, + uint64 maturityTime + ); + event WithdrawClaimed(address indexed user, uint256 indexed requestId, uint256 amountOut); + event WithdrawReserveMoved( + uint256 indexed requestId, + uint256 amountOut, + uint256 pendingWithdrawReserveAfter, + uint256 maturedWithdrawReserveAfter + ); event TotalStakedSynced(uint256 previousTotalStaked, uint256 newTotalStaked); modifier onlyOwner() { @@ -129,10 +182,21 @@ contract CommunityPool { return bondToken.balanceOf(address(this)); } - /// @notice Total pool assets used for share pricing. - /// @dev This excludes unclaimed rewards until `harvest` is called. - function poolAssets() public view returns (uint256) { - return liquidBalance() + totalStaked; + /// @notice Current liquid principal available for stake/deposit pricing. + /// @dev Ledger-driven value; independent from raw balance deltas. + function principalLiquid() public view returns (uint256) { + return stakeablePrincipalLedger; + } + + /// @notice Total principal assets used for ownership pricing. + /// @dev In strict staked-withdraw mode this tracks liquid principal plus currently staked principal. + function principalAssets() public view returns (uint256) { + return principalLiquid() + totalStaked; + } + + /// @notice Total principal currently committed to pending or matured async withdraw requests. + function totalWithdrawCommitments() external view returns (uint256) { + return pendingWithdrawReserve + maturedWithdrawReserve; } /// @notice Returns 1e18-scaled token value per ownership unit. @@ -140,20 +204,22 @@ contract CommunityPool { if (totalUnits == 0) { return 1e18; } - return (poolAssets() * 1e18) / totalUnits; + return (principalAssets() * 1e18) / totalUnits; } /// @notice Deposits tokens and mints proportional pool units. /// @dev /// - First deposit mints 1:1 units. - /// - Later deposits mint: floor(amount * totalUnits / poolAssets). + /// - Later deposits mint: floor(amount * totalUnits / principalAssets). /// - Floor rounding avoids over-minting; tiny deposits that would mint 0 units revert. function deposit(uint256 amount) external nonReentrant returns (uint256 mintedUnits) { if (amount == 0) { revert InvalidAmount(); } - uint256 assetsBefore = poolAssets(); + _claimPendingRewards(msg.sender); + + uint256 assetsBefore = principalAssets(); if (totalUnits == 0 || assetsBefore == 0) { mintedUnits = amount; } else { @@ -168,44 +234,125 @@ contract CommunityPool { revert TokenTransferFromFailed(); } + stakeablePrincipalLedger += amount; unitsOf[msg.sender] += mintedUnits; totalUnits += mintedUnits; + rewardDebt[msg.sender] = (unitsOf[msg.sender] * accRewardPerUnit) / PRECISION; + _assertReserveInvariant(); emit Deposit(msg.sender, amount, mintedUnits, totalUnits); } - /// @notice Burns user units and withdraws proportional assets from liquid balance. - /// @dev Reverts with `InsufficientLiquid` if the proportional claim exceeds liquid funds. - function withdraw(uint256 userUnits) external nonReentrant returns (uint256 amountOut) { + /// @notice Requests an async staked-principal withdrawal by burning ownership units now. + /// @dev + /// - Withdrawal sizing is based only on `totalStaked` (strict unbonding-only model). + /// - Final payout happens via `claimWithdraw` after maturity. + /// - Undelegation source validators are selected internally by staking precompile. + function withdraw(uint256 userUnits) external nonReentrant returns (uint256 requestId) { if (userUnits == 0) { revert InvalidUnits(); } + _claimPendingRewards(msg.sender); + uint256 userBalanceUnits = unitsOf[msg.sender]; if (userUnits > userBalanceUnits || totalUnits == 0) { revert InvalidUnits(); } - amountOut = (userUnits * poolAssets()) / totalUnits; - uint256 liquid = liquidBalance(); - if (amountOut > liquid) { - revert InsufficientLiquid(amountOut, liquid); + uint256 amountOut = (userUnits * totalStaked) / totalUnits; + if (amountOut == 0) { + revert InvalidAmount(); + } + uint64 currentTime = uint64(block.timestamp); + uint256 undelegatedAmount; + int64 completionTime; + (undelegatedAmount,, completionTime) = staking.STAKING_CONTRACT.undelegateFromBondedValidators( + address(this), + amountOut, + maxValidators + ); + if (undelegatedAmount != amountOut) { + revert UnexpectedUndelegatedAmount(amountOut, undelegatedAmount); } + if (completionTime <= 0 || uint64(completionTime) < currentTime) { + revert InvalidCompletionTime(completionTime, currentTime); + } + uint64 maturityTime = uint64(completionTime); unitsOf[msg.sender] = userBalanceUnits - userUnits; totalUnits -= userUnits; + totalStaked -= amountOut; + pendingWithdrawReserve += amountOut; + rewardDebt[msg.sender] = (unitsOf[msg.sender] * accRewardPerUnit) / PRECISION; + _assertReserveInvariant(); + + requestId = nextWithdrawRequestId++; + withdrawRequests[requestId] = WithdrawRequest({ + owner: msg.sender, + amountOut: amountOut, + maturityTime: maturityTime, + reserveMoved: false, + claimed: false + }); + + emit WithdrawRequested(msg.sender, requestId, userUnits, amountOut, maturityTime); + } + + /// @notice Claims a matured async withdrawal request. + /// @dev + /// - On first successful matured claim path, request amount is moved from + /// `pendingWithdrawReserve` to `maturedWithdrawReserve`. + /// - Payout consumes `maturedWithdrawReserve` and transfers principal to request owner. + function claimWithdraw(uint256 requestId) external nonReentrant returns (uint256 amountOut) { + WithdrawRequest storage request = withdrawRequests[requestId]; + if (request.owner == address(0)) { + revert InvalidRequest(); + } + if (request.owner != msg.sender) { + revert Unauthorized(); + } + if (request.claimed) { + revert RequestAlreadyClaimed(); + } + uint64 currentTime = uint64(block.timestamp); + if (currentTime < request.maturityTime) { + revert RequestNotMatured(request.maturityTime, currentTime); + } + + if (!request.reserveMoved) { + if (request.amountOut > pendingWithdrawReserve) { + revert InsufficientLiquid(request.amountOut, pendingWithdrawReserve); + } + pendingWithdrawReserve -= request.amountOut; + maturedWithdrawReserve += request.amountOut; + request.reserveMoved = true; + emit WithdrawReserveMoved(requestId, request.amountOut, pendingWithdrawReserve, maturedWithdrawReserve); + } + + request.claimed = true; + amountOut = request.amountOut; + if (amountOut > maturedWithdrawReserve) { + revert InsufficientLiquid(amountOut, maturedWithdrawReserve); + } + uint256 liquidPrincipalBefore = liquidBalance() - rewardReserve; + if (amountOut > liquidPrincipalBefore) { + revert InsufficientLiquid(amountOut, liquidPrincipalBefore); + } + maturedWithdrawReserve -= amountOut; if (!bondToken.transfer(msg.sender, amountOut)) { revert TokenTransferFailed(); } + _assertReserveInvariant(); - emit Withdraw(msg.sender, userUnits, amountOut, totalUnits); + emit WithdrawClaimed(msg.sender, requestId, amountOut); } - /// @notice Delegates available liquid to bonded validators via staking precompile. + /// @notice Delegates available principal liquid to bonded validators via staking precompile. /// @dev Uses a single precompile call that performs bonded-set selection and equal split. function stake() external nonReentrant returns (uint256 delegatedAmount) { - uint256 liquidBefore = liquidBalance(); + uint256 liquidBefore = stakeablePrincipalLedger; if (liquidBefore < minStakeAmount) { return 0; } @@ -216,7 +363,9 @@ contract CommunityPool { maxValidators ); + stakeablePrincipalLedger -= delegatedAmount; totalStaked += delegatedAmount; + _assertReserveInvariant(); emit Stake(liquidBefore, delegatedAmount, uint256(validatorsCount), totalStaked); } @@ -234,8 +383,58 @@ contract CommunityPool { uint256 liquidAfter = liquidBalance(); harvestedAmount = liquidAfter > liquidBefore ? liquidAfter - liquidBefore : 0; + if (harvestedAmount > 0) { + rewardReserve += harvestedAmount; + if (totalUnits > 0) { + accRewardPerUnit += (harvestedAmount * PRECISION) / totalUnits; + } + emit RewardIndexUpdated(harvestedAmount, accRewardPerUnit, rewardReserve); + } + _assertReserveInvariant(); emit Harvest(liquidBefore, liquidAfter, harvestedAmount); } + /// @notice Claims caller's accrued rewards from the reward reserve. + /// @dev Uses reward index accounting and does not trigger distribution precompile calls. + function claimRewards() external nonReentrant returns (uint256 claimedAmount) { + claimedAmount = _claimPendingRewards(msg.sender); + } + + function _claimPendingRewards(address user) internal returns (uint256 claimedAmount) { + uint256 accumulated = (unitsOf[user] * accRewardPerUnit) / PRECISION; + uint256 debt = rewardDebt[user]; + rewardDebt[user] = accumulated; + if (accumulated <= debt) { + return 0; + } + + claimedAmount = accumulated - debt; + rewardReserve -= claimedAmount; + if (!bondToken.transfer(user, claimedAmount)) { + revert TokenTransferFailed(); + } + _assertReserveInvariant(); + + emit RewardsClaimed(user, claimedAmount); + } + + function _assertReserveInvariant() internal view { + uint256 liquid = liquidBalance(); + if (rewardReserve > liquid) { + revert RewardReserveInvariantViolation(rewardReserve, liquid); + } + // Only liquid reserves are constrained by current liquid balance. + // Pending withdraw reserve is intentionally excluded because it is not yet + // moved to the matured (liquid, claim-ready) reserve. + uint256 reserved = rewardReserve + maturedWithdrawReserve; + if (reserved > liquid) { + revert LiquidReserveInvariantViolation(reserved, liquid); + } + uint256 accountedLiquid = stakeablePrincipalLedger + rewardReserve + maturedWithdrawReserve; + if (accountedLiquid > liquid) { + revert StakeablePrincipalInvariantViolation(accountedLiquid, liquid); + } + } + } From 0c99d12cf2e19894a2f4e2431444a80105381507 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Tue, 31 Mar 2026 21:27:40 +0530 Subject: [PATCH 24/31] test(communitypool): harden integration coverage for withdraw, config, and event assertions --- .../communitypool/test_integration.go | 656 ++++++++++++++++-- .../precompiles/communitypool/test_utils.go | 162 ++++- 2 files changed, 767 insertions(+), 51 deletions(-) diff --git a/tests/integration/precompiles/communitypool/test_integration.go b/tests/integration/precompiles/communitypool/test_integration.go index e8c7b116..8f5c3861 100644 --- a/tests/integration/precompiles/communitypool/test_integration.go +++ b/tests/integration/precompiles/communitypool/test_integration.go @@ -25,7 +25,6 @@ import ( func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp, options ...network.ConfigOption) { _ = Describe("CommunityPool integration scaffold", func() { var s *IntegrationTestSuite - var err error BeforeEach(func() { s = NewIntegrationTestSuite(create, options...) @@ -65,11 +64,12 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp owner := s.keyring.GetKey(0) poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) - txArgs := buildTxArgs(poolAddr) - callArgs := buildCallArgs(s.communityPoolContract, "deposit", big.NewInt(0)) - check := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) - _, _, err := s.factory.CallContractAndCheckLogs(owner.Priv, txArgs, callArgs, check) - Expect(err).To(BeNil()) + s.execTxExpectCustomError( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", big.NewInt(0)), + "InvalidAmount()", + ) }) It("mints 1:1 units on first deposit", func() { @@ -130,7 +130,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(totalUnits.String()).To(Equal("1500")) }) - It("withdraws successfully when enough liquid is available", func() { + It("creates async withdraw request and updates accounting", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) user := s.keyring.GetKey(1) @@ -145,6 +145,14 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) Expect(s.network.NextBlock()).To(BeNil()) + // Withdraw path is strict unbonding-based, so ensure principal is staked first. + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + s.execTxExpectSuccess( user.Priv, buildTxArgs(poolAddr), @@ -156,14 +164,30 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp totalUnits := s.queryPoolUint(1, poolAddr, "totalUnits") Expect(remainingUnits.String()).To(Equal("600")) Expect(totalUnits.String()).To(Equal("600")) + + totalStaked := s.queryPoolUint(1, poolAddr, "totalStaked") + pendingReserve := s.queryPoolUint(1, poolAddr, "pendingWithdrawReserve") + maturedReserve := s.queryPoolUint(1, poolAddr, "maturedWithdrawReserve") + Expect(totalStaked.String()).To(Equal("600")) + Expect(pendingReserve.String()).To(Equal("400")) + Expect(maturedReserve.Sign()).To(Equal(0)) + + request := s.queryWithdrawRequest(poolAddr, big.NewInt(1)) + Expect(request.Owner).To(Equal(user.Addr)) + Expect(request.AmountOut.String()).To(Equal("400")) + Expect(request.ReserveMoved).To(BeFalse()) + Expect(request.Claimed).To(BeFalse()) + Expect(request.Maturity).To(BeNumerically(">", 0)) + s.assertPoolInvariants(poolAddr) }) - It("reverts withdraw when proportional claim exceeds liquid balance", func() { + It("increments nextWithdrawRequestId across multiple requests", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) - owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) + withdrawUnits := big.NewInt(200) + s.approveBondToken(1, poolAddr, depositAmount) s.execTxExpectSuccess( user.Priv, @@ -172,22 +196,367 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) Expect(s.network.NextBlock()).To(BeNil()) - // Inflate accounting assets without adding liquid balance. s.execTxExpectSuccess( - owner.Priv, + user.Priv, buildTxArgs(poolAddr), - buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(1000)), + buildCallArgs(s.communityPoolContract, "stake"), ) Expect(s.network.NextBlock()).To(BeNil()) - check := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) - _, _, err = s.factory.CallContractAndCheckLogs( + // Starts at 1 before any request. + nextBefore := s.queryPoolUint(1, poolAddr, "nextWithdrawRequestId") + Expect(nextBefore.String()).To(Equal("1")) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", withdrawUnits), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + nextAfterFirst := s.queryPoolUint(1, poolAddr, "nextWithdrawRequestId") + Expect(nextAfterFirst.String()).To(Equal("2")) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", withdrawUnits), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + nextAfterSecond := s.queryPoolUint(1, poolAddr, "nextWithdrawRequestId") + Expect(nextAfterSecond.String()).To(Equal("3")) + + req1 := s.queryWithdrawRequest(poolAddr, big.NewInt(1)) + req2 := s.queryWithdrawRequest(poolAddr, big.NewInt(2)) + Expect(req1.Owner).To(Equal(user.Addr)) + Expect(req2.Owner).To(Equal(user.Addr)) + Expect(req1.AmountOut.String()).To(Equal("200")) + Expect(req2.AmountOut.String()).To(Equal("200")) + Expect(req1.Claimed).To(BeFalse()) + Expect(req2.Claimed).To(BeFalse()) + s.assertPoolInvariants(poolAddr) + }) + + It("reverts withdraw when userUnits is zero", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + + depositAmount := big.NewInt(1000) + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectCustomError( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", big.NewInt(0)), + "InvalidUnits()", + ) + s.assertPoolInvariants(poolAddr) + }) + + It("reverts withdraw when requested units exceed user balance", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + + depositAmount := big.NewInt(1000) + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectCustomError( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", big.NewInt(1001)), + "InvalidUnits()", + ) + s.assertPoolInvariants(poolAddr) + }) + + It("reverts withdraw when no staked principal exists", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + + depositAmount := big.NewInt(1000) + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectCustomError( user.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "withdraw", big.NewInt(1000)), - check, + "InvalidAmount()", + ) + }) + + It("enforces maturity and ownership in claimWithdraw", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + other := s.keyring.GetKey(2) + + depositAmount := big.NewInt(1000) + withdrawUnits := big.NewInt(400) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", withdrawUnits), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + // Request owner only. + s.execTxExpectCustomError( + other.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimWithdraw", big.NewInt(1)), + "Unauthorized()", + ) + + // Request cannot be claimed before maturity. + s.execTxExpectCustomError( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimWithdraw", big.NewInt(1)), + "RequestNotMatured(uint64,uint64)", + ) + }) + + It("claims matured withdraw and prevents double claim", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + + depositAmount := big.NewInt(1000) + withdrawUnits := big.NewInt(400) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", withdrawUnits), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + request := s.queryWithdrawRequest(poolAddr, big.NewInt(1)) + s.advanceToMaturity(request.Maturity) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimWithdraw", big.NewInt(1)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + // Reserves should be fully consumed for this single request. + pendingReserve := s.queryPoolUint(1, poolAddr, "pendingWithdrawReserve") + maturedReserve := s.queryPoolUint(1, poolAddr, "maturedWithdrawReserve") + commitments := s.queryPoolUint(1, poolAddr, "totalWithdrawCommitments") + Expect(pendingReserve.Sign()).To(Equal(0)) + Expect(maturedReserve.Sign()).To(Equal(0)) + Expect(commitments.Sign()).To(Equal(0)) + + claimedReq := s.queryWithdrawRequest(poolAddr, big.NewInt(1)) + Expect(claimedReq.ReserveMoved).To(BeTrue()) + Expect(claimedReq.Claimed).To(BeTrue()) + + // Second claim must revert. + s.execTxExpectCustomError( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimWithdraw", big.NewInt(1)), + "RequestAlreadyClaimed()", + ) + s.assertPoolInvariants(poolAddr) + }) + + It("emits withdraw lifecycle events with expected request id", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + withdrawUnits := big.NewInt(400) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + withdrawRes := s.execTxAndGetEthResponse( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", withdrawUnits), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + withdrawEvt := s.communityPoolContract.ABI.Events["WithdrawRequested"] + withdrawLog := s.findEventLog(withdrawRes, poolAddr, withdrawEvt) + Expect(withdrawLog).ToNot(BeNil(), "expected WithdrawRequested event") + Expect(withdrawLog.Topics).To(HaveLen(3)) + Expect(withdrawLog.Topics[1]).To(Equal(common.BytesToHash(user.Addr.Bytes()).Hex())) + Expect(withdrawLog.Topics[2]).To(Equal(common.BigToHash(big.NewInt(1)).Hex())) + + requestData, err := withdrawEvt.Inputs.Unpack(withdrawLog.Data) + Expect(err).To(BeNil(), "failed to decode WithdrawRequested data") + Expect(requestData).To(HaveLen(3)) + unitsVal, ok := requestData[0].(*big.Int) + Expect(ok).To(BeTrue()) + amountOutVal, ok := requestData[1].(*big.Int) + Expect(ok).To(BeTrue()) + Expect(unitsVal.String()).To(Equal(withdrawUnits.String())) + Expect(amountOutVal.String()).To(Equal("400")) + + request := s.queryWithdrawRequest(poolAddr, big.NewInt(1)) + s.advanceToMaturity(request.Maturity) + + claimRes := s.execTxAndGetEthResponse( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimWithdraw", big.NewInt(1)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + claimEvt := s.communityPoolContract.ABI.Events["WithdrawClaimed"] + claimLog := s.findEventLog(claimRes, poolAddr, claimEvt) + Expect(claimLog).ToNot(BeNil(), "expected WithdrawClaimed event") + Expect(claimLog.Topics).To(HaveLen(3)) + Expect(claimLog.Topics[1]).To(Equal(common.BytesToHash(user.Addr.Bytes()).Hex())) + Expect(claimLog.Topics[2]).To(Equal(common.BigToHash(big.NewInt(1)).Hex())) + }) + + It("claims multiple matured requests out of order", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + + depositAmount := big.NewInt(1000) + withdrawUnits := big.NewInt(200) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", withdrawUnits), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "withdraw", withdrawUnits), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + req1 := s.queryWithdrawRequest(poolAddr, big.NewInt(1)) + req2 := s.queryWithdrawRequest(poolAddr, big.NewInt(2)) + if req2.Maturity > req1.Maturity { + s.advanceToMaturity(req2.Maturity) + } else { + s.advanceToMaturity(req1.Maturity) + } + + // Claim second request first, then first request. + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimWithdraw", big.NewInt(2)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimWithdraw", big.NewInt(1)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + claimedReq1 := s.queryWithdrawRequest(poolAddr, big.NewInt(1)) + claimedReq2 := s.queryWithdrawRequest(poolAddr, big.NewInt(2)) + Expect(claimedReq1.Claimed).To(BeTrue()) + Expect(claimedReq2.Claimed).To(BeTrue()) + Expect(claimedReq1.ReserveMoved).To(BeTrue()) + Expect(claimedReq2.ReserveMoved).To(BeTrue()) + + pendingReserve := s.queryPoolUint(1, poolAddr, "pendingWithdrawReserve") + maturedReserve := s.queryPoolUint(1, poolAddr, "maturedWithdrawReserve") + Expect(pendingReserve.Sign()).To(Equal(0)) + Expect(maturedReserve.Sign()).To(Equal(0)) + s.assertPoolInvariants(poolAddr) + }) + + It("reverts claimWithdraw for non-existent request", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + + s.execTxExpectCustomError( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimWithdraw", big.NewInt(9999)), + "InvalidRequest()", ) - Expect(err).To(BeNil()) }) It("returns expected pricePerUnit for empty and adjusted pool", func() { @@ -208,7 +577,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) Expect(s.network.NextBlock()).To(BeNil()) - // poolAssets=2000, totalUnits=1000 => pricePerUnit=2e18. + // principalAssets=2000, totalUnits=1000 => pricePerUnit=2e18. s.execTxExpectSuccess( owner.Priv, buildTxArgs(poolAddr), @@ -225,31 +594,29 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp owner := s.keyring.GetKey(0) nonOwner := s.keyring.GetKey(1) - revertCheck := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) - - _, _, err := s.factory.CallContractAndCheckLogs( + s.execTxExpectCustomError( nonOwner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "setConfig", uint32(20), uint32(7), big.NewInt(2)), - revertCheck, + "Unauthorized()", ) - Expect(err).To(BeNil()) + Expect(s.network.NextBlock()).To(BeNil()) - _, _, err = s.factory.CallContractAndCheckLogs( + s.execTxExpectCustomError( nonOwner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(123)), - revertCheck, + "Unauthorized()", ) - Expect(err).To(BeNil()) + Expect(s.network.NextBlock()).To(BeNil()) - _, _, err = s.factory.CallContractAndCheckLogs( + s.execTxExpectCustomError( nonOwner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "transferOwnership", nonOwner.Addr), - revertCheck, + "Unauthorized()", ) - Expect(err).To(BeNil()) + Expect(s.network.NextBlock()).To(BeNil()) // Owner can still execute privileged actions. s.execTxExpectSuccess( @@ -287,13 +654,12 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp beforeUser2Units := s.queryPoolUint(2, poolAddr, "unitsOf", user2.Addr) beforeTotalUnits := s.queryPoolUint(2, poolAddr, "totalUnits") - _, _, err = s.factory.CallContractAndCheckLogs( + s.execTxExpectCustomError( user2.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "deposit", big.NewInt(1)), - testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()), + "ZeroMintedUnits()", ) - Expect(err).To(BeNil()) afterUser2Units := s.queryPoolUint(2, poolAddr, "unitsOf", user2.Addr) afterTotalUnits := s.queryPoolUint(2, poolAddr, "totalUnits") @@ -313,16 +679,13 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) Expect(s.network.NextBlock()).To(BeNil()) - revertCheck := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) - // Old owner should now be blocked. - _, _, err = s.factory.CallContractAndCheckLogs( + s.execTxExpectCustomError( oldOwner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "setConfig", uint32(99), uint32(9), big.NewInt(3)), - revertCheck, + "Unauthorized()", ) - Expect(err).To(BeNil()) // New owner should now be allowed. s.execTxExpectSuccess( @@ -337,13 +700,12 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp owner := s.keyring.GetKey(0) zeroAddr := common.Address{} - _, _, err := s.factory.CallContractAndCheckLogs( + s.execTxExpectCustomError( owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "transferOwnership", zeroAddr), - testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()), + "InvalidAddress()", ) - Expect(err).To(BeNil()) }) It("allows owner to call all privileged methods", func() { @@ -370,6 +732,99 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(totalStaked.String()).To(Equal("321")) }) + It("reverts setConfig when maxValidators is zero", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + + s.execTxExpectCustomError( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setConfig", uint32(10), uint32(0), big.NewInt(1)), + "InvalidConfig()", + ) + }) + + It("emits ConfigUpdated with applied values", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + + res := s.execTxAndGetEthResponse( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setConfig", uint32(20), uint32(7), big.NewInt(2)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + cfgEvt := s.communityPoolContract.ABI.Events["ConfigUpdated"] + cfgLog := s.findEventLog(res, poolAddr, cfgEvt) + Expect(cfgLog).ToNot(BeNil(), "expected ConfigUpdated event") + + cfgData, err := cfgEvt.Inputs.Unpack(cfgLog.Data) + Expect(err).To(BeNil(), "failed to decode ConfigUpdated data") + Expect(cfgData).To(HaveLen(3)) + maxRetrieve, ok := cfgData[0].(uint32) + Expect(ok).To(BeTrue()) + maxValidators, ok := cfgData[1].(uint32) + Expect(ok).To(BeTrue()) + minStakeAmount, ok := cfgData[2].(*big.Int) + Expect(ok).To(BeTrue()) + + Expect(maxRetrieve).To(Equal(uint32(20))) + Expect(maxValidators).To(Equal(uint32(7))) + Expect(minStakeAmount.String()).To(Equal("2")) + }) + + It("setConfig minStakeAmount change gates stake behavior", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + user := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + // Raise threshold above available liquid; stake should no-op. + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setConfig", uint32(10), uint32(5), big.NewInt(2000)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + totalStaked := s.queryPoolUint(1, poolAddr, "totalStaked") + Expect(totalStaked.Sign()).To(Equal(0)) + + // Lower threshold; stake should now delegate. + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setConfig", uint32(10), uint32(5), big.NewInt(1)), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + totalStaked = s.queryPoolUint(1, poolAddr, "totalStaked") + Expect(totalStaked.String()).To(Equal("1000")) + s.assertPoolInvariants(poolAddr) + }) + It("blocks old owner from syncTotalStaked after ownership transfer", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) oldOwner := s.keyring.GetKey(0) @@ -382,15 +837,12 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) Expect(s.network.NextBlock()).To(BeNil()) - revertCheck := testutil.LogCheckArgs{}.WithErrContains(vm.ErrExecutionReverted.Error()) - - _, _, err = s.factory.CallContractAndCheckLogs( + s.execTxExpectCustomError( oldOwner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "syncTotalStaked", big.NewInt(500)), - revertCheck, + "Unauthorized()", ) - Expect(err).To(BeNil()) s.execTxExpectSuccess( newOwner.Priv, @@ -424,7 +876,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp beforeUserUnits := s.queryPoolUint(1, poolAddr, "unitsOf", user.Addr) beforeTotalUnits := s.queryPoolUint(1, poolAddr, "totalUnits") - _, _, err = s.factory.CallContractAndCheckLogs( + _, _, err := s.factory.CallContractAndCheckLogs( user.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "withdraw", amount), @@ -583,7 +1035,114 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(afterLiquid.Cmp(beforeLiquid)).To(BeNumerically(">=", 0)) }) - It("syncTotalStaked updates accounting views (poolAssets and pricePerUnit)", func() { + It("claimRewards is a no-op without harvested rewards", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + // No harvest happened, so user has no claimable rewards. + beforeRewardReserve := s.queryPoolUint(1, poolAddr, "rewardReserve") + + _, ethRes, err := s.factory.CallContractAndCheckLogs( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimRewards"), + testutil.LogCheckArgs{}.WithExpPass(true), + ) + Expect(err).To(BeNil()) + Expect(s.network.NextBlock()).To(BeNil()) + + afterRewardReserve := s.queryPoolUint(1, poolAddr, "rewardReserve") + unpacked, err := s.communityPoolContract.ABI.Unpack("claimRewards", ethRes.Ret) + Expect(err).To(BeNil()) + Expect(unpacked).To(HaveLen(1)) + claimedAmount, ok := unpacked[0].(*big.Int) + Expect(ok).To(BeTrue()) + + Expect(claimedAmount.Sign()).To(Equal(0)) + Expect(afterRewardReserve.String()).To(Equal(beforeRewardReserve.String())) + }) + + It("claimRewards is idempotent for a given reward index", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + user := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + // Harvest updates reward index and reserve (or leaves unchanged in zero-reward conditions). + s.execTxExpectSuccess( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "harvest"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + beforeFirstClaimReserve := s.queryPoolUint(1, poolAddr, "rewardReserve") + + _, firstClaimRes, err := s.factory.CallContractAndCheckLogs( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimRewards"), + testutil.LogCheckArgs{}.WithExpPass(true), + ) + Expect(err).To(BeNil()) + Expect(s.network.NextBlock()).To(BeNil()) + + afterFirstClaimReserve := s.queryPoolUint(1, poolAddr, "rewardReserve") + firstUnpacked, err := s.communityPoolContract.ABI.Unpack("claimRewards", firstClaimRes.Ret) + Expect(err).To(BeNil()) + Expect(firstUnpacked).To(HaveLen(1)) + firstClaimed, ok := firstUnpacked[0].(*big.Int) + Expect(ok).To(BeTrue()) + + // First claim cannot increase reserve and cannot decrease user balance. + Expect(afterFirstClaimReserve.Cmp(beforeFirstClaimReserve)).To(BeNumerically("<=", 0)) + Expect(firstClaimed.Sign()).To(BeNumerically(">=", 0)) + + // Second immediate claim should be a no-op at the same reward index. + _, secondClaimRes, err := s.factory.CallContractAndCheckLogs( + user.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "claimRewards"), + testutil.LogCheckArgs{}.WithExpPass(true), + ) + Expect(err).To(BeNil()) + Expect(s.network.NextBlock()).To(BeNil()) + + afterSecondClaimReserve := s.queryPoolUint(1, poolAddr, "rewardReserve") + secondUnpacked, err := s.communityPoolContract.ABI.Unpack("claimRewards", secondClaimRes.Ret) + Expect(err).To(BeNil()) + Expect(secondUnpacked).To(HaveLen(1)) + secondClaimed, ok := secondUnpacked[0].(*big.Int) + Expect(ok).To(BeTrue()) + + Expect(afterSecondClaimReserve.String()).To(Equal(afterFirstClaimReserve.String())) + Expect(secondClaimed.Sign()).To(Equal(0)) + }) + + It("syncTotalStaked updates accounting views (principalAssets and pricePerUnit)", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) @@ -598,7 +1157,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) Expect(s.network.NextBlock()).To(BeNil()) - beforeAssets := s.queryPoolUint(0, poolAddr, "poolAssets") + beforeAssets := s.queryPoolUint(0, poolAddr, "principalAssets") beforePPU := s.queryPoolUint(0, poolAddr, "pricePerUnit") s.execTxExpectSuccess( @@ -608,7 +1167,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) Expect(s.network.NextBlock()).To(BeNil()) - afterAssets := s.queryPoolUint(0, poolAddr, "poolAssets") + afterAssets := s.queryPoolUint(0, poolAddr, "principalAssets") afterPPU := s.queryPoolUint(0, poolAddr, "pricePerUnit") Expect(beforeAssets.String()).To(Equal("1000")) @@ -642,4 +1201,3 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp RegisterFailHandler(Fail) RunSpecs(t, "CommunityPool Integration Suite") } - diff --git a/tests/integration/precompiles/communitypool/test_utils.go b/tests/integration/precompiles/communitypool/test_utils.go index a945733b..cc3cd50a 100644 --- a/tests/integration/precompiles/communitypool/test_utils.go +++ b/tests/integration/precompiles/communitypool/test_utils.go @@ -1,17 +1,31 @@ package communitypool import ( + "bytes" "math/big" + "strings" + "time" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" . "github.com/onsi/gomega" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/evm/precompiles/erc20" testutiltypes "github.com/cosmos/evm/testutil/types" evmtypes "github.com/cosmos/evm/x/vm/types" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" ) +type withdrawRequestView struct { + Owner common.Address + AmountOut *big.Int + Maturity uint64 + ReserveMoved bool + Claimed bool +} + // deployCommunityPool deploys CommunityPool with deterministic defaults used in tests. func (s *IntegrationTestSuite) deployCommunityPool( ownerIdx int, @@ -109,6 +123,15 @@ func (s *IntegrationTestSuite) execTxExpectSuccess( txArgs evmtypes.EvmTxArgs, callArgs testutiltypes.CallArgs, ) { + ethRes := s.execTxAndGetEthResponse(priv, txArgs, callArgs) + Expect(ethRes.VmError).To(BeEmpty(), "unexpected EVM execution revert") +} + +func (s *IntegrationTestSuite) execTxAndGetEthResponse( + priv cryptotypes.PrivKey, + txArgs evmtypes.EvmTxArgs, + callArgs testutiltypes.CallArgs, +) *evmtypes.MsgEthereumTxResponse { if txArgs.GasLimit == 0 { txArgs.GasLimit = 2_000_000 } @@ -117,6 +140,141 @@ func (s *IntegrationTestSuite) execTxExpectSuccess( ethRes, err := evmtypes.DecodeTxResponse(res.Data) Expect(err).To(BeNil(), "failed to decode ethereum tx response") - Expect(ethRes.VmError).To(BeEmpty(), "unexpected EVM execution revert") + return ethRes +} + +func (s *IntegrationTestSuite) findEventLog( + ethRes *evmtypes.MsgEthereumTxResponse, + emitter common.Address, + event abi.Event, +) *evmtypes.Log { + for _, lg := range ethRes.Logs { + if !strings.EqualFold(lg.Address, emitter.Hex()) { + continue + } + if len(lg.Topics) == 0 { + continue + } + if strings.EqualFold(lg.Topics[0], event.ID.Hex()) { + return lg + } + } + return nil +} + +func (s *IntegrationTestSuite) execTxExpectCustomError( + priv cryptotypes.PrivKey, + txArgs evmtypes.EvmTxArgs, + callArgs testutiltypes.CallArgs, + errorSignature string, +) { + if txArgs.GasLimit == 0 { + txArgs.GasLimit = 2_000_000 + } + res, err := s.factory.ExecuteContractCall(priv, txArgs, callArgs) + Expect(err).To(BeNil(), "expected tx execution to return response for revert checks") + + ethRes, err := evmtypes.DecodeTxResponse(res.Data) + Expect(err).To(BeNil(), "failed to decode ethereum tx response") + Expect(ethRes.VmError).To(ContainSubstring(vm.ErrExecutionReverted.Error())) + Expect(len(ethRes.Ret)).To(BeNumerically(">=", 4), "revert payload too short for custom error selector") + + expectedSelector := crypto.Keccak256([]byte(errorSignature))[:4] + Expect(bytes.Equal(ethRes.Ret[:4], expectedSelector)). + To(BeTrue(), "expected custom error %s (selector %x), got selector %x", errorSignature, expectedSelector, ethRes.Ret[:4]) } +func (s *IntegrationTestSuite) queryBondTokenBalance(addr common.Address) *big.Int { + ethRes, err := s.factory.QueryContract( + buildTxArgs(s.bondTokenAddr), + testutiltypes.CallArgs{ + ContractABI: s.bondTokenPC.ABI, + MethodName: erc20.BalanceOfMethod, + Args: []interface{}{addr}, + }, + 0, + ) + Expect(err).To(BeNil(), "failed querying bond token balance") + + out, err := s.bondTokenPC.ABI.Unpack(erc20.BalanceOfMethod, ethRes.Ret) + Expect(err).To(BeNil(), "failed to unpack bond token balance") + Expect(out).To(HaveLen(1)) + bal, ok := out[0].(*big.Int) + Expect(ok).To(BeTrue(), "unexpected balance output type") + return bal +} + +func (s *IntegrationTestSuite) queryWithdrawRequest(contractAddr common.Address, requestID *big.Int) withdrawRequestView { + ethRes, err := s.factory.QueryContract( + buildTxArgs(contractAddr), + buildCallArgs(s.communityPoolContract, "withdrawRequests", requestID), + 0, + ) + Expect(err).To(BeNil(), "failed querying withdraw request") + + out, err := s.communityPoolContract.ABI.Unpack("withdrawRequests", ethRes.Ret) + Expect(err).To(BeNil(), "failed to unpack withdraw request") + Expect(out).To(HaveLen(5)) + + owner, ok := out[0].(common.Address) + Expect(ok).To(BeTrue(), "unexpected owner type") + amountOut, ok := out[1].(*big.Int) + Expect(ok).To(BeTrue(), "unexpected amountOut type") + + var maturity uint64 + switch t := out[2].(type) { + case uint64: + maturity = t + case *big.Int: + maturity = t.Uint64() + default: + Expect(false).To(BeTrue(), "unexpected maturity type") + } + + reserveMoved, ok := out[3].(bool) + Expect(ok).To(BeTrue(), "unexpected reserveMoved type") + claimed, ok := out[4].(bool) + Expect(ok).To(BeTrue(), "unexpected claimed type") + + return withdrawRequestView{ + Owner: owner, + AmountOut: amountOut, + Maturity: maturity, + ReserveMoved: reserveMoved, + Claimed: claimed, + } +} + +func (s *IntegrationTestSuite) advanceToMaturity(maturity uint64) { + now := uint64(s.network.GetContext().BlockTime().Unix()) + if maturity <= now { + return + } + delta := time.Duration(maturity-now+1) * time.Second + Expect(s.network.NextBlockAfter(delta)).To(BeNil(), "failed to advance block time to maturity") +} + +func (s *IntegrationTestSuite) assertPoolInvariants(poolAddr common.Address) { + liquid := s.queryPoolUint(0, poolAddr, "liquidBalance") + rewardReserve := s.queryPoolUint(0, poolAddr, "rewardReserve") + maturedReserve := s.queryPoolUint(0, poolAddr, "maturedWithdrawReserve") + pendingReserve := s.queryPoolUint(0, poolAddr, "pendingWithdrawReserve") + ledger := s.queryPoolUint(0, poolAddr, "stakeablePrincipalLedger") + commitments := s.queryPoolUint(0, poolAddr, "totalWithdrawCommitments") + + // rewardReserve <= liquidBalance + Expect(rewardReserve.Cmp(liquid)).To(BeNumerically("<=", 0)) + + // rewardReserve + maturedWithdrawReserve <= liquidBalance + reserved := new(big.Int).Add(new(big.Int).Set(rewardReserve), maturedReserve) + Expect(reserved.Cmp(liquid)).To(BeNumerically("<=", 0)) + + // stakeablePrincipalLedger + rewardReserve + maturedWithdrawReserve <= liquidBalance + accounted := new(big.Int).Add(new(big.Int).Set(ledger), rewardReserve) + accounted.Add(accounted, maturedReserve) + Expect(accounted.Cmp(liquid)).To(BeNumerically("<=", 0)) + + // totalWithdrawCommitments == pendingWithdrawReserve + maturedWithdrawReserve + expectedCommitments := new(big.Int).Add(new(big.Int).Set(pendingReserve), maturedReserve) + Expect(commitments.String()).To(Equal(expectedCommitments.String())) +} From 31b0a2dc095007464da3ed74e37826803921c36c Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Tue, 31 Mar 2026 23:08:26 +0530 Subject: [PATCH 25/31] feat(communitypool): restrict stake and harvest to owner or automation caller --- contracts/solidity/pool/CommunityPool.json | 63 ++++++++-- contracts/solidity/pool/CommunityPool.sol | 29 ++++- .../communitypool/TEST_ASSUMPTIONS.md | 4 +- .../communitypool/test_integration.go | 109 +++++++++++++++--- .../precompiles/communitypool/test_utils.go | 20 ++++ 5 files changed, 193 insertions(+), 32 deletions(-) diff --git a/contracts/solidity/pool/CommunityPool.json b/contracts/solidity/pool/CommunityPool.json index f7dd86cf..aaaf3367 100644 --- a/contracts/solidity/pool/CommunityPool.json +++ b/contracts/solidity/pool/CommunityPool.json @@ -201,6 +201,25 @@ "name": "ZeroMintedUnits", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousCaller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newCaller", + "type": "address" + } + ], + "name": "AutomationCallerUpdated", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -514,6 +533,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "automationCaller", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "bondToken", @@ -766,6 +798,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAutomationCaller", + "type": "address" + } + ], + "name": "setAutomationCaller", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -958,34 +1003,34 @@ "type": "function" } ], - "bytecode": "0x60a0346200014b57601f6200183838819003918201601f19168301916001600160401b038311848410176200014f5780849260a0946040528339810103126200014b576200004d8162000163565b906200005c6020820162000178565b906200006b6040820162000178565b916200007f60806060840151930162000163565b60016008556001600160a01b039490939085168015801562000140575b6200012e5763ffffffff90818316156200011c5760805267ffffffff000000006009549260201b1692169060018060401b0319161717600955600a551660018060a01b03195f5416175f556040516116ad90816200018b82396080518181816102e1015281816104010152818161066d015281816111a2015261150b0152f35b6040516306b7c75960e31b8152600490fd5b60405163e6c4247b60e01b8152600490fd5b50858516156200009c565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036200014b57565b519063ffffffff821682036200014b5756fe6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac52561461112d575081630eccc708146110f35781630ed61edb146110cf5781631a0a253c146110045781632e1a7d4d14610caf578163372500ab14610c7f5781633a4b66f114610c465781634641257d14610a395781635873eb9b146109ff5781636d86acc4146109e05781636f620185146109c15781637bfe7d57146109a2578163817b1cd2146109835781638ca82108146109645781638da5cb5b1461093c578163992a7dfb146108d1578163a8c7914714610862578163aaf5eb681461083f578163b13acedd14610573578163b6b55f2514610376578163b7ec1a3314610359578163bae8059414610335578163bbe9a07014610310578163c28f4392146102cc578163cab64bcd146102ae578163d5f884a11461028f578163dacd7e0c14610270578163e66825c31461024c578163f18876841461022d578163f2fde38b14610198575063f74bcf2914610177575f80fd5b346101945781600319360112610194576020906005549051908152f35b5080fd5b91905034610229576020366003190112610229576001600160a01b03823581811693908490036102255784549182169283330361021957841561020c5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b505034610194578160031936011261019457602090600a549051908152f35b505034610194578160031936011261019457602090610269611268565b9051908152f35b5050346101945781600319360112610194576020906003549051908152f35b5050346101945781600319360112610194576020906006549051908152f35b90503461022957826003193601126102295760209250549051908152f35b505034610194578160031936011261019457517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50503461019457816003193601126101945760209063ffffffff600954169051908152f35b50503461019457816003193601126101945760209061026960055460025490611216565b505034610194578160031936011261019457602090610269611187565b91905034610229576020928360031936011261057057823561039a600e54156112b4565b6001600e558015610561576103ae33611467565b506103be60055460025490611216565b6001549081158015610559575b1561054157505080935b84156105335783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156105295784916104fc575b50156104ee575061044c81600554611216565b600555338252600b8552828220610464858254611216565b905561047284600154611216565b600155338252600b8552670de0b6b3a76400006104958484205460035490611237565b04338352600c8652838320556104a96115b5565b600154835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600e5551908152f35b835163be24f3c560e01b8152fd5b61051c9150873d8911610522575b6105148183611151565b8101906112ed565b5f610439565b503d61050a565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b61054e6105539284611237565b61124a565b936103d5565b5080156103cb565b50505163162908e360e11b8152fd5b80fd5b919050346102295760209283600319360112610570578235610597600e54156112b4565b6001600e55808252600d855282822080546001600160a01b039591908616801561082f5733036108215760028101805460ff8160481c166108115767ffffffffffffffff8042169082168082106107f5575050861c60ff1615610742575b805460ff60481b1916600160481b179055600101546007549095908087116107265761062a610622611187565b84549061131a565b80881161070a57508661063c9161131a565b600755845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af19081156105295784916106ed575b50156106df57506106ac6115b5565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600e5551908152f35b835163022e258160e11b8152fd5b6107049150873d8911610522576105148183611151565b5f61069d565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b6001820180546006548082116107d857600194939261078388937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361131a565b6006556107938154600754611216565b6007558560401b60ff60401b1985541617845554600654906107cd6007548c51938493846040919493926060820195825260208201520152565b0390a29091506105f5565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b50503461019457816003193601126101945760209051670de0b6b3a76400008152f35b905034610229576020366003190112610229578254813591906001600160a01b031633036108c45750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610229576020366003190112610229578160a09360ff92358152600d602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b505034610194578160031936011261019457905490516001600160a01b039091168152602090f35b5050346101945781600319360112610194576020906008549051908152f35b5050346101945781600319360112610194576020906002549051908152f35b5050346101945781600319360112610194576020906007549051908152f35b5050346101945781600319360112610194576020906005549051908152f35b5050346101945781600319360112610194576020906001549051908152f35b90503461022957602036600319011261022957356001600160a01b038116908190036102295782829160209452600c845220549051908152f35b838334610194578160031936011261019457610a57600e54156112b4565b6001600e55610a64611187565b9163ffffffff60095416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610c3c578291610c1e575b5015610c0e57610aad611187565b83811115610c0757610abf848261131a565b935b84158015610b08575b5060209550905f8051602061165883398151915291610ae76115b5565b8451908152602081019190915260408101859052606090a1600e5551908152f35b610b13868854611216565b908188556001549081610b86575b505060209650907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f805160206116588339815191529392600354610b7c88519283928b846040919493926060820195825260208201520152565b0390a19091610aca565b670de0b6b3a76400009081890291898304141715610bf4576020985091610be9610be17f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691935f8051602061165883398151915297969561124a565b600354611216565b600355919293610b21565b634e487b7160e01b865260118952602486fd5b8193610ac1565b8151630d599dd960e11b81528490fd5b610c36915060203d8111610522576105148183611151565b85610a9f565b83513d84823e3d90fd5b50503461019457816003193601126101945790602091610c68600e54156112b4565b6001600e55610c75611327565b91600e5551908152f35b50503461019457816003193601126101945790602091610ca1600e54156112b4565b6001600e55610c7533611467565b919050346102295760209283600319360112610570578235610cd3600e54156112b4565b60019384600e558115610ff657610ce933611467565b50338352600b8652838320548083118015610fed575b610fde57610d1a610d1260025485611237565b87549061124a565b918215610fd0576009548651633991e9e560e11b81523081840190815260208101869052918a1c63ffffffff16604083015260609493909267ffffffffffffffff9290919042841690879086908190830103818c6108005af1948515610fc65789908a96610f6a575b50868103610f4e57508460070b898113801590610f43575b610f2857505086610dab9161131a565b338852600b8b5288882055610dc1868a5461131a565b8955610dcf8460025461131a565b600255610dde84600654611216565b600655338752600b8a52670de0b6b3a7640000610e018989205460035490611237565b04338852600c8b5288882055610e156115b5565b600854985f198a14610f1557808a0160085588519160a083019083821085831117610f0257508a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea198958f94958e859d9c9a978152338352868301908982528581850199169a8b8a52600d8d860199828b526080870199838b52835252209260018060a01b0390511660018060a01b031984541617835551908201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600e5551908152f35b634e487b7160e01b8a5260419052602489fd5b634e487b7160e01b885260118252602488fd5b8a5163158e5da560e11b815293840152602483015250604490fd5b508185871610610d9b565b83604491888d5192633a54e96d60e21b84528301526024820152fd5b80929394959650888092503d8311610fbf575b610f878183611151565b81010312610fbb57908982610fa38e9796959451978201611309565b500151948560070b8603610fb7575f610d83565b8980fd5b8880fd5b503d610f7d565b8a513d8b823e3d90fd5b855163162908e360e11b8152fd5b508351630e433c2360e31b8152fd5b50855415610cff565b8351630e433c2360e31b8152fd5b9050346102295760603660031901126102295780359163ffffffff80841680940361022557602435908116908181036110cb57855460443594906001600160a01b031633036110be5782156110b057506009805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600a84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b50503461019457816003193601126101945760209061026960065460075490611216565b90503461022957602036600319011261022957356001600160a01b038116908190036102295782829160209452600b845220549051908152f35b84903461019457816003193601126101945760209063ffffffff600954831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761117357604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561120b575f916111dd575090565b906020823d8211611203575b816111f660209383611151565b8101031261057057505190565b3d91506111e9565b6040513d5f823e3d90fd5b9190820180921161122357565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561122357565b8115611254570490565b634e487b7160e01b5f52601260045260245ffd5b60015480156112a75761128060055460025490611216565b90670de0b6b3a764000091828102928184041490151715611223576112a49161124a565b90565b50670de0b6b3a764000090565b156112bb57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312611305575180151581036113055790565b5f80fd5b519063ffffffff8216820361130557565b9190820391821161122357565b60055490600a548210611462576009546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af1958615611456578380976113ec575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6939160809382976113b98460055461131a565b6005556113c884600254611216565b93846002556113d56115b5565b8351958652602086015216908301526060820152a1565b91965092508183813d831161144f575b6114068183611151565b81010312610570575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6936114436020608095519301611309565b96919381939550611382565b503d6113fc565b505051903d90823e3d90fd5b5f9150565b9060018060a01b0391828116905f90828252602091600b8352604091670de0b6b3a764000061149c8484205460035490611237565b04858352600c8552838320908082549255818111156115aa57916114c486926115079461131a565b9889916114d38360045461131a565b60045585875180968195829463a9059cbb60e01b84526004840160209093929193604081019460018060a01b031681520152565b03927f0000000000000000000000000000000000000000000000000000000000000000165af191821561159f5791611582575b501561157257907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe9161156b6115b5565b51858152a2565b5163022e258160e11b8152600490fd5b6115999150833d8511610522576105148183611151565b5f61153a565b8351903d90823e3d90fd5b509196505050505050565b6115bd611187565b60045481811161163a57600754906115d58282611216565b83811161161c5750906115ed6115f292600554611216565b611216565b908082116115fe575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea2646970667358221220682df586013c5d054b693ac7ca6c6e79dcfb4d82a89610b1d1213d4d9a50700864736f6c63430008140033", - "deployedBytecode": "0x6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac52561461112d575081630eccc708146110f35781630ed61edb146110cf5781631a0a253c146110045781632e1a7d4d14610caf578163372500ab14610c7f5781633a4b66f114610c465781634641257d14610a395781635873eb9b146109ff5781636d86acc4146109e05781636f620185146109c15781637bfe7d57146109a2578163817b1cd2146109835781638ca82108146109645781638da5cb5b1461093c578163992a7dfb146108d1578163a8c7914714610862578163aaf5eb681461083f578163b13acedd14610573578163b6b55f2514610376578163b7ec1a3314610359578163bae8059414610335578163bbe9a07014610310578163c28f4392146102cc578163cab64bcd146102ae578163d5f884a11461028f578163dacd7e0c14610270578163e66825c31461024c578163f18876841461022d578163f2fde38b14610198575063f74bcf2914610177575f80fd5b346101945781600319360112610194576020906005549051908152f35b5080fd5b91905034610229576020366003190112610229576001600160a01b03823581811693908490036102255784549182169283330361021957841561020c5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b505034610194578160031936011261019457602090600a549051908152f35b505034610194578160031936011261019457602090610269611268565b9051908152f35b5050346101945781600319360112610194576020906003549051908152f35b5050346101945781600319360112610194576020906006549051908152f35b90503461022957826003193601126102295760209250549051908152f35b505034610194578160031936011261019457517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b50503461019457816003193601126101945760209063ffffffff600954169051908152f35b50503461019457816003193601126101945760209061026960055460025490611216565b505034610194578160031936011261019457602090610269611187565b91905034610229576020928360031936011261057057823561039a600e54156112b4565b6001600e558015610561576103ae33611467565b506103be60055460025490611216565b6001549081158015610559575b1561054157505080935b84156105335783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156105295784916104fc575b50156104ee575061044c81600554611216565b600555338252600b8552828220610464858254611216565b905561047284600154611216565b600155338252600b8552670de0b6b3a76400006104958484205460035490611237565b04338352600c8652838320556104a96115b5565b600154835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600e5551908152f35b835163be24f3c560e01b8152fd5b61051c9150873d8911610522575b6105148183611151565b8101906112ed565b5f610439565b503d61050a565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b61054e6105539284611237565b61124a565b936103d5565b5080156103cb565b50505163162908e360e11b8152fd5b80fd5b919050346102295760209283600319360112610570578235610597600e54156112b4565b6001600e55808252600d855282822080546001600160a01b039591908616801561082f5733036108215760028101805460ff8160481c166108115767ffffffffffffffff8042169082168082106107f5575050861c60ff1615610742575b805460ff60481b1916600160481b179055600101546007549095908087116107265761062a610622611187565b84549061131a565b80881161070a57508661063c9161131a565b600755845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af19081156105295784916106ed575b50156106df57506106ac6115b5565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600e5551908152f35b835163022e258160e11b8152fd5b6107049150873d8911610522576105148183611151565b5f61069d565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b6001820180546006548082116107d857600194939261078388937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361131a565b6006556107938154600754611216565b6007558560401b60ff60401b1985541617845554600654906107cd6007548c51938493846040919493926060820195825260208201520152565b0390a29091506105f5565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b50503461019457816003193601126101945760209051670de0b6b3a76400008152f35b905034610229576020366003190112610229578254813591906001600160a01b031633036108c45750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600254908060025582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610229576020366003190112610229578160a09360ff92358152600d602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b505034610194578160031936011261019457905490516001600160a01b039091168152602090f35b5050346101945781600319360112610194576020906008549051908152f35b5050346101945781600319360112610194576020906002549051908152f35b5050346101945781600319360112610194576020906007549051908152f35b5050346101945781600319360112610194576020906005549051908152f35b5050346101945781600319360112610194576020906001549051908152f35b90503461022957602036600319011261022957356001600160a01b038116908190036102295782829160209452600c845220549051908152f35b838334610194578160031936011261019457610a57600e54156112b4565b6001600e55610a64611187565b9163ffffffff60095416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610c3c578291610c1e575b5015610c0e57610aad611187565b83811115610c0757610abf848261131a565b935b84158015610b08575b5060209550905f8051602061165883398151915291610ae76115b5565b8451908152602081019190915260408101859052606090a1600e5551908152f35b610b13868854611216565b908188556001549081610b86575b505060209650907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f805160206116588339815191529392600354610b7c88519283928b846040919493926060820195825260208201520152565b0390a19091610aca565b670de0b6b3a76400009081890291898304141715610bf4576020985091610be9610be17f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691935f8051602061165883398151915297969561124a565b600354611216565b600355919293610b21565b634e487b7160e01b865260118952602486fd5b8193610ac1565b8151630d599dd960e11b81528490fd5b610c36915060203d8111610522576105148183611151565b85610a9f565b83513d84823e3d90fd5b50503461019457816003193601126101945790602091610c68600e54156112b4565b6001600e55610c75611327565b91600e5551908152f35b50503461019457816003193601126101945790602091610ca1600e54156112b4565b6001600e55610c7533611467565b919050346102295760209283600319360112610570578235610cd3600e54156112b4565b60019384600e558115610ff657610ce933611467565b50338352600b8652838320548083118015610fed575b610fde57610d1a610d1260025485611237565b87549061124a565b918215610fd0576009548651633991e9e560e11b81523081840190815260208101869052918a1c63ffffffff16604083015260609493909267ffffffffffffffff9290919042841690879086908190830103818c6108005af1948515610fc65789908a96610f6a575b50868103610f4e57508460070b898113801590610f43575b610f2857505086610dab9161131a565b338852600b8b5288882055610dc1868a5461131a565b8955610dcf8460025461131a565b600255610dde84600654611216565b600655338752600b8a52670de0b6b3a7640000610e018989205460035490611237565b04338852600c8b5288882055610e156115b5565b600854985f198a14610f1557808a0160085588519160a083019083821085831117610f0257508a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea198958f94958e859d9c9a978152338352868301908982528581850199169a8b8a52600d8d860199828b526080870199838b52835252209260018060a01b0390511660018060a01b031984541617835551908201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600e5551908152f35b634e487b7160e01b8a5260419052602489fd5b634e487b7160e01b885260118252602488fd5b8a5163158e5da560e11b815293840152602483015250604490fd5b508185871610610d9b565b83604491888d5192633a54e96d60e21b84528301526024820152fd5b80929394959650888092503d8311610fbf575b610f878183611151565b81010312610fbb57908982610fa38e9796959451978201611309565b500151948560070b8603610fb7575f610d83565b8980fd5b8880fd5b503d610f7d565b8a513d8b823e3d90fd5b855163162908e360e11b8152fd5b508351630e433c2360e31b8152fd5b50855415610cff565b8351630e433c2360e31b8152fd5b9050346102295760603660031901126102295780359163ffffffff80841680940361022557602435908116908181036110cb57855460443594906001600160a01b031633036110be5782156110b057506009805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600a84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b50503461019457816003193601126101945760209061026960065460075490611216565b90503461022957602036600319011261022957356001600160a01b038116908190036102295782829160209452600b845220549051908152f35b84903461019457816003193601126101945760209063ffffffff600954831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761117357604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561120b575f916111dd575090565b906020823d8211611203575b816111f660209383611151565b8101031261057057505190565b3d91506111e9565b6040513d5f823e3d90fd5b9190820180921161122357565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561122357565b8115611254570490565b634e487b7160e01b5f52601260045260245ffd5b60015480156112a75761128060055460025490611216565b90670de0b6b3a764000091828102928184041490151715611223576112a49161124a565b90565b50670de0b6b3a764000090565b156112bb57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312611305575180151581036113055790565b5f80fd5b519063ffffffff8216820361130557565b9190820391821161122357565b60055490600a548210611462576009546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af1958615611456578380976113ec575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6939160809382976113b98460055461131a565b6005556113c884600254611216565b93846002556113d56115b5565b8351958652602086015216908301526060820152a1565b91965092508183813d831161144f575b6114068183611151565b81010312610570575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6936114436020608095519301611309565b96919381939550611382565b503d6113fc565b505051903d90823e3d90fd5b5f9150565b9060018060a01b0391828116905f90828252602091600b8352604091670de0b6b3a764000061149c8484205460035490611237565b04858352600c8552838320908082549255818111156115aa57916114c486926115079461131a565b9889916114d38360045461131a565b60045585875180968195829463a9059cbb60e01b84526004840160209093929193604081019460018060a01b031681520152565b03927f0000000000000000000000000000000000000000000000000000000000000000165af191821561159f5791611582575b501561157257907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe9161156b6115b5565b51858152a2565b5163022e258160e11b8152600490fd5b6115999150833d8511610522576105148183611151565b5f61153a565b8351903d90823e3d90fd5b509196505050505050565b6115bd611187565b60045481811161163a57600754906115d58282611216565b83811161161c5750906115ed6115f292600554611216565b611216565b908082116115fe575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea2646970667358221220682df586013c5d054b693ac7ca6c6e79dcfb4d82a89610b1d1213d4d9a50700864736f6c63430008140033", + "bytecode": "0x60a0346200015557601f6200195c38819003918201601f19168301916001600160401b03831184841017620001595780849260a09460405283398101031262000155576200004d816200016d565b906200005c6020820162000182565b906200006b6040820162000182565b916200007f6080606084015193016200016d565b60016009556001600160a01b03949093908516801580156200014a575b620001385763ffffffff9081831615620001265760805267ffffffff00000000600a549260201b1692169060018060401b0319161717600a55600b551660018060a01b031981815f5416175f5560015416176001556040516117c7908162000195823960805181818161031f0152818161043f015281816106ab015281816112b701526116250152f35b6040516306b7c75960e31b8152600490fd5b60405163e6c4247b60e01b8152600490fd5b50858516156200009c565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036200015557565b519063ffffffff82168203620001555756fe6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac525614611242575081630eccc708146112085781630ed61edb146111e45781631a0a253c146111195781632e1a7d4d14610dc9578163372500ab14610d995781633a4b66f114610d355781634641257d14610af15781635873eb9b14610ab75781636d86acc414610a985781636f62018514610a795781637bfe7d5714610a5a578163817b1cd214610a3b57816383810d1d146109c15781638ca82108146109a25781638da5cb5b1461097a578163992a7dfb1461090f578163a8c79147146108a0578163aaf5eb681461087d578163b13acedd146105b0578163b6b55f25146103b4578163b7ec1a3314610397578163bae8059414610373578163bbe9a0701461034e578163c28f43921461030a578163cab64bcd146102eb578163d5f884a1146102cc578163dacd7e0c146102ae578163e66825c31461028a578163f18876841461026b578163f2fde38b146101d657508063f74bcf29146101b85763fa303a531461018d575f80fd5b346101b457816003193601126101b45760015490516001600160a01b039091168152602090f35b5080fd5b50346101b457816003193601126101b4576020906006549051908152f35b91905034610267576020366003190112610267576001600160a01b03823581811693908490036102635784549182169283330361025757841561024a5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b5050346101b457816003193601126101b457602090600b549051908152f35b5050346101b457816003193601126101b4576020906102a761137d565b9051908152f35b90503461026757826003193601126102675760209250549051908152f35b5050346101b457816003193601126101b4576020906007549051908152f35b5050346101b457816003193601126101b4576020906005549051908152f35b5050346101b457816003193601126101b457517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5050346101b457816003193601126101b45760209063ffffffff600a54169051908152f35b5050346101b457816003193601126101b4576020906102a76006546003549061132b565b5050346101b457816003193601126101b4576020906102a761129c565b9190503461026757602092836003193601126105ad5782356103d8600f54156113c9565b6001600f55801561059e576103ec3361157c565b506103fc6006546003549061132b565b6002549081158015610596575b1561057e57505080935b84156105705783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610566578491610539575b501561052b576104d2670de0b6b3a7640000916104968460065461132b565b600655338552600c88528585206104ae88825461132b565b90556104bc8760025461132b565b600255338552600c88528585205490549061134c565b04338352600d8652838320556104e66116cf565b600254835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600f5551908152f35b835163be24f3c560e01b8152fd5b6105599150873d891161055f575b6105518183611266565b810190611402565b5f610477565b503d610547565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b61058b610590928461134c565b61135f565b93610413565b508015610409565b50505163162908e360e11b8152fd5b80fd5b9190503461026757602092836003193601126105ad5782356105d4600f54156113c9565b6001600f55808252600e855282822080546001600160a01b039591908616801561086d57330361085f5760028101805460ff8160481c1661084f5767ffffffffffffffff804216908216808210610833575050861c60ff1615610780575b805460ff60481b1916600160481b179055600101546008549095908087116107645761066861065f61129c565b6005549061142f565b80881161074857508661067a9161142f565b600855845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af190811561056657849161072b575b501561071d57506106ea6116cf565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600f5551908152f35b835163022e258160e11b8152fd5b6107429150873d891161055f576105518183611266565b5f6106db565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b6001820180546007548082116108165760019493926107c188937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361142f565b6007556107d1815460085461132b565b6008558560401b60ff60401b19855416178455546007549061080b6008548c51938493846040919493926060820195825260208201520152565b0390a2909150610632565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b5050346101b457816003193601126101b45760209051670de0b6b3a76400008152f35b905034610267576020366003190112610267578254813591906001600160a01b031633036109025750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600354908060035582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610267576020366003190112610267578160a09360ff92358152600e602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b5050346101b457816003193601126101b457905490516001600160a01b039091168152602090f35b5050346101b457816003193601126101b4576020906009549051908152f35b91905034610267576020366003190112610267576001600160a01b038235818116939192908490036102635782855416330361025757831561024a575050600180546001600160a01b031981168417909155167f9b6cbce723aab630d07d7af8531985c84625fa96e4c7405835f8d8ca53b5bb498380a380f35b5050346101b457816003193601126101b4576020906003549051908152f35b5050346101b457816003193601126101b4576020906008549051908152f35b5050346101b457816003193601126101b4576020906006549051908152f35b5050346101b457816003193601126101b4576020906002549051908152f35b90503461026757602036600319011261026757356001600160a01b038116908190036102675782829160209452600d845220549051908152f35b8383346101b457816003193601126101b457610b0f600f54156113c9565b6001600f558154336001600160a01b0391821614159081610d26575b50610d1857610b3861129c565b9163ffffffff600a5416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610d0e578291610cf0575b5015610ce057610b8161129c565b83811115610cd957610b93848261142f565b935b84158015610bdc575b5060209550905f8051602061177283398151915291610bbb6116cf565b8451908152602081019190915260408101859052606090a1600f5551908152f35b610be88660055461132b565b90816005556002549081610c59575b5050907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f80516020611772833981519152939260209854610c4f88519283928b846040919493926060820195825260208201520152565b0390a19091610b9e565b670de0b6b3a76400009081890291898304141715610cc65791602098610cba610cb37f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691945f8051602061177283398151915298979661135f565b825461132b565b81559850919293610bf7565b634e487b7160e01b865260118952602486fd5b8193610b95565b8151630d599dd960e11b81528490fd5b610d08915060203d811161055f576105518183611266565b85610b73565b83513d84823e3d90fd5b516282b42960e81b81529050fd5b90506001541633141584610b2b565b8383346101b457816003193601126101b457610d53600f54156113c9565b6001600f558154336001600160a01b0391821614159081610d8a575b50610d185760209250610d8061143c565b91600f5551908152f35b90506001541633141584610d6f565b5050346101b457816003193601126101b45790602091610dbb600f54156113c9565b6001600f55610d803361157c565b9190503461026757602092836003193601126105ad578235610ded600f54156113c9565b6001600f55801561110a57610e013361157c565b50338252600c8552828220548082118015611100575b6110f057610e33610e2a6003548461134c565b6002549061135f565b9081156110e057600a548551633991e9e560e11b8152308189019081526020810185905291891c63ffffffff16604083015260609392909167ffffffffffffffff919042831690869085908190830103818b6108005af19384156110d65788908995611083575b5085810361106757508360070b88811380159061105c575b61104057505085610ec29161142f565b338752600c8a5287872055610ed98560025461142f565b600255610ee88360035461142f565b600355610ef78360075461132b565b600755338652600c8952670de0b6b3a7640000610f19888820548a549061134c565b04338752600d8a5287872055610f2d6116cf565b600954975f19891461102d576001890160095587519060a08201908282108483111761101a5750928a8a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea19895839b9a988e523381528d85820190888252848184019816998a8952600e8c850198828a526080860198838a52835252209160018060a01b0390511660018060a01b03198354161782555160018201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600f5551908152f35b634e487b7160e01b895260419052602488fd5b634e487b7160e01b875260119052602486fd5b6044918b918b519263158e5da560e11b84528301526024820152fd5b508184861610610eb2565b8a604491878c5192633a54e96d60e21b84528301526024820152fd5b809550878092503d83116110cf575b61109c8183611266565b810103126110cb57888451946110b38d820161141e565b500151938460070b85036110c7575f610e9a565b8880fd5b8780fd5b503d611092565b89513d8a823e3d90fd5b845163162908e360e11b81528690fd5b50505051630e433c2360e31b8152fd5b5060025415610e17565b505051630e433c2360e31b8152fd5b9050346102675760603660031901126102675780359163ffffffff80841680940361026357602435908116908181036111e057855460443594906001600160a01b031633036111d35782156111c55750600a805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600b84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b5050346101b457816003193601126101b4576020906102a76007546008549061132b565b90503461026757602036600319011261026757356001600160a01b038116908190036102675782829160209452600c845220549051908152f35b8490346101b457816003193601126101b45760209063ffffffff600a54831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761128857604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611320575f916112f2575090565b906020823d8211611318575b8161130b60209383611266565b810103126105ad57505190565b3d91506112fe565b6040513d5f823e3d90fd5b9190820180921161133857565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561133857565b8115611369570490565b634e487b7160e01b5f52601260045260245ffd5b60025480156113bc576113956006546003549061132b565b90670de0b6b3a764000091828102928184041490151715611338576113b99161135f565b90565b50670de0b6b3a764000090565b156113d057565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b9081602091031261141a5751801515810361141a5790565b5f80fd5b519063ffffffff8216820361141a57565b9190820391821161133857565b60065490600b54821061157757600a546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af195861561156b57838097611501575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6939160809382976114ce8460065461142f565b6006556114dd8460035461132b565b93846003556114ea6116cf565b8351958652602086015216908301526060820152a1565b91965092508183813d8311611564575b61151b8183611266565b810103126105ad575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f693611558602060809551930161141e565b96919381939550611497565b503d611511565b505051903d90823e3d90fd5b5f9150565b9060018060a01b0391828116905f90828252602091600c8352604091670de0b6b3a76400006115b1848420546004549061134c565b04858352600d8552838320908082549255818111156116c457916115d986926116219461142f565b9889916115e88360055461142f565b600555865163a9059cbb60e01b81526001600160a01b039091166004820152602481019290925290928391908290869082906044820190565b03927f0000000000000000000000000000000000000000000000000000000000000000165af19182156116b9579161169c575b501561168c57907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe916116856116cf565b51858152a2565b5163022e258160e11b8152600490fd5b6116b39150833d851161055f576105518183611266565b5f611654565b8351903d90823e3d90fd5b509196505050505050565b6116d761129c565b60055481811161175457600854906116ef828261132b565b83811161173657509061170761170c9260065461132b565b61132b565b90808211611718575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea2646970667358221220414c83de887f7aba70f466b3b0148b72c8c1b8e43eba93c815fb2625fddf1cb564736f6c63430008140033", + "deployedBytecode": "0x6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac525614611242575081630eccc708146112085781630ed61edb146111e45781631a0a253c146111195781632e1a7d4d14610dc9578163372500ab14610d995781633a4b66f114610d355781634641257d14610af15781635873eb9b14610ab75781636d86acc414610a985781636f62018514610a795781637bfe7d5714610a5a578163817b1cd214610a3b57816383810d1d146109c15781638ca82108146109a25781638da5cb5b1461097a578163992a7dfb1461090f578163a8c79147146108a0578163aaf5eb681461087d578163b13acedd146105b0578163b6b55f25146103b4578163b7ec1a3314610397578163bae8059414610373578163bbe9a0701461034e578163c28f43921461030a578163cab64bcd146102eb578163d5f884a1146102cc578163dacd7e0c146102ae578163e66825c31461028a578163f18876841461026b578163f2fde38b146101d657508063f74bcf29146101b85763fa303a531461018d575f80fd5b346101b457816003193601126101b45760015490516001600160a01b039091168152602090f35b5080fd5b50346101b457816003193601126101b4576020906006549051908152f35b91905034610267576020366003190112610267576001600160a01b03823581811693908490036102635784549182169283330361025757841561024a5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b5050346101b457816003193601126101b457602090600b549051908152f35b5050346101b457816003193601126101b4576020906102a761137d565b9051908152f35b90503461026757826003193601126102675760209250549051908152f35b5050346101b457816003193601126101b4576020906007549051908152f35b5050346101b457816003193601126101b4576020906005549051908152f35b5050346101b457816003193601126101b457517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5050346101b457816003193601126101b45760209063ffffffff600a54169051908152f35b5050346101b457816003193601126101b4576020906102a76006546003549061132b565b5050346101b457816003193601126101b4576020906102a761129c565b9190503461026757602092836003193601126105ad5782356103d8600f54156113c9565b6001600f55801561059e576103ec3361157c565b506103fc6006546003549061132b565b6002549081158015610596575b1561057e57505080935b84156105705783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610566578491610539575b501561052b576104d2670de0b6b3a7640000916104968460065461132b565b600655338552600c88528585206104ae88825461132b565b90556104bc8760025461132b565b600255338552600c88528585205490549061134c565b04338352600d8652838320556104e66116cf565b600254835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600f5551908152f35b835163be24f3c560e01b8152fd5b6105599150873d891161055f575b6105518183611266565b810190611402565b5f610477565b503d610547565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b61058b610590928461134c565b61135f565b93610413565b508015610409565b50505163162908e360e11b8152fd5b80fd5b9190503461026757602092836003193601126105ad5782356105d4600f54156113c9565b6001600f55808252600e855282822080546001600160a01b039591908616801561086d57330361085f5760028101805460ff8160481c1661084f5767ffffffffffffffff804216908216808210610833575050861c60ff1615610780575b805460ff60481b1916600160481b179055600101546008549095908087116107645761066861065f61129c565b6005549061142f565b80881161074857508661067a9161142f565b600855845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af190811561056657849161072b575b501561071d57506106ea6116cf565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600f5551908152f35b835163022e258160e11b8152fd5b6107429150873d891161055f576105518183611266565b5f6106db565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b6001820180546007548082116108165760019493926107c188937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361142f565b6007556107d1815460085461132b565b6008558560401b60ff60401b19855416178455546007549061080b6008548c51938493846040919493926060820195825260208201520152565b0390a2909150610632565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b5050346101b457816003193601126101b45760209051670de0b6b3a76400008152f35b905034610267576020366003190112610267578254813591906001600160a01b031633036109025750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600354908060035582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610267576020366003190112610267578160a09360ff92358152600e602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b5050346101b457816003193601126101b457905490516001600160a01b039091168152602090f35b5050346101b457816003193601126101b4576020906009549051908152f35b91905034610267576020366003190112610267576001600160a01b038235818116939192908490036102635782855416330361025757831561024a575050600180546001600160a01b031981168417909155167f9b6cbce723aab630d07d7af8531985c84625fa96e4c7405835f8d8ca53b5bb498380a380f35b5050346101b457816003193601126101b4576020906003549051908152f35b5050346101b457816003193601126101b4576020906008549051908152f35b5050346101b457816003193601126101b4576020906006549051908152f35b5050346101b457816003193601126101b4576020906002549051908152f35b90503461026757602036600319011261026757356001600160a01b038116908190036102675782829160209452600d845220549051908152f35b8383346101b457816003193601126101b457610b0f600f54156113c9565b6001600f558154336001600160a01b0391821614159081610d26575b50610d1857610b3861129c565b9163ffffffff600a5416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610d0e578291610cf0575b5015610ce057610b8161129c565b83811115610cd957610b93848261142f565b935b84158015610bdc575b5060209550905f8051602061177283398151915291610bbb6116cf565b8451908152602081019190915260408101859052606090a1600f5551908152f35b610be88660055461132b565b90816005556002549081610c59575b5050907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f80516020611772833981519152939260209854610c4f88519283928b846040919493926060820195825260208201520152565b0390a19091610b9e565b670de0b6b3a76400009081890291898304141715610cc65791602098610cba610cb37f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691945f8051602061177283398151915298979661135f565b825461132b565b81559850919293610bf7565b634e487b7160e01b865260118952602486fd5b8193610b95565b8151630d599dd960e11b81528490fd5b610d08915060203d811161055f576105518183611266565b85610b73565b83513d84823e3d90fd5b516282b42960e81b81529050fd5b90506001541633141584610b2b565b8383346101b457816003193601126101b457610d53600f54156113c9565b6001600f558154336001600160a01b0391821614159081610d8a575b50610d185760209250610d8061143c565b91600f5551908152f35b90506001541633141584610d6f565b5050346101b457816003193601126101b45790602091610dbb600f54156113c9565b6001600f55610d803361157c565b9190503461026757602092836003193601126105ad578235610ded600f54156113c9565b6001600f55801561110a57610e013361157c565b50338252600c8552828220548082118015611100575b6110f057610e33610e2a6003548461134c565b6002549061135f565b9081156110e057600a548551633991e9e560e11b8152308189019081526020810185905291891c63ffffffff16604083015260609392909167ffffffffffffffff919042831690869085908190830103818b6108005af19384156110d65788908995611083575b5085810361106757508360070b88811380159061105c575b61104057505085610ec29161142f565b338752600c8a5287872055610ed98560025461142f565b600255610ee88360035461142f565b600355610ef78360075461132b565b600755338652600c8952670de0b6b3a7640000610f19888820548a549061134c565b04338752600d8a5287872055610f2d6116cf565b600954975f19891461102d576001890160095587519060a08201908282108483111761101a5750928a8a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea19895839b9a988e523381528d85820190888252848184019816998a8952600e8c850198828a526080860198838a52835252209160018060a01b0390511660018060a01b03198354161782555160018201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600f5551908152f35b634e487b7160e01b895260419052602488fd5b634e487b7160e01b875260119052602486fd5b6044918b918b519263158e5da560e11b84528301526024820152fd5b508184861610610eb2565b8a604491878c5192633a54e96d60e21b84528301526024820152fd5b809550878092503d83116110cf575b61109c8183611266565b810103126110cb57888451946110b38d820161141e565b500151938460070b85036110c7575f610e9a565b8880fd5b8780fd5b503d611092565b89513d8a823e3d90fd5b845163162908e360e11b81528690fd5b50505051630e433c2360e31b8152fd5b5060025415610e17565b505051630e433c2360e31b8152fd5b9050346102675760603660031901126102675780359163ffffffff80841680940361026357602435908116908181036111e057855460443594906001600160a01b031633036111d35782156111c55750600a805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600b84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b5050346101b457816003193601126101b4576020906102a76007546008549061132b565b90503461026757602036600319011261026757356001600160a01b038116908190036102675782829160209452600c845220549051908152f35b8490346101b457816003193601126101b45760209063ffffffff600a54831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761128857604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611320575f916112f2575090565b906020823d8211611318575b8161130b60209383611266565b810103126105ad57505190565b3d91506112fe565b6040513d5f823e3d90fd5b9190820180921161133857565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561133857565b8115611369570490565b634e487b7160e01b5f52601260045260245ffd5b60025480156113bc576113956006546003549061132b565b90670de0b6b3a764000091828102928184041490151715611338576113b99161135f565b90565b50670de0b6b3a764000090565b156113d057565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b9081602091031261141a5751801515810361141a5790565b5f80fd5b519063ffffffff8216820361141a57565b9190820391821161133857565b60065490600b54821061157757600a546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af195861561156b57838097611501575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6939160809382976114ce8460065461142f565b6006556114dd8460035461132b565b93846003556114ea6116cf565b8351958652602086015216908301526060820152a1565b91965092508183813d8311611564575b61151b8183611266565b810103126105ad575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f693611558602060809551930161141e565b96919381939550611497565b503d611511565b505051903d90823e3d90fd5b5f9150565b9060018060a01b0391828116905f90828252602091600c8352604091670de0b6b3a76400006115b1848420546004549061134c565b04858352600d8552838320908082549255818111156116c457916115d986926116219461142f565b9889916115e88360055461142f565b600555865163a9059cbb60e01b81526001600160a01b039091166004820152602481019290925290928391908290869082906044820190565b03927f0000000000000000000000000000000000000000000000000000000000000000165af19182156116b9579161169c575b501561168c57907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe916116856116cf565b51858152a2565b5163022e258160e11b8152600490fd5b6116b39150833d851161055f576105518183611266565b5f611654565b8351903d90823e3d90fd5b509196505050505050565b6116d761129c565b60055481811161175457600854906116ef828261132b565b83811161173657509061170761170c9260065461132b565b61132b565b90808211611718575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea2646970667358221220414c83de887f7aba70f466b3b0148b72c8c1b8e43eba93c815fb2625fddf1cb564736f6c63430008140033", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": { - "3943": [ + "9": [ { "length": 32, - "start": 737 + "start": 799 }, { "length": 32, - "start": 1025 + "start": 1087 }, { "length": 32, - "start": 1645 + "start": 1707 }, { "length": 32, - "start": 4514 + "start": 4791 }, { "length": 32, - "start": 5387 + "start": 5669 } ] }, "inputSourceName": "project/solidity/pool/CommunityPool.sol", - "buildInfoId": "solc-0_8_20-976e47a1ebd979fc766a2ad9b546f4ca71dab7dd" + "buildInfoId": "solc-0_8_20-964f328906be1a5d90d685a6c14ba52665e8f58a" } \ No newline at end of file diff --git a/contracts/solidity/pool/CommunityPool.sol b/contracts/solidity/pool/CommunityPool.sol index 555a817d..734b2ab6 100644 --- a/contracts/solidity/pool/CommunityPool.sol +++ b/contracts/solidity/pool/CommunityPool.sol @@ -24,6 +24,8 @@ contract CommunityPool { uint256 public constant PRECISION = 1e18; address public owner; + /// @dev Optional automation caller allowed to trigger periodic stake/harvest. + address public automationCaller; /// @dev Total ownership units minted by the pool. uint256 public totalUnits; /// @dev Accounting value of delegated principal (not auto-reconciled with staking state). @@ -82,6 +84,7 @@ contract CommunityPool { error StakeablePrincipalInvariantViolation(uint256 accountedLiquid, uint256 liquidBalance); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); + event AutomationCallerUpdated(address indexed previousCaller, address indexed newCaller); event ConfigUpdated(uint32 maxRetrieve, uint32 maxValidators, uint256 minStakeAmount); event Deposit(address indexed user, uint256 amount, uint256 mintedUnits, uint256 totalUnitsAfter); event Stake(uint256 liquidBefore, uint256 delegatedAmount, uint256 validatorsCount, uint256 totalStakedAfter); @@ -111,6 +114,13 @@ contract CommunityPool { _; } + modifier onlyAutomationOrOwner() { + if (msg.sender != owner && msg.sender != automationCaller) { + revert Unauthorized(); + } + _; + } + modifier nonReentrant() { require(_entered == 0, "reentrancy"); _entered = 1; @@ -137,6 +147,7 @@ contract CommunityPool { maxValidators = maxValidators_; minStakeAmount = minStakeAmount_; owner = owner_; + automationCaller = owner_; } /// @notice Transfers owner privileges to a new address. @@ -150,6 +161,16 @@ contract CommunityPool { emit OwnershipTransferred(previousOwner, newOwner); } + /// @notice Sets the automation caller allowed to run stake/harvest besides owner. + function setAutomationCaller(address newAutomationCaller) external onlyOwner { + if (newAutomationCaller == address(0)) { + revert InvalidAddress(); + } + address previousCaller = automationCaller; + automationCaller = newAutomationCaller; + emit AutomationCallerUpdated(previousCaller, newAutomationCaller); + } + /// @notice Updates operational parameters used by stake/harvest. /// @param newMaxRetrieve Max validator rewards to claim per harvest call. /// @param newMaxValidators Max bonded validators to target in one stake call. @@ -350,8 +371,8 @@ contract CommunityPool { } /// @notice Delegates available principal liquid to bonded validators via staking precompile. - /// @dev Uses a single precompile call that performs bonded-set selection and equal split. - function stake() external nonReentrant returns (uint256 delegatedAmount) { + /// @dev Callable by owner or automation caller; uses one precompile call for bonded-set selection and equal split. + function stake() external nonReentrant onlyAutomationOrOwner returns (uint256 delegatedAmount) { uint256 liquidBefore = stakeablePrincipalLedger; if (liquidBefore < minStakeAmount) { return 0; @@ -370,8 +391,8 @@ contract CommunityPool { } /// @notice Claims staking rewards to this contract's liquid balance. - /// @dev Does not modify `totalStaked` because rewards are liquid yield, not principal. - function harvest() external nonReentrant returns (uint256 harvestedAmount) { + /// @dev Callable by owner or automation caller; does not modify `totalStaked` because rewards are liquid yield, not principal. + function harvest() external nonReentrant onlyAutomationOrOwner returns (uint256 harvestedAmount) { uint256 liquidBefore = liquidBalance(); bool success = distribution.DISTRIBUTION_CONTRACT.claimRewards( address(this), diff --git a/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md b/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md index 91ae0a70..427ccc58 100644 --- a/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md +++ b/tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md @@ -24,7 +24,7 @@ This document captures assumptions that the `communitypool` integration suite de - Deposit/withdraw accounting uses floor rounding and must never over-mint shares. - Dust deposits that mint zero units must revert and preserve unit state. - Owner-gated methods (`setConfig`, `syncTotalStaked`, `transferOwnership`) enforce access control. -- `stake()` and `harvest()` are callable in the current implementation and are tested as operational actions, not owner-only actions. +- `stake()` and `harvest()` are restricted to `owner` or configured `automationCaller`. - `stake()` delegates through `staking.delegateToBondedValidators(address(this), liquid, maxValidators)`. - The staking precompile path is atomic at transaction scope: if any internal per-validator delegate fails, no partial delegation state persists. - Validator selection policy for `stake()` is the first `maxValidators` bonded validators in staking precompile/keeper order. @@ -35,4 +35,4 @@ This document captures assumptions that the `communitypool` integration suite de - If staking precompile validator ordering or bonded-set query semantics change, staking-path tests may fail and need expectation updates. - If default gas behavior changes in factory or precompiles, tx helper gas defaults may need adjustment. -- If ownership/permissions policy changes (for example, restricting `stake`/`harvest`), tests must be updated to reflect the new access model. +- If ownership/permissions policy changes, tests must be updated to reflect the new access model. diff --git a/tests/integration/precompiles/communitypool/test_integration.go b/tests/integration/precompiles/communitypool/test_integration.go index 8f5c3861..c0106453 100644 --- a/tests/integration/precompiles/communitypool/test_integration.go +++ b/tests/integration/precompiles/communitypool/test_integration.go @@ -132,6 +132,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("creates async withdraw request and updates accounting", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) @@ -147,7 +148,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp // Withdraw path is strict unbonding-based, so ensure principal is staked first. s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -183,6 +184,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("increments nextWithdrawRequestId across multiple requests", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) @@ -197,7 +199,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -305,6 +307,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("enforces maturity and ownership in claimWithdraw", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) other := s.keyring.GetKey(2) @@ -320,7 +323,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -352,6 +355,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("claims matured withdraw and prevents double claim", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) @@ -366,7 +370,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -413,6 +417,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("emits withdraw lifecycle events with expected request id", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) withdrawUnits := big.NewInt(400) @@ -426,7 +431,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -476,6 +481,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("claims multiple matured requests out of order", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) @@ -490,7 +496,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -618,6 +624,14 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) Expect(s.network.NextBlock()).To(BeNil()) + s.execTxExpectCustomError( + nonOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setAutomationCaller", nonOwner.Addr), + "Unauthorized()", + ) + Expect(s.network.NextBlock()).To(BeNil()) + // Owner can still execute privileged actions. s.execTxExpectSuccess( owner.Priv, @@ -626,6 +640,51 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) }) + It("restricts stake and harvest to owner or automation caller", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + nonOwner := s.keyring.GetKey(1) + automation := s.keyring.GetKey(2) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + nonOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectCustomError( + nonOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + "Unauthorized()", + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setAutomationCaller", automation.Addr), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + automation.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "stake"), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectCustomError( + nonOwner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "harvest"), + "Unauthorized()", + ) + }) + It("reverts dust deposit that would mint zero units", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) owner := s.keyring.GetKey(0) @@ -711,6 +770,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("allows owner to call all privileged methods", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) owner := s.keyring.GetKey(0) + automation := s.keyring.GetKey(1) s.execTxExpectSuccess( owner.Priv, @@ -726,10 +786,19 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) Expect(s.network.NextBlock()).To(BeNil()) + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setAutomationCaller", automation.Addr), + ) + Expect(s.network.NextBlock()).To(BeNil()) + maxValidators := s.queryPoolUint(0, poolAddr, "maxValidators") totalStaked := s.queryPoolUint(0, poolAddr, "totalStaked") + automationCaller := s.queryPoolAddress(poolAddr, "automationCaller") Expect(maxValidators.String()).To(Equal("6")) Expect(totalStaked.String()).To(Equal("321")) + Expect(automationCaller.Hex()).To(Equal(automation.Addr.Hex())) }) It("reverts setConfig when maxValidators is zero", func() { @@ -797,7 +866,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -814,7 +883,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -893,6 +962,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("stake is a no-op when liquid is below minStakeAmount", func() { // minStakeAmount is intentionally set above deposit. poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(2000)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) @@ -905,7 +975,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -917,6 +987,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("stake delegates liquid and updates totalStaked accounting", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) @@ -929,7 +1000,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -941,6 +1012,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("stake creates on-chain delegation for pool contract delegator", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) firstVal := s.network.GetValidators()[0].OperatorAddress @@ -954,7 +1026,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -970,6 +1042,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("harvest executes successfully after staking", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) @@ -982,14 +1055,14 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "harvest"), ) @@ -998,6 +1071,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("harvest does not modify totalStaked accounting", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) @@ -1010,7 +1084,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -1020,7 +1094,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp beforeLiquid := s.queryPoolUint(1, poolAddr, "liquidBalance") s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "harvest"), ) @@ -1073,6 +1147,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp It("claimRewards is idempotent for a given reward index", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) user := s.keyring.GetKey(1) depositAmount := big.NewInt(1000) @@ -1085,7 +1160,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(s.network.NextBlock()).To(BeNil()) s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "stake"), ) @@ -1093,7 +1168,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp // Harvest updates reward index and reserve (or leaves unchanged in zero-reward conditions). s.execTxExpectSuccess( - user.Priv, + owner.Priv, buildTxArgs(poolAddr), buildCallArgs(s.communityPoolContract, "harvest"), ) diff --git a/tests/integration/precompiles/communitypool/test_utils.go b/tests/integration/precompiles/communitypool/test_utils.go index cc3cd50a..6d873183 100644 --- a/tests/integration/precompiles/communitypool/test_utils.go +++ b/tests/integration/precompiles/communitypool/test_utils.go @@ -118,6 +118,26 @@ func (s *IntegrationTestSuite) queryPoolUint( } } +func (s *IntegrationTestSuite) queryPoolAddress( + contractAddr common.Address, + method string, + args ...interface{}, +) common.Address { + txArgs := buildTxArgs(contractAddr) + callArgs := buildCallArgs(s.communityPoolContract, method, args...) + + ethRes, err := s.factory.QueryContract(txArgs, callArgs, 0) + Expect(err).To(BeNil(), "query call failed") + + out, err := s.communityPoolContract.ABI.Unpack(method, ethRes.Ret) + Expect(err).To(BeNil(), "failed to unpack query output") + Expect(out).To(HaveLen(1), "unexpected query output length") + + addr, ok := out[0].(common.Address) + Expect(ok).To(BeTrue(), "unexpected query output type") + return addr +} + func (s *IntegrationTestSuite) execTxExpectSuccess( priv cryptotypes.PrivKey, txArgs evmtypes.EvmTxArgs, From f055639cfadcc543ade4dc093508ad480bcc81db Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Tue, 31 Mar 2026 23:08:37 +0530 Subject: [PATCH 26/31] docs(communitypool): add pool contract architecture and lifecycle guide --- contracts/solidity/pool/README.md | 139 ++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 contracts/solidity/pool/README.md diff --git a/contracts/solidity/pool/README.md b/contracts/solidity/pool/README.md new file mode 100644 index 00000000..4c4a1163 --- /dev/null +++ b/contracts/solidity/pool/README.md @@ -0,0 +1,139 @@ +# CommunityPool Contract + +The `CommunityPool` contract is a pooled staking vault for a single bond token. +Users deposit tokens and receive internal ownership units, while the contract +stakes principal through staking precompiles and handles rewards/withdrawals. + +## Goals + +- Keep pool ownership simple (`unitsOf[user] / totalUnits`). +- Separate principal accounting from reward accounting. +- Support async withdrawals for staked principal (request now, claim at maturity). +- Keep heavy validator selection logic in precompiles. + +## Main Components + +- **Bond token**: `bondToken` (ERC20 representation of chain bond denom). +- **Ownership units**: `unitsOf`, `totalUnits`. +- **Principal accounting**: + - `stakeablePrincipalLedger`: liquid principal available for `stake`. + - `totalStaked`: accounting view of delegated principal. + - `pendingWithdrawReserve`: requested principal waiting for maturity. + - `maturedWithdrawReserve`: matured principal reserved for claims. +- **Rewards accounting**: + - `rewardReserve`: liquid rewards reserved for users. + - `accRewardPerUnit` + `rewardDebt[user]`: index-based reward accrual. + +## Lifecycle + +### 1) Deposit + +`deposit(amount)`: + +- Reverts on `amount == 0`. +- Claims caller pending rewards first (to keep reward index accounting fair). +- Mints units: + - first deposit: `mintedUnits = amount` + - otherwise: `mintedUnits = floor(amount * totalUnits / principalAssets())` +- Reverts with `ZeroMintedUnits()` if floor rounding gives `0`. +- Transfers tokens in and increases `stakeablePrincipalLedger`. + +### 2) Stake + +`stake()`: + +- Callable only by `owner` or `automationCaller`. +- No-op when `stakeablePrincipalLedger < minStakeAmount`. +- Calls staking precompile `delegateToBondedValidators(address(this), liquid, maxValidators)`. +- Moves delegated amount from liquid principal ledger to `totalStaked`. + +### 3) Harvest and claim rewards + +`harvest()`: + +- Callable only by `owner` or `automationCaller`. +- Calls distribution precompile to claim validator rewards to contract balance. +- Computes `harvestedAmount = liquidAfter - liquidBefore`. +- Adds harvested rewards to `rewardReserve`. +- Updates `accRewardPerUnit` if `totalUnits > 0`. + +`claimRewards()`: + +- Uses reward index delta per user: + `pending = unitsOf[user] * accRewardPerUnit / PRECISION - rewardDebt[user]`. +- Transfers pending rewards from `rewardReserve`. +- Updates `rewardDebt[user]`. + +### 4) Async withdraw + +`withdraw(userUnits)`: + +- Reverts on invalid unit input/balance. +- Claims caller pending rewards first. +- Computes principal out using staked-only model: + `amountOut = userUnits * totalStaked / totalUnits`. +- Calls staking precompile: + `undelegateFromBondedValidators(address(this), amountOut, maxValidators)`. +- Requires exact undelegation amount and valid future completion time. +- Burns units immediately. +- Decreases `totalStaked`, increases `pendingWithdrawReserve`. +- Stores a `WithdrawRequest` with maturity. + +`claimWithdraw(requestId)`: + +- Checks ownership, maturity, and not already claimed. +- Moves reserve once from `pendingWithdrawReserve` to `maturedWithdrawReserve`. +- Pays out from matured reserve and marks request claimed. + +## Key View Methods + +- `liquidBalance()`: current token balance held by contract. +- `principalLiquid()`: currently stakeable liquid principal. +- `principalAssets()`: `principalLiquid + totalStaked`. +- `pricePerUnit()`: `principalAssets * 1e18 / totalUnits` (or `1e18` if empty). +- `totalWithdrawCommitments()`: pending + matured principal commitments. + +## Invariants Enforced On State Changes + +Internal `_assertReserveInvariant()` ensures: + +- `rewardReserve <= liquidBalance` +- `rewardReserve + maturedWithdrawReserve <= liquidBalance` +- `stakeablePrincipalLedger + rewardReserve + maturedWithdrawReserve <= liquidBalance` + +Note: `pendingWithdrawReserve` is excluded from liquid-reserve checks because it +represents principal already requested for unbonding, not immediately liquid. + +## Admin Operations + +- `setConfig(maxRetrieve, maxValidators, minStakeAmount)` (`maxValidators > 0`). +- `setAutomationCaller(newAutomationCaller)` to configure scheduler/module caller. +- `syncTotalStaked(newTotalStaked)` to reconcile accounting drift (e.g. slashing). +- `transferOwnership(newOwner)`. + +All admin methods are `onlyOwner`. + +## Error Model (selected) + +- Input/permission: `InvalidAmount`, `InvalidUnits`, `InvalidConfig`, `Unauthorized`. +- External trust boundaries: + - `UnexpectedUndelegatedAmount` + - `InvalidCompletionTime` + - `HarvestFailed` +- Reserve/invariant failures: + - `InsufficientLiquid` + - `RewardReserveInvariantViolation` + - `LiquidReserveInvariantViolation` + - `StakeablePrincipalInvariantViolation` + +## Test Coverage + +Integration tests for this contract are under: + +- `tests/integration/precompiles/communitypool/test_integration.go` +- `tests/integration/precompiles/communitypool/test_utils.go` +- `tests/integration/precompiles/communitypool/TEST_ASSUMPTIONS.md` + +They cover core lifecycle flow, custom-error paths, ownership/config transitions, +accounting invariants, and event assertions for critical operations. + From 6a7df573109b1d98dcf06ed1ff3599901530ddc2 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Wed, 1 Apr 2026 12:58:30 +0530 Subject: [PATCH 27/31] feat(poolrebalancer): automate CommunityPool harvest/stake in EndBlock via EVM Signed-off-by: Nikhil Sharma --- contracts/solidity/pool/README.md | 46 ++++++++ evmd/app.go | 15 +-- evmd/config/permissions.go | 2 + .../communitypool/test_integration.go | 59 ++++++++++ .../x/poolrebalancer/test_suite.go | 1 + x/poolrebalancer/abci.go | 9 +- x/poolrebalancer/abci_test.go | 11 +- x/poolrebalancer/genesis_test.go | 4 +- x/poolrebalancer/keeper/community_pool.go | 40 +++++++ .../keeper/community_pool_test.go | 104 ++++++++++++++++++ x/poolrebalancer/keeper/evm_interface_test.go | 9 ++ x/poolrebalancer/keeper/keeper.go | 3 + .../keeper/rebalance_process_test.go | 2 +- x/poolrebalancer/keeper/rebalance_test.go | 2 +- x/poolrebalancer/keeper/test_helpers_test.go | 2 +- x/poolrebalancer/types/communitypool_abi.go | 25 +++++ x/poolrebalancer/types/communitypool_abi.json | 28 +++++ .../types/communitypool_abi_test.go | 18 +++ x/poolrebalancer/types/interfaces.go | 19 ++++ x/poolrebalancer/types/keys.go | 12 ++ x/poolrebalancer/types/keys_test.go | 15 +++ 21 files changed, 408 insertions(+), 18 deletions(-) create mode 100644 x/poolrebalancer/keeper/community_pool.go create mode 100644 x/poolrebalancer/keeper/community_pool_test.go create mode 100644 x/poolrebalancer/keeper/evm_interface_test.go create mode 100644 x/poolrebalancer/types/communitypool_abi.go create mode 100644 x/poolrebalancer/types/communitypool_abi.json create mode 100644 x/poolrebalancer/types/communitypool_abi_test.go create mode 100644 x/poolrebalancer/types/keys_test.go diff --git a/contracts/solidity/pool/README.md b/contracts/solidity/pool/README.md index 4c4a1163..84a0cee1 100644 --- a/contracts/solidity/pool/README.md +++ b/contracts/solidity/pool/README.md @@ -113,6 +113,52 @@ represents principal already requested for unbonding, not immediately liquid. All admin methods are `onlyOwner`. +## PoolRebalancer EndBlock Automation + +`CommunityPool.stake()` and `CommunityPool.harvest()` can be called by the +`poolrebalancer` module during `EndBlock`. + +### Required Configuration + +1. Set CommunityPool automation caller to the poolrebalancer module EVM address: + +- `setAutomationCaller()` + +2. Set poolrebalancer params so the pool delegator is the CommunityPool contract: + +- `pool_delegator_address = ` + +Both are required. If either is wrong, EndBlock automation will not execute +successfully. + +### Why This Is Required + +- `stake()` and `harvest()` are protected by `onlyAutomationOrOwner`. +- EndBlock calls run with `msg.sender = poolrebalancer ModuleEVMAddress`. +- The module targets the contract at `pool_delegator_address` (address bytes + mapped to EVM address). + +### Operational Checks + +Before enabling automation: + +- `automationCaller` on the contract equals poolrebalancer module EVM address. +- `poolrebalancer.params.pool_delegator_address` equals the CommunityPool + contract address (bech32 account form). + +### Failure Symptoms + +- `Unauthorized()` revert from `stake()` or `harvest()`: + - `automationCaller` does not match module EVM address. +- Automation logs failures and state does not move: + - `pool_delegator_address` is wrong or not the pool contract. + +### Notes + +- EndBlock automation is best-effort; errors are logged and retried in later + blocks. +- Automation and rebalance are independent best-effort steps in EndBlock. + ## Error Model (selected) - Input/permission: `InvalidAmount`, `InvalidUnits`, `InvalidConfig`, `Unauthorized`. diff --git a/evmd/app.go b/evmd/app.go index fb27269c..3a0e63c1 100644 --- a/evmd/app.go +++ b/evmd/app.go @@ -369,13 +369,6 @@ func NewExampleApp( stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()), ) - app.PoolRebalancerKeeper = poolrebalancerkeeper.NewKeeper( - appCodec, - runtime.NewKVStoreService(keys[poolrebalancertypes.StoreKey]), - app.StakingKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName), - ) - app.AuthzKeeper = authzkeeper.NewKeeper( runtime.NewKVStoreService(keys[authzkeeper.StoreKey]), appCodec, @@ -489,6 +482,14 @@ func NewExampleApp( ), ) + app.PoolRebalancerKeeper = poolrebalancerkeeper.NewKeeper( + appCodec, + runtime.NewKVStoreService(keys[poolrebalancertypes.StoreKey]), + app.StakingKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName), + app.EVMKeeper, + ) + app.Erc20Keeper = erc20keeper.NewKeeper( keys[erc20types.StoreKey], appCodec, diff --git a/evmd/config/permissions.go b/evmd/config/permissions.go index 2aa0d5fa..6daa57e1 100644 --- a/evmd/config/permissions.go +++ b/evmd/config/permissions.go @@ -12,6 +12,7 @@ import ( cosmosevmutils "github.com/cosmos/evm/utils" erc20types "github.com/cosmos/evm/x/erc20/types" feemarkettypes "github.com/cosmos/evm/x/feemarket/types" + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" precisebanktypes "github.com/cosmos/evm/x/precisebank/types" vmtypes "github.com/cosmos/evm/x/vm/types" transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types" @@ -64,6 +65,7 @@ var maccPerms = map[string][]string{ vmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, feemarkettypes.ModuleName: nil, erc20types.ModuleName: {authtypes.Minter, authtypes.Burner}, + poolrebalancertypes.ModuleName: nil, precisebanktypes.ModuleName: {authtypes.Minter, authtypes.Burner}, } diff --git a/tests/integration/precompiles/communitypool/test_integration.go b/tests/integration/precompiles/communitypool/test_integration.go index c0106453..f2c93f81 100644 --- a/tests/integration/precompiles/communitypool/test_integration.go +++ b/tests/integration/precompiles/communitypool/test_integration.go @@ -15,9 +15,15 @@ import ( "github.com/cosmos/evm/precompiles/testutil" "github.com/cosmos/evm/testutil/integration/evm/network" testutiltypes "github.com/cosmos/evm/testutil/types" + poolrebalancer "github.com/cosmos/evm/x/poolrebalancer" + poolrebalancerkeeper "github.com/cosmos/evm/x/poolrebalancer/keeper" + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" evmtypes "github.com/cosmos/evm/x/vm/types" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" ) // TestCommunityPoolIntegrationSuite scaffolds the CommunityPool integration suite. @@ -685,6 +691,59 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp ) }) + It("runs stake automation from poolrebalancer EndBlock", func() { + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + depositor := s.keyring.GetKey(1) + depositAmount := big.NewInt(1000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + depositor.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + // Authorize the module EVM address so EndBlock can call stake/harvest. + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setAutomationCaller", poolrebalancertypes.ModuleEVMAddress), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + ctx := s.network.GetContext() + moduleAcc := sdk.AccAddress(poolrebalancertypes.ModuleEVMAddress.Bytes()) + accountKeeper := s.network.App.GetAccountKeeper() + if accountKeeper.GetAccount(ctx, moduleAcc) == nil { + // This integration harness uses a custom genesis setup that may omit + // the module account, so seed it explicitly for deterministic E2E coverage. + accountKeeper.SetAccount(ctx, accountKeeper.NewAccountWithAddress(ctx, moduleAcc)) + } + + beforeStaked := s.queryPoolUint(0, poolAddr, "totalStaked") + Expect(beforeStaked.Sign()).To(Equal(0)) + + storeService := runtime.NewKVStoreService(s.network.App.GetKey(poolrebalancertypes.StoreKey)) + rebalancerKeeper := poolrebalancerkeeper.NewKeeper( + s.network.App.AppCodec(), + storeService, + s.network.App.GetStakingKeeper(), + authtypes.NewModuleAddress(govtypes.ModuleName), + s.network.App.GetEVMKeeper(), + ) + + params := poolrebalancertypes.DefaultParams() + params.PoolDelegatorAddress = sdk.AccAddress(poolAddr.Bytes()).String() + Expect(rebalancerKeeper.SetParams(ctx, params)).To(BeNil()) + + Expect(poolrebalancer.EndBlocker(ctx, rebalancerKeeper)).To(BeNil()) + + afterStaked := s.queryPoolUint(0, poolAddr, "totalStaked") + Expect(afterStaked.Cmp(beforeStaked)).To(BeNumerically(">", 0)) + }) + It("reverts dust deposit that would mint zero units", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) owner := s.keyring.GetKey(0) diff --git a/tests/integration/x/poolrebalancer/test_suite.go b/tests/integration/x/poolrebalancer/test_suite.go index a8e9bd33..81c81d2c 100644 --- a/tests/integration/x/poolrebalancer/test_suite.go +++ b/tests/integration/x/poolrebalancer/test_suite.go @@ -90,6 +90,7 @@ func (s *KeeperIntegrationTestSuite) configurePoolKeeper() { storeService, s.network.App.GetStakingKeeper(), authority, + nil, ) } diff --git a/x/poolrebalancer/abci.go b/x/poolrebalancer/abci.go index a0034a0a..c90d3f01 100644 --- a/x/poolrebalancer/abci.go +++ b/x/poolrebalancer/abci.go @@ -6,7 +6,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// EndBlocker runs at end of block: complete matured redelegations/undelegations, then process rebalance. +// EndBlocker runs at end of block: +// 1) strict cleanup of matured pending entries, +// 2) best-effort CommunityPool automation (harvest/stake), +// 3) best-effort staking rebalance. func EndBlocker(ctx sdk.Context, k keeper.Keeper) error { // Keep cleanup strict to avoid queue/index drift from staking state. if err := k.CompletePendingRedelegations(ctx); err != nil { @@ -17,6 +20,10 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) error { ctx.Logger().Error("poolrebalancer: complete pending undelegations failed", "err", err) return err } + // Community pool automation is best-effort; operational failures are retried next block. + if err := k.MaybeRunCommunityPoolAutomation(ctx); err != nil { + ctx.Logger().Error("poolrebalancer: community pool automation failed", "err", err) + } // Rebalance is best-effort; operational failures are retried next block. if err := k.ProcessRebalance(ctx); err != nil { ctx.Logger().Error("poolrebalancer: process rebalance failed", "err", err) diff --git a/x/poolrebalancer/abci_test.go b/x/poolrebalancer/abci_test.go index 0cd455fd..5e00d837 100644 --- a/x/poolrebalancer/abci_test.go +++ b/x/poolrebalancer/abci_test.go @@ -30,19 +30,20 @@ func newEndBlockerTestKeeper(t *testing.T) (sdk.Context, keeper.Keeper, *storety stakingKeeper := &stakingkeeper.Keeper{} // zero value; tests avoid staking calls authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := keeper.NewKeeper(cdc, storeService, stakingKeeper, authority) + k := keeper.NewKeeper(cdc, storeService, stakingKeeper, authority, nil) return ctx, k, storeKey } -func TestEndBlocker_ProcessRebalanceErrorIsNonHalting(t *testing.T) { +func TestEndBlocker_OperationalErrorIsNonHalting(t *testing.T) { ctx, k, storeKey := newEndBlockerTestKeeper(t) - // Inject malformed params directly to force an operational ProcessRebalance error - // (GetParams unmarshal failure), while keeping cleanup paths healthy. + // Inject malformed params directly to force an operational module error + // (GetParams unmarshal failure) while keeping cleanup paths healthy. + // This now first impacts community pool automation lookup in EndBlock. ctx.KVStore(storeKey).Set(types.ParamsKey, []byte("not-a-valid-proto")) err := EndBlocker(ctx, k) - require.NoError(t, err, "ProcessRebalance errors should not halt EndBlocker") + require.NoError(t, err, "operational errors should not halt EndBlocker") } func TestEndBlocker_CleanupErrorRemainsHalting(t *testing.T) { diff --git a/x/poolrebalancer/genesis_test.go b/x/poolrebalancer/genesis_test.go index ff38c8eb..51bcdaf5 100644 --- a/x/poolrebalancer/genesis_test.go +++ b/x/poolrebalancer/genesis_test.go @@ -28,7 +28,7 @@ func TestGenesis_ExportsAndRestoresPendingState(t *testing.T) { cdc := moduletestutil.MakeTestEncodingConfig().Codec stakingK := &stakingkeeper.Keeper{} authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := keeper.NewKeeper(cdc, storeService, stakingK, authority) + k := keeper.NewKeeper(cdc, storeService, stakingK, authority, nil) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) srcVal := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) @@ -60,7 +60,7 @@ func TestGenesis_ExportsAndRestoresPendingState(t *testing.T) { ctx2 := testutil.DefaultContext(storeKey2, tKey2).WithBlockTime(time.Unix(2_000, 0)) storeService2 := runtime.NewKVStoreService(storeKey2) - k2 := keeper.NewKeeper(cdc, storeService2, stakingK, authority) + k2 := keeper.NewKeeper(cdc, storeService2, stakingK, authority, nil) InitGenesis(ctx2, k2, exported) diff --git a/x/poolrebalancer/keeper/community_pool.go b/x/poolrebalancer/keeper/community_pool.go new file mode 100644 index 00000000..1b623ae6 --- /dev/null +++ b/x/poolrebalancer/keeper/community_pool.go @@ -0,0 +1,40 @@ +package keeper + +import ( + "github.com/ethereum/go-ethereum/common" + + "github.com/cosmos/evm/x/poolrebalancer/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// MaybeRunCommunityPoolAutomation best-effort executes CommunityPool harvest/stake. +// Assumptions: +// - pool params PoolDelegatorAddress points to the CommunityPool contract account, +// - CommunityPool automationCaller is set to types.ModuleEVMAddress. +// It never returns operational call failures; those are logged and retried next block. +func (k Keeper) MaybeRunCommunityPoolAutomation(ctx sdk.Context) error { + del, err := k.GetPoolDelegatorAddress(ctx) + if err != nil { + return err + } + if del.Empty() || k.evmKeeper == nil { + return nil + } + + poolContract := common.BytesToAddress(del.Bytes()) + from := types.ModuleEVMAddress + + for _, method := range []string{"harvest", "stake"} { + res, callErr := k.evmKeeper.CallEVM(ctx, types.CommunityPoolABI, from, poolContract, true, nil, method) + if callErr != nil { + ctx.Logger().Error("poolrebalancer: community pool automation call failed", "method", method, "contract", poolContract.Hex(), "err", callErr) + continue + } + if res != nil && res.Failed() { + ctx.Logger().Error("poolrebalancer: community pool automation vm failed", "method", method, "contract", poolContract.Hex(), "vm_error", res.VmError) + } + } + + return nil +} diff --git a/x/poolrebalancer/keeper/community_pool_test.go b/x/poolrebalancer/keeper/community_pool_test.go new file mode 100644 index 00000000..d5fe228a --- /dev/null +++ b/x/poolrebalancer/keeper/community_pool_test.go @@ -0,0 +1,104 @@ +package keeper + +import ( + "bytes" + "errors" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + pooltypes "github.com/cosmos/evm/x/poolrebalancer/types" + evmtypes "github.com/cosmos/evm/x/vm/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type mockEVMKeeper struct { + methods []string + froms []common.Address + contracts []common.Address + + errByMethod map[string]error +} + +func (m *mockEVMKeeper) CallEVM( + ctx sdk.Context, + abi abi.ABI, + from, contract common.Address, + commit bool, + gasCap *big.Int, + method string, + args ...any, +) (*evmtypes.MsgEthereumTxResponse, error) { + m.methods = append(m.methods, method) + m.froms = append(m.froms, from) + m.contracts = append(m.contracts, contract) + if err, ok := m.errByMethod[method]; ok { + return nil, err + } + return &evmtypes.MsgEthereumTxResponse{}, nil +} + +func TestMaybeRunCommunityPoolAutomation_SkipsWhenPoolDelegatorUnset(t *testing.T) { + ctx, k := newTestKeeper(t) + mockEVM := &mockEVMKeeper{} + k.evmKeeper = mockEVM + + require.NoError(t, k.MaybeRunCommunityPoolAutomation(ctx)) + require.Empty(t, mockEVM.methods) +} + +func TestMaybeRunCommunityPoolAutomation_SkipsWhenEVMKeeperUnset(t *testing.T) { + ctx, k := newTestKeeper(t) + + del := sdk.AccAddress(bytes.Repeat([]byte{7}, 20)) + params := pooltypes.DefaultParams() + params.PoolDelegatorAddress = del.String() + require.NoError(t, k.SetParams(ctx, params)) + + require.NoError(t, k.MaybeRunCommunityPoolAutomation(ctx)) +} + +func TestMaybeRunCommunityPoolAutomation_CallsHarvestThenStake(t *testing.T) { + ctx, k := newTestKeeper(t) + mockEVM := &mockEVMKeeper{} + k.evmKeeper = mockEVM + + del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + params := pooltypes.DefaultParams() + params.PoolDelegatorAddress = del.String() + require.NoError(t, k.SetParams(ctx, params)) + + require.NoError(t, k.MaybeRunCommunityPoolAutomation(ctx)) + require.Equal(t, []string{"harvest", "stake"}, mockEVM.methods) + + expectedContract := common.BytesToAddress(del.Bytes()) + require.Len(t, mockEVM.froms, 2) + require.Len(t, mockEVM.contracts, 2) + require.Equal(t, pooltypes.ModuleEVMAddress, mockEVM.froms[0]) + require.Equal(t, pooltypes.ModuleEVMAddress, mockEVM.froms[1]) + require.Equal(t, expectedContract, mockEVM.contracts[0]) + require.Equal(t, expectedContract, mockEVM.contracts[1]) +} + +func TestMaybeRunCommunityPoolAutomation_HarvestFailureDoesNotBlockStake(t *testing.T) { + ctx, k := newTestKeeper(t) + mockEVM := &mockEVMKeeper{ + errByMethod: map[string]error{ + "harvest": errors.New("mock harvest failure"), + }, + } + k.evmKeeper = mockEVM + + del := sdk.AccAddress(bytes.Repeat([]byte{2}, 20)) + params := pooltypes.DefaultParams() + params.PoolDelegatorAddress = del.String() + require.NoError(t, k.SetParams(ctx, params)) + + require.NoError(t, k.MaybeRunCommunityPoolAutomation(ctx)) + require.Equal(t, []string{"harvest", "stake"}, mockEVM.methods) +} + diff --git a/x/poolrebalancer/keeper/evm_interface_test.go b/x/poolrebalancer/keeper/evm_interface_test.go new file mode 100644 index 00000000..a9becd1d --- /dev/null +++ b/x/poolrebalancer/keeper/evm_interface_test.go @@ -0,0 +1,9 @@ +package keeper + +import ( + evmkeeper "github.com/cosmos/evm/x/vm/keeper" + pooltypes "github.com/cosmos/evm/x/poolrebalancer/types" +) + +// Compile-time contract: vm keeper must satisfy poolrebalancer's minimal EVM interface. +var _ pooltypes.EVMKeeper = (*evmkeeper.Keeper)(nil) diff --git a/x/poolrebalancer/keeper/keeper.go b/x/poolrebalancer/keeper/keeper.go index 4102ddcb..ba13fc5d 100644 --- a/x/poolrebalancer/keeper/keeper.go +++ b/x/poolrebalancer/keeper/keeper.go @@ -13,6 +13,7 @@ type Keeper struct { storeService store.KVStoreService cdc codec.BinaryCodec stakingKeeper types.StakingKeeper + evmKeeper types.EVMKeeper authority sdk.AccAddress } @@ -22,6 +23,7 @@ func NewKeeper( storeService store.KVStoreService, stakingKeeper types.StakingKeeper, authority sdk.AccAddress, + evmKeeper types.EVMKeeper, ) Keeper { if err := sdk.VerifyAddressFormat(authority); err != nil { panic(err) @@ -30,6 +32,7 @@ func NewKeeper( storeService: storeService, cdc: cdc, stakingKeeper: stakingKeeper, + evmKeeper: evmKeeper, authority: authority, } } diff --git a/x/poolrebalancer/keeper/rebalance_process_test.go b/x/poolrebalancer/keeper/rebalance_process_test.go index 915142eb..e97df2f3 100644 --- a/x/poolrebalancer/keeper/rebalance_process_test.go +++ b/x/poolrebalancer/keeper/rebalance_process_test.go @@ -87,7 +87,7 @@ func newProcessRebalanceKeeper(t *testing.T, sk types.StakingKeeper) (sdk.Contex storeService := runtime.NewKVStoreService(storeKey) cdc := moduletestutil.MakeTestEncodingConfig().Codec authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := NewKeeper(cdc, storeService, sk, authority) + k := NewKeeper(cdc, storeService, sk, authority, nil) return ctx, k } diff --git a/x/poolrebalancer/keeper/rebalance_test.go b/x/poolrebalancer/keeper/rebalance_test.go index dad3bae0..32b2e497 100644 --- a/x/poolrebalancer/keeper/rebalance_test.go +++ b/x/poolrebalancer/keeper/rebalance_test.go @@ -33,7 +33,7 @@ func testKeeperWithParams(t *testing.T, rebalanceThresholdBP, maxMovePerOp strin storeService := runtime.NewKVStoreService(storeKey) cdc := moduletestutil.MakeTestEncodingConfig().Codec stakingKeeper := &stakingkeeper.Keeper{} // zero value; do not call staking methods - k := keeper.NewKeeper(cdc, storeService, stakingKeeper, sdk.AccAddress(bytes.Repeat([]byte{9}, 20))) + k := keeper.NewKeeper(cdc, storeService, stakingKeeper, sdk.AccAddress(bytes.Repeat([]byte{9}, 20)), nil) bp, err := strconv.ParseUint(rebalanceThresholdBP, 10, 32) require.NoError(t, err) diff --git a/x/poolrebalancer/keeper/test_helpers_test.go b/x/poolrebalancer/keeper/test_helpers_test.go index ffe89d1f..d74321f8 100644 --- a/x/poolrebalancer/keeper/test_helpers_test.go +++ b/x/poolrebalancer/keeper/test_helpers_test.go @@ -27,6 +27,6 @@ func newTestKeeper(t *testing.T) (sdk.Context, Keeper) { stakingKeeper := &stakingkeeper.Keeper{} // zero value; do not call staking methods in unit tests authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := NewKeeper(cdc, storeService, stakingKeeper, authority) + k := NewKeeper(cdc, storeService, stakingKeeper, authority, nil) return ctx, k } diff --git a/x/poolrebalancer/types/communitypool_abi.go b/x/poolrebalancer/types/communitypool_abi.go new file mode 100644 index 00000000..dddb0a77 --- /dev/null +++ b/x/poolrebalancer/types/communitypool_abi.go @@ -0,0 +1,25 @@ +package types + +import ( + "bytes" + + "github.com/ethereum/go-ethereum/accounts/abi" + + _ "embed" +) + +var ( + //go:embed communitypool_abi.json + communityPoolABIBz []byte + + // CommunityPoolABI contains the minimal ABI required by EndBlock automation. + CommunityPoolABI abi.ABI +) + +func init() { + var err error + CommunityPoolABI, err = abi.JSON(bytes.NewReader(communityPoolABIBz)) + if err != nil { + panic(err) + } +} diff --git a/x/poolrebalancer/types/communitypool_abi.json b/x/poolrebalancer/types/communitypool_abi.json new file mode 100644 index 00000000..f57dfd14 --- /dev/null +++ b/x/poolrebalancer/types/communitypool_abi.json @@ -0,0 +1,28 @@ +[ + { + "inputs": [], + "name": "stake", + "outputs": [ + { + "internalType": "uint256", + "name": "delegatedAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "harvest", + "outputs": [ + { + "internalType": "uint256", + "name": "harvestedAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/x/poolrebalancer/types/communitypool_abi_test.go b/x/poolrebalancer/types/communitypool_abi_test.go new file mode 100644 index 00000000..dd924a9a --- /dev/null +++ b/x/poolrebalancer/types/communitypool_abi_test.go @@ -0,0 +1,18 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestCommunityPoolABI_MethodsPresent(t *testing.T) { + stakeMethod, ok := CommunityPoolABI.Methods["stake"] + require.True(t, ok) + require.Empty(t, stakeMethod.Inputs) + + harvestMethod, ok := CommunityPoolABI.Methods["harvest"] + require.True(t, ok) + require.Empty(t, harvestMethod.Inputs) +} + diff --git a/x/poolrebalancer/types/interfaces.go b/x/poolrebalancer/types/interfaces.go index 0a06f008..53ad846c 100644 --- a/x/poolrebalancer/types/interfaces.go +++ b/x/poolrebalancer/types/interfaces.go @@ -2,8 +2,14 @@ package types import ( "context" + "math/big" "time" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + evmtypes "github.com/cosmos/evm/x/vm/types" + sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -20,3 +26,16 @@ type StakingKeeper interface { UnbondingTime(ctx context.Context) (time.Duration, error) BondDenom(ctx context.Context) (string, error) } + +// EVMKeeper defines the subset of vm keeper methods used by poolrebalancer. +type EVMKeeper interface { + CallEVM( + ctx sdk.Context, + abi abi.ABI, + from, contract common.Address, + commit bool, + gasCap *big.Int, + method string, + args ...any, + ) (*evmtypes.MsgEthereumTxResponse, error) +} diff --git a/x/poolrebalancer/types/keys.go b/x/poolrebalancer/types/keys.go index 50b504a9..8d1137b3 100644 --- a/x/poolrebalancer/types/keys.go +++ b/x/poolrebalancer/types/keys.go @@ -4,8 +4,11 @@ import ( "fmt" "time" + "github.com/ethereum/go-ethereum/common" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/address" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) const ( @@ -21,6 +24,10 @@ const ( // Store key prefixes (single-byte prefixes). var ( + // ModuleEVMAddress is the EVM address of the poolrebalancer module account. + // Operators should set this as CommunityPool automationCaller for EndBlock automation. + ModuleEVMAddress common.Address + ParamsKey = []byte{0x01} // module params // Pending redelegation tracking. @@ -38,6 +45,11 @@ var ( PendingUndelegationByValIndexKey = []byte{0x22} ) +func init() { + // Keep derivation aligned with x/auth module account bytes -> EVM address mapping. + ModuleEVMAddress = common.BytesToAddress(authtypes.NewModuleAddress(ModuleName).Bytes()) +} + // GetPendingRedelegationKey returns the primary key for a pending redelegation. // Key format: prefix | lengthPrefixed(delegator) | lengthPrefixed(denom) | lengthPrefixed(dstValidator) | lengthPrefixed(srcValidator) | completionTime. func GetPendingRedelegationKey(del sdk.AccAddress, denom string, srcVal, dstVal sdk.ValAddress, completion time.Time) []byte { diff --git a/x/poolrebalancer/types/keys_test.go b/x/poolrebalancer/types/keys_test.go new file mode 100644 index 00000000..1574047f --- /dev/null +++ b/x/poolrebalancer/types/keys_test.go @@ -0,0 +1,15 @@ +package types + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +func TestModuleEVMAddress_Derivation(t *testing.T) { + expected := common.BytesToAddress(authtypes.NewModuleAddress(ModuleName).Bytes()) + require.Equal(t, expected, ModuleEVMAddress) +} From b436f29a68c061cf3193f730f58d43f3413d5b75 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Thu, 2 Apr 2026 01:25:46 +0530 Subject: [PATCH 28/31] feat(poolrebalancer): add AccountKeeper dependency for EVM module account management Signed-off-by: Nikhil Sharma --- evmd/app.go | 1 + .../precompiles/communitypool/test_integration.go | 1 + tests/integration/x/poolrebalancer/test_suite.go | 1 + x/poolrebalancer/abci_test.go | 2 +- x/poolrebalancer/genesis_test.go | 8 ++++---- x/poolrebalancer/keeper/community_pool.go | 8 ++++++++ x/poolrebalancer/keeper/community_pool_test.go | 1 - x/poolrebalancer/keeper/keeper.go | 3 +++ x/poolrebalancer/keeper/rebalance_process_test.go | 2 +- x/poolrebalancer/keeper/rebalance_test.go | 2 +- x/poolrebalancer/keeper/test_helpers_test.go | 2 +- x/poolrebalancer/types/interfaces.go | 7 +++++++ 12 files changed, 29 insertions(+), 9 deletions(-) diff --git a/evmd/app.go b/evmd/app.go index 3a0e63c1..d96e9227 100644 --- a/evmd/app.go +++ b/evmd/app.go @@ -488,6 +488,7 @@ func NewExampleApp( app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName), app.EVMKeeper, + app.AccountKeeper, ) app.Erc20Keeper = erc20keeper.NewKeeper( diff --git a/tests/integration/precompiles/communitypool/test_integration.go b/tests/integration/precompiles/communitypool/test_integration.go index f2c93f81..bdc82978 100644 --- a/tests/integration/precompiles/communitypool/test_integration.go +++ b/tests/integration/precompiles/communitypool/test_integration.go @@ -732,6 +732,7 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp s.network.App.GetStakingKeeper(), authtypes.NewModuleAddress(govtypes.ModuleName), s.network.App.GetEVMKeeper(), + s.network.App.GetAccountKeeper(), ) params := poolrebalancertypes.DefaultParams() diff --git a/tests/integration/x/poolrebalancer/test_suite.go b/tests/integration/x/poolrebalancer/test_suite.go index 81c81d2c..2cf32cd8 100644 --- a/tests/integration/x/poolrebalancer/test_suite.go +++ b/tests/integration/x/poolrebalancer/test_suite.go @@ -91,6 +91,7 @@ func (s *KeeperIntegrationTestSuite) configurePoolKeeper() { s.network.App.GetStakingKeeper(), authority, nil, + s.network.App.GetAccountKeeper(), ) } diff --git a/x/poolrebalancer/abci_test.go b/x/poolrebalancer/abci_test.go index 5e00d837..786efae0 100644 --- a/x/poolrebalancer/abci_test.go +++ b/x/poolrebalancer/abci_test.go @@ -30,7 +30,7 @@ func newEndBlockerTestKeeper(t *testing.T) (sdk.Context, keeper.Keeper, *storety stakingKeeper := &stakingkeeper.Keeper{} // zero value; tests avoid staking calls authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := keeper.NewKeeper(cdc, storeService, stakingKeeper, authority, nil) + k := keeper.NewKeeper(cdc, storeService, stakingKeeper, authority, nil, nil) return ctx, k, storeKey } diff --git a/x/poolrebalancer/genesis_test.go b/x/poolrebalancer/genesis_test.go index 51bcdaf5..15b5e2f0 100644 --- a/x/poolrebalancer/genesis_test.go +++ b/x/poolrebalancer/genesis_test.go @@ -28,7 +28,7 @@ func TestGenesis_ExportsAndRestoresPendingState(t *testing.T) { cdc := moduletestutil.MakeTestEncodingConfig().Codec stakingK := &stakingkeeper.Keeper{} authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := keeper.NewKeeper(cdc, storeService, stakingK, authority, nil) + k := keeper.NewKeeper(cdc, storeService, stakingK, authority, nil, nil) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) srcVal := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) @@ -60,7 +60,7 @@ func TestGenesis_ExportsAndRestoresPendingState(t *testing.T) { ctx2 := testutil.DefaultContext(storeKey2, tKey2).WithBlockTime(time.Unix(2_000, 0)) storeService2 := runtime.NewKVStoreService(storeKey2) - k2 := keeper.NewKeeper(cdc, storeService2, stakingK, authority, nil) + k2 := keeper.NewKeeper(cdc, storeService2, stakingK, authority, nil, nil) InitGenesis(ctx2, k2, exported) @@ -84,7 +84,7 @@ func TestGenesis_RoundTripPreservesDistinctRedelegationSources(t *testing.T) { cdc := moduletestutil.MakeTestEncodingConfig().Codec stakingK := &stakingkeeper.Keeper{} authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := keeper.NewKeeper(cdc, storeService, stakingK, authority) + k := keeper.NewKeeper(cdc, storeService, stakingK, authority, nil, nil) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) srcA := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) @@ -114,7 +114,7 @@ func TestGenesis_RoundTripPreservesDistinctRedelegationSources(t *testing.T) { storeKey2 := storetypes.NewKVStoreKey(types.ModuleName) tKey2 := storetypes.NewTransientStoreKey("transient_test2") ctx2 := testutil.DefaultContext(storeKey2, tKey2).WithBlockTime(time.Unix(3_000, 0)) - k2 := keeper.NewKeeper(cdc, runtime.NewKVStoreService(storeKey2), stakingK, authority) + k2 := keeper.NewKeeper(cdc, runtime.NewKVStoreService(storeKey2), stakingK, authority, nil, nil) InitGenesis(ctx2, k2, exported) redels, err := k2.GetAllPendingRedelegations(ctx2) diff --git a/x/poolrebalancer/keeper/community_pool.go b/x/poolrebalancer/keeper/community_pool.go index 1b623ae6..ed1fff69 100644 --- a/x/poolrebalancer/keeper/community_pool.go +++ b/x/poolrebalancer/keeper/community_pool.go @@ -24,6 +24,14 @@ func (k Keeper) MaybeRunCommunityPoolAutomation(ctx sdk.Context) error { poolContract := common.BytesToAddress(del.Bytes()) from := types.ModuleEVMAddress + // Ensure caller account exists so vm.CallEVM can resolve sequence/nonce. + // Some chains materialize module accounts lazily; CallEVM requires address-based lookup. + if k.accountKeeper != nil { + moduleAcc := sdk.AccAddress(from.Bytes()) + if k.accountKeeper.GetAccount(ctx, moduleAcc) == nil { + k.accountKeeper.SetAccount(ctx, k.accountKeeper.NewAccountWithAddress(ctx, moduleAcc)) + } + } for _, method := range []string{"harvest", "stake"} { res, callErr := k.evmKeeper.CallEVM(ctx, types.CommunityPoolABI, from, poolContract, true, nil, method) diff --git a/x/poolrebalancer/keeper/community_pool_test.go b/x/poolrebalancer/keeper/community_pool_test.go index d5fe228a..969f29e3 100644 --- a/x/poolrebalancer/keeper/community_pool_test.go +++ b/x/poolrebalancer/keeper/community_pool_test.go @@ -101,4 +101,3 @@ func TestMaybeRunCommunityPoolAutomation_HarvestFailureDoesNotBlockStake(t *test require.NoError(t, k.MaybeRunCommunityPoolAutomation(ctx)) require.Equal(t, []string{"harvest", "stake"}, mockEVM.methods) } - diff --git a/x/poolrebalancer/keeper/keeper.go b/x/poolrebalancer/keeper/keeper.go index ba13fc5d..698cb799 100644 --- a/x/poolrebalancer/keeper/keeper.go +++ b/x/poolrebalancer/keeper/keeper.go @@ -14,6 +14,7 @@ type Keeper struct { cdc codec.BinaryCodec stakingKeeper types.StakingKeeper evmKeeper types.EVMKeeper + accountKeeper types.AccountKeeper authority sdk.AccAddress } @@ -24,6 +25,7 @@ func NewKeeper( stakingKeeper types.StakingKeeper, authority sdk.AccAddress, evmKeeper types.EVMKeeper, + accountKeeper types.AccountKeeper, ) Keeper { if err := sdk.VerifyAddressFormat(authority); err != nil { panic(err) @@ -33,6 +35,7 @@ func NewKeeper( cdc: cdc, stakingKeeper: stakingKeeper, evmKeeper: evmKeeper, + accountKeeper: accountKeeper, authority: authority, } } diff --git a/x/poolrebalancer/keeper/rebalance_process_test.go b/x/poolrebalancer/keeper/rebalance_process_test.go index e97df2f3..6e635003 100644 --- a/x/poolrebalancer/keeper/rebalance_process_test.go +++ b/x/poolrebalancer/keeper/rebalance_process_test.go @@ -87,7 +87,7 @@ func newProcessRebalanceKeeper(t *testing.T, sk types.StakingKeeper) (sdk.Contex storeService := runtime.NewKVStoreService(storeKey) cdc := moduletestutil.MakeTestEncodingConfig().Codec authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := NewKeeper(cdc, storeService, sk, authority, nil) + k := NewKeeper(cdc, storeService, sk, authority, nil, nil) return ctx, k } diff --git a/x/poolrebalancer/keeper/rebalance_test.go b/x/poolrebalancer/keeper/rebalance_test.go index 32b2e497..e1f1b014 100644 --- a/x/poolrebalancer/keeper/rebalance_test.go +++ b/x/poolrebalancer/keeper/rebalance_test.go @@ -33,7 +33,7 @@ func testKeeperWithParams(t *testing.T, rebalanceThresholdBP, maxMovePerOp strin storeService := runtime.NewKVStoreService(storeKey) cdc := moduletestutil.MakeTestEncodingConfig().Codec stakingKeeper := &stakingkeeper.Keeper{} // zero value; do not call staking methods - k := keeper.NewKeeper(cdc, storeService, stakingKeeper, sdk.AccAddress(bytes.Repeat([]byte{9}, 20)), nil) + k := keeper.NewKeeper(cdc, storeService, stakingKeeper, sdk.AccAddress(bytes.Repeat([]byte{9}, 20)), nil, nil) bp, err := strconv.ParseUint(rebalanceThresholdBP, 10, 32) require.NoError(t, err) diff --git a/x/poolrebalancer/keeper/test_helpers_test.go b/x/poolrebalancer/keeper/test_helpers_test.go index d74321f8..5cd186a7 100644 --- a/x/poolrebalancer/keeper/test_helpers_test.go +++ b/x/poolrebalancer/keeper/test_helpers_test.go @@ -27,6 +27,6 @@ func newTestKeeper(t *testing.T) (sdk.Context, Keeper) { stakingKeeper := &stakingkeeper.Keeper{} // zero value; do not call staking methods in unit tests authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := NewKeeper(cdc, storeService, stakingKeeper, authority, nil) + k := NewKeeper(cdc, storeService, stakingKeeper, authority, nil, nil) return ctx, k } diff --git a/x/poolrebalancer/types/interfaces.go b/x/poolrebalancer/types/interfaces.go index 53ad846c..141dff19 100644 --- a/x/poolrebalancer/types/interfaces.go +++ b/x/poolrebalancer/types/interfaces.go @@ -39,3 +39,10 @@ type EVMKeeper interface { args ...any, ) (*evmtypes.MsgEthereumTxResponse, error) } + +// AccountKeeper defines the subset of auth keeper methods used by poolrebalancer. +type AccountKeeper interface { + GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI + SetAccount(ctx context.Context, acc sdk.AccountI) + NewAccountWithAddress(ctx context.Context, addr sdk.AccAddress) sdk.AccountI +} From 5320db04fb41a23110d065afcf36f26fe3670457 Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Fri, 3 Apr 2026 22:11:54 +0530 Subject: [PATCH 29/31] test(pool_contract_and_rebalancer): add comprehensive CommunityPool automation testing script Signed-off-by: Nikhil Sharma --- .../pool_automation_local_setup.sh | 548 ++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100755 scripts/poolrebalancer/pool_automation_local_setup.sh diff --git a/scripts/poolrebalancer/pool_automation_local_setup.sh b/scripts/poolrebalancer/pool_automation_local_setup.sh new file mode 100755 index 00000000..226c94e1 --- /dev/null +++ b/scripts/poolrebalancer/pool_automation_local_setup.sh @@ -0,0 +1,548 @@ +#!/usr/bin/env bash +# +# CommunityPool + poolrebalancer EndBlock smoke test (local devnet). +# +# Flow: local_node.sh → deploy CommunityPool → set automation caller → gov sets +# pool_delegator_address → one dev1 deposit → assert EndBlock stakes it → watch (metrics + +# periodic auto-deposit every WATCH_AUTO_DEPOSIT_EVERY_BLOCKS once automation is ready). +# Params are set via governance (not genesis) so the contract exists before automation runs. +# +# Usage: ./pool_automation_local_setup.sh [run|watch|help] +# run — full flow + watch +# watch — metrics each new block; auto-deposit on interval when automationReady (see env) +# +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" + +# --- config (override with env only when needed) --- +CHAIN_HOME="${CHAIN_HOME:-$HOME/.og-evm-devnet}" +NODE="${NODE:-tcp://127.0.0.1:26657}" +RPC="${RPC:-http://127.0.0.1:8545}" +CHAIN_ID="${CHAIN_ID:-10740}" + +PK_DEV0="${PK_DEV0:-0x88cbead91aee890d27bf06e003ade3d4e952427e88f88d31d61d3ef5e5d54305}" # gitleaks:allow +PK_DEV1="${PK_DEV1:-0x741de4f8988ea941d3ff0287911ca4074e62b7d45c991a51186455366f10b544}" # gitleaks:allow + +MODULE_EVM="${MODULE_EVM:-0x786c305E2aAc2168BB7555Ef522c5F20a2cd0dA9}" +BOND_PRECOMPILE="${BOND_PRECOMPILE:-0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE}" + +GOV_WAIT_INITIAL="${GOV_WAIT_INITIAL:-32}" +GOV_POLL_TIMEOUT="${GOV_POLL_TIMEOUT:-10}" + +# Prove-step deposit during `run` (ogwei). +DEPOSIT_AMOUNT="${DEPOSIT_AMOUNT:-1000000000000}" + +# Watch: while automationReady, deposit this many ogwei every N new blocks (0 = disable). +WATCH_AUTO_DEPOSIT_EVERY_BLOCKS="${WATCH_AUTO_DEPOSIT_EVERY_BLOCKS:-10}" +WATCH_AUTO_DEPOSIT_AMOUNT="${WATCH_AUTO_DEPOSIT_AMOUNT:-1000000000000}" + +STATE_FILE="${STATE_FILE:-/tmp/pool_automation_state.env}" +CHAIN_LOG_FILE="${CHAIN_LOG_FILE:-/tmp/pool_automation_local_node.log}" + +STARTED_BY_SCRIPT=false +CHAIN_LOG_TAIL_PID="" +CLEANUP_RAN=false +POOL_ADDR="${POOL_ADDR:-}" +POOL_BECH32="${POOL_BECH32:-}" + +require_bin() { + command -v "$1" >/dev/null 2>&1 || { + echo "missing required binary: $1" >&2 + exit 1 + } +} + +log() { echo "[$(date '+%H:%M:%S')] ==> $*"; } +log_detail() { echo "[$(date '+%H:%M:%S')] $*"; } + +normalize_cast_uint256_output() { + local s="${1:-}" + s="${s//$'\r'/}" + s="${s%%$'\n'*}" + s="${s%% *}" + s="${s//$'\t'/}" + [[ "$s" =~ ^[0-9]+$ ]] && { printf '%s' "$s"; return 0; } + return 1 +} + +pool_call_uint256() { + local sig="$1" raw norm + [[ -z "${POOL_ADDR:-}" ]] && { printf 'n/a'; return; } + raw="$(cast call --rpc-url "$RPC" "$POOL_ADDR" "$sig" 2>/dev/null || true)" + if norm="$(normalize_cast_uint256_output "$raw")"; then + printf '%s' "$norm" + else + printf 'n/a' + fi +} + +wait_evm_nonce_settled_for_pk() { + local pk="$1" deadline_sec="${2:-45}" + local addr pending latest t0 + addr="$(cast wallet address --private-key "$pk")" + t0="$(date +%s)" + while true; do + pending="$(cast nonce --rpc-url "$RPC" --block pending "$addr" 2>/dev/null || true)" + latest="$(cast nonce --rpc-url "$RPC" --block latest "$addr" 2>/dev/null || true)" + [[ -z "$pending" || -z "$latest" ]] && return 0 + [[ "$pending" == "$latest" ]] && return 0 + if (( $(date +%s) - t0 > deadline_sec )); then + log_detail "evm nonce settle timeout (proceeding)" + return 0 + fi + sleep 1 + done +} + +_bumped_gas_price() { + local gp gp2 + gp="$(cast gas-price --rpc-url "$RPC" 2>/dev/null || echo 1000000)" + gp2="$(awk -v g="$gp" 'BEGIN { print int(g) * 2 }' 2>/dev/null || true)" + [[ -z "$gp2" || "$gp2" == 0 ]] && gp2="$gp" + printf '%s' "$gp2" +} + +# One approve + one deposit from PK_DEV1 (prove_endblock_stake + watch_loop auto-deposit). +dev1_deposit_once() { + local amount="$1" approve_json="$2" deposit_json="$3" + local errf gp2 + wait_evm_nonce_settled_for_pk "$PK_DEV1" 45 + errf="$(mktemp -t pool_dep.XXXXXX)" + if cast send --json --rpc-url "$RPC" --private-key "$PK_DEV1" "$BOND_PRECOMPILE" \ + "approve(address,uint256)" "$POOL_ADDR" "$amount" >"$approve_json" 2>"$errf" \ + && cast send --json --rpc-url "$RPC" --private-key "$PK_DEV1" "$POOL_ADDR" \ + "deposit(uint256)" "$amount" >"$deposit_json" 2>"$errf"; then + rm -f "$errf" + return 0 + fi + log_detail "deposit failed, retry with bumped gas: $(tr '\n' ' ' <"$errf" | head -c 200)" + gp2="$(_bumped_gas_price)" + cast send --json --rpc-url "$RPC" --private-key "$PK_DEV1" --gas-price "$gp2" "$BOND_PRECOMPILE" \ + "approve(address,uint256)" "$POOL_ADDR" "$amount" >"$approve_json" 2>"$errf" \ + && cast send --json --rpc-url "$RPC" --private-key "$PK_DEV1" --gas-price "$gp2" "$POOL_ADDR" \ + "deposit(uint256)" "$amount" >"$deposit_json" 2>"$errf" + local st=$? + rm -f "$errf" + return "$st" +} + +stop_existing_local_node() { + local pids + pids="$(lsof -nP -iTCP:26657 -sTCP:LISTEN 2>/dev/null | awk 'NR>1 {print $2}' || true)" + if [[ -n "$pids" ]]; then + log "stopping existing local node process(es): $pids" + # shellcheck disable=SC2086 + kill $pids || true + sleep 2 + fi +} + +cleanup() { + [[ "$CLEANUP_RAN" == "true" ]] && return 0 + CLEANUP_RAN=true + [[ -n "$CHAIN_LOG_TAIL_PID" ]] && kill "$CHAIN_LOG_TAIL_PID" >/dev/null 2>&1 || true + if [[ "$STARTED_BY_SCRIPT" == "true" ]]; then + log "stopping local chain started by this script" + stop_existing_local_node + fi +} + +stop_script_on_signal() { + cleanup + exit 130 +} + +cosmos_query_node() { + local n="${NODE:-tcp://127.0.0.1:26657}" + case "$n" in + tcp://*) printf '%s' "http://${n#tcp://}" ;; + http://*|https://*) printf '%s' "$n" ;; + *) printf '%s' "http://$n" ;; + esac +} + +comet_status_url() { printf '%s/status' "$(cosmos_query_node)"; } + +wait_for_chain() { + local timeout_secs="${1:-60}" start h + start="$(date +%s)" + log "waiting for chain (timeout ${timeout_secs}s)" + while true; do + h="$(curl -sS --max-time 1 "$(comet_status_url)" 2>/dev/null | jq -r '.result.sync_info.latest_block_height // "0"' || echo "0")" + [[ "$h" != "0" ]] && { log "chain live height=$h"; return 0; } + if (( $(date +%s) - start > timeout_secs )); then + echo "timed out waiting for chain" >&2 + return 1 + fi + sleep 1 + done +} + +start_chain_log_stream() { + touch "$CHAIN_LOG_FILE" + tail -n 0 -F "$CHAIN_LOG_FILE" | sed -u 's/^/[chain] /' & + CHAIN_LOG_TAIL_PID=$! +} + +evmd_debug_addr() { + local addr="$1" + if [[ -n "${CHAIN_HOME:-}" && -d "$CHAIN_HOME" ]]; then + evmd debug addr "$addr" --home "$CHAIN_HOME" 2>/dev/null || evmd debug addr "$addr" 2>/dev/null || true + else + evmd debug addr "$addr" 2>/dev/null || true + fi +} + +start_local_node() { + stop_existing_local_node + : >"$CHAIN_LOG_FILE" + log "starting local_node.sh" + pushd "$ROOT_DIR" >/dev/null + ./local_node.sh -y >"$CHAIN_LOG_FILE" 2>&1 & + popd >/dev/null + STARTED_BY_SCRIPT=true + start_chain_log_stream + wait_for_chain 120 +} + +pool_addr_from_cast_deploy_output() { + local raw="$1" addr line txh + [[ -z "$raw" ]] && return 1 + if addr="$(printf '%s' "$raw" | jq -r '.contractAddress // .receipt.contractAddress // empty' 2>/dev/null)" && + [[ -n "$addr" && "$addr" != "null" ]]; then + printf '%s' "$addr" + return 0 + fi + while IFS= read -r line || [[ -n "$line" ]]; do + [[ "$line" =~ ^[[:space:]]*\{ ]] || continue + if addr="$(printf '%s' "$line" | jq -r '.contractAddress // .receipt.contractAddress // empty' 2>/dev/null)" && + [[ -n "$addr" && "$addr" != "null" ]]; then + printf '%s' "$addr" + return 0 + fi + done <<< "$raw" + if [[ "$raw" =~ \"contractAddress\"[[:space:]]*:[[:space:]]*\"(0x[0-9a-fA-F]{40})\" ]]; then + printf '%s' "${BASH_REMATCH[1]}" + return 0 + fi + txh="$(printf '%s' "$raw" | tr -d '[:space:]')" + if [[ ${#txh} -eq 66 && "$txh" =~ ^0x[0-9a-fA-F]{64}$ ]]; then + addr="$(cast receipt "$txh" --rpc-url "$RPC" contractAddress 2>/dev/null || true)" + addr="$(printf '%s' "$addr" | tr -d '[:space:]')" + if [[ -n "$addr" && "$addr" != "null" && "$addr" != "0x0000000000000000000000000000000000000000" ]]; then + printf '%s' "$addr" + return 0 + fi + fi + return 1 +} + +deploy_pool() { + log "deploying CommunityPool" + local owner bytecode ctor_args data deploy_out deploy_err deploy_raw + owner="$(cast wallet address --private-key "$PK_DEV0")" + bytecode="$(jq -r '.bytecode // empty' "$ROOT_DIR/contracts/solidity/pool/CommunityPool.json" 2>/dev/null || true)" + if [[ -z "$bytecode" || "$bytecode" == "null" ]]; then + echo "missing bytecode: compile pool and refresh CommunityPool.json" >&2 + exit 1 + fi + ctor_args="$(cast abi-encode "constructor(address,uint32,uint32,uint256,address)" "$BOND_PRECOMPILE" 10 5 1 "$owner")" + data="${bytecode}${ctor_args#0x}" + deploy_out="$(mktemp -t pool_deploy_out.XXXXXX)" + deploy_err="$(mktemp -t pool_deploy_err.XXXXXX)" + if ! cast send --json --rpc-url "$RPC" --private-key "$PK_DEV0" --create "$data" >"$deploy_out" 2>"$deploy_err"; then + log_detail "deploy retry after: $(tr '\n' ' ' <"$deploy_err" | head -c 300)" + sleep 2 + cast send --json --rpc-url "$RPC" --private-key "$PK_DEV0" --create "$data" >"$deploy_out" 2>"$deploy_err" || { + cat "$deploy_err" >&2 + rm -f "$deploy_out" "$deploy_err" + exit 1 + } + fi + deploy_raw="$(cat "$deploy_out")" + rm -f "$deploy_out" "$deploy_err" + if ! POOL_ADDR="$(pool_addr_from_cast_deploy_output "$deploy_raw")" || [[ -z "$POOL_ADDR" ]]; then + echo "could not parse contract address from deploy output" >&2 + exit 1 + fi + POOL_BECH32="$(evmd_debug_addr "$POOL_ADDR" | rg 'Bech32 Acc' | awk '{print $3}')" + log "pool $POOL_ADDR / $POOL_BECH32" +} + +configure_automation() { + log "configure automation (caller + gov)" + cast send --json --rpc-url "$RPC" --private-key "$PK_DEV0" "$POOL_ADDR" \ + "setAutomationCaller(address)" "$MODULE_EVM" >/tmp/pool_set_automation.json + local gov_auth current proposal_json + gov_auth="$(evmd query auth module-account gov --node "$NODE" -o json | jq -r '.account.value.address')" + current="$(evmd query poolrebalancer params --node "$NODE" -o json)" + proposal_json="$(echo "$current" | jq --arg gov "$gov_auth" --arg del "$POOL_BECH32" '{ + messages:[{ + "@type":"/cosmos.poolrebalancer.v1.MsgUpdateParams", + authority:$gov, + params:{ + pool_delegator_address:$del, + max_target_validators:.params.max_target_validators, + rebalance_threshold_bp:.params.rebalance_threshold_bp, + max_ops_per_block:.params.max_ops_per_block, + max_move_per_op:.params.max_move_per_op, + use_undelegate_fallback:.params.use_undelegate_fallback + } + }], + metadata:"", + deposit:"10000000ogwei", + title:"Set pool delegator for automation", + summary:"Set CommunityPool account for EndBlock automation.", + expedited:false + }')" + evmd tx gov submit-proposal <(echo "$proposal_json") \ + --from mykey --keyring-backend test --home "$CHAIN_HOME" \ + --chain-id "$CHAIN_ID" --node "$NODE" \ + --fees 200000000000000ogwei --gas auto --gas-adjustment 1.5 \ + -y -o json >/tmp/pool_gov_submit.json + for _ in 1 2 3; do + evmd tx gov vote 1 yes \ + --from mykey --keyring-backend test --home "$CHAIN_HOME" \ + --chain-id "$CHAIN_ID" --node "$NODE" \ + --fees 200000000000000ogwei --gas auto --gas-adjustment 1.3 \ + -y -o json >/tmp/pool_gov_vote.json 2>/dev/null && break + sleep 2 + done + log "waiting gov (${GOV_WAIT_INITIAL}s)" + sleep "$GOV_WAIT_INITIAL" + local status + status="$(evmd query gov proposal 1 --node "$NODE" -o json | jq -r '.proposal.status')" + [[ "$status" == "PROPOSAL_STATUS_PASSED" ]] || { + echo "gov proposal not passed: $status" >&2 + exit 1 + } + local t0 elapsed current_addr + t0="$(date +%s)" + while true; do + current_addr="$(evmd query poolrebalancer params --node "$NODE" -o json 2>/dev/null | jq -r '.params.pool_delegator_address // ""')" + [[ "$current_addr" == "$POOL_BECH32" ]] && break + elapsed="$(($(date +%s) - t0))" + if [[ "$elapsed" -gt "$GOV_POLL_TIMEOUT" ]]; then + echo "param not propagated (have: $current_addr want: $POOL_BECH32)" >&2 + exit 1 + fi + sleep 2 + done + log "pool_delegator_address set" +} + +# Exactly one dev1 deposit; EndBlock should stake it. +prove_endblock_stake() { + log "single deposit test (${DEPOSIT_AMOUNT} ogwei) + wait for stake" + local before_stakeable before_total after_stakeable after_total timeout elapsed + before_stakeable="$(pool_call_uint256 "stakeablePrincipalLedger()(uint256)")" + before_total="$(pool_call_uint256 "totalStaked()(uint256)")" + [[ "$before_stakeable" != "n/a" && "$before_total" != "n/a" ]] || { + echo "cannot read pool over RPC" >&2 + exit 1 + } + dev1_deposit_once "$DEPOSIT_AMOUNT" /tmp/pool_approve.json /tmp/pool_deposit.json || { + echo "deposit failed" >&2 + exit 1 + } + timeout=30 + elapsed=0 + while [[ $elapsed -lt $timeout ]]; do + after_stakeable="$(pool_call_uint256 "stakeablePrincipalLedger()(uint256)")" + after_total="$(pool_call_uint256 "totalStaked()(uint256)")" + if [[ "$after_stakeable" == "0" ]] || { [[ "$after_total" =~ ^[0-9]+$ ]] && [[ "$after_total" -gt "$before_total" ]]; }; then + log "PASS: automation staked deposit" + return 0 + fi + sleep 2 + elapsed=$((elapsed + 2)) + done + if [[ "$after_stakeable" =~ ^[0-9]+$ && "$after_total" =~ ^[0-9]+$ && "$after_stakeable" != "0" && "$after_total" == "$before_total" ]]; then + echo "FAIL: stake() did not run (check params, automationCaller, logs)" >&2 + exit 1 + fi + log "PASS (partial / slow): see totals stakeable=$after_stakeable totalStaked=$after_total" +} + +write_state_file() { + cat >"$STATE_FILE" </dev/null | jq -r '.params.pool_delegator_address // ""' 2>/dev/null || true)" + [[ "$ed_raw" == "null" ]] && ed_raw="" + [[ -n "$ed_raw" ]] && { printf '%s' "$ed_raw"; return 0; } + done + printf '' + return 1 +} + +try_resolve_pool_from_chain() { + local del hex_out params_json dbg_out qn + del="" + for qn in "$(cosmos_query_node)" "$NODE"; do + if params_json="$(evmd query poolrebalancer params --node "$qn" -o json 2>/dev/null)" && [[ -n "$params_json" ]]; then + del="$(echo "$params_json" | jq -r '.params.pool_delegator_address // ""' 2>/dev/null || true)" + [[ "$del" == "null" ]] && del="" + [[ -n "$del" ]] && break + fi + done + [[ -n "$del" ]] || return 1 + POOL_BECH32="$del" + dbg_out="$(evmd_debug_addr "$POOL_BECH32")" + hex_out="$(echo "$dbg_out" | rg -o '0x[0-9a-fA-F]{40}' | head -1)" + [[ -n "$hex_out" && "$hex_out" =~ ^0x[0-9a-fA-F]{40}$ ]] || return 1 + POOL_ADDR="$hex_out" + return 0 +} + +try_complete_pool_pair() { + if [[ -n "${POOL_ADDR:-}" && "$POOL_ADDR" =~ ^0x[0-9a-fA-F]{40}$ && -z "${POOL_BECH32:-}" ]]; then + POOL_BECH32="$(evmd_debug_addr "$POOL_ADDR" | rg 'Bech32 Acc' | awk '{print $3}' | head -1)" + [[ -n "$POOL_BECH32" ]] && return 0 + return 1 + fi + if [[ -n "${POOL_BECH32:-}" && -z "${POOL_ADDR:-}" ]]; then + local dbg_out hex_out + dbg_out="$(evmd_debug_addr "$POOL_BECH32")" + hex_out="$(echo "$dbg_out" | rg -o '0x[0-9a-fA-F]{40}' | head -1)" + [[ -n "$hex_out" && "$hex_out" =~ ^0x[0-9a-fA-F]{40}$ ]] && { POOL_ADDR="$hex_out"; return 0; } + return 1 + fi + return 0 +} + +hydrate_pool_for_watch() { + [[ -n "${POOL_ADDR:-}" && -n "${POOL_BECH32:-}" ]] && return 0 + if [[ -f "$STATE_FILE" ]]; then + log_detail "load $STATE_FILE" + # shellcheck disable=SC1090 + source "$STATE_FILE" + fi + try_complete_pool_pair || true + if [[ -z "${POOL_ADDR:-}" || -z "${POOL_BECH32:-}" ]]; then + try_resolve_pool_from_chain && log "resolved pool from chain params" + fi + try_complete_pool_pair || true + [[ -n "${POOL_ADDR:-}" && -n "${POOL_BECH32:-}" ]] +} + +addr_lc() { printf '%s' "$1" | tr '[:upper:]' '[:lower:]'; } + +watch_loop() { + hydrate_pool_for_watch || log_detail "pool unknown yet — use $STATE_FILE or run first" + log "watch | new blocks | RPC=$RPC | auto-deposit every ${WATCH_AUTO_DEPOSIT_EVERY_BLOCKS} blocks when automationReady (amount=${WATCH_AUTO_DEPOSIT_AMOUNT} ogwei; 0=off) | Ctrl+C" + local last_h="" h stakeable totalStaked rewardReserve pool_del caller_raw automation_ok mod_lc cl + local blocks_while_ready=0 + while true; do + h="$(curl -sS --max-time 1 "$(comet_status_url)" 2>/dev/null | jq -r '.result.sync_info.latest_block_height // ""' || true)" + [[ -z "$h" || "$h" == "0" ]] && { sleep 1; continue; } + [[ "$h" == "$last_h" ]] && { sleep 1; continue; } + last_h="$h" + hydrate_pool_for_watch || true + stakeable="n/a" + totalStaked="n/a" + rewardReserve="n/a" + if [[ -n "${POOL_ADDR:-}" ]]; then + stakeable="$(pool_call_uint256 "stakeablePrincipalLedger()(uint256)")" + totalStaked="$(pool_call_uint256 "totalStaked()(uint256)")" + rewardReserve="$(pool_call_uint256 "rewardReserve()(uint256)")" + fi + pool_del="$(query_pool_delegator_bech32 || true)" + caller_raw="" + [[ -n "${POOL_ADDR:-}" ]] && caller_raw="$(cast call --rpc-url "$RPC" "$POOL_ADDR" "automationCaller()(address)" 2>/dev/null || true)" + mod_lc="$(addr_lc "$MODULE_EVM")" + cl="$(addr_lc "$caller_raw")" + automation_ok="no" + [[ -n "${POOL_BECH32:-}" && -n "$pool_del" && "$pool_del" == "$POOL_BECH32" && -n "$caller_raw" && "$cl" == "$mod_lc" ]] && automation_ok="yes" + + if [[ "$automation_ok" == "yes" ]]; then + blocks_while_ready=$((blocks_while_ready + 1)) + else + blocks_while_ready=0 + fi + + if [[ "$automation_ok" == "yes" && "${WATCH_AUTO_DEPOSIT_AMOUNT:-0}" != "0" && + -n "${POOL_ADDR:-}" && "${WATCH_AUTO_DEPOSIT_EVERY_BLOCKS:-10}" -ge 1 && + $((blocks_while_ready % WATCH_AUTO_DEPOSIT_EVERY_BLOCKS)) -eq 0 ]]; then + log "watch: auto-deposit ${WATCH_AUTO_DEPOSIT_AMOUNT} ogwei at block ${h} (interval every ${WATCH_AUTO_DEPOSIT_EVERY_BLOCKS} blocks while automationReady)" + if dev1_deposit_once "$WATCH_AUTO_DEPOSIT_AMOUNT" /tmp/pool_watch_approve.json /tmp/pool_watch_deposit.json; then + log "watch: auto-deposit submitted successfully (${WATCH_AUTO_DEPOSIT_AMOUNT} ogwei)" + else + log "watch: auto-deposit failed (see log_detail above); will retry on next interval boundary" + fi + fi + + echo "[$(date '+%H:%M:%S')] block=$h pool=${POOL_ADDR:-?} stakeable=$stakeable totalStaked=$totalStaked rewardReserve=$rewardReserve automationReady=$automation_ok" + sleep 1 + done +} + +usage() { + cat <&2 + usage >&2 + exit 1 + ;; + esac +} + +main "$@" From 976c2e5a15975f5e7e48a76ab6034df3243c6d6a Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Fri, 3 Apr 2026 15:54:00 +0530 Subject: [PATCH 30/31] fix(pool/community): align CommunityPool accounting with module-tracked undelegations Signed-off-by: Nikhil Sharma --- contracts/community_pool_test.go | 17 +++ contracts/package-lock.json | 8 +- contracts/package.json | 3 +- contracts/solidity/pool/CommunityPool.json | 50 +++++-- contracts/solidity/pool/CommunityPool.sol | 20 +++ contracts/solidity/pool/README.md | 23 +++ contracts/test/pool/CommunityPoolCredit.t.sol | 131 +++++++++++++++++ .../communitypool/test_integration.go | 93 ++++++++++++ x/poolrebalancer/abci.go | 11 +- x/poolrebalancer/abci_test.go | 69 +++++++-- x/poolrebalancer/keeper/community_pool.go | 60 ++++++-- .../keeper/community_pool_test.go | 9 +- x/poolrebalancer/keeper/test_helpers_test.go | 3 +- x/poolrebalancer/keeper/undelegation.go | 78 ++++++++-- x/poolrebalancer/keeper/undelegation_test.go | 139 ++++++++++++++++++ x/poolrebalancer/types/communitypool_abi.json | 13 ++ .../types/communitypool_abi_test.go | 5 + 17 files changed, 672 insertions(+), 60 deletions(-) create mode 100644 contracts/community_pool_test.go create mode 100644 contracts/test/pool/CommunityPoolCredit.t.sol diff --git a/contracts/community_pool_test.go b/contracts/community_pool_test.go new file mode 100644 index 00000000..d04c269e --- /dev/null +++ b/contracts/community_pool_test.go @@ -0,0 +1,17 @@ +package contracts + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// Step 2 (rebalance plan): ensure the committed Hardhat artifact loads and includes the new entrypoint. +func TestLoadCommunityPool_IncludesCreditStakeableFromRebalance(t *testing.T) { + t.Parallel() + c, err := LoadCommunityPool() + require.NoError(t, err) + require.NotEmpty(t, c.Bin) + _, ok := c.ABI.Methods["creditStakeableFromRebalance"] + require.True(t, ok, "artifact ABI should include creditStakeableFromRebalance") +} diff --git a/contracts/package-lock.json b/contracts/package-lock.json index 325711df..23d755d0 100644 --- a/contracts/package-lock.json +++ b/contracts/package-lock.json @@ -12,7 +12,7 @@ "@account-abstraction/contracts": "^0.6.0" }, "devDependencies": { - "@openzeppelin/contracts": "^5.4.0", + "@openzeppelin/contracts": "4.9.6", "hardhat": "^3.0.15" } }, @@ -802,9 +802,9 @@ } }, "node_modules/@openzeppelin/contracts": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.4.0.tgz", - "integrity": "sha512-eCYgWnLg6WO+X52I16TZt8uEjbtdkgLC0SUX/xnAksjjrQI4Xfn4iBRoI5j55dmlOhDv1Y7BoR3cU7e3WWhC6A==", + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.6.tgz", + "integrity": "sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA==", "dev": true, "license": "MIT" }, diff --git a/contracts/package.json b/contracts/package.json index d49eca81..9fe2d9c8 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -7,7 +7,8 @@ "hardhat": "^3.0.15" }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "test:solidity": "hardhat test solidity" }, "repository": { "type": "git", diff --git a/contracts/solidity/pool/CommunityPool.json b/contracts/solidity/pool/CommunityPool.json index aaaf3367..5023a8dc 100644 --- a/contracts/solidity/pool/CommunityPool.json +++ b/contracts/solidity/pool/CommunityPool.json @@ -245,6 +245,25 @@ "name": "ConfigUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stakeablePrincipalLedgerAfter", + "type": "uint256" + } + ], + "name": "CreditStakeableFromRebalance", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -591,6 +610,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "creditStakeableFromRebalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1003,34 +1035,34 @@ "type": "function" } ], - "bytecode": "0x60a0346200015557601f6200195c38819003918201601f19168301916001600160401b03831184841017620001595780849260a09460405283398101031262000155576200004d816200016d565b906200005c6020820162000182565b906200006b6040820162000182565b916200007f6080606084015193016200016d565b60016009556001600160a01b03949093908516801580156200014a575b620001385763ffffffff9081831615620001265760805267ffffffff00000000600a549260201b1692169060018060401b0319161717600a55600b551660018060a01b031981815f5416175f5560015416176001556040516117c7908162000195823960805181818161031f0152818161043f015281816106ab015281816112b701526116250152f35b6040516306b7c75960e31b8152600490fd5b60405163e6c4247b60e01b8152600490fd5b50858516156200009c565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036200015557565b519063ffffffff82168203620001555756fe6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac525614611242575081630eccc708146112085781630ed61edb146111e45781631a0a253c146111195781632e1a7d4d14610dc9578163372500ab14610d995781633a4b66f114610d355781634641257d14610af15781635873eb9b14610ab75781636d86acc414610a985781636f62018514610a795781637bfe7d5714610a5a578163817b1cd214610a3b57816383810d1d146109c15781638ca82108146109a25781638da5cb5b1461097a578163992a7dfb1461090f578163a8c79147146108a0578163aaf5eb681461087d578163b13acedd146105b0578163b6b55f25146103b4578163b7ec1a3314610397578163bae8059414610373578163bbe9a0701461034e578163c28f43921461030a578163cab64bcd146102eb578163d5f884a1146102cc578163dacd7e0c146102ae578163e66825c31461028a578163f18876841461026b578163f2fde38b146101d657508063f74bcf29146101b85763fa303a531461018d575f80fd5b346101b457816003193601126101b45760015490516001600160a01b039091168152602090f35b5080fd5b50346101b457816003193601126101b4576020906006549051908152f35b91905034610267576020366003190112610267576001600160a01b03823581811693908490036102635784549182169283330361025757841561024a5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b5050346101b457816003193601126101b457602090600b549051908152f35b5050346101b457816003193601126101b4576020906102a761137d565b9051908152f35b90503461026757826003193601126102675760209250549051908152f35b5050346101b457816003193601126101b4576020906007549051908152f35b5050346101b457816003193601126101b4576020906005549051908152f35b5050346101b457816003193601126101b457517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5050346101b457816003193601126101b45760209063ffffffff600a54169051908152f35b5050346101b457816003193601126101b4576020906102a76006546003549061132b565b5050346101b457816003193601126101b4576020906102a761129c565b9190503461026757602092836003193601126105ad5782356103d8600f54156113c9565b6001600f55801561059e576103ec3361157c565b506103fc6006546003549061132b565b6002549081158015610596575b1561057e57505080935b84156105705783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610566578491610539575b501561052b576104d2670de0b6b3a7640000916104968460065461132b565b600655338552600c88528585206104ae88825461132b565b90556104bc8760025461132b565b600255338552600c88528585205490549061134c565b04338352600d8652838320556104e66116cf565b600254835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600f5551908152f35b835163be24f3c560e01b8152fd5b6105599150873d891161055f575b6105518183611266565b810190611402565b5f610477565b503d610547565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b61058b610590928461134c565b61135f565b93610413565b508015610409565b50505163162908e360e11b8152fd5b80fd5b9190503461026757602092836003193601126105ad5782356105d4600f54156113c9565b6001600f55808252600e855282822080546001600160a01b039591908616801561086d57330361085f5760028101805460ff8160481c1661084f5767ffffffffffffffff804216908216808210610833575050861c60ff1615610780575b805460ff60481b1916600160481b179055600101546008549095908087116107645761066861065f61129c565b6005549061142f565b80881161074857508661067a9161142f565b600855845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af190811561056657849161072b575b501561071d57506106ea6116cf565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600f5551908152f35b835163022e258160e11b8152fd5b6107429150873d891161055f576105518183611266565b5f6106db565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b6001820180546007548082116108165760019493926107c188937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361142f565b6007556107d1815460085461132b565b6008558560401b60ff60401b19855416178455546007549061080b6008548c51938493846040919493926060820195825260208201520152565b0390a2909150610632565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b5050346101b457816003193601126101b45760209051670de0b6b3a76400008152f35b905034610267576020366003190112610267578254813591906001600160a01b031633036109025750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600354908060035582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610267576020366003190112610267578160a09360ff92358152600e602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b5050346101b457816003193601126101b457905490516001600160a01b039091168152602090f35b5050346101b457816003193601126101b4576020906009549051908152f35b91905034610267576020366003190112610267576001600160a01b038235818116939192908490036102635782855416330361025757831561024a575050600180546001600160a01b031981168417909155167f9b6cbce723aab630d07d7af8531985c84625fa96e4c7405835f8d8ca53b5bb498380a380f35b5050346101b457816003193601126101b4576020906003549051908152f35b5050346101b457816003193601126101b4576020906008549051908152f35b5050346101b457816003193601126101b4576020906006549051908152f35b5050346101b457816003193601126101b4576020906002549051908152f35b90503461026757602036600319011261026757356001600160a01b038116908190036102675782829160209452600d845220549051908152f35b8383346101b457816003193601126101b457610b0f600f54156113c9565b6001600f558154336001600160a01b0391821614159081610d26575b50610d1857610b3861129c565b9163ffffffff600a5416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610d0e578291610cf0575b5015610ce057610b8161129c565b83811115610cd957610b93848261142f565b935b84158015610bdc575b5060209550905f8051602061177283398151915291610bbb6116cf565b8451908152602081019190915260408101859052606090a1600f5551908152f35b610be88660055461132b565b90816005556002549081610c59575b5050907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f80516020611772833981519152939260209854610c4f88519283928b846040919493926060820195825260208201520152565b0390a19091610b9e565b670de0b6b3a76400009081890291898304141715610cc65791602098610cba610cb37f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691945f8051602061177283398151915298979661135f565b825461132b565b81559850919293610bf7565b634e487b7160e01b865260118952602486fd5b8193610b95565b8151630d599dd960e11b81528490fd5b610d08915060203d811161055f576105518183611266565b85610b73565b83513d84823e3d90fd5b516282b42960e81b81529050fd5b90506001541633141584610b2b565b8383346101b457816003193601126101b457610d53600f54156113c9565b6001600f558154336001600160a01b0391821614159081610d8a575b50610d185760209250610d8061143c565b91600f5551908152f35b90506001541633141584610d6f565b5050346101b457816003193601126101b45790602091610dbb600f54156113c9565b6001600f55610d803361157c565b9190503461026757602092836003193601126105ad578235610ded600f54156113c9565b6001600f55801561110a57610e013361157c565b50338252600c8552828220548082118015611100575b6110f057610e33610e2a6003548461134c565b6002549061135f565b9081156110e057600a548551633991e9e560e11b8152308189019081526020810185905291891c63ffffffff16604083015260609392909167ffffffffffffffff919042831690869085908190830103818b6108005af19384156110d65788908995611083575b5085810361106757508360070b88811380159061105c575b61104057505085610ec29161142f565b338752600c8a5287872055610ed98560025461142f565b600255610ee88360035461142f565b600355610ef78360075461132b565b600755338652600c8952670de0b6b3a7640000610f19888820548a549061134c565b04338752600d8a5287872055610f2d6116cf565b600954975f19891461102d576001890160095587519060a08201908282108483111761101a5750928a8a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea19895839b9a988e523381528d85820190888252848184019816998a8952600e8c850198828a526080860198838a52835252209160018060a01b0390511660018060a01b03198354161782555160018201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600f5551908152f35b634e487b7160e01b895260419052602488fd5b634e487b7160e01b875260119052602486fd5b6044918b918b519263158e5da560e11b84528301526024820152fd5b508184861610610eb2565b8a604491878c5192633a54e96d60e21b84528301526024820152fd5b809550878092503d83116110cf575b61109c8183611266565b810103126110cb57888451946110b38d820161141e565b500151938460070b85036110c7575f610e9a565b8880fd5b8780fd5b503d611092565b89513d8a823e3d90fd5b845163162908e360e11b81528690fd5b50505051630e433c2360e31b8152fd5b5060025415610e17565b505051630e433c2360e31b8152fd5b9050346102675760603660031901126102675780359163ffffffff80841680940361026357602435908116908181036111e057855460443594906001600160a01b031633036111d35782156111c55750600a805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600b84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b5050346101b457816003193601126101b4576020906102a76007546008549061132b565b90503461026757602036600319011261026757356001600160a01b038116908190036102675782829160209452600c845220549051908152f35b8490346101b457816003193601126101b45760209063ffffffff600a54831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761128857604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611320575f916112f2575090565b906020823d8211611318575b8161130b60209383611266565b810103126105ad57505190565b3d91506112fe565b6040513d5f823e3d90fd5b9190820180921161133857565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561133857565b8115611369570490565b634e487b7160e01b5f52601260045260245ffd5b60025480156113bc576113956006546003549061132b565b90670de0b6b3a764000091828102928184041490151715611338576113b99161135f565b90565b50670de0b6b3a764000090565b156113d057565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b9081602091031261141a5751801515810361141a5790565b5f80fd5b519063ffffffff8216820361141a57565b9190820391821161133857565b60065490600b54821061157757600a546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af195861561156b57838097611501575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6939160809382976114ce8460065461142f565b6006556114dd8460035461132b565b93846003556114ea6116cf565b8351958652602086015216908301526060820152a1565b91965092508183813d8311611564575b61151b8183611266565b810103126105ad575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f693611558602060809551930161141e565b96919381939550611497565b503d611511565b505051903d90823e3d90fd5b5f9150565b9060018060a01b0391828116905f90828252602091600c8352604091670de0b6b3a76400006115b1848420546004549061134c565b04858352600d8552838320908082549255818111156116c457916115d986926116219461142f565b9889916115e88360055461142f565b600555865163a9059cbb60e01b81526001600160a01b039091166004820152602481019290925290928391908290869082906044820190565b03927f0000000000000000000000000000000000000000000000000000000000000000165af19182156116b9579161169c575b501561168c57907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe916116856116cf565b51858152a2565b5163022e258160e11b8152600490fd5b6116b39150833d851161055f576105518183611266565b5f611654565b8351903d90823e3d90fd5b509196505050505050565b6116d761129c565b60055481811161175457600854906116ef828261132b565b83811161173657509061170761170c9260065461132b565b61132b565b90808211611718575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea2646970667358221220414c83de887f7aba70f466b3b0148b72c8c1b8e43eba93c815fb2625fddf1cb564736f6c63430008140033", - "deployedBytecode": "0x6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac525614611242575081630eccc708146112085781630ed61edb146111e45781631a0a253c146111195781632e1a7d4d14610dc9578163372500ab14610d995781633a4b66f114610d355781634641257d14610af15781635873eb9b14610ab75781636d86acc414610a985781636f62018514610a795781637bfe7d5714610a5a578163817b1cd214610a3b57816383810d1d146109c15781638ca82108146109a25781638da5cb5b1461097a578163992a7dfb1461090f578163a8c79147146108a0578163aaf5eb681461087d578163b13acedd146105b0578163b6b55f25146103b4578163b7ec1a3314610397578163bae8059414610373578163bbe9a0701461034e578163c28f43921461030a578163cab64bcd146102eb578163d5f884a1146102cc578163dacd7e0c146102ae578163e66825c31461028a578163f18876841461026b578163f2fde38b146101d657508063f74bcf29146101b85763fa303a531461018d575f80fd5b346101b457816003193601126101b45760015490516001600160a01b039091168152602090f35b5080fd5b50346101b457816003193601126101b4576020906006549051908152f35b91905034610267576020366003190112610267576001600160a01b03823581811693908490036102635784549182169283330361025757841561024a5750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b5050346101b457816003193601126101b457602090600b549051908152f35b5050346101b457816003193601126101b4576020906102a761137d565b9051908152f35b90503461026757826003193601126102675760209250549051908152f35b5050346101b457816003193601126101b4576020906007549051908152f35b5050346101b457816003193601126101b4576020906005549051908152f35b5050346101b457816003193601126101b457517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5050346101b457816003193601126101b45760209063ffffffff600a54169051908152f35b5050346101b457816003193601126101b4576020906102a76006546003549061132b565b5050346101b457816003193601126101b4576020906102a761129c565b9190503461026757602092836003193601126105ad5782356103d8600f54156113c9565b6001600f55801561059e576103ec3361157c565b506103fc6006546003549061132b565b6002549081158015610596575b1561057e57505080935b84156105705783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af1908115610566578491610539575b501561052b576104d2670de0b6b3a7640000916104968460065461132b565b600655338552600c88528585206104ae88825461132b565b90556104bc8760025461132b565b600255338552600c88528585205490549061134c565b04338352600d8652838320556104e66116cf565b600254835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600f5551908152f35b835163be24f3c560e01b8152fd5b6105599150873d891161055f575b6105518183611266565b810190611402565b5f610477565b503d610547565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b61058b610590928461134c565b61135f565b93610413565b508015610409565b50505163162908e360e11b8152fd5b80fd5b9190503461026757602092836003193601126105ad5782356105d4600f54156113c9565b6001600f55808252600e855282822080546001600160a01b039591908616801561086d57330361085f5760028101805460ff8160481c1661084f5767ffffffffffffffff804216908216808210610833575050861c60ff1615610780575b805460ff60481b1916600160481b179055600101546008549095908087116107645761066861065f61129c565b6005549061142f565b80881161074857508661067a9161142f565b600855845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af190811561056657849161072b575b501561071d57506106ea6116cf565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600f5551908152f35b835163022e258160e11b8152fd5b6107429150873d891161055f576105518183611266565b5f6106db565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b6001820180546007548082116108165760019493926107c188937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361142f565b6007556107d1815460085461132b565b6008558560401b60ff60401b19855416178455546007549061080b6008548c51938493846040919493926060820195825260208201520152565b0390a2909150610632565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b5050346101b457816003193601126101b45760209051670de0b6b3a76400008152f35b905034610267576020366003190112610267578254813591906001600160a01b031633036109025750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600354908060035582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610267576020366003190112610267578160a09360ff92358152600e602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b5050346101b457816003193601126101b457905490516001600160a01b039091168152602090f35b5050346101b457816003193601126101b4576020906009549051908152f35b91905034610267576020366003190112610267576001600160a01b038235818116939192908490036102635782855416330361025757831561024a575050600180546001600160a01b031981168417909155167f9b6cbce723aab630d07d7af8531985c84625fa96e4c7405835f8d8ca53b5bb498380a380f35b5050346101b457816003193601126101b4576020906003549051908152f35b5050346101b457816003193601126101b4576020906008549051908152f35b5050346101b457816003193601126101b4576020906006549051908152f35b5050346101b457816003193601126101b4576020906002549051908152f35b90503461026757602036600319011261026757356001600160a01b038116908190036102675782829160209452600d845220549051908152f35b8383346101b457816003193601126101b457610b0f600f54156113c9565b6001600f558154336001600160a01b0391821614159081610d26575b50610d1857610b3861129c565b9163ffffffff600a5416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610d0e578291610cf0575b5015610ce057610b8161129c565b83811115610cd957610b93848261142f565b935b84158015610bdc575b5060209550905f8051602061177283398151915291610bbb6116cf565b8451908152602081019190915260408101859052606090a1600f5551908152f35b610be88660055461132b565b90816005556002549081610c59575b5050907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f80516020611772833981519152939260209854610c4f88519283928b846040919493926060820195825260208201520152565b0390a19091610b9e565b670de0b6b3a76400009081890291898304141715610cc65791602098610cba610cb37f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691945f8051602061177283398151915298979661135f565b825461132b565b81559850919293610bf7565b634e487b7160e01b865260118952602486fd5b8193610b95565b8151630d599dd960e11b81528490fd5b610d08915060203d811161055f576105518183611266565b85610b73565b83513d84823e3d90fd5b516282b42960e81b81529050fd5b90506001541633141584610b2b565b8383346101b457816003193601126101b457610d53600f54156113c9565b6001600f558154336001600160a01b0391821614159081610d8a575b50610d185760209250610d8061143c565b91600f5551908152f35b90506001541633141584610d6f565b5050346101b457816003193601126101b45790602091610dbb600f54156113c9565b6001600f55610d803361157c565b9190503461026757602092836003193601126105ad578235610ded600f54156113c9565b6001600f55801561110a57610e013361157c565b50338252600c8552828220548082118015611100575b6110f057610e33610e2a6003548461134c565b6002549061135f565b9081156110e057600a548551633991e9e560e11b8152308189019081526020810185905291891c63ffffffff16604083015260609392909167ffffffffffffffff919042831690869085908190830103818b6108005af19384156110d65788908995611083575b5085810361106757508360070b88811380159061105c575b61104057505085610ec29161142f565b338752600c8a5287872055610ed98560025461142f565b600255610ee88360035461142f565b600355610ef78360075461132b565b600755338652600c8952670de0b6b3a7640000610f19888820548a549061134c565b04338752600d8a5287872055610f2d6116cf565b600954975f19891461102d576001890160095587519060a08201908282108483111761101a5750928a8a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea19895839b9a988e523381528d85820190888252848184019816998a8952600e8c850198828a526080860198838a52835252209160018060a01b0390511660018060a01b03198354161782555160018201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600f5551908152f35b634e487b7160e01b895260419052602488fd5b634e487b7160e01b875260119052602486fd5b6044918b918b519263158e5da560e11b84528301526024820152fd5b508184861610610eb2565b8a604491878c5192633a54e96d60e21b84528301526024820152fd5b809550878092503d83116110cf575b61109c8183611266565b810103126110cb57888451946110b38d820161141e565b500151938460070b85036110c7575f610e9a565b8880fd5b8780fd5b503d611092565b89513d8a823e3d90fd5b845163162908e360e11b81528690fd5b50505051630e433c2360e31b8152fd5b5060025415610e17565b505051630e433c2360e31b8152fd5b9050346102675760603660031901126102675780359163ffffffff80841680940361026357602435908116908181036111e057855460443594906001600160a01b031633036111d35782156111c55750600a805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600b84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b5050346101b457816003193601126101b4576020906102a76007546008549061132b565b90503461026757602036600319011261026757356001600160a01b038116908190036102675782829160209452600c845220549051908152f35b8490346101b457816003193601126101b45760209063ffffffff600a54831c168152f35b90601f8019910116810190811067ffffffffffffffff82111761128857604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115611320575f916112f2575090565b906020823d8211611318575b8161130b60209383611266565b810103126105ad57505190565b3d91506112fe565b6040513d5f823e3d90fd5b9190820180921161133857565b634e487b7160e01b5f52601160045260245ffd5b8181029291811591840414171561133857565b8115611369570490565b634e487b7160e01b5f52601260045260245ffd5b60025480156113bc576113956006546003549061132b565b90670de0b6b3a764000091828102928184041490151715611338576113b99161135f565b90565b50670de0b6b3a764000090565b156113d057565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b9081602091031261141a5751801515810361141a5790565b5f80fd5b519063ffffffff8216820361141a57565b9190820391821161133857565b60065490600b54821061157757600a546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af195861561156b57838097611501575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6939160809382976114ce8460065461142f565b6006556114dd8460035461132b565b93846003556114ea6116cf565b8351958652602086015216908301526060820152a1565b91965092508183813d8311611564575b61151b8183611266565b810103126105ad575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f693611558602060809551930161141e565b96919381939550611497565b503d611511565b505051903d90823e3d90fd5b5f9150565b9060018060a01b0391828116905f90828252602091600c8352604091670de0b6b3a76400006115b1848420546004549061134c565b04858352600d8552838320908082549255818111156116c457916115d986926116219461142f565b9889916115e88360055461142f565b600555865163a9059cbb60e01b81526001600160a01b039091166004820152602481019290925290928391908290869082906044820190565b03927f0000000000000000000000000000000000000000000000000000000000000000165af19182156116b9579161169c575b501561168c57907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe916116856116cf565b51858152a2565b5163022e258160e11b8152600490fd5b6116b39150833d851161055f576105518183611266565b5f611654565b8351903d90823e3d90fd5b509196505050505050565b6116d761129c565b60055481811161175457600854906116ef828261132b565b83811161173657509061170761170c9260065461132b565b61132b565b90808211611718575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea2646970667358221220414c83de887f7aba70f466b3b0148b72c8c1b8e43eba93c815fb2625fddf1cb564736f6c63430008140033", + "bytecode": "0x60a0346200015557601f62001a4538819003918201601f19168301916001600160401b03831184841017620001595780849260a09460405283398101031262000155576200004d816200016d565b906200005c6020820162000182565b906200006b6040820162000182565b916200007f6080606084015193016200016d565b60016009556001600160a01b03949093908516801580156200014a575b620001385763ffffffff9081831615620001265760805267ffffffff00000000600a549260201b1692169060018060401b0319161717600a55600b551660018060a01b031981815f5416175f5560015416176001556040516118b0908162000195823960805181818161038c015281816104ac0152818161071801528181611324015261170e0152f35b6040516306b7c75960e31b8152600490fd5b60405163e6c4247b60e01b8152600490fd5b50858516156200009c565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036200015557565b519063ffffffff82168203620001555756fe6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac5256146112af575081630eccc708146112755781630ed61edb146112515781631a0a253c146111865781632e1a7d4d14610e36578163372500ab14610e065781633a4b66f114610da25781634641257d14610b5e5781635873eb9b14610b245781636d86acc414610b055781636f62018514610ae65781637bfe7d5714610ac7578163817b1cd214610aa857816383810d1d14610a2e5781638ca8210814610a0f5781638da5cb5b146109e7578163992a7dfb1461097c578163a8c791471461090d578163aaf5eb68146108ea578163b13acedd1461061d578163b6b55f2514610421578163b7ec1a3314610404578163bae80594146103e0578163bbe9a070146103bb578163c28f439214610377578163c73d4d4114610315578163cab64bcd146102f6578163d5f884a1146102d7578163dacd7e0c146102b9578163e66825c314610295578163f188768414610276578163f2fde38b146101e157508063f74bcf29146101c35763fa303a5314610198575f80fd5b346101bf57816003193601126101bf5760015490516001600160a01b039091168152602090f35b5080fd5b50346101bf57816003193601126101bf576020906006549051908152f35b91905034610272576020366003190112610272576001600160a01b038235818116939084900361026e578454918216928333036102625784156102555750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b5050346101bf57816003193601126101bf57602090600b549051908152f35b5050346101bf57816003193601126101bf576020906102b26113ea565b9051908152f35b90503461027257826003193601126102725760209250549051908152f35b5050346101bf57816003193601126101bf576020906007549051908152f35b5050346101bf57816003193601126101bf576020906005549051908152f35b9190503461027257602036600319011261027257610335600f5415611436565b6001600f558254336001600160a01b0391821614159081610368575b50610262575061036190356115e9565b80600f5580f35b9050600154163314155f610351565b5050346101bf57816003193601126101bf57517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5050346101bf57816003193601126101bf5760209063ffffffff600a54169051908152f35b5050346101bf57816003193601126101bf576020906102b260065460035490611398565b5050346101bf57816003193601126101bf576020906102b2611309565b91905034610272576020928360031936011261061a578235610445600f5415611436565b6001600f55801561060b5761045933611665565b5061046960065460035490611398565b6002549081158015610603575b156105eb57505080935b84156105dd5783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156105d35784916105a6575b50156105985761053f670de0b6b3a76400009161050384600654611398565b600655338552600c885285852061051b888254611398565b905561052987600254611398565b600255338552600c8852858520549054906113b9565b04338352600d8652838320556105536117b8565b600254835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600f5551908152f35b835163be24f3c560e01b8152fd5b6105c69150873d89116105cc575b6105be81836112d3565b81019061146f565b5f6104e4565b503d6105b4565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6105f86105fd92846113b9565b6113cc565b93610480565b508015610476565b50505163162908e360e11b8152fd5b80fd5b91905034610272576020928360031936011261061a578235610641600f5415611436565b6001600f55808252600e855282822080546001600160a01b03959190861680156108da5733036108cc5760028101805460ff8160481c166108bc5767ffffffffffffffff8042169082168082106108a0575050861c60ff16156107ed575b805460ff60481b1916600160481b179055600101546008549095908087116107d1576106d56106cc611309565b6005549061149c565b8088116107b55750866106e79161149c565b600855845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af19081156105d3578491610798575b501561078a57506107576117b8565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600f5551908152f35b835163022e258160e11b8152fd5b6107af9150873d89116105cc576105be81836112d3565b5f610748565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b60018201805460075480821161088357600194939261082e88937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361149c565b60075561083e8154600854611398565b6008558560401b60ff60401b1985541617845554600754906108786008548c51938493846040919493926060820195825260208201520152565b0390a290915061069f565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b5050346101bf57816003193601126101bf5760209051670de0b6b3a76400008152f35b905034610272576020366003190112610272578254813591906001600160a01b0316330361096f5750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600354908060035582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610272576020366003190112610272578160a09360ff92358152600e602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b5050346101bf57816003193601126101bf57905490516001600160a01b039091168152602090f35b5050346101bf57816003193601126101bf576020906009549051908152f35b91905034610272576020366003190112610272576001600160a01b0382358181169391929084900361026e57828554163303610262578315610255575050600180546001600160a01b031981168417909155167f9b6cbce723aab630d07d7af8531985c84625fa96e4c7405835f8d8ca53b5bb498380a380f35b5050346101bf57816003193601126101bf576020906003549051908152f35b5050346101bf57816003193601126101bf576020906008549051908152f35b5050346101bf57816003193601126101bf576020906006549051908152f35b5050346101bf57816003193601126101bf576020906002549051908152f35b90503461027257602036600319011261027257356001600160a01b038116908190036102725782829160209452600d845220549051908152f35b8383346101bf57816003193601126101bf57610b7c600f5415611436565b6001600f558154336001600160a01b0391821614159081610d93575b50610d8557610ba5611309565b9163ffffffff600a5416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610d7b578291610d5d575b5015610d4d57610bee611309565b83811115610d4657610c00848261149c565b935b84158015610c49575b5060209550905f8051602061185b83398151915291610c286117b8565b8451908152602081019190915260408101859052606090a1600f5551908152f35b610c5586600554611398565b90816005556002549081610cc6575b5050907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f8051602061185b833981519152939260209854610cbc88519283928b846040919493926060820195825260208201520152565b0390a19091610c0b565b670de0b6b3a76400009081890291898304141715610d335791602098610d27610d207f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691945f8051602061185b8339815191529897966113cc565b8254611398565b81559850919293610c64565b634e487b7160e01b865260118952602486fd5b8193610c02565b8151630d599dd960e11b81528490fd5b610d75915060203d81116105cc576105be81836112d3565b85610be0565b83513d84823e3d90fd5b516282b42960e81b81529050fd5b90506001541633141584610b98565b8383346101bf57816003193601126101bf57610dc0600f5415611436565b6001600f558154336001600160a01b0391821614159081610df7575b50610d855760209250610ded6114a9565b91600f5551908152f35b90506001541633141584610ddc565b5050346101bf57816003193601126101bf5790602091610e28600f5415611436565b6001600f55610ded33611665565b91905034610272576020928360031936011261061a578235610e5a600f5415611436565b6001600f55801561117757610e6e33611665565b50338252600c855282822054808211801561116d575b61115d57610ea0610e97600354846113b9565b600254906113cc565b90811561114d57600a548551633991e9e560e11b8152308189019081526020810185905291891c63ffffffff16604083015260609392909167ffffffffffffffff919042831690869085908190830103818b6108005af193841561114357889089956110f0575b508581036110d457508360070b8881138015906110c9575b6110ad57505085610f2f9161149c565b338752600c8a5287872055610f468560025461149c565b600255610f558360035461149c565b600355610f6483600754611398565b600755338652600c8952670de0b6b3a7640000610f86888820548a54906113b9565b04338752600d8a5287872055610f9a6117b8565b600954975f19891461109a576001890160095587519060a0820190828210848311176110875750928a8a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea19895839b9a988e523381528d85820190888252848184019816998a8952600e8c850198828a526080860198838a52835252209160018060a01b0390511660018060a01b03198354161782555160018201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600f5551908152f35b634e487b7160e01b895260419052602488fd5b634e487b7160e01b875260119052602486fd5b6044918b918b519263158e5da560e11b84528301526024820152fd5b508184861610610f1f565b8a604491878c5192633a54e96d60e21b84528301526024820152fd5b809550878092503d831161113c575b61110981836112d3565b8101031261113857888451946111208d820161148b565b500151938460070b8503611134575f610f07565b8880fd5b8780fd5b503d6110ff565b89513d8a823e3d90fd5b845163162908e360e11b81528690fd5b50505051630e433c2360e31b8152fd5b5060025415610e84565b505051630e433c2360e31b8152fd5b9050346102725760603660031901126102725780359163ffffffff80841680940361026e576024359081169081810361124d57855460443594906001600160a01b031633036112405782156112325750600a805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600b84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b5050346101bf57816003193601126101bf576020906102b260075460085490611398565b90503461027257602036600319011261027257356001600160a01b038116908190036102725782829160209452600c845220549051908152f35b8490346101bf57816003193601126101bf5760209063ffffffff600a54831c168152f35b90601f8019910116810190811067ffffffffffffffff8211176112f557604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561138d575f9161135f575090565b906020823d8211611385575b81611378602093836112d3565b8101031261061a57505190565b3d915061136b565b6040513d5f823e3d90fd5b919082018092116113a557565b634e487b7160e01b5f52601160045260245ffd5b818102929181159184041417156113a557565b81156113d6570490565b634e487b7160e01b5f52601260045260245ffd5b60025480156114295761140260065460035490611398565b90670de0b6b3a7640000918281029281840414901517156113a557611426916113cc565b90565b50670de0b6b3a764000090565b1561143d57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312611487575180151581036114875790565b5f80fd5b519063ffffffff8216820361148757565b919082039182116113a557565b60065490600b5482106115e457600a546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af19586156115d85783809761156e575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f69391608093829761153b8460065461149c565b60065561154a84600354611398565b93846003556115576117b8565b8351958652602086015216908301526060820152a1565b91965092508183813d83116115d1575b61158881836112d3565b8101031261061a575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6936115c5602060809551930161148b565b96919381939550611504565b503d61157e565b505051903d90823e3d90fd5b5f9150565b80156116625760035480821161165057816040916116388261162e7f059c0130eec0bf9098b2fa923e100804f27098dd107ac34a8c15fc23c662f74e96600654611398565b928360065561149c565b6003556116436117b8565b82519182526020820152a1565b60405163162908e360e11b8152600490fd5b50565b9060018060a01b0391828116905f90828252602091600c8352604091670de0b6b3a764000061169a84842054600454906113b9565b04858352600d8552838320908082549255818111156117ad57916116c2869261170a9461149c565b9889916116d18360055461149c565b600555865163a9059cbb60e01b81526001600160a01b039091166004820152602481019290925290928391908290869082906044820190565b03927f0000000000000000000000000000000000000000000000000000000000000000165af19182156117a25791611785575b501561177557907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe9161176e6117b8565b51858152a2565b5163022e258160e11b8152600490fd5b61179c9150833d85116105cc576105be81836112d3565b5f61173d565b8351903d90823e3d90fd5b509196505050505050565b6117c0611309565b60055481811161183d57600854906117d88282611398565b83811161181f5750906117f06117f592600654611398565b611398565b90808211611801575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea264697066735822122054e23a886bd27cecc0b0630910bfbc27326cae87ecae43dcceaca3608ea1dc0064736f6c63430008140033", + "deployedBytecode": "0x6080604081815260049182361015610015575f80fd5b5f92833560e01c91826308ac5256146112af575081630eccc708146112755781630ed61edb146112515781631a0a253c146111865781632e1a7d4d14610e36578163372500ab14610e065781633a4b66f114610da25781634641257d14610b5e5781635873eb9b14610b245781636d86acc414610b055781636f62018514610ae65781637bfe7d5714610ac7578163817b1cd214610aa857816383810d1d14610a2e5781638ca8210814610a0f5781638da5cb5b146109e7578163992a7dfb1461097c578163a8c791471461090d578163aaf5eb68146108ea578163b13acedd1461061d578163b6b55f2514610421578163b7ec1a3314610404578163bae80594146103e0578163bbe9a070146103bb578163c28f439214610377578163c73d4d4114610315578163cab64bcd146102f6578163d5f884a1146102d7578163dacd7e0c146102b9578163e66825c314610295578163f188768414610276578163f2fde38b146101e157508063f74bcf29146101c35763fa303a5314610198575f80fd5b346101bf57816003193601126101bf5760015490516001600160a01b039091168152602090f35b5080fd5b50346101bf57816003193601126101bf576020906006549051908152f35b91905034610272576020366003190112610272576001600160a01b038235818116939084900361026e578454918216928333036102625784156102555750506001600160a01b031916821783557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b5163e6c4247b60e01b8152fd5b516282b42960e81b8152fd5b8480fd5b8280fd5b5050346101bf57816003193601126101bf57602090600b549051908152f35b5050346101bf57816003193601126101bf576020906102b26113ea565b9051908152f35b90503461027257826003193601126102725760209250549051908152f35b5050346101bf57816003193601126101bf576020906007549051908152f35b5050346101bf57816003193601126101bf576020906005549051908152f35b9190503461027257602036600319011261027257610335600f5415611436565b6001600f558254336001600160a01b0391821614159081610368575b50610262575061036190356115e9565b80600f5580f35b9050600154163314155f610351565b5050346101bf57816003193601126101bf57517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b5050346101bf57816003193601126101bf5760209063ffffffff600a54169051908152f35b5050346101bf57816003193601126101bf576020906102b260065460035490611398565b5050346101bf57816003193601126101bf576020906102b2611309565b91905034610272576020928360031936011261061a578235610445600f5415611436565b6001600f55801561060b5761045933611665565b5061046960065460035490611398565b6002549081158015610603575b156105eb57505080935b84156105dd5783516323b872dd60e01b81523382820152306024820152604481018390528681606481877f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165af19081156105d35784916105a6575b50156105985761053f670de0b6b3a76400009161050384600654611398565b600655338552600c885285852061051b888254611398565b905561052987600254611398565b600255338552600c8852858520549054906113b9565b04338352600d8652838320556105536117b8565b600254835191825260208201859052604082015233907f36af321ec8d3c75236829c5317affd40ddb308863a1236d2d277a4025cccee1e90606090a2600f5551908152f35b835163be24f3c560e01b8152fd5b6105c69150873d89116105cc575b6105be81836112d3565b81019061146f565b5f6104e4565b503d6105b4565b85513d86823e3d90fd5b8351639345f64b60e01b8152fd5b6105f86105fd92846113b9565b6113cc565b93610480565b508015610476565b50505163162908e360e11b8152fd5b80fd5b91905034610272576020928360031936011261061a578235610641600f5415611436565b6001600f55808252600e855282822080546001600160a01b03959190861680156108da5733036108cc5760028101805460ff8160481c166108bc5767ffffffffffffffff8042169082168082106108a0575050861c60ff16156107ed575b805460ff60481b1916600160481b179055600101546008549095908087116107d1576106d56106cc611309565b6005549061149c565b8088116107b55750866106e79161149c565b600855845163a9059cbb60e01b815233838201908152602081018890529091889183919082908890829060400103927f0000000000000000000000000000000000000000000000000000000000000000165af19081156105d3578491610798575b501561078a57506107576117b8565b82518481527f5b9b0bc34c7f6a61889ce3382d8697cc823f00d6e619362ae6b156bc8ee3ad46863392a3600f5551908152f35b835163022e258160e11b8152fd5b6107af9150873d89116105cc576105be81836112d3565b5f610748565b83604491898951926382b3a56560e01b84528301526024820152fd5b82604491888851926382b3a56560e01b84528301526024820152fd5b60018201805460075480821161088357600194939261082e88937fe303da04bf6b13e3562ddfe787f074bcf5855167c6667376cadc0e0d5706eeee9361149c565b60075561083e8154600854611398565b6008558560401b60ff60401b1985541617845554600754906108786008548c51938493846040919493926060820195825260208201520152565b0390a290915061069f565b88516382b3a56560e01b8152808701929092526024820152604490fd5b60449186918a5192633760603560e21b84528301526024820152fd5b86516354e19feb60e01b81528490fd5b5083516282b42960e81b8152fd5b85516341abc80160e01b81528390fd5b5050346101bf57816003193601126101bf5760209051670de0b6b3a76400008152f35b905034610272576020366003190112610272578254813591906001600160a01b0316330361096f5750907f0e6c1ecf62bc9f6c26287bb6a3404d50dd44446d71506263b3bcf5393cc8f74a91600354908060035582519182526020820152a180f35b82516282b42960e81b8152fd5b905034610272576020366003190112610272578160a09360ff92358152600e602052209181600180861b0384541693600260018201549101549283918151968752602087015267ffffffffffffffff8216818701521c161515606084015260481c1615156080820152f35b5050346101bf57816003193601126101bf57905490516001600160a01b039091168152602090f35b5050346101bf57816003193601126101bf576020906009549051908152f35b91905034610272576020366003190112610272576001600160a01b0382358181169391929084900361026e57828554163303610262578315610255575050600180546001600160a01b031981168417909155167f9b6cbce723aab630d07d7af8531985c84625fa96e4c7405835f8d8ca53b5bb498380a380f35b5050346101bf57816003193601126101bf576020906003549051908152f35b5050346101bf57816003193601126101bf576020906008549051908152f35b5050346101bf57816003193601126101bf576020906006549051908152f35b5050346101bf57816003193601126101bf576020906002549051908152f35b90503461027257602036600319011261027257356001600160a01b038116908190036102725782829160209452600d845220549051908152f35b8383346101bf57816003193601126101bf57610b7c600f5415611436565b6001600f558154336001600160a01b0391821614159081610d93575b50610d8557610ba5611309565b9163ffffffff600a5416825190632efe8a5f60e01b825230868301526024820152602081604481856108015af1908115610d7b578291610d5d575b5015610d4d57610bee611309565b83811115610d4657610c00848261149c565b935b84158015610c49575b5060209550905f8051602061185b83398151915291610c286117b8565b8451908152602081019190915260408101859052606090a1600f5551908152f35b610c5586600554611398565b90816005556002549081610cc6575b5050907f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c5926915f8051602061185b833981519152939260209854610cbc88519283928b846040919493926060820195825260208201520152565b0390a19091610c0b565b670de0b6b3a76400009081890291898304141715610d335791602098610d27610d207f4ca31b8f435df10a9cb69690e4af29947006cdd5ad35a27a2075cf262c592691945f8051602061185b8339815191529897966113cc565b8254611398565b81559850919293610c64565b634e487b7160e01b865260118952602486fd5b8193610c02565b8151630d599dd960e11b81528490fd5b610d75915060203d81116105cc576105be81836112d3565b85610be0565b83513d84823e3d90fd5b516282b42960e81b81529050fd5b90506001541633141584610b98565b8383346101bf57816003193601126101bf57610dc0600f5415611436565b6001600f558154336001600160a01b0391821614159081610df7575b50610d855760209250610ded6114a9565b91600f5551908152f35b90506001541633141584610ddc565b5050346101bf57816003193601126101bf5790602091610e28600f5415611436565b6001600f55610ded33611665565b91905034610272576020928360031936011261061a578235610e5a600f5415611436565b6001600f55801561117757610e6e33611665565b50338252600c855282822054808211801561116d575b61115d57610ea0610e97600354846113b9565b600254906113cc565b90811561114d57600a548551633991e9e560e11b8152308189019081526020810185905291891c63ffffffff16604083015260609392909167ffffffffffffffff919042831690869085908190830103818b6108005af193841561114357889089956110f0575b508581036110d457508360070b8881138015906110c9575b6110ad57505085610f2f9161149c565b338752600c8a5287872055610f468560025461149c565b600255610f558360035461149c565b600355610f6483600754611398565b600755338652600c8952670de0b6b3a7640000610f86888820548a54906113b9565b04338752600d8a5287872055610f9a6117b8565b600954975f19891461109a576001890160095587519060a0820190828210848311176110875750928a8a899460027f3310f1d43f4f9df9a267a6a9da8bd7ab75ac0e320a65fc3405d43a0ca97c5ea19895839b9a988e523381528d85820190888252848184019816998a8952600e8c850198828a526080860198838a52835252209160018060a01b0390511660018060a01b03198354161782555160018201550193511683549260ff60401b905115158d1b169160ff60481b9051151560481b169269ffffffffffffffffffff19161717179055875194855289850152868401523392a3600f5551908152f35b634e487b7160e01b895260419052602488fd5b634e487b7160e01b875260119052602486fd5b6044918b918b519263158e5da560e11b84528301526024820152fd5b508184861610610f1f565b8a604491878c5192633a54e96d60e21b84528301526024820152fd5b809550878092503d831161113c575b61110981836112d3565b8101031261113857888451946111208d820161148b565b500151938460070b8503611134575f610f07565b8880fd5b8780fd5b503d6110ff565b89513d8a823e3d90fd5b845163162908e360e11b81528690fd5b50505051630e433c2360e31b8152fd5b5060025415610e84565b505051630e433c2360e31b8152fd5b9050346102725760603660031901126102725780359163ffffffff80841680940361026e576024359081169081810361124d57855460443594906001600160a01b031633036112405782156112325750600a805467ffffffffffffffff19168617602092831b67ffffffff0000000016179055600b84905582519485528401528201527f7d10c2f08263d04ad9c37d1a4368c63e1f087bbe9d13c792e72a112cc37aef8f90606090a180f35b83516306b7c75960e31b8152fd5b83516282b42960e81b8152fd5b8580fd5b5050346101bf57816003193601126101bf576020906102b260075460085490611398565b90503461027257602036600319011261027257356001600160a01b038116908190036102725782829160209452600c845220549051908152f35b8490346101bf57816003193601126101bf5760209063ffffffff600a54831c168152f35b90601f8019910116810190811067ffffffffffffffff8211176112f557604052565b634e487b7160e01b5f52604160045260245ffd5b6040516370a0823160e01b81523060048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811561138d575f9161135f575090565b906020823d8211611385575b81611378602093836112d3565b8101031261061a57505190565b3d915061136b565b6040513d5f823e3d90fd5b919082018092116113a557565b634e487b7160e01b5f52601160045260245ffd5b818102929181159184041417156113a557565b81156113d6570490565b634e487b7160e01b5f52601260045260245ffd5b60025480156114295761140260065460035490611398565b90670de0b6b3a7640000918281029281840414901517156113a557611426916113cc565b90565b50670de0b6b3a764000090565b1561143d57565b60405162461bcd60e51b815260206004820152600a6024820152697265656e7472616e637960b01b6044820152606490fd5b90816020910312611487575180151581036114875790565b5f80fd5b519063ffffffff8216820361148757565b919082039182116113a557565b60065490600b5482106115e457600a546040805162141ed760e41b81523060048201526024810185905263ffffffff60209390931c8316604482015293915f91908186606481866108005af19586156115d85783809761156e575b5050917f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f69391608093829761153b8460065461149c565b60065561154a84600354611398565b93846003556115576117b8565b8351958652602086015216908301526060820152a1565b91965092508183813d83116115d1575b61158881836112d3565b8101031261061a575091817f4cdda2b0641e11d4d0c953327ff68eb973718a3128f576eb86e3260df1ce45f6936115c5602060809551930161148b565b96919381939550611504565b503d61157e565b505051903d90823e3d90fd5b5f9150565b80156116625760035480821161165057816040916116388261162e7f059c0130eec0bf9098b2fa923e100804f27098dd107ac34a8c15fc23c662f74e96600654611398565b928360065561149c565b6003556116436117b8565b82519182526020820152a1565b60405163162908e360e11b8152600490fd5b50565b9060018060a01b0391828116905f90828252602091600c8352604091670de0b6b3a764000061169a84842054600454906113b9565b04858352600d8552838320908082549255818111156117ad57916116c2869261170a9461149c565b9889916116d18360055461149c565b600555865163a9059cbb60e01b81526001600160a01b039091166004820152602481019290925290928391908290869082906044820190565b03927f0000000000000000000000000000000000000000000000000000000000000000165af19182156117a25791611785575b501561177557907ffc30cddea38e2bf4d6ea7d3f9ed3b6ad7f176419f4963bd81318067a4aee73fe9161176e6117b8565b51858152a2565b5163022e258160e11b8152600490fd5b61179c9150833d85116105cc576105be81836112d3565b5f61173d565b8351903d90823e3d90fd5b509196505050505050565b6117c0611309565b60055481811161183d57600854906117d88282611398565b83811161181f5750906117f06117f592600654611398565b611398565b90808211611801575050565b6044925060405191630648624b60e21b835260048301526024820152fd5b604490846040519163c53ef3b160e01b835260048301526024820152fd5b60449160405191637843b5b360e01b835260048301526024820152fdfe4ec2d4038813a7f233af1d6d09519189db3ed5bc5b823bf72f6d3144574721dea264697066735822122054e23a886bd27cecc0b0630910bfbc27326cae87ecae43dcceaca3608ea1dc0064736f6c63430008140033", "linkReferences": {}, "deployedLinkReferences": {}, "immutableReferences": { - "9": [ + "10615": [ { "length": 32, - "start": 799 + "start": 908 }, { "length": 32, - "start": 1087 + "start": 1196 }, { "length": 32, - "start": 1707 + "start": 1816 }, { "length": 32, - "start": 4791 + "start": 4900 }, { "length": 32, - "start": 5669 + "start": 5902 } ] }, "inputSourceName": "project/solidity/pool/CommunityPool.sol", - "buildInfoId": "solc-0_8_20-964f328906be1a5d90d685a6c14ba52665e8f58a" + "buildInfoId": "solc-0_8_20-73ba749b7410351eda1c49f7cccac4bc1253acac" } \ No newline at end of file diff --git a/contracts/solidity/pool/CommunityPool.sol b/contracts/solidity/pool/CommunityPool.sol index 734b2ab6..18317cd1 100644 --- a/contracts/solidity/pool/CommunityPool.sol +++ b/contracts/solidity/pool/CommunityPool.sol @@ -106,6 +106,8 @@ contract CommunityPool { uint256 maturedWithdrawReserveAfter ); event TotalStakedSynced(uint256 previousTotalStaked, uint256 newTotalStaked); + /// @dev Emitted when automation/owner credits principal from module-tracked rebalance undelegations. + event CreditStakeableFromRebalance(uint256 amount, uint256 stakeablePrincipalLedgerAfter); modifier onlyOwner() { if (msg.sender != owner) { @@ -390,6 +392,24 @@ contract CommunityPool { emit Stake(liquidBefore, delegatedAmount, uint256(validatorsCount), totalStaked); } + /// @notice Credits liquid principal from module-tracked rebalance undelegations into `stakeablePrincipalLedger`. + /// @dev Intended for poolrebalancer after staking unbond payouts land on this contract. Decrements `totalStaked` + /// by the same `amount` so `principalAssets` stays consistent when undelegation bypasses `withdraw()` (module path). + /// The caller must pass the exact aggregate `amount` for matured entries only; incorrect values break accounting. + /// Not used for user `withdraw` flows. Callable by owner or `automationCaller` (same as `stake` / `harvest`). + function creditStakeableFromRebalance(uint256 amount) external nonReentrant onlyAutomationOrOwner { + if (amount == 0) { + return; + } + if (amount > totalStaked) { + revert InvalidAmount(); + } + stakeablePrincipalLedger += amount; + totalStaked -= amount; + _assertReserveInvariant(); + emit CreditStakeableFromRebalance(amount, stakeablePrincipalLedger); + } + /// @notice Claims staking rewards to this contract's liquid balance. /// @dev Callable by owner or automation caller; does not modify `totalStaked` because rewards are liquid yield, not principal. function harvest() external nonReentrant onlyAutomationOrOwner returns (uint256 harvestedAmount) { diff --git a/contracts/solidity/pool/README.md b/contracts/solidity/pool/README.md index 84a0cee1..247569a2 100644 --- a/contracts/solidity/pool/README.md +++ b/contracts/solidity/pool/README.md @@ -159,6 +159,29 @@ Before enabling automation: blocks. - Automation and rebalance are independent best-effort steps in EndBlock. +### `creditStakeableFromRebalance` (poolrebalancer / module undelegations) + +When the **poolrebalancer** module **undelegates** the pool delegator on-chain +(in a path that does **not** go through `withdraw()`), bonded principal drops +but contract `totalStaked` would otherwise stay too high until reconciled. + +`creditStakeableFromRebalance(amount)` fixes that **after** unbonded tokens have +landed as liquid on the pool: it increases `stakeablePrincipalLedger` and +decreases `totalStaked` by the same `amount`, so `principalAssets()` stays +consistent. It enforces `amount <= totalStaked` and the usual liquid/ledger +invariants. + +**Who may call it:** `owner` or `automationCaller` (same ACL as `stake` / +`harvest`). In production, **`automationCaller`** should be the poolrebalancer +**module EVM address**; the keeper invokes this via **`CallEVM`** using that +sender. + +**EndBlock order (application):** the **staking** module completes matured +unbonding entries and pays out **before** poolrebalancer `EndBlock` runs. The +rebalancer then **`CompletePendingUndelegations`** (strict: EVM credit, then +queue delete), then best-effort **`harvest` / `stake`** automation. So the +payout is already in the pool balance when `creditStakeableFromRebalance` runs. + ## Error Model (selected) - Input/permission: `InvalidAmount`, `InvalidUnits`, `InvalidConfig`, `Unauthorized`. diff --git a/contracts/test/pool/CommunityPoolCredit.t.sol b/contracts/test/pool/CommunityPoolCredit.t.sol new file mode 100644 index 00000000..023518e6 --- /dev/null +++ b/contracts/test/pool/CommunityPoolCredit.t.sol @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: LGPL-3.0-only +pragma solidity ^0.8.20; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +import {CommunityPool} from "../../solidity/pool/CommunityPool.sol"; + +contract MockBond is ERC20 { + constructor() ERC20("Bond", "BOND") {} + + function mint(address to, uint256 value) external { + _mint(to, value); + } +} + +/// @dev Invoked by tests so `msg.sender` to `CommunityPool` is the configured `automationCaller`. +contract AutomationProxy { + function credit(CommunityPool pool, uint256 amount) external { + pool.creditStakeableFromRebalance(amount); + } +} + +contract Stranger { + function touch(CommunityPool pool, uint256 amount) external { + pool.creditStakeableFromRebalance(amount); + } +} + +/// @dev Step 1 (plan): unit tests for `creditStakeableFromRebalance` — happy path, no-op, invariant, ACL. +contract CommunityPoolCreditTest { + MockBond internal bond; + CommunityPool internal pool; + AutomationProxy internal automation; + + function setUp() public { + bond = new MockBond(); + pool = new CommunityPool(address(bond), 10, 5, 1 ether, address(this)); + automation = new AutomationProxy(); + pool.setAutomationCaller(address(automation)); + } + + function test_CreditStakeableFromRebalance_increasesLedgerWhenLiquidCovers() public { + bond.mint(address(pool), 100 ether); + pool.syncTotalStaked(100 ether); + require(pool.stakeablePrincipalLedger() == 0, "ledger0"); + pool.creditStakeableFromRebalance(60 ether); + require(pool.stakeablePrincipalLedger() == 60 ether, "ledger60"); + require(pool.totalStaked() == 40 ether, "staked40"); + } + + function test_CreditStakeableFromRebalance_ownerCanCredit() public { + bond.mint(address(pool), 50 ether); + pool.syncTotalStaked(50 ether); + pool.creditStakeableFromRebalance(50 ether); + require(pool.stakeablePrincipalLedger() == 50 ether, "ledger50"); + require(pool.totalStaked() == 0, "staked0"); + } + + function test_CreditStakeableFromRebalance_automationCallerCanCredit() public { + bond.mint(address(pool), 40 ether); + pool.syncTotalStaked(40 ether); + automation.credit(pool, 40 ether); + require(pool.stakeablePrincipalLedger() == 40 ether, "ledger40"); + } + + function test_CreditStakeableFromRebalance_zeroAmount_noop() public { + bond.mint(address(pool), 10 ether); + pool.creditStakeableFromRebalance(0); + require(pool.stakeablePrincipalLedger() == 0, "noop"); + } + + function test_CreditStakeableFromRebalance_decreasesTotalStaked_preservesPrincipalAssets() public { + bond.mint(address(pool), 100 ether); + pool.syncTotalStaked(100 ether); + uint256 beforeAssets = pool.principalAssets(); + pool.creditStakeableFromRebalance(35 ether); + require(pool.totalStaked() == 65 ether, "staked65"); + require(pool.stakeablePrincipalLedger() == 35 ether, "ledger35"); + require(pool.principalAssets() == beforeAssets, "assets"); + } + + function test_CreditStakeableFromRebalance_revertsIfAmountExceedsTotalStaked() public { + bond.mint(address(pool), 50 ether); + pool.syncTotalStaked(40 ether); + try pool.creditStakeableFromRebalance(41 ether) { + revert("expected revert totalStaked"); + } catch (bytes memory err) { + require(err.length >= 4, "short err"); + bytes4 sel; + assembly { + sel := mload(add(err, 0x20)) + } + require(sel == CommunityPool.InvalidAmount.selector, "wrong err"); + } + } + + function test_CreditStakeableFromRebalance_revertsIfExceedsLiquidInvariant() public { + bond.mint(address(pool), 10 ether); + pool.syncTotalStaked(20 ether); + // Must be called as owner (this test contract); a Stranger would hit `Unauthorized` first. + try pool.creditStakeableFromRebalance(11 ether) { + revert("expected revert invariant"); + } catch (bytes memory err) { + require(err.length >= 4, "short err"); + bytes4 sel; + assembly { + sel := mload(add(err, 0x20)) + } + require( + sel == CommunityPool.StakeablePrincipalInvariantViolation.selector, + "wrong err" + ); + } + } + + function test_CreditStakeableFromRebalance_revertsUnauthorized() public { + bond.mint(address(pool), 10 ether); + pool.syncTotalStaked(5 ether); + Stranger s = new Stranger(); + try s.touch(pool, 1 ether) { + revert("expected revert auth"); + } catch (bytes memory err) { + require(err.length >= 4, "short err"); + bytes4 sel; + assembly { + sel := mload(add(err, 0x20)) + } + require(sel == CommunityPool.Unauthorized.selector, "wrong err"); + } + } +} diff --git a/tests/integration/precompiles/communitypool/test_integration.go b/tests/integration/precompiles/communitypool/test_integration.go index bdc82978..a8cf0486 100644 --- a/tests/integration/precompiles/communitypool/test_integration.go +++ b/tests/integration/precompiles/communitypool/test_integration.go @@ -3,6 +3,7 @@ package communitypool import ( "math/big" "testing" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" @@ -20,6 +21,8 @@ import ( poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" evmtypes "github.com/cosmos/evm/x/vm/types" + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/runtime" sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -745,6 +748,96 @@ func TestCommunityPoolIntegrationSuite(t *testing.T, create network.CreateEvmApp Expect(afterStaked.Cmp(beforeStaked)).To(BeNumerically(">", 0)) }) + It("credits ledger and restores principal NAV after a module-tracked undelegation matures (app EndBlock)", func() { + ctx := s.network.GetContext() + sk := s.network.App.GetStakingKeeper() + sp, err := sk.GetParams(ctx) + Expect(err).To(BeNil()) + sp.UnbondingTime = 30 * time.Second + Expect(sk.SetParams(ctx, sp)).To(BeNil()) + Expect(s.network.NextBlock()).To(BeNil()) + + poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) + owner := s.keyring.GetKey(0) + depositor := s.keyring.GetKey(1) + depositAmount := big.NewInt(10_000) + + s.approveBondToken(1, poolAddr, depositAmount) + s.execTxExpectSuccess( + depositor.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "deposit", depositAmount), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + s.execTxExpectSuccess( + owner.Priv, + buildTxArgs(poolAddr), + buildCallArgs(s.communityPoolContract, "setAutomationCaller", poolrebalancertypes.ModuleEVMAddress), + ) + Expect(s.network.NextBlock()).To(BeNil()) + + ctx = s.network.GetContext() + moduleAcc := sdk.AccAddress(poolrebalancertypes.ModuleEVMAddress.Bytes()) + accountKeeper := s.network.App.GetAccountKeeper() + if accountKeeper.GetAccount(ctx, moduleAcc) == nil { + accountKeeper.SetAccount(ctx, accountKeeper.NewAccountWithAddress(ctx, moduleAcc)) + } + + storeService := runtime.NewKVStoreService(s.network.App.GetKey(poolrebalancertypes.StoreKey)) + rebalancerKeeper := poolrebalancerkeeper.NewKeeper( + s.network.App.AppCodec(), + storeService, + s.network.App.GetStakingKeeper(), + authtypes.NewModuleAddress(govtypes.ModuleName), + s.network.App.GetEVMKeeper(), + s.network.App.GetAccountKeeper(), + ) + + params := poolrebalancertypes.DefaultParams() + params.PoolDelegatorAddress = sdk.AccAddress(poolAddr.Bytes()).String() + Expect(rebalancerKeeper.SetParams(ctx, params)).To(BeNil()) + + Expect(poolrebalancer.EndBlocker(ctx, rebalancerKeeper)).To(BeNil()) + + stakedAfterStake := s.queryPoolUint(0, poolAddr, "totalStaked") + Expect(stakedAfterStake.Sign()).To(BeNumerically(">", 0)) + principalAfterStake := s.queryPoolUint(0, poolAddr, "principalAssets") + Expect(principalAfterStake.Cmp(stakedAfterStake)).To(Equal(0)) + + poolDel := sdk.AccAddress(poolAddr.Bytes()) + vals := s.network.GetValidators() + Expect(vals).ToNot(BeEmpty()) + valAddr, vErr := sdk.ValAddressFromBech32(vals[0].OperatorAddress) + Expect(vErr).To(BeNil()) + + bonded, bErr := sk.GetDelegatorBonded(ctx, poolDel) + Expect(bErr).To(BeNil()) + Expect(bonded.IsPositive()).To(BeTrue()) + undelegAmt := bonded.Quo(sdkmath.NewInt(5)) + if undelegAmt.IsZero() { + undelegAmt = sdkmath.NewInt(1) + } + undelegCoin := sdk.NewCoin(s.bondDenom, undelegAmt) + + goCtx := sdk.WrapSDKContext(ctx) + _, amountUB, uErr := rebalancerKeeper.BeginTrackedUndelegation(goCtx, poolDel, valAddr, undelegCoin) + Expect(uErr).To(BeNil()) + Expect(amountUB.IsPositive()).To(BeTrue()) + + Expect(s.network.NextBlock()).To(BeNil()) + + Expect(s.network.NextBlockAfter(40 * time.Second)).To(BeNil()) + + principalAfterMaturity := s.queryPoolUint(0, poolAddr, "principalAssets") + Expect(principalAfterMaturity.Cmp(principalAfterStake)).To(Equal(0)) + + ledger := s.queryPoolUint(0, poolAddr, "stakeablePrincipalLedger") + stakedNow := s.queryPoolUint(0, poolAddr, "totalStaked") + sum := new(big.Int).Add(new(big.Int).Set(ledger), stakedNow) + Expect(sum.Cmp(stakedAfterStake)).To(Equal(0)) + }) + It("reverts dust deposit that would mint zero units", func() { poolAddr := s.deployCommunityPool(0, 10, 5, big.NewInt(1)) owner := s.keyring.GetKey(0) diff --git a/x/poolrebalancer/abci.go b/x/poolrebalancer/abci.go index c90d3f01..5b461097 100644 --- a/x/poolrebalancer/abci.go +++ b/x/poolrebalancer/abci.go @@ -7,11 +7,14 @@ import ( ) // EndBlocker runs at end of block: -// 1) strict cleanup of matured pending entries, -// 2) best-effort CommunityPool automation (harvest/stake), -// 3) best-effort staking rebalance. +// 1) Strict cleanup of matured pending redelegations and undelegations. For matured module-tracked +// undelegations matching PoolDelegatorAddress and bond denom, CompletePendingUndelegations calls +// CommunityPool.creditStakeableFromRebalance (EVM) before removing queue entries so stakeablePrincipalLedger +// can be delegated on the next step; staking EndBlock has already released liquid tokens to the delegator. +// 2) Best-effort CommunityPool automation (harvest, then stake). +// 3) Best-effort staking rebalance. func EndBlocker(ctx sdk.Context, k keeper.Keeper) error { - // Keep cleanup strict to avoid queue/index drift from staking state. + // Keep cleanup strict to avoid queue/index drift from staking state and to avoid dropping creditable amounts. if err := k.CompletePendingRedelegations(ctx); err != nil { ctx.Logger().Error("poolrebalancer: complete pending redelegations failed", "err", err) return err diff --git a/x/poolrebalancer/abci_test.go b/x/poolrebalancer/abci_test.go index 786efae0..9518d518 100644 --- a/x/poolrebalancer/abci_test.go +++ b/x/poolrebalancer/abci_test.go @@ -2,23 +2,26 @@ package poolrebalancer import ( "bytes" + "context" + "errors" "testing" "time" storetypes "cosmossdk.io/store/types" + "cosmossdk.io/math" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/evm/x/poolrebalancer/keeper" "github.com/cosmos/evm/x/poolrebalancer/types" ) -func newEndBlockerTestKeeper(t *testing.T) (sdk.Context, keeper.Keeper, *storetypes.KVStoreKey) { +func newEndBlockerTestKeeper(t *testing.T, sk types.StakingKeeper) (sdk.Context, keeper.Keeper, *storetypes.KVStoreKey) { t.Helper() storeKey := storetypes.NewKVStoreKey(types.ModuleName) @@ -27,27 +30,70 @@ func newEndBlockerTestKeeper(t *testing.T) (sdk.Context, keeper.Keeper, *storety storeService := runtime.NewKVStoreService(storeKey) cdc := moduletestutil.MakeTestEncodingConfig().Codec - stakingKeeper := &stakingkeeper.Keeper{} // zero value; tests avoid staking calls authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := keeper.NewKeeper(cdc, storeService, stakingKeeper, authority, nil, nil) + k := keeper.NewKeeper(cdc, storeService, sk, authority, nil, nil) return ctx, k, storeKey } -func TestEndBlocker_OperationalErrorIsNonHalting(t *testing.T) { - ctx, k, storeKey := newEndBlockerTestKeeper(t) +// stakingKeeperOpError implements types.StakingKeeper for EndBlocker tests; fails GetBondedValidatorsByPower. +type stakingKeeperOpError struct{} - // Inject malformed params directly to force an operational module error - // (GetParams unmarshal failure) while keeping cleanup paths healthy. - // This now first impacts community pool automation lookup in EndBlock. +func (stakingKeeperOpError) GetBondedValidatorsByPower(ctx context.Context) ([]stakingtypes.Validator, error) { + return nil, errors.New("mock staking operational error") +} + +func (stakingKeeperOpError) GetDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) ([]stakingtypes.Delegation, error) { + return nil, nil +} + +func (stakingKeeperOpError) GetValidator(ctx context.Context, addr sdk.ValAddress) (stakingtypes.Validator, error) { + return stakingtypes.Validator{}, errors.New("validator not found") +} + +func (stakingKeeperOpError) GetDelegation(ctx context.Context, delegatorAddr sdk.AccAddress, valAddr sdk.ValAddress) (stakingtypes.Delegation, error) { + return stakingtypes.Delegation{}, errors.New("delegation not found") +} + +func (stakingKeeperOpError) BeginRedelegation(ctx context.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount math.LegacyDec) (time.Time, error) { + return time.Time{}, errors.New("not implemented") +} + +func (stakingKeeperOpError) Undelegate(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount math.LegacyDec) (time.Time, math.Int, error) { + return time.Time{}, math.ZeroInt(), errors.New("not implemented") +} + +func (stakingKeeperOpError) UnbondingTime(ctx context.Context) (time.Duration, error) { + return time.Hour, nil +} + +func (stakingKeeperOpError) BondDenom(ctx context.Context) (string, error) { + return "stake", nil +} + +func TestEndBlocker_ProcessRebalanceErrorIsNonHalting(t *testing.T) { + ctx, k, _ := newEndBlockerTestKeeper(t, stakingKeeperOpError{}) + + params := types.DefaultParams() + params.PoolDelegatorAddress = sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String() + require.NoError(t, k.SetParams(ctx, params)) + + err := EndBlocker(ctx, k) + require.NoError(t, err, "ProcessRebalance failures should not halt EndBlocker") +} + +func TestEndBlocker_InvalidParamsHaltsOnCleanup(t *testing.T) { + ctx, k, storeKey := newEndBlockerTestKeeper(t, stakingKeeperOpError{}) + + // CompletePendingUndelegations loads params before harvest/stake; invalid proto must halt EndBlock. ctx.KVStore(storeKey).Set(types.ParamsKey, []byte("not-a-valid-proto")) err := EndBlocker(ctx, k) - require.NoError(t, err, "operational errors should not halt EndBlocker") + require.Error(t, err, "params corruption should halt during pending undelegation completion") } func TestEndBlocker_CleanupErrorRemainsHalting(t *testing.T) { - ctx, k, storeKey := newEndBlockerTestKeeper(t) + ctx, k, storeKey := newEndBlockerTestKeeper(t, stakingKeeperOpError{}) now := time.Now().UTC() ctx = ctx.WithBlockTime(now) @@ -58,4 +104,3 @@ func TestEndBlocker_CleanupErrorRemainsHalting(t *testing.T) { err := EndBlocker(ctx, k) require.Error(t, err, "cleanup failures should remain halting") } - diff --git a/x/poolrebalancer/keeper/community_pool.go b/x/poolrebalancer/keeper/community_pool.go index ed1fff69..c0b4d079 100644 --- a/x/poolrebalancer/keeper/community_pool.go +++ b/x/poolrebalancer/keeper/community_pool.go @@ -1,13 +1,56 @@ package keeper import ( + "errors" + "fmt" + "github.com/ethereum/go-ethereum/common" + evmtypes "github.com/cosmos/evm/x/vm/types" + "github.com/cosmos/evm/x/poolrebalancer/types" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" ) +// ensurePoolRebalancerModuleEVMAccount materializes the module account used as tx sender for CallEVM. +func (k Keeper) ensurePoolRebalancerModuleEVMAccount(ctx sdk.Context) { + if k.accountKeeper == nil { + return + } + moduleAcc := sdk.AccAddress(types.ModuleEVMAddress.Bytes()) + if k.accountKeeper.GetAccount(ctx, moduleAcc) == nil { + k.accountKeeper.SetAccount(ctx, k.accountKeeper.NewAccountWithAddress(ctx, moduleAcc)) + } +} + +// callCommunityPoolEVM invokes a CommunityPool method using the minimal embedded ABI (commit=true). +func (k Keeper) callCommunityPoolEVM(ctx sdk.Context, poolDel sdk.AccAddress, method string, args ...any) (*evmtypes.MsgEthereumTxResponse, error) { + if k.evmKeeper == nil { + return nil, errors.New("evm keeper is nil") + } + k.ensurePoolRebalancerModuleEVMAccount(ctx) + poolContract := common.BytesToAddress(poolDel.Bytes()) + return k.evmKeeper.CallEVM(ctx, types.CommunityPoolABI, types.ModuleEVMAddress, poolContract, true, nil, method, args...) +} + +// creditCommunityPoolStakeableFromRebalance calls CommunityPool.creditStakeableFromRebalance(amount). +func (k Keeper) creditCommunityPoolStakeableFromRebalance(ctx sdk.Context, poolDel sdk.AccAddress, amount math.Int) error { + if !amount.IsPositive() { + return nil + } + res, err := k.callCommunityPoolEVM(ctx, poolDel, "creditStakeableFromRebalance", amount.BigInt()) + if err != nil { + return fmt.Errorf("creditStakeableFromRebalance: %w", err) + } + if res != nil && res.Failed() { + return fmt.Errorf("creditStakeableFromRebalance vm error: %s", res.VmError) + } + return nil +} + // MaybeRunCommunityPoolAutomation best-effort executes CommunityPool harvest/stake. // Assumptions: // - pool params PoolDelegatorAddress points to the CommunityPool contract account, @@ -22,25 +65,14 @@ func (k Keeper) MaybeRunCommunityPoolAutomation(ctx sdk.Context) error { return nil } - poolContract := common.BytesToAddress(del.Bytes()) - from := types.ModuleEVMAddress - // Ensure caller account exists so vm.CallEVM can resolve sequence/nonce. - // Some chains materialize module accounts lazily; CallEVM requires address-based lookup. - if k.accountKeeper != nil { - moduleAcc := sdk.AccAddress(from.Bytes()) - if k.accountKeeper.GetAccount(ctx, moduleAcc) == nil { - k.accountKeeper.SetAccount(ctx, k.accountKeeper.NewAccountWithAddress(ctx, moduleAcc)) - } - } - for _, method := range []string{"harvest", "stake"} { - res, callErr := k.evmKeeper.CallEVM(ctx, types.CommunityPoolABI, from, poolContract, true, nil, method) + res, callErr := k.callCommunityPoolEVM(ctx, del, method) if callErr != nil { - ctx.Logger().Error("poolrebalancer: community pool automation call failed", "method", method, "contract", poolContract.Hex(), "err", callErr) + ctx.Logger().Error("poolrebalancer: community pool automation call failed", "method", method, "contract", common.BytesToAddress(del.Bytes()).Hex(), "err", callErr) continue } if res != nil && res.Failed() { - ctx.Logger().Error("poolrebalancer: community pool automation vm failed", "method", method, "contract", poolContract.Hex(), "vm_error", res.VmError) + ctx.Logger().Error("poolrebalancer: community pool automation vm failed", "method", method, "contract", common.BytesToAddress(del.Bytes()).Hex(), "vm_error", res.VmError) } } diff --git a/x/poolrebalancer/keeper/community_pool_test.go b/x/poolrebalancer/keeper/community_pool_test.go index 969f29e3..c31b416d 100644 --- a/x/poolrebalancer/keeper/community_pool_test.go +++ b/x/poolrebalancer/keeper/community_pool_test.go @@ -20,8 +20,10 @@ type mockEVMKeeper struct { methods []string froms []common.Address contracts []common.Address + args [][]any errByMethod map[string]error + failedVM map[string]string // method -> VmError (non-empty => Failed()) } func (m *mockEVMKeeper) CallEVM( @@ -36,10 +38,15 @@ func (m *mockEVMKeeper) CallEVM( m.methods = append(m.methods, method) m.froms = append(m.froms, from) m.contracts = append(m.contracts, contract) + m.args = append(m.args, append([]any(nil), args...)) if err, ok := m.errByMethod[method]; ok { return nil, err } - return &evmtypes.MsgEthereumTxResponse{}, nil + vmErr := "" + if m.failedVM != nil { + vmErr = m.failedVM[method] + } + return &evmtypes.MsgEthereumTxResponse{VmError: vmErr}, nil } func TestMaybeRunCommunityPoolAutomation_SkipsWhenPoolDelegatorUnset(t *testing.T) { diff --git a/x/poolrebalancer/keeper/test_helpers_test.go b/x/poolrebalancer/keeper/test_helpers_test.go index 5cd186a7..f07b9e34 100644 --- a/x/poolrebalancer/keeper/test_helpers_test.go +++ b/x/poolrebalancer/keeper/test_helpers_test.go @@ -10,7 +10,6 @@ import ( "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" - stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/evm/x/poolrebalancer/types" ) @@ -24,7 +23,7 @@ func newTestKeeper(t *testing.T) (sdk.Context, Keeper) { storeService := runtime.NewKVStoreService(storeKey) cdc := moduletestutil.MakeTestEncodingConfig().Codec - stakingKeeper := &stakingkeeper.Keeper{} // zero value; do not call staking methods in unit tests + stakingKeeper := &mockStakingKeeper{} authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) k := NewKeeper(cdc, storeService, stakingKeeper, authority, nil, nil) diff --git a/x/poolrebalancer/keeper/undelegation.go b/x/poolrebalancer/keeper/undelegation.go index 9c705d0e..b4297e0d 100644 --- a/x/poolrebalancer/keeper/undelegation.go +++ b/x/poolrebalancer/keeper/undelegation.go @@ -105,38 +105,92 @@ func (k Keeper) BeginTrackedUndelegation(ctx context.Context, del sdk.AccAddress return completionTime, amountUnbonded, nil } -// CompletePendingUndelegations deletes matured pending undelegation queue and index entries. -// The staking module handles actual token payout to the delegator; we only clean up our tracking state. +// maturedUndelegationBatch is a snapshot of one queue key and its unmarshaled entries. +type maturedUndelegationBatch struct { + queueKey []byte + completionTime time.Time + queued types.QueuedUndelegation +} + +// CompletePendingUndelegations credits CommunityPool stakeable principal for matured module-tracked +// undelegations, then deletes queue and index entries. The EVM call also reduces CommunityPool.totalStaked +// by the credited amount so principal NAV matches module undelegations that bypass withdraw(). +// Credit runs before deletes so a failed EVM call retains queue state for retry. The staking module pays +// out liquid tokens before this runs (staking EndBlock). func (k Keeper) CompletePendingUndelegations(ctx context.Context) error { sdkCtx := sdk.UnwrapSDKContext(ctx) blockTime := sdkCtx.BlockTime() - completed := 0 coreStore := k.storeService.OpenKVStore(ctx) iterStore := runtime.KVStoreAdapter(coreStore) - // Iterate all queue entries with completionTime <= blockTime. start := types.PendingUndelegationQueueKey end := types.GetPendingUndelegationQueueKeyByTime(blockTime) endExclusive := append(append([]byte{}, end...), 0xFF) iter := iterStore.Iterator(start, endExclusive) - defer iter.Close() //nolint:errcheck - + var batches []maturedUndelegationBatch for ; iter.Valid(); iter.Next() { - key := iter.Key() + key := append([]byte(nil), iter.Key()...) completionTime, err := types.ParsePendingUndelegationQueueKeyForCompletionTime(key) if err != nil { + iter.Close() //nolint:errcheck return err } var queued types.QueuedUndelegation if err := k.cdc.Unmarshal(iter.Value(), &queued); err != nil { + iter.Close() //nolint:errcheck return err } + batches = append(batches, maturedUndelegationBatch{ + queueKey: key, + completionTime: completionTime, + queued: queued, + }) + } + iter.Close() //nolint:errcheck + + poolDel, err := k.GetPoolDelegatorAddress(ctx) + if err != nil { + return err + } + + var bondDenom string + if !poolDel.Empty() { + bondDenom, err = k.stakingKeeper.BondDenom(ctx) + if err != nil { + return fmt.Errorf("bond denom: %w", err) + } + } - // Delete by-validator index entries for each queued undelegation entry. - for _, entry := range queued.Entries { + creditSum := math.ZeroInt() + if !poolDel.Empty() { + poolBech := poolDel.String() + for _, b := range batches { + for _, e := range b.queued.Entries { + if e.DelegatorAddress == poolBech && e.Balance.Denom == bondDenom { + creditSum = creditSum.Add(e.Balance.Amount) + } + } + } + } + + if creditSum.IsPositive() { + if k.evmKeeper == nil { + return fmt.Errorf("poolrebalancer: matured pool undelegations %s require evm keeper", creditSum) + } + if poolDel.Empty() { + return fmt.Errorf("poolrebalancer: matured pool undelegations %s require PoolDelegatorAddress", creditSum) + } + if err := k.creditCommunityPoolStakeableFromRebalance(sdkCtx, poolDel, creditSum); err != nil { + return err + } + } + + completed := 0 + for _, b := range batches { + for _, entry := range b.queued.Entries { delAddr, err := sdk.AccAddressFromBech32(entry.DelegatorAddress) if err != nil { return err @@ -145,15 +199,13 @@ func (k Keeper) CompletePendingUndelegations(ctx context.Context) error { if err != nil { return err } - indexKey := types.GetPendingUndelegationByValIndexKey(valAddr, completionTime, entry.Balance.Denom, delAddr) + indexKey := types.GetPendingUndelegationByValIndexKey(valAddr, b.completionTime, entry.Balance.Denom, delAddr) if err := coreStore.Delete(indexKey); err != nil { return err } completed++ } - - // Delete the queue key itself. - iterStore.Delete(key) + iterStore.Delete(b.queueKey) } if completed > 0 { diff --git a/x/poolrebalancer/keeper/undelegation_test.go b/x/poolrebalancer/keeper/undelegation_test.go index d12fcb13..2b5cbc49 100644 --- a/x/poolrebalancer/keeper/undelegation_test.go +++ b/x/poolrebalancer/keeper/undelegation_test.go @@ -2,6 +2,7 @@ package keeper import ( "bytes" + "math/big" "testing" "time" @@ -52,3 +53,141 @@ func TestCompletePendingUndelegations_RemovesQueueAndIndex(t *testing.T) { // Idempotency. require.NoError(t, k.CompletePendingUndelegations(ctx)) } + +func TestCompletePendingUndelegations_CreditsPoolBeforeDelete(t *testing.T) { + ctx, k := newTestKeeper(t) + mockEVM := &mockEVMKeeper{} + k.evmKeeper = mockEVM + + poolDel := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + params := types.DefaultParams() + params.PoolDelegatorAddress = poolDel.String() + require.NoError(t, k.SetParams(ctx, params)) + + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + val := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + completion := ctx.BlockTime().Add(-time.Second) + coin := sdk.NewCoin("stake", math.NewInt(123)) + entry := types.PendingUndelegation{ + DelegatorAddress: poolDel.String(), + ValidatorAddress: val.String(), + Balance: coin, + CompletionTime: completion, + } + require.NoError(t, k.SetPendingUndelegation(ctx, entry)) + + require.NoError(t, k.CompletePendingUndelegations(ctx)) + + require.Equal(t, []string{"creditStakeableFromRebalance"}, mockEVM.methods) + require.Len(t, mockEVM.args, 1) + amount, ok := mockEVM.args[0][0].(*big.Int) + require.True(t, ok) + require.Equal(t, "123", amount.String()) + + store := k.storeService.OpenKVStore(ctx) + queueKey := types.GetPendingUndelegationQueueKey(completion, poolDel) + bz, err := store.Get(queueKey) + require.NoError(t, err) + require.Nil(t, bz) +} + +func TestCompletePendingUndelegations_RetainsQueueOnCreditVMFailure(t *testing.T) { + ctx, k := newTestKeeper(t) + mockEVM := &mockEVMKeeper{ + failedVM: map[string]string{ + "creditStakeableFromRebalance": "execution reverted", + }, + } + k.evmKeeper = mockEVM + + poolDel := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + params := types.DefaultParams() + params.PoolDelegatorAddress = poolDel.String() + require.NoError(t, k.SetParams(ctx, params)) + + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + val := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + completion := ctx.BlockTime().Add(-time.Second) + coin := sdk.NewCoin("stake", math.NewInt(50)) + entry := types.PendingUndelegation{ + DelegatorAddress: poolDel.String(), + ValidatorAddress: val.String(), + Balance: coin, + CompletionTime: completion, + } + require.NoError(t, k.SetPendingUndelegation(ctx, entry)) + + err := k.CompletePendingUndelegations(ctx) + require.Error(t, err) + + store := k.storeService.OpenKVStore(ctx) + queueKey := types.GetPendingUndelegationQueueKey(completion, poolDel) + bz, err := store.Get(queueKey) + require.NoError(t, err) + require.NotNil(t, bz) +} + +func TestCompletePendingUndelegations_SumsOnlyPoolDelegatorBondDenom(t *testing.T) { + ctx, k := newTestKeeper(t) + mockEVM := &mockEVMKeeper{} + k.evmKeeper = mockEVM + + poolDel := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + otherDel := sdk.AccAddress(bytes.Repeat([]byte{3}, 20)) + params := types.DefaultParams() + params.PoolDelegatorAddress = poolDel.String() + require.NoError(t, k.SetParams(ctx, params)) + + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + val := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + completionA := ctx.BlockTime().Add(-2 * time.Second) + completionB := ctx.BlockTime().Add(-time.Second) + + require.NoError(t, k.SetPendingUndelegation(ctx, types.PendingUndelegation{ + DelegatorAddress: poolDel.String(), + ValidatorAddress: val.String(), + Balance: sdk.NewCoin("stake", math.NewInt(40)), + CompletionTime: completionA, + })) + require.NoError(t, k.SetPendingUndelegation(ctx, types.PendingUndelegation{ + DelegatorAddress: otherDel.String(), + ValidatorAddress: val.String(), + Balance: sdk.NewCoin("stake", math.NewInt(999)), + CompletionTime: completionB, + })) + require.NoError(t, k.SetPendingUndelegation(ctx, types.PendingUndelegation{ + DelegatorAddress: poolDel.String(), + ValidatorAddress: val.String(), + Balance: sdk.NewCoin("otherdenom", math.NewInt(777)), + CompletionTime: completionB, + })) + + require.NoError(t, k.CompletePendingUndelegations(ctx)) + + require.Equal(t, []string{"creditStakeableFromRebalance"}, mockEVM.methods) + amount, ok := mockEVM.args[0][0].(*big.Int) + require.True(t, ok) + require.Equal(t, "40", amount.String()) +} + +func TestCompletePendingUndelegations_ErrWhenPoolCreditRequiresEVMButNil(t *testing.T) { + ctx, k := newTestKeeper(t) + + poolDel := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) + params := types.DefaultParams() + params.PoolDelegatorAddress = poolDel.String() + require.NoError(t, k.SetParams(ctx, params)) + + ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) + val := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) + completion := ctx.BlockTime().Add(-time.Second) + require.NoError(t, k.SetPendingUndelegation(ctx, types.PendingUndelegation{ + DelegatorAddress: poolDel.String(), + ValidatorAddress: val.String(), + Balance: sdk.NewCoin("stake", math.NewInt(1)), + CompletionTime: completion, + })) + + err := k.CompletePendingUndelegations(ctx) + require.Error(t, err) +} diff --git a/x/poolrebalancer/types/communitypool_abi.json b/x/poolrebalancer/types/communitypool_abi.json index f57dfd14..850aa540 100644 --- a/x/poolrebalancer/types/communitypool_abi.json +++ b/x/poolrebalancer/types/communitypool_abi.json @@ -24,5 +24,18 @@ ], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "creditStakeableFromRebalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ] diff --git a/x/poolrebalancer/types/communitypool_abi_test.go b/x/poolrebalancer/types/communitypool_abi_test.go index dd924a9a..999aa519 100644 --- a/x/poolrebalancer/types/communitypool_abi_test.go +++ b/x/poolrebalancer/types/communitypool_abi_test.go @@ -14,5 +14,10 @@ func TestCommunityPoolABI_MethodsPresent(t *testing.T) { harvestMethod, ok := CommunityPoolABI.Methods["harvest"] require.True(t, ok) require.Empty(t, harvestMethod.Inputs) + + creditMethod, ok := CommunityPoolABI.Methods["creditStakeableFromRebalance"] + require.True(t, ok) + require.Len(t, creditMethod.Inputs, 1) + require.Equal(t, "uint256", creditMethod.Inputs[0].Type.String()) } From 57746da9518b9189abfa9e2b7b30912d8854481b Mon Sep 17 00:00:00 2001 From: Nikhil Sharma Date: Fri, 3 Apr 2026 20:48:49 +0530 Subject: [PATCH 31/31] feat(poolrebalancer): validate pool_delegator_address on SetParams with EVM contract checks Signed-off-by: Nikhil Sharma --- .../x/poolrebalancer/stub_evm_keeper.go | 37 ++++++ .../x/poolrebalancer/test_suite.go | 10 +- x/poolrebalancer/abci_test.go | 23 +++- .../keeper/community_pool_test.go | 22 +++- x/poolrebalancer/keeper/grpc_query_test.go | 10 +- x/poolrebalancer/keeper/msg_server_test.go | 115 +++++++++++++++++- x/poolrebalancer/keeper/params.go | 3 + x/poolrebalancer/keeper/pool_delegator.go | 54 ++++++++ .../keeper/rebalance_events_test.go | 4 +- .../keeper/rebalance_process_test.go | 2 +- x/poolrebalancer/keeper/redelegation_test.go | 6 +- x/poolrebalancer/keeper/test_helpers_test.go | 49 +++++++- x/poolrebalancer/keeper/undelegation_test.go | 13 +- x/poolrebalancer/types/helpers.go | 7 +- x/poolrebalancer/types/helpers_test.go | 11 ++ x/poolrebalancer/types/interfaces.go | 2 + 16 files changed, 335 insertions(+), 33 deletions(-) create mode 100644 tests/integration/x/poolrebalancer/stub_evm_keeper.go create mode 100644 x/poolrebalancer/keeper/pool_delegator.go diff --git a/tests/integration/x/poolrebalancer/stub_evm_keeper.go b/tests/integration/x/poolrebalancer/stub_evm_keeper.go new file mode 100644 index 00000000..a3c4213f --- /dev/null +++ b/tests/integration/x/poolrebalancer/stub_evm_keeper.go @@ -0,0 +1,37 @@ +package poolrebalancer + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + + poolrebalancertypes "github.com/cosmos/evm/x/poolrebalancer/types" + evmtypes "github.com/cosmos/evm/x/vm/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// rebalanceIntegrationStubEVM implements poolrebalancertypes.EVMKeeper for this package only. +// Used with a nil account keeper in test_suite so a prefunded keyring delegator can be the pool +// address without failing the user-pubkey check. These tests target rebalance scheduling, queues, +// and staking—not CommunityPool calldata or real VM execution (see precompiles/communitypool). +type rebalanceIntegrationStubEVM struct{} + +func (rebalanceIntegrationStubEVM) CallEVM( + _ sdk.Context, + _ abi.ABI, + _, _ common.Address, + _ bool, + _ *big.Int, + _ string, + _ ...any, +) (*evmtypes.MsgEthereumTxResponse, error) { + return &evmtypes.MsgEthereumTxResponse{}, nil +} + +func (rebalanceIntegrationStubEVM) IsContract(sdk.Context, common.Address) bool { + return true +} + +var _ poolrebalancertypes.EVMKeeper = rebalanceIntegrationStubEVM{} diff --git a/tests/integration/x/poolrebalancer/test_suite.go b/tests/integration/x/poolrebalancer/test_suite.go index 2cf32cd8..8835c7b0 100644 --- a/tests/integration/x/poolrebalancer/test_suite.go +++ b/tests/integration/x/poolrebalancer/test_suite.go @@ -78,20 +78,22 @@ func (s *KeeperIntegrationTestSuite) configureStakingParamsForTests() { s.Require().NoError(sk.SetParams(s.ctx, sp)) } -// configurePoolKeeper builds a keeper bound to the same stores as the app under test. +// configurePoolKeeper builds a keeper bound to the same module KV stores as the app under test. func (s *KeeperIntegrationTestSuite) configurePoolKeeper() { - // This keeper shares module KV stores with the app; no mocked state. poolKey := s.network.App.GetKey(poolrebalancertypes.StoreKey) storeService := runtime.NewKVStoreService(poolKey) authority := authtypes.NewModuleAddress(govtypes.ModuleName) + // nil account keeper: avoid rejecting the prefunded keyring account (pubkey) in + // validatePoolDelegatorAddress. Stub EVM reports IsContract true so params still match the + // "non-empty pool needs EVM attestation" path without CommunityPool deploy. s.poolKeeper = poolrebalancerkeeper.NewKeeper( s.network.App.AppCodec(), storeService, s.network.App.GetStakingKeeper(), authority, + rebalanceIntegrationStubEVM{}, nil, - s.network.App.GetAccountKeeper(), ) } @@ -107,7 +109,7 @@ func (s *KeeperIntegrationTestSuite) captureBaselineInfo() { // UnitTestNetwork seeds delegations for the first test account; use it as pool delegator. s.poolDel = s.keyring.GetAccAddr(0) - // Guard rail: no stake means rebalancer has nothing to do. + // No stake would make rebalance tests vacuous. _, total, err := s.poolKeeper.GetDelegatorStakeByValidator(s.ctx, s.poolDel) s.Require().NoError(err) s.Require().True(total.IsPositive(), "expected pool delegator stake to be > 0") diff --git a/x/poolrebalancer/abci_test.go b/x/poolrebalancer/abci_test.go index 9518d518..67984cf5 100644 --- a/x/poolrebalancer/abci_test.go +++ b/x/poolrebalancer/abci_test.go @@ -4,11 +4,14 @@ import ( "bytes" "context" "errors" + "math/big" "testing" "time" storetypes "cosmossdk.io/store/types" "cosmossdk.io/math" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/runtime" @@ -19,8 +22,26 @@ import ( "github.com/cosmos/evm/x/poolrebalancer/keeper" "github.com/cosmos/evm/x/poolrebalancer/types" + evmtypes "github.com/cosmos/evm/x/vm/types" ) +// endBlockerMockEVM satisfies types.EVMKeeper for module-level ABCI tests. +type endBlockerMockEVM struct{} + +func (endBlockerMockEVM) CallEVM( + _ sdk.Context, + _ abi.ABI, + _, _ common.Address, + _ bool, + _ *big.Int, + _ string, + _ ...any, +) (*evmtypes.MsgEthereumTxResponse, error) { + return &evmtypes.MsgEthereumTxResponse{}, nil +} + +func (endBlockerMockEVM) IsContract(sdk.Context, common.Address) bool { return true } + func newEndBlockerTestKeeper(t *testing.T, sk types.StakingKeeper) (sdk.Context, keeper.Keeper, *storetypes.KVStoreKey) { t.Helper() @@ -32,7 +53,7 @@ func newEndBlockerTestKeeper(t *testing.T, sk types.StakingKeeper) (sdk.Context, cdc := moduletestutil.MakeTestEncodingConfig().Codec authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := keeper.NewKeeper(cdc, storeService, sk, authority, nil, nil) + k := keeper.NewKeeper(cdc, storeService, sk, authority, endBlockerMockEVM{}, nil) return ctx, k, storeKey } diff --git a/x/poolrebalancer/keeper/community_pool_test.go b/x/poolrebalancer/keeper/community_pool_test.go index c31b416d..25510900 100644 --- a/x/poolrebalancer/keeper/community_pool_test.go +++ b/x/poolrebalancer/keeper/community_pool_test.go @@ -24,6 +24,16 @@ type mockEVMKeeper struct { errByMethod map[string]error failedVM map[string]string // method -> VmError (non-empty => Failed()) + + // isContractFn optionally gates IsContract; nil means all addresses are treated as contracts. + isContractFn func(common.Address) bool +} + +func (m *mockEVMKeeper) IsContract(_ sdk.Context, addr common.Address) bool { + if m != nil && m.isContractFn != nil { + return m.isContractFn(addr) + } + return true } func (m *mockEVMKeeper) CallEVM( @@ -50,7 +60,7 @@ func (m *mockEVMKeeper) CallEVM( } func TestMaybeRunCommunityPoolAutomation_SkipsWhenPoolDelegatorUnset(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) mockEVM := &mockEVMKeeper{} k.evmKeeper = mockEVM @@ -59,18 +69,22 @@ func TestMaybeRunCommunityPoolAutomation_SkipsWhenPoolDelegatorUnset(t *testing. } func TestMaybeRunCommunityPoolAutomation_SkipsWhenEVMKeeperUnset(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) + mockEVM := &mockEVMKeeper{} + k.evmKeeper = mockEVM del := sdk.AccAddress(bytes.Repeat([]byte{7}, 20)) params := pooltypes.DefaultParams() params.PoolDelegatorAddress = del.String() require.NoError(t, k.SetParams(ctx, params)) + k.evmKeeper = nil require.NoError(t, k.MaybeRunCommunityPoolAutomation(ctx)) + require.Empty(t, mockEVM.methods) } func TestMaybeRunCommunityPoolAutomation_CallsHarvestThenStake(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) mockEVM := &mockEVMKeeper{} k.evmKeeper = mockEVM @@ -92,7 +106,7 @@ func TestMaybeRunCommunityPoolAutomation_CallsHarvestThenStake(t *testing.T) { } func TestMaybeRunCommunityPoolAutomation_HarvestFailureDoesNotBlockStake(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) mockEVM := &mockEVMKeeper{ errByMethod: map[string]error{ "harvest": errors.New("mock harvest failure"), diff --git a/x/poolrebalancer/keeper/grpc_query_test.go b/x/poolrebalancer/keeper/grpc_query_test.go index b7462732..e750d997 100644 --- a/x/poolrebalancer/keeper/grpc_query_test.go +++ b/x/poolrebalancer/keeper/grpc_query_test.go @@ -17,7 +17,7 @@ import ( ) func TestQueryParams_RoundTrip(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) params := types.DefaultParams() params.MaxOpsPerBlock = 7 @@ -30,7 +30,7 @@ func TestQueryParams_RoundTrip(t *testing.T) { } func TestQueryPendingRedelegations_DecodesProtoValues(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) @@ -56,7 +56,7 @@ func TestQueryPendingRedelegations_DecodesProtoValues(t *testing.T) { } func TestQueryPendingUndelegations_PaginatesByQueueBuckets(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) @@ -97,7 +97,7 @@ func TestQueryPendingUndelegations_PaginatesByQueueBuckets(t *testing.T) { } func TestQueryPendingRedelegations_NilRequest(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) qs := NewQueryServer(k) _, err := qs.PendingRedelegations(ctx, nil) @@ -106,7 +106,7 @@ func TestQueryPendingRedelegations_NilRequest(t *testing.T) { } func TestQueryPendingUndelegations_NilRequest(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) qs := NewQueryServer(k) _, err := qs.PendingUndelegations(ctx, nil) diff --git a/x/poolrebalancer/keeper/msg_server_test.go b/x/poolrebalancer/keeper/msg_server_test.go index 2f6ae9f7..44981cce 100644 --- a/x/poolrebalancer/keeper/msg_server_test.go +++ b/x/poolrebalancer/keeper/msg_server_test.go @@ -7,13 +7,16 @@ import ( "cosmossdk.io/math" "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/ethereum/go-ethereum/common" "github.com/cosmos/evm/x/poolrebalancer/types" ) func TestUpdateParams_RejectsWrongAuthority(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) // Current keeper authority is 0x09..09; use a different address. wrongAuthority := sdk.AccAddress(bytes.Repeat([]byte{8}, 20)).String() @@ -29,7 +32,7 @@ func TestUpdateParams_RejectsWrongAuthority(t *testing.T) { } func TestUpdateParams_RejectsNilRequest(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) _, err := k.UpdateParams(ctx, nil) require.Error(t, err) @@ -37,7 +40,7 @@ func TestUpdateParams_RejectsNilRequest(t *testing.T) { } func TestUpdateParams_AcceptsAuthorityAndUpdatesParams(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) authority := k.authority.String() @@ -60,7 +63,7 @@ func TestUpdateParams_AcceptsAuthorityAndUpdatesParams(t *testing.T) { } func TestUpdateParams_RejectsInvalidParamsWithValidAuthority(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) authority := k.authority.String() invalid := types.DefaultParams() @@ -76,6 +79,41 @@ func TestUpdateParams_RejectsInvalidParamsWithValidAuthority(t *testing.T) { require.Contains(t, err.Error(), "max_target_validators must be positive") } +// UpdateParams calls SetParams, so pool_delegator validation applies on the gov path too. +func TestUpdateParams_RejectsNonEmptyPoolWhenEVMKeeperNil(t *testing.T) { + ctx, k, _ := newTestKeeper(t) + + params := types.DefaultParams() + params.PoolDelegatorAddress = sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String() + + _, err := k.UpdateParams(ctx, &types.MsgUpdateParams{ + Authority: k.authority.String(), + Params: params, + }) + require.Error(t, err) + require.Contains(t, err.Error(), "requires evm keeper") +} + +func TestUpdateParams_RejectsUserAccountPoolDelegator(t *testing.T) { + ctx, k, mockAcc := newTestKeeper(t) + k.evmKeeper = &mockEVMKeeper{} + + priv := secp256k1.GenPrivKey() + pub := priv.PubKey() + addr := sdk.AccAddress(pub.Address()) + mockAcc.SetAccount(ctx, authtypes.NewBaseAccount(addr, pub, 0, 0)) + + params := types.DefaultParams() + params.PoolDelegatorAddress = addr.String() + + _, err := k.UpdateParams(ctx, &types.MsgUpdateParams{ + Authority: k.authority.String(), + Params: params, + }) + require.Error(t, err) + require.Contains(t, err.Error(), "user account with signing keys") +} + func TestMsgUpdateParams_ValidateBasic_RejectsInvalidParams(t *testing.T) { msg := &types.MsgUpdateParams{ Authority: sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String(), @@ -93,7 +131,7 @@ func TestMsgUpdateParams_ValidateBasic_RejectsInvalidParams(t *testing.T) { } func TestSetParams_RejectsInvalidParamsDirectly(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) invalid := types.DefaultParams() invalid.MaxTargetValidators = 0 @@ -102,3 +140,70 @@ func TestSetParams_RejectsInvalidParamsDirectly(t *testing.T) { require.Error(t, err) require.Contains(t, err.Error(), "max_target_validators must be positive") } + +func TestSetParams_RejectsNonEmptyPoolWhenEVMKeeperNil(t *testing.T) { + ctx, k, _ := newTestKeeper(t) + params := types.DefaultParams() + params.PoolDelegatorAddress = sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String() + + err := k.SetParams(ctx, params) + require.Error(t, err) + require.Contains(t, err.Error(), "requires evm keeper") +} + +func TestSetParams_RejectsNonEmptyPoolWhenAuthAndEVMUnset(t *testing.T) { + ctx, k := newTestKeeperNilAuthAndEVM(t) + params := types.DefaultParams() + params.PoolDelegatorAddress = sdk.AccAddress(bytes.Repeat([]byte{1}, 20)).String() + + err := k.SetParams(ctx, params) + require.Error(t, err) + require.Contains(t, err.Error(), "requires account keeper or evm keeper for validation") +} + +// User account with pubkey (signing keys); same intent as plan's RejectsUserAccountWithPubkey. +func TestSetParams_RejectsUserAccountPoolDelegator(t *testing.T) { + ctx, k, mockAcc := newTestKeeper(t) + k.evmKeeper = &mockEVMKeeper{} + + priv := secp256k1.GenPrivKey() + pub := priv.PubKey() + addr := sdk.AccAddress(pub.Address()) + acc := authtypes.NewBaseAccount(addr, pub, 0, 0) + mockAcc.SetAccount(ctx, acc) + + params := types.DefaultParams() + params.PoolDelegatorAddress = addr.String() + + err := k.SetParams(ctx, params) + require.Error(t, err) + require.Contains(t, err.Error(), "user account with signing keys") +} + +func TestSetParams_AcceptsBootstrapNoAuthAccount(t *testing.T) { + ctx, k, _ := newTestKeeper(t) + k.evmKeeper = &mockEVMKeeper{ + isContractFn: func(common.Address) bool { return false }, + } + addr := sdk.AccAddress(bytes.Repeat([]byte{0xAB}, 20)) + params := types.DefaultParams() + params.PoolDelegatorAddress = addr.String() + + require.NoError(t, k.SetParams(ctx, params)) +} + +func TestSetParams_RejectsNonContractWhenAccountExistsWithoutBootstrap(t *testing.T) { + ctx, k, mockAcc := newTestKeeper(t) + k.evmKeeper = &mockEVMKeeper{ + isContractFn: func(common.Address) bool { return false }, + } + addr := sdk.AccAddress(bytes.Repeat([]byte{0xAB}, 20)) + mockAcc.SetAccount(ctx, authtypes.NewBaseAccountWithAddress(addr)) + + params := types.DefaultParams() + params.PoolDelegatorAddress = addr.String() + + err := k.SetParams(ctx, params) + require.Error(t, err) + require.Contains(t, err.Error(), "must be an EVM contract") +} diff --git a/x/poolrebalancer/keeper/params.go b/x/poolrebalancer/keeper/params.go index e550845b..4b32b83e 100644 --- a/x/poolrebalancer/keeper/params.go +++ b/x/poolrebalancer/keeper/params.go @@ -33,6 +33,9 @@ func (k Keeper) SetParams(ctx context.Context, params types.Params) error { if err := params.Validate(); err != nil { return err } + if err := k.validatePoolDelegatorAddress(ctx, params.PoolDelegatorAddress); err != nil { + return err + } store := k.storeService.OpenKVStore(ctx) bz := k.cdc.MustMarshal(¶ms) return store.Set(types.ParamsKey, bz) diff --git a/x/poolrebalancer/keeper/pool_delegator.go b/x/poolrebalancer/keeper/pool_delegator.go new file mode 100644 index 00000000..0be94066 --- /dev/null +++ b/x/poolrebalancer/keeper/pool_delegator.go @@ -0,0 +1,54 @@ +package keeper + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// validatePoolDelegatorAddress enforces pool_delegator_address safety for governance and genesis. +// +// Contract-only policy: a non-empty address must be validated with IsContract on the EVM keeper, +// except bootstrap when auth has no account yet. User accounts with signing keys are rejected. +// There is no module-account shortcut. Non-empty pool address requires a non-nil evm keeper. +func (k Keeper) validatePoolDelegatorAddress(ctx context.Context, poolDelStr string) error { + if poolDelStr == "" { + return nil + } + poolDel, err := sdk.AccAddressFromBech32(poolDelStr) + if err != nil { + return fmt.Errorf("invalid pool_delegator_address: %w", err) + } + + if k.accountKeeper == nil && k.evmKeeper == nil { + return fmt.Errorf("pool_delegator_address requires account keeper or evm keeper for validation") + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + + var acc sdk.AccountI + if k.accountKeeper != nil { + acc = k.accountKeeper.GetAccount(ctx, poolDel) + if acc != nil { + if pk := acc.GetPubKey(); pk != nil && len(pk.Bytes()) > 0 { + return fmt.Errorf("pool_delegator_address cannot be a user account with signing keys") + } + } + } + + if k.evmKeeper == nil { + return fmt.Errorf("pool_delegator_address requires evm keeper when set") + } + + if k.evmKeeper.IsContract(sdkCtx, common.BytesToAddress(poolDel.Bytes())) { + return nil + } + if k.accountKeeper != nil && acc == nil { + // Bootstrap: params may be set before the contract account exists in auth. + return nil + } + return fmt.Errorf("pool_delegator_address must be an EVM contract when evm keeper is configured") +} diff --git a/x/poolrebalancer/keeper/rebalance_events_test.go b/x/poolrebalancer/keeper/rebalance_events_test.go index 9d0fa673..fc53a892 100644 --- a/x/poolrebalancer/keeper/rebalance_events_test.go +++ b/x/poolrebalancer/keeper/rebalance_events_test.go @@ -12,7 +12,7 @@ import ( ) func TestEmitRedelegationFailureEvent(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) src := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) @@ -42,7 +42,7 @@ func TestEmitRedelegationFailureEvent(t *testing.T) { } func TestEmitUndelegationFailureEvent(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) val := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) diff --git a/x/poolrebalancer/keeper/rebalance_process_test.go b/x/poolrebalancer/keeper/rebalance_process_test.go index 6e635003..ed5aa07e 100644 --- a/x/poolrebalancer/keeper/rebalance_process_test.go +++ b/x/poolrebalancer/keeper/rebalance_process_test.go @@ -87,7 +87,7 @@ func newProcessRebalanceKeeper(t *testing.T, sk types.StakingKeeper) (sdk.Contex storeService := runtime.NewKVStoreService(storeKey) cdc := moduletestutil.MakeTestEncodingConfig().Codec authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) - k := NewKeeper(cdc, storeService, sk, authority, nil, nil) + k := NewKeeper(cdc, storeService, sk, authority, &mockEVMKeeper{}, nil) return ctx, k } diff --git a/x/poolrebalancer/keeper/redelegation_test.go b/x/poolrebalancer/keeper/redelegation_test.go index 55b33e9e..e9aa029b 100644 --- a/x/poolrebalancer/keeper/redelegation_test.go +++ b/x/poolrebalancer/keeper/redelegation_test.go @@ -14,7 +14,7 @@ import ( ) func TestHasImmatureRedelegationTo_BlocksSrcWhenDstHasIncoming(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) @@ -38,7 +38,7 @@ func TestHasImmatureRedelegationTo_BlocksSrcWhenDstHasIncoming(t *testing.T) { } func TestCompletePendingRedelegations_RemovesPrimaryIndexAndQueue(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) @@ -85,7 +85,7 @@ func TestCompletePendingRedelegations_RemovesPrimaryIndexAndQueue(t *testing.T) } func TestSetPendingRedelegation_DistinctSourcesDoNotMerge(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) diff --git a/x/poolrebalancer/keeper/test_helpers_test.go b/x/poolrebalancer/keeper/test_helpers_test.go index f07b9e34..caddc5dc 100644 --- a/x/poolrebalancer/keeper/test_helpers_test.go +++ b/x/poolrebalancer/keeper/test_helpers_test.go @@ -2,6 +2,7 @@ package keeper import ( "bytes" + "context" "testing" storetypes "cosmossdk.io/store/types" @@ -10,11 +11,39 @@ import ( "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/cosmos/evm/x/poolrebalancer/types" ) -func newTestKeeper(t *testing.T) (sdk.Context, Keeper) { +// mockAccountKeeper is an in-memory auth stub for unit tests (e.g. user pubkey rejection). +type mockAccountKeeper struct { + accounts map[string]sdk.AccountI +} + +func newMockAccountKeeper() *mockAccountKeeper { + return &mockAccountKeeper{accounts: make(map[string]sdk.AccountI)} +} + +func (m *mockAccountKeeper) GetAccount(_ context.Context, addr sdk.AccAddress) sdk.AccountI { + if m == nil { + return nil + } + return m.accounts[addr.String()] +} + +func (m *mockAccountKeeper) SetAccount(_ context.Context, acc sdk.AccountI) { + m.accounts[acc.GetAddress().String()] = acc +} + +func (m *mockAccountKeeper) NewAccountWithAddress(_ context.Context, addr sdk.AccAddress) sdk.AccountI { + return authtypes.NewBaseAccountWithAddress(addr) +} + +// newTestKeeper returns a keeper with in-memory auth (mockAccountKeeper) and nil EVM. +// Before SetParams with a non-empty PoolDelegatorAddress, assign k.evmKeeper (e.g. &mockEVMKeeper{}) +// unless the test intentionally exercises validation failure or clears EVM after a successful SetParams. +func newTestKeeper(t *testing.T) (sdk.Context, Keeper, *mockAccountKeeper) { t.Helper() storeKey := storetypes.NewKVStoreKey(types.ModuleName) @@ -25,6 +54,24 @@ func newTestKeeper(t *testing.T) (sdk.Context, Keeper) { cdc := moduletestutil.MakeTestEncodingConfig().Codec stakingKeeper := &mockStakingKeeper{} + authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) + mockAcc := newMockAccountKeeper() + k := NewKeeper(cdc, storeService, stakingKeeper, authority, nil, mockAcc) + return ctx, k, mockAcc +} + +// newTestKeeperNilAuthAndEVM matches genesis-style wiring (no auth, no EVM). Non-empty +// pool_delegator_address cannot be persisted on this keeper. +func newTestKeeperNilAuthAndEVM(t *testing.T) (sdk.Context, Keeper) { + t.Helper() + + storeKey := storetypes.NewKVStoreKey(types.ModuleName) + tKey := storetypes.NewTransientStoreKey("transient_test") + ctx := testutil.DefaultContext(storeKey, tKey) + + storeService := runtime.NewKVStoreService(storeKey) + cdc := moduletestutil.MakeTestEncodingConfig().Codec + stakingKeeper := &mockStakingKeeper{} authority := sdk.AccAddress(bytes.Repeat([]byte{9}, 20)) k := NewKeeper(cdc, storeService, stakingKeeper, authority, nil, nil) return ctx, k diff --git a/x/poolrebalancer/keeper/undelegation_test.go b/x/poolrebalancer/keeper/undelegation_test.go index 2b5cbc49..c77ffb95 100644 --- a/x/poolrebalancer/keeper/undelegation_test.go +++ b/x/poolrebalancer/keeper/undelegation_test.go @@ -15,7 +15,7 @@ import ( ) func TestCompletePendingUndelegations_RemovesQueueAndIndex(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) del := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) @@ -55,7 +55,7 @@ func TestCompletePendingUndelegations_RemovesQueueAndIndex(t *testing.T) { } func TestCompletePendingUndelegations_CreditsPoolBeforeDelete(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) mockEVM := &mockEVMKeeper{} k.evmKeeper = mockEVM @@ -92,7 +92,7 @@ func TestCompletePendingUndelegations_CreditsPoolBeforeDelete(t *testing.T) { } func TestCompletePendingUndelegations_RetainsQueueOnCreditVMFailure(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) mockEVM := &mockEVMKeeper{ failedVM: map[string]string{ "creditStakeableFromRebalance": "execution reverted", @@ -128,7 +128,7 @@ func TestCompletePendingUndelegations_RetainsQueueOnCreditVMFailure(t *testing.T } func TestCompletePendingUndelegations_SumsOnlyPoolDelegatorBondDenom(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) mockEVM := &mockEVMKeeper{} k.evmKeeper = mockEVM @@ -171,12 +171,15 @@ func TestCompletePendingUndelegations_SumsOnlyPoolDelegatorBondDenom(t *testing. } func TestCompletePendingUndelegations_ErrWhenPoolCreditRequiresEVMButNil(t *testing.T) { - ctx, k := newTestKeeper(t) + ctx, k, _ := newTestKeeper(t) + mockEVM := &mockEVMKeeper{} + k.evmKeeper = mockEVM poolDel := sdk.AccAddress(bytes.Repeat([]byte{1}, 20)) params := types.DefaultParams() params.PoolDelegatorAddress = poolDel.String() require.NoError(t, k.SetParams(ctx, params)) + k.evmKeeper = nil ctx = ctx.WithBlockTime(time.Unix(2_000, 0)) val := sdk.ValAddress(bytes.Repeat([]byte{2}, 20)) diff --git a/x/poolrebalancer/types/helpers.go b/x/poolrebalancer/types/helpers.go index 304945b2..43e3da12 100644 --- a/x/poolrebalancer/types/helpers.go +++ b/x/poolrebalancer/types/helpers.go @@ -20,7 +20,9 @@ func DefaultParams() Params { } } -// Validate validates the params. +// Validate runs stateless checks only. For pool_delegator_address that means Bech32 form when +// non-empty—no EVM IsContract, no auth/account checks. User accounts, contract proof, and +// bootstrap ordering are enforced in keeper.validatePoolDelegatorAddress (via SetParams). func (p Params) Validate() error { if p.PoolDelegatorAddress != "" { if _, err := sdk.AccAddressFromBech32(p.PoolDelegatorAddress); err != nil { @@ -49,7 +51,8 @@ func DefaultGenesisState() *GenesisState { } } -// Validate validates the genesis state. +// Validate checks genesis params using the same stateless rules as Params.Validate; pool +// delegator safety still depends on keeper validation when InitGenesis calls SetParams. func (gs *GenesisState) Validate() error { return gs.Params.Validate() } diff --git a/x/poolrebalancer/types/helpers_test.go b/x/poolrebalancer/types/helpers_test.go index 43f6afa0..49b5703d 100644 --- a/x/poolrebalancer/types/helpers_test.go +++ b/x/poolrebalancer/types/helpers_test.go @@ -1,10 +1,13 @@ package types import ( + "bytes" "testing" "cosmossdk.io/math" "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" ) func TestParamsValidate_RejectsThresholdAbove10000(t *testing.T) { @@ -34,6 +37,14 @@ func TestParamsValidate_RejectsInvalidPoolDelegatorAddress(t *testing.T) { require.Contains(t, err.Error(), "pool_delegator_address") } +// Well-formed Bech32 is enough for Params.Validate; contract-only and user-pubkey rules are not applied here. +func TestParamsValidate_AcceptsWellFormedBech32PoolDelegatorOnly(t *testing.T) { + p := DefaultParams() + p.PoolDelegatorAddress = sdk.AccAddress(bytes.Repeat([]byte{0x42}, 20)).String() + + require.NoError(t, p.Validate()) +} + func TestParamsValidate_RejectsZeroMaxOpsPerBlock(t *testing.T) { p := DefaultParams() p.MaxOpsPerBlock = 0 diff --git a/x/poolrebalancer/types/interfaces.go b/x/poolrebalancer/types/interfaces.go index 141dff19..eeb87b84 100644 --- a/x/poolrebalancer/types/interfaces.go +++ b/x/poolrebalancer/types/interfaces.go @@ -38,6 +38,8 @@ type EVMKeeper interface { method string, args ...any, ) (*evmtypes.MsgEthereumTxResponse, error) + // IsContract reports whether the address holds non-delegated EVM bytecode (see x/vm/keeper.IsContract). + IsContract(ctx sdk.Context, address common.Address) bool } // AccountKeeper defines the subset of auth keeper methods used by poolrebalancer.