From 8cfa9a49372bd3acf6c4e01ce66cb4f24a47f085 Mon Sep 17 00:00:00 2001 From: Pavel Gross Date: Mon, 9 Dec 2024 23:54:50 +0300 Subject: [PATCH 1/3] [#28] Client: add method to calculate ObjectId Signed-off-by: Pavel Gross --- src/FrostFS.SDK.Client/FrostFSClient.cs | 8 ++++ .../Interfaces/IFrostFSClient.cs | 2 + .../Models/Object/FrostFsSplitInfo.cs | 6 ++- src/FrostFS.SDK.Client/Pool/Pool.cs | 12 ++++++ .../Services/ObjectServiceProvider.cs | 2 +- src/FrostFS.SDK.Client/Tools/ObjectTools.cs | 38 ++++++++++++++----- 6 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/FrostFS.SDK.Client/FrostFSClient.cs b/src/FrostFS.SDK.Client/FrostFSClient.cs index eea24fc..9135f27 100644 --- a/src/FrostFS.SDK.Client/FrostFSClient.cs +++ b/src/FrostFS.SDK.Client/FrostFSClient.cs @@ -290,6 +290,14 @@ public class FrostFSClient : IFrostFSClient { return GetObjectService().SearchObjectsAsync(args, ctx); } + + public FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header) + { + if (header == null) + throw new ArgumentNullException(nameof(header)); + + return ObjectTools.CalculateObjectId(header, ClientCtx.Owner, ClientCtx.Version, ClientCtx.Key); + } #endregion #region Session Implementation diff --git a/src/FrostFS.SDK.Client/Interfaces/IFrostFSClient.cs b/src/FrostFS.SDK.Client/Interfaces/IFrostFSClient.cs index cce7364..160e4e0 100644 --- a/src/FrostFS.SDK.Client/Interfaces/IFrostFSClient.cs +++ b/src/FrostFS.SDK.Client/Interfaces/IFrostFSClient.cs @@ -65,4 +65,6 @@ public interface IFrostFSClient #endregion public Task Dial(CallContext ctx); + + FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header); } diff --git a/src/FrostFS.SDK.Client/Models/Object/FrostFsSplitInfo.cs b/src/FrostFS.SDK.Client/Models/Object/FrostFsSplitInfo.cs index 5030410..d8f8783 100644 --- a/src/FrostFS.SDK.Client/Models/Object/FrostFsSplitInfo.cs +++ b/src/FrostFS.SDK.Client/Models/Object/FrostFsSplitInfo.cs @@ -20,7 +20,9 @@ public class FrostFsSplitInfo public SplitId SplitId => _splitId ??= new SplitId(_splitInfo.SplitId.ToUuid()); - public FrostFsObjectId Link => _link ??= FrostFsObjectId.FromHash(_splitInfo.Link.Value.Span); + public FrostFsObjectId? Link => _link ??= _splitInfo.Link == null + ? null : FrostFsObjectId.FromHash(_splitInfo.Link.Value.Span); - public FrostFsObjectId LastPart => _lastPart ??= FrostFsObjectId.FromHash(_splitInfo.LastPart.Value.Span); + public FrostFsObjectId? LastPart => _lastPart ??= _splitInfo.LastPart == null + ? null : FrostFsObjectId.FromHash(_splitInfo.LastPart.Value.Span); } diff --git a/src/FrostFS.SDK.Client/Pool/Pool.cs b/src/FrostFS.SDK.Client/Pool/Pool.cs index b4bb357..56ac3bf 100644 --- a/src/FrostFS.SDK.Client/Pool/Pool.cs +++ b/src/FrostFS.SDK.Client/Pool/Pool.cs @@ -39,6 +39,8 @@ public partial class Pool : IFrostFSClient private OwnerID? _ownerId; + private FrostFsVersion _version; + private FrostFsOwner? _owner; private FrostFsOwner Owner @@ -94,6 +96,8 @@ public partial class Pool : IFrostFSClient throw new ArgumentException($"Missed required parameter {nameof(options.Key)}"); } + _version = new FrostFsVersion(2, 13); + var nodesParams = AdjustNodeParams(options.NodeParams); var cache = new SessionCache(options.SessionExpirationDuration); @@ -642,6 +646,14 @@ public partial class Pool : IFrostFSClient return client.Client!.SearchObjectsAsync(args, ctx); } + public FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header) + { + if (header == null) + throw new ArgumentNullException(nameof(header)); + + return ObjectTools.CalculateObjectId(header, Owner, _version, Key); + } + public async Task GetBalanceAsync(CallContext ctx) { var client = Connection(); diff --git a/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs b/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs index 8561b50..133d2e3 100644 --- a/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs +++ b/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs @@ -565,7 +565,7 @@ internal sealed class ObjectServiceProvider(ObjectService.ObjectServiceClient cl if (header.Split != null) { - ObjectTools.SetSplitValues(grpcHeader, header.Split, ClientContext); + ObjectTools.SetSplitValues(grpcHeader, header.Split, ClientContext.Owner, ClientContext.Version, ClientContext.Key); } var oid = new ObjectID { Value = grpcHeader.Sha256() }; diff --git a/src/FrostFS.SDK.Client/Tools/ObjectTools.cs b/src/FrostFS.SDK.Client/Tools/ObjectTools.cs index 58f9f30..fdc9a23 100644 --- a/src/FrostFS.SDK.Client/Tools/ObjectTools.cs +++ b/src/FrostFS.SDK.Client/Tools/ObjectTools.cs @@ -11,6 +11,20 @@ namespace FrostFS.SDK.Client; internal static class ObjectTools { + internal static FrostFsObjectId CalculateObjectId( + FrostFsObjectHeader header, + FrostFsOwner owner, + FrostFsVersion version, + ClientKey key) + { + var grpcHeader = CreateHeader(header, [], owner, version); + + if (header.Split != null) + SetSplitValues(grpcHeader, header.Split, owner, version, key); + + return new ObjectID { Value = grpcHeader.Sha256() }.ToModel(); + } + internal static Object.Object CreateObject(FrostFsObject @object, ClientContext ctx) { @object.Header.OwnerId ??= ctx.Owner; @@ -24,7 +38,7 @@ internal static class ObjectTools var split = @object.Header.Split; if (split != null) { - SetSplitValues(grpcHeader, split, ctx); + SetSplitValues(grpcHeader, split, ctx.Owner, ctx.Version, ctx.Key); } var obj = new Object.Object @@ -43,13 +57,17 @@ internal static class ObjectTools return obj; } - internal static void SetSplitValues(Header grpcHeader, FrostFsSplit split, ClientContext ctx) + internal static void SetSplitValues( + Header grpcHeader, + FrostFsSplit split, + FrostFsOwner owner, FrostFsVersion version, + ClientKey key) { if (split == null) return; - if (ctx.Key == null) - throw new FrostFsInvalidObjectException(nameof(ctx.Key)); + if (key == null) + throw new FrostFsInvalidObjectException(nameof(key)); grpcHeader.Split = new Header.Types.Split { @@ -61,24 +79,24 @@ internal static class ObjectTools if (split.ParentHeader is not null) { - var grpcParentHeader = CreateHeader(split.ParentHeader, [], ctx); + var grpcParentHeader = CreateHeader(split.ParentHeader, [], owner, version); grpcHeader.Split.Parent = new ObjectID { Value = grpcParentHeader.Sha256() }; grpcHeader.Split.ParentHeader = grpcParentHeader; grpcHeader.Split.ParentSignature = new Signature { - Key = ctx.Key.PublicKeyProto, - Sign = ctx.Key.ECDsaKey.SignData(grpcHeader.Split.Parent.ToByteArray()), + Key = key.PublicKeyProto, + Sign = key.ECDsaKey.SignData(grpcHeader.Split.Parent.ToByteArray()), }; } grpcHeader.Split.Previous = split.Previous?.ToMessage(); } - internal static Header CreateHeader(FrostFsObjectHeader header, byte[]? payload, ClientContext ctx) + internal static Header CreateHeader(FrostFsObjectHeader header, byte[]? payload, FrostFsOwner owner, FrostFsVersion version) { - header.OwnerId ??= ctx.Owner; - header.Version ??= ctx.Version; + header.OwnerId ??= owner; + header.Version ??= version; var grpcHeader = header.GetHeader(); -- 2.45.2 From a643baa4afcfc7cdb12a76f069bd15e9d7a97832 Mon Sep 17 00:00:00 2001 From: Pavel Gross Date: Tue, 10 Dec 2024 15:01:28 +0300 Subject: [PATCH 2/3] [#28] Client: Move CalculateObjectId from IFrostFsClient to statis tools Signed-off-by: Pavel Gross --- src/FrostFS.SDK.Client/FrostFSClient.cs | 8 ------ .../Interfaces/IFrostFSClient.cs | 2 -- src/FrostFS.SDK.Client/Pool/Pool.cs | 8 ------ src/FrostFS.SDK.Client/Tools/ObjectTools.cs | 25 +++++++++++++++++-- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/FrostFS.SDK.Client/FrostFSClient.cs b/src/FrostFS.SDK.Client/FrostFSClient.cs index 9135f27..eea24fc 100644 --- a/src/FrostFS.SDK.Client/FrostFSClient.cs +++ b/src/FrostFS.SDK.Client/FrostFSClient.cs @@ -290,14 +290,6 @@ public class FrostFSClient : IFrostFSClient { return GetObjectService().SearchObjectsAsync(args, ctx); } - - public FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header) - { - if (header == null) - throw new ArgumentNullException(nameof(header)); - - return ObjectTools.CalculateObjectId(header, ClientCtx.Owner, ClientCtx.Version, ClientCtx.Key); - } #endregion #region Session Implementation diff --git a/src/FrostFS.SDK.Client/Interfaces/IFrostFSClient.cs b/src/FrostFS.SDK.Client/Interfaces/IFrostFSClient.cs index 160e4e0..cce7364 100644 --- a/src/FrostFS.SDK.Client/Interfaces/IFrostFSClient.cs +++ b/src/FrostFS.SDK.Client/Interfaces/IFrostFSClient.cs @@ -65,6 +65,4 @@ public interface IFrostFSClient #endregion public Task Dial(CallContext ctx); - - FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header); } diff --git a/src/FrostFS.SDK.Client/Pool/Pool.cs b/src/FrostFS.SDK.Client/Pool/Pool.cs index 56ac3bf..3abfe60 100644 --- a/src/FrostFS.SDK.Client/Pool/Pool.cs +++ b/src/FrostFS.SDK.Client/Pool/Pool.cs @@ -646,14 +646,6 @@ public partial class Pool : IFrostFSClient return client.Client!.SearchObjectsAsync(args, ctx); } - public FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header) - { - if (header == null) - throw new ArgumentNullException(nameof(header)); - - return ObjectTools.CalculateObjectId(header, Owner, _version, Key); - } - public async Task GetBalanceAsync(CallContext ctx) { var client = Connection(); diff --git a/src/FrostFS.SDK.Client/Tools/ObjectTools.cs b/src/FrostFS.SDK.Client/Tools/ObjectTools.cs index fdc9a23..7abdbaf 100644 --- a/src/FrostFS.SDK.Client/Tools/ObjectTools.cs +++ b/src/FrostFS.SDK.Client/Tools/ObjectTools.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using FrostFS.Object; @@ -9,14 +10,34 @@ using Google.Protobuf; namespace FrostFS.SDK.Client; -internal static class ObjectTools +public static class ObjectTools { - internal static FrostFsObjectId CalculateObjectId( + public static FrostFsObjectId CalculateObjectId( FrostFsObjectHeader header, FrostFsOwner owner, FrostFsVersion version, ClientKey key) { + if (header is null) + { + throw new ArgumentNullException(nameof(header)); + } + + if (owner is null) + { + throw new ArgumentNullException(nameof(owner)); + } + + if (version is null) + { + throw new ArgumentNullException(nameof(version)); + } + + if (key is null) + { + throw new ArgumentNullException(nameof(key)); + } + var grpcHeader = CreateHeader(header, [], owner, version); if (header.Split != null) -- 2.45.2 From 7fd60805e78f60f26d0c970ffa4d2daf6dd538c5 Mon Sep 17 00:00:00 2001 From: Pavel Gross Date: Wed, 11 Dec 2024 12:57:56 +0300 Subject: [PATCH 3/3] [#28] Client: Move CalculateObjectId from IFrostFsClient to statis tools Get payload hash as an argument Signed-off-by: Pavel Gross --- .../Services/ObjectServiceProvider.cs | 2 +- src/FrostFS.SDK.Client/Tools/ObjectTools.cs | 30 ++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs b/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs index 133d2e3..246c3eb 100644 --- a/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs +++ b/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs @@ -268,7 +268,7 @@ internal sealed class ObjectServiceProvider(ObjectService.ObjectServiceClient cl internal async Task PutSingleObjectAsync(PrmSingleObjectPut args, CallContext ctx) { - var grpcObject = ObjectTools.CreateObject(args.FrostFsObject, ClientContext); + var grpcObject = ObjectTools.CreateSingleObject(args.FrostFsObject, ClientContext); var request = new PutSingleRequest { diff --git a/src/FrostFS.SDK.Client/Tools/ObjectTools.cs b/src/FrostFS.SDK.Client/Tools/ObjectTools.cs index 7abdbaf..36a22a1 100644 --- a/src/FrostFS.SDK.Client/Tools/ObjectTools.cs +++ b/src/FrostFS.SDK.Client/Tools/ObjectTools.cs @@ -14,6 +14,7 @@ public static class ObjectTools { public static FrostFsObjectId CalculateObjectId( FrostFsObjectHeader header, + ReadOnlyMemory payloadHash, FrostFsOwner owner, FrostFsVersion version, ClientKey key) @@ -38,7 +39,7 @@ public static class ObjectTools throw new ArgumentNullException(nameof(key)); } - var grpcHeader = CreateHeader(header, [], owner, version); + var grpcHeader = CreateHeader(header, payloadHash, owner, version); if (header.Split != null) SetSplitValues(grpcHeader, header.Split, owner, version, key); @@ -46,7 +47,7 @@ public static class ObjectTools return new ObjectID { Value = grpcHeader.Sha256() }.ToModel(); } - internal static Object.Object CreateObject(FrostFsObject @object, ClientContext ctx) + internal static Object.Object CreateSingleObject(FrostFsObject @object, ClientContext ctx) { @object.Header.OwnerId ??= ctx.Owner; @object.Header.Version ??= ctx.Version; @@ -81,7 +82,8 @@ public static class ObjectTools internal static void SetSplitValues( Header grpcHeader, FrostFsSplit split, - FrostFsOwner owner, FrostFsVersion version, + FrostFsOwner owner, + FrostFsVersion version, ClientKey key) { if (split == null) @@ -100,7 +102,7 @@ public static class ObjectTools if (split.ParentHeader is not null) { - var grpcParentHeader = CreateHeader(split.ParentHeader, [], owner, version); + var grpcParentHeader = CreateHeader(split.ParentHeader, Array.Empty().Sha256(), owner, version); grpcHeader.Split.Parent = new ObjectID { Value = grpcParentHeader.Sha256() }; grpcHeader.Split.ParentHeader = grpcParentHeader; @@ -114,16 +116,19 @@ public static class ObjectTools grpcHeader.Split.Previous = split.Previous?.ToMessage(); } - internal static Header CreateHeader(FrostFsObjectHeader header, byte[]? payload, FrostFsOwner owner, FrostFsVersion version) + internal static Header CreateHeader( + FrostFsObjectHeader header, + ReadOnlyMemory payloadChecksum, + FrostFsOwner owner, + FrostFsVersion version) { header.OwnerId ??= owner; header.Version ??= version; var grpcHeader = header.GetHeader(); - if (payload != null) // && payload.Length > 0 - grpcHeader.PayloadHash = Sha256Checksum(payload); - + grpcHeader.PayloadHash = ChecksumFromSha256(payloadChecksum); + return grpcHeader; } @@ -135,4 +140,13 @@ public static class ObjectTools Sum = ByteString.CopyFrom(data.Sha256()) }; } + + internal static Checksum ChecksumFromSha256(ReadOnlyMemory dataHash) + { + return new Checksum + { + Type = ChecksumType.Sha256, + Sum = UnsafeByteOperations.UnsafeWrap(dataHash) + }; + } } \ No newline at end of file -- 2.45.2