diff --git a/cmd/neofs-adm/internal/modules/morph/epoch.go b/cmd/neofs-adm/internal/modules/morph/epoch.go index af1faecde..14ab193b5 100644 --- a/cmd/neofs-adm/internal/modules/morph/epoch.go +++ b/cmd/neofs-adm/internal/modules/morph/epoch.go @@ -4,8 +4,6 @@ import ( "errors" "fmt" - "github.com/nspcc-dev/neo-go/pkg/core/transaction" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" @@ -31,19 +29,6 @@ func forceNewEpochCmd(cmd *cobra.Command, args []string) error { return fmt.Errorf("can't get netmap contract hash: %w", err) } - signer := transaction.Signer{ - Account: wCtx.CommitteeAcc.Contract.ScriptHash(), - Scopes: transaction.Global, // Scope is important, as we have nested call to container contract. - } - - groupKey, err := nnsResolveKey(wCtx.Client, cs.Hash, groupKeyDomain) - if err != nil { - cmd.Println("Can't resolve neofs contract group key, using Global scope") - } else { - signer.Scopes = transaction.CustomGroups - signer.AllowedGroups = keys.PublicKeys{groupKey} - } - res, err := wCtx.Client.InvokeFunction(nmHash, "epoch", []smartcontract.Parameter{}, nil) if err != nil || res.State != vm.HaltState.String() || len(res.Stack) == 0 { return errors.New("can't fetch current epoch from the netmap contract") diff --git a/cmd/neofs-adm/internal/modules/morph/initialize.go b/cmd/neofs-adm/internal/modules/morph/initialize.go index 26fedb795..ad22ff093 100644 --- a/cmd/neofs-adm/internal/modules/morph/initialize.go +++ b/cmd/neofs-adm/internal/modules/morph/initialize.go @@ -9,6 +9,7 @@ import ( "time" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" + "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/rpc/client" @@ -21,8 +22,14 @@ import ( "github.com/spf13/viper" ) +type cache struct { + nnsCs *state.Contract + groupKey *keys.PublicKey +} + type initializeContext struct { clientContext + cache // CommitteeAcc is used for retrieving committee address and verification script. CommitteeAcc *wallet.Account // ConsensusAcc is used for retrieving committee address and verification script. @@ -227,6 +234,48 @@ func (c *initializeContext) awaitTx() error { return c.clientContext.awaitTx(c.Command) } +func (c *initializeContext) nnsContractState() (*state.Contract, error) { + if c.nnsCs != nil { + return c.nnsCs, nil + } + + cs, err := c.Client.GetContractStateByID(1) + if err != nil { + return nil, err + } + + c.nnsCs = cs + return cs, nil +} + +func (c *initializeContext) getSigner() transaction.Signer { + if c.groupKey != nil { + return transaction.Signer{ + Scopes: transaction.CustomGroups, + AllowedGroups: keys.PublicKeys{c.groupKey}, + } + } + + signer := transaction.Signer{ + Account: c.CommitteeAcc.Contract.ScriptHash(), + Scopes: transaction.Global, // Scope is important, as we have nested call to container contract. + } + + nnsCs, err := c.nnsContractState() + if err != nil { + return signer + } + + groupKey, err := nnsResolveKey(c.Client, nnsCs.Hash, groupKeyDomain) + if err == nil { + c.groupKey = groupKey + + signer.Scopes = transaction.CustomGroups + signer.AllowedGroups = keys.PublicKeys{groupKey} + } + return signer +} + func (c *clientContext) awaitTx(cmd *cobra.Command) error { if len(c.Hashes) == 0 { return nil @@ -266,10 +315,7 @@ loop: func (c *initializeContext) sendCommitteeTx(script []byte, sysFee int64) error { tx, err := c.Client.CreateTxFromScript(script, c.CommitteeAcc, sysFee, 0, []client.SignerAccount{{ - Signer: transaction.Signer{ - Account: c.CommitteeAcc.Contract.ScriptHash(), - Scopes: transaction.Global, - }, + Signer: c.getSigner(), Account: c.CommitteeAcc, }}) if err != nil { diff --git a/cmd/neofs-adm/internal/modules/morph/initialize_deploy.go b/cmd/neofs-adm/internal/modules/morph/initialize_deploy.go index 6db7a028a..64326e3d4 100644 --- a/cmd/neofs-adm/internal/modules/morph/initialize_deploy.go +++ b/cmd/neofs-adm/internal/modules/morph/initialize_deploy.go @@ -3,6 +3,7 @@ package morph import ( "archive/tar" "compress/gzip" + "encoding/hex" "encoding/json" "errors" "fmt" @@ -98,13 +99,13 @@ func (c *initializeContext) deployNNS(method string) error { cs := c.getContract(nnsContract) h := cs.Hash - realCs, err := c.Client.GetContractStateByID(1) + nnsCs, err := c.nnsContractState() if err == nil { - if realCs.NEF.Checksum == cs.NEF.Checksum { + if nnsCs.NEF.Checksum == cs.NEF.Checksum { c.Command.Println("NNS contract is already deployed.") return nil } - h = realCs.Hash + h = nnsCs.Hash } err = c.addManifestGroup(h, cs) @@ -121,10 +122,6 @@ func (c *initializeContext) deployNNS(method string) error { mgmtHash := c.nativeHash(nativenames.Management) if method == updateMethodName { - nnsCs, err := c.Client.GetContractStateByID(1) - if err != nil { - return fmt.Errorf("can't resolve NNS hash for contract update: %w", err) - } mgmtHash = nnsCs.Hash } @@ -155,7 +152,7 @@ func (c *initializeContext) updateContracts() error { mgmtHash := c.nativeHash(nativenames.Management) alphaCs := c.getContract(alphabetContract) - nnsCs, err := c.Client.GetContractStateByID(1) + nnsCs, err := c.nnsContractState() if err != nil { return err } @@ -272,10 +269,12 @@ func (c *initializeContext) updateContracts() error { } } - sysFee, err := c.emitUpdateNNSGroupScript(w, nnsHash, c.ContractWallet.Accounts[0].PrivateKey().PublicKey()) + groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey() + sysFee, err := c.emitUpdateNNSGroupScript(w, nnsHash, groupKey) if err != nil { return err } + c.Command.Printf("NNS: Set %s -> %s\n", groupKeyDomain, hex.EncodeToString(groupKey.Bytes())) totalGasCost += sysFee if err := c.sendCommitteeTx(w.Bytes(), totalGasCost); err != nil { diff --git a/cmd/neofs-adm/internal/modules/morph/initialize_nns.go b/cmd/neofs-adm/internal/modules/morph/initialize_nns.go index 434b4d3ad..624a4bbfb 100644 --- a/cmd/neofs-adm/internal/modules/morph/initialize_nns.go +++ b/cmd/neofs-adm/internal/modules/morph/initialize_nns.go @@ -69,10 +69,12 @@ func (c *initializeContext) setNNS() error { c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE()) } - err = c.updateNNSGroup(nnsCs.Hash, c.ContractWallet.Accounts[0].PrivateKey().PublicKey()) + groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey() + err = c.updateNNSGroup(nnsCs.Hash, groupKey) if err != nil { return err } + c.Command.Printf("NNS: Set %s -> %s\n", groupKeyDomain, hex.EncodeToString(groupKey.Bytes())) return c.awaitTx() }