diff --git a/cmd/frostfs-adm/internal/modules/morph/initialize_deploy.go b/cmd/frostfs-adm/internal/modules/morph/initialize_deploy.go index 61536b4d5..6cf75c5f9 100644 --- a/cmd/frostfs-adm/internal/modules/morph/initialize_deploy.go +++ b/cmd/frostfs-adm/internal/modules/morph/initialize_deploy.go @@ -222,7 +222,11 @@ func (c *initializeContext) deployOrUpdateContracts(w *io2.BufBinWriter, nnsHash invokeHash = ctrHash } - params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam, updateMethodName)) + args, err := c.getContractDeployData(ctrName, keysParam, updateMethodName) + if err != nil { + return fmt.Errorf("%s: getting update params: %v", ctrName, err) + } + params := getContractDeployParameters(cs, args) res, err := c.CommitteeAct.MakeCall(invokeHash, method, params...) if err != nil { if method != updateMethodName || !strings.Contains(err.Error(), common.ErrAlreadyUpdated) { @@ -345,7 +349,11 @@ func (c *initializeContext) deployContracts() error { return fmt.Errorf("can't sign manifest group: %v", err) } - params := getContractDeployParameters(cs, c.getContractDeployData(ctrName, keysParam, deployMethodName)) + args, err := c.getContractDeployData(ctrName, keysParam, deployMethodName) + if err != nil { + return fmt.Errorf("%s: getting deploy params: %v", ctrName, err) + } + params := getContractDeployParameters(cs, args) res, err := c.CommitteeAct.MakeCall(management.Hash, deployMethodName, params...) if err != nil { return fmt.Errorf("can't deploy %s contract: %w", ctrName, err) @@ -511,7 +519,7 @@ func getContractDeployParameters(cs *contractState, deployData []any) []any { return []any{cs.RawNEF, cs.RawManifest, deployData} } -func (c *initializeContext) getContractDeployData(ctrName string, keysParam []any, method string) []any { +func (c *initializeContext) getContractDeployData(ctrName string, keysParam []any, method string) ([]any, error) { items := make([]any, 0, 6) switch ctrName { @@ -522,7 +530,7 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an smartcontract.Parameter{}) case processingContract: items = append(items, c.Contracts[frostfsContract].Hash) - return items[1:] // no notary info + return items[1:], nil // no notary info case balanceContract: items = append(items, c.Contracts[netmapContract].Hash, @@ -533,7 +541,7 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an r := management.NewReader(c.ReadOnlyInvoker) nnsCs, err := r.GetContractByID(1) if err != nil { - panic("NNS is not yet deployed") + return nil, fmt.Errorf("get nns contract: %w", err) } items = append(items, c.Contracts[netmapContract].Hash, @@ -542,9 +550,19 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an nnsCs.Hash, "container") case frostfsIDContract: - h, found, err := getFrostfsIDAdmin(viper.GetViper()) + var ( + h util.Uint160 + found bool + err error + ) + if method == updateMethodName { + h, found, err = c.getFrostfsIDAdminFromContract() + } + if method != updateMethodName || err == nil && !found { + h, found, err = getFrostfsIDAdmin(viper.GetViper()) + } if err != nil { - panic(err) + return nil, err } if found { @@ -555,21 +573,8 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an case netmapContract: md := getDefaultNetmapContractConfigMap() if method == updateMethodName { - arr, err := c.getNetConfigFromNetmapContract() - if err != nil { - panic(err) - } - m, err := parseConfigFromNetmapContract(arr) - if err != nil { - panic(err) - } - for k, v := range m { - for _, key := range netmapConfigKeys { - if k == key { - md[k] = v - break - } - } + if err := c.mergeNetmapConfig(md); err != nil { + return nil, err } } @@ -590,14 +595,43 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an default: panic(fmt.Sprintf("invalid contract name: %s", ctrName)) } - return items + return items, nil +} + +func (c *initializeContext) getFrostfsIDAdminFromContract() (util.Uint160, bool, error) { + r := management.NewReader(c.ReadOnlyInvoker) + cs, err := r.GetContractByID(1) + if err != nil { + return util.Uint160{}, false, fmt.Errorf("get nns contract: %w", err) + } + fidHash, err := nnsResolveHash(c.ReadOnlyInvoker, cs.Hash, domainOf(frostfsIDContract)) + if err != nil { + return util.Uint160{}, false, fmt.Errorf("resolve frostfsid contract hash: %w", err) + } + item, err := unwrap.Item(c.ReadOnlyInvoker.Call(fidHash, "getAdmin")) + if err != nil { + return util.Uint160{}, false, fmt.Errorf("getAdmin: %w", err) + } + if _, ok := item.(stackitem.Null); ok { + return util.Uint160{}, false, nil + } + + bs, err := item.TryBytes() + if err != nil { + return util.Uint160{}, true, fmt.Errorf("getAdmin: decode result: %w", err) + } + h, err := util.Uint160DecodeBytesBE(bs) + if err != nil { + return util.Uint160{}, true, fmt.Errorf("getAdmin: decode result: %w", err) + } + return h, true, nil } func (c *initializeContext) getNetConfigFromNetmapContract() ([]stackitem.Item, error) { r := management.NewReader(c.ReadOnlyInvoker) cs, err := r.GetContractByID(1) if err != nil { - return nil, fmt.Errorf("NNS is not yet deployed: %w", err) + return nil, fmt.Errorf("get nns contract: %w", err) } nmHash, err := nnsResolveHash(c.ReadOnlyInvoker, cs.Hash, domainOf(netmapContract)) if err != nil { @@ -610,6 +644,26 @@ func (c *initializeContext) getNetConfigFromNetmapContract() ([]stackitem.Item, return arr, err } +func (c *initializeContext) mergeNetmapConfig(md map[string]any) error { + arr, err := c.getNetConfigFromNetmapContract() + if err != nil { + return err + } + m, err := parseConfigFromNetmapContract(arr) + if err != nil { + return err + } + for k, v := range m { + for _, key := range netmapConfigKeys { + if k == key { + md[k] = v + break + } + } + } + return nil +} + func (c *initializeContext) getAlphabetDeployItems(i, n int) []any { items := make([]any, 5) items[0] = c.Contracts[netmapContract].Hash