From 80d7459560e85a256081ba09b44aa690344482e3 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 3 Jul 2024 15:31:39 +0300 Subject: [PATCH] Revert "[#1196] morph/client: Remove duplicate utility functions" This reverts commit 259007540fc8ca0899a3cd4598f9e2e33a442e01. Signed-off-by: Evgenii Stratonikov --- go.mod | 2 +- go.sum | Bin 42738 -> 42738 bytes pkg/morph/client/frostfsid/subject.go | 202 +++++++++++++++++++++++++- 3 files changed, 201 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d4eb52f4d..38e66a20f 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( code.gitea.io/sdk/gitea v0.17.1 git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240530152826-2f6d3209e1d3 - git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240621131249-49e5270f673e + git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409111539-e7a05a49ff45 git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0 git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20231101111734-b3ad3335ff65 git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240617140730-1a5886e776de diff --git a/go.sum b/go.sum index 84fdbd47a321d38cf2ba2d350b72678ceec1c7a2..0849b74a11c343918575b55cfbcb1ac83d4c9299 100644 GIT binary patch delta 118 zcmex#mg&=3rVT$BT}%ut4Gj%VjV*Ok%@Ykw6HP4B(o9ShG7POk3QRn;Bm8{|jKiG0 z{Daaef)jHCOR|iEqWnCAlM;P=O~PGFGd-&!Dkc}QD^9j&;h6k@Q9=y6ftx2Y#V-K> D?~Nq+ delta 119 zcmex#mg&=3rVT$BUCoRP4UG+rOe}RxEK^O5%nj1a%#BkOG7PP%fd3#OR~MZ!UK)mOVjmJBO~%G&CK(SeN85RWLKDM&%!bJ0i%Q%b`v*GW{O_| E02u%!EdT%j diff --git a/pkg/morph/client/frostfsid/subject.go b/pkg/morph/client/frostfsid/subject.go index 50733d89a..169be6bc5 100644 --- a/pkg/morph/client/frostfsid/subject.go +++ b/pkg/morph/client/frostfsid/subject.go @@ -1,11 +1,16 @@ package frostfsid import ( + "errors" "fmt" frostfsidclient "git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client" + "github.com/nspcc-dev/neo-go/pkg/neorpc/result" + "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" + "github.com/nspcc-dev/neo-go/pkg/vm/vmstate" ) const ( @@ -23,7 +28,7 @@ func (c *Client) GetSubject(addr util.Uint160) (*frostfsidclient.Subject, error) return nil, fmt.Errorf("could not perform test invocation (%s): %w", methodGetSubject, err) } - subj, err := frostfsidclient.ParseSubject(res) + subj, err := parseSubject(res) if err != nil { return nil, fmt.Errorf("could not parse test invocation result (%s): %w", methodGetSubject, err) } @@ -41,10 +46,203 @@ func (c *Client) GetSubjectExtended(addr util.Uint160) (*frostfsidclient.Subject return nil, fmt.Errorf("could not perform test invocation (%s): %w", methodGetSubject, err) } - subj, err := frostfsidclient.ParseSubjectExtended(res) + subj, err := parseSubjectExtended(res) if err != nil { return nil, fmt.Errorf("could not parse test invocation result (%s): %w", methodGetSubject, err) } return subj, nil } + +func parseSubject(res []stackitem.Item) (*frostfsidclient.Subject, error) { + if ln := len(res); ln != 1 { + return nil, fmt.Errorf("unexpected stack item count (%s): %d", methodGetSubject, ln) + } + + structArr, err := client.ArrayFromStackItem(res[0]) + if err != nil { + return nil, fmt.Errorf("could not get item array of container (%s): %w", methodGetSubject, err) + } + + var subj frostfsidclient.Subject + + subj.PrimaryKey, err = unwrap.PublicKey(makeValidRes(structArr[0])) + if err != nil { + return nil, err + } + + if !structArr[1].Equals(stackitem.Null{}) { + subj.AdditionalKeys, err = unwrap.ArrayOfPublicKeys(makeValidRes(structArr[1])) + if err != nil { + return nil, err + } + } + + if !structArr[2].Equals(stackitem.Null{}) { + subj.Namespace, err = unwrap.UTF8String(makeValidRes(structArr[2])) + if err != nil { + return nil, err + } + } + + if !structArr[3].Equals(stackitem.Null{}) { + subj.Name, err = unwrap.UTF8String(makeValidRes(structArr[3])) + if err != nil { + return nil, err + } + } + + subj.KV, err = parseMap(structArr[4]) + if err != nil { + return nil, err + } + + return &subj, nil +} + +func parseSubjectExtended(res []stackitem.Item) (*frostfsidclient.SubjectExtended, error) { + if ln := len(res); ln != 1 { + return nil, fmt.Errorf("unexpected stack item count (%s): %d", methodGetSubject, ln) + } + + structArr, err := client.ArrayFromStackItem(res[0]) + if err != nil { + return nil, fmt.Errorf("could not get item array of container (%s): %w", methodGetSubject, err) + } + + var subj frostfsidclient.SubjectExtended + + subj.PrimaryKey, err = unwrap.PublicKey(makeValidRes(structArr[0])) + if err != nil { + return nil, err + } + + if !structArr[1].Equals(stackitem.Null{}) { + subj.AdditionalKeys, err = unwrap.ArrayOfPublicKeys(makeValidRes(structArr[1])) + if err != nil { + return nil, err + } + } + + if !structArr[2].Equals(stackitem.Null{}) { + subj.Namespace, err = unwrap.UTF8String(makeValidRes(structArr[2])) + if err != nil { + return nil, err + } + } + + if !structArr[3].Equals(stackitem.Null{}) { + subj.Name, err = unwrap.UTF8String(makeValidRes(structArr[3])) + if err != nil { + return nil, err + } + } + + subj.KV, err = parseMap(structArr[4]) + if err != nil { + return nil, err + } + + if !structArr[5].Equals(stackitem.Null{}) { + groupItems, ok := structArr[5].Value().([]stackitem.Item) + if !ok { + return nil, errors.New("invalid groups field") + } + + subj.Groups, err = parseGroups(groupItems) + if err != nil { + return nil, err + } + } + + return &subj, nil +} + +func makeValidRes(item stackitem.Item) (*result.Invoke, error) { + return &result.Invoke{ + Stack: []stackitem.Item{item}, + State: vmstate.Halt.String(), + }, nil +} + +func parseMap(item stackitem.Item) (map[string]string, error) { + if item.Equals(stackitem.Null{}) { + return nil, nil + } + + metaMap, err := unwrap.Map(makeValidRes(item)) + if err != nil { + return nil, err + } + + meta, ok := metaMap.Value().([]stackitem.MapElement) + if !ok { + return nil, errors.New("invalid map type") + } + + res := make(map[string]string, len(meta)) + for _, element := range meta { + key, err := element.Key.TryBytes() + if err != nil { + return nil, err + } + val, err := element.Value.TryBytes() + if err != nil { + return nil, err + } + res[string(key)] = string(val) + } + + return res, nil +} + +func parseGroups(items []stackitem.Item) ([]*frostfsidclient.Group, error) { + var err error + res := make([]*frostfsidclient.Group, len(items)) + + for i := 0; i < len(items); i++ { + arr, ok := items[i].Value().([]stackitem.Item) + if !ok { + return nil, errors.New("invalid group type") + } + res[i], err = parseGroup(arr) + if err != nil { + return nil, err + } + } + + return res, nil +} + +func parseGroup(structArr []stackitem.Item) (*frostfsidclient.Group, error) { + if len(structArr) < 4 { + return nil, errors.New("invalid response group struct") + } + + groupID, err := structArr[0].TryInteger() + if err != nil { + return nil, err + } + + name, err := structArr[1].TryBytes() + if err != nil { + return nil, err + } + + namespace, err := structArr[2].TryBytes() + if err != nil { + return nil, err + } + + kvs, err := parseMap(structArr[3]) + if err != nil { + return nil, err + } + + return &frostfsidclient.Group{ + ID: groupID.Int64(), + Name: string(name), + Namespace: string(namespace), + KV: kvs, + }, nil +}