From b3c81116b97f70edc88dbfbc046fa84ae8895b60 Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Mon, 19 Jul 2021 20:15:41 +0300 Subject: [PATCH] [#705] pkg/morph/netmap: Add `innerRingList` method Add `innerRingList` method to `netmap` client wrapper. Method parses current IR nodes list. Signed-off-by: Pavel Karpy --- pkg/morph/client/netmap/client.go | 3 ++ pkg/morph/client/netmap/innerring.go | 66 +++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/pkg/morph/client/netmap/client.go b/pkg/morph/client/netmap/client.go index 805e5b1f4..96bf2a9ed 100644 --- a/pkg/morph/client/netmap/client.go +++ b/pkg/morph/client/netmap/client.go @@ -33,6 +33,7 @@ type Option func(*cfg) type cfg struct { addPeerMethod, // add peer method name for invocation newEpochMethod, // new epoch method name for invocation + innerRingList, // get innerring list method name for invocation netMapMethod, // get network map method name netMapCandidatesMethod, // get network candidates method name snapshotMethod, // get network map snapshot method name @@ -48,6 +49,7 @@ const ( defaultAddPeerMethod = "addPeer" // default add peer method name defaultConfigMethod = "config" // default get config value method name defaultEpochMethod = "epoch" // default get epoch number method name + defaultInnerRingListMethod = "innerRingList" // default get innerring list method name defaultNetMapCandidateMethod = "netmapCandidates" // default get network candidates method name defaultNetMapMethod = "netmap" // default get network map method name defaultNewEpochMethod = "newEpoch" // default new epoch method name @@ -64,6 +66,7 @@ func defaultConfig() *cfg { addPeerMethod: defaultAddPeerMethod, configMethod: defaultConfigMethod, epochMethod: defaultEpochMethod, + innerRingList: defaultInnerRingListMethod, netMapCandidatesMethod: defaultNetMapCandidateMethod, netMapMethod: defaultNetMapMethod, newEpochMethod: defaultNewEpochMethod, diff --git a/pkg/morph/client/netmap/innerring.go b/pkg/morph/client/netmap/innerring.go index b82ef2a66..2acc90a0b 100644 --- a/pkg/morph/client/netmap/innerring.go +++ b/pkg/morph/client/netmap/innerring.go @@ -1,6 +1,13 @@ package netmap -import "github.com/nspcc-dev/neo-go/pkg/crypto/keys" +import ( + "crypto/elliptic" + "fmt" + + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" + "github.com/nspcc-dev/neofs-node/pkg/morph/client" +) // SetInnerRing updates inner ring members in netmap contract. func (c *Client) SetInnerRing(keys keys.PublicKeys) error { @@ -11,3 +18,60 @@ func (c *Client) SetInnerRing(keys keys.PublicKeys) error { return c.client.Invoke(c.setInnerRing, args) } + +// InnerRingList returns public keys of inner ring members in +// netmap contract. +func (c *Client) InnerRingList() (keys.PublicKeys, error) { + prms, err := c.client.TestInvoke( + c.innerRingList, + ) + if err != nil { + return nil, fmt.Errorf("could not perform test invocation (%s): %w", c.innerRingList, err) + } + + return irKeysFromStackItem(prms, c.innerRingList) +} + +func irKeysFromStackItem(stack []stackitem.Item, method string) (keys.PublicKeys, error) { + if ln := len(stack); ln != 1 { + return nil, fmt.Errorf("unexpected stack item count (%s): %d", method, ln) + } + + irs, err := client.ArrayFromStackItem(stack[0]) + if err != nil { + return nil, fmt.Errorf("could not get stack item array from stack item (%s): %w", method, err) + } + + irKeys := make(keys.PublicKeys, len(irs)) + + for i := range irs { + irKeys[i], err = irKeyFromStackItem(irs[i]) + if err != nil { + return nil, err + } + } + + return irKeys, nil +} + +const irNodeFixedPrmNumber = 1 + +func irKeyFromStackItem(prm stackitem.Item) (*keys.PublicKey, error) { + prms, err := client.ArrayFromStackItem(prm) + if err != nil { + return nil, fmt.Errorf("could not get stack item array (IRNode): %w", err) + } else if ln := len(prms); ln != irNodeFixedPrmNumber { + return nil, fmt.Errorf( + "unexpected stack item count (IRNode): expected %d, has %d", + irNodeFixedPrmNumber, + ln, + ) + } + + byteKey, err := client.BytesFromStackItem(prms[0]) + if err != nil { + return nil, fmt.Errorf("could not parse bytes from stack item (IRNode): %w", err) + } + + return keys.NewPublicKeyFromBytes(byteKey, elliptic.P256()) +}