Skip to content

Commit

Permalink
[#907] container/put: Work with named containers
Browse files Browse the repository at this point in the history
Add name and zone arguments to `Put` method of wrapper over the Container
contract client. Pass result of `container.GetNativeNameWithZone` function
to the method in `Put` helper function. Due to this, the storage node will
call the method depending on the presence of the container name in the
attributes.

Make IR to listen `putNamed` notification event. The event is processed like
`put` event, but with sanity check of the container attributes.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
  • Loading branch information
Leonard Lyubich committed Oct 14, 2021
1 parent 51cf791 commit b0a0386
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 19 deletions.
6 changes: 1 addition & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/multiformats/go-multiaddr v0.4.0
github.com/nspcc-dev/hrw v1.0.9
github.com/nspcc-dev/neo-go v0.97.1
github.com/nspcc-dev/neofs-api-go v1.29.1-0.20210929081312-010b1b011827
github.com/nspcc-dev/neofs-api-go v1.29.1-0.20211014122040-db1ed764733b
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20210520210714-9dee13f0d556
github.com/nspcc-dev/tzhash v1.4.0
github.com/panjf2000/ants/v2 v2.4.0
Expand All @@ -24,11 +24,7 @@ require (
go.etcd.io/bbolt v1.3.6
go.uber.org/atomic v1.9.0
go.uber.org/zap v1.18.1
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b // indirect
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
golang.org/x/term v0.0.0-20210429154555-c04ba851c2a4
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20210928142010-c7af6a1a74c9 // indirect
google.golang.org/grpc v1.41.0
google.golang.org/protobuf v1.27.1
)
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,8 @@ github.com/nspcc-dev/neo-go v0.97.1/go.mod h1:yguwQBpWMTHx07INKoElJT8Gga1LUdTSi0
github.com/nspcc-dev/neofs-api-go v1.24.0/go.mod h1:G7dqincfdjBrAbL5nxVp82emF05fSVEqe59ICsoRDI8=
github.com/nspcc-dev/neofs-api-go v1.26.1/go.mod h1:SHuH1Ba3U/h3j+8HHbb3Cns1LfMlEb88guWog9Qi68Y=
github.com/nspcc-dev/neofs-api-go v1.27.1/go.mod h1:i0Cwgvcu9A4M4e58pydbXFisUhSxpfljmuWFPIp2btE=
github.com/nspcc-dev/neofs-api-go v1.29.1-0.20210929081312-010b1b011827 h1:FBPEP4kOEkXmx4codT/0HkIHRGJ+mnub3nWtfsb24EY=
github.com/nspcc-dev/neofs-api-go v1.29.1-0.20210929081312-010b1b011827/go.mod h1:CAeWsIt2BKrg3Gty80ogQNXnFVpJt18k55AOOlzssBw=
github.com/nspcc-dev/neofs-api-go v1.29.1-0.20211014122040-db1ed764733b h1:n5tIRk8WMwJJCjpBO6V2sJFqNDnJvYXH7lY5GdkQaAo=
github.com/nspcc-dev/neofs-api-go v1.29.1-0.20211014122040-db1ed764733b/go.mod h1:KC8T91skIg8juvUh7lQabswQ9J6KmnXErpH8qwDitXA=
github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA=
github.com/nspcc-dev/neofs-crypto v0.2.3/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnBg0L4ifM=
Expand Down
4 changes: 2 additions & 2 deletions pkg/innerring/processors/container/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

func (cp *Processor) handlePut(ev event.Event) {
put := ev.(containerEvent.Put)
put := ev.(putEvent)

id := sha256.Sum256(put.Container())
cp.log.Info("notification",
Expand All @@ -19,7 +19,7 @@ func (cp *Processor) handlePut(ev event.Event) {

// send event to the worker pool

err := cp.pool.Submit(func() { cp.processContainerPut(&put) })
err := cp.pool.Submit(func() { cp.processContainerPut(put) })
if err != nil {
// there system can be moved into controlled degradation stage
cp.log.Warn("container processor worker pool drained",
Expand Down
65 changes: 59 additions & 6 deletions pkg/innerring/processors/container/process_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,46 @@ import (
"fmt"

"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/network/payload"
containerSDK "github.com/nspcc-dev/neofs-api-go/pkg/container"
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
"github.com/nspcc-dev/neofs-api-go/pkg/session"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container"
"go.uber.org/zap"
)

// putEvent is a common interface of Put and PutNamed event.
type putEvent interface {
event.Event
Container() []byte
PublicKey() []byte
Signature() []byte
SessionToken() []byte
NotaryRequest() *payload.P2PNotaryRequest
}

type putContainerContext struct {
e putEvent

name, zone string // from container structure
}

// Process new container from the user by checking container sanity
// and sending approve tx back to morph.
func (cp *Processor) processContainerPut(put *containerEvent.Put) {
func (cp *Processor) processContainerPut(put putEvent) {
if !cp.alphabetState.IsAlphabet() {
cp.log.Info("non alphabet mode, ignore container put")
return
}

err := cp.checkPutContainer(put)
ctx := &putContainerContext{
e: put,
}

err := cp.checkPutContainer(ctx)
if err != nil {
cp.log.Error("put container check failed",
zap.String("error", err.Error()),
Expand All @@ -33,10 +55,12 @@ func (cp *Processor) processContainerPut(put *containerEvent.Put) {
return
}

cp.approvePutContainer(put)
cp.approvePutContainer(ctx)
}

func (cp *Processor) checkPutContainer(e *containerEvent.Put) error {
func (cp *Processor) checkPutContainer(ctx *putContainerContext) error {
e := ctx.e

// verify signature
key, err := keys.NewPublicKeyFromBytes(e.PublicKey(), elliptic.P256())
if err != nil {
Expand All @@ -58,6 +82,12 @@ func (cp *Processor) checkPutContainer(e *containerEvent.Put) error {
return fmt.Errorf("invalid binary container: %w", err)
}

// check native name and zone
err = checkNNS(ctx, cnr)
if err != nil {
return fmt.Errorf("NNS: %w", err)
}

// perform format check
err = container.CheckFormat(cnr)
if err != nil {
Expand Down Expand Up @@ -85,15 +115,17 @@ func (cp *Processor) checkPutContainer(e *containerEvent.Put) error {
return cp.checkKeyOwnership(cnr, key)
}

func (cp *Processor) approvePutContainer(e *containerEvent.Put) {
func (cp *Processor) approvePutContainer(ctx *putContainerContext) {
e := ctx.e

var err error

if nr := e.NotaryRequest(); nr != nil {
// put event was received via Notary service
err = cp.cnrClient.Morph().NotarySignAndInvokeTX(nr.MainTransaction)
} else {
// put event was received via notification service
err = cp.cnrClient.Put(e.Container(), e.PublicKey(), e.Signature(), e.SessionToken())
err = cp.cnrClient.Put(e.Container(), e.PublicKey(), e.Signature(), e.SessionToken(), ctx.name, ctx.zone)
}
if err != nil {
cp.log.Error("could not approve put container",
Expand Down Expand Up @@ -202,3 +234,24 @@ func (cp *Processor) approveDeleteContainer(e *containerEvent.Delete) {
)
}
}

func checkNNS(ctx *putContainerContext, cnr *containerSDK.Container) error {
// fetch native name and zone
ctx.name, ctx.zone = containerSDK.GetNativeNameWithZone(cnr)

// if PutNamed event => check if values in container correspond to args
if named, ok := ctx.e.(interface {
Name() string
Zone() string
}); ok {
if name := named.Name(); name != ctx.name {
return fmt.Errorf("names differ %s/%s", name, ctx.name)
}

if zone := named.Zone(); zone != ctx.zone {
return fmt.Errorf("zones differ %s/%s", zone, ctx.zone)
}
}

return nil
}
13 changes: 11 additions & 2 deletions pkg/innerring/processors/container/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (cp *Processor) ListenerNotaryParsers() []event.NotaryParserInfo {
var (
p event.NotaryParserInfo

pp = make([]event.NotaryParserInfo, 0, 3)
pp = make([]event.NotaryParserInfo, 0, 4)
)

p.SetMempoolType(mempoolevent.TransactionAdded)
Expand All @@ -172,6 +172,11 @@ func (cp *Processor) ListenerNotaryParsers() []event.NotaryParserInfo {
p.SetParser(containerEvent.ParsePutNotary)
pp = append(pp, p)

// container named put
p.SetRequestType(containerEvent.PutNamedNotaryEvent)
p.SetParser(containerEvent.ParsePutNamedNotary)
pp = append(pp, p)

// container delete
p.SetRequestType(containerEvent.DeleteNotaryEvent)
p.SetParser(containerEvent.ParseDeleteNotary)
Expand All @@ -190,7 +195,7 @@ func (cp *Processor) ListenerNotaryHandlers() []event.NotaryHandlerInfo {
var (
h event.NotaryHandlerInfo

hh = make([]event.NotaryHandlerInfo, 0, 3)
hh = make([]event.NotaryHandlerInfo, 0, 4)
)

h.SetScriptHash(cp.cnrClient.ContractAddress())
Expand All @@ -201,6 +206,10 @@ func (cp *Processor) ListenerNotaryHandlers() []event.NotaryHandlerInfo {
h.SetHandler(cp.handlePut)
hh = append(hh, h)

// container named put (same handler)
h.SetRequestType(containerEvent.PutNamedNotaryEvent)
hh = append(hh, h)

// container delete
h.SetRequestType(containerEvent.DeleteNotaryEvent)
h.SetHandler(cp.handleDelete)
Expand Down
7 changes: 5 additions & 2 deletions pkg/morph/client/container/wrapper/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ func Put(w *Wrapper, cnr *container.Container) (*cid.ID, error) {

sig := cnr.Signature()

err = w.Put(data, sig.Key(), sig.Sign(), binToken)
name, zone := container.GetNativeNameWithZone(cnr)

err = w.Put(data, sig.Key(), sig.Sign(), binToken, name, zone)
if err != nil {
return nil, err
}
Expand All @@ -59,7 +61,7 @@ func Put(w *Wrapper, cnr *container.Container) (*cid.ID, error) {
// encountered that caused the saving to interrupt.
//
// If TryNotary is provided, calls notary contract.
func (w *Wrapper) Put(cnr, key, sig, token []byte) error {
func (w *Wrapper) Put(cnr, key, sig, token []byte, name, zone string) error {
if len(sig) == 0 || len(key) == 0 {
return errNilArgument
}
Expand All @@ -70,6 +72,7 @@ func (w *Wrapper) Put(cnr, key, sig, token []byte) error {
args.SetSignature(sig)
args.SetPublicKey(key)
args.SetSessionToken(token)
args.SetNativeNameWithZone(name, zone)

err := w.client.Put(args)
if err != nil {
Expand Down

0 comments on commit b0a0386

Please sign in to comment.