forked from TrueCloudLab/frostfs-node
[#807] morph/event/container: Add delete
notary support
Includes: - `delete` container notary notification; - refactor in processor bindings; - fixed conflicts in `put` notifications. Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
19e97e4d7c
commit
e03b44ffc1
6 changed files with 152 additions and 33 deletions
|
@ -187,7 +187,15 @@ func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *Processor) approveDeleteContainer(e *containerEvent.Delete) {
|
func (cp *Processor) approveDeleteContainer(e *containerEvent.Delete) {
|
||||||
err := cp.cnrClient.Delete(e.ContainerID(), e.Signature(), e.SessionToken())
|
var err error
|
||||||
|
|
||||||
|
if nr := e.NotaryRequest(); nr != nil {
|
||||||
|
// delete event was received via Notary service
|
||||||
|
err = cp.cnrClient.Morph().NotarySignAndInvokeTX(nr.MainTransaction)
|
||||||
|
} else {
|
||||||
|
// delete event was received via notification service
|
||||||
|
err = cp.cnrClient.Delete(e.ContainerID(), e.Signature(), e.SessionToken())
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cp.log.Error("could not approve delete container",
|
cp.log.Error("could not approve delete container",
|
||||||
zap.String("error", err.Error()),
|
zap.String("error", err.Error()),
|
||||||
|
|
|
@ -98,6 +98,10 @@ func New(p *Params) (*Processor, error) {
|
||||||
|
|
||||||
// ListenerNotificationParsers for the 'event.Listener' event producer.
|
// ListenerNotificationParsers for the 'event.Listener' event producer.
|
||||||
func (cp *Processor) ListenerNotificationParsers() []event.NotificationParserInfo {
|
func (cp *Processor) ListenerNotificationParsers() []event.NotificationParserInfo {
|
||||||
|
if !cp.notaryDisabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
parsers = make([]event.NotificationParserInfo, 0, 3)
|
parsers = make([]event.NotificationParserInfo, 0, 3)
|
||||||
|
|
||||||
|
@ -106,12 +110,10 @@ func (cp *Processor) ListenerNotificationParsers() []event.NotificationParserInf
|
||||||
|
|
||||||
p.SetScriptHash(cp.containerContract)
|
p.SetScriptHash(cp.containerContract)
|
||||||
|
|
||||||
if cp.notaryDisabled {
|
|
||||||
// container put
|
// container put
|
||||||
p.SetType(event.TypeFromString(putNotification))
|
p.SetType(event.TypeFromString(putNotification))
|
||||||
p.SetParser(containerEvent.ParsePut)
|
p.SetParser(containerEvent.ParsePut)
|
||||||
parsers = append(parsers, p)
|
parsers = append(parsers, p)
|
||||||
}
|
|
||||||
|
|
||||||
// container delete
|
// container delete
|
||||||
p.SetType(event.TypeFromString(deleteNotification))
|
p.SetType(event.TypeFromString(deleteNotification))
|
||||||
|
@ -128,6 +130,10 @@ func (cp *Processor) ListenerNotificationParsers() []event.NotificationParserInf
|
||||||
|
|
||||||
// ListenerNotificationHandlers for the 'event.Listener' event producer.
|
// ListenerNotificationHandlers for the 'event.Listener' event producer.
|
||||||
func (cp *Processor) ListenerNotificationHandlers() []event.NotificationHandlerInfo {
|
func (cp *Processor) ListenerNotificationHandlers() []event.NotificationHandlerInfo {
|
||||||
|
if !cp.notaryDisabled {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
handlers = make([]event.NotificationHandlerInfo, 0, 3)
|
handlers = make([]event.NotificationHandlerInfo, 0, 3)
|
||||||
|
|
||||||
|
@ -136,12 +142,10 @@ func (cp *Processor) ListenerNotificationHandlers() []event.NotificationHandlerI
|
||||||
|
|
||||||
h.SetScriptHash(cp.containerContract)
|
h.SetScriptHash(cp.containerContract)
|
||||||
|
|
||||||
if cp.notaryDisabled {
|
|
||||||
// container put
|
// container put
|
||||||
h.SetType(event.TypeFromString(putNotification))
|
h.SetType(event.TypeFromString(putNotification))
|
||||||
h.SetHandler(cp.handlePut)
|
h.SetHandler(cp.handlePut)
|
||||||
handlers = append(handlers, h)
|
handlers = append(handlers, h)
|
||||||
}
|
|
||||||
|
|
||||||
// container delete
|
// container delete
|
||||||
h.SetType(event.TypeFromString(deleteNotification))
|
h.SetType(event.TypeFromString(deleteNotification))
|
||||||
|
@ -158,26 +162,50 @@ func (cp *Processor) ListenerNotificationHandlers() []event.NotificationHandlerI
|
||||||
|
|
||||||
// ListenerNotaryParsers for the 'event.Listener' notary event producer.
|
// ListenerNotaryParsers for the 'event.Listener' notary event producer.
|
||||||
func (cp *Processor) ListenerNotaryParsers() []event.NotaryParserInfo {
|
func (cp *Processor) ListenerNotaryParsers() []event.NotaryParserInfo {
|
||||||
var p event.NotaryParserInfo
|
var (
|
||||||
|
p event.NotaryParserInfo
|
||||||
|
|
||||||
|
pp = make([]event.NotaryParserInfo, 0, 3)
|
||||||
|
)
|
||||||
|
|
||||||
p.SetMempoolType(mempoolevent.TransactionAdded)
|
p.SetMempoolType(mempoolevent.TransactionAdded)
|
||||||
p.SetRequestType(containerEvent.PutNotaryEvent)
|
|
||||||
p.SetScriptHash(cp.containerContract)
|
p.SetScriptHash(cp.containerContract)
|
||||||
p.SetParser(containerEvent.ParsePutNotary)
|
|
||||||
|
|
||||||
return []event.NotaryParserInfo{p}
|
// container put
|
||||||
|
p.SetRequestType(containerEvent.PutNotaryEvent)
|
||||||
|
p.SetParser(containerEvent.ParsePutNotary)
|
||||||
|
pp = append(pp, p)
|
||||||
|
|
||||||
|
// container delete
|
||||||
|
p.SetRequestType(containerEvent.DeleteNotaryEvent)
|
||||||
|
p.SetParser(containerEvent.ParseDeleteNotary)
|
||||||
|
pp = append(pp, p)
|
||||||
|
|
||||||
|
return pp
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListenerNotaryHandlers for the 'event.Listener' notary event producer.
|
// ListenerNotaryHandlers for the 'event.Listener' notary event producer.
|
||||||
func (cp *Processor) ListenerNotaryHandlers() []event.NotaryHandlerInfo {
|
func (cp *Processor) ListenerNotaryHandlers() []event.NotaryHandlerInfo {
|
||||||
var h event.NotaryHandlerInfo
|
var (
|
||||||
|
h event.NotaryHandlerInfo
|
||||||
|
|
||||||
|
hh = make([]event.NotaryHandlerInfo, 0, 3)
|
||||||
|
)
|
||||||
|
|
||||||
h.SetMempoolType(mempoolevent.TransactionAdded)
|
|
||||||
h.SetRequestType(containerEvent.PutNotaryEvent)
|
|
||||||
h.SetScriptHash(cp.containerContract)
|
h.SetScriptHash(cp.containerContract)
|
||||||
h.SetHandler(cp.handlePut)
|
h.SetMempoolType(mempoolevent.TransactionAdded)
|
||||||
|
|
||||||
return []event.NotaryHandlerInfo{h}
|
// container put
|
||||||
|
h.SetRequestType(containerEvent.PutNotaryEvent)
|
||||||
|
h.SetHandler(cp.handlePut)
|
||||||
|
hh = append(hh, h)
|
||||||
|
|
||||||
|
// container delete
|
||||||
|
h.SetRequestType(containerEvent.DeleteNotaryEvent)
|
||||||
|
h.SetHandler(cp.handleDelete)
|
||||||
|
hh = append(hh, h)
|
||||||
|
|
||||||
|
return hh
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimersHandlers for the 'Timers' event producer.
|
// TimersHandlers for the 'Timers' event producer.
|
||||||
|
|
|
@ -3,6 +3,7 @@ package container
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
||||||
|
@ -13,6 +14,10 @@ type Delete struct {
|
||||||
containerID []byte
|
containerID []byte
|
||||||
signature []byte
|
signature []byte
|
||||||
token []byte
|
token []byte
|
||||||
|
|
||||||
|
// For notary notifications only.
|
||||||
|
// Contains raw transactions of notary request.
|
||||||
|
notaryRequest *payload.P2PNotaryRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
// MorphEvent implements Neo:Morph Event interface.
|
// MorphEvent implements Neo:Morph Event interface.
|
||||||
|
@ -30,6 +35,14 @@ func (d Delete) SessionToken() []byte {
|
||||||
return d.token
|
return d.token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotaryRequest returns raw notary request if notification
|
||||||
|
// was received via notary service. Otherwise, returns nil.
|
||||||
|
func (d Delete) NotaryRequest() *payload.P2PNotaryRequest {
|
||||||
|
return d.notaryRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
const expectedItemNumDelete = 3
|
||||||
|
|
||||||
// ParseDelete from notification into container event structure.
|
// ParseDelete from notification into container event structure.
|
||||||
//
|
//
|
||||||
// Expects 3 stack items.
|
// Expects 3 stack items.
|
||||||
|
@ -39,10 +52,8 @@ func ParseDelete(params []stackitem.Item) (event.Event, error) {
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
const expectedItemNumEACL = 3
|
if ln := len(params); ln != expectedItemNumDelete {
|
||||||
|
return nil, event.WrongNumberOfParameters(expectedItemNumDelete, ln)
|
||||||
if ln := len(params); ln != expectedItemNumEACL {
|
|
||||||
return nil, event.WrongNumberOfParameters(expectedItemNumEACL, ln)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse container
|
// parse container
|
||||||
|
|
70
pkg/morph/event/container/delete_notary.go
Normal file
70
pkg/morph/event/container/delete_notary.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package container
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
|
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (d *Delete) setContainerID(v []byte) {
|
||||||
|
if v != nil {
|
||||||
|
d.containerID = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Delete) setSignature(v []byte) {
|
||||||
|
if v != nil {
|
||||||
|
d.signature = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Delete) setToken(v []byte) {
|
||||||
|
if v != nil {
|
||||||
|
d.token = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var deleteFieldSetters = []func(*Delete, []byte){
|
||||||
|
// order on stack is reversed
|
||||||
|
(*Delete).setToken,
|
||||||
|
(*Delete).setSignature,
|
||||||
|
(*Delete).setContainerID,
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DeleteNotaryEvent is method name for container delete operations
|
||||||
|
// in `Container` contract. Is used as identificator for notary
|
||||||
|
// delete container requests.
|
||||||
|
DeleteNotaryEvent = "delete"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseDeleteNotary from NotaryEvent into container event structure.
|
||||||
|
func ParseDeleteNotary(ne event.NotaryEvent) (event.Event, error) {
|
||||||
|
var (
|
||||||
|
ev Delete
|
||||||
|
currentOp opcode.Opcode
|
||||||
|
)
|
||||||
|
|
||||||
|
fieldNum := 0
|
||||||
|
|
||||||
|
for _, op := range ne.Params() {
|
||||||
|
currentOp = op.Code()
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case opcode.PUSHDATA1 <= currentOp && currentOp <= opcode.PUSHDATA4:
|
||||||
|
if fieldNum == expectedItemNumDelete {
|
||||||
|
return nil, event.UnexpectedArgNumErr(DeleteNotaryEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteFieldSetters[fieldNum](&ev, op.Param())
|
||||||
|
fieldNum++
|
||||||
|
case opcode.PUSH0 <= currentOp && currentOp <= opcode.PUSH16 || currentOp == opcode.PACK:
|
||||||
|
// array packing opcodes. do nothing with it
|
||||||
|
default:
|
||||||
|
return nil, event.UnexpectedOpcode(DeleteNotaryEvent, op.Code())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ev.notaryRequest = ne.Raw()
|
||||||
|
|
||||||
|
return ev, nil
|
||||||
|
}
|
|
@ -1,8 +1,6 @@
|
||||||
package container
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
||||||
)
|
)
|
||||||
|
@ -31,7 +29,7 @@ func (p *Put) setToken(v []byte) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fieldSetters = []func(*Put, []byte){
|
var putFieldSetters = []func(*Put, []byte){
|
||||||
// order on stack is reversed
|
// order on stack is reversed
|
||||||
(*Put).setToken,
|
(*Put).setToken,
|
||||||
(*Put).setPublicKey,
|
(*Put).setPublicKey,
|
||||||
|
@ -46,8 +44,6 @@ const (
|
||||||
PutNotaryEvent = "put"
|
PutNotaryEvent = "put"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errUnexpectedArgumentAmount = fmt.Errorf("unexpected arguments amount in %s call", PutNotaryEvent)
|
|
||||||
|
|
||||||
// ParsePutNotary from NotaryEvent into container event structure.
|
// ParsePutNotary from NotaryEvent into container event structure.
|
||||||
func ParsePutNotary(ne event.NotaryEvent) (event.Event, error) {
|
func ParsePutNotary(ne event.NotaryEvent) (event.Event, error) {
|
||||||
var (
|
var (
|
||||||
|
@ -63,10 +59,10 @@ func ParsePutNotary(ne event.NotaryEvent) (event.Event, error) {
|
||||||
switch {
|
switch {
|
||||||
case opcode.PUSHDATA1 <= currentOp && currentOp <= opcode.PUSHDATA4:
|
case opcode.PUSHDATA1 <= currentOp && currentOp <= opcode.PUSHDATA4:
|
||||||
if fieldNum == expectedItemNumPut {
|
if fieldNum == expectedItemNumPut {
|
||||||
return nil, errUnexpectedArgumentAmount
|
return nil, event.UnexpectedArgNumErr(PutNotaryEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldSetters[fieldNum](&ev, op.Param())
|
putFieldSetters[fieldNum](&ev, op.Param())
|
||||||
fieldNum++
|
fieldNum++
|
||||||
case opcode.PUSH0 <= currentOp && currentOp <= opcode.PUSH16 || currentOp == opcode.PACK:
|
case opcode.PUSH0 <= currentOp && currentOp <= opcode.PUSH16 || currentOp == opcode.PACK:
|
||||||
// array packing opcodes. do nothing with it
|
// array packing opcodes. do nothing with it
|
||||||
|
|
|
@ -43,6 +43,12 @@ func NotaryTypeFromString(str string) NotaryType {
|
||||||
return NotaryType(str)
|
return NotaryType(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnexpectedArgNumErr returns error when notary parsers
|
||||||
|
// get unexpected amount of argument in contract call.
|
||||||
|
func UnexpectedArgNumErr(method string) error {
|
||||||
|
return fmt.Errorf("unexpected arguments amount in %s call", method)
|
||||||
|
}
|
||||||
|
|
||||||
// UnexpectedOpcode returns error when notary parsers
|
// UnexpectedOpcode returns error when notary parsers
|
||||||
// get unexpected opcode in contract call.
|
// get unexpected opcode in contract call.
|
||||||
func UnexpectedOpcode(method string, op opcode.Opcode) error {
|
func UnexpectedOpcode(method string, op opcode.Opcode) error {
|
||||||
|
|
Loading…
Reference in a new issue