From 9500ae4a78af2cd9dfacdb5a9ff962015ec50a64 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 26 Jul 2023 15:47:32 +0300 Subject: [PATCH 1/4] [#533] services: Assume API supports status codes Signed-off-by: Evgenii Stratonikov --- pkg/services/accounting/sign.go | 2 +- pkg/services/container/sign.go | 28 ++++++++--------- pkg/services/netmap/sign.go | 12 +++---- pkg/services/object/sign.go | 55 ++++++++++++++------------------- pkg/services/session/sign.go | 4 +-- pkg/services/util/sign.go | 16 +--------- 6 files changed, 47 insertions(+), 70 deletions(-) diff --git a/pkg/services/accounting/sign.go b/pkg/services/accounting/sign.go index be7b08a39..cd6ff0307 100644 --- a/pkg/services/accounting/sign.go +++ b/pkg/services/accounting/sign.go @@ -23,5 +23,5 @@ func NewSignService(key *ecdsa.PrivateKey, svc Server) Server { func (s *signService) Balance(ctx context.Context, req *accounting.BalanceRequest) (*accounting.BalanceResponse, error) { resp, err := util.EnsureNonNilResponse(s.svc.Balance(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } diff --git a/pkg/services/container/sign.go b/pkg/services/container/sign.go index b336f19c3..bba717f60 100644 --- a/pkg/services/container/sign.go +++ b/pkg/services/container/sign.go @@ -24,62 +24,62 @@ func NewSignService(key *ecdsa.PrivateKey, svc Server) Server { func (s *signService) Put(ctx context.Context, req *container.PutRequest) (*container.PutResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(container.PutResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.Put(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *signService) Delete(ctx context.Context, req *container.DeleteRequest) (*container.DeleteResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(container.DeleteResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.Delete(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *signService) Get(ctx context.Context, req *container.GetRequest) (*container.GetResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(container.GetResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.Get(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *signService) List(ctx context.Context, req *container.ListRequest) (*container.ListResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(container.ListResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.List(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *signService) SetExtendedACL(ctx context.Context, req *container.SetExtendedACLRequest) (*container.SetExtendedACLResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(container.SetExtendedACLResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.SetExtendedACL(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *signService) GetExtendedACL(ctx context.Context, req *container.GetExtendedACLRequest) (*container.GetExtendedACLResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(container.GetExtendedACLResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.GetExtendedACL(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *signService) AnnounceUsedSpace(ctx context.Context, req *container.AnnounceUsedSpaceRequest) (*container.AnnounceUsedSpaceResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(container.AnnounceUsedSpaceResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.AnnounceUsedSpace(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } diff --git a/pkg/services/netmap/sign.go b/pkg/services/netmap/sign.go index 2d01164a3..305d3443e 100644 --- a/pkg/services/netmap/sign.go +++ b/pkg/services/netmap/sign.go @@ -26,26 +26,26 @@ func (s *signService) LocalNodeInfo( req *netmap.LocalNodeInfoRequest) (*netmap.LocalNodeInfoResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(netmap.LocalNodeInfoResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.LocalNodeInfo(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *signService) NetworkInfo(ctx context.Context, req *netmap.NetworkInfoRequest) (*netmap.NetworkInfoResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(netmap.NetworkInfoResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.NetworkInfo(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *signService) Snapshot(ctx context.Context, req *netmap.SnapshotRequest) (*netmap.SnapshotResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(netmap.SnapshotResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.Snapshot(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } diff --git a/pkg/services/object/sign.go b/pkg/services/object/sign.go index c516872e3..f4f40dd7c 100644 --- a/pkg/services/object/sign.go +++ b/pkg/services/object/sign.go @@ -19,29 +19,25 @@ type SignService struct { type searchStreamSigner struct { SearchStream - statusSupported bool - sigSvc *util.SignService + sigSvc *util.SignService nonEmptyResp bool // set on first Send call } type getStreamSigner struct { GetObjectStream - statusSupported bool - sigSvc *util.SignService + sigSvc *util.SignService } type putStreamSigner struct { - sigSvc *util.SignService - stream PutObjectStream - statusSupported bool - err error + sigSvc *util.SignService + stream PutObjectStream + err error } type getRangeStreamSigner struct { GetObjectRangeStream - statusSupported bool - sigSvc *util.SignService + sigSvc *util.SignService } func NewSignService(key *ecdsa.PrivateKey, svc ServiceServer) *SignService { @@ -53,7 +49,7 @@ func NewSignService(key *ecdsa.PrivateKey, svc ServiceServer) *SignService { } func (s *getStreamSigner) Send(resp *object.GetResponse) error { - if err := s.sigSvc.SignResponse(s.statusSupported, resp, nil); err != nil { + if err := s.sigSvc.SignResponse(resp, nil); err != nil { return err } return s.GetObjectStream.Send(resp) @@ -62,20 +58,17 @@ func (s *getStreamSigner) Send(resp *object.GetResponse) error { func (s *SignService) Get(req *object.GetRequest, stream GetObjectStream) error { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(object.GetResponse) - _ = s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + _ = s.sigSvc.SignResponse(resp, err) return stream.Send(resp) } return s.svc.Get(req, &getStreamSigner{ GetObjectStream: stream, sigSvc: s.sigSvc, - statusSupported: util.IsStatusSupported(req), }) } func (s *putStreamSigner) Send(ctx context.Context, req *object.PutRequest) error { - s.statusSupported = util.IsStatusSupported(req) - if s.err = s.sigSvc.VerifyRequest(req); s.err != nil { return util.ErrAbortStream } @@ -96,7 +89,7 @@ func (s *putStreamSigner) CloseAndRecv(ctx context.Context) (resp *object.PutRes } } - return resp, s.sigSvc.SignResponse(s.statusSupported, resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *SignService) Put() (PutObjectStream, error) { @@ -114,24 +107,24 @@ func (s *SignService) Put() (PutObjectStream, error) { func (s *SignService) Head(ctx context.Context, req *object.HeadRequest) (*object.HeadResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(object.HeadResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.Head(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *SignService) PutSingle(ctx context.Context, req *object.PutSingleRequest) (*object.PutSingleResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(object.PutSingleResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.PutSingle(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *searchStreamSigner) Send(resp *object.SearchResponse) error { s.nonEmptyResp = true - if err := s.sigSvc.SignResponse(s.statusSupported, resp, nil); err != nil { + if err := s.sigSvc.SignResponse(resp, nil); err != nil { return err } return s.SearchStream.Send(resp) @@ -140,14 +133,13 @@ func (s *searchStreamSigner) Send(resp *object.SearchResponse) error { func (s *SignService) Search(req *object.SearchRequest, stream SearchStream) error { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(object.SearchResponse) - _ = s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + _ = s.sigSvc.SignResponse(resp, err) return stream.Send(resp) } ss := &searchStreamSigner{ - SearchStream: stream, - sigSvc: s.sigSvc, - statusSupported: util.IsStatusSupported(req), + SearchStream: stream, + sigSvc: s.sigSvc, } err := s.svc.Search(req, ss) if err == nil && !ss.nonEmptyResp { @@ -164,14 +156,14 @@ func (s *SignService) Search(req *object.SearchRequest, stream SearchStream) err func (s *SignService) Delete(ctx context.Context, req *object.DeleteRequest) (*object.DeleteResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(object.DeleteResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.Delete(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } func (s *getRangeStreamSigner) Send(resp *object.GetRangeResponse) error { - if err := s.sigSvc.SignResponse(s.statusSupported, resp, nil); err != nil { + if err := s.sigSvc.SignResponse(resp, nil); err != nil { return err } return s.GetObjectRangeStream.Send(resp) @@ -180,22 +172,21 @@ func (s *getRangeStreamSigner) Send(resp *object.GetRangeResponse) error { func (s *SignService) GetRange(req *object.GetRangeRequest, stream GetObjectRangeStream) error { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(object.GetRangeResponse) - _ = s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + _ = s.sigSvc.SignResponse(resp, err) return stream.Send(resp) } return s.svc.GetRange(req, &getRangeStreamSigner{ GetObjectRangeStream: stream, sigSvc: s.sigSvc, - statusSupported: util.IsStatusSupported(req), }) } func (s *SignService) GetRangeHash(ctx context.Context, req *object.GetRangeHashRequest) (*object.GetRangeHashResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(object.GetRangeHashResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.GetRangeHash(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } diff --git a/pkg/services/session/sign.go b/pkg/services/session/sign.go index ffce0621e..690fff896 100644 --- a/pkg/services/session/sign.go +++ b/pkg/services/session/sign.go @@ -24,8 +24,8 @@ func NewSignService(key *ecdsa.PrivateKey, svc Server) Server { func (s *signService) Create(ctx context.Context, req *session.CreateRequest) (*session.CreateResponse, error) { if err := s.sigSvc.VerifyRequest(req); err != nil { resp := new(session.CreateResponse) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } resp, err := util.EnsureNonNilResponse(s.svc.Create(ctx, req)) - return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err) + return resp, s.sigSvc.SignResponse(resp, err) } diff --git a/pkg/services/util/sign.go b/pkg/services/util/sign.go index a26bd311c..26586ff49 100644 --- a/pkg/services/util/sign.go +++ b/pkg/services/util/sign.go @@ -36,12 +36,8 @@ func NewUnarySignService(key *ecdsa.PrivateKey) *SignService { // The signature error affects the result depending on the protocol version: // - if status return is supported, panics since we cannot return the failed status, because it will not be signed. // - otherwise, returns error in order to transport it directly. -func (s *SignService) SignResponse(statusSupported bool, resp ResponseMessage, err error) error { +func (s *SignService) SignResponse(resp ResponseMessage, err error) error { if err != nil { - if !statusSupported { - return err - } - setStatusV2(resp, err) } @@ -70,16 +66,6 @@ func EnsureNonNilResponse[T any](resp *T, err error) (*T, error) { return new(T), err } -// IsStatusSupported returns true iff request version implies expecting status return. -// This allows us to handle protocol versions <=2.10 (API statuses was introduced in 2.11 only). -func IsStatusSupported(req RequestMessage) bool { - version := req.GetMetaHeader().GetVersion() - - mjr := version.GetMajor() - - return mjr > 2 || mjr == 2 && version.GetMinor() >= 11 -} - func setStatusV2(resp ResponseMessage, err error) { // unwrap error for e := errors.Unwrap(err); e != nil; e = errors.Unwrap(err) { -- 2.45.2 From c5b015a9adf93c31741a2e68c3d076f3810864ee Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 26 Jul 2023 16:01:02 +0300 Subject: [PATCH 2/4] [#547] objectsvc: Work with `traversal` struct from a single thread Signed-off-by: Evgenii Stratonikov --- pkg/services/object/put/distributed.go | 20 ++++++-------------- pkg/services/object/put/single.go | 5 ++--- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/pkg/services/object/put/distributed.go b/pkg/services/object/put/distributed.go index cf5cc558e..f4afd44aa 100644 --- a/pkg/services/object/put/distributed.go +++ b/pkg/services/object/put/distributed.go @@ -47,9 +47,6 @@ type traversal struct { // need of additional broadcast after the object is saved extraBroadcastEnabled bool - // mtx protects mExclude map. - mtx sync.RWMutex - // container nodes which was processed during the primary object placement mExclude map[string]struct{} } @@ -75,21 +72,17 @@ func (x *traversal) submitProcessed(n placement.Node) { if x.extraBroadcastEnabled { key := string(n.PublicKey()) - x.mtx.Lock() if x.mExclude == nil { x.mExclude = make(map[string]struct{}, 1) } x.mExclude[key] = struct{}{} - x.mtx.Unlock() } } // checks if specified node was processed during the primary object placement. func (x *traversal) processed(n placement.Node) bool { - x.mtx.RLock() _, ok := x.mExclude[string(n.PublicKey())] - x.mtx.RUnlock() return ok } @@ -235,13 +228,6 @@ func (t *distributedTarget) iterateAddresses(ctx context.Context, traverser *pla defer wg.Done() err := t.sendObject(ctx, nodeDesc{local: isLocal, info: addr}) - - // mark the container node as processed in order to exclude it - // in subsequent container broadcast. Note that we don't - // process this node during broadcast if primary placement - // on it failed. - t.traversal.submitProcessed(addr) - if err != nil { resErr.Store(err) svcutil.LogServiceError(t.log, "PUT", addr.Addresses(), err) @@ -254,6 +240,12 @@ func (t *distributedTarget) iterateAddresses(ctx context.Context, traverser *pla svcutil.LogWorkerPoolError(t.log, "PUT", err) return true } + + // mark the container node as processed in order to exclude it + // in subsequent container broadcast. Note that we don't + // process this node during broadcast if primary placement + // on it failed. + t.traversal.submitProcessed(addr) } wg.Wait() diff --git a/pkg/services/object/put/single.go b/pkg/services/object/put/single.go index 200830e15..fbbf11597 100644 --- a/pkg/services/object/put/single.go +++ b/pkg/services/object/put/single.go @@ -152,7 +152,6 @@ func (s *Service) saveToNodes(ctx context.Context, obj *objectSDK.Object, req *o opts: placementOptions, extraBroadcastEnabled: len(obj.Children()) > 0 || (!localOnly && (obj.Type() == objectSDK.TypeTombstone || obj.Type() == objectSDK.TypeLock)), - mtx: sync.RWMutex{}, mExclude: make(map[string]struct{}), } signer := &putSingleRequestSigner{ @@ -261,8 +260,6 @@ func (s *Service) saveToPlacementNodes(ctx context.Context, err := s.saveToPlacementNode(ctx, &nodeDesc{local: local, info: nodeAddress}, obj, signer) - traversal.submitProcessed(nodeAddress) - if err != nil { resultError.Store(err) svcutil.LogServiceError(s.log, "PUT", nodeAddress.Addresses(), err) @@ -275,6 +272,8 @@ func (s *Service) saveToPlacementNodes(ctx context.Context, svcutil.LogWorkerPoolError(s.log, "PUT", err) return true } + + traversal.submitProcessed(nodeAddress) } wg.Wait() -- 2.45.2 From e1141c2456edd066eec46cf366764020943f0f16 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 26 Jul 2023 16:02:08 +0300 Subject: [PATCH 3/4] [#547] metabase: Fix datarace in tests Quite an old one bf9e938a3b2829199. Signed-off-by: Evgenii Stratonikov --- pkg/local_object_storage/metabase/put.go | 1 + pkg/local_object_storage/metabase/select.go | 1 + pkg/local_object_storage/metabase/util.go | 2 -- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/local_object_storage/metabase/put.go b/pkg/local_object_storage/metabase/put.go index 7a24485b3..28f12851f 100644 --- a/pkg/local_object_storage/metabase/put.go +++ b/pkg/local_object_storage/metabase/put.go @@ -111,6 +111,7 @@ func (db *DB) put(tx *bbolt.Tx, exists, err := db.exists(tx, objectCore.AddressOf(obj), currEpoch) + var splitInfoError *objectSDK.SplitInfoError if errors.As(err, &splitInfoError) { exists = true // object exists, however it is virtual } else if err != nil { diff --git a/pkg/local_object_storage/metabase/select.go b/pkg/local_object_storage/metabase/select.go index 6a7acd7cc..8b086a89f 100644 --- a/pkg/local_object_storage/metabase/select.go +++ b/pkg/local_object_storage/metabase/select.go @@ -427,6 +427,7 @@ func (db *DB) selectObjectID( addr.SetContainer(cnr) addr.SetObject(id) + var splitInfoError *objectSDK.SplitInfoError ok, err := db.exists(tx, addr, currEpoch) if (err == nil && ok) || errors.As(err, &splitInfoError) { raw := make([]byte, objectKeySize) diff --git a/pkg/local_object_storage/metabase/util.go b/pkg/local_object_storage/metabase/util.go index 4e58ec20b..c9d9bb947 100644 --- a/pkg/local_object_storage/metabase/util.go +++ b/pkg/local_object_storage/metabase/util.go @@ -120,8 +120,6 @@ const ( addressKeySize = cidSize + objectKeySize ) -var splitInfoError *objectSDK.SplitInfoError // for errors.As comparisons - func bucketName(cnr cid.ID, prefix byte, key []byte) []byte { key[0] = prefix cnr.Encode(key[1:]) -- 2.45.2 From 1983b03617cb6599c49509e431370cf852051c95 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Mon, 31 Jul 2023 14:35:07 +0300 Subject: [PATCH 4/4] [#547] go.mod: Update api-go, sdk-go Signed-off-by: Evgenii Stratonikov --- go.mod | 4 ++-- go.sum | Bin 99007 -> 99007 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 2e7d8fd56..05e720a75 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module git.frostfs.info/TrueCloudLab/frostfs-node go 1.19 require ( - git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.15.1-0.20230719100335-582d94c81c74 + git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.15.1-0.20230726155259-7a5ee927c8a2 git.frostfs.info/TrueCloudLab/frostfs-contract v0.0.0-20230627134746-36f3d39c406a git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6 - git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20230719130356-5defed4ab435 + git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20230731113339-0fe0d716784b git.frostfs.info/TrueCloudLab/hrw v1.2.1 git.frostfs.info/TrueCloudLab/tzhash v1.8.0 github.com/cheggaaa/pb v1.0.29 diff --git a/go.sum b/go.sum index c8737ebdc0f41b608ce700934e28be010bf10068..e3310bbe583d2a4909bd4d117a77e3ffde341ba7 100644 GIT binary patch delta 279 zcmdnr%C^6iZG#Q3i;cK&q2Lxv5F6)ytr|0YC=BI$n^b3zPbv6!23-fdGFVio`@XN6DvM`GZOev1Y k_bdtW3#hPguM9}dNp%YanyE0kMu@9fS7^Jg5aXl*0Bd+sIRF3v delta 278 zcmdnr%C^6iZG#Q3i=m~Vfq}8HsjjJoQHrHWvV~!?xrsuCp;bkCYH(FlfQdnHlCN)= zdz!mpn0ZB!vqi4COR!l^PLySKc9y@TkA-$tQNk0TIA(!9#rOLWE$-4 zk!~=#o>z0SilB%$R!rZIM$q -- 2.45.2