Skip to content

Commit

Permalink
morph: support overloads for container.Put contract method
Browse files Browse the repository at this point in the history
It now may have additional arg that enables meta-on-chain support and be named,
see nspcc-dev/neofs-contract#451. Closes #2877.

Signed-off-by: Pavel Karpy <[email protected]>
  • Loading branch information
carpawell committed Dec 23, 2024
1 parent ba2f720 commit c6c6aea
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog for NeoFS Node
## [Unreleased]

### Added
- Initial support for meta-on-chain for objects (#2877)

### Fixed

Expand Down
46 changes: 25 additions & 21 deletions pkg/morph/client/container/put.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

containercore "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
containerSDK "github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
)

Expand All @@ -21,6 +22,10 @@ func Put(c *Client, cnr containercore.Container) (*cid.ID, error) {
prm.SetContainer(data)
prm.SetName(d.Name())
prm.SetZone(d.Zone())
switch metaAttribute(cnr.Value) {
case "optimistic", "strict":
prm.EnableMeta()
}

if cnr.Session != nil {
prm.SetToken(cnr.Session.Marshal())
Expand All @@ -41,12 +46,13 @@ func Put(c *Client, cnr containercore.Container) (*cid.ID, error) {

// PutPrm groups parameters of Put operation.
type PutPrm struct {
cnr []byte
key []byte
sig []byte
token []byte
name string
zone string
cnr []byte
key []byte
sig []byte
token []byte
name string
zone string
enableMetaOnChain bool

client.InvokePrmOptional
}
Expand Down Expand Up @@ -81,6 +87,11 @@ func (p *PutPrm) SetZone(zone string) {
p.zone = zone
}

// EnableMeta enables meta-on-chain.
func (p *PutPrm) EnableMeta() {
p.enableMetaOnChain = true
}

// Put saves binary container with its session token, key and signature
// in NeoFS system through Container contract call.
//
Expand All @@ -91,21 +102,10 @@ func (c *Client) Put(p PutPrm) error {
return errNilArgument
}

var (
method string
prm client.InvokePrm
)

if p.name != "" {
method = putNamedMethod
prm.SetArgs(p.cnr, p.sig, p.key, p.token, p.name, p.zone)
} else {
method = putMethod
prm.SetArgs(p.cnr, p.sig, p.key, p.token)
}

prm.SetMethod(method)
var prm client.InvokePrm
prm.SetMethod(putMethod)
prm.InvokePrmOptional = p.InvokePrmOptional
prm.SetArgs(p.cnr, p.sig, p.key, p.token, p.name, p.zone, p.enableMetaOnChain)

// no magic bugs with notary requests anymore, this operation should
// _always_ be notary signed so make it one more time even if it is
Expand All @@ -114,7 +114,11 @@ func (c *Client) Put(p PutPrm) error {

err := c.client.Invoke(prm)
if err != nil {
return fmt.Errorf("could not invoke method (%s): %w", method, err)
return fmt.Errorf("could not invoke method (%s): %w", putMethod, err)
}
return nil
}

func metaAttribute(cnr containerSDK.Container) string {
return cnr.Attribute("__NEOFS__METAINFO_CONSISTENCY")
}
3 changes: 3 additions & 0 deletions pkg/morph/event/container/put.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ type Put struct {
signature []byte
publicKey []byte
token []byte
name string
zone string
metaOnChain bool

// For notary notifications only.
// Contains raw transactions of notary request.
Expand Down
71 changes: 64 additions & 7 deletions pkg/morph/event/container/put_notary.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ func (p *Put) setToken(v []byte) {
}
}

func (p *Put) setName(v string) {
p.name = v
}

func (p *Put) setZone(v string) {
p.zone = v
}

func (p *Put) setMetaOnChain(v bool) {
p.metaOnChain = v
}

var putFieldSetters = []func(*Put, []byte){
// order on stack is reversed
(*Put).setToken,
Expand All @@ -56,6 +68,34 @@ func parsePutNotary(ev *Put, raw *payload.P2PNotaryRequest, ops []event.Op) erro
fieldNum = 0
)

switch len(ops) {
case expectedItemNumPut + 3:
enableMeta, err := event.BoolFromOpcode(ops[0])
if err != nil {
return fmt.Errorf("parse arg meta: %w", err)
}
ev.setMetaOnChain(enableMeta)

ops = ops[1:]

err = parseNamedArgs(ev, ops)
if err != nil {
return err
}

ops = ops[2:]
case expectedItemNumPut + 2:
err := parseNamedArgs(ev, ops)
if err != nil {
return err
}

ops = ops[2:]
case expectedItemNumPut:
default:
return fmt.Errorf("unknown number of args: %d", len(ops))
}

for _, op := range ops {
currentOp = op.Code()

Expand Down Expand Up @@ -104,14 +144,9 @@ func ParsePutNamedNotary(ne event.NotaryEvent) (event.Event, error) {
err error
)

ev.zone, err = event.StringFromOpcode(ops[0])
err = parseNamedArgs(&ev, ops)
if err != nil {
return nil, fmt.Errorf("parse arg zone: %w", err)
}

ev.name, err = event.StringFromOpcode(ops[1])
if err != nil {
return nil, fmt.Errorf("parse arg name: %w", err)
return nil, err
}

err = parsePutNotary(&ev.Put, ne.Raw(), ops[putNamedAdditionalArgs:])
Expand All @@ -121,3 +156,25 @@ func ParsePutNamedNotary(ne event.NotaryEvent) (event.Event, error) {

return ev, nil
}

type putEvNamed interface {
setName(v string)
setZone(v string)
}

func parseNamedArgs(p putEvNamed, ops []event.Op) error {
zone, err := event.StringFromOpcode(ops[0])
if err != nil {
return fmt.Errorf("parse arg zone: %w", err)
}

name, err := event.StringFromOpcode(ops[1])
if err != nil {
return fmt.Errorf("parse arg name: %w", err)
}

p.setZone(zone)
p.setName(name)

return nil
}
12 changes: 12 additions & 0 deletions pkg/morph/event/opcodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ func BytesFromOpcode(op Op) ([]byte, error) {
}
}

// BoolFromOpcode tries to retrieve bool from Op.
func BoolFromOpcode(op Op) (bool, error) {
switch code := op.Code(); code {
case opcode.PUSHT:
return true, nil
case opcode.PUSHF:
return false, nil
default:
return false, fmt.Errorf("unexpected ByteArray opcode %s", code)
}
}

// IntFromOpcode tries to retrieve int from Op.
func IntFromOpcode(op Op) (int64, error) {
switch code := op.Code(); {
Expand Down

0 comments on commit c6c6aea

Please sign in to comment.