From a306eb9ce7d2c93e47e546196e6c172372a4c645 Mon Sep 17 00:00:00 2001
From: Leonard Lyubich <leonard@nspcc.ru>
Date: Wed, 19 May 2021 15:46:45 +0300
Subject: [PATCH] [#505] ir: Process set eACL notifications from Container
 contract

Add `setEACL` notification event parser (handler) to the return of the
`ListenerParsers` (`ListenerHandlers`) method. Read address of NeoFS ID
contract from `contracts.neofsid` config. Implement `NewNeoFSIDClient`
constructor in `invoke` package and use it in IR application.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
---
 pkg/innerring/innerring.go                    | 15 ++++++++++++
 .../processors/container/processor.go         | 24 +++++++++++++++++--
 pkg/morph/client/neofsid/wrapper/client.go    | 18 ++++++++------
 3 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go
index 6f884044d..cc9455e0b 100644
--- a/pkg/innerring/innerring.go
+++ b/pkg/innerring/innerring.go
@@ -27,6 +27,7 @@ import (
 	auditWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/audit/wrapper"
 	balanceWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/balance/wrapper"
 	cntWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper"
+	neofsid "github.com/nspcc-dev/neofs-node/pkg/morph/client/neofsid/wrapper"
 	nmWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
 	repWrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/reputation/wrapper"
 	"github.com/nspcc-dev/neofs-node/pkg/morph/event"
@@ -101,6 +102,7 @@ type (
 		proxy      util.Uint160 // in morph
 		processing util.Uint160 // in mainnet
 		reputation util.Uint160 // in morph
+		neofsID    util.Uint160 // in morph
 
 		alphabet alphabetContracts // in morph
 	}
@@ -375,6 +377,11 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
 		return nil, err
 	}
 
+	neofsIDClient, err := neofsid.NewFromMorph(server.morphClient, server.contracts.neofsID, fee)
+	if err != nil {
+		return nil, err
+	}
+
 	// create global runtime config reader
 	globalConfig := config.NewGlobalConfigReader(cfg, nmClient)
 
@@ -545,6 +552,8 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
 		MorphClient:       server.morphClient,
 		AlphabetState:     server,
 		FeeProvider:       server.feeConfig,
+		ContainerClient:   cnrClient,
+		NeoFSIDClient:     neofsIDClient,
 	})
 	if err != nil {
 		return nil, err
@@ -744,6 +753,7 @@ func parseContracts(cfg *viper.Viper) (*contracts, error) {
 	proxyContractStr := cfg.GetString("contracts.proxy")
 	processingContractStr := cfg.GetString("contracts.processing")
 	reputationContractStr := cfg.GetString("contracts.reputation")
+	neofsIDContractStr := cfg.GetString("contracts.neofsid")
 
 	result.netmap, err = util.Uint160DecodeStringLE(netmapContractStr)
 	if err != nil {
@@ -785,6 +795,11 @@ func parseContracts(cfg *viper.Viper) (*contracts, error) {
 		return nil, fmt.Errorf("ir: can't read reputation script-hash: %w", err)
 	}
 
+	result.neofsID, err = util.Uint160DecodeStringLE(neofsIDContractStr)
+	if err != nil {
+		return nil, fmt.Errorf("ir: can't read NeoFS ID script-hash: %w", err)
+	}
+
 	result.alphabet, err = parseAlphabetContracts(cfg)
 	if err != nil {
 		return nil, err
diff --git a/pkg/innerring/processors/container/processor.go b/pkg/innerring/processors/container/processor.go
index 2a6997ebe..007b01103 100644
--- a/pkg/innerring/processors/container/processor.go
+++ b/pkg/innerring/processors/container/processor.go
@@ -41,12 +41,16 @@ type (
 		MorphClient       *client.Client
 		AlphabetState     AlphabetState
 		FeeProvider       *config.FeeConfig
+		ContainerClient   *wrapper.Wrapper
+		NeoFSIDClient     *neofsid.ClientWrapper
 	}
 )
 
 const (
 	putNotification    = "containerPut"
 	deleteNotification = "containerDelete"
+
+	setEACLNotification = "setEACL"
 )
 
 // New creates container contract processor instance.
@@ -60,6 +64,10 @@ func New(p *Params) (*Processor, error) {
 		return nil, errors.New("ir/container: global state is not set")
 	case p.FeeProvider == nil:
 		return nil, errors.New("ir/container: fee provider is not set")
+	case p.ContainerClient == nil:
+		return nil, errors.New("ir/container: Container client is not set")
+	case p.NeoFSIDClient == nil:
+		return nil, errors.New("ir/container: NeoFS ID client is not set")
 	}
 
 	p.Log.Debug("container worker pool", zap.Int("size", p.PoolSize))
@@ -76,13 +84,15 @@ func New(p *Params) (*Processor, error) {
 		morphClient:       p.MorphClient,
 		alphabetState:     p.AlphabetState,
 		feeProvider:       p.FeeProvider,
+		cnrClient:         p.ContainerClient,
+		idClient:          p.NeoFSIDClient,
 	}, nil
 }
 
 // ListenerParsers for the 'event.Listener' event producer.
 func (cp *Processor) ListenerParsers() []event.ParserInfo {
 	var (
-		parsers = make([]event.ParserInfo, 0, 2)
+		parsers = make([]event.ParserInfo, 0, 3)
 
 		p event.ParserInfo
 	)
@@ -99,13 +109,18 @@ func (cp *Processor) ListenerParsers() []event.ParserInfo {
 	p.SetParser(containerEvent.ParseDelete)
 	parsers = append(parsers, p)
 
+	// set eACL
+	p.SetType(event.TypeFromString(setEACLNotification))
+	p.SetParser(containerEvent.ParseSetEACL)
+	parsers = append(parsers, p)
+
 	return parsers
 }
 
 // ListenerHandlers for the 'event.Listener' event producer.
 func (cp *Processor) ListenerHandlers() []event.HandlerInfo {
 	var (
-		handlers = make([]event.HandlerInfo, 0, 2)
+		handlers = make([]event.HandlerInfo, 0, 3)
 
 		h event.HandlerInfo
 	)
@@ -122,6 +137,11 @@ func (cp *Processor) ListenerHandlers() []event.HandlerInfo {
 	h.SetHandler(cp.handleDelete)
 	handlers = append(handlers, h)
 
+	// set eACL
+	h.SetType(event.TypeFromString(setEACLNotification))
+	h.SetHandler(cp.handleSetEACL)
+	handlers = append(handlers, h)
+
 	return handlers
 }
 
diff --git a/pkg/morph/client/neofsid/wrapper/client.go b/pkg/morph/client/neofsid/wrapper/client.go
index 720e51e05..1678a25ef 100644
--- a/pkg/morph/client/neofsid/wrapper/client.go
+++ b/pkg/morph/client/neofsid/wrapper/client.go
@@ -1,6 +1,11 @@
 package neofsid
 
 import (
+	"fmt"
+
+	"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
+	"github.com/nspcc-dev/neo-go/pkg/util"
+	"github.com/nspcc-dev/neofs-node/pkg/morph/client"
 	"github.com/nspcc-dev/neofs-node/pkg/morph/client/neofsid"
 )
 
@@ -11,13 +16,12 @@ import (
 // Working ClientWrapper must be created via Wrap.
 type ClientWrapper neofsid.Client
 
-// Wrap creates, initializes and returns the ClientWrapper instance.
-//
-// If c is nil, panic occurs.
-func Wrap(c *neofsid.Client) *ClientWrapper {
-	if c == nil {
-		panic("neofs ID client is nil")
+// NewFromMorph wraps client to work with NeoFS ID contract.
+func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8) (*ClientWrapper, error) {
+	sc, err := client.NewStatic(cli, contract, fee)
+	if err != nil {
+		return nil, fmt.Errorf("could not create client of NeoFS ID contract: %w", err)
 	}
 
-	return (*ClientWrapper)(c)
+	return (*ClientWrapper)(neofsid.New(sc)), nil
 }