From 4fbd53ba7308a1af13067d118715c524fe3c06f0 Mon Sep 17 00:00:00 2001 From: Denis Kirillov Date: Mon, 10 Oct 2022 16:41:10 +0300 Subject: [PATCH] [#308] audit: Add CollectMembers function Add new function to build storage group using OIDs of virtual objects. Signed-off-by: Denis Kirillov --- audit/collect.go | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 audit/collect.go diff --git a/audit/collect.go b/audit/collect.go new file mode 100644 index 00000000..0c406c12 --- /dev/null +++ b/audit/collect.go @@ -0,0 +1,76 @@ +package audit + +import ( + "context" + "fmt" + + "github.com/nspcc-dev/neofs-sdk-go/checksum" + cid "github.com/nspcc-dev/neofs-sdk-go/container/id" + "github.com/nspcc-dev/neofs-sdk-go/object" + oid "github.com/nspcc-dev/neofs-sdk-go/object/id" + "github.com/nspcc-dev/neofs-sdk-go/object/relations" + "github.com/nspcc-dev/neofs-sdk-go/storagegroup" + "github.com/nspcc-dev/tzhash/tz" +) + +type Collector interface { + Head(ctx context.Context, addr oid.Address) (*object.Object, error) + relations.Relations +} + +// CollectMembers creates new storage group structure and fills it +// with information about members collected via HeadReceiver. +// +// Resulting storage group consists of physically stored objects only. +func CollectMembers(ctx context.Context, collector Collector, cnr cid.ID, members []oid.ID, tokens relations.Tokens, calcHomoHash bool) (*storagegroup.StorageGroup, error) { + var ( + err error + sumPhySize uint64 + phyMembers []oid.ID + phyHashes [][]byte + addr oid.Address + sg storagegroup.StorageGroup + ) + + addr.SetContainer(cnr) + + for i := range members { + if phyMembers, err = relations.ListRelations(ctx, collector, cnr, members[i], tokens, false); err != nil { + return nil, err + } + + for _, phyMember := range phyMembers { + addr.SetObject(phyMember) + leaf, err := collector.Head(ctx, addr) + if err != nil { + return nil, fmt.Errorf("head phy member '%s': %w", phyMember.EncodeToString(), err) + } + + sumPhySize += leaf.PayloadSize() + cs, _ := leaf.PayloadHomomorphicHash() + + if calcHomoHash { + phyHashes = append(phyHashes, cs.Value()) + } + } + } + + sg.SetMembers(phyMembers) + sg.SetValidationDataSize(sumPhySize) + + if calcHomoHash { + sumHash, err := tz.Concat(phyHashes) + if err != nil { + return nil, err + } + + var cs checksum.Checksum + tzHash := [64]byte{} + copy(tzHash[:], sumHash) + cs.SetTillichZemor(tzHash) + + sg.SetValidationDataHash(cs) + } + + return &sg, nil +}