62 lines
1.5 KiB
Go
62 lines
1.5 KiB
Go
|
package snapshot
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||
|
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
|
||
|
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||
|
)
|
||
|
|
||
|
const getNetmapSnapshotMethod = "netmap"
|
||
|
|
||
|
// Fetch returns current netmap node infos.
|
||
|
// Consider using pkg/morph/client/netmap for this.
|
||
|
func Fetch(cli *client.Client, contract util.Uint160) (*netmap.Netmap, error) {
|
||
|
rawNetmapStack, err := cli.TestInvoke(contract, 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, fmt.Errorf("invalid RPC response: %w", err)
|
||
|
}
|
||
|
|
||
|
result = append(result, *nodeInfo)
|
||
|
}
|
||
|
|
||
|
return netmap.NewNetmap(netmap.NodesFromInfo(result))
|
||
|
}
|
||
|
|
||
|
func peerInfoFromStackItem(prm stackitem.Item) (*netmap.NodeInfo, error) {
|
||
|
node := netmap.NewNodeInfo()
|
||
|
|
||
|
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 = node.Unmarshal(rawNodeInfo); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return node, nil
|
||
|
}
|