From 24e5497b1d117e44930dba1c9910935132aab284 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Mon, 18 Nov 2019 19:22:08 +0300 Subject: [PATCH 01/12] Update develop branch --- Makefile | 2 +- accounting/service.go | 3 - accounting/service.pb.go | Bin 18970 -> 21135 bytes accounting/service.proto | 11 ++- accounting/withdraw.go | 12 --- accounting/withdraw.pb.go | Bin 66702 -> 73944 bytes accounting/withdraw.proto | 54 +++++++----- bootstrap/service.go | 3 - bootstrap/service.pb.go | Bin 13256 -> 15356 bytes bootstrap/service.proto | 13 +-- container/service.go | 12 --- container/service.pb.go | Bin 55156 -> 62382 bytes container/service.proto | 51 ++++++----- object/service.go | 51 +---------- object/service.pb.go | Bin 114748 -> 120649 bytes object/service.proto | 105 ++++++++++------------ object/utils.go | 14 ++- service/meta.go | 90 +++++++++++++++++++ service/meta.pb.go | Bin 0 -> 8671 bytes service/meta.proto | 12 +++ service/meta_test.go | 70 +++++++++++++++ service/role_test.go | 3 +- service/ttl.go | 45 ---------- service/ttl_test.go | 72 --------------- service/verify.go | 179 ++++++++++++++++++++++++++++++++++++++ service/verify.pb.go | Bin 0 -> 21382 bytes service/verify.proto | 20 +++++ service/verify_test.go | 106 ++++++++++++++++++++++ service/verify_test.pb.go | Bin 0 -> 13453 bytes service/verify_test.proto | 17 ++++ session/service.pb.go | Bin 24221 -> 27061 bytes session/service.proto | 4 + state/service.pb.go | Bin 29918 -> 37509 bytes state/service.proto | 17 +++- 34 files changed, 642 insertions(+), 324 deletions(-) create mode 100644 service/meta.go create mode 100644 service/meta.pb.go create mode 100644 service/meta.proto create mode 100644 service/meta_test.go delete mode 100644 service/ttl.go delete mode 100644 service/ttl_test.go create mode 100644 service/verify.go create mode 100644 service/verify.pb.go create mode 100644 service/verify.proto create mode 100644 service/verify_test.go create mode 100644 service/verify_test.pb.go create mode 100644 service/verify_test.proto diff --git a/Makefile b/Makefile index 64b09397..9609923a 100644 --- a/Makefile +++ b/Makefile @@ -33,5 +33,5 @@ protoc: echo "${B}${G}⇒ Processing $$f ${R}"; \ protoc \ --proto_path=.:./vendor:/usr/local/include \ - --gofast_out=plugins=grpc,paths=source_relative:. $$f; \ + --gofast_out=plugins=grpc,paths=source_relative:. $$f; \ done diff --git a/accounting/service.go b/accounting/service.go index df74e588..ac1ceb50 100644 --- a/accounting/service.go +++ b/accounting/service.go @@ -31,9 +31,6 @@ const ( ErrEmptyParentAddress = internal.Error("empty parent address") ) -// SetTTL sets ttl to BalanceRequest to satisfy TTLRequest interface. -func (m BalanceRequest) SetTTL(v uint32) { m.TTL = v } - // SumFunds goes through all accounts and sums up active funds. func SumFunds(accounts []*Account) (res *decimal.Decimal) { res = decimal.Zero.Copy() diff --git a/accounting/service.pb.go b/accounting/service.pb.go index bc31ce1c95e387bba39ce3f43caadbbb4a6c5fec..7a8a08697d669bbe504b7a89aeddd598ed2a25ad 100644 GIT binary patch delta 3175 zcmb7GzmFS56qX&##a1G5B8cP)G%>NcC89+RhIHZ-RgB0;QO0k_3`~_Q5DH7 zKkO$Ll`5?`vWokaHIZX=WU{hg;9ASrIP8m$%3^ZZHwOLVUiaWYEMmW}rlWk6BI^aA zQ7NP-RV9jCl%tc0tY%YHnt$qHt)>^^t}5QVC+-%R64j}!ghott?wZGv@c-xdggiE> z#+LgJS2$d3u;uZRFa9;H&dwFF_G@-JdzY90o7X!B9sHS}biTbb&%3{DwW8+E_GulY zmaxy`p;?p6tbsCXmYCJGtzOqYAA06b5!-`94h|0F31M%;H_C~C2N9rcsOljB2_gwk5H7$;WW=b?8P&@Tehh>N zu@$li!BZ)Uga?e|B3{Z=NtCkToX$S>l#})>i36{|to4F(>Hr}{W~A$ai3CL(9x3)A z%AEqu0Wx`#2uniFER2Mu?k98-cm@dJYv)>v4$K&lQe@0M8zh9PF&f8)JRY2h6Cy7y zj}b2h0=q;ZXbLoTU9}Ht;LDL*6P`!{MX&?>fqm&_5_E3a9 zZ;1q2$Z!-7x#ZY;h%nSA8lOiJ92~i(QpWNjv7CDtQQQ!Tr4VL_coAZUl#?g0@hK8k zhh^X$&oismOcG?KAVW+v^!qwbilIAQ+p{n+uM+H&wF#ig7OVd$2G%dyTIsl0=LE4xCmTA{j3$@Hx>WdW(%=noetuKsNcaiA*=> zszNv242DBUKiCF9V>|^T-V7fCxUk`1<6R*IUhAB91vU<43jmO0H3UU$wv5jb!-}^n zVmBf^4@G3J1`x@GC2goSGtw8pP~g>Ix!J3%D%m=U_|Px}4lBbfIm_6eTmx#0!e}iF zf=?-#3|0wwGKj}F1ZSp0so>0;p+ewG9C0cR5kf(c#ckki2@rKr02UW+LkPzAk#1;R zLmTI0?&7HrdrkljCH9#=tige$4B^N3OHN5}qkW{bc&Ff&u*G7Ol_Quq6p0xrcm?cL zhUQCytt{CwHB_>ZWr{r?a431mLcw(XgpJO@s*AKLG-o3Ro)0lxka9ViaFRe$<` zmNEXMP?)okb0veDR?Hx5n^&!md);n1dZd+8)2TQ-6658kQ6G=B`9-;HIj`}B~jPvQR#)sCIHJNWV0!I@Y~Y87Gs zo`&DmU%(TwcO;yqyZ_Suzf3pte}YT%;FX*6w{QQo)sCa)%z1Bn<2!o((`#GpoyWyl s<Qe>})$hC0{>^RM6dt=0T`^@aHl(TCfA1596VqyPW_ delta 2296 zcmZWq&yU+g6jrp-t`Z6h3yV;p(qu0*Y?d95?bu#5z)FZk6$J_PRu$pc<8DyaNgZcv z`a}K`kZ?~NihAG-Qm#l`IPfoU0saESAAkfi->9St=2|;{rV^3Y%wpzNQ+5a+|q?8PvczN)y1?g#-&JgQs{WDQ!&nkKG((9BG=Pw zevnU7-Dw{liVyXy&`DhC^hn$pPbLG1TZ!h$`yr#?eV;!d^$K|=! z2KxL9J(rYXH{>R>H>cOtAJPG6V=q5s)z$@=)6l>y&A5 zI|unQHd!qz&7v_f;8Zcg3L8if2MU(0 zqMi~!T${?RNG{+=p6V&efZznQT?|0V{3Bq{Nn(5*97_a*(3T?+vJH~$gTxftLjY@| zcnUr|b+C5e@1mRl>(E4*`aN`mS0koMF2@7}0@x8EIAWYS&S8dnRxMc*om~8k;oq)+6BD`!jJ_C^C~Hxf*qp_G-ef&D3Etx3Bi_d=m!b% zd*~1EAzzV@En(|{O%181(a>ffnGm@z=<53NiigPWBABD3 zc{LPkfDFWr@qjsq3%C#KW1kNPo4&dMkdx0BS;Q!lch$TDwgf+{Ei+C%r8FTqLxx~>OyZaiUWEMsE%C8t=?Q%JKxXa@i^l^3rE72|*s4SV0|*cznls5;!beGB z3=~QjKoXfW@9n(a{CDv}S0=#mz=f5sy3M(DmiupZU)&yN;_O}XwG`cu zjh^|0x5ozu#-_*R@s06KVLU2Fn(ylJ-`+2qZ#)xf9CNWh6i)M4?ruNDFdt##*xdf$ z)#fiXTt0Gs-D>{+XtyPs$AkAb?05aMlifBsm;}v_*RD1{pWJ^5r0x%&eANF4t}I`> N`e$qT*75w6{{cXrR6zg$ diff --git a/accounting/service.proto b/accounting/service.proto index 9cfdb0f6..f2696c44 100644 --- a/accounting/service.proto +++ b/accounting/service.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package accounting; option go_package = "github.com/nspcc-dev/neofs-proto/accounting"; +import "service/meta.proto"; +import "service/verify.proto"; import "decimal/decimal.proto"; import "accounting/types.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; @@ -17,10 +19,11 @@ service Accounting { message BalanceRequest { // OwnerID is a wallet address - bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; - // TTL must be larger than zero, it decreased in every neofs-node - // Deprecated: will be replaced with RequestMetaHeader (see develop branch) - uint32 TTL = 2; + bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; + // RequestMetaHeader contains information about request meta headers (should be embedded into message) + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } message BalanceResponse { diff --git a/accounting/withdraw.go b/accounting/withdraw.go index 3cd27666..0a8cf901 100644 --- a/accounting/withdraw.go +++ b/accounting/withdraw.go @@ -11,18 +11,6 @@ type ( MessageID = refs.MessageID ) -// SetTTL sets ttl to GetRequest to satisfy TTLRequest interface. -func (m *GetRequest) SetTTL(v uint32) { m.TTL = v } - -// SetTTL sets ttl to PutRequest to satisfy TTLRequest interface. -func (m *PutRequest) SetTTL(v uint32) { m.TTL = v } - -// SetTTL sets ttl to ListRequest to satisfy TTLRequest interface. -func (m *ListRequest) SetTTL(v uint32) { m.TTL = v } - -// SetTTL sets ttl to DeleteRequest to satisfy TTLRequest interface. -func (m *DeleteRequest) SetTTL(v uint32) { m.TTL = v } - // SetSignature sets signature to PutRequest to satisfy SignedRequest interface. func (m *PutRequest) SetSignature(v []byte) { m.Signature = v } diff --git a/accounting/withdraw.pb.go b/accounting/withdraw.pb.go index f0e78aa5dcd5182df57c0a7f759e10290077b87b..a2116c01a729f0d2f6b3bcbaeedee0341339c404 100644 GIT binary patch delta 7540 zcmeHMON06C6YBG7Xv0incMZ;{ zq@r;n5d~g!Cu}sjU|~|MjF4br{3T*^;{tWUf`vvC*T%&6&Z&Vm0~!-afWV@7{p!B^ zIrrTA?sUKL+Pv>i&--visjn+K`&yAW{M+p_%Y0esgKGAecy2;;(}zVGY!yK)I!4qU zPlMKY*JzC=?ao+`w%X%H5Vj{$qeEe1Oi3HNA>K8Hy1UyGdtxILh8PP)9E(^TP1{PU z+YLs=x@x5`zG1epY}ejSJ8g#($?#w}m5Of7_iF9EX>B|h6C>KI8Uz}(8Qs_%G@k9Y z$A<^Cz~HWGW#dMp(EX(7w31c?uZw_MT_Z5MA~o8H(QS>62kAsdboD2(FB6?9V~1!z z@VK#~9SbAf9i)b`7%AUX95Vs`_ZTnX$Lvu3ntdTw9GIFFEw^Xl-Kmd93aoR1Ik>*9s^y^A)@&A;nE)psM^*L%A6uUaVMwM+A%<=f{S*)Tu< zdexHoH?n@cXMOQYi}HBwwz=hWYOgT1x4QD1Rm<`<>z3T8`0KvGA9c&}O}j7uxc>Rv z{H!zFH`lE@a$saMi=vugPCAZ$+I9VOL;Z|x?3lG`#hk3;gAjVl;@a2i(ACdote*~! zg-~Qd(h2l_+|Wl0|O!42oksf=WVSbn{2=j<%Y83Lny-9g3SaLEXX9-F|jtG$eEGRAelJUM2Lc@ z!kGqDU?;S+nI1*iWCTqrlJsLZ19SxvfW5>+3_Q#oLe&tkz=9{lb;P3y zrT7HEVp#S;ZVPVHNd{ZTTa|fjKR_fVjy3QiV$UEC+2jZx*VN6zwONx$n1FpYF&A;h z*a^X&m>hzqfrSukKhqvtFv?^#;HwFJ0ZtG@HpRj+_E~$Z>juy!0ccqzQm26c2&nTA zVI9#HqIK98^c9q4w`yRA35e-2k`cl?_2-xJ+KHKH0KhsZvP3))lnKY!6l_!gn-a6? z$BZ8+v960g1*NL_>KK?%AM7%rgQv;y7%q`+$|dC(ZwOX>aqqzSIs)_op1Kv3Wb9?I zpcth-F*xe*5Oe`IB8dSBTN)F?nq)U1!mL9R9=Uj`D;3oM#~Lu|zyY?PB*Rt{fRcwz z`hq937a(Sj1%<=CO<7rk1#+S%(4sWqh65D=%p_Rz!u2ySgBL$@Nc!633Mw-ql@f@u za$Go5hw}uFJFEt#hpeIuyBkLV-XCOGlo4Bw84+UOeL!|oD|<6_+ei%4=VIN2Uu1oV zBo!?Ssv|tr$e}@E$wr8cDl!$EN__;BNLB*iK@)3_31CxfB65x}%p^&o#t2woKJlcG zAnU+h8_qDCI)crLI~{p5c^GQ}CzG_9L;w8)&2rd9%WpJJ> zY7%KBB)s3)OKfN$ZPf6p6U`j5TXIMxZ`c%cFIV=NCC;-A=%z=E&8JpY9b)E=N040L z<^U2hy_ZA0wAmV1Z|ro0N|(E`&q0RJ_s$3fm26mG4E%e8jNu5w+o!l?dLZnTB!`N@ z9Mmg@BXzxHy56uypo@tOv|<&TNC~I9Vvs;8nNW5E_5s!q>A~AlHAtNXmI+n!l3@sH zJic8s9T9pY6k9NMSo>xq|9tQ^gHs*b2un7CV;m&RW_{y}+ms=TIVh)%~C9x=vd zzRR8cJ*OB;gn9f8WjFLKje zi{)p}f1&@+D_K78+K$Lb-^)+F`e<2BA6PK+Bg93%Zg^Y~dPw~QGH%>GVp#I@fwe=I z{iR~I@M^j9@J{*2>+@y*&E@>~!MEq!u}9U*h3fmC4gI!yQ9gZWXX%Q?@{G)~vOIq9 zzI?gtzp}9$b^G(L-Wpvo$M@vvb5Gnf>$fKvygQKlpZs2uzaFhz;`QdUyXN@5K09#P zjQvf=KZtEU`*i-)N9RlVu@lFaUPT`LQj(^jh;?GRBoCcZEc>=BtLL85>%9Nl!_}+E k)$=9Ut}V`2PJg-N>hkIbuRs6v%yj9<&*l7~Kekl<0?@?*g#Z8m delta 4977 zcmdT|OKenC7*1^qov~0P);1xumu{eRg!{g88v#u;xB`4B-*-tGp2Eh!;&6M;`Cs4v z{r`X3ix;{+IMns^ijMY69Vg29)~%b3U9&SyBNoO~)Yu^!Msp&n8T&+|UNI({MkO6sYNDRaJXx!!qFh?P-gs6_H$)OOMLKTmot&D|sv2T?DoT{l-pS^K z@ru|zD`uK6ie~hJh*D)^&5RIA^`0>?Ri8HEMpR2CM$0Ab%`N|CCu>c|HVk=fV5nc+ zs7yEN&AKyUyggH|jgP1ud1`E4e%sgE7E3pF%4NeP{X^gLqN&c-j2cuR&y-g#R~zNh zfpV!KnzN0XVU`cHKY#4};{O|lZTA6#u^sWpv)TB_o~WU~srZ%pbhA>6c8Lvl#^=&- zuM|rM+E-U>?vi_l2YYV@XW7l*v@K((`yq$MzBe?-<-2Pa1DcDg9nxpt+9m&$KBckX zVW*FGZ;a;U#;`~J>=CD*+%ui>?4iNiVRS2tTGfqW_K0ly&@KwSoP*#gT|>|1(2Z<%y2gar$7%)Jc@gjW`|86oLQ_eh2imjck8^0p^e}u*6arQ>lV|77k)? z;HpI`vEik#5V7hOq>m|K9Y%nS))*&im6awCIiWS7&5sd6Y~~th2U^ME6o3-?A`1Hxc7Yhk(hPT4_4F=-ZhBNCnwMDVDba(N zn>?ZiY~2LWWy%1I4V!$)u}ydoV1wj5;4_11;7BKXIoLR- z)N?_HP#owC=dGe1K_$wi0GbaB&P%qVfP9DdOfFkyl}U$>HwGx8VlQD=(rMnpW>j?{}?-Nf6j6(f1Y69qx>Ijabu4QLG2`-2mN zG~qPk1qyeLK0RS65Cnz7?E<9pq;M=iyi?MTarn94Qq`6S78^;r7i~Wc+$dCrh zlB>6@G@w8W2(PE$fJi(w2$o{?77S3({qDexchqJdpYsmdU<(WPkYRbA9Jv zS5@h6A3gj>kNoH3?oQ>ZeCv}n-Rl3*QQ7zD8}icfCGCUrM;?*JZI54DwL~7Ae?|@; z@wI}Fj=zfEkFOn@yMw;V#}>i0?Z>y?US}%LkN31sezs$U-1KF?9R1~Kcy-~6{t}^7 zNXie-{kRmk&TY8y2bso?>{g0 V%PXhuTlDu19rD?e{T*YE{tH?AbOQhY diff --git a/accounting/withdraw.proto b/accounting/withdraw.proto index eb58d080..bb950ba4 100644 --- a/accounting/withdraw.proto +++ b/accounting/withdraw.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package accounting; option go_package = "github.com/nspcc-dev/neofs-proto/accounting"; +import "service/meta.proto"; +import "service/verify.proto"; import "decimal/decimal.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; @@ -34,12 +36,13 @@ message Item { message GetRequest { // ID is cheque identifier - bytes ID = 1 [(gogoproto.customtype) = "ChequeID", (gogoproto.nullable) = false]; + bytes ID = 1 [(gogoproto.customtype) = "ChequeID", (gogoproto.nullable) = false]; // OwnerID is a wallet address - bytes OwnerID = 2 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; - // TTL must be larger than zero, it decreased in every neofs-node - // Deprecated: will be replaced with RequestMetaHeader (see develop branch) - uint32 TTL = 3; + bytes OwnerID = 2 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; + // RequestMetaHeader contains information about request meta headers (should be embedded into message) + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } message GetResponse { @@ -49,18 +52,19 @@ message GetResponse { message PutRequest { // OwnerID is a wallet address - bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; + bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; // Amount of funds - decimal.Decimal Amount = 2; + decimal.Decimal Amount = 2; // Height is the neo blockchain height until the cheque is valid - uint64 Height = 3; + uint64 Height = 3; // MessageID is a nonce for uniq request (UUIDv4) - bytes MessageID = 4 [(gogoproto.customtype) = "MessageID", (gogoproto.nullable) = false]; + bytes MessageID = 4 [(gogoproto.customtype) = "MessageID", (gogoproto.nullable) = false]; // Signature is a signature of the sent request - bytes Signature = 5; - // TTL must be larger than zero, it decreased in every neofs-node - // Deprecated: will be replaced with RequestMetaHeader (see develop branch) - uint32 TTL = 6; + bytes Signature = 5; + // RequestMetaHeader contains information about request meta headers (should be embedded into message) + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } message PutResponse { // ID is cheque identifier @@ -69,10 +73,11 @@ message PutResponse { message ListRequest { // OwnerID is a wallet address - bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; - // TTL must be larger than zero, it decreased in every neofs-node - // Deprecated: will be replaced with RequestMetaHeader (see develop branch) - uint32 TTL = 2; + bytes OwnerID = 1 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; + // RequestMetaHeader contains information about request meta headers (should be embedded into message) + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } message ListResponse { @@ -82,16 +87,17 @@ message ListResponse { message DeleteRequest { // ID is cheque identifier - bytes ID = 1 [(gogoproto.customtype) = "ChequeID", (gogoproto.nullable) = false]; + bytes ID = 1 [(gogoproto.customtype) = "ChequeID", (gogoproto.nullable) = false]; // OwnerID is a wallet address - bytes OwnerID = 2 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; + bytes OwnerID = 2 [(gogoproto.customtype) = "OwnerID", (gogoproto.nullable) = false]; // MessageID is a nonce for uniq request (UUIDv4) - bytes MessageID = 3 [(gogoproto.customtype) = "MessageID", (gogoproto.nullable) = false]; + bytes MessageID = 3 [(gogoproto.customtype) = "MessageID", (gogoproto.nullable) = false]; // Signature is a signature of the sent request - bytes Signature = 4; - // TTL must be larger than zero, it decreased in every neofs-node - // Deprecated: will be replaced with RequestMetaHeader (see develop branch) - uint32 TTL = 5; + bytes Signature = 4; + // RequestMetaHeader contains information about request meta headers (should be embedded into message) + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } // DeleteResponse is empty diff --git a/bootstrap/service.go b/bootstrap/service.go index 6d0d3ca9..e67ea6df 100644 --- a/bootstrap/service.go +++ b/bootstrap/service.go @@ -6,6 +6,3 @@ import ( // NodeType type alias. type NodeType = service.NodeRole - -// SetTTL sets ttl to Request to satisfy TTLRequest interface. -func (m *Request) SetTTL(v uint32) { m.TTL = v } diff --git a/bootstrap/service.pb.go b/bootstrap/service.pb.go index f00f814b8b9127a72859dfd937b007460c21ebcc..7165399abca3e1f22125e42612a8b4e77b732e51 100644 GIT binary patch delta 2953 zcmb7GO>Y}j6ctG$#TJ_`K&k}c)kviwPCTCPiR48$hy~4p0*X`+c{A^gGbQn)o=I@% zV*Wyr7fAdEgpl{JV8c)75~Ti%vf#aQCaqCiB(k`9zH{$A=YGAJKgNH5`}Fy+($k9~ z)1o&n>f`ftFDp+6lj+Q@s?qKYFxr|0>8 zFTJdF)lcGnc~Gv3dLIT}--d2%Y-oGpQB_X%d)A_N)a?ugqK*B9o)&qL$+{>f zWG;$INKxrpl)0#i@kG|=Q(f6#`a(}H#eptAdLRx;rA2)#Yhe&GL*1ltm2aD3^FMN2 z!Q*Ze{?U zh!-Pv3{8d!;*~*IIDCEqkdy%kL5N$%sGUIu`*|FT?Tys`~W54mBH9; zdypF^$&3fK0iYb~9On#qa<(`+k}$Jjs~0*&JvGehV-$(Q(-BA$b!dG7}>qK20uC0D7H z=%={|Z5!}5nXx~tr{gXrH=n<``=s0HRK<73SWl;7ee0zI$u_=TU$51uf)itoyczI_0e8^ExwHM_R1*k;-{@=Yj;je%$HP_oF5pjcg<(x zMC^=&J0IWP+WVL33f9+L-e3HF`^M&463<`U`E14K?0X-+wK)FZ#TzRgjkk~1lEnJm WdhJK${L247Ovc*}7x#CbZ2kj12|F+V delta 2194 zcmZWq&x<2f5M~^h*~AqO{=mZ`&!{lj&A9z5N%ydG7!VX0JxGKBQTKIs^-OEh9Xp+w zjI&FxM{f&#@#sO=KOkQ9;>Cl1gCKYi{1-g<-uGo-z#NK7y{h`EzN+{7-;3W)pZ>LT zTFn#HYoEOG>N?n}wwuZ1Sk0D;TE(KKx;m9g)n~d;-$+#sR9>r8l1lVKQk54<&ZW9k zg_PN1zbI4bcJAL-@5;QAMAwoYsEd3$wW%tZPjzB~F7obzw7?F?S(-* zd;YW$Z=jr&3mIfqPc$TSFB^0_&dQ6d$rDKE0i3+VT2cpg1O)U+VPT@!>H$1?nhtRa zd*g*bAgF<}1pvVvTb<>F0dg=?X!Vd4q3jf=5#$ik9a$fJt=kp?-} z1hk0yjeH&~a9w$*TUZw*I@DvdzytHgmQ9I*Lm-C;j-Zpg)auPD0ee39@u52iPGAYq z;fACk4m3aot|J^fq@E)o^`x6RB?jZVwz?EiV)bUVN#UXgm$ZU_1il(vvB-@MyATbY zV_J|k0uI|r(5(jkI0irlCl}?7jcenqGGan%>c|&?F$a?N5Pb>|xFj*T1sB3i^6)2y z^jIX)4R6rEIa`JeevD#bb^_gD6&OA71L`Sy7@+_U&?Dsbkvj%eBMd!5x&T$UsDhMa zh~fY&7Y08<@DRZ!0Lw}^Vl8lKUxlbM{qCV0b1A?8=pfT&P zL0}w_(cuteM3B6>%)xF0OfrE#J%!|PlLE|*v*oNf!vuCplfvRN6E7u+4%jm%1_a){ z&20$K11~wDhv{@u}ll^RY57 zkVVi47I4U?iRl;|c);fk;48x3xH5cX9gYE=kGMA+H18WrrOa?aDO2ct@W?PH%)NC$ zgX659z4XWJ7wxCZex~f_%TZVD550S@!_YV1+fKf}Z)AE@AAOpCri{nR4cjN`we<(R zU!S{m9ozo+*52;q*hV~V@2EG|zr6kT?v~#^bzW{i?;qWn9QOw1OJB+4axONl{Umle bfN6j3|9;!RKRVoePuuVBK3IS2U)}l-rRzWU diff --git a/bootstrap/service.proto b/bootstrap/service.proto index cde94dcd..f0bf755d 100644 --- a/bootstrap/service.proto +++ b/bootstrap/service.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package bootstrap; option go_package = "github.com/nspcc-dev/neofs-proto/bootstrap"; +import "service/meta.proto"; +import "service/verify.proto"; import "bootstrap/types.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; @@ -17,10 +19,11 @@ service Bootstrap { message Request { // Type is NodeType, can be InnerRingNode (type=1) or StorageNode (type=2) - int32 type = 1 [(gogoproto.customname) = "Type" , (gogoproto.nullable) = false, (gogoproto.customtype) = "NodeType"]; + int32 type = 1 [(gogoproto.customname) = "Type" , (gogoproto.nullable) = false, (gogoproto.customtype) = "NodeType"]; // Info contains information about node - bootstrap.NodeInfo info = 2 [(gogoproto.nullable) = false]; - // TTL must be larger than zero, it decreased in every neofs-node - // Deprecated: will be replaced with RequestMetaHeader (see develop branch) - uint32 TTL = 3; + bootstrap.NodeInfo info = 2 [(gogoproto.nullable) = false]; + // RequestMetaHeader contains information about request meta headers (should be embedded into message) + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } diff --git a/container/service.go b/container/service.go index 27f39e78..5f446dae 100644 --- a/container/service.go +++ b/container/service.go @@ -19,18 +19,6 @@ type ( MessageID = refs.MessageID ) -// SetTTL sets ttl to GetRequest to satisfy TTLRequest interface. -func (m *GetRequest) SetTTL(v uint32) { m.TTL = v } - -// SetTTL sets ttl to PutRequest to satisfy TTLRequest interface. -func (m *PutRequest) SetTTL(v uint32) { m.TTL = v } - -// SetTTL sets ttl to ListRequest to satisfy TTLRequest interface. -func (m *ListRequest) SetTTL(v uint32) { m.TTL = v } - -// SetTTL sets ttl to DeleteRequest to satisfy TTLRequest interface. -func (m *DeleteRequest) SetTTL(v uint32) { m.TTL = v } - // SetSignature sets signature to PutRequest to satisfy SignedRequest interface. func (m *PutRequest) SetSignature(v []byte) { m.Signature = v } diff --git a/container/service.pb.go b/container/service.pb.go index cfd401d920b046267eef658e8ff3d2d569c6d528..8b98cfa59116761173e6a5fa44f193826114d292 100644 GIT binary patch delta 7166 zcmeHMU5H%O9cOp5$;@O;vI|@Av;WXJ)^7d+P0fO}%usM=WIwAXB7a@KgF$a@E8^@7>OR&!y&sBQmR^t)L%0qUAi zw=g235CbF6jG}wI7Y&AeQRq)%r4;>B#)BgN#Y4t}c`A&-iD+ObkBP#rc&rir|2f_O z$9k$^+qudW8&0ib%jq?~_$1HnxP8XB=1-p4cc8KMS$?=dy$pBLx z+qI?Iw{vx>y1e^^oAo}F`e-R$|B(f-j#`!}1Vd0tl6$;NlD1)vJXeoNsz+bwF?IClChbZKB|Mj4|GF zuNlKZ2Sx*M>j0#sft4d0wrwDbu_%L$0P_LRXFy@&ZH##n^LD1uB_=%BnCgH+0uvFo zS@33a9;1zUSC8e$$5Kk~a48wmHdJ*oiUe8-7A1Hcfe+;&5zaeU$&iFtqgslB+5tv^ zy{RTrjsp1ar0|e1h#2EQ?_kh7kl4aZh-VWrB(O)@0=Oc8wqV}?Z$zzd8qqsld0Ph5;AoH;dr@L@T44mdCm97+j$ z6o5Vj>~$cCO-aBu1;YT6q?jiPl|3qu8ANg!XA>sOtX--%)GEZ3hkdLrTFNlvGU<@G z89Xr2Ld=^$%328+1`jW|*`aG}PVh{r%n<%l1`!;5mI?H5urMb> zfR9NE^B(xCMx!Z2eyKThu#W)PKna6sprWMKu+r+ZhEEUn*yKE_06P)9DeT&VNv8+~ zGn3|2y(^=p3I9}y{;8Dg{PK9rRpT~q_hG$scI1CY?tYdKlCDb_pmPc1+##jYSK!GReaVNN+! z%CL z0=y+)b{(qSfq!-4Y6lr4Ax{f0N*mPK{TUgaFT9HIq-0t#-1Qv^n=|0z!BPi0!V4B_ zhG(`q_DLG0Fx*`7_+hX5K&1}2u4=PBS11q<74e)iYB0uOkK`;~~Eioer=4_KR z%Bm{aIYI>53*mu%g7w1#nN`H%XP`On!#|r<-M--2#k|RGfEk86tS3`z^OIG=25zEOStSWloMTE4j2myV^??j9?8=k`2WUC6s0`HORfRohzzj)Uds_2yq%IXYO7Ks`LY{BD5%4-g*D-V> z;QD9>E7ll;%O=JU*Y`EZ!|MX`OjQ*qD9zRVhu3#DM0S5BC>wj-n_1)F$yCl5Rwf;u ziHM%n*`z&?0%ORC@oNR|BKiua{0jttqVoV@Z)DtQrJVc|G$Xk4j>t zC(AlT1+qVtsW1UUGh$Tq_IrO*s>bzp&z`pzr*ODUGM@kZ&%o z-s`uT-MP6|Gd(gm@@V%lIAVmab2>^;?G3mDACLyz}(Y z4Ry1sBHoaV)g$uo+38or9rE>6Uw%&zK5!P!Lw#jc^eWZHr!r!<44~LY49smFU delta 4775 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 PssE1;*WUlNSl;$OLD(kP delta 10619 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 VtQRsbk3YC}3Fub^+xoYi{{p+M`Ro7y literal 0 HcmV?d00001 diff --git a/service/meta.proto b/service/meta.proto new file mode 100644 index 00000000..4c09fb3c --- /dev/null +++ b/service/meta.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package service; +option go_package = "github.com/nspcc-dev/neofs-proto/service"; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +option (gogoproto.stable_marshaler_all) = true; + +message RequestMetaHeader { + uint32 TTL = 1; + uint64 Epoch = 2; +} diff --git a/service/meta_test.go b/service/meta_test.go new file mode 100644 index 00000000..893ca5ee --- /dev/null +++ b/service/meta_test.go @@ -0,0 +1,70 @@ +package service + +import ( + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type mockedRequest struct { + msg string + name string + role NodeRole + code codes.Code + RequestMetaHeader +} + +func TestMetaRequest(t *testing.T) { + tests := []mockedRequest{ + { + role: InnerRingNode, + name: "direct to ir node", + RequestMetaHeader: RequestMetaHeader{TTL: NonForwardingTTL}, + }, + { + role: StorageNode, + code: codes.InvalidArgument, + msg: ErrIncorrectTTL.Error(), + name: "direct to storage node", + RequestMetaHeader: RequestMetaHeader{TTL: NonForwardingTTL}, + }, + { + role: StorageNode, + msg: ErrZeroTTL.Error(), + code: codes.InvalidArgument, + name: "zero ttl", + RequestMetaHeader: RequestMetaHeader{TTL: ZeroTTL}, + }, + { + role: InnerRingNode, + name: "default to ir node", + RequestMetaHeader: RequestMetaHeader{TTL: SingleForwardingTTL}, + }, + { + role: StorageNode, + name: "default to storage node", + RequestMetaHeader: RequestMetaHeader{TTL: SingleForwardingTTL}, + }, + } + + for i := range tests { + tt := tests[i] + t.Run(tt.name, func(t *testing.T) { + before := tt.GetTTL() + err := ProcessRequestTTL(&tt, IRNonForwarding(tt.role)) + if tt.msg != "" { + require.Errorf(t, err, tt.msg) + + state, ok := status.FromError(err) + require.True(t, ok) + require.Equal(t, state.Code(), tt.code) + require.Equal(t, state.Message(), tt.msg) + } else { + require.NoError(t, err) + require.NotEqualf(t, before, tt.GetTTL(), "ttl should be changed: %d vs %d", before, tt.GetTTL()) + } + }) + } +} diff --git a/service/role_test.go b/service/role_test.go index a1f1cc06..01dbee26 100644 --- a/service/role_test.go +++ b/service/role_test.go @@ -1,8 +1,9 @@ package service import ( - "github.com/stretchr/testify/require" "testing" + + "github.com/stretchr/testify/require" ) func TestNodeRole_String(t *testing.T) { diff --git a/service/ttl.go b/service/ttl.go deleted file mode 100644 index 8ddf1dec..00000000 --- a/service/ttl.go +++ /dev/null @@ -1,45 +0,0 @@ -package service - -import ( - "github.com/nspcc-dev/neofs-proto/internal" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -// TTLRequest to verify and update ttl requests. -type TTLRequest interface { - GetTTL() uint32 - SetTTL(uint32) -} - -const ( - // ZeroTTL is empty ttl, should produce ErrZeroTTL. - ZeroTTL = iota - - // NonForwardingTTL is a ttl that allows direct connections only. - NonForwardingTTL - - // SingleForwardingTTL is a ttl that allows connections through another node. - SingleForwardingTTL - - // ErrZeroTTL is raised when zero ttl is passed. - ErrZeroTTL = internal.Error("zero ttl") - - // ErrIncorrectTTL is raised when NonForwardingTTL is passed and NodeRole != InnerRingNode. - ErrIncorrectTTL = internal.Error("incorrect ttl") -) - -// CheckTTLRequest validates and update ttl requests. -func CheckTTLRequest(req TTLRequest, role NodeRole) error { - var ttl = req.GetTTL() - - if ttl == ZeroTTL { - return status.New(codes.InvalidArgument, ErrZeroTTL.Error()).Err() - } else if ttl == NonForwardingTTL && role != InnerRingNode { - return status.New(codes.InvalidArgument, ErrIncorrectTTL.Error()).Err() - } - - req.SetTTL(ttl - 1) - - return nil -} diff --git a/service/ttl_test.go b/service/ttl_test.go deleted file mode 100644 index 13491984..00000000 --- a/service/ttl_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package service - -import ( - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "testing" -) - -type mockedRequest struct { - msg string - ttl uint32 - name string - role NodeRole - code codes.Code -} - -func (m *mockedRequest) SetTTL(v uint32) { m.ttl = v } -func (m mockedRequest) GetTTL() uint32 { return m.ttl } - -func TestCheckTTLRequest(t *testing.T) { - tests := []mockedRequest{ - { - ttl: NonForwardingTTL, - role: InnerRingNode, - name: "direct to ir node", - }, - { - ttl: NonForwardingTTL, - role: StorageNode, - code: codes.InvalidArgument, - msg: ErrIncorrectTTL.Error(), - name: "direct to storage node", - }, - { - ttl: ZeroTTL, - role: StorageNode, - msg: ErrZeroTTL.Error(), - code: codes.InvalidArgument, - name: "zero ttl", - }, - { - ttl: SingleForwardingTTL, - role: InnerRingNode, - name: "default to ir node", - }, - { - ttl: SingleForwardingTTL, - role: StorageNode, - name: "default to storage node", - }, - } - - for i := range tests { - tt := tests[i] - t.Run(tt.name, func(t *testing.T) { - before := tt.ttl - err := CheckTTLRequest(&tt, tt.role) - if tt.msg != "" { - require.Errorf(t, err, tt.msg) - - state, ok := status.FromError(err) - require.True(t, ok) - require.Equal(t, state.Code(), tt.code) - require.Equal(t, state.Message(), tt.msg) - } else { - require.NoError(t, err) - require.NotEqualf(t, before, tt.ttl, "ttl should be changed: %d vs %d", before, tt.ttl) - } - }) - } -} diff --git a/service/verify.go b/service/verify.go new file mode 100644 index 00000000..d8ede7ea --- /dev/null +++ b/service/verify.go @@ -0,0 +1,179 @@ +package service + +import ( + "crypto/ecdsa" + + "github.com/gogo/protobuf/proto" + crypto "github.com/nspcc-dev/neofs-crypto" + "github.com/nspcc-dev/neofs-proto/internal" + "github.com/pkg/errors" +) + +type ( + // VerifiableRequest adds possibility to sign and verify request header + VerifiableRequest interface { + proto.Message + Marshal() ([]byte, error) + AddSignature(*RequestVerificationHeader_Signature) + GetSignatures() []*RequestVerificationHeader_Signature + SetSignatures([]*RequestVerificationHeader_Signature) + } + + // MaintainableRequest adds possibility to set and get (+validate) + // owner (client) public key from RequestVerificationHeader. + MaintainableRequest interface { + proto.Message + GetOwner() (*ecdsa.PublicKey, error) + SetOwner(*ecdsa.PublicKey, []byte) + GetLastPeer() (*ecdsa.PublicKey, error) + } +) + +const ( + // ErrCannotLoadPublicKey is raised when cannot unmarshal public key from RequestVerificationHeader_Sign + ErrCannotLoadPublicKey = internal.Error("cannot load public key") + + // ErrCannotFindOwner is raised when signatures empty in GetOwner + ErrCannotFindOwner = internal.Error("cannot find owner public key") +) + +// SetSignatures replaces signatures stored in RequestVerificationHeader +func (m *RequestVerificationHeader) SetSignatures(signatures []*RequestVerificationHeader_Signature) { + m.Signatures = signatures +} + +// AddSignature adds new Signature into RequestVerificationHeader +func (m *RequestVerificationHeader) AddSignature(sig *RequestVerificationHeader_Signature) { + if sig == nil { + return + } + m.Signatures = append(m.Signatures, sig) +} + +// SetOwner adds origin (sign and public key) of owner (client) into first signature. +func (m *RequestVerificationHeader) SetOwner(pub *ecdsa.PublicKey, sign []byte) { + if len(m.Signatures) == 0 || pub == nil { + return + } + + m.Signatures[0].Origin = &RequestVerificationHeader_Sign{ + Sign: sign, + Peer: crypto.MarshalPublicKey(pub), + } +} + +// GetOwner tries to get owner (client) public key from signatures. +// If signatures contains not empty Origin, we should try to validate, +// that session key was signed by owner (client), otherwise return error. +func (m *RequestVerificationHeader) GetOwner() (*ecdsa.PublicKey, error) { + if len(m.Signatures) == 0 { + return nil, ErrCannotFindOwner + } + + // if first signature contains origin, we should try to validate session key + if m.Signatures[0].Origin != nil { + owner := crypto.UnmarshalPublicKey(m.Signatures[0].Origin.Peer) + if owner == nil { + return nil, ErrCannotLoadPublicKey + } else if err := crypto.Verify(owner, m.Signatures[0].Peer, m.Signatures[0].Origin.Sign); err != nil { + return nil, errors.Wrap(err, "could not verify session token") + } + + return owner, nil + } else if key := crypto.UnmarshalPublicKey(m.Signatures[0].Peer); key != nil { + return key, nil + } + + return nil, ErrCannotLoadPublicKey +} + +// GetLastPeer tries to get last peer public key from signatures. +// If signatures has zero length, returns ErrCannotFindOwner. +// If signatures has length equal to one, uses GetOwner. +// Otherwise tries to unmarshal last peer public key. +func (m *RequestVerificationHeader) GetLastPeer() (*ecdsa.PublicKey, error) { + switch ln := len(m.Signatures); ln { + case 0: + return nil, ErrCannotFindOwner + case 1: + return m.GetOwner() + default: + if key := crypto.UnmarshalPublicKey(m.Signatures[ln-1].Peer); key != nil { + return key, nil + } + + return nil, ErrCannotLoadPublicKey + } +} + +func newSignature(key *ecdsa.PrivateKey, data []byte) (*RequestVerificationHeader_Signature, error) { + sign, err := crypto.Sign(key, data) + if err != nil { + return nil, err + } + + return &RequestVerificationHeader_Signature{ + RequestVerificationHeader_Sign: RequestVerificationHeader_Sign{ + Sign: sign, + Peer: crypto.MarshalPublicKey(&key.PublicKey), + }, + }, nil +} + +// SignRequestHeader receives private key and request with RequestVerificationHeader, +// tries to marshal and sign request with passed PrivateKey, after that adds +// new signature to headers. If something went wrong, returns error. +func SignRequestHeader(key *ecdsa.PrivateKey, req VerifiableRequest) error { + msg := proto.Clone(req).(VerifiableRequest) + + // ignore meta header + if meta, ok := msg.(MetaHeader); ok { + meta.ResetMeta() + } + + data, err := msg.Marshal() + if err != nil { + return err + } + + signature, err := newSignature(key, data) + if err != nil { + return err + } + + req.AddSignature(signature) + + return nil +} + +// VerifyRequestHeader receives request with RequestVerificationHeader, +// tries to marshal and verify each signature from request +// If something went wrong, returns error. +func VerifyRequestHeader(req VerifiableRequest) error { + msg := proto.Clone(req).(VerifiableRequest) + // ignore meta header + if meta, ok := msg.(MetaHeader); ok { + meta.ResetMeta() + } + + signatures := msg.GetSignatures() + + for i := range signatures { + msg.SetSignatures(signatures[:i]) + peer := signatures[i].GetPeer() + sign := signatures[i].GetSign() + + key := crypto.UnmarshalPublicKey(peer) + if key == nil { + return errors.Wrapf(ErrCannotLoadPublicKey, "%d: %02x", i, peer) + } + + if data, err := msg.Marshal(); err != nil { + return errors.Wrapf(err, "%d: %02x", i, peer) + } else if err := crypto.Verify(key, data, sign); err != nil { + return errors.Wrapf(err, "%d: %02x", i, peer) + } + } + + return nil +} diff --git a/service/verify.pb.go b/service/verify.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..3c0f357ec62f5c1b9f723676d4a9c1e2355febde GIT binary patch literal 21382 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 literal 0 HcmV?d00001 diff --git a/service/verify.proto b/service/verify.proto new file mode 100644 index 00000000..7d833089 --- /dev/null +++ b/service/verify.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package service; +option go_package = "github.com/nspcc-dev/neofs-proto/service"; + +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +option (gogoproto.stable_marshaler_all) = true; + +message RequestVerificationHeader { + message Sign { + bytes Sign = 1; + bytes Peer = 2; + } + message Signature { + Sign Sign = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + Sign Origin = 2; + } + + repeated Signature Signatures = 1; +} diff --git a/service/verify_test.go b/service/verify_test.go new file mode 100644 index 00000000..4aaefb47 --- /dev/null +++ b/service/verify_test.go @@ -0,0 +1,106 @@ +package service + +import ( + "math" + "testing" + + crypto "github.com/nspcc-dev/neofs-crypto" + "github.com/nspcc-dev/neofs-crypto/test" + "github.com/pkg/errors" + "github.com/stretchr/testify/require" +) + +func TestSignRequestHeader(t *testing.T) { + req := &TestRequest{ + IntField: math.MaxInt32, + StringField: "TestRequestStringField", + BytesField: []byte("TestRequestBytesField"), + } + + key := test.DecodeKey(0) + peer := crypto.MarshalPublicKey(&key.PublicKey) + + data, err := req.Marshal() + require.NoError(t, err) + + require.NoError(t, SignRequestHeader(key, req)) + + require.Len(t, req.Signatures, 1) + for i := range req.Signatures { + sign := req.Signatures[i].GetSign() + require.Equal(t, peer, req.Signatures[i].GetPeer()) + require.NoError(t, crypto.Verify(&key.PublicKey, data, sign)) + } +} + +func TestVerifyRequestHeader(t *testing.T) { + req := &TestRequest{ + IntField: math.MaxInt32, + StringField: "TestRequestStringField", + BytesField: []byte("TestRequestBytesField"), + RequestMetaHeader: RequestMetaHeader{TTL: 10}, + } + + for i := 0; i < 10; i++ { + req.TTL-- + require.NoError(t, SignRequestHeader(test.DecodeKey(i), req)) + } + + require.NoError(t, VerifyRequestHeader(req)) +} + +func TestMaintainableRequest(t *testing.T) { + req := &TestRequest{ + IntField: math.MaxInt32, + StringField: "TestRequestStringField", + BytesField: []byte("TestRequestBytesField"), + RequestMetaHeader: RequestMetaHeader{TTL: 10}, + } + + count := 10 + owner := test.DecodeKey(count + 1) + + for i := 0; i < count; i++ { + req.TTL-- + + key := test.DecodeKey(i) + require.NoError(t, SignRequestHeader(key, req)) + + // sign first key (session key) by owner key + if i == 0 { + sign, err := crypto.Sign(owner, crypto.MarshalPublicKey(&key.PublicKey)) + require.NoError(t, err) + + req.SetOwner(&owner.PublicKey, sign) + } + } + + { // Good case: + require.NoError(t, VerifyRequestHeader(req)) + + // validate, that first key (session key) was signed with owner + signatures := req.GetSignatures() + + require.Len(t, signatures, count) + + pub, err := req.GetOwner() + require.NoError(t, err) + + require.Equal(t, &owner.PublicKey, pub) + } + + { // wrong owner: + req.Signatures[0].Origin = nil + + pub, err := req.GetOwner() + require.NoError(t, err) + + require.NotEqual(t, &owner.PublicKey, pub) + } + + { // Wrong signatures: + copy(req.Signatures[count-1].Sign, req.Signatures[count-1].Peer) + err := VerifyRequestHeader(req) + require.EqualError(t, errors.Cause(err), crypto.ErrInvalidSignature.Error()) + } +} diff --git a/service/verify_test.pb.go b/service/verify_test.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..a029c2e2af2b981508f1a30f47410b6c04925a0d GIT binary patch literal 13453 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 Ai2wiq literal 0 HcmV?d00001 diff --git a/service/verify_test.proto b/service/verify_test.proto new file mode 100644 index 00000000..5eb8cfdf --- /dev/null +++ b/service/verify_test.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package service; +option go_package = "github.com/nspcc-dev/neofs-proto/service"; + +import "service/meta.proto"; +import "service/verify.proto"; +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + +option (gogoproto.stable_marshaler_all) = true; + +message TestRequest { + int32 IntField = 1; + string StringField = 2; + bytes BytesField = 3; + RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + RequestVerificationHeader Header = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; +} diff --git a/session/service.pb.go b/session/service.pb.go index b99b611d61a1b1d61790d0a64c8783d5f9992ccf..eef58192979350812ad2f5ceb3ffabf56c925878 100644 GIT binary patch delta 3065 zcmb7G&u<%55LSx$VS^EERaF&9SeYLpU?;o#*83xpTY5kgq@swTs!|DL_r15Uh}gm2 zR4!HJBV3Rw_RJrFERMayg$rj8e*zNsiub;6gA*JiTB(!g*_rufzL__>-#=XW@z<3H ze|Qr;zEeo;bUrQ0&knOqIojVEP7b8(DSc;as7LvvcQ786qpjNVhu>D8sMgyTt8boZ zS1&ZyX0?9v1O4Tpo|M;hnO@VW(qrf7-yQ;Fhxv9VyIbl>H;KEWgR(nJ_w~TqcVQs9 zdOy=jX$57+`Ft`OZg;FfXRp=#7tT#RF7iUAH_Bo(tO1vSk_8YP?k+)5eFVl|)kp11 z7ml*W-$^+>l;yqq)wk`=`4dlW@7kKG2aQ+GozNGr=S5(pA!7cxN95UKjGq$U9-qk7OQ$OK+_fD!~!?c+h;wEzMY zN~@pMMW@IqL!B-%ijlp7b4Fxj(T9v-Z*sIGNfgHiDG(G&AfGHZ1%3v74uD7kUjRp= zlEkW}lI%f~=WGK&eZ+Q=l12hP96aa~NIH{Fk{6+<1UW{CBY_`SIh#ts8t6@1BoHH4 zQk=ujw9GaM_#qpLxe3`e=q0FPOF~+*4H*D3g!YiUFd=3p9%8ffdIAyKh15Vuaqc6Y zK#oLUV-k{-10h6lBqK*+3EW)p>7u9@A!0KI79S2N9uOf#4Sg8(p;sCtv2g)#ax^qY z)DZQ!BoEFcscsDPE{3kwATQ6*Y49~1@)QUHky22iU=^VB7&wxch@@Z{;>^5`x5Uhi zZ54buVP+U`q3H}t0>3-6^M*(s(CRx2BcF`{0fHF=U*RdE=4=x5ywTGD&=N&QpejNS zT^KP?hH#+(KJOk!GslSez|0UkL3_Aebch-_8Kg2sY#$tQ?FdliL8eGGLZA?q8N!7C zFf`lx>!pAPhGDP-N|=D=9B}q15tWP0OopY9)e;l+^GrK)% z=;pk$eb`Xb;}w!a57m-31%|1~z_8gj7J)O#n^x~wq{pSeNfI9LLuAiN*dN}2dYPjo z9N!FQQ@KS*@q?R~^T`Fp#o+^ubaPht&M-YRCD(6@5cnJ-c9k^X)<~^w24WNyCO}@lC21%ZIee0bes-M@^9QH@Sk49VpB+2#XPpyA^zI(6LY)*== zOuc$McD4u3{?S+1(bv)9Xt)H(Jf1^X9dIT6n2)*V=C>|yw4avgL_0}bt?qny zcInf1{`dPXh>d|}eyjZ-i-kzGA4@Q&n-J#M`(*_1kY~V|E;N|oH@aic5 T%cd4+{`}3qR_1%x2WS5Vxwb&< delta 1738 zcmYk7yKWUR5QcS#AWEVfZYiJuoi|E!PW?}Pc_&7=9v?(VX4^3RxYxaR_S(f4jw|tTI4SPjeB7zKA0+>ciy*i}aw*6nVQk)xxxYb&v z9PK@k9P(w&UGjTRHHQR)D#x`NAtLXGm^6(o?5#w@-bov)v<+ymL<~$FUep~3fdff& zKo6<*=vYgMVn1-LSBb=H8qF1)4$T%NIb3W2p@O%F1@;X!;&HMV(H$3LA=<_sWUpp` zU#S7G=u#cbwYRS6<{1NpkS3% z;?iKW5K7n?*Q6J_OP zC`ASsYbHx%RM- Q|60xOPLG!NFOF~j17ByluK)l5 diff --git a/session/service.proto b/session/service.proto index 4b37aafb..9b0c65ee 100644 --- a/session/service.proto +++ b/session/service.proto @@ -3,6 +3,8 @@ package session; option go_package = "github.com/nspcc-dev/neofs-proto/session"; import "session/types.proto"; +import "service/meta.proto"; +import "service/verify.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; option (gogoproto.stable_marshaler_all) = true; @@ -34,6 +36,8 @@ message CreateRequest { // Signed Init message response (Unsigned) from server with user private key session.Token Signed = 2; } + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } message CreateResponse { diff --git a/state/service.pb.go b/state/service.pb.go index a3684101176dc7672a7ab3b85e33ed22fec9b65c..8e66a2f8fd1094e11e3cfe81e9efb57e402459ae 100644 GIT binary patch delta 5652 zcmeHLOK%%h7*$?vY^WMiM4(93CYbT8#mI4j?Gy)8 zoDCaTp<%}cgpfe$BGq)kiWR%A_yd5D5Ms+8fP2ren}oC~FVRI4DbwqF@AsYao$oPm zzyEdM{VxW$?;kkalFduCSbp^L$^J6GZ{X{}Zf}3?ynJgzw%TW8TRba8BAZ74=fZk( zt-Tg)r1O)}W?QyOVNhCIZn4Pktw_*>+xRi!^UB)E~1`(dVsrSROemZdNMp(PJ539t|YZ2&Y z*R+8U2>mGlPKdRG^8j{&{$NM1d-j1)hHn>l0;~gA#R&j>x&ZkE2Brq+cFI5tv6TW- zfCW8;FffUX_{)fsOaouDmH`kF7&CMM0uIb1ktqP=3E%?abvqu+{9TMa98+N*Yc~ag zjSmu_%uft68wh@)$q0sn9SiA+5e~zo%pPu9I-G9D0woo#PBdk8m~Qx%P?R65yh&V(dg<%%*vJDqB3wOa-Dolkh5iQi{xGAPB@pE{ws2C-xx~PJtgYa*C87bk;sQ!@@CJ(?On9O=$cG z2MJ)fO5ctfG3wO+q z!q;hFO$H1X@$~$GMy~)!8zfbID6bqD5%vQ}%XJ7|5%`+DGtnZXZw13}%UaouHs>#2?{~2L$y#(B+H%RB6*8&|iXjV0|?DDNH#hP9WFfL zOAa6Sj(GsHknZ>fr6i=p&{>V7=Ry+h@YTi9$aQZh0a*fue{pzSps7iyV@N?mKsXZz zB%^9s_W@*JadGWJ5>~7UTMj68H+zpo7qV7aA2y;AFzB-OsS+cxc8S4M`VfQT&?Y;i z+r*P|MLl&0yvhWGpvQ0{0%)(SB{-1G-Z3E*)S9xWv_f)R=+i4wqj_f+4Azt%X%@b z?yHm9>};`+EVdV4tyPVR64txPUMPx%TeI5v7WI$VSbv+1m2EFgWebb^1OE3XA09l= z>~FI^ih)m1;-XuX{xpL;=d&y?z(hA~qyEMvx~8#CEw&mRlx zx~KM7?QhsyS`R7f?CQeFZ1(gi{lzr9{@mgnqL9y?{(RsLVXN@HZ0pQu_T$oM?w_p= zAC5&!8ex!qSX=4O!JTAGmW;P+O}VnUE|vD2b%jf!X{@#`*0Y7zt`B1|R$b=e_5R{Y z^}SQIbl-&C@jUlpV^uU;Z;1L7$K%=L>CXK6TC2U>NMxrv{X}-P{@8K7tLo&&z9K=w zp(gD0{-bGs9sC>O&)kIgeuTdkKz^?N+d%f^*pYl|<*UI1u~9C&tK>fyJ0E@Jsp5gq L|AWvoGC%qU^7?DC delta 2071 zcmYk7yK5Fv5XJfOASNmys3_Q&I*HzW?^ad;Q}_anC=%G$6-BEw={^xfECk7x+FIBJ z7c2h`n-sAS0wM&#!q$6#XMcuzR*SW=R zf8l)pY4-iJbL@84PtEoF3%BO|X}@>w!^!C=G~LbRN8_Yky<~QZz}w1t8@Jxpk++dq zU6?mJfx(sHA~etaw+XTMlhS{uv9}H1A-2Y(Xc9>_kP7N2n?Ptt z&NvQfv7xA?gylP=Xd`@Ec$O8!B5a0YC01x*Bm^1_IB2NXKtMB$K`X%@97SUvGF^kB(N$;ve7mL*n#8nqNMgtmyJd6rIXhaX5W7)Mf7bHg8@TS*DG zB>pyp5{aNl+wG+swqE3iJ>)c`P);KfECZ%=9*3V(F5}p#=MhR>L=d!rEypcVTGl`k zrD1>pJ(1 z2jIIW$o*6Ozmz+s2BAhubt3leBD&Cm1U*v$l~k`%x7s1v(Pkzp4YHn_Q~*sf_Vu(- z!!1&jEO~nH8r5JWVzGc-i$BF0vfAV2@|%<)cZGUd?vi94AGfjKm)du-^#oN6H)Alh zIwVc6m{#2A*=tpsW64mHoFIU*4R!?r7sg|Lfkv x(cnn?%MYH-^nafJ81-BB^Aum*mYpZ?@WuC0x3<01eS3MoU)w&MbH}?&{{Y3qAsYYy diff --git a/state/service.proto b/state/service.proto index 3c85d860..cb2698b8 100644 --- a/state/service.proto +++ b/state/service.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package state; option go_package = "github.com/nspcc-dev/neofs-proto/state"; +import "service/meta.proto"; +import "service/verify.proto"; import "bootstrap/types.proto"; import "github.com/gogo/protobuf/gogoproto/gogo.proto"; @@ -19,10 +21,16 @@ service Status { } // NetmapRequest message to request current node netmap -message NetmapRequest {} +message NetmapRequest { + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; +} // MetricsRequest message to request node metrics -message MetricsRequest {} +message MetricsRequest { + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; +} // MetricsResponse contains [][]byte, // every []byte is marshaled MetricFamily proto message @@ -32,7 +40,10 @@ message MetricsResponse { } // HealthRequest message to check current state -message HealthRequest {} +message HealthRequest { + service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; +} // HealthResponse message with current state message HealthResponse { From 5c344bfceb7d42921d070a43546d2cff3db298ff Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Tue, 19 Nov 2019 19:03:42 +0300 Subject: [PATCH 02/12] Fix issue with Sign/VerifyRequestHeader proto.Clone proto.Clone couldn't makes copy for custom fields. We should reset and restore MetaHeader before/after Sign/Verify. Add test coverage to check that all works like expected. --- service/meta.go | 24 +++++++++----- service/verify.go | 68 ++++++++++++++++++++++++++++++-------- service/verify_test.go | 37 +++++++++++++++++++++ service/verify_test.pb.go | Bin 13453 -> 14924 bytes service/verify_test.proto | 1 + 5 files changed, 108 insertions(+), 22 deletions(-) diff --git a/service/meta.go b/service/meta.go index cd3459ef..52874c12 100644 --- a/service/meta.go +++ b/service/meta.go @@ -8,10 +8,11 @@ import ( type ( // MetaHeader contains meta information of request. - // It provides methods to get or set meta information - // and reset meta header. + // It provides methods to get or set meta information meta header. + // Also contains methods to reset and restore meta header. MetaHeader interface { - ResetMeta() + ResetMeta() RequestMetaHeader + RestoreMeta(RequestMetaHeader) // TTLRequest to verify and update ttl requests. GetTTL() uint32 @@ -22,7 +23,7 @@ type ( SetEpoch(v uint64) } - // TTLCondition is closure, that allows to validate request with ttl + // TTLCondition is closure, that allows to validate request with ttl. TTLCondition func(ttl uint32) error ) @@ -45,14 +46,21 @@ const ( ErrIncorrectTTL = internal.Error("incorrect ttl") ) -// SetTTL sets TTL to RequestMetaHeader +// SetTTL sets TTL to RequestMetaHeader. func (m *RequestMetaHeader) SetTTL(v uint32) { m.TTL = v } -// SetEpoch sets Epoch to RequestMetaHeader +// SetEpoch sets Epoch to RequestMetaHeader. func (m *RequestMetaHeader) SetEpoch(v uint64) { m.Epoch = v } -// ResetMeta sets RequestMetaHeader to empty value -func (m *RequestMetaHeader) ResetMeta() { m.Reset() } +// ResetMeta returns current value and sets RequestMetaHeader to empty value. +func (m *RequestMetaHeader) ResetMeta() RequestMetaHeader { + cp := *m + m.Reset() + return cp +} + +// RestoreMeta sets current RequestMetaHeader to passed value. +func (m *RequestMetaHeader) RestoreMeta(v RequestMetaHeader) { *m = v } // IRNonForwarding condition that allows NonForwardingTTL only for IR func IRNonForwarding(role NodeRole) TTLCondition { diff --git a/service/verify.go b/service/verify.go index d8ede7ea..a6ac3a51 100644 --- a/service/verify.go +++ b/service/verify.go @@ -10,7 +10,7 @@ import ( ) type ( - // VerifiableRequest adds possibility to sign and verify request header + // VerifiableRequest adds possibility to sign and verify request header. VerifiableRequest interface { proto.Message Marshal() ([]byte, error) @@ -30,19 +30,19 @@ type ( ) const ( - // ErrCannotLoadPublicKey is raised when cannot unmarshal public key from RequestVerificationHeader_Sign + // ErrCannotLoadPublicKey is raised when cannot unmarshal public key from RequestVerificationHeader_Sign. ErrCannotLoadPublicKey = internal.Error("cannot load public key") - // ErrCannotFindOwner is raised when signatures empty in GetOwner + // ErrCannotFindOwner is raised when signatures empty in GetOwner. ErrCannotFindOwner = internal.Error("cannot find owner public key") ) -// SetSignatures replaces signatures stored in RequestVerificationHeader +// SetSignatures replaces signatures stored in RequestVerificationHeader. func (m *RequestVerificationHeader) SetSignatures(signatures []*RequestVerificationHeader_Signature) { m.Signatures = signatures } -// AddSignature adds new Signature into RequestVerificationHeader +// AddSignature adds new Signature into RequestVerificationHeader. func (m *RequestVerificationHeader) AddSignature(sig *RequestVerificationHeader_Signature) { if sig == nil { return @@ -123,12 +123,14 @@ func newSignature(key *ecdsa.PrivateKey, data []byte) (*RequestVerificationHeade // SignRequestHeader receives private key and request with RequestVerificationHeader, // tries to marshal and sign request with passed PrivateKey, after that adds // new signature to headers. If something went wrong, returns error. -func SignRequestHeader(key *ecdsa.PrivateKey, req VerifiableRequest) error { - msg := proto.Clone(req).(VerifiableRequest) - +func SignRequestHeader(key *ecdsa.PrivateKey, msg VerifiableRequest) error { // ignore meta header if meta, ok := msg.(MetaHeader); ok { - meta.ResetMeta() + h := meta.ResetMeta() + + defer func() { + meta.RestoreMeta(h) + }() } data, err := msg.Marshal() @@ -141,22 +143,28 @@ func SignRequestHeader(key *ecdsa.PrivateKey, req VerifiableRequest) error { return err } - req.AddSignature(signature) + msg.AddSignature(signature) return nil } // VerifyRequestHeader receives request with RequestVerificationHeader, -// tries to marshal and verify each signature from request +// tries to marshal and verify each signature from request. // If something went wrong, returns error. -func VerifyRequestHeader(req VerifiableRequest) error { - msg := proto.Clone(req).(VerifiableRequest) +func VerifyRequestHeader(msg VerifiableRequest) error { // ignore meta header if meta, ok := msg.(MetaHeader); ok { - meta.ResetMeta() + h := meta.ResetMeta() + + defer func() { + meta.RestoreMeta(h) + }() } signatures := msg.GetSignatures() + defer func() { + msg.SetSignatures(signatures) + }() for i := range signatures { msg.SetSignatures(signatures[:i]) @@ -177,3 +185,35 @@ func VerifyRequestHeader(req VerifiableRequest) error { return nil } + +// testCustomField for test usage only. +type testCustomField [8]uint32 + +var _ internal.Custom = (*testCustomField)(nil) + +// Reset skip, it's for test usage only. +func (t testCustomField) Reset() {} + +// ProtoMessage skip, it's for test usage only. +func (t testCustomField) ProtoMessage() {} + +// Size skip, it's for test usage only. +func (t testCustomField) Size() int { return 32 } + +// String skip, it's for test usage only. +func (t testCustomField) String() string { return "" } + +// Bytes skip, it's for test usage only. +func (t testCustomField) Bytes() []byte { return nil } + +// Unmarshal skip, it's for test usage only. +func (t testCustomField) Unmarshal(data []byte) error { return nil } + +// Empty skip, it's for test usage only. +func (t testCustomField) Empty() bool { return false } + +// UnmarshalTo skip, it's for test usage only. +func (t testCustomField) MarshalTo(data []byte) (int, error) { return 0, nil } + +// Marshal skip, it's for test usage only. +func (t testCustomField) Marshal() ([]byte, error) { return nil, nil } diff --git a/service/verify_test.go b/service/verify_test.go index 4aaefb47..1403c678 100644 --- a/service/verify_test.go +++ b/service/verify_test.go @@ -1,9 +1,12 @@ package service import ( + "bytes" + "log" "math" "testing" + "github.com/gogo/protobuf/proto" crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-crypto/test" "github.com/pkg/errors" @@ -104,3 +107,37 @@ func TestMaintainableRequest(t *testing.T) { require.EqualError(t, errors.Cause(err), crypto.ErrInvalidSignature.Error()) } } + +func TestVerifyAndSignRequestHeaderWithoutCloning(t *testing.T) { + key := test.DecodeKey(0) + + custom := testCustomField{1, 2, 3, 4, 5, 6, 7, 8} + + b := &TestRequest{ + IntField: math.MaxInt32, + StringField: "TestRequestStringField", + BytesField: []byte("TestRequestBytesField"), + CustomField: &custom, + RequestMetaHeader: RequestMetaHeader{ + TTL: math.MaxInt32 - 8, + Epoch: math.MaxInt64 - 12, + }, + } + + require.NoError(t, SignRequestHeader(key, b)) + require.NoError(t, VerifyRequestHeader(b)) + + require.Len(t, b.Signatures, 1) + require.Equal(t, custom, *b.CustomField) + require.Equal(t, uint32(math.MaxInt32-8), b.GetTTL()) + require.Equal(t, uint64(math.MaxInt64-12), b.GetEpoch()) + + buf := bytes.NewBuffer(nil) + log.SetOutput(buf) + + cp, ok := proto.Clone(b).(*TestRequest) + require.True(t, ok) + require.NotEqual(t, b, cp) + + require.Contains(t, buf.String(), "proto: don't know how to copy") +} diff --git a/service/verify_test.pb.go b/service/verify_test.pb.go index a029c2e2af2b981508f1a30f47410b6c04925a0d..06e7971842ae9bc4d66f6166bb8abb5b1c2c02ce 100644 GIT binary patch delta 2412 zcmZveO^X~=7=?))g57=)B?=Qn$`QlF^o08U80ke2vQtE}3&B)%-O>)z)06I+p+^b* z3k0S70s0s0g*z9n-MIBf2wAugM7;MoozN3AFqf)(-+SKkp7-2a{mtaJ_J`h!-sZ3S z_l0Ty$&1%L=snze`=j^qr4LUQ?QGh8(z~*Hzcq_i@3$xBu=egB&u8tdI%y7et24Ve zjEA%1c6d}y&1frbNLVx+1J#}#o6$2!yWWGv?C4;3d(&(>Y0dPwJ=?uM=znS+o~(x# zf4$U;!mxWhSgfL8==saIapO30W8@D9eSaDF?j=v$Xeu`*p&R4UjTzetVl?_=R)H87 z?pgD3%5&|;3WO*oLE#`)%NUF}ck3}2Lh{KFG6t+Bj6N8tM(rggCT9jazg7lPr`im( zQ3;e&y3$t5#<&PsEhihXC0;t_=lv4fKK-G7^z;HIsoYaWmp2sv2OJ8N<;>o?NV52`hh@LZAR| zOsr(6vFs$V`4g&A>vQVVbIN>3 zwF#LsfHpQn$wF4zOc7d0Pc}ycNgkD%kU)M8ES$|BD!)jQCxKoruPDPt5_YSJ3C)!= z0*VgUMq8JvIfIK#7XX(cRRm6Bn_=_U8Z7dvM{EMiqn%pfd@B}q>6DzQ-g zunUzx#YxgIzyTq`*dxBO8A|Yc170Ocj0PYXEk>&-qlOX@OF3FaV<;Wpn%XMnRZb3&&YMJvajE3AHgNUVG`*2Z zV@bx8C^g_obeSt5CWecUa_W>BE$9p(x8+Pq^2-1T5UDbVhFV$BM4b!+hOTsdCv-LH&h(+GPntvxDMwo9 zYO?XJ4GAUGJ2X*(HayFwVb%Tq+RimwnaElHxkeFDD~?+2S8C8-Uw-|s-fDVt>$B^< zGxClmhu+tNe&7A~7n84ycQEqKMcw?&&hA}z>l1H(Ur`|I^ eP8_RqU>5w^shhPFo>y!4?Tx$Zzu)`*)&Btb+Ys#2kRa%+SAYm+0|e|~NJ)v<0lPpV zAfxJ>LA=E3ak+f2eeIebA3nbMd^+Er-ky)syYrvZ>&wrZ?+;FO?9X2wzdxq!?nT(! zwb*qkwh4E)kHTKH<;UFrKNvVpRq=Ql2V!EeeO+ula*Ah}%Xh-lHRU^!t?mUV7mmFq zs>KFu)s@(me3?xCp0GhiT0A2$6?TP7&1pA+kT@71JVL3Z+8X~>V2-_A3c>)(#O;x0 zRQMy;>QrK^xuu3~1tE}WfpBASB$}aTxht5n$aWj5TY)+Dl?zdlq)4D;Pmw_cD+wZa zEHUy`S}+?+AaX>omUv}TB!#R?2}jsBYfvVb_1HigBK}1y0$Detnqkpk2X1wswZspz zG7!2j0Uarvi6LLh_#KRODSAsk9liUL=|DMRHR)y%oWq1-O58v`Ktm-LJWhP+*T?&|>Hx#HUx#8@HRBh~E8Wq^$T55b0-TZt8s zW{lj}xV@3pNmrN=|3nGZJ+w$`XJ^%Ev?U7wIrPYL%^>a@x6Rs6?PweDI}8oq$#Lg< zLG;ll!)Z_-wrg*p>Jr<}4SF_j8^Bi+Ti;RVLOng9Y8yr9DaawRiS9&#j2@+$Aa)g< z*2<;l+b#^&?}+94%f2aM1@C~J5ze52S()%S?+eHkviW>C``1CI&u&<9AM d`jFdwNl$;DF0Y Date: Wed, 20 Nov 2019 12:49:05 +0300 Subject: [PATCH 03/12] Add ErrNotFound for container --- container/service.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/container/service.go b/container/service.go index 5f446dae..4d3747e5 100644 --- a/container/service.go +++ b/container/service.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/binary" + "github.com/nspcc-dev/neofs-proto/internal" "github.com/nspcc-dev/neofs-proto/refs" "github.com/pkg/errors" ) @@ -19,6 +20,11 @@ type ( MessageID = refs.MessageID ) +const ( + // ErrNotFound is raised when container could not be found. + ErrNotFound = internal.Error("could not find container") +) + // SetSignature sets signature to PutRequest to satisfy SignedRequest interface. func (m *PutRequest) SetSignature(v []byte) { m.Signature = v } From ce667591e94686db28c21dcb08d15db1c33c14e5 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 14:09:44 +0300 Subject: [PATCH 04/12] Add CODECOV_TOKEN --- .github/workflows/go.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index de59f364..d8460559 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -38,4 +38,6 @@ jobs: run: go test -coverprofile=coverage.txt -covermode=atomic ./... - name: Codecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} run: bash <(curl -s https://codecov.io/bash) From 16101b7d84cebf35e855ba0e30ab6d7d552e2385 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 15:13:07 +0300 Subject: [PATCH 05/12] proto: add version of protocol into meta header --- service/meta.go | 12 +++++++++++- service/meta.proto | 5 +++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/service/meta.go b/service/meta.go index 52874c12..1e3fcc86 100644 --- a/service/meta.go +++ b/service/meta.go @@ -10,6 +10,7 @@ type ( // MetaHeader contains meta information of request. // It provides methods to get or set meta information meta header. // Also contains methods to reset and restore meta header. + // Also contains methods to get or set request protocol version MetaHeader interface { ResetMeta() RequestMetaHeader RestoreMeta(RequestMetaHeader) @@ -20,7 +21,16 @@ type ( // EpochRequest gives possibility to get or set epoch in RPC Requests. GetEpoch() uint64 - SetEpoch(v uint64) + SetEpoch(uint64) + + // VersionHeader allows get or set version of protocol request + VersionHeader + } + + // VersionHeader allows get or set version of protocol request + VersionHeader interface { + GetVersion() uint32 + SetVersion(uint32) } // TTLCondition is closure, that allows to validate request with ttl. diff --git a/service/meta.proto b/service/meta.proto index 4c09fb3c..62866d20 100644 --- a/service/meta.proto +++ b/service/meta.proto @@ -7,6 +7,7 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto"; option (gogoproto.stable_marshaler_all) = true; message RequestMetaHeader { - uint32 TTL = 1; - uint64 Epoch = 2; + uint32 TTL = 1; + uint64 Epoch = 2; + uint32 Version = 3; } From cc3b4d9087a9499b5bde677209ebe8b997adbc77 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 15:17:54 +0300 Subject: [PATCH 06/12] proto: SearchRequest rename Version to QueryVersion --- object/service.proto | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/object/service.proto b/object/service.proto index 6abe8ede..da544473 100644 --- a/object/service.proto +++ b/object/service.proto @@ -129,12 +129,12 @@ message HeadResponse { } message SearchRequest { - // Version of search query format - uint32 Version = 1; // ContainerID for searching the object - bytes ContainerID = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "CID"]; + bytes ContainerID = 1 [(gogoproto.nullable) = false, (gogoproto.customtype) = "CID"]; // Query in the binary serialized format - bytes Query = 3; + bytes Query = 2; + // QueryVersion is a version of search query format + uint32 QueryVersion = 3; // RequestMetaHeader contains information about request meta headers (should be embedded into message) service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) From b8f3641b591e2416fe7fa8222d2bda84a49833b5 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 15:20:49 +0300 Subject: [PATCH 07/12] service: add `SetVersion` to satisfy `MetaHeader` interface --- service/meta.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/service/meta.go b/service/meta.go index 1e3fcc86..6b5b8b79 100644 --- a/service/meta.go +++ b/service/meta.go @@ -56,6 +56,9 @@ const ( ErrIncorrectTTL = internal.Error("incorrect ttl") ) +// SetVersion sets protocol version to RequestMetaHeader. +func (m *RequestMetaHeader) SetVersion(v uint32) { m.Version = v } + // SetTTL sets TTL to RequestMetaHeader. func (m *RequestMetaHeader) SetTTL(v uint32) { m.TTL = v } From e2842ae2166ab0f2f6aebd5b5aa0ccb933ef9045 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 15:14:01 +0300 Subject: [PATCH 08/12] docs: add doc comments for meta and verify proto files --- service/meta.proto | 6 ++++++ service/verify.proto | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/service/meta.proto b/service/meta.proto index 62866d20..d3c3005e 100644 --- a/service/meta.proto +++ b/service/meta.proto @@ -6,8 +6,14 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto"; option (gogoproto.stable_marshaler_all) = true; +// RequestMetaHeader contains information about request meta headers +// (should be embedded into message) message RequestMetaHeader { + // TTL must be larger than zero, it decreased in every NeoFS Node uint32 TTL = 1; + // Epoch for user can be empty, because node sets epoch to the actual value uint64 Epoch = 2; + // Version defines protocol version + // TODO: not used for now, should be implemented in future uint32 Version = 3; } diff --git a/service/verify.proto b/service/verify.proto index 7d833089..c70015b6 100644 --- a/service/verify.proto +++ b/service/verify.proto @@ -6,15 +6,25 @@ import "github.com/gogo/protobuf/gogoproto/gogo.proto"; option (gogoproto.stable_marshaler_all) = true; +// RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request +// (should be embedded into message). message RequestVerificationHeader { message Sign { + // Sign is signature of the request or session key. bytes Sign = 1; + // Peer is compressed public key used for signature. bytes Peer = 2; } + message Signature { + // Sign is a signature and public key of the request. Sign Sign = 1 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // Origin used for requests, when trusted node changes it and re-sign with session key. + // If session key used for signature request, then Origin should contain + // public key of user and signed session key. Sign Origin = 2; } + // Signatures is a set of signatures of every passed NeoFS Node repeated Signature Signatures = 1; } From c35eefec3b5e4d0d33aff42f827f41ed8d72d440 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 15:27:17 +0300 Subject: [PATCH 09/12] docs: add doc comments for session and state requests --- session/service.proto | 2 ++ state/service.proto | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/session/service.proto b/session/service.proto index 9b0c65ee..377e77ee 100644 --- a/session/service.proto +++ b/session/service.proto @@ -36,7 +36,9 @@ message CreateRequest { // Signed Init message response (Unsigned) from server with user private key session.Token Signed = 2; } + // RequestMetaHeader contains information about request meta headers (should be embedded into message) service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } diff --git a/state/service.proto b/state/service.proto index cb2698b8..ed90e269 100644 --- a/state/service.proto +++ b/state/service.proto @@ -22,13 +22,17 @@ service Status { // NetmapRequest message to request current node netmap message NetmapRequest { + // RequestMetaHeader contains information about request meta headers (should be embedded into message) service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } // MetricsRequest message to request node metrics message MetricsRequest { + // RequestMetaHeader contains information about request meta headers (should be embedded into message) service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } @@ -41,7 +45,9 @@ message MetricsResponse { // HealthRequest message to check current state message HealthRequest { + // RequestMetaHeader contains information about request meta headers (should be embedded into message) service.RequestMetaHeader Meta = 98 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; + // RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) service.RequestVerificationHeader Verify = 99 [(gogoproto.embed) = true, (gogoproto.nullable) = false]; } From 0aa2d69dbd55afbd3e7e83758c45297958e46a3b Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 15:28:15 +0300 Subject: [PATCH 10/12] docs: regenerate proto documentation --- docs/accounting.md | 15 +++-- docs/bootstrap.md | 3 +- docs/container.md | 12 ++-- docs/object.md | 30 ++++----- docs/service.md | 157 +++++++++++++++++++++++++++++++++++++++++++++ docs/session.md | 2 + docs/state.md | 15 +++++ 7 files changed, 209 insertions(+), 25 deletions(-) create mode 100644 docs/service.md diff --git a/docs/accounting.md b/docs/accounting.md index b4317aee..268a1872 100644 --- a/docs/accounting.md +++ b/docs/accounting.md @@ -87,7 +87,8 @@ Balance returns current balance status of the NeoFS user | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | OwnerID | [bytes](#bytes) | | OwnerID is a wallet address | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -362,7 +363,8 @@ Delete allows user to remove unused cheque | OwnerID | [bytes](#bytes) | | OwnerID is a wallet address | | MessageID | [bytes](#bytes) | | MessageID is a nonce for uniq request (UUIDv4) | | Signature | [bytes](#bytes) | | Signature is a signature of the sent request | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -382,7 +384,8 @@ DeleteResponse is empty | ----- | ---- | ----- | ----------- | | ID | [bytes](#bytes) | | ID is cheque identifier | | OwnerID | [bytes](#bytes) | | OwnerID is a wallet address | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -420,7 +423,8 @@ DeleteResponse is empty | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | OwnerID | [bytes](#bytes) | | OwnerID is a wallet address | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -447,7 +451,8 @@ DeleteResponse is empty | Height | [uint64](#uint64) | | Height is the neo blockchain height until the cheque is valid | | MessageID | [bytes](#bytes) | | MessageID is a nonce for uniq request (UUIDv4) | | Signature | [bytes](#bytes) | | Signature is a signature of the sent request | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | diff --git a/docs/bootstrap.md b/docs/bootstrap.md index 19967bfa..737e0855 100644 --- a/docs/bootstrap.md +++ b/docs/bootstrap.md @@ -62,7 +62,8 @@ Process is method that allows to register node in the network and receive actual | ----- | ---- | ----- | ----------- | | type | [int32](#int32) | | Type is NodeType, can be InnerRingNode (type=1) or StorageNode (type=2) | | info | [NodeInfo](#bootstrap.NodeInfo) | | Info contains information about node | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | diff --git a/docs/container.md b/docs/container.md index 4f98a47d..bc559ce2 100644 --- a/docs/container.md +++ b/docs/container.md @@ -92,8 +92,9 @@ List returns all user's containers | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | CID | [bytes](#bytes) | | CID (container id) is a SHA256 hash of the container structure | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | | Signature | [bytes](#bytes) | | Signature of the container owner | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -113,7 +114,8 @@ via consensus in inner ring nodes | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | CID | [bytes](#bytes) | | CID (container id) is a SHA256 hash of the container structure | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -136,7 +138,8 @@ via consensus in inner ring nodes | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | | OwnerID | [bytes](#bytes) | | OwnerID is a wallet address | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -163,7 +166,8 @@ via consensus in inner ring nodes | OwnerID | [bytes](#bytes) | | OwnerID is a wallet address | | rules | [netmap.PlacementRule](#netmap.PlacementRule) | | Rules define storage policy for the object inside the container. | | Signature | [bytes](#bytes) | | Signature of the user (owner id) | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | diff --git a/docs/object.md b/docs/object.md index 03e41c84..84077332 100644 --- a/docs/object.md +++ b/docs/object.md @@ -147,11 +147,11 @@ calculated for XORed data. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) | | Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) | | OwnerID | [bytes](#bytes) | | OwnerID is a wallet address | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | | Token | [session.Token](#session.Token) | | Token with session public key and user's signature | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -170,11 +170,11 @@ in distributed system. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) | | Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) | | Ranges | [Range](#object.Range) | repeated | Ranges of object's payload to calculate homomorphic hash | | Salt | [bytes](#bytes) | | Salt is used to XOR object's payload ranges before hashing, it can be nil | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -196,10 +196,10 @@ in distributed system. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) | | Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) | | Ranges | [Range](#object.Range) | repeated | Ranges of object's payload to return | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -221,9 +221,9 @@ in distributed system. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) | | Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -246,10 +246,10 @@ in distributed system. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| Epoch | [uint64](#uint64) | | Epoch should be empty on user side, node sets epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) | | Address | [refs.Address](#refs.Address) | | Address of object (container id + object id) | | FullHeaders | [bool](#bool) | | FullHeaders can be set true for extended headers in the object | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -273,6 +273,8 @@ in distributed system. | ----- | ---- | ----- | ----------- | | Header | [PutRequest.PutHeader](#object.PutRequest.PutHeader) | | Header should be the first message in the stream | | Chunk | [bytes](#bytes) | | Chunk should be a remaining message in stream should be chunks | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | @@ -283,9 +285,7 @@ in distributed system. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) | | Object | [Object](#object.Object) | | Object with at least container id and owner id fields | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | | Token | [session.Token](#session.Token) | | Token with session public key and user's signature | @@ -308,11 +308,11 @@ in distributed system. | Field | Type | Label | Description | | ----- | ---- | ----- | ----------- | -| Epoch | [uint64](#uint64) | | Epoch is set by user to 0, node set epoch to the actual value Deprecated: will be replaced with RequestMetaHeader (see develop branch) | -| Version | [uint32](#uint32) | | Version of search query format | | ContainerID | [bytes](#bytes) | | ContainerID for searching the object | | Query | [bytes](#bytes) | | Query in the binary serialized format | -| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every neofs-node Deprecated: will be replaced with RequestMetaHeader (see develop branch) | +| QueryVersion | [uint32](#uint32) | | QueryVersion is a version of search query format | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | diff --git a/docs/service.md b/docs/service.md new file mode 100644 index 00000000..454fab42 --- /dev/null +++ b/docs/service.md @@ -0,0 +1,157 @@ +# Protocol Documentation + + +## Table of Contents + +- [service/meta.proto](#service/meta.proto) + + - Messages + - [RequestMetaHeader](#service.RequestMetaHeader) + + +- [service/verify.proto](#service/verify.proto) + + - Messages + - [RequestVerificationHeader](#service.RequestVerificationHeader) + - [RequestVerificationHeader.Sign](#service.RequestVerificationHeader.Sign) + - [RequestVerificationHeader.Signature](#service.RequestVerificationHeader.Signature) + + +- [service/verify_test.proto](#service/verify_test.proto) + + - Messages + - [TestRequest](#service.TestRequest) + + +- [Scalar Value Types](#scalar-value-types) + + + + +

Top

+ +## service/meta.proto + + + + + + + +### Message RequestMetaHeader +RequestMetaHeader contains information about request meta headers +(should be embedded into message) + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| TTL | [uint32](#uint32) | | TTL must be larger than zero, it decreased in every NeoFS Node | +| Epoch | [uint64](#uint64) | | Epoch for user can be empty, because node sets epoch to the actual value | +| Version | [uint32](#uint32) | | Version defines protocol version TODO: not used for now, should be implemented in future | + + + + + + + + +

Top

+ +## service/verify.proto + + + + + + + +### Message RequestVerificationHeader +RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request +(should be embedded into message). + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| Signatures | [RequestVerificationHeader.Signature](#service.RequestVerificationHeader.Signature) | repeated | Signatures is a set of signatures of every passed NeoFS Node | + + + + +### Message RequestVerificationHeader.Sign + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| Sign | [bytes](#bytes) | | Sign is signature of the request or session key. | +| Peer | [bytes](#bytes) | | Peer is compressed public key used for signature. | + + + + +### Message RequestVerificationHeader.Signature + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| Sign | [RequestVerificationHeader.Sign](#service.RequestVerificationHeader.Sign) | | Sign is a signature and public key of the request. | +| Origin | [RequestVerificationHeader.Sign](#service.RequestVerificationHeader.Sign) | | Origin used for requests, when trusted node changes it and re-sign with session key. If session key used for signature request, then Origin should contain public key of user and signed session key. | + + + + + + + + +

Top

+ +## service/verify_test.proto + + + + + + + +### Message TestRequest + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| IntField | [int32](#int32) | | | +| StringField | [string](#string) | | | +| BytesField | [bytes](#bytes) | | | +| CustomField | [bytes](#bytes) | | | +| Meta | [RequestMetaHeader](#service.RequestMetaHeader) | | | +| Header | [RequestVerificationHeader](#service.RequestVerificationHeader) | | | + + + + + + + +## 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/docs/session.md b/docs/session.md index cf4a1fd0..e8633d39 100644 --- a/docs/session.md +++ b/docs/session.md @@ -70,6 +70,8 @@ session key. Session is established during 4-step handshake in one gRPC stream | ----- | ---- | ----- | ----------- | | Init | [Token](#session.Token) | | Init is a message to initialize session opening. Carry: owner of manipulation object; ID of manipulation object; token lifetime bounds. | | Signed | [Token](#session.Token) | | Signed Init message response (Unsigned) from server with user private key | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | diff --git a/docs/state.md b/docs/state.md index 6d240c1d..e678be32 100644 --- a/docs/state.md +++ b/docs/state.md @@ -70,6 +70,11 @@ If node unhealthy field Status would contains detailed info. HealthRequest message to check current state +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | + @@ -89,6 +94,11 @@ HealthResponse message with current state MetricsRequest message to request node metrics +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | + @@ -109,6 +119,11 @@ from github.com/prometheus/client_model/metrics.proto NetmapRequest message to request current node netmap +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| Meta | [service.RequestMetaHeader](#service.RequestMetaHeader) | | RequestMetaHeader contains information about request meta headers (should be embedded into message) | +| Verify | [service.RequestVerificationHeader](#service.RequestVerificationHeader) | | RequestVerificationHeader is a set of signatures of every NeoFS Node that processed request (should be embedded into message) | + From 1a9a840d1789ab58e8453f9e3590c7fa05888a70 Mon Sep 17 00:00:00 2001 From: Evgeniy Kulikov Date: Thu, 21 Nov 2019 15:21:37 +0300 Subject: [PATCH 11/12] proto: regenerate proto files --- object/service.pb.go | Bin 120649 -> 120751 bytes service/meta.pb.go | Bin 8671 -> 9851 bytes service/verify.pb.go | Bin 21382 -> 21894 bytes session/service.pb.go | Bin 27061 -> 27261 bytes state/service.pb.go | Bin 37509 -> 38187 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/object/service.pb.go b/object/service.pb.go index d58d391d176e2ba3de903b12eeeeeeaccf14ff9a..4cad2f7bbc2c66113fc0081b3d42a0700ebea040 100644 GIT binary patch delta 5345 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 delta 5261 zcmY+I&#N708OJ#nLz+|&N<;){W1vXtHO`!wbLJdHsEG&$SAqqxmCl?qgHdj7NN(W> z%CrbA6j~P}J)q)BSAr3<2yPUY;!ZcxZp2NXwWxo9=<|L)Z_ITw%z5X1pI_ha^W!~t z@1Fg`FVFt!=<4jb>9uQ5O~1JI@wz-bzIAeVvpwoR_gsJb&W+=nhqrDYpBz`0E`ICI z@y*X%dboOgbmOEyx^?oMOD|5}y!z$oua_U6es}fd>ATN7K3%`|%)JkN;a_K_&Gk=R z$Oq1!``-C;xBHWqZr{9EOs_on*!1r&eR2Bd^Jnh;`udfp59ZDEx8sv>dw8+f)qQ%F z9q;SI^XKA6k$w!z^xUq}bIE(L;eC;w9$2umuO6+p2wkjMsnc`Io&q`j76nb4K8zib zhI#t2=KEaPtTdck@vPN={sL1sywA&YcEx_J3q8q&IRlN!Y!SlW4>jq~>mwJ3&^Py5)g@(%T zVe!^Y7|>x-p{eZYSrImU+v*OdJiEZ&1uF|+76Tw1w*tw+@Rs zLQ(_9nw0^NT5ODnBp5`vV`<6fh67a+J?_@nog)J$gtcN*r*C?WEoxpVqDMocNd_9@ zMb8kgaBwM-9Ghbcr^ekDyR~@9yId(bP?c!VZke$ntkSo@BxUQu3U>^~!eC(0R(Ei) z24`Fg{WThTZQ^@raIw2p9=@54=9RS8U}2Ni6=tu{Y<@Nd$%uK_2q)@~ktSGX36KU` zG}qW7l|?K}4d}PX?y;!hJ?I9|8jmC9UKF=D(6heey*qU{6^_uqB|aN`mP%T*cnE-W zOB&Y5mdhr5&9NmeSY8%DvgYvG(5rwwfoF&d?#D9~m(VXu$|XL`aj`Tf*t_A~O%;+# zGB<~cJ+*;hXD(t`Ismlxwr0bY11$$4=405ggua#GMz$5DV`YJ)HC{DZ$GfpzvS*H- zhcNI%X7m_rkix@I))IylLZcie{ZeL$^@3s5(TdZV5xJ6J$a#e)79t@wxcat*A3Zuv zv0MS4HCqh?OiIXD%W+ik6eO`4z*fH54|+MlvmDT`Zx&O-ASC9Y z8EA*fg63#2mu-utZ->+#gKcK^8q1WGUNFp(rT%Y;Ov^JTt{Hv0Id-z15ZmQ+T{7gJ zA>G*de=xA#o`NA)y>0~c2B{XDIqzFQtT|!1+yJQNnNj9p3rH5CIeN_c;B$h(8mNbg z%WVwN>ycO)8Mmq-;|6--COme(Ejn9UbO{e_OF7?=J+SVi63HJt%vBj9&BkU#gN5BH zw(u}9+_VDClEfKcx^s~_Ww%htkJEe?2Af%fW|Lb-hKPTPlKs-L!J$TSxo%-KtdT$A z$pA>|u@IRJnQqn?T(S+idpB)Ar8%OzGAhm{pRulVOY+-&`iuu;H_U z*1XH1Kq)k*w#-v4OC@&aQ4!pNRw+nwT*Gnz;DG@U!xgxdtXpI)ge5$m zv+l5GXh&z4@H}a7Y!K)M(1l@X?vWEE0hsfCy35)vEF}v(%-s^rG1DXknw0xNGG^S> zxNGCh;G#h`8feR&Mb^2nqSBZpUJs&tCJoNV1wu_I!EkEws{__5#dh48AkL&Kj_I?F zatM*HfrJS z0nB^{^qmzwb&>zgUp>)o$hXS-n-j^BJg~Jl=rMnyuta#wqTGZDSV6wq74m(Cb$Kg2 z;y#mHh}b@wzsyaWL%z|W!F!zpi3KV{k5tKR)p77K#Ts3Z*15AI&H(66Oif9Dt_>8w zJPQ#FiCz=W7?onD`QiRZsN_Sw(s5vo>kh`UO7s*Y={#(2iua^nB>i9>bRZVhI%#k& zaKz=#w##EZ{s__>{c=*BUPNWG+LpMWBO4Mu;2e{N2v(TkQ)3+8y-OL~eA>Ve5{D4) zO@im0XaPyG{(OrTN!i1@RkSLZzZ^_*M-&G5Znzy4C4ky`vflYKW{Tv3RV;G_66ZTO zI?aPQ@Z@sj`WpQb%7IaWI)7F)&G7sY3{E)mFoOsWmxLr24m`}ad~6xm;{Yy69Cq6l z{e7kqnWkF>Cmfsd{e_U6Zpaoq8JoEeZ!A#KZ~*kspIq=hY|7d$2j?$iW%0|FK@cv(2eGu&2D^T66{rP(}Bh*w0+mLeJK^?3k?5;2AYw2co( zoyBssWW{MlB#YtR&%XbUVLEv42h+FTzA*j#z28j5J0Cc6W4L&9W%|*(pPk-*_sQ96 zdg_m#oL+qYBlmv#_dh?qfA+E2nf-sBm|gi`{ul4^<@g_OfBeMk)%}k@I(sm^`QWkp zpT02r#GU<Kn5^?O%9v_Lco#zCQcv{kLA5y?(I2`;B;g Y>GjzU5AOfu_p{%gy?^x9?CR(L3zV!yG5`Po diff --git a/service/meta.pb.go b/service/meta.pb.go index 9fbd28355b6d459c9076bcd9c295d248617a5c20..d5f58fdf0784197df92472b3a3d04133e80bf08a 100644 GIT binary patch delta 1120 zcmYjQ-D(p-6sB8gv#COfP_0*opwhx>_9sn~f}m&%LTxV^#9q$Mo^2x8owz&OAEo30 z^g`Gd5km1sFTC>!1h0Gm#TTf8GiQ?4Tzs58^ZlGNOny8*-~RB~vKo!@i*>!rMJic8 z&7q&hB1@R;ixgNW3JDp$DlnIjpk&ZP7GaiG8x2^=d!iUb5F%g_ViaMd)KVy7p0fj7 zEk9ZHXNuVEZbMQi2gMw)>;N;6J(j|2%!C7d2@&!PSx$PuL(EQK2gTMN?1%`fw$>NQ zIq=JK>(Rb)+#Cwt12rfVxpL#mjHVdM6Gv5?sWzla3^~dikmzbM*+XDl7Hj~AY)~j~ z-QoYASx;W-HZCDaz5+3{HfE2*V)DOs^{C;&|zfA#dq)mN_3H5X%bs4(l8Ki;Du}?M9c#J$4 z$vRY{S&BG}wAi8qMlEA!#7!E0&DV-hqqzBu;i*rS{d?bD*#H3I6mw5>wAf4Z2M z&`{fSF&^#4sgL3K=e2$7;t@Pu^e*br;?0?Md0JZ@?=7a6ly|k;Q_A?P_HAyCtG^-y t<(sAMoyohZJ8;y`uzNDZ)v9gVry7#`(^vOv>Fd;?{CHz){C2rp`3DtNQqTYZ delta 499 zcmYjNJxjzu6y%bq=ZPZ7Rf3$=Asn(F$zB#4QS7daSZ9+9+Ng!fHIjc|vwygNpm`vu)+c*1uXP>9b*T|0J{k5W)jr_46$$@>24|mUQZ>mdDy667t z`c9?xCmGt4M7X1s@5DY0zG9wd?qTDl*EeD^VvD(Qa`U*?PU*)OLM{pO2IUk=PAH(r zintb&!8%(gSPi6xQz3;lpA!#C1zo@?HR+Wi5EDQ}CQM-yp zwG19S!N;SnlCZ=yjqn=18oF2L2^q?5=w|3PNX)|m;H_a2ScU|b$Wr4zj@TRu>tGWm k_>Ye<#R3#K3#-BcYH)Y4eIB{3oyW+%4c}MYc(3UH0jW`e7ytkO diff --git a/service/verify.pb.go b/service/verify.pb.go index 3c0f357ec62f5c1b9f723676d4a9c1e2355febde..95a94527cf7b9f61312b264b05f837741b083cad 100644 GIT binary patch delta 648 zcmaixy-or_6omsA5-?F{G_mp8sX?|OvC)VYMlH~U${34f_p&0ynsF_lLr>iR zH_GNUy}3s(>xspG&Rut8lK>1q(!1H}M8tys@>*OSVvGbrQY59A;LyT;IiIt(aBMgzmm(P5knQ)&Kwi delta 117 zcmZo$&Dge_al?KlmXgYX)X4{#q&bR9ib|796sk9`VYX#s3C>KF3{3WBQJlP+MPRZXw;(H6aI(Cx N8<=2&4(CjjQeB0>NF diff --git a/session/service.pb.go b/session/service.pb.go index eef58192979350812ad2f5ceb3ffabf56c925878..853252394b03b14c32b22b18ab6e1031b03a07df 100644 GIT binary patch delta 277 zcmaivJxT;Y6ogrvz%?*15ka9sP29v2Y#=6Xpkm%LU9;1$(@*=oSupYl27LohAc(1# z(A+DSX(HJE#fAl6{XIO5KAuN+sPfHtGoP*Rw37)=csWq*nC6b?JQEs;=0a42*h=c1 z1&MIA42JXrqc1eNZ(OmfoeT?)nqXhkd-`HEDU_<4b1yHd?fhPCDD!Z z!a-?}78>T!*^sDTic6*|%qWMan29H>bB2o~O$jXFe=GhiUK=aZGBn)(eR<9l+R&6s M`E|N_|5iQvPY_dPO8@`> delta 55 xcmex+g>ma;#tjNAlfU!v@+csI$%b5#lPy?eChuX9Vuy-PzRKdhc^>Qi6adQ(57Phu diff --git a/state/service.pb.go b/state/service.pb.go index 8e66a2f8fd1094e11e3cfe81e9efb57e402459ae..520c8ce62a096ee60474980a3e512a8e2acf5669 100644 GIT binary patch delta 722 zcmZo&%CveF(}usyY5MvKL8*nMsl_F}sU?XXsfj76MGDFJc_oRNdBqBud1?7Yxrrs2 z`FRS7N%^HE3Pljb3b{bl3K?MK#R?k58Tq9-DGEuc3aPnCsVOO`DL}0y`9M|0#fj;u znv;Js%S>)(5tbP)g RKOoC7dA Date: Thu, 21 Nov 2019 16:35:17 +0300 Subject: [PATCH 12/12] docs: create changelog --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..e4b71c82 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,22 @@ +# Changelog +This is the changelog for NeoFS Proto + +## [0.2.0] - 2019-11-21 + +### Added +- Container not found error +- GitHub Actions as CI and Codecov +- Auto-generated proto documentation +- RequestMetaHeader to all RPC requests +- RequestVerificationHeader to all RPC requests + +### Changed +- Moved TTL and Epoch fields to RequestMetaHeader +- Renamed Version in object.SearchRequest to QueryVersion +- Removed SetTTL, GetTTL, SetEpoch, GetEpoch from all RPC requests + +## 0.1.0 - 2019-11-18 + +Initial public release + +[0.2.0]: https://github.com/nspcc-dev/neofs-proto/compare/v0.1.0...v0.2.0