From 0fce8a6ba2b6750751d7928a5f0d57e76afebc23 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Mon, 2 Dec 2019 17:56:06 +0300 Subject: [PATCH] proto: publish sg lib, rewrite object --- docs/object.md | 42 +---------------- docs/storagegroup.md | 88 +++++++++++++++++++++++++++++++++++ object/extensions.go | 15 ++---- object/sg.go | 43 ++++------------- object/sg_test.go | 5 +- object/types.pb.go | Bin 93105 -> 79938 bytes object/types.proto | 47 +++++-------------- storagegroup/storage.go | 39 ++++++++++++++++ storagegroup/types.go | 97 +++++++++++++++++++++++++++++++++++++++ storagegroup/types.pb.go | Bin 0 -> 17559 bytes storagegroup/types.proto | 35 ++++++++++++++ 11 files changed, 288 insertions(+), 123 deletions(-) create mode 100644 docs/storagegroup.md create mode 100644 storagegroup/storage.go create mode 100644 storagegroup/types.go create mode 100644 storagegroup/types.pb.go create mode 100644 storagegroup/types.proto diff --git a/docs/object.md b/docs/object.md index 8407733..9e7efe6 100644 --- a/docs/object.md +++ b/docs/object.md @@ -34,8 +34,6 @@ - [Link](#object.Link) - [Object](#object.Object) - [Range](#object.Range) - - [StorageGroup](#object.StorageGroup) - - [StorageGroup.Lifetime](#object.StorageGroup.Lifetime) - [SystemHeader](#object.SystemHeader) - [Tombstone](#object.Tombstone) - [Transform](#object.Transform) @@ -369,7 +367,7 @@ in distributed system. | HomoHash | [bytes](#bytes) | | HomoHash is a homomorphic hash of original object payload | | PayloadChecksum | [bytes](#bytes) | | PayloadChecksum of actual object's payload | | Integrity | [IntegrityHeader](#object.IntegrityHeader) | | Integrity header with checksum of all above headers in the object | -| StorageGroup | [StorageGroup](#object.StorageGroup) | | StorageGroup contains meta information for the data audit | +| StorageGroup | [storagegroup.StorageGroup](#storagegroup.StorageGroup) | | StorageGroup contains meta information for the data audit | @@ -421,31 +419,6 @@ in distributed system. | Length | [uint64](#uint64) | | Length of the data range | - - -### Message StorageGroup - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| ValidationDataSize | [uint64](#uint64) | | ValidationDataSize is size of the all object's payloads included into storage group | -| ValidationHash | [bytes](#bytes) | | ValidationHash is homomorphic hash of all object's payloads included into storage group | -| lifetime | [StorageGroup.Lifetime](#object.StorageGroup.Lifetime) | | Lifetime is time until storage group is valid | - - - - -### Message StorageGroup.Lifetime - - - -| Field | Type | Label | Description | -| ----- | ---- | ----- | ----------- | -| unit | [StorageGroup.Lifetime.Unit](#object.StorageGroup.Lifetime.Unit) | | Unit is lifetime type | -| Value | [int64](#int64) | | Value for lifetime | - - ### Message SystemHeader @@ -514,19 +487,6 @@ in distributed system. - - -### StorageGroup.Lifetime.Unit - - -| Name | Number | Description | -| ---- | ------ | ----------- | -| Unlimited | 0 | Unlimited set if storage group always valid | -| NeoFSEpoch | 1 | NeoFSEpoch set if storage group is valid until lifetime NeoFS epoch | -| UnixTime | 2 | UnixTime set if storage group is valid until lifetime unix timestamp | - - - ### Transform.Type diff --git a/docs/storagegroup.md b/docs/storagegroup.md new file mode 100644 index 0000000..7522902 --- /dev/null +++ b/docs/storagegroup.md @@ -0,0 +1,88 @@ +# Protocol Documentation + + +## Table of Contents + +- [storagegroup/types.proto](#storagegroup/types.proto) + + - Messages + - [StorageGroup](#storagegroup.StorageGroup) + - [StorageGroup.Lifetime](#storagegroup.StorageGroup.Lifetime) + + +- [Scalar Value Types](#scalar-value-types) + + + + +

Top

+ +## storagegroup/types.proto + + + + + + + +### Message StorageGroup + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| ValidationDataSize | [uint64](#uint64) | | ValidationDataSize is size of the all object's payloads included into storage group | +| ValidationHash | [bytes](#bytes) | | ValidationHash is homomorphic hash of all object's payloads included into storage group | +| lifetime | [StorageGroup.Lifetime](#storagegroup.StorageGroup.Lifetime) | | Lifetime is time until storage group is valid | + + + + +### Message StorageGroup.Lifetime + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| unit | [StorageGroup.Lifetime.Unit](#storagegroup.StorageGroup.Lifetime.Unit) | | Unit is lifetime type | +| Value | [int64](#int64) | | Value for lifetime | + + + + + + +### StorageGroup.Lifetime.Unit + + +| Name | Number | Description | +| ---- | ------ | ----------- | +| Unlimited | 0 | Unlimited set if storage group always valid | +| NeoFSEpoch | 1 | NeoFSEpoch set if storage group is valid until lifetime NeoFS epoch | +| UnixTime | 2 | UnixTime set if storage group is valid until lifetime unix timestamp | + + + + + + +## Scalar Value Types + +| .proto Type | Notes | C++ Type | Java Type | Python Type | +| ----------- | ----- | -------- | --------- | ----------- | +| double | | double | double | float | +| float | | float | float | float | +| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | +| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | +| uint32 | Uses variable-length encoding. | uint32 | int | int/long | +| uint64 | Uses variable-length encoding. | uint64 | long | int/long | +| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | +| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | +| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | +| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | +| sfixed32 | Always four bytes. | int32 | int | int | +| sfixed64 | Always eight bytes. | int64 | long | int/long | +| bool | | bool | boolean | boolean | +| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | +| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | + diff --git a/object/extensions.go b/object/extensions.go index 1d89683..7427079 100644 --- a/object/extensions.go +++ b/object/extensions.go @@ -1,8 +1,6 @@ package object -import ( - "github.com/nspcc-dev/neofs-proto/hash" -) +import "github.com/nspcc-dev/neofs-proto/storagegroup" // IsLinking checks if object has children links to another objects. // We have to check payload size because zero-object must have zero @@ -64,7 +62,7 @@ func (m Object) IsTombstone() bool { } // StorageGroup returns storage group structure if it is presented in extended headers. -func (m Object) StorageGroup() (*StorageGroup, error) { +func (m Object) StorageGroup() (*storagegroup.StorageGroup, error) { _, sgHdr := m.LastHeader(HeaderType(StorageGroupHdr)) if sgHdr == nil { return nil, ErrHeaderNotFound @@ -74,11 +72,6 @@ func (m Object) StorageGroup() (*StorageGroup, error) { // SetStorageGroup sets storage group header in the object. // It will replace existing storage group header or add a new one. -func (m *Object) SetStorageGroup(sg *StorageGroup) { - m.SetHeader(&Header{Value: &Header_StorageGroup{StorageGroup: sg}}) -} - -// Empty checks if storage group has some data for validation. -func (m StorageGroup) Empty() bool { - return m.ValidationDataSize == 0 && m.ValidationHash.Equal(hash.Hash{}) +func (m *Object) SetStorageGroup(group *storagegroup.StorageGroup) { + m.SetHeader(&Header{Value: &Header_StorageGroup{StorageGroup: group}}) } diff --git a/object/sg.go b/object/sg.go index 1b48b3e..620d24d 100644 --- a/object/sg.go +++ b/object/sg.go @@ -1,54 +1,31 @@ package object import ( - "bytes" "sort" + + "github.com/nspcc-dev/neofs-proto/refs" + "github.com/nspcc-dev/neofs-proto/storagegroup" ) // Here are defined getter functions for objects that contain storage group // information. -type ( - // IDList is a slice of object ids, that can be sorted. - IDList []ID - - // ZoneInfo provides validation info of storage group. - ZoneInfo struct { - Hash - Size uint64 - } - - // IdentificationInfo provides meta information about storage group. - IdentificationInfo struct { - SGID - CID - OwnerID - } -) - -// Len returns amount of object ids in IDList. -func (s IDList) Len() int { return len(s) } - -// Less returns byte comparision between IDList[i] and IDList[j]. -func (s IDList) Less(i, j int) bool { return bytes.Compare(s[i].Bytes(), s[j].Bytes()) == -1 } - -// Swap swaps element with i and j index in IDList. -func (s IDList) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +var _ storagegroup.Provider = (*Object)(nil) // Group returns slice of object ids that are part of a storage group. -func (m *Object) Group() []ID { +func (m *Object) Group() []refs.ObjectID { sgLinks := m.Links(Link_StorageGroup) - sort.Sort(IDList(sgLinks)) + sort.Sort(storagegroup.IDList(sgLinks)) return sgLinks } // Zones returns validation zones of storage group. -func (m *Object) Zones() []ZoneInfo { +func (m *Object) Zones() []storagegroup.ZoneInfo { sgInfo, err := m.StorageGroup() if err != nil { return nil } - return []ZoneInfo{ + return []storagegroup.ZoneInfo{ { Hash: sgInfo.ValidationHash, Size: sgInfo.ValidationDataSize, @@ -57,8 +34,8 @@ func (m *Object) Zones() []ZoneInfo { } // IDInfo returns meta information about storage group. -func (m *Object) IDInfo() *IdentificationInfo { - return &IdentificationInfo{ +func (m *Object) IDInfo() *storagegroup.IdentificationInfo { + return &storagegroup.IdentificationInfo{ SGID: m.SystemHeader.ID, CID: m.SystemHeader.CID, OwnerID: m.SystemHeader.OwnerID, diff --git a/object/sg_test.go b/object/sg_test.go index 58e2042..15cc21b 100644 --- a/object/sg_test.go +++ b/object/sg_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/nspcc-dev/neofs-proto/hash" + "github.com/nspcc-dev/neofs-proto/storagegroup" "github.com/stretchr/testify/require" ) @@ -28,7 +29,7 @@ func TestObject_StorageGroup(t *testing.T) { } rand.Shuffle(len(obj.Headers), func(i, j int) { obj.Headers[i], obj.Headers[j] = obj.Headers[j], obj.Headers[i] }) - sort.Sort(IDList(idList)) + sort.Sort(storagegroup.IDList(idList)) require.Equal(t, idList, obj.Group()) }) t.Run("identification method", func(t *testing.T) { @@ -58,7 +59,7 @@ func TestObject_StorageGroup(t *testing.T) { Headers: []Header{ { Value: &Header_StorageGroup{ - StorageGroup: &StorageGroup{ + StorageGroup: &storagegroup.StorageGroup{ ValidationDataSize: sgSize, ValidationHash: sgHash, }, diff --git a/object/types.pb.go b/object/types.pb.go index 217ef099bce185ff81f21d608ca4c4bf8340712f..459e124b053ab4c032498513b277709a36b089bb 100644 GIT binary patch delta 5369 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') + return b.String() +} + +// Empty checks if storage group has some data for validation. +func (m StorageGroup) Empty() bool { + return m.ValidationDataSize == 0 && m.ValidationHash.Equal(hash.Hash{}) +} + +// Len returns amount of object ids in IDList. +func (s IDList) Len() int { return len(s) } + +// Less returns byte comparision between IDList[i] and IDList[j]. +func (s IDList) Less(i, j int) bool { return bytes.Compare(s[i].Bytes(), s[j].Bytes()) == -1 } + +// Swap swaps element with i and j index in IDList. +func (s IDList) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// CalculateSize combines length of all zones in storage group. +func CalculateSize(sg Provider) (size uint64) { + zoneList := sg.Zones() + for i := range zoneList { + size += zoneList[i].Size + } + return +} + +// CalculateHash returns homomorphic sum of hashes +// fromm all zones in storage group. +func CalculateHash(sg Provider) (hash.Hash, error) { + var ( + zones = sg.Zones() + hashes = make([]hash.Hash, len(zones)) + ) + for i := range zones { + hashes[i] = zones[i].Hash + } + return hash.Concat(hashes) +} diff --git a/storagegroup/types.pb.go b/storagegroup/types.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..f05288533e982981af115828716b53db2bcaf863 GIT binary patch literal 17559 zcmeHP|8Ltyvj187EA|O!pLCIBeX}k5;sbh@^j?5AIb4&XK;Y+6fxdJTO3$(Wh0w-nGMYJ&McESi~R$P9bCm% zanC$^WnR8|ZJs}S@w(SMJTz&%N_=}}(kxEAD|?m1tL0&Kx3p=Gu+8Su^WWjk#*Ah& zTrA@xGwo($w#ZBik5;pBX$CxlC-D8k;0>lA3U4 zvTJ*1yu_L)&P_|DGn%))w6YVP0; z09f9cm?{!J)LJ>g$l8E9okCg5Kpd^t^ka}KY3v{3cK=Yvd6E8TlN7{9Mv%>|Cu&|^ zB_5o0N1$d?oX`BA?)Z0c$II`+nH3FQzKKNKC>sr%jwJjKNZ&;Ba1n~jrxp`txvv_! zv+?Hdy}Q)hc=Ir5HtJC4DC*vW^ttJi-b)*Q`@{2P>|a+CghfcqtfDNOL&M6yA)K)S zSjR^R^PVn&dwfI)0+;wcMqVU#;LetD!EbBOdvK9AUK8CXFWVzJOx{N$Uql=A$R> z{dbC}bvKVa#E&rY=c@n<791ix>uT5K+H6!HU18qw*!;{`gmiM&g3n>BJLtyCtScUN zz6;jn^ij+FD~+SGR>g!^!p35m-L-z+lIMTC^jc)Oju-eZSzd>}xt1}=^_yfOVm?aJ zh{4kCuu2%2>ICWfE2wHAHaVB!UBNi2qU2Figkb*BV6>rYd3U2>v6v38FaG{i>3C%` zDC46w<9V>#(tR@B7Kn3Y zok5C^ZVhiiGDUumngq2K5PYbawqCBEWo65n){wFzis;KQtD1BqWI{nxpPkafXv9)aHpWh8;`gL1OJh+w?Pn>!td%z1{|ai_oAY&YJ5KNrctCd{>{FxH~C z3s*K=9}21SIS|d`7)WibxT1;_4b_s)q00o-MRqgc8skPv)FL%qSA7z$n+*<^9i#x) zvbK~Ac2nC5g>Rk%Eb{$%TH3Dl>apetg76!WS93QCrCFR5tTOdtZ0iqxiQJ37T^=_x z*2->0eOMA>8-(|V{8G@pC&+KltPks@nRT91*kUW9L*|O0Ud%2<_bvY~rc@M$W}`0r zn{4s??6tkkTnV}8ROgHm&aLDjZ02#e+UYyyGba*PA6CZx5~H6tsca$sqO;4kET5QW z3N#PPH^uah5z~B9;@QHnl~C@@Km~Yj3-V#9r~rR-PAVWf26;l_F>*wG?A)6t1iG9f z>d?5RLT$?0PIVICVlfW_+zvk4R=rbTd9jr{ujvz^4RWNl_=N1N4WWq9bZe`SO&E zicexE1UsP|Gv$tRc0bQ3$COYbl0Tl1fJf0Ld_5#FMK>nzYOX#x@|6|NJfbpHQL5e{ z@hI=7oC7EtnN!ttmf{CQHzqG0xgPL&L@@OhB{rmT#+1pYl*c1c;D|Wwm;{EZ1T`;F zLp1RXqVq{cxziCipBS7-JUThn)QkI+=9m&pNFE*yu9cM|qH_z44E4#%NL@oM$`LGK zAuuDb+Q1{~6LRPA8Srgi3Givjidsu8q^4F2sku&QuqN;|PI({-cOAwrF_Jm<~^nB}VcmL_MWi2ISFF`V%Tm7oa+;CLh>C z2#hF!a;G`qSQSDwx4nt-82NS&zvyWF-Nb(JdMEZi4NmevLo+RMn|k)VnnG4v4x>hJZl`$Uk{? z)ZW_Lc1*tULhCO0Ci})!FWRD8_wZy#t{pqq$ZBx190a|y#UX{vLWy^8gHK@Jp2_Ts z$F}+ublvT%>mE6=UdLsrAS23g$`&Uqt9Rvc8~U2o;L8*(5_B5%Vp^h_%!p|dJo zwW7Q(clJ=%HX5R~QWrNb!>il5s`!rMbS@+w z?E3Hkw?FbQCk>#-V;86zaA{M>qu8ii{%Fv_3(?MMN0QN)e|dOwzH`W@#;Hku`(j;Wo*qV*i~^Qx#|^|n}UC1-USZOa8gURmsYXQShB`}WsC z2i|eqF^5<&&im8&7hRS6P!;r?YH%;<=~Dx2|C^UIQYQ+D4%VYN9(C}SQ`oKL*N6EV zF`i|-to`{`kr}=Wp5MwC)|&(h{r(gcr_>F&W%(isEGO`dgay>2??YU6RE9AkaOrh8 z%LI>%w)-f5{_MuE8a3+3GSO)WD>#7^0!8KbJV{e~WrD(o;?5&D9tL|h4EjRs}-RT+kQrxO0Y?TGTpq$4~v zPZ^Ft*d|_BY6KT05fR3{)|X!cwC$B^SQn9 z<|gy5%vXU?5lHu|pwp7BxoV(GhH{!IF1X@8W&V=t^CdA2&cM}%fY$@kNnL*MGPZS9@`;%^EjW@|BL9L)Lh*gRJu92Hjen zxlt+Fe(x4`w%of>__xv(52w|JRaP5rF5%x`HQsZpvX}%LIXpp>)h+NBZ>U@v*hV5{ zRoHo;VK~j{20?1m7<9xN+1NsLSJ}11n6y|3%Q($813QwJ~c3R_orti?9d+FN@5SwW_1x1FymU@XMeEP~$w()TJ(3X`jQa6`qvfFRl)l3`_Fd5uldp_1uCXW(=z=-D%d#%@CyPYC zu{cp35~oyLj|pZ_Oj}nr_I$*ED(<(VcvR@x-GRZR9uE4WpkjB1d$ZF1)+om36J`9O z*Xyay)O)eBr$A6690ASdQVHQAtE(0(%Ll;ZTfq8zv86rWW|ZB%GW?&-!xy}H$YaLu zxN%sM_!2e^(t@bW&2l9^|9RLKUvD~Lke4eH3~wv{mMXMxSmGmQFRThzITo{*$#`S}aP8%EVao19p0c|6jAV)B)@Isz}Y+n$#)`#gseJ-j}BX zyTmV#>l%K)Pje4Pp3gt6zX!;D2CQm}Xg#&j;%mF!>a=6ndwYDFFYhH)_wih_tC%F6 zO~%DO%jbvoM`exgHc0alu3m|*M+9gsgG+7F5^#+kb6_brT`viU*7fPZ;9|1{TH7OX zoxQwr#R*uscO;&L-7Z=YpSO|o`>LhN!8ZDCP9(%`Y189(Yn2}M!00X09KxLqOfF|_ zPe*N!Zo6X0wXdxWu6ml6emTzj9U2X=E8R-gO0CpakAhb-{(OJ4kwkdjvLN20(smJ? zjKM@XBe~58kXIA~dC6F;qOXFjS!pRE-t&uXuROrXSZOfYPoWx=E)`Ht*-Lq)i zEpYt53MvW8FRSG5yh_Ljt@JFs!T+W~m%=Pwp?M#y_#5+8{&P+I;9Q#b6){s$*P@3D g+AEuw*qx&|EVXv5W^z>=r|@V2zmU$)6FSZR0~9H?cK`qY literal 0 HcmV?d00001 diff --git a/storagegroup/types.proto b/storagegroup/types.proto new file mode 100644 index 0000000..5014b96 --- /dev/null +++ b/storagegroup/types.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; +package storagegroup; +option go_package = "github.com/nspcc-dev/neofs-proto/storagegroup"; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +option (gogoproto.stable_marshaler_all) = true; + +message StorageGroup { + option (gogoproto.goproto_stringer) = false; + + // ValidationDataSize is size of the all object's payloads included into storage group + uint64 ValidationDataSize = 1; + // ValidationHash is homomorphic hash of all object's payloads included into storage group + bytes ValidationHash = 2 [(gogoproto.customtype) = "Hash", (gogoproto.nullable) = false]; + + message Lifetime { + enum Unit { + // Unlimited set if storage group always valid + Unlimited = 0; + // NeoFSEpoch set if storage group is valid until lifetime NeoFS epoch + NeoFSEpoch = 1; + // UnixTime set if storage group is valid until lifetime unix timestamp + UnixTime = 2; + } + + // Unit is lifetime type + Unit unit = 1 [(gogoproto.customname) = "Unit"]; + // Value for lifetime + int64 Value = 2; + } + + // Lifetime is time until storage group is valid + Lifetime lifetime = 3 [(gogoproto.customname) = "Lifetime"]; +}