From 07da9d31f2470ebc4b5ed4307c5664da619a9226 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Mon, 21 Dec 2020 16:47:02 +0300 Subject: [PATCH] [#269] morph/client: Implement Audit contract client Signed-off-by: Leonard Lyubich --- pkg/morph/client/audit/client.go | 86 ++++++++++++++++++++++++++ pkg/morph/client/audit/list_results.go | 55 ++++++++++++++++ pkg/morph/client/audit/put_result.go | 26 ++++++++ 3 files changed, 167 insertions(+) create mode 100644 pkg/morph/client/audit/client.go create mode 100644 pkg/morph/client/audit/list_results.go create mode 100644 pkg/morph/client/audit/put_result.go diff --git a/pkg/morph/client/audit/client.go b/pkg/morph/client/audit/client.go new file mode 100644 index 000000000..a84fd267c --- /dev/null +++ b/pkg/morph/client/audit/client.go @@ -0,0 +1,86 @@ +package audit + +import ( + "github.com/nspcc-dev/neofs-node/pkg/morph/client" +) + +// Client is a wrapper over StaticClient +// which makes calls with the names and arguments +// of the NeoFS Audit contract. +// +// Working client must be created via constructor New. +// Using the Client that has been created with new(Client) +// expression (or just declaring a Client variable) is unsafe +// and can lead to panic. +type Client struct { + client *client.StaticClient // static Audit contract client + + *cfg // contract method names +} + +// Option is a client configuration change function. +type Option func(*cfg) + +type cfg struct { + putResultMethod, // put audit result method name for invocation + listResultsMethod string // list audit results method name for invocation +} + +const ( + defaultPutResultMethod = "put" // default "put audit result" method name + defaultListResultsMethod = "list" // default "list audit results" method name +) + +func defaultConfig() *cfg { + return &cfg{ + putResultMethod: defaultPutResultMethod, + listResultsMethod: defaultListResultsMethod, + } +} + +// New creates, initializes and returns the Client instance. +// +// Other values are set according to provided options, or by default: +// * "put audit result" method name: put; +// * "list audit results" method name: list. +// +// If desired option satisfies the default value, it can be omitted. +// If multiple options of the same config value are supplied, +// the option with the highest index in the arguments will be used. +func New(c *client.StaticClient, opts ...Option) *Client { + res := &Client{ + client: c, + cfg: defaultConfig(), // build default configuration + } + + // apply options + for _, opt := range opts { + opt(res.cfg) + } + + return res +} + +// WithPutAuditResultMethod returns a client constructor option that +// specifies the "put audit result" method name. +// +// Ignores empty value. +func WithPutAuditResultMethod(n string) Option { + return func(c *cfg) { + if n != "" { + c.putResultMethod = n + } + } +} + +// WithListResultsMethod returns a client constructor option that +// specifies the "list audit results" method name. +// +// Ignores empty value. +func WithListResultsMethod(n string) Option { + return func(c *cfg) { + if n != "" { + c.listResultsMethod = n + } + } +} diff --git a/pkg/morph/client/audit/list_results.go b/pkg/morph/client/audit/list_results.go new file mode 100644 index 000000000..e7da9b648 --- /dev/null +++ b/pkg/morph/client/audit/list_results.go @@ -0,0 +1,55 @@ +package audit + +import ( + "github.com/nspcc-dev/neofs-node/pkg/morph/client" + "github.com/pkg/errors" +) + +// ListResultsArgs groups the arguments +// of "list audit results" test invoke call. +type ListResultsArgs struct{} + +// ListResultsValues groups the stack parameters +// returned by "list audit results" test invoke. +type ListResultsValues struct { + rawResults [][]byte // audit results in a binary format +} + +// RawResults returns list of audit results +// in a binary format. +func (v *ListResultsValues) RawResults() [][]byte { + return v.rawResults +} + +// ListAuditResults performs the test invoke of "list audit results" +// method of NeoFS Audit contract. +func (c *Client) ListAuditResults(args ListResultsArgs) (*ListResultsValues, error) { + items, err := c.client.TestInvoke( + c.listResultsMethod, + ) + if err != nil { + return nil, errors.Wrapf(err, "could not perform test invocation (%s)", c.listResultsMethod) + } else if ln := len(items); ln != 1 { + return nil, errors.Errorf("unexpected stack item count (%s): %d", c.listResultsMethod, ln) + } + + items, err = client.ArrayFromStackItem(items[0]) + if err != nil { + return nil, errors.Wrapf(err, "could not get stack item array from stack item (%s)", c.listResultsMethod) + } + + res := &ListResultsValues{ + rawResults: make([][]byte, 0, len(items)), + } + + for i := range items { + rawRes, err := client.BytesFromStackItem(items[i]) + if err != nil { + return nil, errors.Wrapf(err, "could not get byte array from stack item (%s)", c.listResultsMethod) + } + + res.rawResults = append(res.rawResults, rawRes) + } + + return res, nil +} diff --git a/pkg/morph/client/audit/put_result.go b/pkg/morph/client/audit/put_result.go new file mode 100644 index 000000000..084fb7651 --- /dev/null +++ b/pkg/morph/client/audit/put_result.go @@ -0,0 +1,26 @@ +package audit + +import ( + "github.com/pkg/errors" +) + +// PutAuditResultArgs groups the arguments +// of "put audit result" invocation call. +type PutAuditResultArgs struct { + rawResult []byte // audit result in NeoFS API-compatible binary representation +} + +// SetRawResult sets audit result structure +// in NeoFS API-compatible binary representation. +func (g *PutAuditResultArgs) SetRawResult(v []byte) { + g.rawResult = v +} + +// PutAuditResult invokes the call of "put audit result" method +// of NeoFS Audit contract. +func (c *Client) PutAuditResult(args PutAuditResultArgs) error { + return errors.Wrapf(c.client.Invoke( + c.putResultMethod, + args.rawResult, + ), "could not invoke method (%s)", c.putResultMethod) +}