diff --git a/api/cosmos/evm/vm/v1/tx.pulsar.go b/api/cosmos/evm/vm/v1/tx.pulsar.go index 5c27e0b4..c52bd011 100644 --- a/api/cosmos/evm/vm/v1/tx.pulsar.go +++ b/api/cosmos/evm/vm/v1/tx.pulsar.go @@ -5763,6 +5763,846 @@ func (x *fastReflection_MsgUpdateParamsResponse) ProtoMethods() *protoiface.Meth } } +var ( + md_MsgMigrateAccount protoreflect.MessageDescriptor + fd_MsgMigrateAccount_original_address protoreflect.FieldDescriptor + fd_MsgMigrateAccount_new_address protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_evm_vm_v1_tx_proto_init() + md_MsgMigrateAccount = File_cosmos_evm_vm_v1_tx_proto.Messages().ByName("MsgMigrateAccount") + fd_MsgMigrateAccount_original_address = md_MsgMigrateAccount.Fields().ByName("original_address") + fd_MsgMigrateAccount_new_address = md_MsgMigrateAccount.Fields().ByName("new_address") +} + +var _ protoreflect.Message = (*fastReflection_MsgMigrateAccount)(nil) + +type fastReflection_MsgMigrateAccount MsgMigrateAccount + +func (x *MsgMigrateAccount) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgMigrateAccount)(x) +} + +func (x *MsgMigrateAccount) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_vm_v1_tx_proto_msgTypes[8] + 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_MsgMigrateAccount_messageType fastReflection_MsgMigrateAccount_messageType +var _ protoreflect.MessageType = fastReflection_MsgMigrateAccount_messageType{} + +type fastReflection_MsgMigrateAccount_messageType struct{} + +func (x fastReflection_MsgMigrateAccount_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgMigrateAccount)(nil) +} +func (x fastReflection_MsgMigrateAccount_messageType) New() protoreflect.Message { + return new(fastReflection_MsgMigrateAccount) +} +func (x fastReflection_MsgMigrateAccount_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgMigrateAccount +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgMigrateAccount) Descriptor() protoreflect.MessageDescriptor { + return md_MsgMigrateAccount +} + +// 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_MsgMigrateAccount) Type() protoreflect.MessageType { + return _fastReflection_MsgMigrateAccount_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgMigrateAccount) New() protoreflect.Message { + return new(fastReflection_MsgMigrateAccount) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgMigrateAccount) Interface() protoreflect.ProtoMessage { + return (*MsgMigrateAccount)(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_MsgMigrateAccount) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.OriginalAddress != "" { + value := protoreflect.ValueOfString(x.OriginalAddress) + if !f(fd_MsgMigrateAccount_original_address, value) { + return + } + } + if x.NewAddress != "" { + value := protoreflect.ValueOfString(x.NewAddress) + if !f(fd_MsgMigrateAccount_new_address, 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_MsgMigrateAccount) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.evm.vm.v1.MsgMigrateAccount.original_address": + return x.OriginalAddress != "" + case "cosmos.evm.vm.v1.MsgMigrateAccount.new_address": + return x.NewAddress != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgMigrateAccount")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccount 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_MsgMigrateAccount) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.evm.vm.v1.MsgMigrateAccount.original_address": + x.OriginalAddress = "" + case "cosmos.evm.vm.v1.MsgMigrateAccount.new_address": + x.NewAddress = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgMigrateAccount")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccount 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_MsgMigrateAccount) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.evm.vm.v1.MsgMigrateAccount.original_address": + value := x.OriginalAddress + return protoreflect.ValueOfString(value) + case "cosmos.evm.vm.v1.MsgMigrateAccount.new_address": + value := x.NewAddress + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgMigrateAccount")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccount 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_MsgMigrateAccount) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.evm.vm.v1.MsgMigrateAccount.original_address": + x.OriginalAddress = value.Interface().(string) + case "cosmos.evm.vm.v1.MsgMigrateAccount.new_address": + x.NewAddress = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgMigrateAccount")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccount 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_MsgMigrateAccount) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.vm.v1.MsgMigrateAccount.original_address": + panic(fmt.Errorf("field original_address of message cosmos.evm.vm.v1.MsgMigrateAccount is not mutable")) + case "cosmos.evm.vm.v1.MsgMigrateAccount.new_address": + panic(fmt.Errorf("field new_address of message cosmos.evm.vm.v1.MsgMigrateAccount is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgMigrateAccount")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccount 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_MsgMigrateAccount) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.evm.vm.v1.MsgMigrateAccount.original_address": + return protoreflect.ValueOfString("") + case "cosmos.evm.vm.v1.MsgMigrateAccount.new_address": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgMigrateAccount")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccount 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_MsgMigrateAccount) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.vm.v1.MsgMigrateAccount", 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_MsgMigrateAccount) 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_MsgMigrateAccount) 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_MsgMigrateAccount) 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_MsgMigrateAccount) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgMigrateAccount) + 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.OriginalAddress) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.NewAddress) + if l > 0 { + 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().(*MsgMigrateAccount) + 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.NewAddress) > 0 { + i -= len(x.NewAddress) + copy(dAtA[i:], x.NewAddress) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.NewAddress))) + i-- + dAtA[i] = 0x12 + } + if len(x.OriginalAddress) > 0 { + i -= len(x.OriginalAddress) + copy(dAtA[i:], x.OriginalAddress) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.OriginalAddress))) + 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().(*MsgMigrateAccount) + 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: MsgMigrateAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgMigrateAccount: 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 OriginalAddress", 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.OriginalAddress = 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 NewAddress", 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.NewAddress = string(dAtA[iNdEx:postIndex]) + 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_MsgMigrateAccountResponse protoreflect.MessageDescriptor +) + +func init() { + file_cosmos_evm_vm_v1_tx_proto_init() + md_MsgMigrateAccountResponse = File_cosmos_evm_vm_v1_tx_proto.Messages().ByName("MsgMigrateAccountResponse") +} + +var _ protoreflect.Message = (*fastReflection_MsgMigrateAccountResponse)(nil) + +type fastReflection_MsgMigrateAccountResponse MsgMigrateAccountResponse + +func (x *MsgMigrateAccountResponse) ProtoReflect() protoreflect.Message { + return (*fastReflection_MsgMigrateAccountResponse)(x) +} + +func (x *MsgMigrateAccountResponse) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_evm_vm_v1_tx_proto_msgTypes[9] + 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_MsgMigrateAccountResponse_messageType fastReflection_MsgMigrateAccountResponse_messageType +var _ protoreflect.MessageType = fastReflection_MsgMigrateAccountResponse_messageType{} + +type fastReflection_MsgMigrateAccountResponse_messageType struct{} + +func (x fastReflection_MsgMigrateAccountResponse_messageType) Zero() protoreflect.Message { + return (*fastReflection_MsgMigrateAccountResponse)(nil) +} +func (x fastReflection_MsgMigrateAccountResponse_messageType) New() protoreflect.Message { + return new(fastReflection_MsgMigrateAccountResponse) +} +func (x fastReflection_MsgMigrateAccountResponse_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_MsgMigrateAccountResponse +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_MsgMigrateAccountResponse) Descriptor() protoreflect.MessageDescriptor { + return md_MsgMigrateAccountResponse +} + +// 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_MsgMigrateAccountResponse) Type() protoreflect.MessageType { + return _fastReflection_MsgMigrateAccountResponse_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_MsgMigrateAccountResponse) New() protoreflect.Message { + return new(fastReflection_MsgMigrateAccountResponse) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_MsgMigrateAccountResponse) Interface() protoreflect.ProtoMessage { + return (*MsgMigrateAccountResponse)(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_MsgMigrateAccountResponse) 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_MsgMigrateAccountResponse) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgMigrateAccountResponse")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccountResponse 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_MsgMigrateAccountResponse) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.evm.vm.v1.MsgMigrateAccountResponse")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccountResponse 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_MsgMigrateAccountResponse) 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.vm.v1.MsgMigrateAccountResponse")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccountResponse 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_MsgMigrateAccountResponse) 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.vm.v1.MsgMigrateAccountResponse")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccountResponse 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_MsgMigrateAccountResponse) 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.vm.v1.MsgMigrateAccountResponse")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccountResponse 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_MsgMigrateAccountResponse) 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.vm.v1.MsgMigrateAccountResponse")) + } + panic(fmt.Errorf("message cosmos.evm.vm.v1.MsgMigrateAccountResponse 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_MsgMigrateAccountResponse) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.evm.vm.v1.MsgMigrateAccountResponse", 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_MsgMigrateAccountResponse) 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_MsgMigrateAccountResponse) 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_MsgMigrateAccountResponse) 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_MsgMigrateAccountResponse) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*MsgMigrateAccountResponse) + 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().(*MsgMigrateAccountResponse) + 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().(*MsgMigrateAccountResponse) + 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: MsgMigrateAccountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: MsgMigrateAccountResponse: 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 @@ -6395,6 +7235,78 @@ func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { return file_cosmos_evm_vm_v1_tx_proto_rawDescGZIP(), []int{7} } +// todo: comments +type MsgMigrateAccount struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // original_address is the address of the account that is migrating to a new state + OriginalAddress string `protobuf:"bytes,1,opt,name=original_address,json=originalAddress,proto3" json:"original_address,omitempty"` + // new_address is the address of the account that is being migrated to from the old account + NewAddress string `protobuf:"bytes,2,opt,name=new_address,json=newAddress,proto3" json:"new_address,omitempty"` +} + +func (x *MsgMigrateAccount) Reset() { + *x = MsgMigrateAccount{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_vm_v1_tx_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgMigrateAccount) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgMigrateAccount) ProtoMessage() {} + +// Deprecated: Use MsgMigrateAccount.ProtoReflect.Descriptor instead. +func (*MsgMigrateAccount) Descriptor() ([]byte, []int) { + return file_cosmos_evm_vm_v1_tx_proto_rawDescGZIP(), []int{8} +} + +func (x *MsgMigrateAccount) GetOriginalAddress() string { + if x != nil { + return x.OriginalAddress + } + return "" +} + +func (x *MsgMigrateAccount) GetNewAddress() string { + if x != nil { + return x.NewAddress + } + return "" +} + +type MsgMigrateAccountResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *MsgMigrateAccountResponse) Reset() { + *x = MsgMigrateAccountResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_evm_vm_v1_tx_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MsgMigrateAccountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MsgMigrateAccountResponse) ProtoMessage() {} + +// Deprecated: Use MsgMigrateAccountResponse.ProtoReflect.Descriptor instead. +func (*MsgMigrateAccountResponse) Descriptor() ([]byte, []int) { + return file_cosmos_evm_vm_v1_tx_proto_rawDescGZIP(), []int{9} +} + var File_cosmos_evm_vm_v1_tx_proto protoreflect.FileDescriptor var file_cosmos_evm_vm_v1_tx_proto_rawDesc = []byte{ @@ -6532,7 +7444,22 @@ var file_cosmos_evm_vm_v1_tx_proto_rawDesc = []byte{ 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x76, 0x6d, 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, 0xe9, 0x01, 0x0a, 0x03, 0x4d, 0x73, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xd0, 0x01, 0x0a, 0x11, 0x4d, 0x73, + 0x67, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x43, 0x0a, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 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, 0x0f, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x02, 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, 0x0a, 0x6e, 0x65, 0x77, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x3a, + 0x3b, 0x82, 0xe7, 0xb0, 0x2a, 0x10, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x8a, 0xe7, 0xb0, 0x2a, 0x21, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2f, 0x65, 0x76, 0x6d, 0x2f, 0x78, 0x2f, 0x76, 0x6d, 0x2f, 0x4d, 0x73, 0x67, 0x4d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x1b, 0x0a, 0x19, + 0x4d, 0x73, 0x67, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xcd, 0x02, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x7d, 0x0a, 0x0a, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x45, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x54, 0x78, @@ -6546,19 +7473,25 @@ var file_cosmos_evm_vm_v1_tx_proto_rawDesc = []byte{ 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 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, 0xaa, 0x01, 0x0a, 0x14, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x42, 0x07, - 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x26, 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, 0x76, 0x6d, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x6d, 0x76, - 0x31, 0xa2, 0x02, 0x03, 0x43, 0x45, 0x56, 0xaa, 0x02, 0x10, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x45, 0x76, 0x6d, 0x2e, 0x56, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x10, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1c, - 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, 0x56, 0x6d, 0x3a, 0x3a, - 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, + 0x0a, 0x0e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x12, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x65, 0x41, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x2b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, + 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x73, 0x67, 0x4d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x1a, 0x05, 0x80, 0xe7, 0xb0, 0x2a, 0x01, 0x42, 0xaa, 0x01, 0x0a, 0x14, 0x63, 0x6f, + 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x65, 0x76, 0x6d, 0x2e, 0x76, 0x6d, 0x2e, + 0x76, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x26, 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, 0x76, 0x6d, 0x2f, 0x76, 0x31, + 0x3b, 0x76, 0x6d, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x45, 0x56, 0xaa, 0x02, 0x10, 0x43, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x45, 0x76, 0x6d, 0x2e, 0x56, 0x6d, 0x2e, 0x56, 0x31, 0xca, 0x02, + 0x10, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, 0x6d, 0x5c, 0x56, + 0x31, 0xe2, 0x02, 0x1c, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x45, 0x76, 0x6d, 0x5c, 0x56, + 0x6d, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x45, 0x76, 0x6d, 0x3a, 0x3a, + 0x56, 0x6d, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -6573,7 +7506,7 @@ func file_cosmos_evm_vm_v1_tx_proto_rawDescGZIP() []byte { return file_cosmos_evm_vm_v1_tx_proto_rawDescData } -var file_cosmos_evm_vm_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_cosmos_evm_vm_v1_tx_proto_msgTypes = make([]protoimpl.MessageInfo, 10) var file_cosmos_evm_vm_v1_tx_proto_goTypes = []interface{}{ (*MsgEthereumTx)(nil), // 0: cosmos.evm.vm.v1.MsgEthereumTx (*LegacyTx)(nil), // 1: cosmos.evm.vm.v1.LegacyTx @@ -6583,23 +7516,27 @@ var file_cosmos_evm_vm_v1_tx_proto_goTypes = []interface{}{ (*MsgEthereumTxResponse)(nil), // 5: cosmos.evm.vm.v1.MsgEthereumTxResponse (*MsgUpdateParams)(nil), // 6: cosmos.evm.vm.v1.MsgUpdateParams (*MsgUpdateParamsResponse)(nil), // 7: cosmos.evm.vm.v1.MsgUpdateParamsResponse - (*anypb.Any)(nil), // 8: google.protobuf.Any - (*AccessTuple)(nil), // 9: cosmos.evm.vm.v1.AccessTuple - (*Log)(nil), // 10: cosmos.evm.vm.v1.Log - (*Params)(nil), // 11: cosmos.evm.vm.v1.Params + (*MsgMigrateAccount)(nil), // 8: cosmos.evm.vm.v1.MsgMigrateAccount + (*MsgMigrateAccountResponse)(nil), // 9: cosmos.evm.vm.v1.MsgMigrateAccountResponse + (*anypb.Any)(nil), // 10: google.protobuf.Any + (*AccessTuple)(nil), // 11: cosmos.evm.vm.v1.AccessTuple + (*Log)(nil), // 12: cosmos.evm.vm.v1.Log + (*Params)(nil), // 13: cosmos.evm.vm.v1.Params } var file_cosmos_evm_vm_v1_tx_proto_depIdxs = []int32{ - 8, // 0: cosmos.evm.vm.v1.MsgEthereumTx.data:type_name -> google.protobuf.Any - 9, // 1: cosmos.evm.vm.v1.AccessListTx.accesses:type_name -> cosmos.evm.vm.v1.AccessTuple - 9, // 2: cosmos.evm.vm.v1.DynamicFeeTx.accesses:type_name -> cosmos.evm.vm.v1.AccessTuple - 10, // 3: cosmos.evm.vm.v1.MsgEthereumTxResponse.logs:type_name -> cosmos.evm.vm.v1.Log - 11, // 4: cosmos.evm.vm.v1.MsgUpdateParams.params:type_name -> cosmos.evm.vm.v1.Params + 10, // 0: cosmos.evm.vm.v1.MsgEthereumTx.data:type_name -> google.protobuf.Any + 11, // 1: cosmos.evm.vm.v1.AccessListTx.accesses:type_name -> cosmos.evm.vm.v1.AccessTuple + 11, // 2: cosmos.evm.vm.v1.DynamicFeeTx.accesses:type_name -> cosmos.evm.vm.v1.AccessTuple + 12, // 3: cosmos.evm.vm.v1.MsgEthereumTxResponse.logs:type_name -> cosmos.evm.vm.v1.Log + 13, // 4: cosmos.evm.vm.v1.MsgUpdateParams.params:type_name -> cosmos.evm.vm.v1.Params 0, // 5: cosmos.evm.vm.v1.Msg.EthereumTx:input_type -> cosmos.evm.vm.v1.MsgEthereumTx 6, // 6: cosmos.evm.vm.v1.Msg.UpdateParams:input_type -> cosmos.evm.vm.v1.MsgUpdateParams - 5, // 7: cosmos.evm.vm.v1.Msg.EthereumTx:output_type -> cosmos.evm.vm.v1.MsgEthereumTxResponse - 7, // 8: cosmos.evm.vm.v1.Msg.UpdateParams:output_type -> cosmos.evm.vm.v1.MsgUpdateParamsResponse - 7, // [7:9] is the sub-list for method output_type - 5, // [5:7] is the sub-list for method input_type + 8, // 7: cosmos.evm.vm.v1.Msg.MigrateAccount:input_type -> cosmos.evm.vm.v1.MsgMigrateAccount + 5, // 8: cosmos.evm.vm.v1.Msg.EthereumTx:output_type -> cosmos.evm.vm.v1.MsgEthereumTxResponse + 7, // 9: cosmos.evm.vm.v1.Msg.UpdateParams:output_type -> cosmos.evm.vm.v1.MsgUpdateParamsResponse + 9, // 10: cosmos.evm.vm.v1.Msg.MigrateAccount:output_type -> cosmos.evm.vm.v1.MsgMigrateAccountResponse + 8, // [8:11] is the sub-list for method output_type + 5, // [5:8] is the sub-list for method input_type 5, // [5:5] is the sub-list for extension type_name 5, // [5:5] is the sub-list for extension extendee 0, // [0:5] is the sub-list for field type_name @@ -6708,6 +7645,30 @@ func file_cosmos_evm_vm_v1_tx_proto_init() { return nil } } + file_cosmos_evm_vm_v1_tx_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgMigrateAccount); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_evm_vm_v1_tx_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MsgMigrateAccountResponse); 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{ @@ -6715,7 +7676,7 @@ func file_cosmos_evm_vm_v1_tx_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cosmos_evm_vm_v1_tx_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 10, NumExtensions: 0, NumServices: 1, }, diff --git a/api/cosmos/evm/vm/v1/tx_grpc.pb.go b/api/cosmos/evm/vm/v1/tx_grpc.pb.go index cd6db1b5..05c54573 100644 --- a/api/cosmos/evm/vm/v1/tx_grpc.pb.go +++ b/api/cosmos/evm/vm/v1/tx_grpc.pb.go @@ -19,8 +19,9 @@ import ( const _ = grpc.SupportPackageIsVersion7 const ( - Msg_EthereumTx_FullMethodName = "/cosmos.evm.vm.v1.Msg/EthereumTx" - Msg_UpdateParams_FullMethodName = "/cosmos.evm.vm.v1.Msg/UpdateParams" + Msg_EthereumTx_FullMethodName = "/cosmos.evm.vm.v1.Msg/EthereumTx" + Msg_UpdateParams_FullMethodName = "/cosmos.evm.vm.v1.Msg/UpdateParams" + Msg_MigrateAccount_FullMethodName = "/cosmos.evm.vm.v1.Msg/MigrateAccount" ) // MsgClient is the client API for Msg service. @@ -33,6 +34,8 @@ type MsgClient interface { // parameters. The authority is hard-coded to the Cosmos SDK x/gov module // account UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) + // todo: comments + MigrateAccount(ctx context.Context, in *MsgMigrateAccount, opts ...grpc.CallOption) (*MsgMigrateAccountResponse, error) } type msgClient struct { @@ -61,6 +64,15 @@ func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts return out, nil } +func (c *msgClient) MigrateAccount(ctx context.Context, in *MsgMigrateAccount, opts ...grpc.CallOption) (*MsgMigrateAccountResponse, error) { + out := new(MsgMigrateAccountResponse) + err := c.cc.Invoke(ctx, Msg_MigrateAccount_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 @@ -71,6 +83,8 @@ type MsgServer interface { // parameters. The authority is hard-coded to the Cosmos SDK x/gov module // account UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + // todo: comments + MigrateAccount(context.Context, *MsgMigrateAccount) (*MsgMigrateAccountResponse, error) mustEmbedUnimplementedMsgServer() } @@ -84,6 +98,9 @@ func (UnimplementedMsgServer) EthereumTx(context.Context, *MsgEthereumTx) (*MsgE func (UnimplementedMsgServer) UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") } +func (UnimplementedMsgServer) MigrateAccount(context.Context, *MsgMigrateAccount) (*MsgMigrateAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MigrateAccount not implemented") +} func (UnimplementedMsgServer) mustEmbedUnimplementedMsgServer() {} // UnsafeMsgServer may be embedded to opt out of forward compatibility for this service. @@ -133,6 +150,24 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Msg_MigrateAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgMigrateAccount) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).MigrateAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Msg_MigrateAccount_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).MigrateAccount(ctx, req.(*MsgMigrateAccount)) + } + 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) @@ -148,6 +183,10 @@ var Msg_ServiceDesc = grpc.ServiceDesc{ MethodName: "UpdateParams", Handler: _Msg_UpdateParams_Handler, }, + { + MethodName: "MigrateAccount", + Handler: _Msg_MigrateAccount_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cosmos/evm/vm/v1/tx.proto", diff --git a/evmd/app.go b/evmd/app.go index 4ec8dfb1..dc57bd07 100644 --- a/evmd/app.go +++ b/evmd/app.go @@ -512,8 +512,11 @@ func NewExampleApp( app.AccountKeeper, app.PreciseBankKeeper, app.StakingKeeper, + app.FeeGrantKeeper, + app.AuthzKeeper, app.FeeMarketKeeper, &app.Erc20Keeper, + baseapp.NewMsgServiceRouter(), tracer, ) diff --git a/proto/cosmos/evm/vm/v1/tx.proto b/proto/cosmos/evm/vm/v1/tx.proto index 5b2ed24e..46aa6156 100644 --- a/proto/cosmos/evm/vm/v1/tx.proto +++ b/proto/cosmos/evm/vm/v1/tx.proto @@ -24,6 +24,9 @@ service Msg { // parameters. The authority is hard-coded to the Cosmos SDK x/gov module // account rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); + + //todo: comments + rpc MigrateAccount(MsgMigrateAccount) returns (MsgMigrateAccountResponse); } // MsgEthereumTx encapsulates an Ethereum transaction as an SDK message. @@ -208,3 +211,17 @@ message MsgUpdateParams { // MsgUpdateParamsResponse defines the response structure for executing a // MsgUpdateParams message. message MsgUpdateParamsResponse {} + +// todo: comments +message MsgMigrateAccount { + option (amino.name) = "cosmos/evm/x/vm/MsgMigrateAccount"; + option (cosmos.msg.v1.signer) = "original_address"; + + // original_address is the address of the account that is migrating to a new state + string original_address = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; + + // new_address is the address of the account that is being migrated to from the old account + string new_address = 2 [ (cosmos_proto.scalar) = "cosmos.AddressString" ]; +} + +message MsgMigrateAccountResponse {} \ No newline at end of file diff --git a/testutil/integration/common/grpc/feegrant.go b/testutil/integration/common/grpc/feegrant.go new file mode 100644 index 00000000..482fbecd --- /dev/null +++ b/testutil/integration/common/grpc/feegrant.go @@ -0,0 +1,22 @@ +package grpc + +import ( + "context" + "cosmossdk.io/x/feegrant" +) + +// GetGrants returns the grants for the given grantee and granter combination. +// +// NOTE: To extract the concrete authorizations, use the GetAuthorizations method. +func (gqh *IntegrationHandler) Allowance(grantee, granter string) (*feegrant.QueryAllowanceResponse, error) { + feegrantClient := gqh.network.GetFeeGrantClient() + res, err := feegrantClient.Allowance(context.Background(), &feegrant.QueryAllowanceRequest{ + Grantee: grantee, + Granter: granter, + }) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/testutil/integration/common/grpc/grpc.go b/testutil/integration/common/grpc/grpc.go index ef529689..6c477c36 100644 --- a/testutil/integration/common/grpc/grpc.go +++ b/testutil/integration/common/grpc/grpc.go @@ -1,6 +1,7 @@ package grpc import ( + "cosmossdk.io/x/feegrant" "github.com/cosmos/evm/testutil/integration/common/network" sdk "github.com/cosmos/cosmos-sdk/types" @@ -46,6 +47,9 @@ type Handler interface { GetValidatorOutstandingRewards(validatorAddress string) (*distrtypes.QueryValidatorOutstandingRewardsResponse, error) GetCommunityPool() (*distrtypes.QueryCommunityPoolResponse, error) GetBondedValidators() (*stakingtypes.QueryValidatorsResponse, error) + + // Feegrant methods + Allowance(granter, grantee string) (*feegrant.QueryAllowanceResponse, error) } var _ Handler = (*IntegrationHandler)(nil) diff --git a/testutil/integration/common/network/network.go b/testutil/integration/common/network/network.go index c03a3642..8760e13c 100644 --- a/testutil/integration/common/network/network.go +++ b/testutil/integration/common/network/network.go @@ -1,6 +1,7 @@ package network import ( + "cosmossdk.io/x/feegrant" "testing" "time" @@ -39,6 +40,7 @@ type Network interface { GetBankClient() banktypes.QueryClient GetStakingClient() stakingtypes.QueryClient GetDistrClient() distrtypes.QueryClient + GetFeeGrantClient() feegrant.QueryClient BroadcastTxSync(txBytes []byte) (abcitypes.ExecTxResult, error) Simulate(txBytes []byte) (*txtypes.SimulateResponse, error) diff --git a/testutil/integration/os/network/clients.go b/testutil/integration/os/network/clients.go index 8e4c3477..538013aa 100644 --- a/testutil/integration/os/network/clients.go +++ b/testutil/integration/os/network/clients.go @@ -1,6 +1,7 @@ package network import ( + "cosmossdk.io/x/feegrant" erc20types "github.com/cosmos/evm/x/erc20/types" feemarkettypes "github.com/cosmos/evm/x/feemarket/types" precisebankkeeper "github.com/cosmos/evm/x/precisebank/keeper" @@ -74,6 +75,12 @@ func (n *IntegrationNetwork) GetAuthzClient() authz.QueryClient { return authz.NewQueryClient(queryHelper) } +func (n *IntegrationNetwork) GetFeeGrantClient() feegrant.QueryClient { + queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig()) + feegrant.RegisterQueryServer(queryHelper, n.app.FeeGrantKeeper) + return feegrant.NewQueryClient(queryHelper) +} + func (n *IntegrationNetwork) GetStakingClient() stakingtypes.QueryClient { queryHelper := getQueryHelper(n.GetContext(), n.GetEncodingConfig()) stakingtypes.RegisterQueryServer(queryHelper, stakingkeeper.Querier{Keeper: n.app.StakingKeeper}) diff --git a/x/precisebank/keeper/keeper.go b/x/precisebank/keeper/keeper.go index 699cb844..679b9eaa 100644 --- a/x/precisebank/keeper/keeper.go +++ b/x/precisebank/keeper/keeper.go @@ -2,6 +2,7 @@ package keeper import ( "context" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/evm/x/precisebank/types" evmtypes "github.com/cosmos/evm/x/vm/types" @@ -24,6 +25,18 @@ type Keeper struct { ak types.AccountKeeper } +func (k Keeper) GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins { + return k.bk.GetAllBalances(ctx, addr) +} + +func (k Keeper) SpendableBalances(ctx context.Context, req *banktypes.QuerySpendableBalancesRequest) (*banktypes.QuerySpendableBalancesResponse, error) { + return k.bk.SpendableBalances(ctx, req) +} + +func (k Keeper) BlockedAddr(addr sdk.AccAddress) bool { + return k.bk.BlockedAddr(addr) +} + // NewKeeper creates a new keeper func NewKeeper( cdc codec.BinaryCodec, diff --git a/x/precisebank/types/interfaces.go b/x/precisebank/types/interfaces.go index 1e94c8be..1330c5b5 100644 --- a/x/precisebank/types/interfaces.go +++ b/x/precisebank/types/interfaces.go @@ -2,6 +2,7 @@ package types import ( "context" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -20,6 +21,7 @@ type BankKeeper interface { GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin GetSupply(ctx context.Context, denom string) sdk.Coin SpendableCoin(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin + SpendableBalances(ctx context.Context, req *banktypes.QuerySpendableBalancesRequest) (*banktypes.QuerySpendableBalancesResponse, error) BlockedAddr(addr sdk.AccAddress) bool diff --git a/x/precisebank/types/mocks/MockBankKeeper.go b/x/precisebank/types/mocks/MockBankKeeper.go index ff2b8801..ae3a15d3 100644 --- a/x/precisebank/types/mocks/MockBankKeeper.go +++ b/x/precisebank/types/mocks/MockBankKeeper.go @@ -16,6 +16,11 @@ type MockBankKeeper struct { mock.Mock } +func (_m *MockBankKeeper) SpendableBalances(ctx context.Context, req *types.QuerySpendableBalancesRequest) (*types.QuerySpendableBalancesResponse, error) { + //TODO implement me + panic("implement me") +} + type MockBankKeeper_Expecter struct { mock *mock.Mock } diff --git a/x/vm/keeper/account_migration.go b/x/vm/keeper/account_migration.go new file mode 100644 index 00000000..4eb77ec1 --- /dev/null +++ b/x/vm/keeper/account_migration.go @@ -0,0 +1,208 @@ +package keeper + +import ( + "cosmossdk.io/math" + "cosmossdk.io/x/feegrant" + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting/exported" + "github.com/cosmos/cosmos-sdk/x/authz" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// =============== +// === Staking === +// =============== +func (k *Keeper) migrateDelegations(ctx sdk.Context, originalAddress sdk.AccAddress, maxValidators uint16, newAddress sdk.AccAddress) error { + bondDenom, err := k.stakingKeeper.BondDenom(ctx) + if err != nil { + return err + } + + // Check if the account is a vesting account + acc := k.accountKeeper.GetAccount(ctx, originalAddress) + + // remaining vesting delegation + var remainingVestingDelegation int64 = 0 + var isVestingAccount = false + + if acc != nil { + acc, ok := acc.(vesting.VestingAccount) + if ok { + isVestingAccount = true + remainingVestingDelegation = acc.GetDelegatedFree().AmountOf(bondDenom).Int64() + } + } + + delegations, err := k.stakingKeeper.GetDelegatorDelegations(ctx, originalAddress, maxValidators) + + for _, delegation := range delegations { + validatorAddress, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress) + if err != nil { + return err + } + + // Seems like we don't need to go through the whole unbond -> send to user -> send to new address -> bond + // and that we can remove / reset the delegation instead. Tokens aren't moving anywhere anyways + sharesToUnbond := delegation.GetShares() + + if isVestingAccount { + // if there are no unlocked tokens remaining, we return from the function and terminate delegation migration + if remainingVestingDelegation <= 0 { + return nil + } + + if remainingVestingDelegation < sharesToUnbond.TruncateInt64() { + sharesToUnbond = math.LegacyNewDec(remainingVestingDelegation) + remainingVestingDelegation = 0 + } + } + + _, err = k.stakingKeeper.Unbond(ctx, originalAddress, validatorAddress, sharesToUnbond) + if err != nil { + return err + } + + err = k.stakingKeeper.SetDelegation(ctx, stakingtypes.Delegation{ + DelegatorAddress: newAddress.String(), + ValidatorAddress: delegation.ValidatorAddress, + Shares: sharesToUnbond, + }) + if err != nil { + return err + } + + } + return nil +} + +// ============ +// === Bank === +// ============ +func (k *Keeper) migrateBankTokens(err error, ctx sdk.Context, originalAddress sdk.AccAddress, maxTokens uint64, newAddress sdk.AccAddress) error { + balancesResponse, err := k.bankWrapper.SpendableBalances(ctx, &banktypes.QuerySpendableBalancesRequest{ + Address: originalAddress.String(), + Pagination: &query.PageRequest{ + Key: nil, + Offset: 0, + Limit: maxTokens, + CountTotal: false, + Reverse: false, + }, + }) + if err != nil { + return err + } + + balances := balancesResponse.Balances + + err = k.bankWrapper.SendCoins(ctx, originalAddress, newAddress, balances) + if err != nil { + return err + } + return nil +} + +// ================ +// === Feegrant === +// ================ +func (k *Keeper) migrateFeeGrants(ctx sdk.Context, originalAddress sdk.AccAddress, maxFeeGrants uint64, newAddress sdk.AccAddress) error { + allowancesResponse, err := k.feegrantKeeper.AllowancesByGranter(ctx, &feegrant.QueryAllowancesByGranterRequest{ + Granter: originalAddress.String(), + Pagination: &query.PageRequest{ + Key: nil, + Offset: 0, + Limit: maxFeeGrants, + CountTotal: false, + Reverse: false, + }, + }) + if err != nil { + return err + } + + allowances := allowancesResponse.Allowances + + for _, grant := range allowances { + //todo: when keeper call is introduced for revoking, replace this call with it: https://github.com/cosmos/cosmos-sdk/issues/24773 + msgRevoke := feegrant.MsgRevokeAllowance{ + Granter: grant.Granter, + Grantee: grant.Grantee, + } + k.Router().Handler(&msgRevoke) + + granteeAddress, err := sdk.AccAddressFromBech32(grant.Grantee) + if err != nil { + return err + } + + var allowance feegrant.FeeAllowanceI + + // todo: test this + err = k.cdc.UnpackAny(grant.Allowance, &allowance) + if err != nil { + return fmt.Errorf("unknown message type: %s", grant.Allowance.TypeUrl) + } + + err = k.feegrantKeeper.GrantAllowance(ctx, newAddress, granteeAddress, allowance) + if err != nil { + return err + } + } + return nil +} + +// ============= +// === Authz === +// ============= +func (k *Keeper) migrateAuthzGrants(ctx sdk.Context, originalAddress sdk.AccAddress, maxAuthzGrants uint64) error { + authzGrantsResponse, err := k.authzKeeper.GranterGrants(ctx, &authz.QueryGranterGrantsRequest{ + Granter: originalAddress.String(), + Pagination: &query.PageRequest{ + Key: nil, + Offset: 0, + Limit: maxAuthzGrants, + CountTotal: false, + Reverse: false, + }, + }) + if err != nil { + return err + } + + authzGrants := authzGrantsResponse.Grants + + for _, grant := range authzGrants { + granteeAddress, err := sdk.AccAddressFromBech32(grant.Granter) + if err != nil { + return err + } + + granterAddress, err := sdk.AccAddressFromBech32(grant.Granter) + if err != nil { + return err + } + + // todo: is the message type string the same as the type url? + err = k.authzKeeper.DeleteGrant(ctx, granteeAddress, granterAddress, grant.Authorization.TypeUrl) + if err != nil { + return err + } + + var authorization authz.Authorization + + // todo: test this + err = k.cdc.UnpackAny(grant.Authorization, &authorization) + if err != nil { + return fmt.Errorf("unknown message type: %s", grant.Authorization.TypeUrl) + } + + err = k.authzKeeper.SaveGrant(ctx, granteeAddress, granterAddress, authorization, grant.Expiration) + if err != nil { + return err + } + } + return nil +} diff --git a/x/vm/keeper/integration_test.go b/x/vm/keeper/integration_test.go index d70dd1ad..a5438c39 100644 --- a/x/vm/keeper/integration_test.go +++ b/x/vm/keeper/integration_test.go @@ -1,7 +1,10 @@ package keeper_test import ( + factory2 "github.com/cosmos/evm/testutil/integration/common/factory" "math/big" + "testing" + "time" "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" @@ -14,7 +17,6 @@ import ( abcitypes "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/evm/contracts" - "github.com/cosmos/evm/precompiles/staking" "github.com/cosmos/evm/testutil/integration/os/factory" "github.com/cosmos/evm/testutil/integration/os/grpc" testkeyring "github.com/cosmos/evm/testutil/integration/os/keyring" @@ -23,8 +25,14 @@ import ( evmtypes "github.com/cosmos/evm/x/vm/types" "cosmossdk.io/math" + "cosmossdk.io/x/feegrant" sdktypes "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/authz" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" ) type IntegrationTestSuite struct { @@ -34,6 +42,12 @@ type IntegrationTestSuite struct { keyring testkeyring.Keyring } +func TestVMIntegrationTestSuite(t *testing.T) { + // Run Ginkgo integration tests + RegisterFailHandler(Fail) + RunSpecs(t, "Keeper Suite") +} + // This test suite is meant to test the EVM module in the context of the ATOM. // It uses the integration test framework to spin up a local ATOM network and // perform transactions on it. @@ -292,369 +306,1225 @@ var _ = Describe("Handling a MsgEthereumTx message", Label("EVM"), Ordered, func }) }) - DescribeTable("Performs transfer and contract call", func(getTestParams func() evmtypes.Params, transferParams, contractCallParams PermissionsTableTest) { - params := getTestParams() - err := integrationutils.UpdateEvmParams( - integrationutils.UpdateParamsInput{ - Tf: s.factory, - Network: s.network, - Pk: s.keyring.GetPrivKey(0), - Params: params, - }, - ) - Expect(err).To(BeNil()) + //DescribeTable("Performs transfer and contract call", func(getTestParams func() evmtypes.Params, transferParams, contractCallParams PermissionsTableTest) { + // params := getTestParams() + // err := integrationutils.UpdateEvmParams( + // integrationutils.UpdateParamsInput{ + // Tf: s.factory, + // Network: s.network, + // Pk: s.keyring.GetPrivKey(0), + // Params: params, + // }, + // ) + // Expect(err).To(BeNil()) + // + // err = s.network.NextBlock() + // Expect(err).To(BeNil()) + // + // signer := s.keyring.GetKey(transferParams.SignerIndex) + // receiver := s.keyring.GetKey(1) + // txArgs := evmtypes.EvmTxArgs{ + // To: &receiver.Addr, + // Amount: big.NewInt(1000), + // // Hard coded gas limit to avoid failure on gas estimation because + // // of the param + // GasLimit: 100000, + // } + // res, err := s.factory.ExecuteEthTx(signer.Priv, txArgs) + // if transferParams.ExpFail { + // Expect(err).NotTo(BeNil()) + // Expect(err.Error()).To(ContainSubstring("does not have permission to perform a call")) + // } else { + // Expect(err).To(BeNil()) + // Expect(res.IsOK()).To(Equal(true), "transaction should have succeeded", res.GetLog()) + // } + // + // senderKey := s.keyring.GetKey(contractCallParams.SignerIndex) + // contractAddress := common.HexToAddress(evmtypes.StakingPrecompileAddress) + // validatorAddress := s.network.GetValidators()[1].OperatorAddress + // contractABI, err := staking.LoadABI() + // Expect(err).To(BeNil()) + // + // // If grpc query fails, that means there were no previous delegations + // prevDelegation := big.NewInt(0) + // prevDelegationRes, err := s.grpcHandler.GetDelegation(senderKey.AccAddr.String(), validatorAddress) + // if err == nil { + // prevDelegation = prevDelegationRes.DelegationResponse.Balance.Amount.BigInt() + // } + // + // amountToDelegate := big.NewInt(200) + // totalSupplyTxArgs := evmtypes.EvmTxArgs{ + // To: &contractAddress, + // } + // + // // Perform a delegate transaction to the staking precompile + // delegateArgs := factory.CallArgs{ + // ContractABI: contractABI, + // MethodName: staking.DelegateMethod, + // Args: []interface{}{senderKey.Addr, validatorAddress, amountToDelegate}, + // } + // delegateResponse, err := s.factory.ExecuteContractCall(senderKey.Priv, totalSupplyTxArgs, delegateArgs) + // if contractCallParams.ExpFail { + // Expect(err).NotTo(BeNil()) + // Expect(err.Error()).To(ContainSubstring("does not have permission to perform a call")) + // } else { + // Expect(err).To(BeNil()) + // Expect(delegateResponse.IsOK()).To(Equal(true), "transaction should have succeeded", delegateResponse.GetLog()) + // + // err = s.network.NextBlock() + // Expect(err).To(BeNil()) + // + // // Perform query to check the delegation was successful + // queryDelegationArgs := factory.CallArgs{ + // ContractABI: contractABI, + // MethodName: staking.DelegationMethod, + // Args: []interface{}{senderKey.Addr, validatorAddress}, + // } + // queryDelegationResponse, err := s.factory.ExecuteContractCall(senderKey.Priv, totalSupplyTxArgs, queryDelegationArgs) + // Expect(err).To(BeNil()) + // Expect(queryDelegationResponse.IsOK()).To(Equal(true), "transaction should have succeeded", queryDelegationResponse.GetLog()) + // + // // Make sure the delegation amount is correct + // var delegationOutput staking.DelegationOutput + // err = integrationutils.DecodeContractCallResponse(&delegationOutput, queryDelegationArgs, queryDelegationResponse) + // Expect(err).To(BeNil()) + // + // expectedDelegationAmt := amountToDelegate.Add(amountToDelegate, prevDelegation) + // Expect(delegationOutput.Balance.Amount.String()).To(Equal(expectedDelegationAmt.String())) + // } + //}, + // // Entry("transfer and call fail with CALL permission policy set to restricted", func() evmtypes.Params { + // // // Set params to default values + // // defaultParams := evmtypes.DefaultParams() + // // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // // AccessType: evmtypes.AccessTypeRestricted, + // // } + // // return defaultParams + // // }, + // // OpcodeTestTable{ExpFail: true, SignerIndex: 0}, + // // OpcodeTestTable{ExpFail: true, SignerIndex: 0}, + // // ), + // Entry("transfer and call succeed with CALL permission policy set to default and CREATE permission policy set to restricted", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Create = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypeRestricted, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // ), + // Entry("transfer and call are successful with CALL permission policy set to permissionless and address not blocked", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissionless, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // ), + // Entry("transfer fails with signer blocked and call succeeds with signer NOT blocked permission policy set to permissionless", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissionless, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: true, SignerIndex: 1}, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // ), + // Entry("transfer succeeds with signer NOT blocked and call fails with signer blocked permission policy set to permissionless", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissionless, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: true, SignerIndex: 1}, + // ), + // Entry("transfer and call succeeds with CALL permission policy set to permissioned and signer whitelisted on both", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissioned, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 1}, + // PermissionsTableTest{ExpFail: false, SignerIndex: 1}, + // ), + // Entry("transfer and call fails with CALL permission policy set to permissioned and signer not whitelisted on both", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissioned, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: true, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: true, SignerIndex: 0}, + // ), + //) + // + //DescribeTable("Performs contract deployment and contract call with AccessControl", func(getTestParams func() evmtypes.Params, createParams, callParams PermissionsTableTest) { + // params := getTestParams() + // err := integrationutils.UpdateEvmParams( + // integrationutils.UpdateParamsInput{ + // Tf: s.factory, + // Network: s.network, + // Pk: s.keyring.GetPrivKey(0), + // Params: params, + // }, + // ) + // Expect(err).To(BeNil()) + // + // err = s.network.NextBlock() + // Expect(err).To(BeNil()) + // + // createSigner := s.keyring.GetPrivKey(createParams.SignerIndex) + // constructorArgs := []interface{}{"coin", "token", uint8(18)} + // compiledContract := contracts.ERC20MinterBurnerDecimalsContract + // + // contractAddr, err := s.factory.DeployContract( + // createSigner, + // evmtypes.EvmTxArgs{}, // Default values + // factory.ContractDeploymentData{ + // Contract: compiledContract, + // ConstructorArgs: constructorArgs, + // }, + // ) + // if createParams.ExpFail { + // Expect(err).NotTo(BeNil()) + // Expect(err.Error()).To(ContainSubstring("does not have permission to deploy contracts")) + // // If contract deployment is expected to fail, we can skip the rest of the test + // return + // } + // + // Expect(err).To(BeNil()) + // Expect(contractAddr).ToNot(Equal(common.Address{})) + // + // err = s.network.NextBlock() + // Expect(err).To(BeNil()) + // + // callSigner := s.keyring.GetPrivKey(callParams.SignerIndex) + // totalSupplyTxArgs := evmtypes.EvmTxArgs{ + // To: &contractAddr, + // } + // totalSupplyArgs := factory.CallArgs{ + // ContractABI: compiledContract.ABI, + // MethodName: "totalSupply", + // Args: []interface{}{}, + // } + // res, err := s.factory.ExecuteContractCall(callSigner, totalSupplyTxArgs, totalSupplyArgs) + // if callParams.ExpFail { + // Expect(err).NotTo(BeNil()) + // Expect(err.Error()).To(ContainSubstring("does not have permission to perform a call")) + // } else { + // Expect(err).To(BeNil()) + // Expect(res.IsOK()).To(Equal(true), "transaction should have succeeded", res.GetLog()) + // } + //}, + // Entry("Create and call is successful with create permission policy set to permissionless and address not blocked ", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Create = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissionless, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // ), + // Entry("Create fails with create permission policy set to permissionless and signer is blocked ", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Create = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissionless, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: true, SignerIndex: 1}, + // PermissionsTableTest{}, // Call should not be executed + // ), + // Entry("Create and call is successful with call permission policy set to permissionless and address not blocked ", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissionless, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // ), + // Entry("Create is successful and call fails with call permission policy set to permissionless and address blocked ", func() evmtypes.Params { + // blockedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissionless, + // AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: true, SignerIndex: 1}, + // ), + // Entry("Create fails create permission policy set to restricted", func() evmtypes.Params { + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Create = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypeRestricted, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: true, SignerIndex: 0}, + // PermissionsTableTest{}, // Call should not be executed + // ), + // Entry("Create succeeds and call fails when call permission policy set to restricted", func() evmtypes.Params { + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypeRestricted, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: true, SignerIndex: 0}, + // ), + // Entry("Create and call are successful with create permission policy set to permissioned and signer whitelisted", func() evmtypes.Params { + // whitelistedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Create = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissioned, + // AccessControlList: []string{s.keyring.GetAddr(whitelistedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 1}, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // ), + // Entry("Create fails with create permission policy set to permissioned and signer NOT whitelisted", func() evmtypes.Params { + // whitelistedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Create = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissioned, + // AccessControlList: []string{s.keyring.GetAddr(whitelistedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: true, SignerIndex: 0}, + // PermissionsTableTest{}, + // ), + // Entry("Create and call are successful with call permission policy set to permissioned and signer whitelisted", func() evmtypes.Params { + // whitelistedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissioned, + // AccessControlList: []string{s.keyring.GetAddr(whitelistedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: false, SignerIndex: 1}, + // ), + // Entry("Create succeeds and call fails with call permission policy set to permissioned and signer NOT whitelisted", func() evmtypes.Params { + // whitelistedSignerIndex := 1 + // // Set params to default values + // defaultParams := evmtypes.DefaultParams() + // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ + // AccessType: evmtypes.AccessTypePermissioned, + // AccessControlList: []string{s.keyring.GetAddr(whitelistedSignerIndex).String()}, + // } + // return defaultParams + // }, + // PermissionsTableTest{ExpFail: false, SignerIndex: 0}, + // PermissionsTableTest{ExpFail: true, SignerIndex: 0}, + // ), + //) - err = s.network.NextBlock() - Expect(err).To(BeNil()) + // ========================================== + // Account Migration Integration Tests + // ========================================== - signer := s.keyring.GetKey(transferParams.SignerIndex) - receiver := s.keyring.GetKey(1) - txArgs := evmtypes.EvmTxArgs{ - To: &receiver.Addr, - Amount: big.NewInt(1000), - // Hard coded gas limit to avoid failure on gas estimation because - // of the param - GasLimit: 100000, - } - res, err := s.factory.ExecuteEthTx(signer.Priv, txArgs) - if transferParams.ExpFail { - Expect(err).NotTo(BeNil()) - Expect(err.Error()).To(ContainSubstring("does not have permission to perform a call")) - } else { - Expect(err).To(BeNil()) - Expect(res.IsOK()).To(Equal(true), "transaction should have succeeded", res.GetLog()) - } + When("testing account migration functionality", Label("Migration"), Ordered, func() { + BeforeAll(func() { + keyring := testkeyring.New(8) + integrationNetwork := network.New( + network.WithPreFundedAccounts(keyring.GetAllAccAddrs()...), + ) + grpcHandler := grpc.NewIntegrationHandler(integrationNetwork) + txFactory := factory.New(integrationNetwork, grpcHandler) + s = &IntegrationTestSuite{ + network: integrationNetwork, + factory: txFactory, + grpcHandler: grpcHandler, + keyring: keyring, + } + }) - senderKey := s.keyring.GetKey(contractCallParams.SignerIndex) - contractAddress := common.HexToAddress(evmtypes.StakingPrecompileAddress) - validatorAddress := s.network.GetValidators()[1].OperatorAddress - contractABI, err := staking.LoadABI() - Expect(err).To(BeNil()) + Context("Bank Token Migration", func() { + It("should successfully migrate bank tokens between accounts", func() { + originalKey := s.keyring.GetKey(0) + newKey := s.keyring.GetKey(1) + denom := s.network.GetBaseDenom() - // If grpc query fails, that means there were no previous delegations - prevDelegation := big.NewInt(0) - prevDelegationRes, err := s.grpcHandler.GetDelegation(senderKey.AccAddr.String(), validatorAddress) - if err == nil { - prevDelegation = prevDelegationRes.DelegationResponse.Balance.Amount.BigInt() - } + // Get initial balances + originalBalance, err := s.grpcHandler.GetBalanceFromBank(originalKey.AccAddr, denom) + Expect(err).To(BeNil()) + originalAmount := originalBalance.GetBalance().Amount - amountToDelegate := big.NewInt(200) - totalSupplyTxArgs := evmtypes.EvmTxArgs{ - To: &contractAddress, - } + newBalance, err := s.grpcHandler.GetBalanceFromBank(newKey.AccAddr, denom) + Expect(err).To(BeNil()) + newAmount := newBalance.GetBalance().Amount - // Perform a delegate transaction to the staking precompile - delegateArgs := factory.CallArgs{ - ContractABI: contractABI, - MethodName: staking.DelegateMethod, - Args: []interface{}{senderKey.Addr, validatorAddress, amountToDelegate}, - } - delegateResponse, err := s.factory.ExecuteContractCall(senderKey.Priv, totalSupplyTxArgs, delegateArgs) - if contractCallParams.ExpFail { - Expect(err).NotTo(BeNil()) - Expect(err.Error()).To(ContainSubstring("does not have permission to perform a call")) - } else { - Expect(err).To(BeNil()) - Expect(delegateResponse.IsOK()).To(Equal(true), "transaction should have succeeded", delegateResponse.GetLog()) + // Execute migration + msg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } - err = s.network.NextBlock() - Expect(err).To(BeNil()) + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{msg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "migration should have succeeded", res.GetLog()) - // Perform query to check the delegation was successful - queryDelegationArgs := factory.CallArgs{ - ContractABI: contractABI, - MethodName: staking.DelegationMethod, - Args: []interface{}{senderKey.Addr, validatorAddress}, - } - queryDelegationResponse, err := s.factory.ExecuteContractCall(senderKey.Priv, totalSupplyTxArgs, queryDelegationArgs) - Expect(err).To(BeNil()) - Expect(queryDelegationResponse.IsOK()).To(Equal(true), "transaction should have succeeded", queryDelegationResponse.GetLog()) + err = s.network.NextBlock() + Expect(err).To(BeNil()) - // Make sure the delegation amount is correct - var delegationOutput staking.DelegationOutput - err = integrationutils.DecodeContractCallResponse(&delegationOutput, queryDelegationArgs, queryDelegationResponse) - Expect(err).To(BeNil()) + // Verify balances after migration + originalBalanceAfter, err := s.grpcHandler.GetBalanceFromBank(originalKey.AccAddr, denom) + Expect(err).To(BeNil()) + Expect(originalBalanceAfter.GetBalance().Amount.IsZero()).To(BeTrue(), "original account should have zero balance") - expectedDelegationAmt := amountToDelegate.Add(amountToDelegate, prevDelegation) - Expect(delegationOutput.Balance.Amount.String()).To(Equal(expectedDelegationAmt.String())) - } - }, - // Entry("transfer and call fail with CALL permission policy set to restricted", func() evmtypes.Params { - // // Set params to default values - // defaultParams := evmtypes.DefaultParams() - // defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - // AccessType: evmtypes.AccessTypeRestricted, - // } - // return defaultParams - // }, - // OpcodeTestTable{ExpFail: true, SignerIndex: 0}, - // OpcodeTestTable{ExpFail: true, SignerIndex: 0}, - // ), - Entry("transfer and call succeed with CALL permission policy set to default and CREATE permission policy set to restricted", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Create = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypeRestricted, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - ), - Entry("transfer and call are successful with CALL permission policy set to permissionless and address not blocked", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissionless, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - ), - Entry("transfer fails with signer blocked and call succeeds with signer NOT blocked permission policy set to permissionless", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissionless, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: true, SignerIndex: 1}, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - ), - Entry("transfer succeeds with signer NOT blocked and call fails with signer blocked permission policy set to permissionless", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissionless, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + newBalanceAfter, err := s.grpcHandler.GetBalanceFromBank(newKey.AccAddr, denom) + Expect(err).To(BeNil()) + expectedNewBalance := newAmount.Add(originalAmount) + Expect(newBalanceAfter.GetBalance().Amount).To(Equal(expectedNewBalance), "new account should have combined balance") + }) + + It("should handle multiple denominations correctly", func() { + originalKey := s.keyring.GetKey(2) + newKey := s.keyring.GetKey(3) + + // Execute migration + msg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } + + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{msg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "migration should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify all denominations were transferred + balances, err := s.grpcHandler.GetAllBalances(newKey.AccAddr) + Expect(err).To(BeNil()) + Expect(len(balances.GetBalances())).To(BeNumerically(">=", 1)) + }) + }) + + Context("Delegation Migration", func() { + It("should successfully migrate delegations", func() { + originalKey := s.keyring.GetKey(0) + newKey := s.keyring.GetKey(1) + validators := s.network.GetValidators() + Expect(len(validators)).To(BeNumerically(">=", 1)) + + validatorAddr := validators[0].OperatorAddress + delegationAmount := math.NewInt(1000000) // 1 token with 6 decimals + + // Create delegation from original account + delegateMsg := &stakingtypes.MsgDelegate{ + DelegatorAddress: originalKey.AccAddr.String(), + ValidatorAddress: validatorAddr, + Amount: sdktypes.NewCoin(s.network.GetBaseDenom(), delegationAmount), + } + + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{delegateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "delegation should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify delegation exists + delegation, err := s.grpcHandler.GetDelegation(originalKey.AccAddr.String(), validatorAddr) + Expect(err).To(BeNil()) + Expect(delegation.DelegationResponse.Balance.Amount).To(Equal(delegationAmount)) + + // Execute migration + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } + + res, err = s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "migration should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify delegation moved to new account + _, err = s.grpcHandler.GetDelegation(originalKey.AccAddr.String(), validatorAddr) + Expect(err).ToNot(BeNil(), "original account should have no delegations") + + newDelegation, err := s.grpcHandler.GetDelegation(newKey.AccAddr.String(), validatorAddr) + Expect(err).To(BeNil()) + Expect(newDelegation.DelegationResponse.Balance.Amount).To(Equal(delegationAmount)) + }) + + It("should handle multiple delegations across validators", func() { + originalKey := s.keyring.GetKey(2) + newKey := s.keyring.GetKey(3) + validators := s.network.GetValidators() + Expect(len(validators)).To(BeNumerically(">=", 2)) + + delegationAmount := math.NewInt(500000) + + // Create delegations to multiple validators + for i, validator := range validators[:2] { + delegateMsg := &stakingtypes.MsgDelegate{ + DelegatorAddress: originalKey.AccAddr.String(), + ValidatorAddress: validator.OperatorAddress, + Amount: sdktypes.NewCoin(s.network.GetBaseDenom(), delegationAmount), + } + + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{delegateMsg}, + }) + Expect(err).To(BeNil(), "delegation %d should have succeeded", i) + Expect(res.IsOK()).To(Equal(true), "delegation should have succeeded", res.GetLog()) + } + + err := s.network.NextBlock() + Expect(err).To(BeNil()) + + // Execute migration + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } + + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "migration should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify all delegations moved + for _, validator := range validators[:2] { + newDelegation, err := s.grpcHandler.GetDelegation(newKey.AccAddr.String(), validator.OperatorAddress) + Expect(err).To(BeNil()) + Expect(newDelegation.DelegationResponse.Balance.Amount).To(Equal(delegationAmount)) + } + }) + }) + + Context("Fee Grant Migration", func() { + It("should successfully migrate fee grants", func() { + granterKey := s.keyring.GetKey(0) + granteeKey := s.keyring.GetKey(1) + newGranterKey := s.keyring.GetKey(2) + + // Create fee grant + allowance := &feegrant.BasicAllowance{ + SpendLimit: sdktypes.NewCoins(sdktypes.NewCoin(s.network.GetBaseDenom(), math.NewInt(1000000))), + } + + grantMsg := &feegrant.MsgGrantAllowance{ + Granter: granterKey.AccAddr.String(), + Grantee: granteeKey.AccAddr.String(), + Allowance: codectypes.UnsafePackAny(allowance), + } + + res, err := s.factory.ExecuteCosmosTx(granterKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{grantMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "fee grant should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify grant exists + grant, err := s.grpcHandler.Allowance(granterKey.AccAddr.String(), granteeKey.AccAddr.String()) + Expect(err).To(BeNil()) + Expect(grant.Allowance).ToNot(BeNil()) + + // Execute migration + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: granterKey.AccAddr.String(), + NewAddress: newGranterKey.AccAddr.String(), + } + + res, err = s.factory.ExecuteCosmosTx(granterKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "migration should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify grant moved to new granter + _, err = s.grpcHandler.Allowance(granterKey.AccAddr.String(), granteeKey.AccAddr.String()) + Expect(err).ToNot(BeNil(), "original granter should have no grants") + + newGrant, err := s.grpcHandler.Allowance(newGranterKey.AccAddr.String(), granteeKey.AccAddr.String()) + Expect(err).To(BeNil()) + Expect(newGrant.Allowance).ToNot(BeNil()) + }) + + It("should handle multiple fee grants", func() { + granterKey := s.keyring.GetKey(0) + grantee1Key := s.keyring.GetKey(1) + grantee2Key := s.keyring.GetKey(2) + newGranterKey := s.keyring.GetKey(3) + + // Create multiple fee grants + grantees := []testkeyring.Key{grantee1Key, grantee2Key} + for i, grantee := range grantees { + allowance := &feegrant.BasicAllowance{ + SpendLimit: sdktypes.NewCoins(sdktypes.NewCoin(s.network.GetBaseDenom(), math.NewInt(int64((i+1)*100000)))), + } + + grantMsg := &feegrant.MsgGrantAllowance{ + Granter: granterKey.AccAddr.String(), + Grantee: grantee.AccAddr.String(), + Allowance: codectypes.UnsafePackAny(allowance), + } + + res, err := s.factory.ExecuteCosmosTx(granterKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{grantMsg}, + }) + Expect(err).To(BeNil(), "fee grant %d should have succeeded", i) + Expect(res.IsOK()).To(Equal(true), "fee grant should have succeeded", res.GetLog()) + } + + err := s.network.NextBlock() + Expect(err).To(BeNil()) + + // Execute migration + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: granterKey.AccAddr.String(), + NewAddress: newGranterKey.AccAddr.String(), + } + + res, err := s.factory.ExecuteCosmosTx(granterKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "migration should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify all grants moved + for _, grantee := range grantees { + newGrant, err := s.grpcHandler.Allowance(newGranterKey.AccAddr.String(), grantee.AccAddr.String()) + Expect(err).To(BeNil()) + Expect(newGrant.Allowance).ToNot(BeNil()) + } + }) + }) + + Context("Authorization (Authz) Migration", func() { + It("should successfully migrate authz grants", func() { + granterKey := s.keyring.GetKey(0) + granteeKey := s.keyring.GetKey(1) + newGranterKey := s.keyring.GetKey(2) + + // Create authz grant + authorization := &banktypes.SendAuthorization{ + SpendLimit: sdktypes.NewCoins(sdktypes.NewCoin(s.network.GetBaseDenom(), math.NewInt(1000000))), + } + + grantMsg := &authz.MsgGrant{ + Granter: granterKey.AccAddr.String(), + Grantee: granteeKey.AccAddr.String(), + Grant: authz.Grant{ + Authorization: codectypes.UnsafePackAny(authorization), + Expiration: &time.Time{}, // No expiration + }, + } + + res, err := s.factory.ExecuteCosmosTx(granterKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{grantMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "authz grant should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify grant exists + grants, err := s.grpcHandler.GetGrants(granterKey.AccAddr.String(), granteeKey.AccAddr.String()) + Expect(err).To(BeNil()) + Expect(len(grants)).To(BeNumerically(">", 0)) + + // Execute migration + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: granterKey.AccAddr.String(), + NewAddress: newGranterKey.AccAddr.String(), + } + + res, err = s.factory.ExecuteCosmosTx(granterKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "migration should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify grant moved to new granter + _, err = s.grpcHandler.GetGrants(granterKey.AccAddr.String(), granteeKey.AccAddr.String()) + Expect(err).ToNot(BeNil(), "original granter should have no grants") + + newGrants, err := s.grpcHandler.GetGrants(newGranterKey.AccAddr.String(), granteeKey.AccAddr.String()) + Expect(err).To(BeNil()) + Expect(len(newGrants)).To(BeNumerically(">", 0)) + }) + }) + + Context("Complete Migration Scenarios", func() { + It("should migrate all account data in one transaction", func() { + originalKey := s.keyring.GetKey(0) + newKey := s.keyring.GetKey(1) + granteeKey := s.keyring.GetKey(2) + + // Setup account with multiple types of data + validators := s.network.GetValidators() + validatorAddr := validators[0].OperatorAddress + baseDenom := s.network.GetBaseDenom() + + // 1. Create delegation + delegateMsg := &stakingtypes.MsgDelegate{ + DelegatorAddress: originalKey.AccAddr.String(), + ValidatorAddress: validatorAddr, + Amount: sdktypes.NewCoin(baseDenom, math.NewInt(1000000)), + } + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{delegateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + // 2. Create fee grant + allowance := &feegrant.BasicAllowance{ + SpendLimit: sdktypes.NewCoins(sdktypes.NewCoin(baseDenom, math.NewInt(500000))), + } + grantMsg := &feegrant.MsgGrantAllowance{ + Granter: originalKey.AccAddr.String(), + Grantee: granteeKey.AccAddr.String(), + Allowance: codectypes.UnsafePackAny(allowance), + } + res, err = s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{grantMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + // 3. Create authz grant + authorization := &banktypes.SendAuthorization{ + SpendLimit: sdktypes.NewCoins(sdktypes.NewCoin(baseDenom, math.NewInt(300000))), + } + authzGrantMsg := &authz.MsgGrant{ + Granter: originalKey.AccAddr.String(), + Grantee: granteeKey.AccAddr.String(), + Grant: authz.Grant{ + Authorization: codectypes.UnsafePackAny(authorization), + }, + } + res, err = s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{authzGrantMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Get original balance + originalBalance, err := s.grpcHandler.GetBalanceFromBank(originalKey.AccAddr, baseDenom) + Expect(err).To(BeNil()) + + // Execute migration + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } + + res, err = s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "complete migration should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify all data migrated + // 1. Check delegation + newDelegation, err := s.grpcHandler.GetDelegation(newKey.AccAddr.String(), validatorAddr) + Expect(err).To(BeNil()) + Expect(newDelegation.DelegationResponse.Balance.Amount).To(Equal(math.NewInt(1000000))) + + // 2. Check fee grant + newFeeGrant, err := s.grpcHandler.Allowance(newKey.AccAddr.String(), granteeKey.AccAddr.String()) + Expect(err).To(BeNil()) + Expect(newFeeGrant.Allowance).ToNot(BeNil()) + + // 3. Check authz grant + newAuthzGrants, err := s.grpcHandler.GetGrants(newKey.AccAddr.String(), granteeKey.AccAddr.String()) + Expect(err).To(BeNil()) + Expect(len(newAuthzGrants)).To(BeNumerically(">", 0)) + + // 4. Check bank balance + newBalance, err := s.grpcHandler.GetBalanceFromBank(newKey.AccAddr, baseDenom) + Expect(err).To(BeNil()) + Expect(newBalance.GetBalance().Amount.GT(originalBalance.GetBalance().Amount)).To(BeTrue()) + }) + }) + + Context("Error Scenarios", func() { + It("should fail with invalid original address", func() { + newKey := s.keyring.GetKey(1) + + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: "invalid-address", + NewAddress: newKey.AccAddr.String(), + } + + _, err := s.factory.ExecuteCosmosTx(s.keyring.GetPrivKey(0), factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("invalid address")) + }) + + It("should fail with invalid new address", func() { + originalKey := s.keyring.GetKey(0) + + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: "invalid-address", + } + + _, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("invalid address")) + }) + + It("should fail when original address has no permissions", func() { + unauthorizedKey := s.keyring.GetKey(4) // Different key than the original + originalKey := s.keyring.GetKey(0) + newKey := s.keyring.GetKey(1) + + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } + + _, err := s.factory.ExecuteCosmosTx(unauthorizedKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("unauthorized")) + }) + }) + + DescribeTable("Migration with different signer scenarios", func(migrationTest MigrationTestCase) { + originalKey := s.keyring.GetKey(migrationTest.OriginalKeyIndex) + newKey := s.keyring.GetKey(migrationTest.NewKeyIndex) + signerKey := s.keyring.GetKey(migrationTest.SignerKeyIndex) + + // Setup some data to migrate + if migrationTest.SetupData { + validators := s.network.GetValidators() + if len(validators) > 0 { + delegateMsg := &stakingtypes.MsgDelegate{ + DelegatorAddress: originalKey.AccAddr.String(), + ValidatorAddress: validators[0].OperatorAddress, + Amount: sdktypes.NewCoin(s.network.GetBaseDenom(), math.NewInt(100000)), + } + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{delegateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + } } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - PermissionsTableTest{ExpFail: true, SignerIndex: 1}, - ), - Entry("transfer and call succeeds with CALL permission policy set to permissioned and signer whitelisted on both", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissioned, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 1}, - PermissionsTableTest{ExpFail: false, SignerIndex: 1}, - ), - Entry("transfer and call fails with CALL permission policy set to permissioned and signer not whitelisted on both", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissioned, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, + + res, err := s.factory.ExecuteCosmosTx(signerKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + + if migrationTest.ExpectError { + Expect(err).ToNot(BeNil()) + if migrationTest.ErrorSubstring != "" { + Expect(err.Error()).To(ContainSubstring(migrationTest.ErrorSubstring)) + } + } else { + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "migration should have succeeded", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify migration occurred + if migrationTest.SetupData { + validators := s.network.GetValidators() + if len(validators) > 0 { + newDelegation, err := s.grpcHandler.GetDelegation(newKey.AccAddr.String(), validators[0].OperatorAddress) + Expect(err).To(BeNil()) + Expect(newDelegation.DelegationResponse.Balance.Amount).To(Equal(math.NewInt(100000))) + } + } } - return defaultParams }, - PermissionsTableTest{ExpFail: true, SignerIndex: 0}, - PermissionsTableTest{ExpFail: true, SignerIndex: 0}, - ), - ) - - DescribeTable("Performs contract deployment and contract call with AccessControl", func(getTestParams func() evmtypes.Params, createParams, callParams PermissionsTableTest) { - params := getTestParams() - err := integrationutils.UpdateEvmParams( - integrationutils.UpdateParamsInput{ - Tf: s.factory, - Network: s.network, - Pk: s.keyring.GetPrivKey(0), - Params: params, - }, + Entry("successful migration with original account signer", MigrationTestCase{ + OriginalKeyIndex: 0, + NewKeyIndex: 1, + SignerKeyIndex: 0, + SetupData: true, + ExpectError: false, + }), + Entry("successful migration with new account signer", MigrationTestCase{ + OriginalKeyIndex: 0, + NewKeyIndex: 1, + SignerKeyIndex: 1, + SetupData: true, + ExpectError: false, + }), + Entry("failed migration with unauthorized signer", MigrationTestCase{ + OriginalKeyIndex: 0, + NewKeyIndex: 1, + SignerKeyIndex: 2, + SetupData: false, + ExpectError: true, + ErrorSubstring: "unauthorized", + }), + Entry("migration with same original and new address should fail", MigrationTestCase{ + OriginalKeyIndex: 0, + NewKeyIndex: 0, // Same as original + SignerKeyIndex: 0, + SetupData: false, + ExpectError: true, + ErrorSubstring: "same address", + }), ) - Expect(err).To(BeNil()) - err = s.network.NextBlock() - Expect(err).To(BeNil()) + Context("Advanced Migration Scenarios", func() { + It("should handle migration with high gas requirements", func() { + originalKey := s.keyring.GetKey(0) + newKey := s.keyring.GetKey(1) - createSigner := s.keyring.GetPrivKey(createParams.SignerIndex) - constructorArgs := []interface{}{"coin", "token", uint8(18)} - compiledContract := contracts.ERC20MinterBurnerDecimalsContract + // Setup account with multiple entities + validators := s.network.GetValidators() + baseDenom := s.network.GetBaseDenom() - contractAddr, err := s.factory.DeployContract( - createSigner, - evmtypes.EvmTxArgs{}, // Default values - factory.ContractDeploymentData{ - Contract: compiledContract, - ConstructorArgs: constructorArgs, - }, - ) - if createParams.ExpFail { - Expect(err).NotTo(BeNil()) - Expect(err.Error()).To(ContainSubstring("does not have permission to deploy contracts")) - // If contract deployment is expected to fail, we can skip the rest of the test - return - } + // Create multiple delegations + maxDelegations := 3 // Use smaller number for test performance + for i := 0; i < maxDelegations && i < len(validators); i++ { + delegateMsg := &stakingtypes.MsgDelegate{ + DelegatorAddress: originalKey.AccAddr.String(), + ValidatorAddress: validators[i].OperatorAddress, + Amount: sdktypes.NewCoin(baseDenom, math.NewInt(100000)), + } + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{delegateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + } - Expect(err).To(BeNil()) - Expect(contractAddr).ToNot(Equal(common.Address{})) + // Create multiple fee grants + maxFeeGrants := 2 + var grantMsgs []sdktypes.Msg - err = s.network.NextBlock() - Expect(err).To(BeNil()) + for i := 0; i < maxFeeGrants; i++ { + granteeKey := s.keyring.GetKey((i % 6) + 2) // Rotate through available keys + allowance := &feegrant.BasicAllowance{ + SpendLimit: sdktypes.NewCoins(sdktypes.NewCoin(baseDenom, math.NewInt(int64(10000*(i+1))))), + } + grantMsg := &feegrant.MsgGrantAllowance{ + Granter: originalKey.AccAddr.String(), + Grantee: granteeKey.AccAddr.String(), + Allowance: codectypes.UnsafePackAny(allowance), // Changed from UnsafePackAny to MustPackAny + } + grantMsgs = append(grantMsgs, grantMsg) + } - callSigner := s.keyring.GetPrivKey(callParams.SignerIndex) - totalSupplyTxArgs := evmtypes.EvmTxArgs{ - To: &contractAddr, - } - totalSupplyArgs := factory.CallArgs{ - ContractABI: compiledContract.ABI, - MethodName: "totalSupply", - Args: []interface{}{}, - } - res, err := s.factory.ExecuteContractCall(callSigner, totalSupplyTxArgs, totalSupplyArgs) - if callParams.ExpFail { - Expect(err).NotTo(BeNil()) - Expect(err.Error()).To(ContainSubstring("does not have permission to perform a call")) - } else { - Expect(err).To(BeNil()) - Expect(res.IsOK()).To(Equal(true), "transaction should have succeeded", res.GetLog()) - } - }, - Entry("Create and call is successful with create permission policy set to permissionless and address not blocked ", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Create = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissionless, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - ), - Entry("Create fails with create permission policy set to permissionless and signer is blocked ", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Create = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissionless, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: true, SignerIndex: 1}, - PermissionsTableTest{}, // Call should not be executed - ), - Entry("Create and call is successful with call permission policy set to permissionless and address not blocked ", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissionless, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - ), - Entry("Create is successful and call fails with call permission policy set to permissionless and address blocked ", func() evmtypes.Params { - blockedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissionless, - AccessControlList: []string{s.keyring.GetAddr(blockedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - PermissionsTableTest{ExpFail: true, SignerIndex: 1}, - ), - Entry("Create fails create permission policy set to restricted", func() evmtypes.Params { - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Create = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypeRestricted, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: true, SignerIndex: 0}, - PermissionsTableTest{}, // Call should not be executed - ), - Entry("Create succeeds and call fails when call permission policy set to restricted", func() evmtypes.Params { - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypeRestricted, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - PermissionsTableTest{ExpFail: true, SignerIndex: 0}, - ), - Entry("Create and call are successful with create permission policy set to permissioned and signer whitelisted", func() evmtypes.Params { - whitelistedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Create = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissioned, - AccessControlList: []string{s.keyring.GetAddr(whitelistedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 1}, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - ), - Entry("Create fails with create permission policy set to permissioned and signer NOT whitelisted", func() evmtypes.Params { - whitelistedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Create = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissioned, - AccessControlList: []string{s.keyring.GetAddr(whitelistedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: true, SignerIndex: 0}, - PermissionsTableTest{}, - ), - Entry("Create and call are successful with call permission policy set to permissioned and signer whitelisted", func() evmtypes.Params { - whitelistedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissioned, - AccessControlList: []string{s.keyring.GetAddr(whitelistedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - PermissionsTableTest{ExpFail: false, SignerIndex: 1}, - ), - Entry("Create succeeds and call fails with call permission policy set to permissioned and signer NOT whitelisted", func() evmtypes.Params { - whitelistedSignerIndex := 1 - // Set params to default values - defaultParams := evmtypes.DefaultParams() - defaultParams.AccessControl.Call = evmtypes.AccessControlType{ - AccessType: evmtypes.AccessTypePermissioned, - AccessControlList: []string{s.keyring.GetAddr(whitelistedSignerIndex).String()}, - } - return defaultParams - }, - PermissionsTableTest{ExpFail: false, SignerIndex: 0}, - PermissionsTableTest{ExpFail: true, SignerIndex: 0}, - ), - ) + // Execute all fee grants in a single transaction + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: grantMsgs, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Execute migration with custom gas settings + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } + + // Use higher gas limit for complex migration + res, err = s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "high-complexity migration should succeed", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify all entities migrated + for i := 0; i < maxDelegations && i < len(validators); i++ { + delegation, err := s.grpcHandler.GetDelegation(newKey.AccAddr.String(), validators[i].OperatorAddress) + Expect(err).To(BeNil()) + Expect(delegation.DelegationResponse.Balance.Amount).To(Equal(math.NewInt(100000))) + } + }) + + It("should handle migration when target account already has data", func() { + originalKey := s.keyring.GetKey(0) + newKey := s.keyring.GetKey(1) + validators := s.network.GetValidators() + baseDenom := s.network.GetBaseDenom() + + // Setup both accounts with existing data + if len(validators) > 0 { + // Original account delegation + delegateMsg1 := &stakingtypes.MsgDelegate{ + DelegatorAddress: originalKey.AccAddr.String(), + ValidatorAddress: validators[0].OperatorAddress, + Amount: sdktypes.NewCoin(baseDenom, math.NewInt(100000)), + } + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{delegateMsg1}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + // New account already has some delegation + delegateMsg2 := &stakingtypes.MsgDelegate{ + DelegatorAddress: newKey.AccAddr.String(), + ValidatorAddress: validators[0].OperatorAddress, + Amount: sdktypes.NewCoin(baseDenom, math.NewInt(50000)), + } + res, err = s.factory.ExecuteCosmosTx(newKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{delegateMsg2}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + } + + // Get pre-migration state + var preMigrationDelegation math.Int + if len(validators) > 0 { + delegation, err := s.grpcHandler.GetDelegation(newKey.AccAddr.String(), validators[0].OperatorAddress) + Expect(err).To(BeNil()) + preMigrationDelegation = delegation.DelegationResponse.Balance.Amount + } + + // Execute migration + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } + + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "migration to account with existing data should succeed", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify combined delegation + if len(validators) > 0 { + finalDelegation, err := s.grpcHandler.GetDelegation(newKey.AccAddr.String(), validators[0].OperatorAddress) + Expect(err).To(BeNil()) + expectedTotal := preMigrationDelegation.Add(math.NewInt(100000)) + Expect(finalDelegation.DelegationResponse.Balance.Amount).To(Equal(expectedTotal)) + } + }) + + It("should maintain state consistency during migration", func() { + originalKey := s.keyring.GetKey(0) + newKey := s.keyring.GetKey(1) + + // Setup initial state + validators := s.network.GetValidators() + baseDenom := s.network.GetBaseDenom() + + // Get initial balances + originalBalance, err := s.grpcHandler.GetBalanceFromBank(originalKey.AccAddr, baseDenom) + Expect(err).To(BeNil()) + initialAmount := originalBalance.GetBalance().Amount + + newBalance, err := s.grpcHandler.GetBalanceFromBank(newKey.AccAddr, baseDenom) + Expect(err).To(BeNil()) + newInitialAmount := newBalance.GetBalance().Amount + + // Create delegation + if len(validators) > 0 { + delegateMsg := &stakingtypes.MsgDelegate{ + DelegatorAddress: originalKey.AccAddr.String(), + ValidatorAddress: validators[0].OperatorAddress, + Amount: sdktypes.NewCoin(baseDenom, math.NewInt(100000)), + } + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{delegateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + } + + // Execute migration + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } + + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify state consistency + // 1. Original account should have minimal/zero balance + finalOriginalBalance, err := s.grpcHandler.GetBalanceFromBank(originalKey.AccAddr, baseDenom) + Expect(err).To(BeNil()) + Expect(finalOriginalBalance.GetBalance().Amount.LTE(initialAmount)).To(BeTrue()) + + // 2. New account should have the migrated funds + finalNewBalance, err := s.grpcHandler.GetBalanceFromBank(newKey.AccAddr, baseDenom) + Expect(err).To(BeNil()) + Expect(finalNewBalance.GetBalance().Amount.GT(newInitialAmount)).To(BeTrue()) + }) + + It("should handle migration of account with zero balance", func() { + // Create new accounts with zero balance + originalKey := s.keyring.GetKey(6) + newKey := s.keyring.GetKey(7) + + // Ensure original account has zero balance by transferring all funds out + originalBalance, err := s.grpcHandler.GetBalanceFromBank(originalKey.AccAddr, s.network.GetBaseDenom()) + Expect(err).To(BeNil()) + + if originalBalance.GetBalance().Amount.GT(math.ZeroInt()) { + // Transfer all funds to another account to create zero balance + transferKey := s.keyring.GetKey(0) + sendMsg := &banktypes.MsgSend{ + FromAddress: originalKey.AccAddr.String(), + ToAddress: transferKey.AccAddr.String(), + Amount: sdktypes.NewCoins(*originalBalance.GetBalance()), + } + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{sendMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true)) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + } + + // Verify zero balance + zeroBalance, err := s.grpcHandler.GetBalanceFromBank(originalKey.AccAddr, s.network.GetBaseDenom()) + Expect(err).To(BeNil()) + Expect(zeroBalance.GetBalance().Amount.IsZero()).To(BeTrue()) + + // Execute migration + migrateMsg := &evmtypes.MsgMigrateAccount{ + OriginalAddress: originalKey.AccAddr.String(), + NewAddress: newKey.AccAddr.String(), + } + + res, err := s.factory.ExecuteCosmosTx(originalKey.Priv, factory2.CosmosTxArgs{ + Msgs: []sdktypes.Msg{migrateMsg}, + }) + Expect(err).To(BeNil()) + Expect(res.IsOK()).To(Equal(true), "zero balance migration should succeed", res.GetLog()) + + err = s.network.NextBlock() + Expect(err).To(BeNil()) + + // Verify migration completed + _, err = s.grpcHandler.GetBalanceFromBank(newKey.AccAddr, s.network.GetBaseDenom()) + Expect(err).To(BeNil()) + // New account might have some dust from the migration process + }) + }) + }) }) type PermissionsTableTest struct { @@ -662,6 +1532,15 @@ type PermissionsTableTest struct { SignerIndex int } +type MigrationTestCase struct { + OriginalKeyIndex int + NewKeyIndex int + SignerKeyIndex int + SetupData bool + ExpectError bool + ErrorSubstring string +} + func checkMintTopics(res abcitypes.ExecTxResult) error { // Check contract call response has the expected topics for a mint // call within an ERC20 contract diff --git a/x/vm/keeper/keeper.go b/x/vm/keeper/keeper.go index bfb81aad..e216f4c8 100644 --- a/x/vm/keeper/keeper.go +++ b/x/vm/keeper/keeper.go @@ -1,6 +1,7 @@ package keeper import ( + "github.com/cosmos/cosmos-sdk/baseapp" "math/big" "github.com/ethereum/go-ethereum/common" @@ -49,6 +50,14 @@ type Keeper struct { // access historical headers for EVM state transition execution stakingKeeper types.StakingKeeper + + // used for migrations from cointype 118 to cointype 60 accounts + feegrantKeeper types.FeegrantKeeper + authzKeeper types.AuthzKeeper + // Msg server router + router baseapp.MessageRouter + migrateAccountHooks types.MigrateAccountHooks + // fetch EIP1559 base fee and parameters feeMarketWrapper *wrappers.FeeMarketWrapper // erc20Keeper interface needed to instantiate erc20 precompiles @@ -57,8 +66,8 @@ type Keeper struct { // Tracer used to collect execution traces from the EVM transaction execution tracer string - hooks types.EvmHooks // EVM Hooks for tx post-processing + hooks types.EvmHooks // precompiles defines the map of all available precompiled smart contracts. // Some of these precompiled contracts might not be active depending on the EVM @@ -74,8 +83,11 @@ func NewKeeper( ak types.AccountKeeper, bankKeeper types.BankKeeper, sk types.StakingKeeper, + feegrantKeeper types.FeegrantKeeper, + authzKeeper types.AuthzKeeper, fmk types.FeeMarketKeeper, erc20Keeper types.Erc20Keeper, + router baseapp.MessageRouter, tracer string, ) *Keeper { // ensure evm module account is set @@ -98,9 +110,12 @@ func NewKeeper( accountKeeper: ak, bankWrapper: bankWrapper, stakingKeeper: sk, + feegrantKeeper: feegrantKeeper, + authzKeeper: authzKeeper, feeMarketWrapper: feeMarketWrapper, storeKey: storeKey, transientKey: transientKey, + router: router, tracer: tracer, erc20Keeper: erc20Keeper, } @@ -171,9 +186,9 @@ func (k Keeper) GetTxIndexTransient(ctx sdk.Context) uint64 { // Hooks // ---------------------------------------------------------------------------- -// SetHooks sets the hooks for the EVM module +// SetEVMHooks sets the hooks for the EVM module // Called only once during initialization, panics if called more than once. -func (k *Keeper) SetHooks(eh types.EvmHooks) *Keeper { +func (k *Keeper) SetEVMHooks(eh types.EvmHooks) *Keeper { if k.hooks != nil { panic("cannot set evm hooks twice") } @@ -182,6 +197,25 @@ func (k *Keeper) SetHooks(eh types.EvmHooks) *Keeper { return k } +// SetMigrateAccountHooks sets the hooks for the EVM module +// Called only once during initialization, panics if called more than once. +func (k *Keeper) SetMigrateAccountHooks(hooks types.MigrateAccountHooks) *Keeper { + if k.migrateAccountHooks != nil { + panic("cannot set migrate account hooks twice") + } + + k.migrateAccountHooks = hooks + return k +} + +// todo: docs +func (k *Keeper) MigrateAccountHooks() types.MigrateAccountHooks { + if k.migrateAccountHooks == nil { + return MultiMigrateAccountHooks{} + } + return k.migrateAccountHooks +} + // PostTxProcessing delegates the call to the hooks. // If no hook has been registered, this function returns with a `nil` error func (k *Keeper) PostTxProcessing(ctx sdk.Context, sender common.Address, msg core.Message, receipt *ethtypes.Receipt) error { @@ -341,3 +375,7 @@ func (k Keeper) AddTransientGasUsed(ctx sdk.Context, gasUsed uint64) (uint64, er k.SetTransientGasUsed(ctx, result) return result, nil } + +func (k Keeper) Router() baseapp.MessageRouter { + return k.router +} diff --git a/x/vm/keeper/migrate_account_hooks.go b/x/vm/keeper/migrate_account_hooks.go new file mode 100644 index 00000000..37777011 --- /dev/null +++ b/x/vm/keeper/migrate_account_hooks.go @@ -0,0 +1,64 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/evm/x/vm/types" +) + +// Event Hooks +// These can be utilized to customize evm transaction processing. + +var _ types.MigrateAccountHooks = MultiMigrateAccountHooks{} + +// MultiMigrateAccountHooks TODO +type MultiMigrateAccountHooks []types.MigrateAccountHooks + +// NewMultiMigrateAccountHooks TODO +func NewMultiMigrateAccountHooks(hooks ...types.MigrateAccountHooks) MultiMigrateAccountHooks { + return hooks +} + +func (m MultiMigrateAccountHooks) BeforeAll(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error { + for i := range m { + if err := m[i].BeforeAll(ctx, originalAddress, newAddress); err != nil { + return err + } + } + return nil +} + +func (m MultiMigrateAccountHooks) AfterMigrateDelegations(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error { + for i := range m { + if err := m[i].BeforeAll(ctx, originalAddress, newAddress); err != nil { + return err + } + } + return nil +} + +func (m MultiMigrateAccountHooks) AfterMigrateBankTokens(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error { + for i := range m { + if err := m[i].BeforeAll(ctx, originalAddress, newAddress); err != nil { + return err + } + } + return nil +} + +func (m MultiMigrateAccountHooks) AfterMigrateFeeGrants(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error { + for i := range m { + if err := m[i].BeforeAll(ctx, originalAddress, newAddress); err != nil { + return err + } + } + return nil +} + +func (m MultiMigrateAccountHooks) AfterAll(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error { + for i := range m { + if err := m[i].BeforeAll(ctx, originalAddress, newAddress); err != nil { + return err + } + } + return nil +} diff --git a/x/vm/keeper/msg_server.go b/x/vm/keeper/msg_server.go index 03d17da6..acacf7c2 100644 --- a/x/vm/keeper/msg_server.go +++ b/x/vm/keeper/msg_server.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "strconv" "github.com/hashicorp/go-metrics" @@ -146,3 +147,85 @@ func (k *Keeper) UpdateParams(goCtx context.Context, req *types.MsgUpdateParams) return &types.MsgUpdateParamsResponse{}, nil } + +func (k *Keeper) MigrateAccount(goCtx context.Context, req *types.MsgMigrateAccount) (*types.MsgMigrateAccountResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + const ( + // all active validators in the network + maxValidators = 180 + // 99.99th percentile of tokens held per account + maxTokens = 20 + // >99th percentile of feegrants granted per granter + maxFeeGrants = 55 + // >99th percentile of authz grants granted per granter + maxAuthzGrants = 5 + ) + + // todo: should someone need to sign with both keys? + // one key signing is probably fine - this functions with similar effect to bank send. + // on the other hand, may be good for users to confirm that the other address is actually functional; + // hmm + + originalAddress, err := sdk.AccAddressFromBech32(req.OriginalAddress) + if err != nil { + return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid original address: %s", err) + } + + if k.bankWrapper.BlockedAddr(originalAddress) { + return nil, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive external funds", originalAddress) + } + + newAddress, err := sdk.AccAddressFromBech32(req.NewAddress) + if err != nil { + return nil, sdkerrors.ErrInvalidAddress.Wrapf("invalid new address: %s", err) + } + + if k.bankWrapper.BlockedAddr(newAddress) { + return nil, errorsmod.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to receive external funds", newAddress) + } + + // call the before-delegation-modified hook + if err := k.MigrateAccountHooks().BeforeAll(ctx, originalAddress, newAddress); err != nil { + return nil, err + } + + // delegations need to be migrated first to withdraw any staking rewards to handle them in the bank migration + err = k.migrateDelegations(ctx, originalAddress, maxValidators, newAddress) + if err != nil { + return nil, err + } + + if err := k.MigrateAccountHooks().AfterMigrateDelegations(ctx, originalAddress, newAddress); err != nil { + return nil, err + } + + err = k.migrateBankTokens(err, ctx, originalAddress, maxTokens, newAddress) + if err != nil { + return nil, err + } + + if err := k.MigrateAccountHooks().AfterMigrateBankTokens(ctx, originalAddress, newAddress); err != nil { + return nil, err + } + + err = k.migrateFeeGrants(ctx, originalAddress, maxFeeGrants, newAddress) + if err != nil { + return nil, err + } + + if err := k.MigrateAccountHooks().AfterMigrateFeeGrants(ctx, originalAddress, newAddress); err != nil { + return nil, err + } + + err = k.migrateAuthzGrants(ctx, originalAddress, maxAuthzGrants) + if err != nil { + return nil, err + } + + if err := k.MigrateAccountHooks().AfterAll(ctx, originalAddress, newAddress); err != nil { + return nil, err + } + + return &types.MsgMigrateAccountResponse{}, nil +} diff --git a/x/vm/keeper/hooks.go b/x/vm/keeper/multi_evm_hooks.go similarity index 100% rename from x/vm/keeper/hooks.go rename to x/vm/keeper/multi_evm_hooks.go diff --git a/x/vm/keeper/hooks_test.go b/x/vm/keeper/multi_evm_hooks_test.go similarity index 96% rename from x/vm/keeper/hooks_test.go rename to x/vm/keeper/multi_evm_hooks_test.go index e82b6fb3..d79dca14 100644 --- a/x/vm/keeper/hooks_test.go +++ b/x/vm/keeper/multi_evm_hooks_test.go @@ -62,7 +62,7 @@ func (suite *KeeperTestSuite) TestEvmHooks() { for _, tc := range testCases { suite.SetupTest() hook := tc.setupHook() - suite.network.App.EVMKeeper.SetHooks(keeper.NewMultiEvmHooks(hook)) + suite.network.App.EVMKeeper.SetEVMHooks(keeper.NewMultiEvmHooks(hook)) k := suite.network.App.EVMKeeper ctx := suite.network.GetContext() diff --git a/x/vm/types/interfaces.go b/x/vm/types/interfaces.go index 0ce18553..23cf1e76 100644 --- a/x/vm/types/interfaces.go +++ b/x/vm/types/interfaces.go @@ -2,7 +2,11 @@ package types import ( "context" + "cosmossdk.io/x/feegrant" + "github.com/cosmos/cosmos-sdk/x/authz" + "github.com/cosmos/cosmos-sdk/x/bank/types" "math/big" + "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -35,7 +39,11 @@ type AccountKeeper interface { type BankKeeper interface { authtypes.BankKeeper GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin + GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins + SpendableBalances(ctx context.Context, req *types.QuerySpendableBalancesRequest) (*types.QuerySpendableBalancesResponse, error) + BlockedAddr(addr sdk.AccAddress) bool SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error MintCoins(ctx context.Context, moduleName string, amt sdk.Coins) error BurnCoins(ctx context.Context, moduleName string, amt sdk.Coins) error } @@ -45,6 +53,23 @@ type StakingKeeper interface { GetHistoricalInfo(ctx context.Context, height int64) (stakingtypes.HistoricalInfo, error) GetValidatorByConsAddr(ctx context.Context, consAddr sdk.ConsAddress) (stakingtypes.Validator, error) ValidatorAddressCodec() address.Codec + GetDelegatorDelegations(ctx context.Context, delegator sdk.AccAddress, maxRetrieve uint16) (delegations []stakingtypes.Delegation, err error) + Unbond(ctx context.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares math.LegacyDec) (amount math.Int, err error) + GetValidator(ctx context.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, err error) + BondDenom(ctx context.Context) (string, error) + SetDelegation(ctx context.Context, delegation stakingtypes.Delegation) error + RemoveDelegation(ctx context.Context, delegation stakingtypes.Delegation) error +} + +type FeegrantKeeper interface { + AllowancesByGranter(c context.Context, req *feegrant.QueryAllowancesByGranterRequest) (*feegrant.QueryAllowancesByGranterResponse, error) + GrantAllowance(ctx context.Context, granter, grantee sdk.AccAddress, feeAllowance feegrant.FeeAllowanceI) error +} + +type AuthzKeeper interface { + GranterGrants(ctx context.Context, req *authz.QueryGranterGrantsRequest) (*authz.QueryGranterGrantsResponse, error) + DeleteGrant(ctx context.Context, grantee, granter sdk.AccAddress, msgType string) error + SaveGrant(ctx context.Context, grantee, granter sdk.AccAddress, authorization authz.Authorization, expiration *time.Time) error } // FeeMarketKeeper defines the expected interfaces needed for the feemarket @@ -65,6 +90,15 @@ type EvmHooks interface { PostTxProcessing(ctx sdk.Context, sender common.Address, msg core.Message, receipt *ethtypes.Receipt) error } +// MigrateAccountHooks TODO +type MigrateAccountHooks interface { + BeforeAll(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error + AfterMigrateDelegations(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error + AfterMigrateBankTokens(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error + AfterMigrateFeeGrants(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error + AfterAll(ctx sdk.Context, originalAddress sdk.AccAddress, newAddress sdk.AccAddress) error +} + // BankWrapper defines the methods required by the wrapper around // the Cosmos SDK x/bank keeper that is used to manage an EVM coin // with a configurable value for decimals. diff --git a/x/vm/types/tx.pb.go b/x/vm/types/tx.pb.go index d16bb3c9..7a561f74 100644 --- a/x/vm/types/tx.pb.go +++ b/x/vm/types/tx.pb.go @@ -441,6 +441,97 @@ func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo +// todo: comments +type MsgMigrateAccount struct { + // original_address is the address of the account that is migrating to a new state + OriginalAddress string `protobuf:"bytes,1,opt,name=original_address,json=originalAddress,proto3" json:"original_address,omitempty"` + // new_address is the address of the account that is being migrated to from the old account + NewAddress string `protobuf:"bytes,2,opt,name=new_address,json=newAddress,proto3" json:"new_address,omitempty"` +} + +func (m *MsgMigrateAccount) Reset() { *m = MsgMigrateAccount{} } +func (m *MsgMigrateAccount) String() string { return proto.CompactTextString(m) } +func (*MsgMigrateAccount) ProtoMessage() {} +func (*MsgMigrateAccount) Descriptor() ([]byte, []int) { + return fileDescriptor_77a8ac5e8c9c4850, []int{8} +} +func (m *MsgMigrateAccount) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgMigrateAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgMigrateAccount.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 *MsgMigrateAccount) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgMigrateAccount.Merge(m, src) +} +func (m *MsgMigrateAccount) XXX_Size() int { + return m.Size() +} +func (m *MsgMigrateAccount) XXX_DiscardUnknown() { + xxx_messageInfo_MsgMigrateAccount.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgMigrateAccount proto.InternalMessageInfo + +func (m *MsgMigrateAccount) GetOriginalAddress() string { + if m != nil { + return m.OriginalAddress + } + return "" +} + +func (m *MsgMigrateAccount) GetNewAddress() string { + if m != nil { + return m.NewAddress + } + return "" +} + +type MsgMigrateAccountResponse struct { +} + +func (m *MsgMigrateAccountResponse) Reset() { *m = MsgMigrateAccountResponse{} } +func (m *MsgMigrateAccountResponse) String() string { return proto.CompactTextString(m) } +func (*MsgMigrateAccountResponse) ProtoMessage() {} +func (*MsgMigrateAccountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_77a8ac5e8c9c4850, []int{9} +} +func (m *MsgMigrateAccountResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgMigrateAccountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgMigrateAccountResponse.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 *MsgMigrateAccountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgMigrateAccountResponse.Merge(m, src) +} +func (m *MsgMigrateAccountResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgMigrateAccountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgMigrateAccountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgMigrateAccountResponse proto.InternalMessageInfo + func init() { proto.RegisterType((*MsgEthereumTx)(nil), "cosmos.evm.vm.v1.MsgEthereumTx") proto.RegisterType((*LegacyTx)(nil), "cosmos.evm.vm.v1.LegacyTx") @@ -450,77 +541,84 @@ func init() { proto.RegisterType((*MsgEthereumTxResponse)(nil), "cosmos.evm.vm.v1.MsgEthereumTxResponse") proto.RegisterType((*MsgUpdateParams)(nil), "cosmos.evm.vm.v1.MsgUpdateParams") proto.RegisterType((*MsgUpdateParamsResponse)(nil), "cosmos.evm.vm.v1.MsgUpdateParamsResponse") + proto.RegisterType((*MsgMigrateAccount)(nil), "cosmos.evm.vm.v1.MsgMigrateAccount") + proto.RegisterType((*MsgMigrateAccountResponse)(nil), "cosmos.evm.vm.v1.MsgMigrateAccountResponse") } func init() { proto.RegisterFile("cosmos/evm/vm/v1/tx.proto", fileDescriptor_77a8ac5e8c9c4850) } var fileDescriptor_77a8ac5e8c9c4850 = []byte{ - // 1026 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0x4d, 0x8b, 0x23, 0x45, - 0x18, 0xc7, 0xa7, 0x93, 0xce, 0x5b, 0x25, 0xea, 0xd8, 0xce, 0x30, 0x9d, 0xe0, 0xa6, 0xb3, 0xad, - 0xab, 0xd9, 0x81, 0xe9, 0x66, 0x23, 0x08, 0x1b, 0x4f, 0x93, 0x9d, 0x59, 0x59, 0x99, 0xc1, 0xa5, - 0xcd, 0x5e, 0x44, 0x88, 0x35, 0x9d, 0x9a, 0x4e, 0x63, 0xba, 0xab, 0xe9, 0xaa, 0x84, 0x44, 0x10, - 0x64, 0x4f, 0xe2, 0x49, 0xf0, 0x2c, 0x78, 0xf0, 0xa0, 0x9e, 0xe6, 0xb0, 0x78, 0xf0, 0x13, 0x2c, - 0x9e, 0x16, 0xbd, 0x88, 0x87, 0xac, 0x64, 0x84, 0xc1, 0x39, 0xfa, 0x09, 0xa4, 0x5e, 0xb2, 0xe9, - 0x4c, 0x9c, 0x99, 0x75, 0x41, 0xa1, 0x09, 0xf5, 0xd4, 0xf3, 0xd2, 0x4f, 0xff, 0x9e, 0x7f, 0xaa, - 0x1b, 0x94, 0x5d, 0x4c, 0x02, 0x4c, 0x6c, 0x34, 0x0c, 0x6c, 0x76, 0xdd, 0xb0, 0xe9, 0xc8, 0x8a, - 0x62, 0x4c, 0xb1, 0xb6, 0x2a, 0x5c, 0x16, 0x1a, 0x06, 0x16, 0xbb, 0x6e, 0x54, 0x5e, 0x84, 0x81, - 0x1f, 0x62, 0x9b, 0xff, 0x8a, 0xa0, 0xca, 0x86, 0xcc, 0x0f, 0x88, 0xc7, 0x92, 0x03, 0xe2, 0x49, - 0x87, 0x2c, 0xdc, 0xe1, 0x96, 0x2d, 0x4b, 0x09, 0xd7, 0x9a, 0x87, 0x3d, 0x2c, 0xf6, 0xd9, 0x4a, - 0xee, 0xbe, 0xec, 0x61, 0xec, 0xf5, 0x91, 0x0d, 0x23, 0xdf, 0x86, 0x61, 0x88, 0x29, 0xa4, 0x3e, - 0x0e, 0x67, 0x39, 0x65, 0xe9, 0xe5, 0xd6, 0xc1, 0xe0, 0xd0, 0x86, 0xe1, 0x58, 0xba, 0x2a, 0x4b, - 0x8f, 0xc0, 0x3a, 0xe6, 0x3e, 0xf3, 0x07, 0x05, 0x3c, 0xb7, 0x4f, 0xbc, 0x5d, 0xda, 0x43, 0x31, - 0x1a, 0x04, 0xed, 0x91, 0x56, 0x07, 0x6a, 0x17, 0x52, 0xa8, 0x2b, 0x35, 0xa5, 0x5e, 0x6c, 0xac, - 0x59, 0xa2, 0xae, 0x35, 0xab, 0x6b, 0x6d, 0x87, 0x63, 0x87, 0x47, 0x68, 0x55, 0xa0, 0x12, 0xff, - 0x63, 0xa4, 0xa7, 0x6a, 0x4a, 0x5d, 0x69, 0x81, 0xd3, 0x89, 0xa1, 0x6c, 0x7d, 0x7b, 0x72, 0xb4, - 0xa9, 0x38, 0x7c, 0x5f, 0x7b, 0x15, 0xa8, 0x3d, 0x48, 0x7a, 0x7a, 0xba, 0xa6, 0xd4, 0x0b, 0xad, - 0xd5, 0xbf, 0x26, 0x46, 0x2e, 0xee, 0x47, 0x4d, 0x73, 0xcb, 0x94, 0x51, 0xcc, 0xab, 0x69, 0x40, - 0x3d, 0x8c, 0x71, 0xa0, 0xab, 0x2c, 0xca, 0xe1, 0xeb, 0xe6, 0xd5, 0xcf, 0xbe, 0x36, 0x56, 0x3e, - 0x3f, 0x39, 0xda, 0xd4, 0x13, 0xad, 0x2f, 0xb4, 0x69, 0x7e, 0x97, 0x02, 0xf9, 0x3d, 0xe4, 0x41, - 0x77, 0xdc, 0x1e, 0x69, 0x6b, 0x20, 0x13, 0xe2, 0xd0, 0x45, 0xbc, 0x69, 0xd5, 0x11, 0x86, 0xf6, - 0x26, 0x28, 0x78, 0x90, 0x01, 0xf6, 0x5d, 0xd1, 0x64, 0xa1, 0x55, 0xfe, 0x6d, 0x62, 0xac, 0x8b, - 0x9a, 0xa4, 0xfb, 0x91, 0xe5, 0x63, 0x3b, 0x80, 0xb4, 0x67, 0xdd, 0x09, 0xa9, 0x93, 0xf7, 0x20, - 0xb9, 0xcb, 0x42, 0xb5, 0x2a, 0x48, 0x7b, 0x90, 0xf0, 0xb6, 0xd5, 0x56, 0x69, 0x3a, 0x31, 0xf2, - 0x6f, 0x43, 0xb2, 0xe7, 0x07, 0x3e, 0x75, 0x98, 0x43, 0x7b, 0x1e, 0xa4, 0x28, 0x96, 0xfd, 0xa6, - 0x28, 0xd6, 0x6e, 0x82, 0xcc, 0x10, 0xf6, 0x07, 0x48, 0xcf, 0xf0, 0x7b, 0xbc, 0x72, 0xee, 0x3d, - 0xa6, 0x13, 0x23, 0xbb, 0x1d, 0xe0, 0x41, 0x48, 0x1d, 0x91, 0xc1, 0x1e, 0x9e, 0xc3, 0xce, 0xd6, - 0x94, 0x7a, 0x49, 0x62, 0x2d, 0x01, 0x65, 0xa8, 0xe7, 0xf8, 0x86, 0x32, 0x64, 0x56, 0xac, 0xe7, - 0x85, 0x15, 0x33, 0x8b, 0xe8, 0x05, 0x61, 0x91, 0xe6, 0x6b, 0x0c, 0xd3, 0x4f, 0x0f, 0xb6, 0xb2, - 0xed, 0xd1, 0x0e, 0xa4, 0x90, 0x01, 0x7b, 0x29, 0x01, 0x6c, 0x86, 0xc7, 0x7c, 0x9c, 0x06, 0xa5, - 0x6d, 0xd7, 0x45, 0x84, 0xec, 0xf9, 0x84, 0xb6, 0x47, 0xda, 0x3b, 0x20, 0xef, 0xf6, 0xa0, 0x1f, - 0x76, 0xfc, 0x2e, 0x47, 0x56, 0x68, 0xd9, 0x17, 0x35, 0x9d, 0xbb, 0xc5, 0x82, 0xef, 0xec, 0x9c, - 0x4e, 0x8c, 0x9c, 0x2b, 0x96, 0x8e, 0x5c, 0x74, 0xe7, 0xec, 0x53, 0xe7, 0xb2, 0x4f, 0xff, 0x6b, - 0xf6, 0xea, 0xc5, 0xec, 0x33, 0xcb, 0xec, 0xb3, 0xcf, 0xcc, 0x3e, 0x97, 0x60, 0xff, 0x21, 0xc8, - 0x43, 0x0e, 0x0a, 0x11, 0x3d, 0x5f, 0x4b, 0xd7, 0x8b, 0x8d, 0x2b, 0xd6, 0xd9, 0x7f, 0xb9, 0x25, - 0x50, 0xb6, 0x07, 0x51, 0x1f, 0xb5, 0xae, 0x3d, 0x9c, 0x18, 0x2b, 0xa7, 0x13, 0x03, 0xc0, 0x27, - 0x7c, 0xbf, 0x7f, 0x6c, 0x80, 0x39, 0x6d, 0x21, 0xf5, 0x27, 0x55, 0xc5, 0x74, 0x0b, 0x0b, 0xd3, - 0x05, 0x0b, 0xd3, 0x2d, 0xce, 0xa6, 0xbb, 0xb9, 0x3c, 0xdd, 0x8d, 0xc4, 0x74, 0x93, 0x03, 0x35, - 0xbf, 0x52, 0x41, 0x69, 0x67, 0x1c, 0xc2, 0xc0, 0x77, 0x6f, 0x23, 0xf4, 0xbf, 0x4c, 0xf8, 0x26, - 0x28, 0xb2, 0x09, 0x53, 0x3f, 0xea, 0xb8, 0x30, 0xba, 0x7c, 0xc6, 0x4c, 0x0f, 0x6d, 0x3f, 0xba, - 0x05, 0xa3, 0x59, 0xea, 0x21, 0x42, 0x3c, 0x55, 0x7d, 0x9a, 0xd4, 0xdb, 0x08, 0xb1, 0x54, 0xa9, - 0x8f, 0xcc, 0xc5, 0xfa, 0xc8, 0x2e, 0xeb, 0x23, 0xf7, 0xcc, 0xfa, 0xc8, 0x9f, 0xa3, 0x8f, 0xc2, - 0x7f, 0xa7, 0x0f, 0xb0, 0xa0, 0x8f, 0xe2, 0x82, 0x3e, 0x4a, 0x4f, 0xa9, 0x8f, 0xa4, 0x1c, 0x4c, - 0x13, 0x54, 0x76, 0x47, 0x14, 0x85, 0xc4, 0xc7, 0xe1, 0xbb, 0x11, 0x7f, 0x6f, 0xcc, 0xcf, 0xd2, - 0xa6, 0xca, 0x2a, 0x99, 0xdf, 0x28, 0x60, 0x7d, 0xe1, 0x8c, 0x75, 0x10, 0x89, 0x70, 0x48, 0x38, - 0x09, 0x7e, 0x90, 0x2b, 0xe2, 0x88, 0xe6, 0xc7, 0xf6, 0x75, 0xa0, 0xf6, 0xb1, 0x47, 0xf4, 0x14, - 0xa7, 0xb0, 0xbe, 0x4c, 0x61, 0x0f, 0x7b, 0x0e, 0x0f, 0xd1, 0x56, 0x41, 0x3a, 0x46, 0x94, 0x2b, - 0xa4, 0xe4, 0xb0, 0xa5, 0x56, 0x06, 0xf9, 0x61, 0xd0, 0x41, 0x71, 0x8c, 0x63, 0x79, 0x8e, 0xe6, - 0x86, 0xc1, 0x2e, 0x33, 0x99, 0x8b, 0x69, 0x63, 0x40, 0x50, 0x57, 0x4c, 0xd9, 0xc9, 0x79, 0x90, - 0xdc, 0x23, 0xa8, 0x2b, 0xdb, 0xfc, 0x51, 0x01, 0x2f, 0xec, 0x13, 0xef, 0x5e, 0xd4, 0x85, 0x14, - 0xdd, 0x85, 0x31, 0x0c, 0x08, 0x3b, 0x6d, 0xe0, 0x80, 0xf6, 0x70, 0xec, 0xd3, 0xb1, 0x94, 0xbb, - 0xfe, 0xf3, 0x83, 0xad, 0x35, 0xd9, 0xd4, 0x76, 0xb7, 0x1b, 0x23, 0x42, 0xde, 0xa3, 0xb1, 0x1f, - 0x7a, 0xce, 0x3c, 0x54, 0x7b, 0x0b, 0x64, 0x23, 0x5e, 0x81, 0x4b, 0xbb, 0xd8, 0xd0, 0x97, 0x1f, - 0x43, 0xdc, 0xa1, 0x55, 0x60, 0x73, 0x14, 0xb3, 0x92, 0x29, 0xcd, 0xc6, 0xfd, 0x93, 0xa3, 0xcd, - 0x79, 0x31, 0xc6, 0xdf, 0x48, 0xf0, 0x1f, 0xd9, 0xe2, 0x9d, 0x95, 0x6c, 0xd4, 0x2c, 0x83, 0x8d, - 0x33, 0x5b, 0x33, 0xc8, 0x8d, 0x3f, 0x15, 0x90, 0xde, 0x27, 0x9e, 0xf6, 0x09, 0x00, 0x89, 0xb7, - 0xb1, 0xb1, 0xdc, 0xd1, 0xc2, 0x8c, 0x2a, 0xaf, 0x5f, 0x12, 0x30, 0xab, 0x6f, 0x5e, 0xbb, 0xff, - 0xcb, 0x1f, 0x5f, 0xa6, 0x0c, 0xf3, 0x8a, 0xbd, 0xfc, 0x39, 0x20, 0xa3, 0x3b, 0x74, 0xa4, 0x7d, - 0x00, 0x4a, 0x0b, 0x68, 0xaf, 0xfe, 0x63, 0xfd, 0x64, 0x48, 0xe5, 0xfa, 0xa5, 0x21, 0xb3, 0x26, - 0x2a, 0x99, 0x4f, 0x19, 0xc2, 0x56, 0xf3, 0xe1, 0xb4, 0xaa, 0x3c, 0x9a, 0x56, 0x95, 0xdf, 0xa7, - 0x55, 0xe5, 0x8b, 0xe3, 0xea, 0xca, 0xa3, 0xe3, 0xea, 0xca, 0xaf, 0xc7, 0xd5, 0x95, 0xf7, 0x6b, - 0x9e, 0x4f, 0x7b, 0x83, 0x03, 0xcb, 0xc5, 0x81, 0x7d, 0x16, 0x26, 0x1d, 0x47, 0x88, 0x1c, 0x64, - 0xf9, 0x97, 0xc8, 0x1b, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0x5e, 0xf0, 0xb6, 0xa5, 0x99, 0x09, - 0x00, 0x00, + // 1118 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xdf, 0x6b, 0x23, 0x45, + 0x1c, 0xef, 0x26, 0x9b, 0x5f, 0x93, 0x78, 0xd7, 0x5b, 0x7b, 0x74, 0x13, 0xbd, 0x6c, 0xba, 0xe7, + 0x69, 0xae, 0xd2, 0x5d, 0xae, 0x82, 0x70, 0xb9, 0xa7, 0xa6, 0xed, 0xc9, 0x49, 0x8b, 0xc7, 0x9a, + 0x7b, 0x11, 0x21, 0x4e, 0x37, 0xd3, 0xcd, 0x60, 0x76, 0x67, 0xd9, 0x99, 0xe4, 0x12, 0x41, 0x90, + 0x7b, 0x12, 0x9f, 0x04, 0x9f, 0x05, 0x1f, 0x7c, 0x50, 0x9f, 0xfa, 0x70, 0xf8, 0xe0, 0x5f, 0x70, + 0x08, 0x42, 0xd1, 0x17, 0xf1, 0x21, 0x27, 0xad, 0x50, 0xe8, 0xa3, 0x7f, 0x81, 0xcc, 0xcc, 0xa6, + 0x4d, 0x9a, 0xfe, 0xf2, 0x40, 0x21, 0x84, 0x99, 0xef, 0xaf, 0xf9, 0x7e, 0x3f, 0x9f, 0xcf, 0xce, + 0x2e, 0x28, 0xba, 0x84, 0xfa, 0x84, 0xda, 0xa8, 0xe7, 0xdb, 0xfc, 0x77, 0xc7, 0x66, 0x7d, 0x2b, + 0x8c, 0x08, 0x23, 0xda, 0xac, 0x74, 0x59, 0xa8, 0xe7, 0x5b, 0xfc, 0x77, 0xa7, 0x74, 0x0d, 0xfa, + 0x38, 0x20, 0xb6, 0xf8, 0x97, 0x41, 0xa5, 0xf9, 0x38, 0xdf, 0xa7, 0x1e, 0x4f, 0xf6, 0xa9, 0x17, + 0x3b, 0xe2, 0xc2, 0x4d, 0xb1, 0xb3, 0xe3, 0x52, 0xd2, 0x35, 0xe7, 0x11, 0x8f, 0x48, 0x3b, 0x5f, + 0xc5, 0xd6, 0x57, 0x3d, 0x42, 0xbc, 0x0e, 0xb2, 0x61, 0x88, 0x6d, 0x18, 0x04, 0x84, 0x41, 0x86, + 0x49, 0x30, 0xca, 0x29, 0xc6, 0x5e, 0xb1, 0xdb, 0xea, 0x6e, 0xdb, 0x30, 0x18, 0xc4, 0xae, 0xd2, + 0xd4, 0x08, 0xbc, 0x63, 0xe1, 0x33, 0x7f, 0x54, 0xc0, 0x4b, 0x9b, 0xd4, 0x5b, 0x67, 0x6d, 0x14, + 0xa1, 0xae, 0xdf, 0xe8, 0x6b, 0x55, 0xa0, 0xb6, 0x20, 0x83, 0xba, 0x52, 0x51, 0xaa, 0xf9, 0xe5, + 0x39, 0x4b, 0xd6, 0xb5, 0x46, 0x75, 0xad, 0x95, 0x60, 0xe0, 0x88, 0x08, 0xad, 0x0c, 0x54, 0x8a, + 0x3f, 0x41, 0x7a, 0xa2, 0xa2, 0x54, 0x95, 0x3a, 0x38, 0x1c, 0x1a, 0xca, 0xd2, 0x77, 0x07, 0x3b, + 0x8b, 0x8a, 0x23, 0xec, 0xda, 0x6b, 0x40, 0x6d, 0x43, 0xda, 0xd6, 0x93, 0x15, 0xa5, 0x9a, 0xab, + 0xcf, 0xfe, 0x3d, 0x34, 0x32, 0x51, 0x27, 0xac, 0x99, 0x4b, 0x66, 0x1c, 0xc5, 0xbd, 0x9a, 0x06, + 0xd4, 0xed, 0x88, 0xf8, 0xba, 0xca, 0xa3, 0x1c, 0xb1, 0xae, 0x2d, 0x7c, 0xfe, 0x8d, 0x31, 0xf3, + 0xc5, 0xc1, 0xce, 0xa2, 0x3e, 0xd6, 0xfa, 0x44, 0x9b, 0xe6, 0xf7, 0x09, 0x90, 0xdd, 0x40, 0x1e, + 0x74, 0x07, 0x8d, 0xbe, 0x36, 0x07, 0x52, 0x01, 0x09, 0x5c, 0x24, 0x9a, 0x56, 0x1d, 0xb9, 0xd1, + 0xde, 0x06, 0x39, 0x0f, 0x72, 0x80, 0xb1, 0x2b, 0x9b, 0xcc, 0xd5, 0x8b, 0x7f, 0x0c, 0x8d, 0xeb, + 0xb2, 0x26, 0x6d, 0x7d, 0x6c, 0x61, 0x62, 0xfb, 0x90, 0xb5, 0xad, 0x07, 0x01, 0x73, 0xb2, 0x1e, + 0xa4, 0x0f, 0x79, 0xa8, 0x56, 0x06, 0x49, 0x0f, 0x52, 0xd1, 0xb6, 0x5a, 0x2f, 0xec, 0x0d, 0x8d, + 0xec, 0x3b, 0x90, 0x6e, 0x60, 0x1f, 0x33, 0x87, 0x3b, 0xb4, 0x2b, 0x20, 0xc1, 0x48, 0xdc, 0x6f, + 0x82, 0x11, 0xed, 0x2e, 0x48, 0xf5, 0x60, 0xa7, 0x8b, 0xf4, 0x94, 0x38, 0xe3, 0xe6, 0x99, 0x67, + 0xec, 0x0d, 0x8d, 0xf4, 0x8a, 0x4f, 0xba, 0x01, 0x73, 0x64, 0x06, 0x1f, 0x5e, 0x80, 0x9d, 0xae, + 0x28, 0xd5, 0x42, 0x0c, 0x6b, 0x01, 0x28, 0x3d, 0x3d, 0x23, 0x0c, 0x4a, 0x8f, 0xef, 0x22, 0x3d, + 0x2b, 0x77, 0x11, 0xdf, 0x51, 0x3d, 0x27, 0x77, 0xb4, 0xf6, 0x3a, 0x87, 0xe9, 0xe7, 0xa7, 0x4b, + 0xe9, 0x46, 0x7f, 0x0d, 0x32, 0xc8, 0x01, 0x7b, 0x79, 0x0c, 0xb0, 0x11, 0x3c, 0xe6, 0xf3, 0x24, + 0x28, 0xac, 0xb8, 0x2e, 0xa2, 0x74, 0x03, 0x53, 0xd6, 0xe8, 0x6b, 0xef, 0x82, 0xac, 0xdb, 0x86, + 0x38, 0x68, 0xe2, 0x96, 0x80, 0x2c, 0x57, 0xb7, 0xcf, 0x6b, 0x3a, 0xb3, 0xca, 0x83, 0x1f, 0xac, + 0x1d, 0x0e, 0x8d, 0x8c, 0x2b, 0x97, 0x4e, 0xbc, 0x68, 0x1d, 0x63, 0x9f, 0x38, 0x13, 0xfb, 0xe4, + 0xbf, 0xc6, 0x5e, 0x3d, 0x1f, 0xfb, 0xd4, 0x34, 0xf6, 0xe9, 0x17, 0xc6, 0x3e, 0x33, 0x86, 0xfd, + 0x47, 0x20, 0x0b, 0x05, 0x50, 0x88, 0xea, 0xd9, 0x4a, 0xb2, 0x9a, 0x5f, 0xbe, 0x61, 0x9d, 0x7c, + 0xca, 0x2d, 0x09, 0x65, 0xa3, 0x1b, 0x76, 0x50, 0xfd, 0xd6, 0xb3, 0xa1, 0x31, 0x73, 0x38, 0x34, + 0x00, 0x3c, 0xc2, 0xf7, 0x87, 0xe7, 0x06, 0x38, 0x46, 0x5b, 0x4a, 0xfd, 0xa8, 0xaa, 0x64, 0x37, + 0x37, 0xc1, 0x2e, 0x98, 0x60, 0x37, 0x3f, 0x62, 0x77, 0x71, 0x9a, 0xdd, 0xf9, 0x31, 0x76, 0xc7, + 0x09, 0x35, 0xbf, 0x56, 0x41, 0x61, 0x6d, 0x10, 0x40, 0x1f, 0xbb, 0xf7, 0x11, 0xfa, 0x5f, 0x18, + 0xbe, 0x0b, 0xf2, 0x9c, 0x61, 0x86, 0xc3, 0xa6, 0x0b, 0xc3, 0x8b, 0x39, 0xe6, 0x7a, 0x68, 0xe0, + 0x70, 0x15, 0x86, 0xa3, 0xd4, 0x6d, 0x84, 0x44, 0xaa, 0x7a, 0x99, 0xd4, 0xfb, 0x08, 0xf1, 0xd4, + 0x58, 0x1f, 0xa9, 0xf3, 0xf5, 0x91, 0x9e, 0xd6, 0x47, 0xe6, 0x85, 0xf5, 0x91, 0x3d, 0x43, 0x1f, + 0xb9, 0xff, 0x4e, 0x1f, 0x60, 0x42, 0x1f, 0xf9, 0x09, 0x7d, 0x14, 0x2e, 0xa9, 0x8f, 0x71, 0x39, + 0x98, 0x26, 0x28, 0xad, 0xf7, 0x19, 0x0a, 0x28, 0x26, 0xc1, 0x7b, 0xa1, 0x78, 0x6f, 0x1c, 0xdf, + 0xa5, 0x35, 0x95, 0x57, 0x32, 0xbf, 0x55, 0xc0, 0xf5, 0x89, 0x3b, 0xd6, 0x41, 0x34, 0x24, 0x01, + 0x15, 0x48, 0x88, 0x8b, 0x5c, 0x91, 0x57, 0xb4, 0xb8, 0xb6, 0x6f, 0x03, 0xb5, 0x43, 0x3c, 0xaa, + 0x27, 0x04, 0x0a, 0xd7, 0xa7, 0x51, 0xd8, 0x20, 0x9e, 0x23, 0x42, 0xb4, 0x59, 0x90, 0x8c, 0x10, + 0x13, 0x0a, 0x29, 0x38, 0x7c, 0xa9, 0x15, 0x41, 0xb6, 0xe7, 0x37, 0x51, 0x14, 0x91, 0x28, 0xbe, + 0x47, 0x33, 0x3d, 0x7f, 0x9d, 0x6f, 0xb9, 0x8b, 0x6b, 0xa3, 0x4b, 0x51, 0x4b, 0xb2, 0xec, 0x64, + 0x3c, 0x48, 0x1f, 0x51, 0xd4, 0x8a, 0xdb, 0xfc, 0x49, 0x01, 0x57, 0x37, 0xa9, 0xf7, 0x28, 0x6c, + 0x41, 0x86, 0x1e, 0xc2, 0x08, 0xfa, 0x94, 0xdf, 0x36, 0xb0, 0xcb, 0xda, 0x24, 0xc2, 0x6c, 0x10, + 0xcb, 0x5d, 0xff, 0xf5, 0xe9, 0xd2, 0x5c, 0xdc, 0xd4, 0x4a, 0xab, 0x15, 0x21, 0x4a, 0xdf, 0x67, + 0x11, 0x0e, 0x3c, 0xe7, 0x38, 0x54, 0xbb, 0x07, 0xd2, 0xa1, 0xa8, 0x20, 0xa4, 0x9d, 0x5f, 0xd6, + 0xa7, 0xc7, 0x90, 0x27, 0xd4, 0x73, 0x9c, 0x47, 0xc9, 0x55, 0x9c, 0x52, 0x5b, 0x7e, 0x72, 0xb0, + 0xb3, 0x78, 0x5c, 0x8c, 0xe3, 0x6f, 0x8c, 0xe1, 0xdf, 0xb7, 0xe5, 0x3b, 0x6b, 0xbc, 0x51, 0xb3, + 0x08, 0xe6, 0x4f, 0x98, 0x46, 0x20, 0x9b, 0xbb, 0x0a, 0xb8, 0xb6, 0x49, 0xbd, 0x4d, 0xec, 0x45, + 0x90, 0xa1, 0x15, 0xd7, 0xe5, 0x5a, 0xd4, 0x56, 0xc1, 0x2c, 0x89, 0xb0, 0x87, 0x03, 0xd8, 0x69, + 0x42, 0x39, 0xc6, 0x85, 0x03, 0x5e, 0x1d, 0x65, 0xc4, 0x66, 0xfe, 0xbc, 0x05, 0xe8, 0xf1, 0x51, + 0x7e, 0xe2, 0x82, 0x7c, 0x10, 0xa0, 0xc7, 0xb1, 0xa5, 0x76, 0x8f, 0x0f, 0x39, 0xd5, 0x02, 0x9f, + 0x75, 0xe1, 0x94, 0x59, 0x27, 0x9b, 0x37, 0x5f, 0x01, 0xc5, 0x29, 0xe3, 0x68, 0xde, 0xe5, 0x5f, + 0x12, 0x20, 0xb9, 0x49, 0x3d, 0xed, 0x53, 0x00, 0xc6, 0xbe, 0x3e, 0x8c, 0x69, 0x06, 0x26, 0x34, + 0x59, 0x7a, 0xe3, 0x82, 0x80, 0x23, 0x3c, 0x6f, 0x3d, 0xf9, 0xed, 0xaf, 0xaf, 0x12, 0x86, 0x79, + 0xc3, 0x9e, 0xfe, 0xfc, 0x89, 0xa3, 0x9b, 0xac, 0xaf, 0x7d, 0x08, 0x0a, 0x13, 0x52, 0x5a, 0x38, + 0xb5, 0xfe, 0x78, 0x48, 0xe9, 0xf6, 0x85, 0x21, 0x47, 0x4f, 0xce, 0x16, 0xb8, 0x72, 0x82, 0xd0, + 0x9b, 0xa7, 0x26, 0x4f, 0x06, 0x95, 0xde, 0xbc, 0x44, 0xd0, 0xe8, 0x8c, 0x52, 0xea, 0x33, 0x2e, + 0xcb, 0x7a, 0xed, 0xd9, 0x5e, 0x59, 0xd9, 0xdd, 0x2b, 0x2b, 0x7f, 0xee, 0x95, 0x95, 0x2f, 0xf7, + 0xcb, 0x33, 0xbb, 0xfb, 0xe5, 0x99, 0xdf, 0xf7, 0xcb, 0x33, 0x1f, 0x54, 0x3c, 0xcc, 0xda, 0xdd, + 0x2d, 0xcb, 0x25, 0xbe, 0x7d, 0x92, 0x34, 0x36, 0x08, 0x11, 0xdd, 0x4a, 0x8b, 0xaf, 0xbb, 0xb7, + 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0xc4, 0x64, 0xbc, 0x03, 0xed, 0x0a, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -541,6 +639,8 @@ type MsgClient interface { // parameters. The authority is hard-coded to the Cosmos SDK x/gov module // account UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) + //todo: comments + MigrateAccount(ctx context.Context, in *MsgMigrateAccount, opts ...grpc.CallOption) (*MsgMigrateAccountResponse, error) } type msgClient struct { @@ -569,6 +669,15 @@ func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts return out, nil } +func (c *msgClient) MigrateAccount(ctx context.Context, in *MsgMigrateAccount, opts ...grpc.CallOption) (*MsgMigrateAccountResponse, error) { + out := new(MsgMigrateAccountResponse) + err := c.cc.Invoke(ctx, "/cosmos.evm.vm.v1.Msg/MigrateAccount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // MsgServer is the server API for Msg service. type MsgServer interface { // EthereumTx defines a method submitting Ethereum transactions. @@ -577,6 +686,8 @@ type MsgServer interface { // parameters. The authority is hard-coded to the Cosmos SDK x/gov module // account UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) + //todo: comments + MigrateAccount(context.Context, *MsgMigrateAccount) (*MsgMigrateAccountResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -589,6 +700,9 @@ func (*UnimplementedMsgServer) EthereumTx(ctx context.Context, req *MsgEthereumT func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") } +func (*UnimplementedMsgServer) MigrateAccount(ctx context.Context, req *MsgMigrateAccount) (*MsgMigrateAccountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method MigrateAccount not implemented") +} func RegisterMsgServer(s grpc1.Server, srv MsgServer) { s.RegisterService(&_Msg_serviceDesc, srv) @@ -630,6 +744,24 @@ func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Msg_MigrateAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgMigrateAccount) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).MigrateAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.evm.vm.v1.Msg/MigrateAccount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).MigrateAccount(ctx, req.(*MsgMigrateAccount)) + } + return interceptor(ctx, in, info, handler) +} + var _Msg_serviceDesc = grpc.ServiceDesc{ ServiceName: "cosmos.evm.vm.v1.Msg", HandlerType: (*MsgServer)(nil), @@ -642,6 +774,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "UpdateParams", Handler: _Msg_UpdateParams_Handler, }, + { + MethodName: "MigrateAccount", + Handler: _Msg_MigrateAccount_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "cosmos/evm/vm/v1/tx.proto", @@ -1191,6 +1327,66 @@ func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *MsgMigrateAccount) 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 *MsgMigrateAccount) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgMigrateAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.NewAddress) > 0 { + i -= len(m.NewAddress) + copy(dAtA[i:], m.NewAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.NewAddress))) + i-- + dAtA[i] = 0x12 + } + if len(m.OriginalAddress) > 0 { + i -= len(m.OriginalAddress) + copy(dAtA[i:], m.OriginalAddress) + i = encodeVarintTx(dAtA, i, uint64(len(m.OriginalAddress))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgMigrateAccountResponse) 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 *MsgMigrateAccountResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgMigrateAccountResponse) 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 @@ -1442,6 +1638,32 @@ func (m *MsgUpdateParamsResponse) Size() (n int) { return n } +func (m *MsgMigrateAccount) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.OriginalAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.NewAddress) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgMigrateAccountResponse) 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 } @@ -3185,6 +3407,170 @@ func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgMigrateAccount) 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: MsgMigrateAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgMigrateAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OriginalAddress", 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.OriginalAddress = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NewAddress", 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.NewAddress = string(dAtA[iNdEx:postIndex]) + 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 *MsgMigrateAccountResponse) 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: MsgMigrateAccountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgMigrateAccountResponse: 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 diff --git a/x/vm/wrappers/testutil/mock.go b/x/vm/wrappers/testutil/mock.go index c3b17785..b1131cf7 100644 --- a/x/vm/wrappers/testutil/mock.go +++ b/x/vm/wrappers/testutil/mock.go @@ -11,6 +11,7 @@ package testutil import ( context "context" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" big "math/big" reflect "reflect" @@ -93,6 +94,21 @@ type MockBankWrapper struct { isgomock struct{} } +func (m *MockBankWrapper) SpendableBalances(ctx context.Context, req *banktypes.QuerySpendableBalancesRequest) (*banktypes.QuerySpendableBalancesResponse, error) { + //TODO implement me + panic("implement me") +} + +func (m *MockBankWrapper) BlockedAddr(addr types.AccAddress) bool { + //TODO implement me + panic("implement me") +} + +func (m *MockBankWrapper) SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt types.Coins) error { + //TODO implement me + panic("implement me") +} + // MockBankWrapperMockRecorder is the mock recorder for MockBankWrapper. type MockBankWrapperMockRecorder struct { mock *MockBankWrapper