diff --git a/go.sum b/go.sum index d0aa12697..20bbac32e 100644 --- a/go.sum +++ b/go.sum @@ -574,6 +574,7 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= gopkg.in/abiosoft/ishell.v2 v2.0.0/go.mod h1:sFp+cGtH6o4s1FtpVPTMcHq2yue+c4DGOVohJCPUzwY= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/innerring/invoke/netmap.go b/pkg/innerring/invoke/netmap.go index 7f71321f2..73bbdb74d 100644 --- a/pkg/innerring/invoke/netmap.go +++ b/pkg/innerring/invoke/netmap.go @@ -3,7 +3,11 @@ package invoke import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" + netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap/grpc" "github.com/nspcc-dev/neofs-node/pkg/morph/client" + "github.com/pkg/errors" + "google.golang.org/protobuf/proto" ) type ( @@ -19,12 +23,13 @@ type ( ) const ( - getEpochMethod = "epoch" - setNewEpochMethod = "newEpoch" - approvePeerMethod = "addPeer" - updatePeerStateMethod = "updateState" - setConfigMethod = "setConfigMethod" - updateInnerRingMethod = "updateInnerRingMethod" + getEpochMethod = "epoch" + setNewEpochMethod = "newEpoch" + approvePeerMethod = "addPeer" + updatePeerStateMethod = "updateState" + setConfigMethod = "setConfigMethod" + updateInnerRingMethod = "updateInnerRingMethod" + getNetmapSnapshotMethod = "netmap" ) // Epoch return epoch value from contract. @@ -101,3 +106,54 @@ func UpdateInnerRing(cli *client.Client, con util.Uint160, list []*keys.PublicKe return cli.Invoke(con, extraFee, updateInnerRingMethod, rawKeys) } + +// NetmapSnapshot returns current netmap node infos. +func NetmapSnapshot(cli *client.Client, con util.Uint160) ([]netmap.NodeInfo, error) { + if cli == nil { + return nil, client.ErrNilClient + } + + rawNetmapStack, err := cli.TestInvoke(con, getNetmapSnapshotMethod) + if err != nil { + return nil, err + } + + if ln := len(rawNetmapStack); ln != 1 { + return nil, errors.New("invalid RPC response") + } + + rawNodeInfos, err := client.ArrayFromStackItem(rawNetmapStack[0]) + if err != nil { + return nil, err + } + + result := make([]netmap.NodeInfo, 0, len(rawNodeInfos)) + + for i := range rawNodeInfos { + nodeInfo, err := peerInfoFromStackItem(rawNodeInfos[i]) + if err != nil { + return nil, errors.Wrap(err, "invalid RPC response") + } + + result = append(result, *nodeInfo) + } + + return result, nil +} + +func peerInfoFromStackItem(prm stackitem.Item) (*netmap.NodeInfo, error) { + node := new(netmap.NodeInfo) + + subItems, err := client.ArrayFromStackItem(prm) + if err != nil { + return nil, err + } else if ln := len(subItems); ln != 1 { + return nil, errors.New("invalid RPC response") + } else if rawNodeInfo, err := client.BytesFromStackItem(subItems[0]); err != nil { + return nil, err + } else if err = proto.Unmarshal(rawNodeInfo, node); err != nil { + return nil, err + } + + return node, nil +}