Skip to content

Commit 3bc4b81

Browse files
committed
ir/container: Handle creation request calling new CreateV2 method
Will become available with nspcc-dev/neofs-contract#534 upgrade. Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
1 parent 97ee3e2 commit 3bc4b81

File tree

6 files changed

+104
-1
lines changed

6 files changed

+104
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Changelog for NeoFS Node
99
- SN `pprof.enable_block` and `pprof.enable_mutex` options (#3655)
1010
- `neofs-adm fschain load-report` command (#3649)
1111
- SN now supports new `getInfo` and `createV2` methods of the Container contract (#XXX)
12+
- IR now supports container creation requests submitted via new `createV2` contract method (#XXX)
1213

1314
### Fixed
1415
- Write cache using too much CPU (#3642)

pkg/innerring/processors/container/handlers.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ import (
1010
"go.uber.org/zap"
1111
)
1212

13+
func (cp *Processor) handleCreationRequest(ev event.Event) {
14+
err := cp.pool.Submit(func() { cp.processCreateContainerRequest(ev.(containerEvent.CreateContainerV2Request)) })
15+
if err != nil {
16+
// there system can be moved into controlled degradation stage
17+
cp.log.Warn("container processor worker pool drained",
18+
zap.Int("capacity", cp.pool.Cap()))
19+
}
20+
}
21+
1322
func (cp *Processor) handlePut(ev event.Event) {
1423
req, ok := ev.(containerEvent.CreateContainerRequest)
1524
if !ok {

pkg/innerring/processors/container/process_container.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
99
"github.com/nspcc-dev/neo-go/pkg/network/payload"
10+
fschaincontracts "github.com/nspcc-dev/neofs-node/pkg/morph/contracts"
1011
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
1112
containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container"
1213
containerSDK "github.com/nspcc-dev/neofs-sdk-go/container"
@@ -15,6 +16,31 @@ import (
1516
"go.uber.org/zap"
1617
)
1718

19+
func (cp *Processor) processCreateContainerRequest(req containerEvent.CreateContainerV2Request) {
20+
if !cp.alphabetState.IsAlphabet() {
21+
cp.log.Info("non alphabet mode, ignore container creation request")
22+
return
23+
}
24+
25+
cnr, err := fschaincontracts.ContainerFromStruct(req.Container)
26+
if err != nil {
27+
cp.log.Error("invalid container struct in creation request", zap.Error(err))
28+
return
29+
}
30+
31+
cnrBytes := cnr.Marshal()
32+
id := cid.NewFromMarshalledContainer(cnrBytes)
33+
34+
err = cp.checkPutContainer(cnr, cnrBytes, req.SessionToken, req.InvocationScript, req.VerificationScript, "", "")
35+
if err != nil {
36+
cp.log.Error("container creation request failed check",
37+
zap.Stringer("container", id), zap.Error(err))
38+
return
39+
}
40+
41+
cp.approvePutContainer(req.MainTransaction, cnr, id)
42+
}
43+
1844
// putEvent is a common interface of Put and PutNamed event.
1945
type putEvent interface {
2046
event.Event

pkg/innerring/processors/container/processor.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ func (cp *Processor) ListenerNotaryParsers() []event.NotaryParserInfo {
137137
p.SetParser(containerEvent.RestoreCreateContainerRequest)
138138
pp = append(pp, p)
139139

140+
p.SetRequestType(fschaincontracts.CreateContainerV2Method)
141+
p.SetParser(containerEvent.RestoreCreateContainerV2Request)
142+
pp = append(pp, p)
143+
140144
// container delete
141145
p.SetRequestType(containerEvent.DeleteNotaryEvent)
142146
p.SetParser(containerEvent.ParseDeleteNotary)
@@ -194,6 +198,10 @@ func (cp *Processor) ListenerNotaryHandlers() []event.NotaryHandlerInfo {
194198
h.SetHandler(cp.handlePut)
195199
hh = append(hh, h)
196200

201+
h.SetRequestType(fschaincontracts.CreateContainerV2Method)
202+
h.SetHandler(cp.handleCreationRequest)
203+
hh = append(hh, h)
204+
197205
// container delete
198206
h.SetRequestType(containerEvent.DeleteNotaryEvent)
199207
h.SetHandler(cp.handleDelete)

pkg/morph/contracts/models.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ func ContainerFromStackItem(item stackitem.Item) (container.Container, error) {
2222
return container.Container{}, err
2323
}
2424

25+
return ContainerFromStruct(contractStruct)
26+
}
27+
28+
// ContainerFromStruct decodes container from contract structure.
29+
func ContainerFromStruct(contractStruct containerrpc.ContainerInfo) (container.Container, error) {
2530
mjr, mnr, err := containerVersionFromStruct(contractStruct.Version)
2631
if err != nil {
2732
return container.Container{}, err

pkg/morph/event/container/notary_requests.go

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"fmt"
55

66
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
7+
"github.com/nspcc-dev/neo-go/pkg/vm"
78
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
9+
containerrpc "github.com/nspcc-dev/neofs-contract/rpc/container"
810
fschaincontracts "github.com/nspcc-dev/neofs-node/pkg/morph/contracts"
911
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
1012
)
@@ -17,14 +19,66 @@ func getArgsFromEvent(ne event.NotaryEvent, expectedNum int) ([]event.Op, error)
1719
return args, nil
1820
}
1921

22+
func wrapInvalidArgError(i int, typ stackitem.Type, desc string, err error) error {
23+
return fmt.Errorf("arg#%d (%s, %s): %w", i, typ, desc, err)
24+
}
25+
2026
func getValueFromArg[T any](args []event.Op, i int, desc string, typ stackitem.Type, f func(event.Op) (T, error)) (v T, err error) {
2127
v, err = f(args[i])
2228
if err != nil {
23-
return v, fmt.Errorf("arg#%d (%s, %s): %w", i, typ, desc, err)
29+
return v, wrapInvalidArgError(i, typ, desc, err)
2430
}
2531
return v, nil
2632
}
2733

34+
// CreateContainerRequest wraps container creation request to provide
35+
// app-internal event.
36+
type CreateContainerV2Request struct {
37+
event.Event
38+
MainTransaction transaction.Transaction
39+
40+
Container containerrpc.ContainerInfo
41+
InvocationScript []byte
42+
VerificationScript []byte
43+
SessionToken []byte
44+
}
45+
46+
// RestoreCreateContainerV2Request restores [CreateContainerV2Request] from the
47+
// notary one.
48+
func RestoreCreateContainerV2Request(notaryReq event.NotaryEvent) (event.Event, error) {
49+
testVM := vm.New()
50+
testVM.LoadScript(notaryReq.ArgumentScript())
51+
52+
if err := testVM.Run(); err != nil {
53+
return nil, fmt.Errorf("exec script on test VM: %w", err)
54+
}
55+
56+
stack := testVM.Estack()
57+
const argNum = 4
58+
if got := stack.Len(); got != argNum {
59+
return nil, fmt.Errorf("wrong/unsupported arg num %d instead of %d", got, argNum) // TODO: share error
60+
}
61+
62+
var res CreateContainerV2Request
63+
var err error
64+
65+
if err = res.Container.FromStackItem(stack.Pop().Item()); err != nil {
66+
return nil, wrapInvalidArgError(argNum-1, stackitem.StructT, "container", err)
67+
}
68+
if res.InvocationScript, err = stack.Pop().Item().TryBytes(); err != nil {
69+
return nil, wrapInvalidArgError(argNum-2, stackitem.ByteArrayT, "invocation script", err)
70+
}
71+
if res.VerificationScript, err = stack.Pop().Item().TryBytes(); err != nil {
72+
return nil, wrapInvalidArgError(argNum-3, stackitem.ByteArrayT, "verification script", err)
73+
}
74+
if res.SessionToken, err = stack.Pop().Item().TryBytes(); err != nil {
75+
return nil, wrapInvalidArgError(argNum-4, stackitem.ByteArrayT, "session token", err)
76+
}
77+
res.MainTransaction = *notaryReq.Raw().MainTransaction
78+
79+
return res, nil
80+
}
81+
2882
// CreateContainerRequest wraps container creation request to provide
2983
// app-internal event.
3084
type CreateContainerRequest struct {

0 commit comments

Comments
 (0)