using System.Linq; using FrostFS.Object; using FrostFS.Refs; using FrostFS.SDK.ClientV2.Mappers.GRPC; using FrostFS.SDK.Cryptography; using Google.Protobuf; namespace FrostFS.SDK.ClientV2; internal static class ObjectTools { internal static FrostFsObjectId CalculateObjectId(FrostFsObjectHeader header, CallContext ctx) { var grpcHeader = CreateHeader(header, [], ctx); if (header.Split != null) SetSplitValues(grpcHeader, header.Split, ctx); return new ObjectID { Value = grpcHeader.Sha256() }.ToModel(); } internal static Object.Object CreateObject(FrostFsObject @object, CallContext ctx) { @object.Header.OwnerId ??= ctx.OwnerId; @object.Header.Version ??= ctx.Version; var grpcHeader = @object.Header.GetHeader(); grpcHeader.PayloadLength = (ulong)@object.SingleObjectPayload.Length; grpcHeader.PayloadHash = Sha256Checksum(@object.SingleObjectPayload); var split = @object.Header.Split; if (split != null) { SetSplitValues(grpcHeader, split, ctx); } var obj = new Object.Object { Header = grpcHeader, ObjectId = new ObjectID { Value = grpcHeader.Sha256() }, Payload = ByteString.CopyFrom(@object.SingleObjectPayload) }; obj.Signature = new Signature { Key = ctx.GetPublicKeyCache(), Sign = ByteString.CopyFrom(ctx.Key!.SignData(obj.ObjectId.ToByteArray())), }; return obj; } internal static void SetSplitValues(Header grpcHeader, FrostFsSplit split, CallContext ctx) { if (split == null) return; if (ctx.Key == null) throw new FrostFsInvalidObjectException(nameof(ctx.Key)); grpcHeader.Split = new Header.Types.Split { SplitId = split.SplitId?.GetSplitId() }; if (split.Children != null && split.Children.Count != 0) grpcHeader.Split.Children.AddRange(split.Children.Select(id => id.ToMessage())); if (split.ParentHeader is not null) { var grpcParentHeader = CreateHeader(split.ParentHeader, [], ctx); grpcHeader.Split.Parent = new ObjectID { Value = grpcParentHeader.Sha256() }; grpcHeader.Split.ParentHeader = grpcParentHeader; grpcHeader.Split.ParentSignature = new Signature { Key = ctx.GetPublicKeyCache(), Sign = ByteString.CopyFrom(ctx.Key.SignData(grpcHeader.Split.Parent.ToByteArray())), }; } grpcHeader.Split.Previous = split.Previous?.ToMessage(); } internal static Header CreateHeader(FrostFsObjectHeader header, byte[]? payload, CallContext ctx) { header.OwnerId ??= ctx.OwnerId; header.Version ??= ctx.Version; var grpcHeader = header.GetHeader(); if (payload != null) // && payload.Length > 0 grpcHeader.PayloadHash = Sha256Checksum(payload); return grpcHeader; } internal static Checksum Sha256Checksum(byte[] data) { return new Checksum { Type = ChecksumType.Sha256, Sum = ByteString.CopyFrom(data.Sha256()) }; } }