package helper import ( "fmt" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants" "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" "github.com/nspcc-dev/neo-go/pkg/rpcclient/management" "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/spf13/viper" ) func getFrostfsIDAdminFromContract(roInvoker *invoker.Invoker) (util.Uint160, bool, error) { r := management.NewReader(roInvoker) cs, err := GetContractByID(r, 1) if err != nil { return util.Uint160{}, false, fmt.Errorf("get nns contract: %w", err) } fidHash, err := NNSResolveHash(roInvoker, cs.Hash, DomainOf(constants.FrostfsIDContract)) if err != nil { return util.Uint160{}, false, fmt.Errorf("resolve frostfsid contract hash: %w", err) } item, err := unwrap.Item(roInvoker.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 GetContractDeployData(c *InitializeContext, ctrName string, keysParam []any, method string) ([]any, error) { items := make([]any, 0, 6) switch ctrName { case constants.FrostfsContract: items = append(items, c.Contracts[constants.ProcessingContract].Hash, keysParam, smartcontract.Parameter{}) case constants.ProcessingContract: items = append(items, c.Contracts[constants.FrostfsContract].Hash) return items[1:], nil // no notary info case constants.BalanceContract: items = append(items, c.Contracts[constants.NetmapContract].Hash, c.Contracts[constants.ContainerContract].Hash) case constants.ContainerContract: // In case if NNS is updated multiple times, we can't calculate // it's actual hash based on local data, thus query chain. r := management.NewReader(c.ReadOnlyInvoker) nnsCs, err := GetContractByID(r, 1) if err != nil { return nil, fmt.Errorf("get nns contract: %w", err) } items = append(items, c.Contracts[constants.NetmapContract].Hash, c.Contracts[constants.BalanceContract].Hash, c.Contracts[constants.FrostfsIDContract].Hash, nnsCs.Hash, "container") case constants.FrostfsIDContract: var ( h util.Uint160 found bool err error ) if method == constants.UpdateMethodName { h, found, err = getFrostfsIDAdminFromContract(c.ReadOnlyInvoker) } if method != constants.UpdateMethodName || err == nil && !found { h, found, err = GetFrostfsIDAdmin(viper.GetViper()) } if err != nil { return nil, err } if found { items = append(items, h) } else { items = append(items, c.Contracts[constants.ProxyContract].Hash) } case constants.NetmapContract: md := GetDefaultNetmapContractConfigMap() if method == constants.UpdateMethodName { if err := MergeNetmapConfig(c.ReadOnlyInvoker, md); err != nil { return nil, err } } var configParam []any for k, v := range md { configParam = append(configParam, k, v) } items = append(items, c.Contracts[constants.BalanceContract].Hash, c.Contracts[constants.ContainerContract].Hash, keysParam, configParam) case constants.ProxyContract: items = nil case constants.PolicyContract: items = append(items, c.Contracts[constants.ProxyContract].Hash) default: panic("invalid contract name: " + ctrName) } return items, nil } func GetContractDeployParameters(cs *ContractState, deployData []any) []any { return []any{cs.RawNEF, cs.RawManifest, deployData} } func DeployNNS(c *InitializeContext, method string) error { cs := c.GetContract(constants.NNSContract) h := cs.Hash nnsCs, err := c.NNSContractState() if err != nil { return err } if nnsCs != nil { if nnsCs.NEF.Checksum == cs.NEF.Checksum { if method == constants.DeployMethodName { c.Command.Println("NNS contract is already deployed.") } else { c.Command.Println("NNS contract is already updated.") } return nil } h = nnsCs.Hash } err = AddManifestGroup(c.ContractWallet, h, cs) if err != nil { return fmt.Errorf("can't sign manifest group: %v", err) } params := GetContractDeployParameters(cs, nil) invokeHash := management.Hash if method == constants.UpdateMethodName { invokeHash = nnsCs.Hash } tx, err := c.CommitteeAct.MakeCall(invokeHash, method, params...) if err != nil { return fmt.Errorf("failed to create deploy tx for %s: %w", constants.NNSContract, err) } if err := c.MultiSignAndSend(tx, constants.CommitteeAccountName); err != nil { return fmt.Errorf("can't send deploy transaction: %w", err) } c.Command.Println("NNS hash:", invokeHash.StringLE()) return c.AwaitTx() }