[#2224] adm: Use native neo-go sessions in dump-hashes

If we had lots of domains in one zone, `dump-hashes` for all others
can miss some domains, because we need to restrict ourselves with _some_
number.
In this commit we use neo-go sessions by default, with a proper
failback to in-script iterator unwrapping.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2023-01-27 18:27:49 +03:00 committed by fyrchik
parent 40822adb51
commit 236c4af615
2 changed files with 44 additions and 10 deletions

View file

@ -28,6 +28,7 @@ Changelog for FrostFS Node
- Prevent node process from killing by systemd when shutting down (#1465) - Prevent node process from killing by systemd when shutting down (#1465)
- Restore subscriptions correctly on morph client switch (#2212) - Restore subscriptions correctly on morph client switch (#2212)
- Expired objects could be returned if not marked with GC yet (#2213) - Expired objects could be returned if not marked with GC yet (#2213)
- `neofs-adm morph dump-hashes` now properly iterates over custom domain (#2224)
### Removed ### Removed
### Updated ### Updated

View file

@ -2,6 +2,7 @@ package morph
import ( import (
"bytes" "bytes"
"errors"
"fmt" "fmt"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
@ -107,31 +108,30 @@ func dumpContractHashes(cmd *cobra.Command, _ []string) error {
func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c Client) error { func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c Client) error {
const nnsMaxTokens = 100 const nnsMaxTokens = 100
inv := invoker.New(c, nil)
arr, err := unwrap.Array(inv.CallAndExpandIterator(nnsHash, "tokens", nnsMaxTokens)) inv := invoker.New(c, nil)
if err != nil {
return fmt.Errorf("can't get a list of NNS domains: %w", err)
}
if !strings.HasPrefix(zone, ".") { if !strings.HasPrefix(zone, ".") {
zone = "." + zone zone = "." + zone
} }
var infos []contractDumpInfo var infos []contractDumpInfo
for i := range arr { processItem := func(item stackitem.Item) {
bs, err := arr[i].TryBytes() bs, err := item.TryBytes()
if err != nil { if err != nil {
continue cmd.PrintErrf("Invalid NNS record: %v\n", err)
return
} }
if !bytes.HasSuffix(bs, []byte(zone)) { if !bytes.HasSuffix(bs, []byte(zone)) {
continue // Related https://github.com/nspcc-dev/neofs-contract/issues/316.
return
} }
h, err := nnsResolveHash(inv, nnsHash, string(bs)) h, err := nnsResolveHash(inv, nnsHash, string(bs))
if err != nil { if err != nil {
continue cmd.PrintErrf("Could not resolve name %s: %v\n", string(bs), err)
return
} }
infos = append(infos, contractDumpInfo{ infos = append(infos, contractDumpInfo{
@ -140,6 +140,39 @@ func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string,
}) })
} }
sessionID, iter, err := unwrap.SessionIterator(inv.Call(nnsHash, "tokens"))
if err != nil {
if errors.Is(err, unwrap.ErrNoSessionID) {
items, err := unwrap.Array(inv.CallAndExpandIterator(nnsHash, "tokens", nnsMaxTokens))
if err != nil {
return fmt.Errorf("can't get a list of NNS domains: %w", err)
}
if len(items) == nnsMaxTokens {
cmd.PrintErrln("Provided RPC endpoint doesn't support sessions, some hashes might be lost.")
}
for i := range items {
processItem(items[i])
}
} else {
return err
}
} else {
defer func() {
_ = inv.TerminateSession(sessionID)
}()
items, err := inv.TraverseIterator(sessionID, &iter, nnsMaxTokens)
for err == nil && len(items) != 0 {
for i := range items {
processItem(items[i])
}
items, err = inv.TraverseIterator(sessionID, &iter, nnsMaxTokens)
}
if err != nil {
return fmt.Errorf("error during NNS domains iteration: %w", err)
}
}
fillContractVersion(cmd, c, infos) fillContractVersion(cmd, c, infos)
printContractInfo(cmd, infos) printContractInfo(cmd, infos)