From 67087bbb6f7ddd4877c7045eedd1a11f68d45ffc Mon Sep 17 00:00:00 2001 From: HuangYi Date: Mon, 17 Jan 2022 18:18:50 +0800 Subject: [PATCH 01/10] Add hooks to allow app modules to add things to state-sync Closes: #7340 - Support registering multiple snapshotters in snapshot manager. - Append the extension snapshotters to existing snapshot stream. fix v2 store fix rootmulti unit tests fix unit tests fix unit tests fix typo add utility function WriteExtensionItem add convenient public methods --- .../base/snapshots/v1beta1/snapshot.pulsar.go | 3126 ++++++++++++++++- baseapp/baseapp.go | 12 + baseapp/options.go | 2 +- .../base/snapshots/v1beta1/snapshot.proto | 37 +- .../cosmos/base/store/v1beta1/snapshot.proto | 28 - server/mock/store.go | 8 +- snapshots/{util.go => chunk.go} | 0 snapshots/{util_test.go => chunk_test.go} | 0 snapshots/helpers_test.go | 105 +- snapshots/manager.go | 149 +- snapshots/manager_test.go | 47 +- snapshots/stream.go | 107 + snapshots/types/snapshot.pb.go | 1548 +++++++- snapshots/types/snapshotter.go | 27 +- snapshots/types/util.go | 16 + store/rootmulti/snapshot_test.go | 296 ++ store/rootmulti/store.go | 204 +- store/rootmulti/store_test.go | 344 +- store/types/snapshot.pb.go | 594 +++- store/v2/multi/store.go | 12 +- 20 files changed, 5951 insertions(+), 711 deletions(-) delete mode 100644 proto/cosmos/base/store/v1beta1/snapshot.proto rename snapshots/{util.go => chunk.go} (100%) rename snapshots/{util_test.go => chunk_test.go} (100%) create mode 100644 snapshots/stream.go create mode 100644 snapshots/types/util.go create mode 100644 store/rootmulti/snapshot_test.go diff --git a/api/cosmos/base/snapshots/v1beta1/snapshot.pulsar.go b/api/cosmos/base/snapshots/v1beta1/snapshot.pulsar.go index 6541ca886133..ce92b9e1ea1c 100644 --- a/api/cosmos/base/snapshots/v1beta1/snapshot.pulsar.go +++ b/api/cosmos/base/snapshots/v1beta1/snapshot.pulsar.go @@ -1138,6 +1138,2686 @@ func (x *fastReflection_Metadata) ProtoMethods() *protoiface.Methods { } } +var ( + md_SnapshotItem protoreflect.MessageDescriptor + fd_SnapshotItem_store protoreflect.FieldDescriptor + fd_SnapshotItem_iavl protoreflect.FieldDescriptor + fd_SnapshotItem_extension protoreflect.FieldDescriptor + fd_SnapshotItem_extension_payload protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_base_snapshots_v1beta1_snapshot_proto_init() + md_SnapshotItem = File_cosmos_base_snapshots_v1beta1_snapshot_proto.Messages().ByName("SnapshotItem") + fd_SnapshotItem_store = md_SnapshotItem.Fields().ByName("store") + fd_SnapshotItem_iavl = md_SnapshotItem.Fields().ByName("iavl") + fd_SnapshotItem_extension = md_SnapshotItem.Fields().ByName("extension") + fd_SnapshotItem_extension_payload = md_SnapshotItem.Fields().ByName("extension_payload") +} + +var _ protoreflect.Message = (*fastReflection_SnapshotItem)(nil) + +type fastReflection_SnapshotItem SnapshotItem + +func (x *SnapshotItem) ProtoReflect() protoreflect.Message { + return (*fastReflection_SnapshotItem)(x) +} + +func (x *SnapshotItem) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_SnapshotItem_messageType fastReflection_SnapshotItem_messageType +var _ protoreflect.MessageType = fastReflection_SnapshotItem_messageType{} + +type fastReflection_SnapshotItem_messageType struct{} + +func (x fastReflection_SnapshotItem_messageType) Zero() protoreflect.Message { + return (*fastReflection_SnapshotItem)(nil) +} +func (x fastReflection_SnapshotItem_messageType) New() protoreflect.Message { + return new(fastReflection_SnapshotItem) +} +func (x fastReflection_SnapshotItem_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotItem +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_SnapshotItem) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotItem +} + +// 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_SnapshotItem) Type() protoreflect.MessageType { + return _fastReflection_SnapshotItem_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_SnapshotItem) New() protoreflect.Message { + return new(fastReflection_SnapshotItem) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_SnapshotItem) Interface() protoreflect.ProtoMessage { + return (*SnapshotItem)(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_SnapshotItem) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Item != nil { + switch o := x.Item.(type) { + case *SnapshotItem_Store: + v := o.Store + value := protoreflect.ValueOfMessage(v.ProtoReflect()) + if !f(fd_SnapshotItem_store, value) { + return + } + case *SnapshotItem_Iavl: + v := o.Iavl + value := protoreflect.ValueOfMessage(v.ProtoReflect()) + if !f(fd_SnapshotItem_iavl, value) { + return + } + case *SnapshotItem_Extension: + v := o.Extension + value := protoreflect.ValueOfMessage(v.ProtoReflect()) + if !f(fd_SnapshotItem_extension, value) { + return + } + case *SnapshotItem_ExtensionPayload: + v := o.ExtensionPayload + value := protoreflect.ValueOfMessage(v.ProtoReflect()) + if !f(fd_SnapshotItem_extension_payload, 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_SnapshotItem) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotItem.store": + if x.Item == nil { + return false + } else if _, ok := x.Item.(*SnapshotItem_Store); ok { + return true + } else { + return false + } + case "cosmos.base.snapshots.v1beta1.SnapshotItem.iavl": + if x.Item == nil { + return false + } else if _, ok := x.Item.(*SnapshotItem_Iavl); ok { + return true + } else { + return false + } + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension": + if x.Item == nil { + return false + } else if _, ok := x.Item.(*SnapshotItem_Extension); ok { + return true + } else { + return false + } + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension_payload": + if x.Item == nil { + return false + } else if _, ok := x.Item.(*SnapshotItem_ExtensionPayload); ok { + return true + } else { + return false + } + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotItem 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_SnapshotItem) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotItem.store": + x.Item = nil + case "cosmos.base.snapshots.v1beta1.SnapshotItem.iavl": + x.Item = nil + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension": + x.Item = nil + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension_payload": + x.Item = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotItem 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_SnapshotItem) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotItem.store": + if x.Item == nil { + return protoreflect.ValueOfMessage((*SnapshotStoreItem)(nil).ProtoReflect()) + } else if v, ok := x.Item.(*SnapshotItem_Store); ok { + return protoreflect.ValueOfMessage(v.Store.ProtoReflect()) + } else { + return protoreflect.ValueOfMessage((*SnapshotStoreItem)(nil).ProtoReflect()) + } + case "cosmos.base.snapshots.v1beta1.SnapshotItem.iavl": + if x.Item == nil { + return protoreflect.ValueOfMessage((*SnapshotIAVLItem)(nil).ProtoReflect()) + } else if v, ok := x.Item.(*SnapshotItem_Iavl); ok { + return protoreflect.ValueOfMessage(v.Iavl.ProtoReflect()) + } else { + return protoreflect.ValueOfMessage((*SnapshotIAVLItem)(nil).ProtoReflect()) + } + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension": + if x.Item == nil { + return protoreflect.ValueOfMessage((*SnapshotExtensionMeta)(nil).ProtoReflect()) + } else if v, ok := x.Item.(*SnapshotItem_Extension); ok { + return protoreflect.ValueOfMessage(v.Extension.ProtoReflect()) + } else { + return protoreflect.ValueOfMessage((*SnapshotExtensionMeta)(nil).ProtoReflect()) + } + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension_payload": + if x.Item == nil { + return protoreflect.ValueOfMessage((*SnapshotExtensionPayload)(nil).ProtoReflect()) + } else if v, ok := x.Item.(*SnapshotItem_ExtensionPayload); ok { + return protoreflect.ValueOfMessage(v.ExtensionPayload.ProtoReflect()) + } else { + return protoreflect.ValueOfMessage((*SnapshotExtensionPayload)(nil).ProtoReflect()) + } + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotItem 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_SnapshotItem) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotItem.store": + cv := value.Message().Interface().(*SnapshotStoreItem) + x.Item = &SnapshotItem_Store{Store: cv} + case "cosmos.base.snapshots.v1beta1.SnapshotItem.iavl": + cv := value.Message().Interface().(*SnapshotIAVLItem) + x.Item = &SnapshotItem_Iavl{Iavl: cv} + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension": + cv := value.Message().Interface().(*SnapshotExtensionMeta) + x.Item = &SnapshotItem_Extension{Extension: cv} + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension_payload": + cv := value.Message().Interface().(*SnapshotExtensionPayload) + x.Item = &SnapshotItem_ExtensionPayload{ExtensionPayload: cv} + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotItem 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_SnapshotItem) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotItem.store": + if x.Item == nil { + value := &SnapshotStoreItem{} + oneofValue := &SnapshotItem_Store{Store: value} + x.Item = oneofValue + return protoreflect.ValueOfMessage(value.ProtoReflect()) + } + switch m := x.Item.(type) { + case *SnapshotItem_Store: + return protoreflect.ValueOfMessage(m.Store.ProtoReflect()) + default: + value := &SnapshotStoreItem{} + oneofValue := &SnapshotItem_Store{Store: value} + x.Item = oneofValue + return protoreflect.ValueOfMessage(value.ProtoReflect()) + } + case "cosmos.base.snapshots.v1beta1.SnapshotItem.iavl": + if x.Item == nil { + value := &SnapshotIAVLItem{} + oneofValue := &SnapshotItem_Iavl{Iavl: value} + x.Item = oneofValue + return protoreflect.ValueOfMessage(value.ProtoReflect()) + } + switch m := x.Item.(type) { + case *SnapshotItem_Iavl: + return protoreflect.ValueOfMessage(m.Iavl.ProtoReflect()) + default: + value := &SnapshotIAVLItem{} + oneofValue := &SnapshotItem_Iavl{Iavl: value} + x.Item = oneofValue + return protoreflect.ValueOfMessage(value.ProtoReflect()) + } + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension": + if x.Item == nil { + value := &SnapshotExtensionMeta{} + oneofValue := &SnapshotItem_Extension{Extension: value} + x.Item = oneofValue + return protoreflect.ValueOfMessage(value.ProtoReflect()) + } + switch m := x.Item.(type) { + case *SnapshotItem_Extension: + return protoreflect.ValueOfMessage(m.Extension.ProtoReflect()) + default: + value := &SnapshotExtensionMeta{} + oneofValue := &SnapshotItem_Extension{Extension: value} + x.Item = oneofValue + return protoreflect.ValueOfMessage(value.ProtoReflect()) + } + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension_payload": + if x.Item == nil { + value := &SnapshotExtensionPayload{} + oneofValue := &SnapshotItem_ExtensionPayload{ExtensionPayload: value} + x.Item = oneofValue + return protoreflect.ValueOfMessage(value.ProtoReflect()) + } + switch m := x.Item.(type) { + case *SnapshotItem_ExtensionPayload: + return protoreflect.ValueOfMessage(m.ExtensionPayload.ProtoReflect()) + default: + value := &SnapshotExtensionPayload{} + oneofValue := &SnapshotItem_ExtensionPayload{ExtensionPayload: value} + x.Item = oneofValue + return protoreflect.ValueOfMessage(value.ProtoReflect()) + } + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotItem 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_SnapshotItem) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotItem.store": + value := &SnapshotStoreItem{} + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "cosmos.base.snapshots.v1beta1.SnapshotItem.iavl": + value := &SnapshotIAVLItem{} + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension": + value := &SnapshotExtensionMeta{} + return protoreflect.ValueOfMessage(value.ProtoReflect()) + case "cosmos.base.snapshots.v1beta1.SnapshotItem.extension_payload": + value := &SnapshotExtensionPayload{} + return protoreflect.ValueOfMessage(value.ProtoReflect()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotItem 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_SnapshotItem) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotItem.item": + if x.Item == nil { + return nil + } + switch x.Item.(type) { + case *SnapshotItem_Store: + return x.Descriptor().Fields().ByName("store") + case *SnapshotItem_Iavl: + return x.Descriptor().Fields().ByName("iavl") + case *SnapshotItem_Extension: + return x.Descriptor().Fields().ByName("extension") + case *SnapshotItem_ExtensionPayload: + return x.Descriptor().Fields().ByName("extension_payload") + } + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.base.snapshots.v1beta1.SnapshotItem", 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_SnapshotItem) 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_SnapshotItem) 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_SnapshotItem) 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_SnapshotItem) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*SnapshotItem) + if x == nil { + return protoiface.SizeOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Size: 0, + } + } + options := runtime.SizeInputToOptions(input) + _ = options + var n int + var l int + _ = l + switch x := x.Item.(type) { + case *SnapshotItem_Store: + if x == nil { + break + } + l = options.Size(x.Store) + n += 1 + l + runtime.Sov(uint64(l)) + case *SnapshotItem_Iavl: + if x == nil { + break + } + l = options.Size(x.Iavl) + n += 1 + l + runtime.Sov(uint64(l)) + case *SnapshotItem_Extension: + if x == nil { + break + } + l = options.Size(x.Extension) + n += 1 + l + runtime.Sov(uint64(l)) + case *SnapshotItem_ExtensionPayload: + if x == nil { + break + } + l = options.Size(x.ExtensionPayload) + 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().(*SnapshotItem) + 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) + } + switch x := x.Item.(type) { + case *SnapshotItem_Store: + encoded, err := options.Marshal(x.Store) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0xa + case *SnapshotItem_Iavl: + encoded, err := options.Marshal(x.Iavl) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x12 + case *SnapshotItem_Extension: + encoded, err := options.Marshal(x.Extension) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x1a + case *SnapshotItem_ExtensionPayload: + encoded, err := options.Marshal(x.ExtensionPayload) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x22 + } + if 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().(*SnapshotItem) + 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: SnapshotItem: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: SnapshotItem: 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 Store", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + v := &SnapshotStoreItem{} + if err := options.Unmarshal(dAtA[iNdEx:postIndex], v); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + x.Item = &SnapshotItem_Store{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Iavl", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + v := &SnapshotIAVLItem{} + if err := options.Unmarshal(dAtA[iNdEx:postIndex], v); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + x.Item = &SnapshotItem_Iavl{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Extension", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + v := &SnapshotExtensionMeta{} + if err := options.Unmarshal(dAtA[iNdEx:postIndex], v); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + x.Item = &SnapshotItem_Extension{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExtensionPayload", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + v := &SnapshotExtensionPayload{} + if err := options.Unmarshal(dAtA[iNdEx:postIndex], v); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + x.Item = &SnapshotItem_ExtensionPayload{v} + 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_SnapshotStoreItem protoreflect.MessageDescriptor + fd_SnapshotStoreItem_name protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_base_snapshots_v1beta1_snapshot_proto_init() + md_SnapshotStoreItem = File_cosmos_base_snapshots_v1beta1_snapshot_proto.Messages().ByName("SnapshotStoreItem") + fd_SnapshotStoreItem_name = md_SnapshotStoreItem.Fields().ByName("name") +} + +var _ protoreflect.Message = (*fastReflection_SnapshotStoreItem)(nil) + +type fastReflection_SnapshotStoreItem SnapshotStoreItem + +func (x *SnapshotStoreItem) ProtoReflect() protoreflect.Message { + return (*fastReflection_SnapshotStoreItem)(x) +} + +func (x *SnapshotStoreItem) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_SnapshotStoreItem_messageType fastReflection_SnapshotStoreItem_messageType +var _ protoreflect.MessageType = fastReflection_SnapshotStoreItem_messageType{} + +type fastReflection_SnapshotStoreItem_messageType struct{} + +func (x fastReflection_SnapshotStoreItem_messageType) Zero() protoreflect.Message { + return (*fastReflection_SnapshotStoreItem)(nil) +} +func (x fastReflection_SnapshotStoreItem_messageType) New() protoreflect.Message { + return new(fastReflection_SnapshotStoreItem) +} +func (x fastReflection_SnapshotStoreItem_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotStoreItem +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_SnapshotStoreItem) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotStoreItem +} + +// 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_SnapshotStoreItem) Type() protoreflect.MessageType { + return _fastReflection_SnapshotStoreItem_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_SnapshotStoreItem) New() protoreflect.Message { + return new(fastReflection_SnapshotStoreItem) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_SnapshotStoreItem) Interface() protoreflect.ProtoMessage { + return (*SnapshotStoreItem)(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_SnapshotStoreItem) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Name != "" { + value := protoreflect.ValueOfString(x.Name) + if !f(fd_SnapshotStoreItem_name, 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_SnapshotStoreItem) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotStoreItem.name": + return x.Name != "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotStoreItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotStoreItem 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_SnapshotStoreItem) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotStoreItem.name": + x.Name = "" + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotStoreItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotStoreItem 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_SnapshotStoreItem) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotStoreItem.name": + value := x.Name + return protoreflect.ValueOfString(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotStoreItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotStoreItem 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_SnapshotStoreItem) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotStoreItem.name": + x.Name = value.Interface().(string) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotStoreItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotStoreItem 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_SnapshotStoreItem) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotStoreItem.name": + panic(fmt.Errorf("field name of message cosmos.base.snapshots.v1beta1.SnapshotStoreItem is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotStoreItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotStoreItem 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_SnapshotStoreItem) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotStoreItem.name": + return protoreflect.ValueOfString("") + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotStoreItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotStoreItem 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_SnapshotStoreItem) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.base.snapshots.v1beta1.SnapshotStoreItem", 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_SnapshotStoreItem) 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_SnapshotStoreItem) 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_SnapshotStoreItem) 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_SnapshotStoreItem) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*SnapshotStoreItem) + 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.Name) + 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().(*SnapshotStoreItem) + 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.Name) > 0 { + i -= len(x.Name) + copy(dAtA[i:], x.Name) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name))) + 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().(*SnapshotStoreItem) + 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: SnapshotStoreItem: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: SnapshotStoreItem: 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 Name", 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.Name = 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_SnapshotIAVLItem protoreflect.MessageDescriptor + fd_SnapshotIAVLItem_key protoreflect.FieldDescriptor + fd_SnapshotIAVLItem_value protoreflect.FieldDescriptor + fd_SnapshotIAVLItem_version protoreflect.FieldDescriptor + fd_SnapshotIAVLItem_height protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_base_snapshots_v1beta1_snapshot_proto_init() + md_SnapshotIAVLItem = File_cosmos_base_snapshots_v1beta1_snapshot_proto.Messages().ByName("SnapshotIAVLItem") + fd_SnapshotIAVLItem_key = md_SnapshotIAVLItem.Fields().ByName("key") + fd_SnapshotIAVLItem_value = md_SnapshotIAVLItem.Fields().ByName("value") + fd_SnapshotIAVLItem_version = md_SnapshotIAVLItem.Fields().ByName("version") + fd_SnapshotIAVLItem_height = md_SnapshotIAVLItem.Fields().ByName("height") +} + +var _ protoreflect.Message = (*fastReflection_SnapshotIAVLItem)(nil) + +type fastReflection_SnapshotIAVLItem SnapshotIAVLItem + +func (x *SnapshotIAVLItem) ProtoReflect() protoreflect.Message { + return (*fastReflection_SnapshotIAVLItem)(x) +} + +func (x *SnapshotIAVLItem) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_SnapshotIAVLItem_messageType fastReflection_SnapshotIAVLItem_messageType +var _ protoreflect.MessageType = fastReflection_SnapshotIAVLItem_messageType{} + +type fastReflection_SnapshotIAVLItem_messageType struct{} + +func (x fastReflection_SnapshotIAVLItem_messageType) Zero() protoreflect.Message { + return (*fastReflection_SnapshotIAVLItem)(nil) +} +func (x fastReflection_SnapshotIAVLItem_messageType) New() protoreflect.Message { + return new(fastReflection_SnapshotIAVLItem) +} +func (x fastReflection_SnapshotIAVLItem_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotIAVLItem +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_SnapshotIAVLItem) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotIAVLItem +} + +// 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_SnapshotIAVLItem) Type() protoreflect.MessageType { + return _fastReflection_SnapshotIAVLItem_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_SnapshotIAVLItem) New() protoreflect.Message { + return new(fastReflection_SnapshotIAVLItem) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_SnapshotIAVLItem) Interface() protoreflect.ProtoMessage { + return (*SnapshotIAVLItem)(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_SnapshotIAVLItem) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Key) != 0 { + value := protoreflect.ValueOfBytes(x.Key) + if !f(fd_SnapshotIAVLItem_key, value) { + return + } + } + if len(x.Value) != 0 { + value := protoreflect.ValueOfBytes(x.Value) + if !f(fd_SnapshotIAVLItem_value, value) { + return + } + } + if x.Version != int64(0) { + value := protoreflect.ValueOfInt64(x.Version) + if !f(fd_SnapshotIAVLItem_version, value) { + return + } + } + if x.Height != int32(0) { + value := protoreflect.ValueOfInt32(x.Height) + if !f(fd_SnapshotIAVLItem_height, 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_SnapshotIAVLItem) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.key": + return len(x.Key) != 0 + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.value": + return len(x.Value) != 0 + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.version": + return x.Version != int64(0) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.height": + return x.Height != int32(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotIAVLItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem 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_SnapshotIAVLItem) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.key": + x.Key = nil + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.value": + x.Value = nil + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.version": + x.Version = int64(0) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.height": + x.Height = int32(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotIAVLItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem 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_SnapshotIAVLItem) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.key": + value := x.Key + return protoreflect.ValueOfBytes(value) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.value": + value := x.Value + return protoreflect.ValueOfBytes(value) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.version": + value := x.Version + return protoreflect.ValueOfInt64(value) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.height": + value := x.Height + return protoreflect.ValueOfInt32(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotIAVLItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem 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_SnapshotIAVLItem) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.key": + x.Key = value.Bytes() + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.value": + x.Value = value.Bytes() + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.version": + x.Version = value.Int() + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.height": + x.Height = int32(value.Int()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotIAVLItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem 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_SnapshotIAVLItem) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.key": + panic(fmt.Errorf("field key of message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem is not mutable")) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.value": + panic(fmt.Errorf("field value of message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem is not mutable")) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.version": + panic(fmt.Errorf("field version of message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem is not mutable")) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.height": + panic(fmt.Errorf("field height of message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotIAVLItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem 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_SnapshotIAVLItem) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.key": + return protoreflect.ValueOfBytes(nil) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.value": + return protoreflect.ValueOfBytes(nil) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.version": + return protoreflect.ValueOfInt64(int64(0)) + case "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem.height": + return protoreflect.ValueOfInt32(int32(0)) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotIAVLItem")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotIAVLItem 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_SnapshotIAVLItem) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.base.snapshots.v1beta1.SnapshotIAVLItem", 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_SnapshotIAVLItem) 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_SnapshotIAVLItem) 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_SnapshotIAVLItem) 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_SnapshotIAVLItem) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*SnapshotIAVLItem) + 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.Key) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + l = len(x.Value) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Version != 0 { + n += 1 + runtime.Sov(uint64(x.Version)) + } + if x.Height != 0 { + n += 1 + runtime.Sov(uint64(x.Height)) + } + 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().(*SnapshotIAVLItem) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Height != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Height)) + i-- + dAtA[i] = 0x20 + } + if x.Version != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Version)) + i-- + dAtA[i] = 0x18 + } + if len(x.Value) > 0 { + i -= len(x.Value) + copy(dAtA[i:], x.Value) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Value))) + i-- + dAtA[i] = 0x12 + } + if len(x.Key) > 0 { + i -= len(x.Key) + copy(dAtA[i:], x.Key) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Key))) + 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().(*SnapshotIAVLItem) + 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: SnapshotIAVLItem: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: SnapshotIAVLItem: 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 Key", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + 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.Key = append(x.Key[:0], dAtA[iNdEx:postIndex]...) + if x.Key == nil { + x.Key = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + 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.Value = append(x.Value[:0], dAtA[iNdEx:postIndex]...) + if x.Value == nil { + x.Value = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + x.Version = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Version |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + x.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Height |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + 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_SnapshotExtensionMeta protoreflect.MessageDescriptor + fd_SnapshotExtensionMeta_name protoreflect.FieldDescriptor + fd_SnapshotExtensionMeta_format protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_base_snapshots_v1beta1_snapshot_proto_init() + md_SnapshotExtensionMeta = File_cosmos_base_snapshots_v1beta1_snapshot_proto.Messages().ByName("SnapshotExtensionMeta") + fd_SnapshotExtensionMeta_name = md_SnapshotExtensionMeta.Fields().ByName("name") + fd_SnapshotExtensionMeta_format = md_SnapshotExtensionMeta.Fields().ByName("format") +} + +var _ protoreflect.Message = (*fastReflection_SnapshotExtensionMeta)(nil) + +type fastReflection_SnapshotExtensionMeta SnapshotExtensionMeta + +func (x *SnapshotExtensionMeta) ProtoReflect() protoreflect.Message { + return (*fastReflection_SnapshotExtensionMeta)(x) +} + +func (x *SnapshotExtensionMeta) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +var _fastReflection_SnapshotExtensionMeta_messageType fastReflection_SnapshotExtensionMeta_messageType +var _ protoreflect.MessageType = fastReflection_SnapshotExtensionMeta_messageType{} + +type fastReflection_SnapshotExtensionMeta_messageType struct{} + +func (x fastReflection_SnapshotExtensionMeta_messageType) Zero() protoreflect.Message { + return (*fastReflection_SnapshotExtensionMeta)(nil) +} +func (x fastReflection_SnapshotExtensionMeta_messageType) New() protoreflect.Message { + return new(fastReflection_SnapshotExtensionMeta) +} +func (x fastReflection_SnapshotExtensionMeta_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotExtensionMeta +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_SnapshotExtensionMeta) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotExtensionMeta +} + +// 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_SnapshotExtensionMeta) Type() protoreflect.MessageType { + return _fastReflection_SnapshotExtensionMeta_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_SnapshotExtensionMeta) New() protoreflect.Message { + return new(fastReflection_SnapshotExtensionMeta) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_SnapshotExtensionMeta) Interface() protoreflect.ProtoMessage { + return (*SnapshotExtensionMeta)(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_SnapshotExtensionMeta) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if x.Name != "" { + value := protoreflect.ValueOfString(x.Name) + if !f(fd_SnapshotExtensionMeta_name, value) { + return + } + } + if x.Format != uint32(0) { + value := protoreflect.ValueOfUint32(x.Format) + if !f(fd_SnapshotExtensionMeta_format, 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_SnapshotExtensionMeta) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.name": + return x.Name != "" + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.format": + return x.Format != uint32(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta 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_SnapshotExtensionMeta) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.name": + x.Name = "" + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.format": + x.Format = uint32(0) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta 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_SnapshotExtensionMeta) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.name": + value := x.Name + return protoreflect.ValueOfString(value) + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.format": + value := x.Format + return protoreflect.ValueOfUint32(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta 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_SnapshotExtensionMeta) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.name": + x.Name = value.Interface().(string) + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.format": + x.Format = uint32(value.Uint()) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta 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_SnapshotExtensionMeta) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.name": + panic(fmt.Errorf("field name of message cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta is not mutable")) + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.format": + panic(fmt.Errorf("field format of message cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta 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_SnapshotExtensionMeta) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.name": + return protoreflect.ValueOfString("") + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta.format": + return protoreflect.ValueOfUint32(uint32(0)) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta 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_SnapshotExtensionMeta) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta", 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_SnapshotExtensionMeta) 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_SnapshotExtensionMeta) 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_SnapshotExtensionMeta) 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_SnapshotExtensionMeta) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*SnapshotExtensionMeta) + 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.Name) + if l > 0 { + n += 1 + l + runtime.Sov(uint64(l)) + } + if x.Format != 0 { + n += 1 + runtime.Sov(uint64(x.Format)) + } + 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().(*SnapshotExtensionMeta) + if x == nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, nil + } + options := runtime.MarshalInputToOptions(input) + _ = options + size := options.Size(x) + dAtA := make([]byte, size) + i := len(dAtA) + _ = i + var l int + _ = l + if x.unknownFields != nil { + i -= len(x.unknownFields) + copy(dAtA[i:], x.unknownFields) + } + if x.Format != 0 { + i = runtime.EncodeVarint(dAtA, i, uint64(x.Format)) + i-- + dAtA[i] = 0x10 + } + if len(x.Name) > 0 { + i -= len(x.Name) + copy(dAtA[i:], x.Name) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Name))) + 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().(*SnapshotExtensionMeta) + 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: SnapshotExtensionMeta: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: SnapshotExtensionMeta: 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 Name", 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.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Format", wireType) + } + x.Format = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + x.Format |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + 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_SnapshotExtensionPayload protoreflect.MessageDescriptor + fd_SnapshotExtensionPayload_payload protoreflect.FieldDescriptor +) + +func init() { + file_cosmos_base_snapshots_v1beta1_snapshot_proto_init() + md_SnapshotExtensionPayload = File_cosmos_base_snapshots_v1beta1_snapshot_proto.Messages().ByName("SnapshotExtensionPayload") + fd_SnapshotExtensionPayload_payload = md_SnapshotExtensionPayload.Fields().ByName("payload") +} + +var _ protoreflect.Message = (*fastReflection_SnapshotExtensionPayload)(nil) + +type fastReflection_SnapshotExtensionPayload SnapshotExtensionPayload + +func (x *SnapshotExtensionPayload) ProtoReflect() protoreflect.Message { + return (*fastReflection_SnapshotExtensionPayload)(x) +} + +func (x *SnapshotExtensionPayload) slowProtoReflect() protoreflect.Message { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[6] + 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_SnapshotExtensionPayload_messageType fastReflection_SnapshotExtensionPayload_messageType +var _ protoreflect.MessageType = fastReflection_SnapshotExtensionPayload_messageType{} + +type fastReflection_SnapshotExtensionPayload_messageType struct{} + +func (x fastReflection_SnapshotExtensionPayload_messageType) Zero() protoreflect.Message { + return (*fastReflection_SnapshotExtensionPayload)(nil) +} +func (x fastReflection_SnapshotExtensionPayload_messageType) New() protoreflect.Message { + return new(fastReflection_SnapshotExtensionPayload) +} +func (x fastReflection_SnapshotExtensionPayload_messageType) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotExtensionPayload +} + +// Descriptor returns message descriptor, which contains only the protobuf +// type information for the message. +func (x *fastReflection_SnapshotExtensionPayload) Descriptor() protoreflect.MessageDescriptor { + return md_SnapshotExtensionPayload +} + +// 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_SnapshotExtensionPayload) Type() protoreflect.MessageType { + return _fastReflection_SnapshotExtensionPayload_messageType +} + +// New returns a newly allocated and mutable empty message. +func (x *fastReflection_SnapshotExtensionPayload) New() protoreflect.Message { + return new(fastReflection_SnapshotExtensionPayload) +} + +// Interface unwraps the message reflection interface and +// returns the underlying ProtoMessage interface. +func (x *fastReflection_SnapshotExtensionPayload) Interface() protoreflect.ProtoMessage { + return (*SnapshotExtensionPayload)(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_SnapshotExtensionPayload) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { + if len(x.Payload) != 0 { + value := protoreflect.ValueOfBytes(x.Payload) + if !f(fd_SnapshotExtensionPayload_payload, 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_SnapshotExtensionPayload) Has(fd protoreflect.FieldDescriptor) bool { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload.payload": + return len(x.Payload) != 0 + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload 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_SnapshotExtensionPayload) Clear(fd protoreflect.FieldDescriptor) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload.payload": + x.Payload = nil + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload 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_SnapshotExtensionPayload) Get(descriptor protoreflect.FieldDescriptor) protoreflect.Value { + switch descriptor.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload.payload": + value := x.Payload + return protoreflect.ValueOfBytes(value) + default: + if descriptor.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload 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_SnapshotExtensionPayload) Set(fd protoreflect.FieldDescriptor, value protoreflect.Value) { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload.payload": + x.Payload = value.Bytes() + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload 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_SnapshotExtensionPayload) Mutable(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload.payload": + panic(fmt.Errorf("field payload of message cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload is not mutable")) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload 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_SnapshotExtensionPayload) NewField(fd protoreflect.FieldDescriptor) protoreflect.Value { + switch fd.FullName() { + case "cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload.payload": + return protoreflect.ValueOfBytes(nil) + default: + if fd.IsExtension() { + panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload")) + } + panic(fmt.Errorf("message cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload 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_SnapshotExtensionPayload) WhichOneof(d protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { + switch d.FullName() { + default: + panic(fmt.Errorf("%s is not a oneof field in cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload", 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_SnapshotExtensionPayload) 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_SnapshotExtensionPayload) 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_SnapshotExtensionPayload) 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_SnapshotExtensionPayload) ProtoMethods() *protoiface.Methods { + size := func(input protoiface.SizeInput) protoiface.SizeOutput { + x := input.Message.Interface().(*SnapshotExtensionPayload) + 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.Payload) + 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().(*SnapshotExtensionPayload) + 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.Payload) > 0 { + i -= len(x.Payload) + copy(dAtA[i:], x.Payload) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Payload))) + 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().(*SnapshotExtensionPayload) + 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: SnapshotExtensionPayload: wiretype end group for non-group") + } + if fieldNum <= 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: SnapshotExtensionPayload: 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 Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + byteLen + 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.Payload = append(x.Payload[:0], dAtA[iNdEx:postIndex]...) + if x.Payload == nil { + x.Payload = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := runtime.Skip(dAtA[iNdEx:]) + if err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if !options.DiscardUnknown { + x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + } + iNdEx += skippy + } + } + + if iNdEx > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, nil + } + return &protoiface.Methods{ + NoUnkeyedLiterals: struct{}{}, + Flags: protoiface.SupportMarshalDeterministic | protoiface.SupportUnmarshalDiscardUnknown, + Size: size, + Marshal: marshal, + Unmarshal: unmarshal, + Merge: nil, + CheckInitialized: nil, + } +} + // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.27.0 @@ -1255,6 +3935,281 @@ func (x *Metadata) GetChunkHashes() [][]byte { return nil } +// SnapshotItem is an item contained in a rootmulti.Store snapshot. +type SnapshotItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // item is the specific type of snapshot item. + // + // Types that are assignable to Item: + // *SnapshotItem_Store + // *SnapshotItem_Iavl + // *SnapshotItem_Extension + // *SnapshotItem_ExtensionPayload + Item isSnapshotItem_Item `protobuf_oneof:"item"` +} + +func (x *SnapshotItem) Reset() { + *x = SnapshotItem{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SnapshotItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SnapshotItem) ProtoMessage() {} + +// Deprecated: Use SnapshotItem.ProtoReflect.Descriptor instead. +func (*SnapshotItem) Descriptor() ([]byte, []int) { + return file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDescGZIP(), []int{2} +} + +func (x *SnapshotItem) GetItem() isSnapshotItem_Item { + if x != nil { + return x.Item + } + return nil +} + +func (x *SnapshotItem) GetStore() *SnapshotStoreItem { + if x, ok := x.GetItem().(*SnapshotItem_Store); ok { + return x.Store + } + return nil +} + +func (x *SnapshotItem) GetIavl() *SnapshotIAVLItem { + if x, ok := x.GetItem().(*SnapshotItem_Iavl); ok { + return x.Iavl + } + return nil +} + +func (x *SnapshotItem) GetExtension() *SnapshotExtensionMeta { + if x, ok := x.GetItem().(*SnapshotItem_Extension); ok { + return x.Extension + } + return nil +} + +func (x *SnapshotItem) GetExtensionPayload() *SnapshotExtensionPayload { + if x, ok := x.GetItem().(*SnapshotItem_ExtensionPayload); ok { + return x.ExtensionPayload + } + return nil +} + +type isSnapshotItem_Item interface { + isSnapshotItem_Item() +} + +type SnapshotItem_Store struct { + Store *SnapshotStoreItem `protobuf:"bytes,1,opt,name=store,proto3,oneof"` +} + +type SnapshotItem_Iavl struct { + Iavl *SnapshotIAVLItem `protobuf:"bytes,2,opt,name=iavl,proto3,oneof"` +} + +type SnapshotItem_Extension struct { + Extension *SnapshotExtensionMeta `protobuf:"bytes,3,opt,name=extension,proto3,oneof"` +} + +type SnapshotItem_ExtensionPayload struct { + ExtensionPayload *SnapshotExtensionPayload `protobuf:"bytes,4,opt,name=extension_payload,json=extensionPayload,proto3,oneof"` +} + +func (*SnapshotItem_Store) isSnapshotItem_Item() {} + +func (*SnapshotItem_Iavl) isSnapshotItem_Item() {} + +func (*SnapshotItem_Extension) isSnapshotItem_Item() {} + +func (*SnapshotItem_ExtensionPayload) isSnapshotItem_Item() {} + +// SnapshotStoreItem contains metadata about a snapshotted store. +type SnapshotStoreItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *SnapshotStoreItem) Reset() { + *x = SnapshotStoreItem{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SnapshotStoreItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SnapshotStoreItem) ProtoMessage() {} + +// Deprecated: Use SnapshotStoreItem.ProtoReflect.Descriptor instead. +func (*SnapshotStoreItem) Descriptor() ([]byte, []int) { + return file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDescGZIP(), []int{3} +} + +func (x *SnapshotStoreItem) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// SnapshotIAVLItem is an exported IAVL node. +type SnapshotIAVLItem struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Version int64 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"` + Height int32 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"` +} + +func (x *SnapshotIAVLItem) Reset() { + *x = SnapshotIAVLItem{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SnapshotIAVLItem) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SnapshotIAVLItem) ProtoMessage() {} + +// Deprecated: Use SnapshotIAVLItem.ProtoReflect.Descriptor instead. +func (*SnapshotIAVLItem) Descriptor() ([]byte, []int) { + return file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDescGZIP(), []int{4} +} + +func (x *SnapshotIAVLItem) GetKey() []byte { + if x != nil { + return x.Key + } + return nil +} + +func (x *SnapshotIAVLItem) GetValue() []byte { + if x != nil { + return x.Value + } + return nil +} + +func (x *SnapshotIAVLItem) GetVersion() int64 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *SnapshotIAVLItem) GetHeight() int32 { + if x != nil { + return x.Height + } + return 0 +} + +// SnapshotExtensionMeta contains metadata about an external snapshotter. +type SnapshotExtensionMeta struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Format uint32 `protobuf:"varint,2,opt,name=format,proto3" json:"format,omitempty"` +} + +func (x *SnapshotExtensionMeta) Reset() { + *x = SnapshotExtensionMeta{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SnapshotExtensionMeta) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SnapshotExtensionMeta) ProtoMessage() {} + +// Deprecated: Use SnapshotExtensionMeta.ProtoReflect.Descriptor instead. +func (*SnapshotExtensionMeta) Descriptor() ([]byte, []int) { + return file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDescGZIP(), []int{5} +} + +func (x *SnapshotExtensionMeta) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *SnapshotExtensionMeta) GetFormat() uint32 { + if x != nil { + return x.Format + } + return 0 +} + +// SnapshotExtensionPayload contains payloads of an external snapshotter. +type SnapshotExtensionPayload struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *SnapshotExtensionPayload) Reset() { + *x = SnapshotExtensionPayload{} + if protoimpl.UnsafeEnabled { + mi := &file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SnapshotExtensionPayload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SnapshotExtensionPayload) ProtoMessage() {} + +// Deprecated: Use SnapshotExtensionPayload.ProtoReflect.Descriptor instead. +func (*SnapshotExtensionPayload) Descriptor() ([]byte, []int) { + return file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDescGZIP(), []int{6} +} + +func (x *SnapshotExtensionPayload) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + var File_cosmos_base_snapshots_v1beta1_snapshot_proto protoreflect.FileDescriptor var file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDesc = []byte{ @@ -1278,25 +4233,65 @@ var file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDesc = []byte{ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x2d, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x68, 0x75, 0x6e, 0x6b, - 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x42, 0x9a, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x73, 0x6e, 0x61, 0x70, 0x73, - 0x68, 0x6f, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x0d, 0x53, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4f, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x6e, 0x61, 0x70, - 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x73, 0x6e, - 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, - 0x03, 0x43, 0x42, 0x53, 0xaa, 0x02, 0x1d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x42, 0x61, - 0x73, 0x65, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2e, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x42, 0x61, - 0x73, 0x65, 0x5c, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x5c, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x42, 0x61, - 0x73, 0x65, 0x5c, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x5c, 0x56, 0x31, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x20, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x42, 0x61, 0x73, 0x65, 0x3a, - 0x3a, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0xef, 0x02, 0x0a, 0x0c, 0x53, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x48, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x62, 0x61, 0x73, 0x65, 0x2e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x12, 0x4f, 0x0a, 0x04, 0x69, 0x61, 0x76, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x73, 0x6e, + 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, + 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x41, 0x56, 0x4c, 0x49, 0x74, 0x65, 0x6d, + 0x42, 0x08, 0xe2, 0xde, 0x1f, 0x04, 0x49, 0x41, 0x56, 0x4c, 0x48, 0x00, 0x52, 0x04, 0x69, 0x61, + 0x76, 0x6c, 0x12, 0x54, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, + 0x61, 0x73, 0x65, 0x2e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x48, 0x00, 0x52, 0x09, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x66, 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x2e, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x48, 0x00, 0x52, 0x10, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x42, 0x06, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x22, 0x27, 0x0a, 0x11, 0x53, 0x6e, 0x61, 0x70, + 0x73, 0x68, 0x6f, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x6c, 0x0a, 0x10, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x41, 0x56, + 0x4c, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, + 0x43, 0x0a, 0x15, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x22, 0x34, 0x0a, 0x18, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42, 0x9a, 0x02, 0x0a, 0x21, 0x63, + 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x73, + 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x42, 0x0d, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x4f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, + 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x62, 0x61, 0x73, 0x65, 0x2f, + 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x3b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x42, 0x53, 0xaa, 0x02, 0x1d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x2e, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, + 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x43, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x5c, 0x42, 0x61, 0x73, 0x65, 0x5c, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, + 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x43, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x5c, 0x42, 0x61, 0x73, 0x65, 0x5c, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, + 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x42, + 0x61, 0x73, 0x65, 0x3a, 0x3a, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1311,18 +4306,27 @@ func file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDescGZIP() []byte { return file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDescData } -var file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_cosmos_base_snapshots_v1beta1_snapshot_proto_goTypes = []interface{}{ - (*Snapshot)(nil), // 0: cosmos.base.snapshots.v1beta1.Snapshot - (*Metadata)(nil), // 1: cosmos.base.snapshots.v1beta1.Metadata + (*Snapshot)(nil), // 0: cosmos.base.snapshots.v1beta1.Snapshot + (*Metadata)(nil), // 1: cosmos.base.snapshots.v1beta1.Metadata + (*SnapshotItem)(nil), // 2: cosmos.base.snapshots.v1beta1.SnapshotItem + (*SnapshotStoreItem)(nil), // 3: cosmos.base.snapshots.v1beta1.SnapshotStoreItem + (*SnapshotIAVLItem)(nil), // 4: cosmos.base.snapshots.v1beta1.SnapshotIAVLItem + (*SnapshotExtensionMeta)(nil), // 5: cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta + (*SnapshotExtensionPayload)(nil), // 6: cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload } var file_cosmos_base_snapshots_v1beta1_snapshot_proto_depIdxs = []int32{ 1, // 0: cosmos.base.snapshots.v1beta1.Snapshot.metadata:type_name -> cosmos.base.snapshots.v1beta1.Metadata - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 3, // 1: cosmos.base.snapshots.v1beta1.SnapshotItem.store:type_name -> cosmos.base.snapshots.v1beta1.SnapshotStoreItem + 4, // 2: cosmos.base.snapshots.v1beta1.SnapshotItem.iavl:type_name -> cosmos.base.snapshots.v1beta1.SnapshotIAVLItem + 5, // 3: cosmos.base.snapshots.v1beta1.SnapshotItem.extension:type_name -> cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta + 6, // 4: cosmos.base.snapshots.v1beta1.SnapshotItem.extension_payload:type_name -> cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload + 5, // [5:5] is the sub-list for method output_type + 5, // [5:5] 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 } func init() { file_cosmos_base_snapshots_v1beta1_snapshot_proto_init() } @@ -1355,6 +4359,72 @@ func file_cosmos_base_snapshots_v1beta1_snapshot_proto_init() { return nil } } + file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SnapshotItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SnapshotStoreItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SnapshotIAVLItem); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SnapshotExtensionMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SnapshotExtensionPayload); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_cosmos_base_snapshots_v1beta1_snapshot_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*SnapshotItem_Store)(nil), + (*SnapshotItem_Iavl)(nil), + (*SnapshotItem_Extension)(nil), + (*SnapshotItem_ExtensionPayload)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1362,7 +4432,7 @@ func file_cosmos_base_snapshots_v1beta1_snapshot_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cosmos_base_snapshots_v1beta1_snapshot_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 7, NumExtensions: 0, NumServices: 0, }, diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 20f90bb7360a..ba8bac9f3dc6 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -260,6 +260,18 @@ func DefaultStoreLoader(ms sdk.CommitMultiStore) error { return ms.LoadLatestVersion() } +// CommitMultiStore returns the root multi-store. +// Extension snapshotter use this to read storage. +func (app *BaseApp) CommitMultiStore() sdk.CommitMultiStore { + return app.cms +} + +// SnapshotManager returns the snapshot manager. +// application use this to register extra extension snapshotters. +func (app *BaseApp) SnapshotManager() *snapshots.Manager { + return app.snapshotManager +} + // LoadVersion loads the BaseApp application version. It will panic if called // more than once on a running baseapp. func (app *BaseApp) LoadVersion(version int64) error { diff --git a/baseapp/options.go b/baseapp/options.go index 1d92698d7fa9..4b24c108da06 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -210,7 +210,7 @@ func (app *BaseApp) SetSnapshotStore(snapshotStore *snapshots.Store) { app.snapshotManager = nil return } - app.snapshotManager = snapshots.NewManager(snapshotStore, app.cms) + app.snapshotManager = snapshots.NewManager(snapshotStore, app.cms, nil) } // SetSnapshotInterval sets the snapshot interval. diff --git a/proto/cosmos/base/snapshots/v1beta1/snapshot.proto b/proto/cosmos/base/snapshots/v1beta1/snapshot.proto index 9ac5a7c31be4..b43842d5eb74 100644 --- a/proto/cosmos/base/snapshots/v1beta1/snapshot.proto +++ b/proto/cosmos/base/snapshots/v1beta1/snapshot.proto @@ -17,4 +17,39 @@ message Snapshot { // Metadata contains SDK-specific snapshot metadata. message Metadata { repeated bytes chunk_hashes = 1; // SHA-256 chunk hashes -} \ No newline at end of file +} + +// SnapshotItem is an item contained in a rootmulti.Store snapshot. +message SnapshotItem { + // item is the specific type of snapshot item. + oneof item { + SnapshotStoreItem store = 1; + SnapshotIAVLItem iavl = 2 [(gogoproto.customname) = "IAVL"]; + SnapshotExtensionMeta extension = 3; + SnapshotExtensionPayload extension_payload = 4; + } +} + +// SnapshotStoreItem contains metadata about a snapshotted store. +message SnapshotStoreItem { + string name = 1; +} + +// SnapshotIAVLItem is an exported IAVL node. +message SnapshotIAVLItem { + bytes key = 1; + bytes value = 2; + int64 version = 3; + int32 height = 4; +} + +// SnapshotExtensionMeta contains metadata about an external snapshotter. +message SnapshotExtensionMeta { + string name = 1; + uint32 format = 2; +} + +// SnapshotExtensionPayload contains payloads of an external snapshotter. +message SnapshotExtensionPayload { + bytes payload = 1; +} diff --git a/proto/cosmos/base/store/v1beta1/snapshot.proto b/proto/cosmos/base/store/v1beta1/snapshot.proto deleted file mode 100644 index 834855093b24..000000000000 --- a/proto/cosmos/base/store/v1beta1/snapshot.proto +++ /dev/null @@ -1,28 +0,0 @@ -syntax = "proto3"; -package cosmos.base.store.v1beta1; - -import "gogoproto/gogo.proto"; - -option go_package = "github.com/cosmos/cosmos-sdk/store/types"; - -// SnapshotItem is an item contained in a rootmulti.Store snapshot. -message SnapshotItem { - // item is the specific type of snapshot item. - oneof item { - SnapshotStoreItem store = 1; - SnapshotIAVLItem iavl = 2 [(gogoproto.customname) = "IAVL"]; - } -} - -// SnapshotStoreItem contains metadata about a snapshotted store. -message SnapshotStoreItem { - string name = 1; -} - -// SnapshotIAVLItem is an exported IAVL node. -message SnapshotIAVLItem { - bytes key = 1; - bytes value = 2; - int64 version = 3; - int32 height = 4; -} \ No newline at end of file diff --git a/server/mock/store.go b/server/mock/store.go index cf67e088fe77..37852de711eb 100644 --- a/server/mock/store.go +++ b/server/mock/store.go @@ -3,8 +3,10 @@ package mock import ( "io" + protoio "github.com/gogo/protobuf/io" dbm "github.com/tendermint/tm-db" + snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -122,13 +124,13 @@ func (ms multiStore) SetInitialVersion(version int64) error { panic("not implemented") } -func (ms multiStore) Snapshot(height uint64, format uint32) (<-chan io.ReadCloser, error) { +func (ms multiStore) Snapshot(height uint64, protoWriter protoio.Writer) error { panic("not implemented") } func (ms multiStore) Restore( - height uint64, format uint32, chunks <-chan io.ReadCloser, ready chan<- struct{}, -) error { + height uint64, format uint32, protoReader protoio.Reader, +) (snapshottypes.SnapshotItem, error) { panic("not implemented") } diff --git a/snapshots/util.go b/snapshots/chunk.go similarity index 100% rename from snapshots/util.go rename to snapshots/chunk.go diff --git a/snapshots/util_test.go b/snapshots/chunk_test.go similarity index 100% rename from snapshots/util_test.go rename to snapshots/chunk_test.go diff --git a/snapshots/helpers_test.go b/snapshots/helpers_test.go index f530eadf21b8..cc3b814d62ac 100644 --- a/snapshots/helpers_test.go +++ b/snapshots/helpers_test.go @@ -1,7 +1,9 @@ package snapshots_test import ( + "bufio" "bytes" + "compress/zlib" "crypto/sha256" "errors" "io" @@ -9,11 +11,14 @@ import ( "testing" "time" + protoio "github.com/gogo/protobuf/io" "github.com/stretchr/testify/require" db "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/snapshots" "github.com/cosmos/cosmos-sdk/snapshots/types" + snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func checksums(slice [][]byte) [][]byte { @@ -56,45 +61,85 @@ func readChunks(chunks <-chan io.ReadCloser) [][]byte { return bodies } +// snapshotItems serialize a array of bytes as SnapshotItem_ExtensionPayload, and return the chunks. +func snapshotItems(items [][]byte) [][]byte { + // copy the same parameters from the code + snapshotChunkSize := uint64(10e6) + snapshotBufferSize := int(snapshotChunkSize) + + ch := make(chan io.ReadCloser) + go func() { + chunkWriter := snapshots.NewChunkWriter(ch, snapshotChunkSize) + bufWriter := bufio.NewWriterSize(chunkWriter, snapshotBufferSize) + zWriter, _ := zlib.NewWriterLevel(bufWriter, 7) + protoWriter := protoio.NewDelimitedWriter(zWriter) + for _, item := range items { + types.WriteExtensionItem(protoWriter, item) + } + protoWriter.Close() + zWriter.Close() + bufWriter.Flush() + chunkWriter.Close() + }() + + var chunks [][]byte + for chunkBody := range ch { + chunk, err := io.ReadAll(chunkBody) + if err != nil { + panic(err) + } + chunks = append(chunks, chunk) + } + return chunks +} + type mockSnapshotter struct { - chunks [][]byte + items [][]byte } func (m *mockSnapshotter) Restore( - height uint64, format uint32, chunks <-chan io.ReadCloser, ready chan<- struct{}, -) error { + height uint64, format uint32, protoReader protoio.Reader, +) (snapshottypes.SnapshotItem, error) { if format == 0 { - return types.ErrUnknownFormat + return snapshottypes.SnapshotItem{}, types.ErrUnknownFormat } - if m.chunks != nil { - return errors.New("already has contents") + if m.items != nil { + return snapshottypes.SnapshotItem{}, errors.New("already has contents") } - if ready != nil { - close(ready) + + m.items = [][]byte{} + for { + item := &snapshottypes.SnapshotItem{} + err := protoReader.ReadMsg(item) + if err == io.EOF { + break + } else if err != nil { + return snapshottypes.SnapshotItem{}, sdkerrors.Wrap(err, "invalid protobuf message") + } + payload := item.GetExtensionPayload() + if payload == nil { + return snapshottypes.SnapshotItem{}, sdkerrors.Wrap(err, "invalid protobuf message") + } + m.items = append(m.items, payload.Payload) } - m.chunks = [][]byte{} - for reader := range chunks { - chunk, err := io.ReadAll(reader) - if err != nil { + return snapshottypes.SnapshotItem{}, nil +} + +func (m *mockSnapshotter) Snapshot(height uint64, protoWriter protoio.Writer) error { + for _, item := range m.items { + if err := types.WriteExtensionItem(protoWriter, item); err != nil { return err } - m.chunks = append(m.chunks, chunk) } - return nil } -func (m *mockSnapshotter) Snapshot(height uint64, format uint32) (<-chan io.ReadCloser, error) { - if format == 0 { - return nil, types.ErrUnknownFormat - } - ch := make(chan io.ReadCloser, len(m.chunks)) - for _, chunk := range m.chunks { - ch <- io.NopCloser(bytes.NewReader(chunk)) - } - close(ch) - return ch, nil +func (m *mockSnapshotter) SnapshotFormat() uint32 { + return 1 +} +func (m *mockSnapshotter) SupportedFormats() []uint32 { + return []uint32{1} } // setupBusyManager creates a manager with an empty store that is busy creating a snapshot at height 1. @@ -110,7 +155,7 @@ func setupBusyManager(t *testing.T) *snapshots.Manager { store, err := snapshots.NewStore(db.NewMemDB(), tempdir) require.NoError(t, err) hung := newHungSnapshotter() - mgr := snapshots.NewManager(store, hung) + mgr := snapshots.NewManager(store, hung, nil) go func() { _, err := mgr.Create(1) @@ -137,15 +182,13 @@ func (m *hungSnapshotter) Close() { close(m.ch) } -func (m *hungSnapshotter) Snapshot(height uint64, format uint32) (<-chan io.ReadCloser, error) { +func (m *hungSnapshotter) Snapshot(height uint64, protoWriter protoio.Writer) error { <-m.ch - ch := make(chan io.ReadCloser, 1) - ch <- io.NopCloser(bytes.NewReader([]byte{})) - return ch, nil + return nil } func (m *hungSnapshotter) Restore( - height uint64, format uint32, chunks <-chan io.ReadCloser, ready chan<- struct{}, -) error { + height uint64, format uint32, protoReader protoio.Reader, +) (snapshottypes.SnapshotItem, error) { panic("not implemented") } diff --git a/snapshots/manager.go b/snapshots/manager.go index f1106505bc56..5e8a85495b4d 100644 --- a/snapshots/manager.go +++ b/snapshots/manager.go @@ -3,7 +3,10 @@ package snapshots import ( "bytes" "crypto/sha256" + "fmt" "io" + "math" + "sort" "sync" "github.com/cosmos/cosmos-sdk/snapshots/types" @@ -17,6 +20,8 @@ const ( opRestore operation = "restore" chunkBufferSize = 4 + + snapshotMaxItemSize = int(64e6) // SDK has no key/value size limit, so we set an arbitrary limit ) // operation represents a Manager operation. Only one operation can be in progress at a time. @@ -42,8 +47,9 @@ type restoreDone struct { // 2) io.ReadCloser streams automatically propagate IO errors, and can pass arbitrary // errors via io.Pipe.CloseWithError(). type Manager struct { - store *Store - target types.Snapshotter + store *Store + multistore types.Snapshotter + extensions map[string]types.ExtensionSnapshotter mtx sync.Mutex operation operation @@ -54,11 +60,27 @@ type Manager struct { } // NewManager creates a new manager. -func NewManager(store *Store, target types.Snapshotter) *Manager { +func NewManager(store *Store, multistore types.Snapshotter, extensions map[string]types.ExtensionSnapshotter) *Manager { return &Manager{ - store: store, - target: target, + store: store, + multistore: multistore, + extensions: extensions, + } +} + +// RegisterExtensions register extension snapshotters to manager +func (m *Manager) RegisterExtensions(extensions ...types.ExtensionSnapshotter) error { + for _, extension := range extensions { + name := extension.SnapshotName() + if _, ok := m.extensions[name]; ok { + return fmt.Errorf("duplicated snapshotter name: %s", name) + } + if !IsFormatSupported(extension, extension.SnapshotFormat()) { + return fmt.Errorf("snapshotter don't support it's own snapshot format: %s %d", name, extension.SnapshotFormat()) + } + m.extensions[name] = extension } + return nil } // begin starts an operation, or errors if one is in progress. It manages the mutex itself. @@ -99,6 +121,17 @@ func (m *Manager) endLocked() { m.restoreChunkIndex = 0 } +// sortedExtensionNames sort extension names for deterministic iteration. +func (m *Manager) sortedExtensionNames() []string { + names := make([]string, 0, len(m.extensions)) + for name := range m.extensions { + names = append(names, name) + } + + sort.Strings(names) + return names +} + // Create creates a snapshot and returns its metadata. func (m *Manager) Create(height uint64) (*types.Snapshot, error) { if m == nil { @@ -119,11 +152,41 @@ func (m *Manager) Create(height uint64) (*types.Snapshot, error) { "a more recent snapshot already exists at height %v", latest.Height) } - chunks, err := m.target.Snapshot(height, types.CurrentFormat) - if err != nil { - return nil, err - } - return m.store.Save(height, types.CurrentFormat, chunks) + // Spawn goroutine to generate snapshot chunks and pass their io.ReadClosers through a channel + ch := make(chan io.ReadCloser) + go func() { + streamWriter := NewStreamWriter(ch) + if streamWriter == nil { + return + } + defer streamWriter.Close() + if err = m.multistore.Snapshot(height, streamWriter); err != nil { + streamWriter.CloseWithError(err) + return + } + for _, name := range m.sortedExtensionNames() { + extension := m.extensions[name] + // write extension metadata + err := streamWriter.WriteMsg(&types.SnapshotItem{ + Item: &types.SnapshotItem_Extension{ + Extension: &types.SnapshotExtensionMeta{ + Name: name, + Format: extension.SnapshotFormat(), + }, + }, + }) + if err != nil { + streamWriter.CloseWithError(err) + return + } + if err := extension.Snapshot(height, streamWriter); err != nil { + streamWriter.CloseWithError(err) + return + } + } + }() + + return m.store.Save(height, types.CurrentFormat, ch) } // List lists snapshots, mirroring ABCI ListSnapshots. It can be concurrent with other operations. @@ -178,8 +241,62 @@ func (m *Manager) Restore(snapshot types.Snapshot) error { chChunks := make(chan io.ReadCloser, chunkBufferSize) chReady := make(chan struct{}, 1) chDone := make(chan restoreDone, 1) + + doRestore := func() error { + // check multistore supported format preemptive + if snapshot.Format != types.CurrentFormat { + return sdkerrors.Wrapf(types.ErrUnknownFormat, "snapshot format %v", snapshot.Format) + } + if snapshot.Height == 0 { + return sdkerrors.Wrap(sdkerrors.ErrLogic, "cannot restore snapshot at height 0") + } + if snapshot.Height > uint64(math.MaxInt64) { + return sdkerrors.Wrapf(types.ErrInvalidMetadata, + "snapshot height %v cannot exceed %v", snapshot.Height, int64(math.MaxInt64)) + } + + // Signal readiness. Must be done before the readers below are set up, since the zlib + // reader reads from the stream on initialization, potentially causing deadlocks. + if chReady != nil { + close(chReady) + } + + streamReader, err := NewStreamReader(chChunks) + if err != nil { + return err + } + defer streamReader.Close() + + next, err := m.multistore.Restore(snapshot.Height, snapshot.Format, streamReader) + if err != nil { + return sdkerrors.Wrap(err, "multistore restore") + } + for { + if next.Item == nil { + // end of stream + break + } + metadata := next.GetExtension() + if metadata == nil { + return sdkerrors.Wrapf(sdkerrors.ErrLogic, "unknown snapshot item %T", next.Item) + } + extension, ok := m.extensions[metadata.Name] + if !ok { + return sdkerrors.Wrapf(sdkerrors.ErrLogic, "unknown extension snapshotter %s", metadata.Name) + } + if !IsFormatSupported(extension, metadata.Format) { + return sdkerrors.Wrapf(types.ErrUnknownFormat, "format %v for extension %s", metadata.Format, metadata.Name) + } + next, err = extension.Restore(snapshot.Height, metadata.Format, streamReader) + if err != nil { + return sdkerrors.Wrapf(err, "extension %s restore", metadata.Name) + } + } + return nil + } + go func() { - err := m.target.Restore(snapshot.Height, snapshot.Format, chChunks, chReady) + err := doRestore() chDone <- restoreDone{ complete: err == nil, err: err, @@ -256,3 +373,13 @@ func (m *Manager) RestoreChunk(chunk []byte) (bool, error) { } return false, nil } + +// IsFormatSupported returns if the snapshotter supports restoration from given format. +func IsFormatSupported(snapshotter types.ExtensionSnapshotter, format uint32) bool { + for _, i := range snapshotter.SupportedFormats() { + if i == format { + return true + } + } + return false +} diff --git a/snapshots/manager_test.go b/snapshots/manager_test.go index 6069666f14f5..f7a8bd6ded11 100644 --- a/snapshots/manager_test.go +++ b/snapshots/manager_test.go @@ -13,7 +13,7 @@ import ( func TestManager_List(t *testing.T) { store := setupStore(t) - manager := snapshots.NewManager(store, nil) + manager := snapshots.NewManager(store, nil, nil) mgrList, err := manager.List() require.NoError(t, err) @@ -32,7 +32,7 @@ func TestManager_List(t *testing.T) { func TestManager_LoadChunk(t *testing.T) { store := setupStore(t) - manager := snapshots.NewManager(store, nil) + manager := snapshots.NewManager(store, nil, nil) // Existing chunk should return body chunk, err := manager.LoadChunk(2, 1, 1) @@ -53,14 +53,16 @@ func TestManager_LoadChunk(t *testing.T) { func TestManager_Take(t *testing.T) { store := setupStore(t) + items := [][]byte{ + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9}, + } snapshotter := &mockSnapshotter{ - chunks: [][]byte{ - {1, 2, 3}, - {4, 5, 6}, - {7, 8, 9}, - }, + items: items, } - manager := snapshots.NewManager(store, snapshotter) + expectChunks := snapshotItems(items) + manager := snapshots.NewManager(store, snapshotter, nil) // nil manager should return error _, err := (*snapshots.Manager)(nil).Create(1) @@ -75,19 +77,18 @@ func TestManager_Take(t *testing.T) { require.NoError(t, err) assert.Equal(t, &types.Snapshot{ Height: 5, - Format: types.CurrentFormat, - Chunks: 3, - Hash: []uint8{0x47, 0xe4, 0xee, 0x7f, 0x21, 0x1f, 0x73, 0x26, 0x5d, 0xd1, 0x76, 0x58, 0xf6, 0xe2, 0x1c, 0x13, 0x18, 0xbd, 0x6c, 0x81, 0xf3, 0x75, 0x98, 0xe2, 0xa, 0x27, 0x56, 0x29, 0x95, 0x42, 0xef, 0xcf}, + Format: snapshotter.SnapshotFormat(), + Chunks: 1, + Hash: []uint8{0xcd, 0x17, 0x9e, 0x7f, 0x28, 0xb6, 0x82, 0x90, 0xc7, 0x25, 0xf3, 0x42, 0xac, 0x65, 0x73, 0x50, 0xaa, 0xa0, 0x10, 0x5c, 0x40, 0x8c, 0xd5, 0x1, 0xed, 0x82, 0xb5, 0xca, 0x8b, 0xe0, 0x83, 0xa2}, Metadata: types.Metadata{ - ChunkHashes: checksums([][]byte{ - {1, 2, 3}, {4, 5, 6}, {7, 8, 9}}), + ChunkHashes: checksums(expectChunks), }, }, snapshot) storeSnapshot, chunks, err := store.Load(snapshot.Height, snapshot.Format) require.NoError(t, err) assert.Equal(t, snapshot, storeSnapshot) - assert.Equal(t, [][]byte{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, readChunks(chunks)) + assert.Equal(t, expectChunks, readChunks(chunks)) // creating a snapshot while a different snapshot is being created should error manager = setupBusyManager(t) @@ -97,7 +98,7 @@ func TestManager_Take(t *testing.T) { func TestManager_Prune(t *testing.T) { store := setupStore(t) - manager := snapshots.NewManager(store, nil) + manager := snapshots.NewManager(store, nil, nil) pruned, err := manager.Prune(2) require.NoError(t, err) @@ -116,14 +117,16 @@ func TestManager_Prune(t *testing.T) { func TestManager_Restore(t *testing.T) { store := setupStore(t) target := &mockSnapshotter{} - manager := snapshots.NewManager(store, target) + manager := snapshots.NewManager(store, target, nil) - chunks := [][]byte{ + expectItems := [][]byte{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, } + chunks := snapshotItems(expectItems) + // Restore errors on invalid format err := manager.Restore(types.Snapshot{ Height: 3, @@ -133,7 +136,7 @@ func TestManager_Restore(t *testing.T) { Metadata: types.Metadata{ChunkHashes: checksums(chunks)}, }) require.Error(t, err) - require.Equal(t, types.ErrUnknownFormat, err) + require.ErrorIs(t, err, types.ErrUnknownFormat) // Restore errors on no chunks err = manager.Restore(types.Snapshot{Height: 3, Format: 1, Hash: []byte{1, 2, 3}}) @@ -154,7 +157,7 @@ func TestManager_Restore(t *testing.T) { Height: 3, Format: 1, Hash: []byte{1, 2, 3}, - Chunks: 3, + Chunks: 1, Metadata: types.Metadata{ChunkHashes: checksums(chunks)}, }) require.NoError(t, err) @@ -182,7 +185,7 @@ func TestManager_Restore(t *testing.T) { } } - assert.Equal(t, chunks, target.chunks) + assert.Equal(t, expectItems, target.items) // Starting a new restore should fail now, because the target already has contents. err = manager.Restore(types.Snapshot{ @@ -197,12 +200,12 @@ func TestManager_Restore(t *testing.T) { // But if we clear out the target we should be able to start a new restore. This time we'll // fail it with a checksum error. That error should stop the operation, so that we can do // a prune operation right after. - target.chunks = nil + target.items = nil err = manager.Restore(types.Snapshot{ Height: 3, Format: 1, Hash: []byte{1, 2, 3}, - Chunks: 3, + Chunks: 1, Metadata: types.Metadata{ChunkHashes: checksums(chunks)}, }) require.NoError(t, err) diff --git a/snapshots/stream.go b/snapshots/stream.go new file mode 100644 index 000000000000..68f7be0ad50d --- /dev/null +++ b/snapshots/stream.go @@ -0,0 +1,107 @@ +package snapshots + +import ( + "bufio" + "compress/zlib" + "io" + + protoio "github.com/gogo/protobuf/io" + "github.com/gogo/protobuf/proto" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const ( + // Do not change chunk size without new snapshot format (must be uniform across nodes) + snapshotChunkSize = uint64(10e6) + snapshotBufferSize = int(snapshotChunkSize) +) + +// StreamWriter set up a stream pipeline to serialize snapshot nodes: +// ExportNode -> delimited Protobuf -> zlib -> buffer -> chunkWriter -> chan io.ReadCloser +type StreamWriter struct { + chunkWriter *ChunkWriter + bufWriter *bufio.Writer + zWriter *zlib.Writer + protoWriter protoio.WriteCloser +} + +// NewStreamWriter set up a stream pipeline to serialize snapshot nodes. +func NewStreamWriter(ch chan<- io.ReadCloser) *StreamWriter { + chunkWriter := NewChunkWriter(ch, snapshotChunkSize) + bufWriter := bufio.NewWriterSize(chunkWriter, snapshotBufferSize) + zWriter, err := zlib.NewWriterLevel(bufWriter, 7) + if err != nil { + chunkWriter.CloseWithError(sdkerrors.Wrap(err, "zlib failure")) + return nil + } + protoWriter := protoio.NewDelimitedWriter(zWriter) + return &StreamWriter{ + chunkWriter: chunkWriter, + bufWriter: bufWriter, + zWriter: zWriter, + protoWriter: protoWriter, + } +} + +// WriteMsg implements protoio.Write interface +func (sw *StreamWriter) WriteMsg(msg proto.Message) error { + return sw.protoWriter.WriteMsg(msg) +} + +// Close implements io.Closer interface +func (sw *StreamWriter) Close() error { + if err := sw.protoWriter.Close(); err != nil { + sw.chunkWriter.CloseWithError(err) + return err + } + if err := sw.zWriter.Close(); err != nil { + sw.chunkWriter.CloseWithError(err) + return err + } + if err := sw.bufWriter.Flush(); err != nil { + sw.chunkWriter.CloseWithError(err) + return err + } + return sw.chunkWriter.Close() +} + +// CloseWithError pass error to chunkWriter +func (sw *StreamWriter) CloseWithError(err error) { + sw.chunkWriter.CloseWithError(err) +} + +// StreamReader set up a restore stream pipeline +// chan io.ReadCloser -> chunkReader -> zlib -> delimited Protobuf -> ExportNode +type StreamReader struct { + chunkReader *ChunkReader + zReader io.ReadCloser + protoReader protoio.ReadCloser +} + +// NewStreamReader set up a restore stream pipeline. +func NewStreamReader(chunks <-chan io.ReadCloser) (*StreamReader, error) { + chunkReader := NewChunkReader(chunks) + zReader, err := zlib.NewReader(chunkReader) + if err != nil { + return nil, sdkerrors.Wrap(err, "zlib failure") + } + protoReader := protoio.NewDelimitedReader(zReader, snapshotMaxItemSize) + return &StreamReader{ + chunkReader: chunkReader, + zReader: zReader, + protoReader: protoReader, + }, nil +} + +// ReadMsg implements protoio.Reader interface +func (sr *StreamReader) ReadMsg(msg proto.Message) error { + return sr.protoReader.ReadMsg(msg) +} + +// Close implements io.Closer interface +func (sr *StreamReader) Close() error { + sr.protoReader.Close() + sr.zReader.Close() + return sr.chunkReader.Close() +} diff --git a/snapshots/types/snapshot.pb.go b/snapshots/types/snapshot.pb.go index f37192f9c569..5a70e5eb8d4d 100644 --- a/snapshots/types/snapshot.pb.go +++ b/snapshots/types/snapshot.pb.go @@ -145,9 +145,340 @@ func (m *Metadata) GetChunkHashes() [][]byte { return nil } +// SnapshotItem is an item contained in a rootmulti.Store snapshot. +type SnapshotItem struct { + // item is the specific type of snapshot item. + // + // Types that are valid to be assigned to Item: + // *SnapshotItem_Store + // *SnapshotItem_IAVL + // *SnapshotItem_Extension + // *SnapshotItem_ExtensionPayload + Item isSnapshotItem_Item `protobuf_oneof:"item"` +} + +func (m *SnapshotItem) Reset() { *m = SnapshotItem{} } +func (m *SnapshotItem) String() string { return proto.CompactTextString(m) } +func (*SnapshotItem) ProtoMessage() {} +func (*SnapshotItem) Descriptor() ([]byte, []int) { + return fileDescriptor_dd7a3c9b0a19e1ee, []int{2} +} +func (m *SnapshotItem) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SnapshotItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SnapshotItem.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 *SnapshotItem) XXX_Merge(src proto.Message) { + xxx_messageInfo_SnapshotItem.Merge(m, src) +} +func (m *SnapshotItem) XXX_Size() int { + return m.Size() +} +func (m *SnapshotItem) XXX_DiscardUnknown() { + xxx_messageInfo_SnapshotItem.DiscardUnknown(m) +} + +var xxx_messageInfo_SnapshotItem proto.InternalMessageInfo + +type isSnapshotItem_Item interface { + isSnapshotItem_Item() + MarshalTo([]byte) (int, error) + Size() int +} + +type SnapshotItem_Store struct { + Store *SnapshotStoreItem `protobuf:"bytes,1,opt,name=store,proto3,oneof" json:"store,omitempty"` +} +type SnapshotItem_IAVL struct { + IAVL *SnapshotIAVLItem `protobuf:"bytes,2,opt,name=iavl,proto3,oneof" json:"iavl,omitempty"` +} +type SnapshotItem_Extension struct { + Extension *SnapshotExtensionMeta `protobuf:"bytes,3,opt,name=extension,proto3,oneof" json:"extension,omitempty"` +} +type SnapshotItem_ExtensionPayload struct { + ExtensionPayload *SnapshotExtensionPayload `protobuf:"bytes,4,opt,name=extension_payload,json=extensionPayload,proto3,oneof" json:"extension_payload,omitempty"` +} + +func (*SnapshotItem_Store) isSnapshotItem_Item() {} +func (*SnapshotItem_IAVL) isSnapshotItem_Item() {} +func (*SnapshotItem_Extension) isSnapshotItem_Item() {} +func (*SnapshotItem_ExtensionPayload) isSnapshotItem_Item() {} + +func (m *SnapshotItem) GetItem() isSnapshotItem_Item { + if m != nil { + return m.Item + } + return nil +} + +func (m *SnapshotItem) GetStore() *SnapshotStoreItem { + if x, ok := m.GetItem().(*SnapshotItem_Store); ok { + return x.Store + } + return nil +} + +func (m *SnapshotItem) GetIAVL() *SnapshotIAVLItem { + if x, ok := m.GetItem().(*SnapshotItem_IAVL); ok { + return x.IAVL + } + return nil +} + +func (m *SnapshotItem) GetExtension() *SnapshotExtensionMeta { + if x, ok := m.GetItem().(*SnapshotItem_Extension); ok { + return x.Extension + } + return nil +} + +func (m *SnapshotItem) GetExtensionPayload() *SnapshotExtensionPayload { + if x, ok := m.GetItem().(*SnapshotItem_ExtensionPayload); ok { + return x.ExtensionPayload + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*SnapshotItem) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*SnapshotItem_Store)(nil), + (*SnapshotItem_IAVL)(nil), + (*SnapshotItem_Extension)(nil), + (*SnapshotItem_ExtensionPayload)(nil), + } +} + +// SnapshotStoreItem contains metadata about a snapshotted store. +type SnapshotStoreItem struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (m *SnapshotStoreItem) Reset() { *m = SnapshotStoreItem{} } +func (m *SnapshotStoreItem) String() string { return proto.CompactTextString(m) } +func (*SnapshotStoreItem) ProtoMessage() {} +func (*SnapshotStoreItem) Descriptor() ([]byte, []int) { + return fileDescriptor_dd7a3c9b0a19e1ee, []int{3} +} +func (m *SnapshotStoreItem) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SnapshotStoreItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SnapshotStoreItem.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 *SnapshotStoreItem) XXX_Merge(src proto.Message) { + xxx_messageInfo_SnapshotStoreItem.Merge(m, src) +} +func (m *SnapshotStoreItem) XXX_Size() int { + return m.Size() +} +func (m *SnapshotStoreItem) XXX_DiscardUnknown() { + xxx_messageInfo_SnapshotStoreItem.DiscardUnknown(m) +} + +var xxx_messageInfo_SnapshotStoreItem proto.InternalMessageInfo + +func (m *SnapshotStoreItem) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +// SnapshotIAVLItem is an exported IAVL node. +type SnapshotIAVLItem struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Version int64 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"` + Height int32 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"` +} + +func (m *SnapshotIAVLItem) Reset() { *m = SnapshotIAVLItem{} } +func (m *SnapshotIAVLItem) String() string { return proto.CompactTextString(m) } +func (*SnapshotIAVLItem) ProtoMessage() {} +func (*SnapshotIAVLItem) Descriptor() ([]byte, []int) { + return fileDescriptor_dd7a3c9b0a19e1ee, []int{4} +} +func (m *SnapshotIAVLItem) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SnapshotIAVLItem) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SnapshotIAVLItem.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 *SnapshotIAVLItem) XXX_Merge(src proto.Message) { + xxx_messageInfo_SnapshotIAVLItem.Merge(m, src) +} +func (m *SnapshotIAVLItem) XXX_Size() int { + return m.Size() +} +func (m *SnapshotIAVLItem) XXX_DiscardUnknown() { + xxx_messageInfo_SnapshotIAVLItem.DiscardUnknown(m) +} + +var xxx_messageInfo_SnapshotIAVLItem proto.InternalMessageInfo + +func (m *SnapshotIAVLItem) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func (m *SnapshotIAVLItem) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *SnapshotIAVLItem) GetVersion() int64 { + if m != nil { + return m.Version + } + return 0 +} + +func (m *SnapshotIAVLItem) GetHeight() int32 { + if m != nil { + return m.Height + } + return 0 +} + +// SnapshotExtensionMeta contains metadata about an external snapshotter. +type SnapshotExtensionMeta struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Format uint32 `protobuf:"varint,2,opt,name=format,proto3" json:"format,omitempty"` +} + +func (m *SnapshotExtensionMeta) Reset() { *m = SnapshotExtensionMeta{} } +func (m *SnapshotExtensionMeta) String() string { return proto.CompactTextString(m) } +func (*SnapshotExtensionMeta) ProtoMessage() {} +func (*SnapshotExtensionMeta) Descriptor() ([]byte, []int) { + return fileDescriptor_dd7a3c9b0a19e1ee, []int{5} +} +func (m *SnapshotExtensionMeta) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SnapshotExtensionMeta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SnapshotExtensionMeta.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 *SnapshotExtensionMeta) XXX_Merge(src proto.Message) { + xxx_messageInfo_SnapshotExtensionMeta.Merge(m, src) +} +func (m *SnapshotExtensionMeta) XXX_Size() int { + return m.Size() +} +func (m *SnapshotExtensionMeta) XXX_DiscardUnknown() { + xxx_messageInfo_SnapshotExtensionMeta.DiscardUnknown(m) +} + +var xxx_messageInfo_SnapshotExtensionMeta proto.InternalMessageInfo + +func (m *SnapshotExtensionMeta) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *SnapshotExtensionMeta) GetFormat() uint32 { + if m != nil { + return m.Format + } + return 0 +} + +// SnapshotExtensionPayload contains payloads of an external snapshotter. +type SnapshotExtensionPayload struct { + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (m *SnapshotExtensionPayload) Reset() { *m = SnapshotExtensionPayload{} } +func (m *SnapshotExtensionPayload) String() string { return proto.CompactTextString(m) } +func (*SnapshotExtensionPayload) ProtoMessage() {} +func (*SnapshotExtensionPayload) Descriptor() ([]byte, []int) { + return fileDescriptor_dd7a3c9b0a19e1ee, []int{6} +} +func (m *SnapshotExtensionPayload) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SnapshotExtensionPayload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SnapshotExtensionPayload.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 *SnapshotExtensionPayload) XXX_Merge(src proto.Message) { + xxx_messageInfo_SnapshotExtensionPayload.Merge(m, src) +} +func (m *SnapshotExtensionPayload) XXX_Size() int { + return m.Size() +} +func (m *SnapshotExtensionPayload) XXX_DiscardUnknown() { + xxx_messageInfo_SnapshotExtensionPayload.DiscardUnknown(m) +} + +var xxx_messageInfo_SnapshotExtensionPayload proto.InternalMessageInfo + +func (m *SnapshotExtensionPayload) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + func init() { proto.RegisterType((*Snapshot)(nil), "cosmos.base.snapshots.v1beta1.Snapshot") proto.RegisterType((*Metadata)(nil), "cosmos.base.snapshots.v1beta1.Metadata") + proto.RegisterType((*SnapshotItem)(nil), "cosmos.base.snapshots.v1beta1.SnapshotItem") + proto.RegisterType((*SnapshotStoreItem)(nil), "cosmos.base.snapshots.v1beta1.SnapshotStoreItem") + proto.RegisterType((*SnapshotIAVLItem)(nil), "cosmos.base.snapshots.v1beta1.SnapshotIAVLItem") + proto.RegisterType((*SnapshotExtensionMeta)(nil), "cosmos.base.snapshots.v1beta1.SnapshotExtensionMeta") + proto.RegisterType((*SnapshotExtensionPayload)(nil), "cosmos.base.snapshots.v1beta1.SnapshotExtensionPayload") } func init() { @@ -155,25 +486,40 @@ func init() { } var fileDescriptor_dd7a3c9b0a19e1ee = []byte{ - // 288 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0x31, 0x4e, 0xc3, 0x30, - 0x14, 0x86, 0x63, 0x1a, 0xaa, 0xc8, 0x0d, 0x8b, 0x85, 0x90, 0x85, 0x84, 0x09, 0x5d, 0xc8, 0xd0, - 0x3a, 0x2a, 0xdc, 0xa0, 0x03, 0x82, 0x81, 0x25, 0x6c, 0x2c, 0xc8, 0x49, 0x4d, 0x5c, 0x55, 0xa9, - 0xa3, 0x3e, 0x17, 0x89, 0x5b, 0x70, 0x15, 0x6e, 0xd1, 0xb1, 0x23, 0x13, 0x42, 0xc9, 0x45, 0x50, - 0x1c, 0x13, 0x31, 0x75, 0xca, 0xfb, 0xbf, 0x7c, 0x4f, 0xcf, 0xfa, 0xf1, 0x24, 0xd7, 0x50, 0x6a, - 0x48, 0x32, 0x01, 0x32, 0x81, 0xb5, 0xa8, 0x40, 0x69, 0x03, 0xc9, 0xdb, 0x2c, 0x93, 0x46, 0xcc, - 0x7a, 0xc2, 0xab, 0x8d, 0x36, 0x9a, 0x5c, 0x74, 0x36, 0x6f, 0x6d, 0xde, 0xdb, 0xdc, 0xd9, 0xe7, - 0xa7, 0x85, 0x2e, 0xb4, 0x35, 0x93, 0x76, 0xea, 0x96, 0xc6, 0x9f, 0x08, 0x07, 0x4f, 0xce, 0x25, - 0x67, 0x78, 0xa8, 0xe4, 0xb2, 0x50, 0x86, 0xa2, 0x08, 0xc5, 0x7e, 0xea, 0x52, 0xcb, 0x5f, 0xf5, - 0xa6, 0x14, 0x86, 0x1e, 0x45, 0x28, 0x3e, 0x49, 0x5d, 0x6a, 0x79, 0xae, 0xb6, 0xeb, 0x15, 0xd0, - 0x41, 0xc7, 0xbb, 0x44, 0x08, 0xf6, 0x95, 0x00, 0x45, 0xfd, 0x08, 0xc5, 0x61, 0x6a, 0x67, 0xf2, - 0x80, 0x83, 0x52, 0x1a, 0xb1, 0x10, 0x46, 0xd0, 0xe3, 0x08, 0xc5, 0xa3, 0x9b, 0x6b, 0x7e, 0xf0, - 0xc1, 0xfc, 0xd1, 0xe9, 0x73, 0x7f, 0xf7, 0x7d, 0xe9, 0xa5, 0xfd, 0xfa, 0x78, 0x8a, 0x83, 0xbf, - 0x7f, 0xe4, 0x0a, 0x87, 0xf6, 0xe8, 0x4b, 0x7b, 0x44, 0x02, 0x45, 0xd1, 0x20, 0x0e, 0xd3, 0x91, - 0x65, 0xf7, 0x16, 0xcd, 0xef, 0x76, 0x35, 0x43, 0xfb, 0x9a, 0xa1, 0x9f, 0x9a, 0xa1, 0x8f, 0x86, - 0x79, 0xfb, 0x86, 0x79, 0x5f, 0x0d, 0xf3, 0x9e, 0x27, 0xc5, 0xd2, 0xa8, 0x6d, 0xc6, 0x73, 0x5d, - 0x26, 0xae, 0xea, 0xee, 0x33, 0x85, 0xc5, 0xea, 0x5f, 0xe1, 0xe6, 0xbd, 0x92, 0x90, 0x0d, 0x6d, - 0x63, 0xb7, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb8, 0x89, 0x2e, 0x8f, 0x96, 0x01, 0x00, 0x00, + // 513 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0xd1, 0x6e, 0xd3, 0x30, + 0x14, 0x8d, 0xd7, 0xb4, 0x74, 0x37, 0x41, 0xea, 0xac, 0x81, 0x22, 0x24, 0xb2, 0x92, 0x97, 0xf5, + 0x61, 0x4b, 0x58, 0x99, 0xc4, 0x33, 0x45, 0xa0, 0x54, 0x02, 0x81, 0x3c, 0xc4, 0x03, 0x2f, 0x93, + 0xdb, 0x7a, 0x4d, 0xd4, 0x26, 0xae, 0x6a, 0xb7, 0xa2, 0x7f, 0xc1, 0xaf, 0xf0, 0x17, 0x7b, 0xdc, + 0x23, 0x4f, 0x13, 0x6a, 0x3f, 0x80, 0x5f, 0x40, 0xb6, 0x93, 0x30, 0x8d, 0x0d, 0xb6, 0xa7, 0xde, + 0x73, 0x7a, 0xee, 0xf1, 0xf5, 0xc9, 0x35, 0x1c, 0x0c, 0xb9, 0xc8, 0xb8, 0x88, 0x06, 0x54, 0xb0, + 0x48, 0xe4, 0x74, 0x26, 0x12, 0x2e, 0x45, 0xb4, 0x3c, 0x1a, 0x30, 0x49, 0x8f, 0x2a, 0x26, 0x9c, + 0xcd, 0xb9, 0xe4, 0xf8, 0xa9, 0x51, 0x87, 0x4a, 0x1d, 0x56, 0xea, 0xb0, 0x50, 0x3f, 0xd9, 0x1d, + 0xf3, 0x31, 0xd7, 0xca, 0x48, 0x55, 0xa6, 0x29, 0xf8, 0x8e, 0xa0, 0x79, 0x52, 0x68, 0xf1, 0x63, + 0x68, 0x24, 0x2c, 0x1d, 0x27, 0xd2, 0x43, 0x6d, 0xd4, 0xb1, 0x49, 0x81, 0x14, 0x7f, 0xc6, 0xe7, + 0x19, 0x95, 0xde, 0x56, 0x1b, 0x75, 0x1e, 0x92, 0x02, 0x29, 0x7e, 0x98, 0x2c, 0xf2, 0x89, 0xf0, + 0x6a, 0x86, 0x37, 0x08, 0x63, 0xb0, 0x13, 0x2a, 0x12, 0xcf, 0x6e, 0xa3, 0x8e, 0x4b, 0x74, 0x8d, + 0xfb, 0xd0, 0xcc, 0x98, 0xa4, 0x23, 0x2a, 0xa9, 0x57, 0x6f, 0xa3, 0x8e, 0xd3, 0xdd, 0x0f, 0xff, + 0x39, 0x70, 0xf8, 0xbe, 0x90, 0xf7, 0xec, 0xf3, 0xcb, 0x3d, 0x8b, 0x54, 0xed, 0xc1, 0x21, 0x34, + 0xcb, 0xff, 0xf0, 0x33, 0x70, 0xf5, 0xa1, 0xa7, 0xea, 0x10, 0x26, 0x3c, 0xd4, 0xae, 0x75, 0x5c, + 0xe2, 0x68, 0x2e, 0xd6, 0x54, 0xf0, 0x6b, 0x0b, 0xdc, 0xf2, 0x8a, 0x7d, 0xc9, 0x32, 0x1c, 0x43, + 0x5d, 0x48, 0x3e, 0x67, 0xfa, 0x96, 0x4e, 0xf7, 0xf9, 0x7f, 0xe6, 0x28, 0x7b, 0x4f, 0x54, 0x8f, + 0x32, 0x88, 0x2d, 0x62, 0x0c, 0xf0, 0x07, 0xb0, 0x53, 0xba, 0x9c, 0xea, 0x58, 0x9c, 0x6e, 0x74, + 0x47, 0xa3, 0xfe, 0xab, 0xcf, 0xef, 0x94, 0x4f, 0xaf, 0xb9, 0xbe, 0xdc, 0xb3, 0x15, 0x8a, 0x2d, + 0xa2, 0x8d, 0xf0, 0x27, 0xd8, 0x66, 0x5f, 0x25, 0xcb, 0x45, 0xca, 0x73, 0x1d, 0xaa, 0xd3, 0x3d, + 0xbe, 0xa3, 0xeb, 0x9b, 0xb2, 0x4f, 0x65, 0x13, 0x5b, 0xe4, 0x8f, 0x11, 0x3e, 0x83, 0x9d, 0x0a, + 0x9c, 0xce, 0xe8, 0x6a, 0xca, 0xe9, 0x48, 0x7f, 0x1c, 0xa7, 0xfb, 0xf2, 0xbe, 0xee, 0x1f, 0x4d, + 0x7b, 0x6c, 0x91, 0x16, 0xbb, 0xc6, 0xf5, 0x1a, 0x60, 0xa7, 0x92, 0x65, 0xc1, 0x3e, 0xec, 0xfc, + 0x15, 0x9a, 0x5a, 0x8a, 0x9c, 0x66, 0x26, 0xf4, 0x6d, 0xa2, 0xeb, 0x60, 0x0a, 0xad, 0xeb, 0xa1, + 0xe0, 0x16, 0xd4, 0x26, 0x6c, 0xa5, 0x65, 0x2e, 0x51, 0x25, 0xde, 0x85, 0xfa, 0x92, 0x4e, 0x17, + 0x4c, 0xc7, 0xec, 0x12, 0x03, 0xb0, 0x07, 0x0f, 0x96, 0x6c, 0x5e, 0x05, 0x55, 0x23, 0x25, 0xbc, + 0xb2, 0xc6, 0xea, 0x8e, 0xf5, 0x72, 0x8d, 0x83, 0xd7, 0xf0, 0xe8, 0xc6, 0xb0, 0x6e, 0x1a, 0xed, + 0xb6, 0x9d, 0x0f, 0x8e, 0xc1, 0xbb, 0x2d, 0x13, 0x35, 0x52, 0x99, 0xae, 0x19, 0xbf, 0x84, 0xbd, + 0xb7, 0xe7, 0x6b, 0x1f, 0x5d, 0xac, 0x7d, 0xf4, 0x73, 0xed, 0xa3, 0x6f, 0x1b, 0xdf, 0xba, 0xd8, + 0xf8, 0xd6, 0x8f, 0x8d, 0x6f, 0x7d, 0x39, 0x18, 0xa7, 0x32, 0x59, 0x0c, 0xc2, 0x21, 0xcf, 0xa2, + 0xe2, 0xb9, 0x9b, 0x9f, 0x43, 0x31, 0x9a, 0x5c, 0x79, 0xf4, 0x72, 0x35, 0x63, 0x62, 0xd0, 0xd0, + 0xaf, 0xf6, 0xc5, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x6c, 0x90, 0xf8, 0x1f, 0x1a, 0x04, 0x00, + 0x00, } func (m *Snapshot) Marshal() (dAtA []byte, err error) { @@ -263,63 +609,974 @@ func (m *Metadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarintSnapshot(dAtA []byte, offset int, v uint64) int { - offset -= sovSnapshot(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *SnapshotItem) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *Snapshot) Size() (n int) { - if m == nil { - return 0 - } + +func (m *SnapshotItem) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotItem) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.Height != 0 { - n += 1 + sovSnapshot(uint64(m.Height)) + if m.Item != nil { + { + size := m.Item.Size() + i -= size + if _, err := m.Item.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } } - if m.Format != 0 { - n += 1 + sovSnapshot(uint64(m.Format)) + return len(dAtA) - i, nil +} + +func (m *SnapshotItem_Store) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotItem_Store) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Store != nil { + { + size, err := m.Store.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSnapshot(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa } - if m.Chunks != 0 { - n += 1 + sovSnapshot(uint64(m.Chunks)) + return len(dAtA) - i, nil +} +func (m *SnapshotItem_IAVL) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotItem_IAVL) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.IAVL != nil { + { + size, err := m.IAVL.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSnapshot(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 } - l = len(m.Hash) - if l > 0 { - n += 1 + l + sovSnapshot(uint64(l)) + return len(dAtA) - i, nil +} +func (m *SnapshotItem_Extension) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotItem_Extension) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Extension != nil { + { + size, err := m.Extension.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSnapshot(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} +func (m *SnapshotItem_ExtensionPayload) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotItem_ExtensionPayload) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ExtensionPayload != nil { + { + size, err := m.ExtensionPayload.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSnapshot(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + return len(dAtA) - i, nil +} +func (m *SnapshotStoreItem) 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 *SnapshotStoreItem) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotStoreItem) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintSnapshot(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SnapshotIAVLItem) 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 *SnapshotIAVLItem) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotIAVLItem) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Height != 0 { + i = encodeVarintSnapshot(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x20 + } + if m.Version != 0 { + i = encodeVarintSnapshot(dAtA, i, uint64(m.Version)) + i-- + dAtA[i] = 0x18 + } + if len(m.Value) > 0 { + i -= len(m.Value) + copy(dAtA[i:], m.Value) + i = encodeVarintSnapshot(dAtA, i, uint64(len(m.Value))) + i-- + dAtA[i] = 0x12 + } + if len(m.Key) > 0 { + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintSnapshot(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SnapshotExtensionMeta) 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 *SnapshotExtensionMeta) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotExtensionMeta) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Format != 0 { + i = encodeVarintSnapshot(dAtA, i, uint64(m.Format)) + i-- + dAtA[i] = 0x10 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintSnapshot(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SnapshotExtensionPayload) 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 *SnapshotExtensionPayload) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotExtensionPayload) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintSnapshot(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintSnapshot(dAtA []byte, offset int, v uint64) int { + offset -= sovSnapshot(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Snapshot) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovSnapshot(uint64(m.Height)) + } + if m.Format != 0 { + n += 1 + sovSnapshot(uint64(m.Format)) + } + if m.Chunks != 0 { + n += 1 + sovSnapshot(uint64(m.Chunks)) + } + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovSnapshot(uint64(l)) + } + l = m.Metadata.Size() + n += 1 + l + sovSnapshot(uint64(l)) + return n +} + +func (m *Metadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ChunkHashes) > 0 { + for _, b := range m.ChunkHashes { + l = len(b) + n += 1 + l + sovSnapshot(uint64(l)) + } + } + return n +} + +func (m *SnapshotItem) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Item != nil { + n += m.Item.Size() + } + return n +} + +func (m *SnapshotItem_Store) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Store != nil { + l = m.Store.Size() + n += 1 + l + sovSnapshot(uint64(l)) + } + return n +} +func (m *SnapshotItem_IAVL) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IAVL != nil { + l = m.IAVL.Size() + n += 1 + l + sovSnapshot(uint64(l)) + } + return n +} +func (m *SnapshotItem_Extension) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Extension != nil { + l = m.Extension.Size() + n += 1 + l + sovSnapshot(uint64(l)) + } + return n +} +func (m *SnapshotItem_ExtensionPayload) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ExtensionPayload != nil { + l = m.ExtensionPayload.Size() + n += 1 + l + sovSnapshot(uint64(l)) + } + return n +} +func (m *SnapshotStoreItem) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovSnapshot(uint64(l)) + } + return n +} + +func (m *SnapshotIAVLItem) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + if l > 0 { + n += 1 + l + sovSnapshot(uint64(l)) + } + l = len(m.Value) + if l > 0 { + n += 1 + l + sovSnapshot(uint64(l)) + } + if m.Version != 0 { + n += 1 + sovSnapshot(uint64(m.Version)) + } + if m.Height != 0 { + n += 1 + sovSnapshot(uint64(m.Height)) + } + return n +} + +func (m *SnapshotExtensionMeta) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovSnapshot(uint64(l)) + } + if m.Format != 0 { + n += 1 + sovSnapshot(uint64(m.Format)) + } + return n +} + +func (m *SnapshotExtensionPayload) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovSnapshot(uint64(l)) + } + return n +} + +func sovSnapshot(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozSnapshot(x uint64) (n int) { + return sovSnapshot(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Snapshot) 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 ErrIntOverflowSnapshot + } + 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: Snapshot: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Snapshot: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Format", wireType) + } + m.Format = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Format |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Chunks", wireType) + } + m.Chunks = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Chunks |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) + if m.Hash == nil { + m.Hash = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSnapshot(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSnapshot + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Metadata) 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 ErrIntOverflowSnapshot + } + 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: Metadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChunkHashes", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChunkHashes = append(m.ChunkHashes, make([]byte, postIndex-iNdEx)) + copy(m.ChunkHashes[len(m.ChunkHashes)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSnapshot(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSnapshot + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SnapshotItem) 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 ErrIntOverflowSnapshot + } + 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: SnapshotItem: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotItem: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Store", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SnapshotStoreItem{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Item = &SnapshotItem_Store{v} + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IAVL", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SnapshotIAVLItem{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Item = &SnapshotItem_IAVL{v} + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Extension", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SnapshotExtensionMeta{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Item = &SnapshotItem_Extension{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExtensionPayload", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SnapshotExtensionPayload{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Item = &SnapshotItem_ExtensionPayload{v} + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSnapshot(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSnapshot + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } } - l = m.Metadata.Size() - n += 1 + l + sovSnapshot(uint64(l)) - return n -} -func (m *Metadata) Size() (n int) { - if m == nil { - return 0 + if iNdEx > l { + return io.ErrUnexpectedEOF } - var l int - _ = l - if len(m.ChunkHashes) > 0 { - for _, b := range m.ChunkHashes { - l = len(b) - n += 1 + l + sovSnapshot(uint64(l)) + return nil +} +func (m *SnapshotStoreItem) 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 ErrIntOverflowSnapshot + } + 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: SnapshotStoreItem: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotStoreItem: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + 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 ErrInvalidLengthSnapshot + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSnapshot(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSnapshot + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy } } - return n -} -func sovSnapshot(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozSnapshot(x uint64) (n int) { - return sovSnapshot(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil } -func (m *Snapshot) Unmarshal(dAtA []byte) error { +func (m *SnapshotIAVLItem) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -342,17 +1599,17 @@ func (m *Snapshot) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Snapshot: wiretype end group for non-group") + return fmt.Errorf("proto: SnapshotIAVLItem: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Snapshot: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SnapshotIAVLItem: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) } - m.Height = 0 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSnapshot @@ -362,16 +1619,31 @@ func (m *Snapshot) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Height |= uint64(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } + if byteLen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Format", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) } - m.Format = 0 + var byteLen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSnapshot @@ -381,16 +1653,31 @@ func (m *Snapshot) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Format |= uint32(b&0x7F) << shift + byteLen |= int(b&0x7F) << shift if b < 0x80 { break } } + if byteLen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Value = append(m.Value[:0], dAtA[iNdEx:postIndex]...) + if m.Value == nil { + m.Value = []byte{} + } + iNdEx = postIndex case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Chunks", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) } - m.Chunks = 0 + m.Version = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSnapshot @@ -400,16 +1687,16 @@ func (m *Snapshot) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Chunks |= uint32(b&0x7F) << shift + m.Version |= int64(b&0x7F) << shift if b < 0x80 { break } } case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) } - var byteLen int + m.Height = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSnapshot @@ -419,31 +1706,66 @@ func (m *Snapshot) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + m.Height |= int32(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { - return ErrInvalidLengthSnapshot + default: + iNdEx = preIndex + skippy, err := skipSnapshot(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + byteLen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthSnapshot } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.Hash = append(m.Hash[:0], dAtA[iNdEx:postIndex]...) - if m.Hash == nil { - m.Hash = []byte{} + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SnapshotExtensionMeta) 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 ErrIntOverflowSnapshot } - iNdEx = postIndex - case 5: + 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: SnapshotExtensionMeta: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotExtensionMeta: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowSnapshot @@ -453,25 +1775,43 @@ func (m *Snapshot) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthSnapshot } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthSnapshot } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Format", wireType) + } + m.Format = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Format |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipSnapshot(dAtA[iNdEx:]) @@ -493,7 +1833,7 @@ func (m *Snapshot) Unmarshal(dAtA []byte) error { } return nil } -func (m *Metadata) Unmarshal(dAtA []byte) error { +func (m *SnapshotExtensionPayload) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -516,15 +1856,15 @@ func (m *Metadata) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Metadata: wiretype end group for non-group") + return fmt.Errorf("proto: SnapshotExtensionPayload: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SnapshotExtensionPayload: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ChunkHashes", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) } var byteLen int for shift := uint(0); ; shift += 7 { @@ -551,8 +1891,10 @@ func (m *Metadata) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ChunkHashes = append(m.ChunkHashes, make([]byte, postIndex-iNdEx)) - copy(m.ChunkHashes[len(m.ChunkHashes)-1], dAtA[iNdEx:postIndex]) + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } iNdEx = postIndex default: iNdEx = preIndex diff --git a/snapshots/types/snapshotter.go b/snapshots/types/snapshotter.go index 1ebd763b5d75..b802db9f1085 100644 --- a/snapshots/types/snapshotter.go +++ b/snapshots/types/snapshotter.go @@ -1,16 +1,33 @@ package types -import "io" +import ( + protoio "github.com/gogo/protobuf/io" +) // Snapshotter is something that can create and restore snapshots, consisting of streamed binary // chunks - all of which must be read from the channel and closed. If an unsupported format is // given, it must return ErrUnknownFormat (possibly wrapped with fmt.Errorf). type Snapshotter interface { - // Snapshot creates a state snapshot, returning a channel of snapshot chunk readers. - Snapshot(height uint64, format uint32) (<-chan io.ReadCloser, error) + // Snapshot writes snapshot items into the protobuf writer. + Snapshot(height uint64, protoWriter protoio.Writer) error - // Restore restores a state snapshot, taking snapshot chunk readers as input. + // Restore restores a state snapshot from the protobuf items read from the reader. // If the ready channel is non-nil, it returns a ready signal (by being closed) once the // restorer is ready to accept chunks. - Restore(height uint64, format uint32, chunks <-chan io.ReadCloser, ready chan<- struct{}) error + Restore(height uint64, format uint32, protoReader protoio.Reader) (SnapshotItem, error) +} + +// ExtensionSnapshotter is an extension Snapshotter that is appended to the snapshot stream. +// ExtensionSnapshotter has an unique name and manages it's own internal formats. +type ExtensionSnapshotter interface { + Snapshotter + + // SnapshotName returns the name of snapshotter, it should be unique in the manager. + SnapshotName() string + + // SnapshotFormat returns the default format used to take a snapshot. + SnapshotFormat() uint32 + + // SupportedFormats returns a list of formats it can restore from. + SupportedFormats() []uint32 } diff --git a/snapshots/types/util.go b/snapshots/types/util.go new file mode 100644 index 000000000000..125ea6fb4610 --- /dev/null +++ b/snapshots/types/util.go @@ -0,0 +1,16 @@ +package types + +import ( + protoio "github.com/gogo/protobuf/io" +) + +// WriteExtensionItem writes an item payload for current extention snapshotter. +func WriteExtensionItem(protoWriter protoio.Writer, item []byte) error { + return protoWriter.WriteMsg(&SnapshotItem{ + Item: &SnapshotItem_ExtensionPayload{ + ExtensionPayload: &SnapshotExtensionPayload{ + Payload: item, + }, + }, + }) +} diff --git a/store/rootmulti/snapshot_test.go b/store/rootmulti/snapshot_test.go new file mode 100644 index 000000000000..fe80d9584df1 --- /dev/null +++ b/store/rootmulti/snapshot_test.go @@ -0,0 +1,296 @@ +package rootmulti_test + +import ( + "crypto/sha256" + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "io" + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/snapshots" + snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" + "github.com/cosmos/cosmos-sdk/store/iavl" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + "github.com/cosmos/cosmos-sdk/store/types" + dbm "github.com/tendermint/tm-db" +) + +func newMultiStoreWithGeneratedData(db dbm.DB, stores uint8, storeKeys uint64) *rootmulti.Store { + multiStore := rootmulti.NewStore(db) + r := rand.New(rand.NewSource(49872768940)) // Fixed seed for deterministic tests + + keys := []*types.KVStoreKey{} + for i := uint8(0); i < stores; i++ { + key := types.NewKVStoreKey(fmt.Sprintf("store%v", i)) + multiStore.MountStoreWithDB(key, types.StoreTypeIAVL, nil) + keys = append(keys, key) + } + multiStore.LoadLatestVersion() + + for _, key := range keys { + store := multiStore.GetCommitKVStore(key).(*iavl.Store) + for i := uint64(0); i < storeKeys; i++ { + k := make([]byte, 8) + v := make([]byte, 1024) + binary.BigEndian.PutUint64(k, i) + _, err := r.Read(v) + if err != nil { + panic(err) + } + store.Set(k, v) + } + } + + multiStore.Commit() + multiStore.LoadLatestVersion() + + return multiStore +} + +func newMultiStoreWithMixedMounts(db dbm.DB) *rootmulti.Store { + store := rootmulti.NewStore(db) + store.MountStoreWithDB(types.NewKVStoreKey("iavl1"), types.StoreTypeIAVL, nil) + store.MountStoreWithDB(types.NewKVStoreKey("iavl2"), types.StoreTypeIAVL, nil) + store.MountStoreWithDB(types.NewKVStoreKey("iavl3"), types.StoreTypeIAVL, nil) + store.MountStoreWithDB(types.NewTransientStoreKey("trans1"), types.StoreTypeTransient, nil) + store.LoadLatestVersion() + + return store +} + +func newMultiStoreWithMixedMountsAndBasicData(db dbm.DB) *rootmulti.Store { + store := newMultiStoreWithMixedMounts(db) + store1 := store.GetStoreByName("iavl1").(types.CommitKVStore) + store2 := store.GetStoreByName("iavl2").(types.CommitKVStore) + trans1 := store.GetStoreByName("trans1").(types.KVStore) + + store1.Set([]byte("a"), []byte{1}) + store1.Set([]byte("b"), []byte{1}) + store2.Set([]byte("X"), []byte{255}) + store2.Set([]byte("A"), []byte{101}) + trans1.Set([]byte("x1"), []byte{91}) + store.Commit() + + store1.Set([]byte("b"), []byte{2}) + store1.Set([]byte("c"), []byte{3}) + store2.Set([]byte("B"), []byte{102}) + store.Commit() + + store2.Set([]byte("C"), []byte{103}) + store2.Delete([]byte("X")) + trans1.Set([]byte("x2"), []byte{92}) + store.Commit() + + return store +} + +func assertStoresEqual(t *testing.T, expect, actual types.CommitKVStore, msgAndArgs ...interface{}) { + assert.Equal(t, expect.LastCommitID(), actual.LastCommitID()) + expectIter := expect.Iterator(nil, nil) + expectMap := map[string][]byte{} + for ; expectIter.Valid(); expectIter.Next() { + expectMap[string(expectIter.Key())] = expectIter.Value() + } + require.NoError(t, expectIter.Error()) + + actualIter := expect.Iterator(nil, nil) + actualMap := map[string][]byte{} + for ; actualIter.Valid(); actualIter.Next() { + actualMap[string(actualIter.Key())] = actualIter.Value() + } + require.NoError(t, actualIter.Error()) + + assert.Equal(t, expectMap, actualMap, msgAndArgs...) +} + +func TestMultistoreSnapshot_Checksum(t *testing.T) { + // Chunks from different nodes must fit together, so all nodes must produce identical chunks. + // This checksum test makes sure that the byte stream remains identical. If the test fails + // without having changed the data (e.g. because the Protobuf or zlib encoding changes), + // snapshottypes.CurrentFormat must be bumped. + store := newMultiStoreWithGeneratedData(dbm.NewMemDB(), 5, 10000) + version := uint64(store.LastCommitID().Version) + + testcases := []struct { + format uint32 + chunkHashes []string + }{ + {1, []string{ + "503e5b51b657055b77e88169fadae543619368744ad15f1de0736c0a20482f24", + "e1a0daaa738eeb43e778aefd2805e3dd720798288a410b06da4b8459c4d8f72e", + "aa048b4ee0f484965d7b3b06822cf0772cdcaad02f3b1b9055e69f2cb365ef3c", + "7921eaa3ed4921341e504d9308a9877986a879fe216a099c86e8db66fcba4c63", + "a4a864e6c02c9fca5837ec80dc84f650b25276ed7e4820cf7516ced9f9901b86", + "ca2879ac6e7205d257440131ba7e72bef784cd61642e32b847729e543c1928b9", + }}, + } + for _, tc := range testcases { + tc := tc + t.Run(fmt.Sprintf("Format %v", tc.format), func(t *testing.T) { + ch := make(chan io.ReadCloser) + go func() { + streamWriter := snapshots.NewStreamWriter(ch) + defer streamWriter.Close() + require.NotNil(t, streamWriter) + err := store.Snapshot(version, streamWriter) + require.NoError(t, err) + }() + hashes := []string{} + hasher := sha256.New() + for chunk := range ch { + hasher.Reset() + _, err := io.Copy(hasher, chunk) + require.NoError(t, err) + hashes = append(hashes, hex.EncodeToString(hasher.Sum(nil))) + } + assert.Equal(t, tc.chunkHashes, hashes, + "Snapshot output for format %v has changed", tc.format) + }) + } +} + +func TestMultistoreSnapshot_Errors(t *testing.T) { + store := newMultiStoreWithMixedMountsAndBasicData(dbm.NewMemDB()) + + testcases := map[string]struct { + height uint64 + expectType error + }{ + "0 height": {0, nil}, + "unknown height": {9, nil}, + } + for name, tc := range testcases { + tc := tc + t.Run(name, func(t *testing.T) { + err := store.Snapshot(tc.height, nil) + require.Error(t, err) + if tc.expectType != nil { + assert.True(t, errors.Is(err, tc.expectType)) + } + }) + } +} + +func TestMultistoreSnapshotRestore(t *testing.T) { + source := newMultiStoreWithMixedMountsAndBasicData(dbm.NewMemDB()) + target := newMultiStoreWithMixedMounts(dbm.NewMemDB()) + version := uint64(source.LastCommitID().Version) + require.EqualValues(t, 3, version) + + chunks := make(chan io.ReadCloser, 100) + go func() { + streamWriter := snapshots.NewStreamWriter(chunks) + require.NotNil(t, streamWriter) + defer streamWriter.Close() + err := source.Snapshot(version, streamWriter) + require.NoError(t, err) + }() + + streamReader, err := snapshots.NewStreamReader(chunks) + require.NoError(t, err) + _, err = target.Restore(version, snapshottypes.CurrentFormat, streamReader) + require.NoError(t, err) + + assert.Equal(t, source.LastCommitID(), target.LastCommitID()) + for key, sourceStore := range source.GetStores() { + targetStore := target.GetStoreByName(key.Name()).(types.CommitKVStore) + switch sourceStore.GetStoreType() { + case types.StoreTypeTransient: + assert.False(t, targetStore.Iterator(nil, nil).Valid(), + "transient store %v not empty", key.Name()) + default: + assertStoresEqual(t, sourceStore, targetStore, "store %q not equal", key.Name()) + } + } +} + +func benchmarkMultistoreSnapshot(b *testing.B, stores uint8, storeKeys uint64) { + b.Skip("Noisy with slow setup time, please see https://github.com/cosmos/cosmos-sdk/issues/8855.") + + b.ReportAllocs() + b.StopTimer() + source := newMultiStoreWithGeneratedData(dbm.NewMemDB(), stores, storeKeys) + version := source.LastCommitID().Version + require.EqualValues(b, 1, version) + b.StartTimer() + + for i := 0; i < b.N; i++ { + target := rootmulti.NewStore(dbm.NewMemDB()) + for key := range source.GetStores() { + target.MountStoreWithDB(key, types.StoreTypeIAVL, nil) + } + err := target.LoadLatestVersion() + require.NoError(b, err) + require.EqualValues(b, 0, target.LastCommitID().Version) + + chunks := make(chan io.ReadCloser) + go func() { + streamWriter := snapshots.NewStreamWriter(chunks) + require.NotNil(b, streamWriter) + err := source.Snapshot(uint64(version), streamWriter) + require.NoError(b, err) + }() + for reader := range chunks { + _, err := io.Copy(io.Discard, reader) + require.NoError(b, err) + err = reader.Close() + require.NoError(b, err) + } + } +} + +func benchmarkMultistoreSnapshotRestore(b *testing.B, stores uint8, storeKeys uint64) { + b.Skip("Noisy with slow setup time, please see https://github.com/cosmos/cosmos-sdk/issues/8855.") + + b.ReportAllocs() + b.StopTimer() + source := newMultiStoreWithGeneratedData(dbm.NewMemDB(), stores, storeKeys) + version := uint64(source.LastCommitID().Version) + require.EqualValues(b, 1, version) + b.StartTimer() + + for i := 0; i < b.N; i++ { + target := rootmulti.NewStore(dbm.NewMemDB()) + for key := range source.GetStores() { + target.MountStoreWithDB(key, types.StoreTypeIAVL, nil) + } + err := target.LoadLatestVersion() + require.NoError(b, err) + require.EqualValues(b, 0, target.LastCommitID().Version) + + chunks := make(chan io.ReadCloser) + go func() { + writer := snapshots.NewStreamWriter(chunks) + require.NotNil(b, writer) + err := source.Snapshot(version, writer) + require.NoError(b, err) + }() + reader, err := snapshots.NewStreamReader(chunks) + require.NoError(b, err) + _, err = target.Restore(version, snapshottypes.CurrentFormat, reader) + require.NoError(b, err) + require.Equal(b, source.LastCommitID(), target.LastCommitID()) + } +} + +func BenchmarkMultistoreSnapshot100K(b *testing.B) { + benchmarkMultistoreSnapshot(b, 10, 10000) +} + +func BenchmarkMultistoreSnapshot1M(b *testing.B) { + benchmarkMultistoreSnapshot(b, 10, 100000) +} + +func BenchmarkMultistoreSnapshotRestore100K(b *testing.B) { + benchmarkMultistoreSnapshotRestore(b, 10, 10000) +} + +func BenchmarkMultistoreSnapshotRestore1M(b *testing.B) { + benchmarkMultistoreSnapshotRestore(b, 10, 100000) +} diff --git a/store/rootmulti/store.go b/store/rootmulti/store.go index bd73c2fb774e..da8f202f9e63 100644 --- a/store/rootmulti/store.go +++ b/store/rootmulti/store.go @@ -1,8 +1,6 @@ package rootmulti import ( - "bufio" - "compress/zlib" "encoding/binary" "fmt" "io" @@ -18,7 +16,6 @@ import ( abci "github.com/tendermint/tendermint/abci/types" dbm "github.com/tendermint/tm-db" - "github.com/cosmos/cosmos-sdk/snapshots" snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" "github.com/cosmos/cosmos-sdk/store/cachemulti" "github.com/cosmos/cosmos-sdk/store/dbadapter" @@ -35,11 +32,6 @@ const ( latestVersionKey = "s/latest" pruneHeightsKey = "s/pruneheights" commitInfoKeyFmt = "s/%d" // s/ - - // Do not change chunk size without new snapshot format (must be uniform across nodes) - snapshotChunkSize = uint64(10e6) - snapshotBufferSize = int(snapshotChunkSize) - snapshotMaxItemSize = int(64e6) // SDK has no key/value size limit, so we set an arbitrary limit ) // Store is composed of many CommitStores. Name contrasts with @@ -156,6 +148,11 @@ func (rs *Store) GetCommitKVStore(key types.StoreKey) types.CommitKVStore { return rs.stores[key] } +// GetStores returns mounted stores +func (rs *Store) GetStores() map[types.StoreKey]types.CommitKVStore { + return rs.stores +} + // LoadLatestVersionAndUpgrade implements CommitMultiStore func (rs *Store) LoadLatestVersionAndUpgrade(upgrades *types.StoreUpgrades) error { ver := getLatestVersion(rs.db) @@ -561,11 +558,11 @@ func (rs *Store) GetKVStore(key types.StoreKey) types.KVStore { return store } -// getStoreByName performs a lookup of a StoreKey given a store name typically +// GetStoreByName performs a lookup of a StoreKey given a store name typically // provided in a path. The StoreKey is then used to perform a lookup and return // a Store. If the Store is wrapped in an inter-block cache, it will be unwrapped // prior to being returned. If the StoreKey does not exist, nil is returned. -func (rs *Store) getStoreByName(name string) types.Store { +func (rs *Store) GetStoreByName(name string) types.Store { key := rs.keysByName[name] if key == nil { return nil @@ -585,7 +582,7 @@ func (rs *Store) Query(req abci.RequestQuery) abci.ResponseQuery { return sdkerrors.QueryResult(err, false) } - store := rs.getStoreByName(storeName) + store := rs.GetStoreByName(storeName) if store == nil { return sdkerrors.QueryResult(sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "no such store: %s", storeName), false) } @@ -670,15 +667,12 @@ func parsePath(path string) (storeName string, subpath string, err error) { // identical across nodes such that chunks from different sources fit together. If the output for a // given format changes (at the byte level), the snapshot format must be bumped - see // TestMultistoreSnapshot_Checksum test. -func (rs *Store) Snapshot(height uint64, format uint32) (<-chan io.ReadCloser, error) { - if format != snapshottypes.CurrentFormat { - return nil, sdkerrors.Wrapf(snapshottypes.ErrUnknownFormat, "format %v", format) - } +func (rs *Store) Snapshot(height uint64, protoWriter protoio.Writer) error { if height == 0 { - return nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "cannot snapshot height 0") + return sdkerrors.Wrap(sdkerrors.ErrLogic, "cannot snapshot height 0") } if height > uint64(rs.LastCommitID().Version) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, "cannot snapshot future height %v", height) + return sdkerrors.Wrapf(sdkerrors.ErrLogic, "cannot snapshot future height %v", height) } // Collect stores to snapshot (only IAVL stores are supported) @@ -695,7 +689,7 @@ func (rs *Store) Snapshot(height uint64, format uint32) (<-chan io.ReadCloser, e // Non-persisted stores shouldn't be snapshotted continue default: - return nil, sdkerrors.Wrapf(sdkerrors.ErrLogic, + return sdkerrors.Wrapf(sdkerrors.ErrLogic, "don't know how to snapshot store %q of type %T", key.Name(), store) } } @@ -703,160 +697,97 @@ func (rs *Store) Snapshot(height uint64, format uint32) (<-chan io.ReadCloser, e return strings.Compare(stores[i].name, stores[j].name) == -1 }) - // Spawn goroutine to generate snapshot chunks and pass their io.ReadClosers through a channel - ch := make(chan io.ReadCloser) - go func() { - // Set up a stream pipeline to serialize snapshot nodes: - // ExportNode -> delimited Protobuf -> zlib -> buffer -> chunkWriter -> chan io.ReadCloser - chunkWriter := snapshots.NewChunkWriter(ch, snapshotChunkSize) - defer chunkWriter.Close() - bufWriter := bufio.NewWriterSize(chunkWriter, snapshotBufferSize) - defer func() { - if err := bufWriter.Flush(); err != nil { - chunkWriter.CloseWithError(err) - } - }() - zWriter, err := zlib.NewWriterLevel(bufWriter, 7) + // Export each IAVL store. Stores are serialized as a stream of SnapshotItem Protobuf + // messages. The first item contains a SnapshotStore with store metadata (i.e. name), + // and the following messages contain a SnapshotNode (i.e. an ExportNode). Store changes + // are demarcated by new SnapshotStore items. + for _, store := range stores { + exporter, err := store.Export(int64(height)) if err != nil { - chunkWriter.CloseWithError(sdkerrors.Wrap(err, "zlib failure")) - return + return err } - defer func() { - if err := zWriter.Close(); err != nil { - chunkWriter.CloseWithError(err) - } - }() - protoWriter := protoio.NewDelimitedWriter(zWriter) - defer func() { - if err := protoWriter.Close(); err != nil { - chunkWriter.CloseWithError(err) - } - }() - - // Export each IAVL store. Stores are serialized as a stream of SnapshotItem Protobuf - // messages. The first item contains a SnapshotStore with store metadata (i.e. name), - // and the following messages contain a SnapshotNode (i.e. an ExportNode). Store changes - // are demarcated by new SnapshotStore items. - for _, store := range stores { - exporter, err := store.Export(int64(height)) - if err != nil { - chunkWriter.CloseWithError(err) - return + defer exporter.Close() + err = protoWriter.WriteMsg(&snapshottypes.SnapshotItem{ + Item: &snapshottypes.SnapshotItem_Store{ + Store: &snapshottypes.SnapshotStoreItem{ + Name: store.name, + }, + }, + }) + if err != nil { + return err + } + + for { + node, err := exporter.Next() + if err == iavltree.ExportDone { + break + } else if err != nil { + return err } - defer exporter.Close() - err = protoWriter.WriteMsg(&types.SnapshotItem{ - Item: &types.SnapshotItem_Store{ - Store: &types.SnapshotStoreItem{ - Name: store.name, + err = protoWriter.WriteMsg(&snapshottypes.SnapshotItem{ + Item: &snapshottypes.SnapshotItem_IAVL{ + IAVL: &snapshottypes.SnapshotIAVLItem{ + Key: node.Key, + Value: node.Value, + Height: int32(node.Height), + Version: node.Version, }, }, }) if err != nil { - chunkWriter.CloseWithError(err) - return + return err } - - for { - node, err := exporter.Next() - if err == iavltree.ExportDone { - break - } else if err != nil { - chunkWriter.CloseWithError(err) - return - } - err = protoWriter.WriteMsg(&types.SnapshotItem{ - Item: &types.SnapshotItem_IAVL{ - IAVL: &types.SnapshotIAVLItem{ - Key: node.Key, - Value: node.Value, - Height: int32(node.Height), - Version: node.Version, - }, - }, - }) - if err != nil { - chunkWriter.CloseWithError(err) - return - } - } - exporter.Close() } - }() + exporter.Close() + } - return ch, nil + return nil } // Restore implements snapshottypes.Snapshotter. +// returns next snapshot item and error. func (rs *Store) Restore( - height uint64, format uint32, chunks <-chan io.ReadCloser, ready chan<- struct{}, -) error { - if format != snapshottypes.CurrentFormat { - return sdkerrors.Wrapf(snapshottypes.ErrUnknownFormat, "format %v", format) - } - if height == 0 { - return sdkerrors.Wrap(sdkerrors.ErrLogic, "cannot restore snapshot at height 0") - } - if height > uint64(math.MaxInt64) { - return sdkerrors.Wrapf(snapshottypes.ErrInvalidMetadata, - "snapshot height %v cannot exceed %v", height, int64(math.MaxInt64)) - } - - // Signal readiness. Must be done before the readers below are set up, since the zlib - // reader reads from the stream on initialization, potentially causing deadlocks. - if ready != nil { - close(ready) - } - - // Set up a restore stream pipeline - // chan io.ReadCloser -> chunkReader -> zlib -> delimited Protobuf -> ExportNode - chunkReader := snapshots.NewChunkReader(chunks) - defer chunkReader.Close() - zReader, err := zlib.NewReader(chunkReader) - if err != nil { - return sdkerrors.Wrap(err, "zlib failure") - } - defer zReader.Close() - protoReader := protoio.NewDelimitedReader(zReader, snapshotMaxItemSize) - defer protoReader.Close() - + height uint64, format uint32, protoReader protoio.Reader, +) (snapshottypes.SnapshotItem, error) { // Import nodes into stores. The first item is expected to be a SnapshotItem containing // a SnapshotStoreItem, telling us which store to import into. The following items will contain // SnapshotNodeItem (i.e. ExportNode) until we reach the next SnapshotStoreItem or EOF. var importer *iavltree.Importer for { - item := &types.SnapshotItem{} - err := protoReader.ReadMsg(item) + snapshotItem := &snapshottypes.SnapshotItem{} + err := protoReader.ReadMsg(snapshotItem) if err == io.EOF { break } else if err != nil { - return sdkerrors.Wrap(err, "invalid protobuf message") + return snapshottypes.SnapshotItem{}, sdkerrors.Wrap(err, "invalid protobuf message") } - switch item := item.Item.(type) { - case *types.SnapshotItem_Store: + switch item := snapshotItem.Item.(type) { + case *snapshottypes.SnapshotItem_Store: if importer != nil { err = importer.Commit() if err != nil { - return sdkerrors.Wrap(err, "IAVL commit failed") + return snapshottypes.SnapshotItem{}, sdkerrors.Wrap(err, "IAVL commit failed") } importer.Close() } - store, ok := rs.getStoreByName(item.Store.Name).(*iavl.Store) + store, ok := rs.GetStoreByName(item.Store.Name).(*iavl.Store) if !ok || store == nil { - return sdkerrors.Wrapf(sdkerrors.ErrLogic, "cannot import into non-IAVL store %q", item.Store.Name) + return snapshottypes.SnapshotItem{}, sdkerrors.Wrapf(sdkerrors.ErrLogic, "cannot import into non-IAVL store %q", item.Store.Name) } importer, err = store.Import(int64(height)) if err != nil { - return sdkerrors.Wrap(err, "import failed") + return snapshottypes.SnapshotItem{}, sdkerrors.Wrap(err, "import failed") } defer importer.Close() - case *types.SnapshotItem_IAVL: + case *snapshottypes.SnapshotItem_IAVL: if importer == nil { - return sdkerrors.Wrap(sdkerrors.ErrLogic, "received IAVL node item before store item") + return snapshottypes.SnapshotItem{}, sdkerrors.Wrap(sdkerrors.ErrLogic, "received IAVL node item before store item") } if item.IAVL.Height > math.MaxInt8 { - return sdkerrors.Wrapf(sdkerrors.ErrLogic, "node height %v cannot exceed %v", + return snapshottypes.SnapshotItem{}, sdkerrors.Wrapf(sdkerrors.ErrLogic, "node height %v cannot exceed %v", item.IAVL.Height, math.MaxInt8) } node := &iavltree.ExportNode{ @@ -875,24 +806,25 @@ func (rs *Store) Restore( } err := importer.Add(node) if err != nil { - return sdkerrors.Wrap(err, "IAVL node import failed") + return snapshottypes.SnapshotItem{}, sdkerrors.Wrap(err, "IAVL node import failed") } default: - return sdkerrors.Wrapf(sdkerrors.ErrLogic, "unknown snapshot item %T", item) + // pass back the unrecognized item. + return *snapshotItem, nil } } if importer != nil { err := importer.Commit() if err != nil { - return sdkerrors.Wrap(err, "IAVL commit failed") + return snapshottypes.SnapshotItem{}, sdkerrors.Wrap(err, "IAVL commit failed") } importer.Close() } flushMetadata(rs.db, int64(height), rs.buildCommitInfo(int64(height)), []int64{}) - return rs.LoadLatestVersion() + return snapshottypes.SnapshotItem{}, rs.LoadLatestVersion() } func (rs *Store) loadCommitStoreFromParams(key types.StoreKey, id types.CommitID, params storeParams) (types.CommitKVStore, error) { diff --git a/store/rootmulti/store_test.go b/store/rootmulti/store_test.go index 7cd09bfeea0c..80cbcf68cbd0 100644 --- a/store/rootmulti/store_test.go +++ b/store/rootmulti/store_test.go @@ -2,24 +2,16 @@ package rootmulti import ( "bytes" - "crypto/sha256" - "encoding/binary" - "encoding/hex" - "errors" "fmt" - "io" - "math/rand" "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/codec" codecTypes "github.com/cosmos/cosmos-sdk/codec/types" - snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" "github.com/cosmos/cosmos-sdk/store/cachemulti" "github.com/cosmos/cosmos-sdk/store/iavl" sdkmaps "github.com/cosmos/cosmos-sdk/store/internal/maps" @@ -86,7 +78,7 @@ func TestCacheMultiStoreWithVersion(t *testing.T) { k, v := []byte("wind"), []byte("blows") - store1 := ms.getStoreByName("store1").(types.KVStore) + store1 := ms.GetStoreByName("store1").(types.KVStore) store1.Set(k, v) cID := ms.Commit() @@ -123,7 +115,7 @@ func TestHashStableWithEmptyCommit(t *testing.T) { k, v := []byte("wind"), []byte("blows") - store1 := ms.getStoreByName("store1").(types.KVStore) + store1 := ms.GetStoreByName("store1").(types.KVStore) store1.Set(k, v) cID := ms.Commit() @@ -147,11 +139,11 @@ func TestMultistoreCommitLoad(t *testing.T) { checkStore(t, store, commitID, commitID) // Make sure we can get stores by name. - s1 := store.getStoreByName("store1") + s1 := store.GetStoreByName("store1") require.NotNil(t, s1) - s3 := store.getStoreByName("store3") + s3 := store.GetStoreByName("store3") require.NotNil(t, s3) - s77 := store.getStoreByName("store77") + s77 := store.GetStoreByName("store77") require.Nil(t, s77) // Make a few commits and check them. @@ -191,21 +183,21 @@ func TestMultistoreLoadWithUpgrade(t *testing.T) { // write some data in all stores k1, v1 := []byte("first"), []byte("store") - s1, _ := store.getStoreByName("store1").(types.KVStore) + s1, _ := store.GetStoreByName("store1").(types.KVStore) require.NotNil(t, s1) s1.Set(k1, v1) k2, v2 := []byte("second"), []byte("restore") - s2, _ := store.getStoreByName("store2").(types.KVStore) + s2, _ := store.GetStoreByName("store2").(types.KVStore) require.NotNil(t, s2) s2.Set(k2, v2) k3, v3 := []byte("third"), []byte("dropped") - s3, _ := store.getStoreByName("store3").(types.KVStore) + s3, _ := store.GetStoreByName("store3").(types.KVStore) require.NotNil(t, s3) s3.Set(k3, v3) - s4, _ := store.getStoreByName("store4").(types.KVStore) + s4, _ := store.GetStoreByName("store4").(types.KVStore) require.Nil(t, s4) // do one commit @@ -228,7 +220,7 @@ func TestMultistoreLoadWithUpgrade(t *testing.T) { checkStore(t, store, commitID, commitID) // let's query data to see it was saved properly - s2, _ = store.getStoreByName("store2").(types.KVStore) + s2, _ = store.GetStoreByName("store2").(types.KVStore) require.NotNil(t, s2) require.Equal(t, v2, s2.Get(k2)) @@ -238,17 +230,17 @@ func TestMultistoreLoadWithUpgrade(t *testing.T) { require.Nil(t, err) // s1 was not changed - s1, _ = restore.getStoreByName("store1").(types.KVStore) + s1, _ = restore.GetStoreByName("store1").(types.KVStore) require.NotNil(t, s1) require.Equal(t, v1, s1.Get(k1)) // store3 is mounted, but data deleted are gone - s3, _ = restore.getStoreByName("store3").(types.KVStore) + s3, _ = restore.GetStoreByName("store3").(types.KVStore) require.NotNil(t, s3) require.Nil(t, s3.Get(k3)) // data was deleted // store4 is mounted, with empty data - s4, _ = restore.getStoreByName("store4").(types.KVStore) + s4, _ = restore.GetStoreByName("store4").(types.KVStore) require.NotNil(t, s4) iterator := s4.Iterator(nil, nil) @@ -266,11 +258,11 @@ func TestMultistoreLoadWithUpgrade(t *testing.T) { s4.Set(k4, v4) // store2 is no longer mounted - st2 := restore.getStoreByName("store2") + st2 := restore.GetStoreByName("store2") require.Nil(t, st2) // restore2 has the old data - rs2, _ := restore.getStoreByName("restore2").(types.KVStore) + rs2, _ := restore.GetStoreByName("restore2").(types.KVStore) require.NotNil(t, rs2) require.Equal(t, v2, rs2.Get(k2)) @@ -284,15 +276,15 @@ func TestMultistoreLoadWithUpgrade(t *testing.T) { require.Equal(t, migratedID, reload.LastCommitID()) // query this new store - rl1, _ := reload.getStoreByName("store1").(types.KVStore) + rl1, _ := reload.GetStoreByName("store1").(types.KVStore) require.NotNil(t, rl1) require.Equal(t, v1, rl1.Get(k1)) - rl2, _ := reload.getStoreByName("restore2").(types.KVStore) + rl2, _ := reload.GetStoreByName("restore2").(types.KVStore) require.NotNil(t, rl2) require.Equal(t, v2, rl2.Get(k2)) - rl4, _ := reload.getStoreByName("store4").(types.KVStore) + rl4, _ := reload.GetStoreByName("store4").(types.KVStore) require.NotNil(t, rl4) require.Equal(t, v4, rl4.Get(k4)) @@ -343,15 +335,15 @@ func TestMultiStoreRestart(t *testing.T) { for i := 1; i < 3; i++ { // Set and commit data in one store. - store1 := multi.getStoreByName("store1").(types.KVStore) + store1 := multi.GetStoreByName("store1").(types.KVStore) store1.Set([]byte(k), []byte(fmt.Sprintf("%s:%d", v, i))) // ... and another. - store2 := multi.getStoreByName("store2").(types.KVStore) + store2 := multi.GetStoreByName("store2").(types.KVStore) store2.Set([]byte(k2), []byte(fmt.Sprintf("%s:%d", v2, i))) // ... and another. - store3 := multi.getStoreByName("store3").(types.KVStore) + store3 := multi.GetStoreByName("store3").(types.KVStore) store3.Set([]byte(k3), []byte(fmt.Sprintf("%s:%d", v3, i))) multi.Commit() @@ -362,11 +354,11 @@ func TestMultiStoreRestart(t *testing.T) { } // Set and commit data in one store. - store1 := multi.getStoreByName("store1").(types.KVStore) + store1 := multi.GetStoreByName("store1").(types.KVStore) store1.Set([]byte(k), []byte(fmt.Sprintf("%s:%d", v, 3))) // ... and another. - store2 := multi.getStoreByName("store2").(types.KVStore) + store2 := multi.GetStoreByName("store2").(types.KVStore) store2.Set([]byte(k2), []byte(fmt.Sprintf("%s:%d", v2, 3))) multi.Commit() @@ -376,7 +368,7 @@ func TestMultiStoreRestart(t *testing.T) { require.NotEqual(t, initCid, flushedCinfo, "CID is different after flush to disk") // ... and another. - store3 := multi.getStoreByName("store3").(types.KVStore) + store3 := multi.GetStoreByName("store3").(types.KVStore) store3.Set([]byte(k3), []byte(fmt.Sprintf("%s:%d", v3, 3))) multi.Commit() @@ -393,16 +385,16 @@ func TestMultiStoreRestart(t *testing.T) { require.Equal(t, int64(4), reloadedCid.Version, "Reloaded CID is not the same as last flushed CID") // Check that store1 and store2 retained date from 3rd commit - store1 = multi.getStoreByName("store1").(types.KVStore) + store1 = multi.GetStoreByName("store1").(types.KVStore) val := store1.Get([]byte(k)) require.Equal(t, []byte(fmt.Sprintf("%s:%d", v, 3)), val, "Reloaded value not the same as last flushed value") - store2 = multi.getStoreByName("store2").(types.KVStore) + store2 = multi.GetStoreByName("store2").(types.KVStore) val2 := store2.Get([]byte(k2)) require.Equal(t, []byte(fmt.Sprintf("%s:%d", v2, 3)), val2, "Reloaded value not the same as last flushed value") // Check that store3 still has data from last commit even though update happened on 2nd commit - store3 = multi.getStoreByName("store3").(types.KVStore) + store3 = multi.GetStoreByName("store3").(types.KVStore) val3 := store3.Get([]byte(k3)) require.Equal(t, []byte(fmt.Sprintf("%s:%d", v3, 3)), val3, "Reloaded value not the same as last flushed value") } @@ -420,15 +412,15 @@ func TestMultiStoreQuery(t *testing.T) { cid := multi.Commit() // Make sure we can get by name. - garbage := multi.getStoreByName("bad-name") + garbage := multi.GetStoreByName("bad-name") require.Nil(t, garbage) // Set and commit data in one store. - store1 := multi.getStoreByName("store1").(types.KVStore) + store1 := multi.GetStoreByName("store1").(types.KVStore) store1.Set(k, v) // ... and another. - store2 := multi.getStoreByName("store2").(types.KVStore) + store2 := multi.GetStoreByName("store2").(types.KVStore) store2.Set(k2, v2) // Commit the multistore. @@ -551,121 +543,6 @@ func TestMultiStore_PruningRestart(t *testing.T) { } } -func TestMultistoreSnapshot_Checksum(t *testing.T) { - // Chunks from different nodes must fit together, so all nodes must produce identical chunks. - // This checksum test makes sure that the byte stream remains identical. If the test fails - // without having changed the data (e.g. because the Protobuf or zlib encoding changes), - // snapshottypes.CurrentFormat must be bumped. - store := newMultiStoreWithGeneratedData(dbm.NewMemDB(), 5, 10000) - version := uint64(store.LastCommitID().Version) - - testcases := []struct { - format uint32 - chunkHashes []string - }{ - {1, []string{ - "503e5b51b657055b77e88169fadae543619368744ad15f1de0736c0a20482f24", - "e1a0daaa738eeb43e778aefd2805e3dd720798288a410b06da4b8459c4d8f72e", - "aa048b4ee0f484965d7b3b06822cf0772cdcaad02f3b1b9055e69f2cb365ef3c", - "7921eaa3ed4921341e504d9308a9877986a879fe216a099c86e8db66fcba4c63", - "a4a864e6c02c9fca5837ec80dc84f650b25276ed7e4820cf7516ced9f9901b86", - "ca2879ac6e7205d257440131ba7e72bef784cd61642e32b847729e543c1928b9", - }}, - } - for _, tc := range testcases { - tc := tc - t.Run(fmt.Sprintf("Format %v", tc.format), func(t *testing.T) { - chunks, err := store.Snapshot(version, tc.format) - require.NoError(t, err) - hashes := []string{} - hasher := sha256.New() - for chunk := range chunks { - hasher.Reset() - _, err := io.Copy(hasher, chunk) - require.NoError(t, err) - hashes = append(hashes, hex.EncodeToString(hasher.Sum(nil))) - } - assert.Equal(t, tc.chunkHashes, hashes, - "Snapshot output for format %v has changed", tc.format) - }) - } -} - -func TestMultistoreSnapshot_Errors(t *testing.T) { - store := newMultiStoreWithMixedMountsAndBasicData(dbm.NewMemDB()) - - testcases := map[string]struct { - height uint64 - format uint32 - expectType error - }{ - "0 height": {0, snapshottypes.CurrentFormat, nil}, - "0 format": {1, 0, snapshottypes.ErrUnknownFormat}, - "unknown height": {9, snapshottypes.CurrentFormat, nil}, - "unknown format": {1, 9, snapshottypes.ErrUnknownFormat}, - } - for name, tc := range testcases { - tc := tc - t.Run(name, func(t *testing.T) { - _, err := store.Snapshot(tc.height, tc.format) - require.Error(t, err) - if tc.expectType != nil { - assert.True(t, errors.Is(err, tc.expectType)) - } - }) - } -} - -func TestMultistoreRestore_Errors(t *testing.T) { - store := newMultiStoreWithMixedMounts(dbm.NewMemDB()) - - testcases := map[string]struct { - height uint64 - format uint32 - expectType error - }{ - "0 height": {0, snapshottypes.CurrentFormat, nil}, - "0 format": {1, 0, snapshottypes.ErrUnknownFormat}, - "unknown format": {1, 9, snapshottypes.ErrUnknownFormat}, - } - for name, tc := range testcases { - tc := tc - t.Run(name, func(t *testing.T) { - err := store.Restore(tc.height, tc.format, nil, nil) - require.Error(t, err) - if tc.expectType != nil { - assert.True(t, errors.Is(err, tc.expectType)) - } - }) - } -} - -func TestMultistoreSnapshotRestore(t *testing.T) { - source := newMultiStoreWithMixedMountsAndBasicData(dbm.NewMemDB()) - target := newMultiStoreWithMixedMounts(dbm.NewMemDB()) - version := uint64(source.LastCommitID().Version) - require.EqualValues(t, 3, version) - - chunks, err := source.Snapshot(version, snapshottypes.CurrentFormat) - require.NoError(t, err) - ready := make(chan struct{}) - err = target.Restore(version, snapshottypes.CurrentFormat, chunks, ready) - require.NoError(t, err) - assert.EqualValues(t, struct{}{}, <-ready) - - assert.Equal(t, source.LastCommitID(), target.LastCommitID()) - for key, sourceStore := range source.stores { - targetStore := target.getStoreByName(key.Name()).(types.CommitKVStore) - switch sourceStore.GetStoreType() { - case types.StoreTypeTransient: - assert.False(t, targetStore.Iterator(nil, nil).Valid(), - "transient store %v not empty", key.Name()) - default: - assertStoresEqual(t, sourceStore, targetStore, "store %q not equal", key.Name()) - } - } -} - func TestSetInitialVersion(t *testing.T) { db := dbm.NewMemDB() multi := newMultiStoreWithMounts(db, types.PruneNothing) @@ -853,79 +730,6 @@ func TestTraceConcurrency(t *testing.T) { stopW <- struct{}{} } -func BenchmarkMultistoreSnapshot100K(b *testing.B) { - benchmarkMultistoreSnapshot(b, 10, 10000) -} - -func BenchmarkMultistoreSnapshot1M(b *testing.B) { - benchmarkMultistoreSnapshot(b, 10, 100000) -} - -func BenchmarkMultistoreSnapshotRestore100K(b *testing.B) { - benchmarkMultistoreSnapshotRestore(b, 10, 10000) -} - -func BenchmarkMultistoreSnapshotRestore1M(b *testing.B) { - benchmarkMultistoreSnapshotRestore(b, 10, 100000) -} - -func benchmarkMultistoreSnapshot(b *testing.B, stores uint8, storeKeys uint64) { - b.Skip("Noisy with slow setup time, please see https://github.com/cosmos/cosmos-sdk/issues/8855.") - - b.ReportAllocs() - b.StopTimer() - source := newMultiStoreWithGeneratedData(dbm.NewMemDB(), stores, storeKeys) - version := source.LastCommitID().Version - require.EqualValues(b, 1, version) - b.StartTimer() - - for i := 0; i < b.N; i++ { - target := NewStore(dbm.NewMemDB()) - for key := range source.stores { - target.MountStoreWithDB(key, types.StoreTypeIAVL, nil) - } - err := target.LoadLatestVersion() - require.NoError(b, err) - require.EqualValues(b, 0, target.LastCommitID().Version) - - chunks, err := source.Snapshot(uint64(version), snapshottypes.CurrentFormat) - require.NoError(b, err) - for reader := range chunks { - _, err := io.Copy(io.Discard, reader) - require.NoError(b, err) - err = reader.Close() - require.NoError(b, err) - } - } -} - -func benchmarkMultistoreSnapshotRestore(b *testing.B, stores uint8, storeKeys uint64) { - b.Skip("Noisy with slow setup time, please see https://github.com/cosmos/cosmos-sdk/issues/8855.") - - b.ReportAllocs() - b.StopTimer() - source := newMultiStoreWithGeneratedData(dbm.NewMemDB(), stores, storeKeys) - version := uint64(source.LastCommitID().Version) - require.EqualValues(b, 1, version) - b.StartTimer() - - for i := 0; i < b.N; i++ { - target := NewStore(dbm.NewMemDB()) - for key := range source.stores { - target.MountStoreWithDB(key, types.StoreTypeIAVL, nil) - } - err := target.LoadLatestVersion() - require.NoError(b, err) - require.EqualValues(b, 0, target.LastCommitID().Version) - - chunks, err := source.Snapshot(version, snapshottypes.CurrentFormat) - require.NoError(b, err) - err = target.Restore(version, snapshottypes.CurrentFormat, chunks, nil) - require.NoError(b, err) - require.Equal(b, source.LastCommitID(), target.LastCommitID()) - } -} - //----------------------------------------------------------------------- // utils @@ -946,75 +750,6 @@ func newMultiStoreWithMounts(db dbm.DB, pruningOpts types.PruningOptions) *Store return store } -func newMultiStoreWithMixedMounts(db dbm.DB) *Store { - store := NewStore(db) - store.MountStoreWithDB(types.NewKVStoreKey("iavl1"), types.StoreTypeIAVL, nil) - store.MountStoreWithDB(types.NewKVStoreKey("iavl2"), types.StoreTypeIAVL, nil) - store.MountStoreWithDB(types.NewKVStoreKey("iavl3"), types.StoreTypeIAVL, nil) - store.MountStoreWithDB(types.NewTransientStoreKey("trans1"), types.StoreTypeTransient, nil) - store.LoadLatestVersion() - - return store -} - -func newMultiStoreWithMixedMountsAndBasicData(db dbm.DB) *Store { - store := newMultiStoreWithMixedMounts(db) - store1 := store.getStoreByName("iavl1").(types.CommitKVStore) - store2 := store.getStoreByName("iavl2").(types.CommitKVStore) - trans1 := store.getStoreByName("trans1").(types.KVStore) - - store1.Set([]byte("a"), []byte{1}) - store1.Set([]byte("b"), []byte{1}) - store2.Set([]byte("X"), []byte{255}) - store2.Set([]byte("A"), []byte{101}) - trans1.Set([]byte("x1"), []byte{91}) - store.Commit() - - store1.Set([]byte("b"), []byte{2}) - store1.Set([]byte("c"), []byte{3}) - store2.Set([]byte("B"), []byte{102}) - store.Commit() - - store2.Set([]byte("C"), []byte{103}) - store2.Delete([]byte("X")) - trans1.Set([]byte("x2"), []byte{92}) - store.Commit() - - return store -} - -func newMultiStoreWithGeneratedData(db dbm.DB, stores uint8, storeKeys uint64) *Store { - multiStore := NewStore(db) - r := rand.New(rand.NewSource(49872768940)) // Fixed seed for deterministic tests - - keys := []*types.KVStoreKey{} - for i := uint8(0); i < stores; i++ { - key := types.NewKVStoreKey(fmt.Sprintf("store%v", i)) - multiStore.MountStoreWithDB(key, types.StoreTypeIAVL, nil) - keys = append(keys, key) - } - multiStore.LoadLatestVersion() - - for _, key := range keys { - store := multiStore.stores[key].(*iavl.Store) - for i := uint64(0); i < storeKeys; i++ { - k := make([]byte, 8) - v := make([]byte, 1024) - binary.BigEndian.PutUint64(k, i) - _, err := r.Read(v) - if err != nil { - panic(err) - } - store.Set(k, v) - } - } - - multiStore.Commit() - multiStore.LoadLatestVersion() - - return multiStore -} - func newMultiStoreWithModifiedMounts(db dbm.DB, pruningOpts types.PruningOptions) (*Store, *types.StoreUpgrades) { store := NewStore(db) store.pruningOpts = pruningOpts @@ -1036,25 +771,6 @@ func newMultiStoreWithModifiedMounts(db dbm.DB, pruningOpts types.PruningOptions return store, upgrades } -func assertStoresEqual(t *testing.T, expect, actual types.CommitKVStore, msgAndArgs ...interface{}) { - assert.Equal(t, expect.LastCommitID(), actual.LastCommitID()) - expectIter := expect.Iterator(nil, nil) - expectMap := map[string][]byte{} - for ; expectIter.Valid(); expectIter.Next() { - expectMap[string(expectIter.Key())] = expectIter.Value() - } - require.NoError(t, expectIter.Error()) - - actualIter := expect.Iterator(nil, nil) - actualMap := map[string][]byte{} - for ; actualIter.Valid(); actualIter.Next() { - actualMap[string(actualIter.Key())] = actualIter.Value() - } - require.NoError(t, actualIter.Error()) - - assert.Equal(t, expectMap, actualMap, msgAndArgs...) -} - func checkStore(t *testing.T, store *Store, expect, got types.CommitID) { require.Equal(t, expect, got) require.Equal(t, expect, store.LastCommitID()) diff --git a/store/types/snapshot.pb.go b/store/types/snapshot.pb.go index 6f001da1bf28..f0b7da06dbbd 100644 --- a/store/types/snapshot.pb.go +++ b/store/types/snapshot.pb.go @@ -30,6 +30,8 @@ type SnapshotItem struct { // Types that are valid to be assigned to Item: // *SnapshotItem_Store // *SnapshotItem_IAVL + // *SnapshotItem_Extension + // *SnapshotItem_ExtensionPayload Item isSnapshotItem_Item `protobuf_oneof:"item"` } @@ -78,9 +80,17 @@ type SnapshotItem_Store struct { type SnapshotItem_IAVL struct { IAVL *SnapshotIAVLItem `protobuf:"bytes,2,opt,name=iavl,proto3,oneof" json:"iavl,omitempty"` } +type SnapshotItem_Extension struct { + Extension *SnapshotExtensionMeta `protobuf:"bytes,3,opt,name=extension,proto3,oneof" json:"extension,omitempty"` +} +type SnapshotItem_ExtensionPayload struct { + ExtensionPayload *SnapshotExtensionPayload `protobuf:"bytes,4,opt,name=extension_payload,json=extensionPayload,proto3,oneof" json:"extension_payload,omitempty"` +} -func (*SnapshotItem_Store) isSnapshotItem_Item() {} -func (*SnapshotItem_IAVL) isSnapshotItem_Item() {} +func (*SnapshotItem_Store) isSnapshotItem_Item() {} +func (*SnapshotItem_IAVL) isSnapshotItem_Item() {} +func (*SnapshotItem_Extension) isSnapshotItem_Item() {} +func (*SnapshotItem_ExtensionPayload) isSnapshotItem_Item() {} func (m *SnapshotItem) GetItem() isSnapshotItem_Item { if m != nil { @@ -103,11 +113,27 @@ func (m *SnapshotItem) GetIAVL() *SnapshotIAVLItem { return nil } +func (m *SnapshotItem) GetExtension() *SnapshotExtensionMeta { + if x, ok := m.GetItem().(*SnapshotItem_Extension); ok { + return x.Extension + } + return nil +} + +func (m *SnapshotItem) GetExtensionPayload() *SnapshotExtensionPayload { + if x, ok := m.GetItem().(*SnapshotItem_ExtensionPayload); ok { + return x.ExtensionPayload + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*SnapshotItem) XXX_OneofWrappers() []interface{} { return []interface{}{ (*SnapshotItem_Store)(nil), (*SnapshotItem_IAVL)(nil), + (*SnapshotItem_Extension)(nil), + (*SnapshotItem_ExtensionPayload)(nil), } } @@ -225,10 +251,110 @@ func (m *SnapshotIAVLItem) GetHeight() int32 { return 0 } +// SnapshotExtensionMeta contains metadata about an external snapshotter. +type SnapshotExtensionMeta struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Format int32 `protobuf:"varint,2,opt,name=format,proto3" json:"format,omitempty"` +} + +func (m *SnapshotExtensionMeta) Reset() { *m = SnapshotExtensionMeta{} } +func (m *SnapshotExtensionMeta) String() string { return proto.CompactTextString(m) } +func (*SnapshotExtensionMeta) ProtoMessage() {} +func (*SnapshotExtensionMeta) Descriptor() ([]byte, []int) { + return fileDescriptor_9c55879db4cc4502, []int{3} +} +func (m *SnapshotExtensionMeta) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SnapshotExtensionMeta) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SnapshotExtensionMeta.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 *SnapshotExtensionMeta) XXX_Merge(src proto.Message) { + xxx_messageInfo_SnapshotExtensionMeta.Merge(m, src) +} +func (m *SnapshotExtensionMeta) XXX_Size() int { + return m.Size() +} +func (m *SnapshotExtensionMeta) XXX_DiscardUnknown() { + xxx_messageInfo_SnapshotExtensionMeta.DiscardUnknown(m) +} + +var xxx_messageInfo_SnapshotExtensionMeta proto.InternalMessageInfo + +func (m *SnapshotExtensionMeta) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *SnapshotExtensionMeta) GetFormat() int32 { + if m != nil { + return m.Format + } + return 0 +} + +// SnapshotExtensionPayload contains payloads of an external snapshotter. +type SnapshotExtensionPayload struct { + Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (m *SnapshotExtensionPayload) Reset() { *m = SnapshotExtensionPayload{} } +func (m *SnapshotExtensionPayload) String() string { return proto.CompactTextString(m) } +func (*SnapshotExtensionPayload) ProtoMessage() {} +func (*SnapshotExtensionPayload) Descriptor() ([]byte, []int) { + return fileDescriptor_9c55879db4cc4502, []int{4} +} +func (m *SnapshotExtensionPayload) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SnapshotExtensionPayload) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SnapshotExtensionPayload.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 *SnapshotExtensionPayload) XXX_Merge(src proto.Message) { + xxx_messageInfo_SnapshotExtensionPayload.Merge(m, src) +} +func (m *SnapshotExtensionPayload) XXX_Size() int { + return m.Size() +} +func (m *SnapshotExtensionPayload) XXX_DiscardUnknown() { + xxx_messageInfo_SnapshotExtensionPayload.DiscardUnknown(m) +} + +var xxx_messageInfo_SnapshotExtensionPayload proto.InternalMessageInfo + +func (m *SnapshotExtensionPayload) GetPayload() []byte { + if m != nil { + return m.Payload + } + return nil +} + func init() { proto.RegisterType((*SnapshotItem)(nil), "cosmos.base.store.v1beta1.SnapshotItem") proto.RegisterType((*SnapshotStoreItem)(nil), "cosmos.base.store.v1beta1.SnapshotStoreItem") proto.RegisterType((*SnapshotIAVLItem)(nil), "cosmos.base.store.v1beta1.SnapshotIAVLItem") + proto.RegisterType((*SnapshotExtensionMeta)(nil), "cosmos.base.store.v1beta1.SnapshotExtensionMeta") + proto.RegisterType((*SnapshotExtensionPayload)(nil), "cosmos.base.store.v1beta1.SnapshotExtensionPayload") } func init() { @@ -236,28 +362,33 @@ func init() { } var fileDescriptor_9c55879db4cc4502 = []byte{ - // 324 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x91, 0xc1, 0x4a, 0xc3, 0x30, - 0x18, 0xc7, 0x1b, 0xd7, 0x4d, 0xfd, 0xdc, 0x61, 0x86, 0x21, 0xd5, 0x43, 0x1d, 0xbb, 0x58, 0x50, - 0x13, 0xa6, 0x4f, 0x60, 0xf1, 0xb0, 0xa1, 0xa7, 0x0c, 0x3c, 0x78, 0x4b, 0x67, 0x68, 0xcb, 0xd6, - 0x65, 0x2c, 0x59, 0x61, 0x6f, 0xe1, 0x6b, 0xf8, 0x26, 0x1e, 0x77, 0xf4, 0x24, 0xd2, 0xbd, 0x88, - 0x24, 0xe9, 0x2e, 0x8a, 0xe0, 0xa9, 0xdf, 0xbf, 0xfc, 0xfe, 0xbf, 0x7c, 0xf0, 0x41, 0x34, 0x91, - 0xaa, 0x90, 0x8a, 0x26, 0x5c, 0x09, 0xaa, 0xb4, 0x5c, 0x0a, 0x5a, 0x0e, 0x12, 0xa1, 0xf9, 0x80, - 0xaa, 0x39, 0x5f, 0xa8, 0x4c, 0x6a, 0xb2, 0x58, 0x4a, 0x2d, 0xf1, 0xa9, 0x23, 0x89, 0x21, 0x89, - 0x25, 0x49, 0x4d, 0x9e, 0x75, 0x53, 0x99, 0x4a, 0x4b, 0x51, 0x33, 0xb9, 0x42, 0xff, 0x0d, 0x41, - 0x7b, 0x5c, 0x3b, 0x46, 0x5a, 0x14, 0xf8, 0x1e, 0x9a, 0xb6, 0x17, 0xa0, 0x1e, 0x8a, 0x8e, 0x6e, - 0xae, 0xc8, 0x9f, 0x46, 0xb2, 0xeb, 0x8d, 0xcd, 0x5f, 0x53, 0x1e, 0x7a, 0xcc, 0x95, 0xf1, 0x03, - 0xf8, 0x39, 0x2f, 0x67, 0xc1, 0x9e, 0x95, 0x5c, 0xfe, 0x43, 0x32, 0xba, 0x7b, 0x7a, 0x34, 0x8e, - 0xf8, 0xa0, 0xfa, 0x3c, 0xf7, 0x4d, 0x1a, 0x7a, 0xcc, 0x4a, 0xe2, 0x16, 0xf8, 0xb9, 0x16, 0x45, - 0xff, 0x02, 0x8e, 0x7f, 0x3d, 0x89, 0x31, 0xf8, 0x73, 0x5e, 0xb8, 0x75, 0x0f, 0x99, 0x9d, 0xfb, - 0x33, 0xe8, 0xfc, 0xd4, 0xe2, 0x0e, 0x34, 0xa6, 0x62, 0x6d, 0xb1, 0x36, 0x33, 0x23, 0xee, 0x42, - 0xb3, 0xe4, 0xb3, 0x95, 0xb0, 0x4b, 0xb6, 0x99, 0x0b, 0x38, 0x80, 0xfd, 0x52, 0x2c, 0x55, 0x2e, - 0xe7, 0x41, 0xa3, 0x87, 0xa2, 0x06, 0xdb, 0x45, 0x7c, 0x02, 0xad, 0x4c, 0xe4, 0x69, 0xa6, 0x03, - 0xbf, 0x87, 0xa2, 0x26, 0xab, 0x53, 0x1c, 0xbf, 0x57, 0x21, 0xda, 0x54, 0x21, 0xfa, 0xaa, 0x42, - 0xf4, 0xba, 0x0d, 0xbd, 0xcd, 0x36, 0xf4, 0x3e, 0xb6, 0xa1, 0xf7, 0x1c, 0xa5, 0xb9, 0xce, 0x56, - 0x09, 0x99, 0xc8, 0x82, 0xd6, 0x27, 0x74, 0x9f, 0x6b, 0xf5, 0x32, 0xad, 0x0f, 0xa9, 0xd7, 0x0b, - 0xa1, 0x92, 0x96, 0xbd, 0xc6, 0xed, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x75, 0x87, 0x24, 0x7b, - 0xea, 0x01, 0x00, 0x00, + // 409 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xc1, 0xae, 0x93, 0x40, + 0x14, 0x86, 0xe1, 0x16, 0xaa, 0xf7, 0xd8, 0x45, 0xef, 0xe4, 0x6a, 0xd0, 0x05, 0x1a, 0x36, 0x36, + 0x51, 0xc1, 0xeb, 0xf5, 0x05, 0x44, 0x4d, 0xb8, 0x51, 0x93, 0x66, 0x9a, 0xb8, 0x70, 0x63, 0x86, + 0x76, 0x04, 0x52, 0x60, 0x08, 0x33, 0x25, 0xf6, 0x2d, 0x7c, 0x2c, 0x97, 0x5d, 0xba, 0x52, 0x43, + 0x5f, 0xc4, 0xcc, 0x0c, 0xd4, 0xa4, 0xb6, 0x49, 0x5d, 0xf5, 0xfc, 0x93, 0xff, 0xff, 0x7a, 0xf8, + 0x73, 0x60, 0x32, 0x67, 0xbc, 0x60, 0x3c, 0x88, 0x09, 0xa7, 0x01, 0x17, 0xac, 0xa6, 0x41, 0x73, + 0x15, 0x53, 0x41, 0xae, 0x02, 0x5e, 0x92, 0x8a, 0xa7, 0x4c, 0xf8, 0x55, 0xcd, 0x04, 0x43, 0xf7, + 0xb5, 0xd3, 0x97, 0x4e, 0x5f, 0x39, 0xfd, 0xce, 0xf9, 0xe0, 0x32, 0x61, 0x09, 0x53, 0xae, 0x40, + 0x4e, 0x3a, 0xe0, 0xfd, 0x3a, 0x83, 0xd1, 0xac, 0x63, 0xdc, 0x08, 0x5a, 0xa0, 0x37, 0x60, 0xab, + 0x9c, 0x63, 0x3e, 0x32, 0x27, 0x77, 0x5e, 0x3c, 0xf5, 0x8f, 0x12, 0xfd, 0x3e, 0x37, 0x93, 0xaf, + 0x32, 0x1c, 0x19, 0x58, 0x87, 0xd1, 0x3b, 0xb0, 0x32, 0xd2, 0xe4, 0xce, 0x99, 0x82, 0x3c, 0x39, + 0x01, 0x72, 0xf3, 0xea, 0xe3, 0x7b, 0xc9, 0x08, 0x6f, 0xb7, 0x3f, 0x1f, 0x5a, 0x52, 0x45, 0x06, + 0x56, 0x10, 0x34, 0x85, 0x73, 0xfa, 0x55, 0xd0, 0x92, 0x67, 0xac, 0x74, 0x06, 0x8a, 0xf8, 0xfc, + 0x04, 0xe2, 0xdb, 0x3e, 0xf3, 0x81, 0x0a, 0x12, 0x19, 0xf8, 0x2f, 0x04, 0xc5, 0x70, 0xb1, 0x13, + 0x9f, 0x2b, 0xb2, 0xce, 0x19, 0x59, 0x38, 0x96, 0x22, 0x5f, 0xff, 0x0f, 0x79, 0xaa, 0xa3, 0x91, + 0x81, 0xc7, 0x74, 0xef, 0x2d, 0x1c, 0x82, 0x95, 0x09, 0x5a, 0x78, 0x8f, 0xe1, 0xe2, 0x9f, 0xa2, + 0x10, 0x02, 0xab, 0x24, 0x85, 0x2e, 0xf9, 0x1c, 0xab, 0xd9, 0xcb, 0x61, 0xbc, 0x5f, 0x06, 0x1a, + 0xc3, 0x60, 0x49, 0xd7, 0xca, 0x36, 0xc2, 0x72, 0x44, 0x97, 0x60, 0x37, 0x24, 0x5f, 0x51, 0x55, + 0xed, 0x08, 0x6b, 0x81, 0x1c, 0xb8, 0xd5, 0xd0, 0x7a, 0x57, 0xd0, 0x00, 0xf7, 0x12, 0xdd, 0x83, + 0x61, 0x4a, 0xb3, 0x24, 0x15, 0xea, 0xfb, 0x6c, 0xdc, 0x29, 0xef, 0x35, 0xdc, 0x3d, 0x58, 0xd4, + 0xa1, 0xd5, 0x24, 0xe4, 0x0b, 0xab, 0x0b, 0x22, 0xd4, 0xbf, 0xda, 0xb8, 0x53, 0xde, 0x4b, 0x70, + 0x8e, 0x75, 0x22, 0x57, 0xea, 0x9b, 0xd5, 0xeb, 0xf7, 0x32, 0x0c, 0xbf, 0xb7, 0xae, 0xb9, 0x69, + 0x5d, 0xf3, 0x77, 0xeb, 0x9a, 0xdf, 0xb6, 0xae, 0xb1, 0xd9, 0xba, 0xc6, 0x8f, 0xad, 0x6b, 0x7c, + 0x9a, 0x24, 0x99, 0x48, 0x57, 0xb1, 0x3f, 0x67, 0x45, 0xd0, 0xdd, 0xbc, 0xfe, 0x79, 0xc6, 0x17, + 0xcb, 0xee, 0xf2, 0xc5, 0xba, 0xa2, 0x3c, 0x1e, 0xaa, 0xf3, 0xbd, 0xfe, 0x13, 0x00, 0x00, 0xff, + 0xff, 0x21, 0xfd, 0xa5, 0x3f, 0x1b, 0x03, 0x00, 0x00, } func (m *SnapshotItem) Marshal() (dAtA []byte, err error) { @@ -334,6 +465,48 @@ func (m *SnapshotItem_IAVL) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } +func (m *SnapshotItem_Extension) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotItem_Extension) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Extension != nil { + { + size, err := m.Extension.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSnapshot(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} +func (m *SnapshotItem_ExtensionPayload) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotItem_ExtensionPayload) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.ExtensionPayload != nil { + { + size, err := m.ExtensionPayload.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSnapshot(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + return len(dAtA) - i, nil +} func (m *SnapshotStoreItem) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -411,6 +584,71 @@ func (m *SnapshotIAVLItem) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *SnapshotExtensionMeta) 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 *SnapshotExtensionMeta) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotExtensionMeta) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Format != 0 { + i = encodeVarintSnapshot(dAtA, i, uint64(m.Format)) + i-- + dAtA[i] = 0x10 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintSnapshot(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SnapshotExtensionPayload) 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 *SnapshotExtensionPayload) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SnapshotExtensionPayload) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Payload) > 0 { + i -= len(m.Payload) + copy(dAtA[i:], m.Payload) + i = encodeVarintSnapshot(dAtA, i, uint64(len(m.Payload))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func encodeVarintSnapshot(dAtA []byte, offset int, v uint64) int { offset -= sovSnapshot(v) base := offset @@ -458,6 +696,30 @@ func (m *SnapshotItem_IAVL) Size() (n int) { } return n } +func (m *SnapshotItem_Extension) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Extension != nil { + l = m.Extension.Size() + n += 1 + l + sovSnapshot(uint64(l)) + } + return n +} +func (m *SnapshotItem_ExtensionPayload) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ExtensionPayload != nil { + l = m.ExtensionPayload.Size() + n += 1 + l + sovSnapshot(uint64(l)) + } + return n +} func (m *SnapshotStoreItem) Size() (n int) { if m == nil { return 0 @@ -494,6 +756,35 @@ func (m *SnapshotIAVLItem) Size() (n int) { return n } +func (m *SnapshotExtensionMeta) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovSnapshot(uint64(l)) + } + if m.Format != 0 { + n += 1 + sovSnapshot(uint64(m.Format)) + } + return n +} + +func (m *SnapshotExtensionPayload) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Payload) + if l > 0 { + n += 1 + l + sovSnapshot(uint64(l)) + } + return n +} + func sovSnapshot(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -599,6 +890,76 @@ func (m *SnapshotItem) Unmarshal(dAtA []byte) error { } m.Item = &SnapshotItem_IAVL{v} iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Extension", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SnapshotExtensionMeta{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Item = &SnapshotItem_Extension{v} + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExtensionPayload", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := &SnapshotExtensionPayload{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Item = &SnapshotItem_ExtensionPayload{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipSnapshot(dAtA[iNdEx:]) @@ -858,6 +1219,191 @@ func (m *SnapshotIAVLItem) Unmarshal(dAtA []byte) error { } return nil } +func (m *SnapshotExtensionMeta) 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 ErrIntOverflowSnapshot + } + 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: SnapshotExtensionMeta: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotExtensionMeta: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + 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 ErrInvalidLengthSnapshot + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Format", wireType) + } + m.Format = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Format |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipSnapshot(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSnapshot + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SnapshotExtensionPayload) 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 ErrIntOverflowSnapshot + } + 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: SnapshotExtensionPayload: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SnapshotExtensionPayload: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSnapshot + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSnapshot + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthSnapshot + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Payload = append(m.Payload[:0], dAtA[iNdEx:postIndex]...) + if m.Payload == nil { + m.Payload = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSnapshot(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSnapshot + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipSnapshot(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/store/v2/multi/store.go b/store/v2/multi/store.go index 5ad1e33fa6af..5a53f5502a85 100644 --- a/store/v2/multi/store.go +++ b/store/v2/multi/store.go @@ -13,6 +13,7 @@ import ( dbm "github.com/cosmos/cosmos-sdk/db" prefixdb "github.com/cosmos/cosmos-sdk/db/prefix" util "github.com/cosmos/cosmos-sdk/internal" + snapshottypes "github.com/cosmos/cosmos-sdk/snapshots/types" sdkmaps "github.com/cosmos/cosmos-sdk/store/internal/maps" "github.com/cosmos/cosmos-sdk/store/listenkv" "github.com/cosmos/cosmos-sdk/store/prefix" @@ -23,6 +24,7 @@ import ( "github.com/cosmos/cosmos-sdk/store/v2/transient" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/kv" + protoio "github.com/gogo/protobuf/io" ) var ( @@ -902,9 +904,11 @@ func (tlm *traceListenMixin) wrapTraceListen(store types.KVStore, skey types.Sto func (s *Store) GetPruning() types.PruningOptions { return s.Pruning } func (s *Store) SetPruning(po types.PruningOptions) { s.Pruning = po } -func (rs *Store) Restore(height uint64, format uint32, chunks <-chan io.ReadCloser, ready chan<- struct{}) error { - return nil +func (rs *Store) Restore( + height uint64, format uint32, protoReader protoio.Reader, +) (snapshottypes.SnapshotItem, error) { + return snapshottypes.SnapshotItem{}, nil } -func (rs *Store) Snapshot(height uint64, format uint32) (<-chan io.ReadCloser, error) { - return nil, nil +func (rs *Store) Snapshot(height uint64, protoWriter protoio.Writer) error { + return nil } From 80862d1aa2bf5654a17ace0bdb70c8231acba19b Mon Sep 17 00:00:00 2001 From: yihuang Date: Tue, 22 Feb 2022 10:11:04 +0800 Subject: [PATCH 02/10] Update snapshots/stream.go Co-authored-by: Robert Zaremba --- snapshots/stream.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snapshots/stream.go b/snapshots/stream.go index 68f7be0ad50d..a4956a4c1c48 100644 --- a/snapshots/stream.go +++ b/snapshots/stream.go @@ -26,7 +26,7 @@ type StreamWriter struct { protoWriter protoio.WriteCloser } -// NewStreamWriter set up a stream pipeline to serialize snapshot nodes. +// NewStreamWriter set up a stream pipeline to serialize snapshot DB records. func NewStreamWriter(ch chan<- io.ReadCloser) *StreamWriter { chunkWriter := NewChunkWriter(ch, snapshotChunkSize) bufWriter := bufio.NewWriterSize(chunkWriter, snapshotBufferSize) From 7190df23f99f2dd6d5f64c3895e0aa0db1e8285e Mon Sep 17 00:00:00 2001 From: HuangYi Date: Tue, 22 Feb 2022 10:30:22 +0800 Subject: [PATCH 03/10] fix review suggestions --- snapshots/stream.go | 6 ++++-- snapshots/types/snapshotter.go | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/snapshots/stream.go b/snapshots/stream.go index a4956a4c1c48..80cd5c3dfdcb 100644 --- a/snapshots/stream.go +++ b/snapshots/stream.go @@ -15,10 +15,12 @@ const ( // Do not change chunk size without new snapshot format (must be uniform across nodes) snapshotChunkSize = uint64(10e6) snapshotBufferSize = int(snapshotChunkSize) + // Do not change compression level without new snapshot format (must be uniform across nodes) + snapshotCompressionLevel = 7 ) // StreamWriter set up a stream pipeline to serialize snapshot nodes: -// ExportNode -> delimited Protobuf -> zlib -> buffer -> chunkWriter -> chan io.ReadCloser +// Exported Items -> delimited Protobuf -> zlib -> buffer -> chunkWriter -> chan io.ReadCloser type StreamWriter struct { chunkWriter *ChunkWriter bufWriter *bufio.Writer @@ -30,7 +32,7 @@ type StreamWriter struct { func NewStreamWriter(ch chan<- io.ReadCloser) *StreamWriter { chunkWriter := NewChunkWriter(ch, snapshotChunkSize) bufWriter := bufio.NewWriterSize(chunkWriter, snapshotBufferSize) - zWriter, err := zlib.NewWriterLevel(bufWriter, 7) + zWriter, err := zlib.NewWriterLevel(bufWriter, snapshotCompressionLevel) if err != nil { chunkWriter.CloseWithError(sdkerrors.Wrap(err, "zlib failure")) return nil diff --git a/snapshots/types/snapshotter.go b/snapshots/types/snapshotter.go index b802db9f1085..f747920d13ad 100644 --- a/snapshots/types/snapshotter.go +++ b/snapshots/types/snapshotter.go @@ -25,7 +25,9 @@ type ExtensionSnapshotter interface { // SnapshotName returns the name of snapshotter, it should be unique in the manager. SnapshotName() string - // SnapshotFormat returns the default format used to take a snapshot. + // SnapshotFormat returns the default format the extension snapshotter use to encode the + // payloads when taking a snapshot. + // It's defined within the extension, different from the global format for the whole state-sync snapshot. SnapshotFormat() uint32 // SupportedFormats returns a list of formats it can restore from. From 893a661311b4b87d60d937e1cf1facf864e15b71 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Tue, 22 Feb 2022 11:12:12 +0800 Subject: [PATCH 04/10] refactor inner restore function to a method --- snapshots/manager.go | 115 ++++++++++++++++++------------------------- 1 file changed, 49 insertions(+), 66 deletions(-) diff --git a/snapshots/manager.go b/snapshots/manager.go index 5e8a85495b4d..437f448e948e 100644 --- a/snapshots/manager.go +++ b/snapshots/manager.go @@ -237,66 +237,24 @@ func (m *Manager) Restore(snapshot types.Snapshot) error { return err } + // check multistore supported format preemptive + if snapshot.Format != types.CurrentFormat { + return sdkerrors.Wrapf(types.ErrUnknownFormat, "snapshot format %v", snapshot.Format) + } + if snapshot.Height == 0 { + return sdkerrors.Wrap(sdkerrors.ErrLogic, "cannot restore snapshot at height 0") + } + if snapshot.Height > uint64(math.MaxInt64) { + return sdkerrors.Wrapf(types.ErrInvalidMetadata, + "snapshot height %v cannot exceed %v", snapshot.Height, int64(math.MaxInt64)) + } + // Start an asynchronous snapshot restoration, passing chunks and completion status via channels. chChunks := make(chan io.ReadCloser, chunkBufferSize) - chReady := make(chan struct{}, 1) chDone := make(chan restoreDone, 1) - doRestore := func() error { - // check multistore supported format preemptive - if snapshot.Format != types.CurrentFormat { - return sdkerrors.Wrapf(types.ErrUnknownFormat, "snapshot format %v", snapshot.Format) - } - if snapshot.Height == 0 { - return sdkerrors.Wrap(sdkerrors.ErrLogic, "cannot restore snapshot at height 0") - } - if snapshot.Height > uint64(math.MaxInt64) { - return sdkerrors.Wrapf(types.ErrInvalidMetadata, - "snapshot height %v cannot exceed %v", snapshot.Height, int64(math.MaxInt64)) - } - - // Signal readiness. Must be done before the readers below are set up, since the zlib - // reader reads from the stream on initialization, potentially causing deadlocks. - if chReady != nil { - close(chReady) - } - - streamReader, err := NewStreamReader(chChunks) - if err != nil { - return err - } - defer streamReader.Close() - - next, err := m.multistore.Restore(snapshot.Height, snapshot.Format, streamReader) - if err != nil { - return sdkerrors.Wrap(err, "multistore restore") - } - for { - if next.Item == nil { - // end of stream - break - } - metadata := next.GetExtension() - if metadata == nil { - return sdkerrors.Wrapf(sdkerrors.ErrLogic, "unknown snapshot item %T", next.Item) - } - extension, ok := m.extensions[metadata.Name] - if !ok { - return sdkerrors.Wrapf(sdkerrors.ErrLogic, "unknown extension snapshotter %s", metadata.Name) - } - if !IsFormatSupported(extension, metadata.Format) { - return sdkerrors.Wrapf(types.ErrUnknownFormat, "format %v for extension %s", metadata.Format, metadata.Name) - } - next, err = extension.Restore(snapshot.Height, metadata.Format, streamReader) - if err != nil { - return sdkerrors.Wrapf(err, "extension %s restore", metadata.Name) - } - } - return nil - } - go func() { - err := doRestore() + err := m.restore(snapshot, chChunks) chDone <- restoreDone{ complete: err == nil, err: err, @@ -304,17 +262,6 @@ func (m *Manager) Restore(snapshot types.Snapshot) error { close(chDone) }() - // Check for any initial errors from the restore, before any chunks are fed. - select { - case done := <-chDone: - m.endLocked() - if done.err != nil { - return done.err - } - return sdkerrors.Wrap(sdkerrors.ErrLogic, "restore ended unexpectedly") - case <-chReady: - } - m.chRestore = chChunks m.chRestoreDone = chDone m.restoreChunkHashes = snapshot.Metadata.ChunkHashes @@ -322,6 +269,42 @@ func (m *Manager) Restore(snapshot types.Snapshot) error { return nil } +// restore do the heavy work of snapshot restoration after preliminary checks on request have passed. +func (m *Manager) restore(snapshot types.Snapshot, chChunks <-chan io.ReadCloser) error { + streamReader, err := NewStreamReader(chChunks) + if err != nil { + return err + } + defer streamReader.Close() + + next, err := m.multistore.Restore(snapshot.Height, snapshot.Format, streamReader) + if err != nil { + return sdkerrors.Wrap(err, "multistore restore") + } + for { + if next.Item == nil { + // end of stream + break + } + metadata := next.GetExtension() + if metadata == nil { + return sdkerrors.Wrapf(sdkerrors.ErrLogic, "unknown snapshot item %T", next.Item) + } + extension, ok := m.extensions[metadata.Name] + if !ok { + return sdkerrors.Wrapf(sdkerrors.ErrLogic, "unknown extension snapshotter %s", metadata.Name) + } + if !IsFormatSupported(extension, metadata.Format) { + return sdkerrors.Wrapf(types.ErrUnknownFormat, "format %v for extension %s", metadata.Format, metadata.Name) + } + next, err = extension.Restore(snapshot.Height, metadata.Format, streamReader) + if err != nil { + return sdkerrors.Wrapf(err, "extension %s restore", metadata.Name) + } + } + return nil +} + // RestoreChunk adds a chunk to an active snapshot restoration, mirroring ABCI ApplySnapshotChunk. // Chunks must be given until the restore is complete, returning true, or a chunk errors. func (m *Manager) RestoreChunk(chunk []byte) (bool, error) { From 9aa2b2444753aab00371996d97c60f15604fb870 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Tue, 22 Feb 2022 11:16:55 +0800 Subject: [PATCH 05/10] refactor createSnapshot to separated method --- snapshots/manager.go | 66 +++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/snapshots/manager.go b/snapshots/manager.go index 437f448e948e..2490e17ae6d9 100644 --- a/snapshots/manager.go +++ b/snapshots/manager.go @@ -154,39 +154,43 @@ func (m *Manager) Create(height uint64) (*types.Snapshot, error) { // Spawn goroutine to generate snapshot chunks and pass their io.ReadClosers through a channel ch := make(chan io.ReadCloser) - go func() { - streamWriter := NewStreamWriter(ch) - if streamWriter == nil { + go m.createSnapshot(height, ch) + + return m.store.Save(height, types.CurrentFormat, ch) +} + +// createSnapshot do the heavy work of snapshotting after the validations of request are done +// the produced chunks are written to the channel. +func (m *Manager) createSnapshot(height uint64, ch chan<- io.ReadCloser) { + streamWriter := NewStreamWriter(ch) + if streamWriter == nil { + return + } + defer streamWriter.Close() + if err := m.multistore.Snapshot(height, streamWriter); err != nil { + streamWriter.CloseWithError(err) + return + } + for _, name := range m.sortedExtensionNames() { + extension := m.extensions[name] + // write extension metadata + err := streamWriter.WriteMsg(&types.SnapshotItem{ + Item: &types.SnapshotItem_Extension{ + Extension: &types.SnapshotExtensionMeta{ + Name: name, + Format: extension.SnapshotFormat(), + }, + }, + }) + if err != nil { + streamWriter.CloseWithError(err) return } - defer streamWriter.Close() - if err = m.multistore.Snapshot(height, streamWriter); err != nil { + if err := extension.Snapshot(height, streamWriter); err != nil { streamWriter.CloseWithError(err) return } - for _, name := range m.sortedExtensionNames() { - extension := m.extensions[name] - // write extension metadata - err := streamWriter.WriteMsg(&types.SnapshotItem{ - Item: &types.SnapshotItem_Extension{ - Extension: &types.SnapshotExtensionMeta{ - Name: name, - Format: extension.SnapshotFormat(), - }, - }, - }) - if err != nil { - streamWriter.CloseWithError(err) - return - } - if err := extension.Snapshot(height, streamWriter); err != nil { - streamWriter.CloseWithError(err) - return - } - } - }() - - return m.store.Save(height, types.CurrentFormat, ch) + } } // List lists snapshots, mirroring ABCI ListSnapshots. It can be concurrent with other operations. @@ -254,7 +258,7 @@ func (m *Manager) Restore(snapshot types.Snapshot) error { chDone := make(chan restoreDone, 1) go func() { - err := m.restore(snapshot, chChunks) + err := m.restoreSnapshot(snapshot, chChunks) chDone <- restoreDone{ complete: err == nil, err: err, @@ -269,8 +273,8 @@ func (m *Manager) Restore(snapshot types.Snapshot) error { return nil } -// restore do the heavy work of snapshot restoration after preliminary checks on request have passed. -func (m *Manager) restore(snapshot types.Snapshot, chChunks <-chan io.ReadCloser) error { +// restoreSnapshot do the heavy work of snapshot restoration after preliminary checks on request have passed. +func (m *Manager) restoreSnapshot(snapshot types.Snapshot, chChunks <-chan io.ReadCloser) error { streamReader, err := NewStreamReader(chChunks) if err != nil { return err From d105e948cdaed6917a3854cb614df40f3b396a56 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Tue, 22 Feb 2022 12:24:57 +0800 Subject: [PATCH 06/10] update comment --- baseapp/baseapp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index ba8bac9f3dc6..090fea537c1e 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -261,7 +261,7 @@ func DefaultStoreLoader(ms sdk.CommitMultiStore) error { } // CommitMultiStore returns the root multi-store. -// Extension snapshotter use this to read storage. +// App constructor can use this to access the `cms`. func (app *BaseApp) CommitMultiStore() sdk.CommitMultiStore { return app.cms } From a41b06dca0de0091a489f601f81780165d1c57fd Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 23 Feb 2022 14:06:13 +0800 Subject: [PATCH 07/10] add safty comment to CommitMultiStore --- baseapp/baseapp.go | 1 + 1 file changed, 1 insertion(+) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 090fea537c1e..615dac622300 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -262,6 +262,7 @@ func DefaultStoreLoader(ms sdk.CommitMultiStore) error { // CommitMultiStore returns the root multi-store. // App constructor can use this to access the `cms`. +// UNSAFE: only safe to use during app initialization. func (app *BaseApp) CommitMultiStore() sdk.CommitMultiStore { return app.cms } From fb15629d29d12b15ad0218bc2f2094b392773e19 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 23 Feb 2022 14:06:55 +0800 Subject: [PATCH 08/10] disable CommitMultiStore after app initialized --- baseapp/baseapp.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 615dac622300..45c65b8030ee 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -264,6 +264,9 @@ func DefaultStoreLoader(ms sdk.CommitMultiStore) error { // App constructor can use this to access the `cms`. // UNSAFE: only safe to use during app initialization. func (app *BaseApp) CommitMultiStore() sdk.CommitMultiStore { + if app.sealed { + panic("cannot call CommitMultiStore() after baseapp is sealed") + } return app.cms } From 451d2b56ed278dd95fd434625b2884fea4f55408 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Wed, 23 Feb 2022 23:07:44 +0800 Subject: [PATCH 09/10] fix unit test --- snapshots/manager.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/snapshots/manager.go b/snapshots/manager.go index 2490e17ae6d9..bdcbfe0a9357 100644 --- a/snapshots/manager.go +++ b/snapshots/manager.go @@ -236,10 +236,6 @@ func (m *Manager) Restore(snapshot types.Snapshot) error { } m.mtx.Lock() defer m.mtx.Unlock() - err := m.beginLocked(opRestore) - if err != nil { - return err - } // check multistore supported format preemptive if snapshot.Format != types.CurrentFormat { @@ -253,6 +249,11 @@ func (m *Manager) Restore(snapshot types.Snapshot) error { "snapshot height %v cannot exceed %v", snapshot.Height, int64(math.MaxInt64)) } + err := m.beginLocked(opRestore) + if err != nil { + return err + } + // Start an asynchronous snapshot restoration, passing chunks and completion status via channels. chChunks := make(chan io.ReadCloser, chunkBufferSize) chDone := make(chan restoreDone, 1) From c0bf26f82c6e3ef5d7b46eaf72ba1eaa595d42fe Mon Sep 17 00:00:00 2001 From: HuangYi Date: Thu, 24 Feb 2022 09:39:52 +0800 Subject: [PATCH 10/10] add comments to SnapshotIAVLItem --- proto/cosmos/base/snapshots/v1beta1/snapshot.proto | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proto/cosmos/base/snapshots/v1beta1/snapshot.proto b/proto/cosmos/base/snapshots/v1beta1/snapshot.proto index b43842d5eb74..1d2365bef652 100644 --- a/proto/cosmos/base/snapshots/v1beta1/snapshot.proto +++ b/proto/cosmos/base/snapshots/v1beta1/snapshot.proto @@ -39,7 +39,9 @@ message SnapshotStoreItem { message SnapshotIAVLItem { bytes key = 1; bytes value = 2; + // version is block height int64 version = 3; + // height is depth of the tree. int32 height = 4; }