diff --git a/cmd/frostfs-adm/internal/modules/morph/balance.go b/cmd/frostfs-adm/internal/modules/morph/balance.go index ca9d939f..f97250c3 100644 --- a/cmd/frostfs-adm/internal/modules/morph/balance.go +++ b/cmd/frostfs-adm/internal/modules/morph/balance.go @@ -44,7 +44,6 @@ const ( notaryEnabled = true ) -// nolint: funlen, gocognit func dumpBalances(cmd *cobra.Command, _ []string) error { var ( dumpStorage, _ = cmd.Flags().GetBool(dumpBalancesStorageFlag) @@ -84,86 +83,110 @@ func dumpBalances(cmd *cobra.Command, _ []string) error { printBalances(cmd, "Inner ring nodes balances:", irList) if dumpStorage { - arr, err := unwrap.Array(inv.Call(nmHash, "netmap")) - if err != nil { - return errors.New("can't fetch the list of storage nodes") - } - - snList := make([]accBalancePair, len(arr)) - for i := range arr { - node, ok := arr[i].Value().([]stackitem.Item) - if !ok || len(node) == 0 { - return errors.New("can't parse the list of storage nodes") - } - bs, err := node[0].TryBytes() - if err != nil { - return errors.New("can't parse the list of storage nodes") - } - var ni netmap.NodeInfo - if err := ni.Unmarshal(bs); err != nil { - return fmt.Errorf("can't parse the list of storage nodes: %w", err) - } - pub, err := keys.NewPublicKeyFromBytes(ni.PublicKey(), elliptic.P256()) - if err != nil { - return fmt.Errorf("can't parse storage node public key: %w", err) - } - snList[i].scriptHash = pub.GetScriptHash() - } - - if err := fetchBalances(inv, gas.Hash, snList); err != nil { + if err := printStorageNodeBalances(cmd, inv, nmHash); err != nil { return err } - printBalances(cmd, "\nStorage node balances:", snList) } if dumpProxy { - h, err := nnsResolveHash(inv, nnsCs.Hash, proxyContract+".frostfs") - if err != nil { - return fmt.Errorf("can't get hash of the proxy contract: %w", err) - } - - proxyList := []accBalancePair{{scriptHash: h}} - if err := fetchBalances(inv, gas.Hash, proxyList); err != nil { + if err := printProxyContractBalance(cmd, inv, nnsCs.Hash); err != nil { return err } - printBalances(cmd, "\nProxy contract balance:", proxyList) } if dumpAlphabet { - alphaList := make([]accBalancePair, len(irList)) - - w := io.NewBufBinWriter() - for i := range alphaList { - emit.AppCall(w.BinWriter, nnsCs.Hash, "resolve", callflag.ReadOnly, - getAlphabetNNSDomain(i), - int64(nns.TXT)) - } - if w.Err != nil { - panic(w.Err) - } - - alphaRes, err := c.InvokeScript(w.Bytes(), nil) - if err != nil { - return fmt.Errorf("can't fetch info from NNS: %w", err) - } - - for i := range alphaList { - h, err := parseNNSResolveResult(alphaRes.Stack[i]) - if err != nil { - return fmt.Errorf("can't fetch the alphabet contract #%d hash: %w", i, err) - } - alphaList[i].scriptHash = h - } - - if err := fetchBalances(inv, gas.Hash, alphaList); err != nil { + if err := printAlphabetContractBalances(cmd, c, inv, len(irList), nnsCs.Hash); err != nil { return err } - printBalances(cmd, "\nAlphabet contracts balances:", alphaList) } return nil } +func printStorageNodeBalances(cmd *cobra.Command, inv *invoker.Invoker, nmHash util.Uint160) error { + arr, err := unwrap.Array(inv.Call(nmHash, "netmap")) + if err != nil { + return errors.New("can't fetch the list of storage nodes") + } + + snList := make([]accBalancePair, len(arr)) + for i := range arr { + node, ok := arr[i].Value().([]stackitem.Item) + if !ok || len(node) == 0 { + return errors.New("can't parse the list of storage nodes") + } + bs, err := node[0].TryBytes() + if err != nil { + return errors.New("can't parse the list of storage nodes") + } + var ni netmap.NodeInfo + if err := ni.Unmarshal(bs); err != nil { + return fmt.Errorf("can't parse the list of storage nodes: %w", err) + } + pub, err := keys.NewPublicKeyFromBytes(ni.PublicKey(), elliptic.P256()) + if err != nil { + return fmt.Errorf("can't parse storage node public key: %w", err) + } + snList[i].scriptHash = pub.GetScriptHash() + } + + if err := fetchBalances(inv, gas.Hash, snList); err != nil { + return err + } + + printBalances(cmd, "\nStorage node balances:", snList) + return nil +} + +func printProxyContractBalance(cmd *cobra.Command, inv *invoker.Invoker, nnsHash util.Uint160) error { + h, err := nnsResolveHash(inv, nnsHash, proxyContract+".frostfs") + if err != nil { + return fmt.Errorf("can't get hash of the proxy contract: %w", err) + } + + proxyList := []accBalancePair{{scriptHash: h}} + if err := fetchBalances(inv, gas.Hash, proxyList); err != nil { + return err + } + + printBalances(cmd, "\nProxy contract balance:", proxyList) + return nil +} + +func printAlphabetContractBalances(cmd *cobra.Command, c Client, inv *invoker.Invoker, count int, nnsHash util.Uint160) error { + alphaList := make([]accBalancePair, count) + + w := io.NewBufBinWriter() + for i := range alphaList { + emit.AppCall(w.BinWriter, nnsHash, "resolve", callflag.ReadOnly, + getAlphabetNNSDomain(i), + int64(nns.TXT)) + } + if w.Err != nil { + panic(w.Err) + } + + alphaRes, err := c.InvokeScript(w.Bytes(), nil) + if err != nil { + return fmt.Errorf("can't fetch info from NNS: %w", err) + } + + for i := range alphaList { + h, err := parseNNSResolveResult(alphaRes.Stack[i]) + if err != nil { + return fmt.Errorf("can't fetch the alphabet contract #%d hash: %w", i, err) + } + alphaList[i].scriptHash = h + } + + if err := fetchBalances(inv, gas.Hash, alphaList); err != nil { + return err + } + + printBalances(cmd, "\nAlphabet contracts balances:", alphaList) + return nil +} + func fetchIRNodes(c Client, nmHash, desigHash util.Uint160) ([]accBalancePair, error) { var irList []accBalancePair